diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c index eb39c95976..f7abfe75b5 100644 --- a/gdk/gdkevents.c +++ b/gdk/gdkevents.c @@ -1686,6 +1686,24 @@ gdk_key_event_is_modifier (GdkEvent *event) return self->key_is_modifier; } +static gboolean +keyval_in_group (GdkKeymap *keymap, + guint keyval, + int group) +{ + GdkKeymapKey *keys; + guint n_keys; + + gdk_keymap_get_cached_entries_for_keyval (keymap, keyval, &keys, &n_keys); + for (int i = 0; i < n_keys; i++) + { + if (keys[i].group == group) + return TRUE; + } + + return FALSE; +} + /** * gdk_key_event_matches: * @event: (type GdkKeyEvent): a key `GdkEvent` @@ -1781,10 +1799,9 @@ gdk_key_event_matches (GdkEvent *event, if (keys[i].keycode == keycode && keys[i].level == level && /* Only match for group if it's an accel mod */ - (!group_mod_is_accel_mod || keys[i].group == layout)) - { - return GDK_KEY_MATCH_PARTIAL; - } + (keys[i].group == layout || + (!group_mod_is_accel_mod && !keyval_in_group (keymap, keyval, layout)))) + return GDK_KEY_MATCH_PARTIAL; } } diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index 712fcd2a98..5211cbbbda 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -1846,6 +1846,36 @@ pointer_handle_axis_discrete (void *data, get_axis_name (axis), value, seat)); } +static int +get_active_layout (GdkKeymap *keymap) +{ + struct xkb_keymap *xkb_keymap; + struct xkb_state *xkb_state; + + xkb_keymap = _gdk_wayland_keymap_get_xkb_keymap (keymap); + xkb_state = _gdk_wayland_keymap_get_xkb_state (keymap); + + for (int i = 0; i < xkb_keymap_num_layouts (xkb_keymap); i++) + { + if (xkb_state_layout_index_is_active (xkb_state, i, XKB_STATE_LAYOUT_EFFECTIVE)) + return i; + } + + return -1; +} + +#ifdef G_ENABLE_DEBUG +static const char * +get_active_layout_name (GdkKeymap *keymap) +{ + struct xkb_keymap *xkb_keymap; + + xkb_keymap = _gdk_wayland_keymap_get_xkb_keymap (keymap); + + return xkb_keymap_layout_get_name (xkb_keymap, get_active_layout (keymap)); +} +#endif + static void keyboard_handle_keymap (void *data, struct wl_keyboard *keyboard, @@ -1870,6 +1900,8 @@ keyboard_handle_keymap (void *data, _gdk_wayland_keymap_update_from_fd (seat->keymap, format, fd, size); + GDK_DISPLAY_NOTE(seat->keymap->display, INPUT, g_print ("active layout now: %s\n", get_active_layout_name (seat->keymap))); + g_signal_emit_by_name (seat->keymap, "keys-changed"); g_signal_emit_by_name (seat->keymap, "state-changed"); if (direction != gdk_keymap_get_direction (seat->keymap)) @@ -2215,17 +2247,18 @@ keyboard_handle_modifiers (void *data, gboolean num_lock; gboolean scroll_lock; GdkModifierType modifiers; + int layout; keymap = seat->keymap; xkb_state = _gdk_wayland_keymap_get_xkb_state (keymap); - direction = gdk_keymap_get_direction (seat->keymap); - bidi = gdk_keymap_have_bidi_layouts (seat->keymap); - caps_lock = gdk_keymap_get_caps_lock_state (seat->keymap); - num_lock = gdk_keymap_get_num_lock_state (seat->keymap); - scroll_lock = gdk_keymap_get_scroll_lock_state (seat->keymap); - modifiers = gdk_keymap_get_modifier_state (seat->keymap); - + direction = gdk_keymap_get_direction (keymap); + bidi = gdk_keymap_have_bidi_layouts (keymap); + caps_lock = gdk_keymap_get_caps_lock_state (keymap); + num_lock = gdk_keymap_get_num_lock_state (keymap); + scroll_lock = gdk_keymap_get_scroll_lock_state (keymap); + modifiers = gdk_keymap_get_modifier_state (keymap); + layout = get_active_layout (keymap); /* Note: the docs for xkb_state_update mask state that all parameters * must be passed, or we may end up with an 'incoherent' state. But the @@ -2247,20 +2280,26 @@ keyboard_handle_modifiers (void *data, seat->key_modifiers = gdk_keymap_get_modifier_state (keymap); g_signal_emit_by_name (keymap, "state-changed"); - if (direction != gdk_keymap_get_direction (keymap)) - g_signal_emit_by_name (keymap, "direction-changed"); + if (layout != get_active_layout (keymap)) + { + GDK_DISPLAY_NOTE(keymap->display, INPUT, g_print ("active layout now: %s\n", get_active_layout_name (keymap))); - if (direction != gdk_keymap_get_direction (seat->keymap)) - g_object_notify (G_OBJECT (seat->logical_keyboard), "direction"); - if (bidi != gdk_keymap_have_bidi_layouts (seat->keymap)) + g_signal_emit_by_name (keymap, "keys-changed"); + } + if (direction != gdk_keymap_get_direction (keymap)) + { + g_signal_emit_by_name (keymap, "direction-changed"); + g_object_notify (G_OBJECT (seat->logical_keyboard), "direction"); + } + if (bidi != gdk_keymap_have_bidi_layouts (keymap)) g_object_notify (G_OBJECT (seat->logical_keyboard), "has-bidi-layouts"); - if (caps_lock != gdk_keymap_get_caps_lock_state (seat->keymap)) + if (caps_lock != gdk_keymap_get_caps_lock_state (keymap)) g_object_notify (G_OBJECT (seat->logical_keyboard), "caps-lock-state"); - if (num_lock != gdk_keymap_get_num_lock_state (seat->keymap)) + if (num_lock != gdk_keymap_get_num_lock_state (keymap)) g_object_notify (G_OBJECT (seat->logical_keyboard), "num-lock-state"); - if (scroll_lock != gdk_keymap_get_scroll_lock_state (seat->keymap)) + if (scroll_lock != gdk_keymap_get_scroll_lock_state (keymap)) g_object_notify (G_OBJECT (seat->logical_keyboard), "scroll-lock-state"); - if (modifiers != gdk_keymap_get_modifier_state (seat->keymap)) + if (modifiers != gdk_keymap_get_modifier_state (keymap)) g_object_notify (G_OBJECT (seat->logical_keyboard), "modifier-state"); }