mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-04-12 10:48:39 +03:00
gtk(x11): fix blur regions when using >200% scaling (#6978)
See #6957 We were not considering GTK's internal scale factor that converts between "surface coordinates" and actual device coordinates, and that worked fine until the scale factor reached 2x (200%). Since the code is now dependent on the scale factor (which could change at any given moment), we also listen to scale factor changes and then unconditionally call `winproto.syncAppearance`. Even though it's somewhat overkill, I don't expect people to change their scale factor dramatically all the time anyway...
This commit is contained in:
@ -281,6 +281,15 @@ pub fn init(self: *Window, app: *App) !void {
|
||||
.detail = "is-active",
|
||||
},
|
||||
);
|
||||
_ = gobject.Object.signals.notify.connect(
|
||||
self.window,
|
||||
*Window,
|
||||
gtkWindowUpdateScaleFactor,
|
||||
self,
|
||||
.{
|
||||
.detail = "scale-factor",
|
||||
},
|
||||
);
|
||||
|
||||
// If Adwaita is enabled and is older than 1.4.0 we don't have the tab overview and so we
|
||||
// need to stick the headerbar into the content box.
|
||||
@ -784,6 +793,24 @@ fn gtkWindowNotifyIsActive(
|
||||
}
|
||||
}
|
||||
|
||||
fn gtkWindowUpdateScaleFactor(
|
||||
_: *adw.ApplicationWindow,
|
||||
_: *gobject.ParamSpec,
|
||||
self: *Window,
|
||||
) callconv(.c) void {
|
||||
// On some platforms (namely X11) we need to refresh our appearance when
|
||||
// the scale factor changes. In theory this could be more fine-grained as
|
||||
// a full refresh could be expensive, but a) this *should* be rare, and
|
||||
// b) quite noticeable visual bugs would occur if this is not present.
|
||||
self.winproto.syncAppearance() catch |err| {
|
||||
log.err(
|
||||
"failed to sync appearance after scale factor has been updated={}",
|
||||
.{err},
|
||||
);
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
// Note: we MUST NOT use the GtkButton parameter because gtkActionNewTab
|
||||
// sends an undefined value.
|
||||
fn gtkTabNewClick(_: *gtk.Button, self: *Window) callconv(.c) void {
|
||||
|
@ -219,13 +219,12 @@ pub const Window = struct {
|
||||
|
||||
pub fn resizeEvent(self: *Window) !void {
|
||||
// The blur region must update with window resizes
|
||||
const gtk_widget = self.gtk_window.as(gtk.Widget);
|
||||
self.blur_region.width = gtk_widget.getWidth();
|
||||
self.blur_region.height = gtk_widget.getHeight();
|
||||
try self.syncBlur();
|
||||
}
|
||||
|
||||
pub fn syncAppearance(self: *Window) !void {
|
||||
// The user could have toggled between CSDs and SSDs,
|
||||
// therefore we need to recalculate the blur region offset.
|
||||
self.blur_region = blur: {
|
||||
// NOTE(pluiedev): CSDs are a f--king mistake.
|
||||
// Please, GNOME, stop this nonsense of making a window ~30% bigger
|
||||
@ -236,6 +235,11 @@ pub const Window = struct {
|
||||
|
||||
self.gtk_window.as(gtk.Native).getSurfaceTransform(&x, &y);
|
||||
|
||||
// Transform surface coordinates to device coordinates.
|
||||
const scale: f64 = @floatFromInt(self.gtk_window.as(gtk.Widget).getScaleFactor());
|
||||
x *= scale;
|
||||
y *= scale;
|
||||
|
||||
break :blur .{
|
||||
.x = @intFromFloat(x),
|
||||
.y = @intFromFloat(y),
|
||||
@ -265,6 +269,13 @@ pub const Window = struct {
|
||||
// and I think it's not really noticeable enough to justify the effort.
|
||||
// (Wayland also has this visual artifact anyway...)
|
||||
|
||||
const gtk_widget = self.gtk_window.as(gtk.Widget);
|
||||
|
||||
// Transform surface coordinates to device coordinates.
|
||||
const scale = self.gtk_window.as(gtk.Widget).getScaleFactor();
|
||||
self.blur_region.width = gtk_widget.getWidth() * scale;
|
||||
self.blur_region.height = gtk_widget.getHeight() * scale;
|
||||
|
||||
const blur = self.config.background_blur;
|
||||
log.debug("set blur={}, window xid={}, region={}", .{
|
||||
blur,
|
||||
|
Reference in New Issue
Block a user