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).
This commit is contained in:
Gregory Anders
2024-01-10 16:22:34 -06:00
parent a63c7e8159
commit d059c57440
2 changed files with 12 additions and 17 deletions

View File

@ -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_);
}

View File

@ -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) {