From d059c574401067756880931c43d580a52ed40592 Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Wed, 10 Jan 2024 16:22:34 -0600 Subject: [PATCH] gtk: use modifier state from GTK key event on X11 On X11 gdk_device_get_modifier_state does not correctly return the modifier state, while the modifier state passed to the key callback does. On Wayland, the situation is exactly reversed. Therefore on X11 we use the mods provided by the key callback and on Wayland we continue to get the modifier state from the device. `App.modifier_state_from_xkb` is removed since we can lift the conditional out of the function call (we would need to make a second, redundant check for the presence of `x11_xkb` otherwise). --- src/apprt/gtk/App.zig | 7 ------- src/apprt/gtk/Surface.zig | 22 ++++++++++++---------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/apprt/gtk/App.zig b/src/apprt/gtk/App.zig index 46a982348..9b1deea9e 100644 --- a/src/apprt/gtk/App.zig +++ b/src/apprt/gtk/App.zig @@ -600,10 +600,3 @@ test "isValidAppId" { try testing.expect(!isValidAppId("")); try testing.expect(!isValidAppId("foo" ** 86)); } - -/// Loads keyboard state from Xkb if there is an event pending and Xkb is -/// loaded (X11 only). Returns null otherwise. -pub fn modifier_state_from_xkb(self: *App, display_: ?*c.GdkDisplay) ?input.Mods { - const x11_xkb = self.x11_xkb orelse return null; - return x11_xkb.modifier_state_from_notify(display_); -} diff --git a/src/apprt/gtk/Surface.zig b/src/apprt/gtk/Surface.zig index 90df1ff35..a3438e242 100644 --- a/src/apprt/gtk/Surface.zig +++ b/src/apprt/gtk/Surface.zig @@ -1349,20 +1349,22 @@ fn keyEvent( if (entry.native == keycode) break :keycode entry.key; } else .invalid; - // Get our modifiers. We have to use the GDK device because the mods - // sent to this event do not have the modifier key applied it if it - // was presssed (i.e. left control) const mods = mods: { - _ = gtk_mods; const device = c.gdk_event_get_device(event); - // Add any modifier state events from Xkb if we have them (X11 only). - // Null back from the Xkb call means there was no modifier - // event to read. This likely means that the key event did not - // result in a modifier change and we can safely rely on the - // GDK state. - var mods = self.app.modifier_state_from_xkb(display) orelse + var mods = if (self.app.x11_xkb) |xkb| + // Add any modifier state events from Xkb if we have them (X11 + // only). Null back from the Xkb call means there was no modifier + // event to read. This likely means that the key event did not + // result in a modifier change and we can safely rely on the GDK + // state. + xkb.modifier_state_from_notify(display) orelse translateMods(gtk_mods) + else + // On Wayland, we have to use the GDK device because the mods sent + // to this event do not have the modifier key applied if it was + // presssed (i.e. left control). translateMods(c.gdk_device_get_modifier_state(device)); + mods.num_lock = c.gdk_device_get_num_lock_state(device) == 1; switch (physical_key) {