[gtk/wip/smcv/shifted-shortcuts] gdkevents: Don't ignore modifiers that are not currently active
- From: Simon McVittie <smcv src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/smcv/shifted-shortcuts] gdkevents: Don't ignore modifiers that are not currently active
- Date: Sat, 17 Sep 2022 17:54:19 +0000 (UTC)
commit a6da84945f14eaff26a341bf0c7a05393bc2e3ff
Author: Simon McVittie <smcv debian org>
Date: Sat Sep 17 18:53:00 2022 +0100
gdkevents: Don't ignore modifiers that are not currently active
The X11 backend can mark modifiers like Shift as consumed even if they
aren't actually active, as a way to make shortcuts like
`<Control><Shift>plus` work as intended on keyboards where the plus
symbol is obtained by pressing Shift and the plus/equals key. This has
the desired effect of making both `<Control>plus` and
`<Control><Shift>plus` work as intended on those keyboards. (The Wayland
and Windows backends do not do this, so only `<Control>plus` can be
used with Wayland or Windows.)
However, this can go badly wrong when the modifier is *not* pressed.
For example, terminals normally have separate bindings for `<Control>c`
(send SIGINT) and `<Control><Shift>c` (copy). If we disregard the
consumed modifiers completely, when the X11 backend marks Shift as
consumed, pressing Ctrl+c would send SIGINT *and* copy to the clipboard,
which is not what was intended.
By masking out the members of `consumed` that are not in `state`, we
get the same interpretation for X11 and Wayland, and ensure that
keyboard shortcuts that explicitly mention Shift can only be triggered
while holding Shift. It continues to be possible to trigger keyboard
shortcuts that do not explicitly mention Shift (such as `<Control>plus`)
while holding Shift, if the backend reports Shift as having been
consumed in order to generate the plus keysym.
Resolves: https://gitlab.gnome.org/GNOME/gtk/-/issues/5095
Signed-off-by: Simon McVittie <smcv debian org>
gdk/gdkevents.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
---
diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c
index 4b61715575..0daf475c3f 100644
--- a/gdk/gdkevents.c
+++ b/gdk/gdkevents.c
@@ -1773,7 +1773,7 @@ gdk_key_event_matches (GdkEvent *event,
guint ev_keyval;
int layout;
int level;
- GdkModifierType consumed_modifiers;
+ GdkModifierType ignored_modifiers;
GdkModifierType shift_group_mask;
gboolean group_mod_is_accel_mod = FALSE;
const GdkModifierType mask = GDK_CONTROL_MASK |
@@ -1792,7 +1792,23 @@ gdk_key_event_matches (GdkEvent *event,
ev_keyval = self->translated[1].keyval;
layout = self->translated[1].layout;
level = self->translated[1].level;
- consumed_modifiers = self->translated[1].consumed;
+
+ /*
+ * If a modifier is currently active (e.g. Shift is pressed) and was marked
+ * as consumed, we ignore it for the purposes of matching shortcuts.
+ * For example, when Ctrl+Shift+[plus/equals key] is translated into
+ * Ctrl+plus on a keyboard where Shift+equals is the plus sign, we want
+ * shortcuts for either <Control><Shift>plus or <Control>plus to match.
+ * (See https://bugzilla.gnome.org/show_bug.cgi?id=100439)
+ *
+ * If a modifier is *not* currently active, the X11 backend can sometimes
+ * mark it as consumed where the Wayland and Windows backends do not.
+ * In this case, we still want to pay attention to its state.
+ * For example, when Ctrl+x is translated into Ctrl+x, we only want to
+ * trigger shortcuts for <Control>x, not for <Control><Shift>x.
+ * (See https://gitlab.gnome.org/GNOME/gtk/-/issues/5095)
+ */
+ ignored_modifiers = (self->translated[1].consumed & state);
/* if the group-toggling modifier is part of the default accel mod
* mask, and it is active, disable it for matching
@@ -1804,7 +1820,7 @@ gdk_key_event_matches (GdkEvent *event,
if (mask & shift_group_mask)
group_mod_is_accel_mod = TRUE;
- if ((modifiers & ~consumed_modifiers & mask) == (state & ~consumed_modifiers & mask))
+ if ((modifiers & ~ignored_modifiers & mask) == (state & ~ignored_modifiers & mask))
{
/* modifier match */
GdkKeymapKey *keys;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]