From ffaa7e11e26b88da4294c48cdc7f3f09d90fc719 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vlad=20P=C4=83n=C4=83zan?= Date: Fri, 27 Oct 2023 23:26:21 +0200 Subject: [PATCH 1/4] apprt/gtk: handle surface scale changes --- src/apprt/gtk/Surface.zig | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/apprt/gtk/Surface.zig b/src/apprt/gtk/Surface.zig index 86a6c816e..06c7ebf8d 100644 --- a/src/apprt/gtk/Surface.zig +++ b/src/apprt/gtk/Surface.zig @@ -354,10 +354,12 @@ pub fn shouldClose(self: *const Surface) bool { } pub fn getContentScale(self: *const Surface) !apprt.ContentScale { - _ = self; - const monitor = glfw.Monitor.getPrimary() orelse return error.NoMonitor; - const scale = monitor.getContentScale(); - return apprt.ContentScale{ .x = scale.x_scale, .y = scale.y_scale }; + const window_scale: f32 = scale: { + const window = @as(*c.GtkNative, @ptrCast(self.window.window)); + const gdk_surface = c.gtk_native_get_surface(window); + break :scale @floatCast(c.gdk_surface_get_scale(gdk_surface)); + }; + return apprt.ContentScale{ .x = window_scale, .y = window_scale }; } pub fn getSize(self: *const Surface) !apprt.SurfaceSize { @@ -625,6 +627,13 @@ fn gtkResize(area: *c.GtkGLArea, width: c.gint, height: c.gint, ud: ?*anyopaque) .height = @intCast(height), }; + if (self.getContentScale()) |scale| { + self.core_surface.contentScaleCallback(scale) catch |err| { + log.err("error in content scale callback err={}", .{err}); + return; + }; + } else |_|{} + // Call the primary callback. if (self.realized) { self.core_surface.sizeCallback(self.size) catch |err| { From b985b289185ed9e6a272f8145faf581f5e8bf4d7 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 27 Oct 2023 15:03:41 -0700 Subject: [PATCH 2/4] apprt/gtk: use gtk widget scale to get content scale --- src/apprt/gtk/App.zig | 9 --------- src/apprt/gtk/Surface.zig | 14 +++----------- 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/src/apprt/gtk/App.zig b/src/apprt/gtk/App.zig index 74d3c6b76..47e69eba3 100644 --- a/src/apprt/gtk/App.zig +++ b/src/apprt/gtk/App.zig @@ -13,7 +13,6 @@ const App = @This(); const std = @import("std"); const assert = std.debug.assert; const builtin = @import("builtin"); -const glfw = @import("glfw"); const configpkg = @import("../../config.zig"); const input = @import("../../input.zig"); const internal_os = @import("../../os/main.zig"); @@ -53,12 +52,6 @@ running: bool = true, pub fn init(core_app: *CoreApp, opts: Options) !App { _ = opts; - // This is super weird, but we still use GLFW with GTK only so that - // we can tap into their folklore logic to get screen DPI. If we can - // figure out a reliable way to determine this ourselves, we can get - // rid of this dep. - if (!glfw.init(.{})) return error.GlfwInitFailed; - // Load our configuration var config = try Config.load(core_app.alloc); errdefer config.deinit(); @@ -166,8 +159,6 @@ pub fn terminate(self: *App) void { if (self.menu) |menu| c.g_object_unref(menu); self.config.deinit(); - - glfw.terminate(); } /// Reload the configuration. This should return the new configuration. diff --git a/src/apprt/gtk/Surface.zig b/src/apprt/gtk/Surface.zig index 06c7ebf8d..64151ff89 100644 --- a/src/apprt/gtk/Surface.zig +++ b/src/apprt/gtk/Surface.zig @@ -4,7 +4,6 @@ const Surface = @This(); const std = @import("std"); -const glfw = @import("glfw"); const configpkg = @import("../../config.zig"); const apprt = @import("../../apprt.zig"); const font = @import("../../font/main.zig"); @@ -19,9 +18,6 @@ const c = @import("c.zig"); const log = std.log.scoped(.gtk); -// We need native X11 access to access the primary clipboard. -const glfw_native = glfw.Native(.{ .x11 = true }); - /// This is detected by the OpenGL renderer to move to a single-threaded /// draw operation. This basically puts locks around our draw path. pub const opengl_single_threaded_draw = true; @@ -354,12 +350,8 @@ pub fn shouldClose(self: *const Surface) bool { } pub fn getContentScale(self: *const Surface) !apprt.ContentScale { - const window_scale: f32 = scale: { - const window = @as(*c.GtkNative, @ptrCast(self.window.window)); - const gdk_surface = c.gtk_native_get_surface(window); - break :scale @floatCast(c.gdk_surface_get_scale(gdk_surface)); - }; - return apprt.ContentScale{ .x = window_scale, .y = window_scale }; + const scale = c.gtk_widget_get_scale_factor(@ptrCast(self.gl_area)); + return .{ .x = @floatFromInt(scale), .y = @floatFromInt(scale) }; } pub fn getSize(self: *const Surface) !apprt.SurfaceSize { @@ -632,7 +624,7 @@ fn gtkResize(area: *c.GtkGLArea, width: c.gint, height: c.gint, ud: ?*anyopaque) log.err("error in content scale callback err={}", .{err}); return; }; - } else |_|{} + } else |_| {} // Call the primary callback. if (self.realized) { From 25e3b21eae91a474b3801594b2674263d9fbd556 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 27 Oct 2023 15:09:52 -0700 Subject: [PATCH 3/4] apprt/gtk: comment about future API --- src/apprt/gtk/Surface.zig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/apprt/gtk/Surface.zig b/src/apprt/gtk/Surface.zig index 64151ff89..054c736e5 100644 --- a/src/apprt/gtk/Surface.zig +++ b/src/apprt/gtk/Surface.zig @@ -350,6 +350,8 @@ pub fn shouldClose(self: *const Surface) bool { } pub fn getContentScale(self: *const Surface) !apprt.ContentScale { + // Future: detect GTK version 4.12+ and use gdk_surface_get_scale so we + // can support fractional scaling. const scale = c.gtk_widget_get_scale_factor(@ptrCast(self.gl_area)); return .{ .x = @floatFromInt(scale), .y = @floatFromInt(scale) }; } @@ -619,6 +621,8 @@ fn gtkResize(area: *c.GtkGLArea, width: c.gint, height: c.gint, ud: ?*anyopaque) .height = @intCast(height), }; + // We also update the content scale because there is no signal for + // content scale change and it seems to trigger a resize event. if (self.getContentScale()) |scale| { self.core_surface.contentScaleCallback(scale) catch |err| { log.err("error in content scale callback err={}", .{err}); From 423d0d58c09d3ec8bd1710924e62f6f1359369f1 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 27 Oct 2023 15:11:04 -0700 Subject: [PATCH 4/4] build: do not build glfw for gtk anymore --- build.zig | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/build.zig b/build.zig index e6e95b0fe..cc914dca2 100644 --- a/build.zig +++ b/build.zig @@ -795,30 +795,24 @@ fn addDeps( // get access to glib for dbus. if (flatpak) step.linkSystemLibrary2("gtk4", dynamic_link_opts); - // We may link GLFW below - const glfw_dep = b.dependency("glfw", .{ - .target = step.target, - .optimize = step.optimize, - .x11 = step.target.isLinux(), - .wayland = step.target.isLinux(), - .metal = step.target.isDarwin(), - }); - switch (app_runtime) { .none => {}, .glfw => { + const glfw_dep = b.dependency("glfw", .{ + .target = step.target, + .optimize = step.optimize, + .x11 = step.target.isLinux(), + .wayland = step.target.isLinux(), + .metal = step.target.isDarwin(), + }); + step.addModule("glfw", mach_glfw_dep.module("mach-glfw")); step.linkLibrary(mach_glfw_dep.artifact("mach-glfw")); step.linkLibrary(glfw_dep.artifact("glfw")); }, .gtk => { - // We need glfw for GTK because we use GLFW to get DPI. - step.addModule("glfw", mach_glfw_dep.module("mach-glfw")); - step.linkLibrary(mach_glfw_dep.artifact("mach-glfw")); - step.linkLibrary(glfw_dep.artifact("glfw")); - step.linkSystemLibrary2("gtk4", dynamic_link_opts); }, }