mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-05-28 19:18:45 +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",
|
.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
|
// 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.
|
// 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
|
// Note: we MUST NOT use the GtkButton parameter because gtkActionNewTab
|
||||||
// sends an undefined value.
|
// sends an undefined value.
|
||||||
fn gtkTabNewClick(_: *gtk.Button, self: *Window) callconv(.c) void {
|
fn gtkTabNewClick(_: *gtk.Button, self: *Window) callconv(.c) void {
|
||||||
|
@ -219,13 +219,12 @@ pub const Window = struct {
|
|||||||
|
|
||||||
pub fn resizeEvent(self: *Window) !void {
|
pub fn resizeEvent(self: *Window) !void {
|
||||||
// The blur region must update with window resizes
|
// 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();
|
try self.syncBlur();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn syncAppearance(self: *Window) !void {
|
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: {
|
self.blur_region = blur: {
|
||||||
// NOTE(pluiedev): CSDs are a f--king mistake.
|
// NOTE(pluiedev): CSDs are a f--king mistake.
|
||||||
// Please, GNOME, stop this nonsense of making a window ~30% bigger
|
// 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);
|
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 .{
|
break :blur .{
|
||||||
.x = @intFromFloat(x),
|
.x = @intFromFloat(x),
|
||||||
.y = @intFromFloat(y),
|
.y = @intFromFloat(y),
|
||||||
@ -265,6 +269,13 @@ pub const Window = struct {
|
|||||||
// and I think it's not really noticeable enough to justify the effort.
|
// and I think it's not really noticeable enough to justify the effort.
|
||||||
// (Wayland also has this visual artifact anyway...)
|
// (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;
|
const blur = self.config.background_blur;
|
||||||
log.debug("set blur={}, window xid={}, region={}", .{
|
log.debug("set blur={}, window xid={}, region={}", .{
|
||||||
blur,
|
blur,
|
||||||
|
Reference in New Issue
Block a user