[gtk/keymap-rework: 2/21] Add gdk_event_get_match
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/keymap-rework: 2/21] Add gdk_event_get_match
- Date: Sun, 5 Apr 2020 14:45:37 +0000 (UTC)
commit d2087a23fc4347df8b7188271d17e5875041873a
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Apr 4 20:02:20 2020 -0400
Add gdk_event_get_match
This is a counterpart to gdk_event_matches() that can
be used to obtain a shortcut matching an event.
docs/reference/gdk/gdk4-sections.txt | 5 ++
gdk/gdkevents.c | 114 ++++++++++++++++++++++++++++++-----
gdk/gdkevents.h | 15 +++++
3 files changed, 119 insertions(+), 15 deletions(-)
---
diff --git a/docs/reference/gdk/gdk4-sections.txt b/docs/reference/gdk/gdk4-sections.txt
index fb0341f9b8..553982ca50 100644
--- a/docs/reference/gdk/gdk4-sections.txt
+++ b/docs/reference/gdk/gdk4-sections.txt
@@ -566,6 +566,11 @@ gdk_events_get_angle
gdk_events_get_center
gdk_events_get_distance
+<SUBSECTION>
+GdkEventMatch
+gdk_event_matches
+gdk_event_get_match
+
<SUBSECTION Standard>
GDK_TYPE_EVENT
GDK_TYPE_EVENT_MASK
diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c
index 1d53d9c30b..5ab593eefb 100644
--- a/gdk/gdkevents.c
+++ b/gdk/gdkevents.c
@@ -2162,18 +2162,30 @@ translate_keyboard_accel_state (GdkKeymap *keymap,
return retval;
}
-
+/**
+ * gdk_event_matches:
+ * @event: the #GdkEvent
+ * @keyval: the keyval to match
+ * @modifiers: the modifiers to match
+ *
+ * Matches an event against a keyboard shortcut that is specified
+ * as a keyval and modifiers. Note that partial matches are possible
+ * where the combination matches if the currently active group is
+ * ignored.
+ *
+ * Returns: a GdkEventMatch value describing whether @event matches
+ */
GdkEventMatch
gdk_event_matches (GdkEvent *event,
- guint match_keyval,
- GdkModifierType match_modifiers)
+ guint keyval,
+ GdkModifierType modifiers)
{
guint keycode;
GdkModifierType state;
GdkModifierType mask;
int group;
GdkKeymap *keymap;
- guint keyval;
+ guint ev_keyval;
int effective_group;
int level;
GdkModifierType consumed_modifiers;
@@ -2181,7 +2193,7 @@ gdk_event_matches (GdkEvent *event,
gboolean group_mod_is_accel_mod = FALSE;
const GdkModifierType xmods = GDK_MOD2_MASK|GDK_MOD3_MASK|GDK_MOD4_MASK|GDK_MOD5_MASK;
const GdkModifierType vmods = GDK_SUPER_MASK|GDK_HYPER_MASK|GDK_META_MASK;
- GdkModifierType modifiers;
+ GdkModifierType mods;
if (gdk_event_get_event_type (event) != GDK_KEY_PRESS)
return GDK_EVENT_MATCH_NONE;
@@ -2200,7 +2212,7 @@ gdk_event_matches (GdkEvent *event,
translate_keyboard_accel_state (keymap,
keycode, state, group,
- &keyval,
+ &ev_keyval,
&effective_group, &level,
&consumed_modifiers);
@@ -2215,10 +2227,10 @@ gdk_event_matches (GdkEvent *event,
gdk_keymap_map_virtual_modifiers (keymap, &mask);
gdk_keymap_add_virtual_modifiers (keymap, &state);
- modifiers = match_modifiers;
- if (gdk_keymap_map_virtual_modifiers (keymap, &modifiers) &&
- ((modifiers & ~consumed_modifiers & mask & ~vmods) == (state & ~consumed_modifiers & mask & ~vmods) ||
- (modifiers & ~consumed_modifiers & mask & ~xmods) == (state & ~consumed_modifiers & mask & ~xmods)))
+ mods = modifiers;
+ if (gdk_keymap_map_virtual_modifiers (keymap, &mods) &&
+ ((mods & ~consumed_modifiers & mask & ~vmods) == (state & ~consumed_modifiers & mask & ~vmods) ||
+ (mods & ~consumed_modifiers & mask & ~xmods) == (state & ~consumed_modifiers & mask & ~xmods)))
{
/* modifier match */
GdkKeymapKey *keys;
@@ -2229,8 +2241,8 @@ gdk_event_matches (GdkEvent *event,
/* Shift gets consumed and applied for the event,
* so apply it to our keyval to match
*/
- key = match_keyval;
- if (match_modifiers & GDK_SHIFT_MASK)
+ key = keyval;
+ if (modifiers & GDK_SHIFT_MASK)
{
if (key == GDK_KEY_Tab)
key = GDK_KEY_ISO_Left_Tab;
@@ -2238,12 +2250,12 @@ gdk_event_matches (GdkEvent *event,
key = gdk_keyval_to_upper (key);
}
- if (keyval == key && /* exact match */
+ if (ev_keyval == key && /* exact match */
(!group_mod_is_accel_mod ||
- (state & shift_group_mask) == (match_modifiers & shift_group_mask)))
+ (state & shift_group_mask) == (modifiers & shift_group_mask)))
return GDK_EVENT_MATCH_EXACT;
- gdk_keymap_get_entries_for_keyval (keymap, match_keyval, &keys, &n_keys);
+ gdk_keymap_get_entries_for_keyval (keymap, keyval, &keys, &n_keys);
for (i = 0; i < n_keys; i++)
{
@@ -2266,3 +2278,75 @@ gdk_event_matches (GdkEvent *event,
return GDK_EVENT_MATCH_NONE;
}
+
+/**
+ * gdk_event_get_match:
+ * @event: a #GdkEvent
+ * @keyval: (out): return location for a keyval
+ * @modifiers: (out): return location for modifiers
+ *
+ * Gets a keyval and modifier combination that will cause
+ * gdk_event_match() to successfully match the given event.
+ *
+ * Returns: %TRUE on success
+ */
+gboolean
+gdk_event_get_match (GdkEvent *event,
+ guint *keyval,
+ GdkModifierType *modifiers)
+{
+ GdkKeymap *keymap;
+ GdkModifierType mask;
+ guint keycode;
+ guint group;
+ guint key;
+ guint accel_key;
+ GdkModifierType accel_mods;
+ GdkModifierType consumed_modifiers;
+
+ if (gdk_event_get_event_type (event) != GDK_KEY_PRESS)
+ return FALSE;
+
+ keymap = gdk_display_get_keymap (gdk_event_get_display (event));
+
+ mask = gdk_keymap_get_modifier_mask (keymap,
+ GDK_MODIFIER_INTENT_DEFAULT_MOD_MASK);
+
+ keycode = gdk_key_event_get_keycode (event);
+ group = gdk_key_event_get_group (event);
+ accel_key = gdk_key_event_get_keyval (event);
+ accel_mods = gdk_event_get_modifier_state (event);
+
+ if (accel_key == GDK_KEY_Sys_Req &&
+ (accel_mods & GDK_MOD1_MASK) != 0)
+ {
+ /* HACK: we don't want to use SysRq as a keybinding (but we do
+ * want Alt+Print), so we avoid translation from Alt+Print to SysRq
+ */
+ *keyval = GDK_KEY_Print;
+ *modifiers = accel_mods & mask;
+ return TRUE;
+ }
+
+ translate_keyboard_accel_state (keymap,
+ keycode,
+ accel_mods,
+ group,
+ &key, NULL, NULL, &consumed_modifiers);
+
+ accel_key = gdk_keyval_to_lower (key);
+
+ if (accel_key == GDK_KEY_ISO_Left_Tab)
+ accel_key = GDK_KEY_Tab;
+
+ accel_mods &= mask & ~consumed_modifiers;
+
+ /* Put shift back if it changed the case of the key, not otherwise. */
+ if (accel_key != key)
+ accel_mods |= GDK_SHIFT_MASK;
+
+ *keyval = accel_key;
+ *modifiers = accel_mods;
+
+ return TRUE;
+}
diff --git a/gdk/gdkevents.h b/gdk/gdkevents.h
index 944047d946..6d5fa26dbf 100644
--- a/gdk/gdkevents.h
+++ b/gdk/gdkevents.h
@@ -428,6 +428,16 @@ gboolean gdk_events_get_center (GdkEvent *event1,
double *x,
double *y);
+/**
+ * GdkEventMatch:
+ * @GDK_EVENT_MATCH_NONE: The key event does not match
+ * @GDK_EVENT_MATCH_PARTIAL: The key event matches if keyboard state
+ * (specifically, the currently active group) is ignored
+ * @GDK_EVENT_MATCH_EXACT: The key event matches
+ *
+ * The possible return values from gdk_event_matches()
+ * describe how well an event matches a given keyval and modifiers.
+ */
typedef enum {
GDK_EVENT_MATCH_NONE,
GDK_EVENT_MATCH_PARTIAL,
@@ -439,6 +449,11 @@ GdkEventMatch gdk_event_matches (GdkEvent *event,
guint keyval,
GdkModifierType modifiers);
+GDK_AVAILABLE_IN_ALL
+gboolean gdk_event_get_match (GdkEvent *event,
+ guint *keyval,
+ GdkModifierType *modifiers);
+
G_END_DECLS
#endif /* __GDK_EVENTS_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]