Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <campbell@blender.org>2022-08-11 09:26:29 +0300
committerCampbell Barton <campbell@blender.org>2022-08-11 09:48:55 +0300
commitaa0ca3aefa3136b09e270995d785fa18618bee61 (patch)
treea3803cfcfc2160cfa3765d6b18672fa7d7342712 /intern/ghost
parent1c716cbeb78367bf8df7d73d20ab4f7e8439ac1d (diff)
GHOST/Wayland: support setting modifiers on window activation
Take advantage of Waylands wl_keyboard_listener.enter callback which takes an array of keys that are pressed when a window is activated. Resolves T74684 under Wayland.
Diffstat (limited to 'intern/ghost')
-rw-r--r--intern/ghost/intern/GHOST_SystemWayland.cpp54
1 files changed, 52 insertions, 2 deletions
diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp
index 482ecf2ba39..18d91d43057 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.cpp
+++ b/intern/ghost/intern/GHOST_SystemWayland.cpp
@@ -13,6 +13,7 @@
#include "GHOST_EventWheel.h"
#include "GHOST_PathUtils.h"
#include "GHOST_TimerManager.h"
+#include "GHOST_WaylandUtils.h"
#include "GHOST_WindowManager.h"
#include "GHOST_utildefines.h"
@@ -2140,7 +2141,7 @@ static void keyboard_handle_enter(void *data,
struct wl_keyboard * /*wl_keyboard*/,
const uint32_t serial,
struct wl_surface *surface,
- struct wl_array * /*keys*/)
+ struct wl_array *keys)
{
if (!ghost_wl_surface_own(surface)) {
CLOG_INFO(LOG, 2, "enter (skipped)");
@@ -2151,6 +2152,49 @@ static void keyboard_handle_enter(void *data,
input_t *input = static_cast<input_t *>(data);
input->keyboard.serial = serial;
input->keyboard.wl_surface = surface;
+
+ if (keys->size != 0) {
+ /* If there are any keys held when activating the window,
+ * modifiers will be compared against the input state,
+ * only enabling modifiers that were previously disabled. */
+
+ const xkb_mod_mask_t state = xkb_state_serialize_mods(input->xkb_state, XKB_STATE_MODS_ALL);
+ uint32_t *key;
+ WL_ARRAY_FOR_EACH (key, keys) {
+ const xkb_keycode_t key_code = *key + EVDEV_OFFSET;
+ const xkb_keysym_t sym = xkb_state_key_get_one_sym(input->xkb_state, key_code);
+ GHOST_TKey gkey = GHOST_kKeyUnknown;
+
+#define MOD_TEST(state, mod) ((mod != XKB_MOD_INVALID) && (state & (1 << mod)))
+#define MOD_TEST_CASE(xkb_key, ghost_key, mod_index) \
+ case xkb_key: \
+ if (!MOD_TEST(state, input->xkb_keymap_mod_index.mod_index)) { \
+ gkey = ghost_key; \
+ } \
+ break
+
+ switch (sym) {
+ MOD_TEST_CASE(XKB_KEY_Shift_L, GHOST_kKeyLeftShift, shift);
+ MOD_TEST_CASE(XKB_KEY_Shift_R, GHOST_kKeyRightShift, shift);
+ MOD_TEST_CASE(XKB_KEY_Control_L, GHOST_kKeyLeftControl, ctrl);
+ MOD_TEST_CASE(XKB_KEY_Control_R, GHOST_kKeyRightControl, ctrl);
+ MOD_TEST_CASE(XKB_KEY_Alt_L, GHOST_kKeyLeftAlt, alt);
+ MOD_TEST_CASE(XKB_KEY_Alt_R, GHOST_kKeyRightAlt, alt);
+ MOD_TEST_CASE(XKB_KEY_Super_L, GHOST_kKeyOS, logo);
+ MOD_TEST_CASE(XKB_KEY_Super_R, GHOST_kKeyOS, logo);
+ }
+
+#undef MOD_TEST
+#undef MOD_TEST_CASE
+
+ if (gkey != GHOST_kKeyUnknown) {
+ GHOST_IWindow *win = ghost_wl_surface_user_data(surface);
+ GHOST_SystemWayland *system = input->system;
+ input->system->pushEvent(
+ new GHOST_EventKey(system->getMilliSeconds(), GHOST_kEventKeyDown, win, gkey, false));
+ }
+ }
+ }
}
/**
@@ -2377,7 +2421,13 @@ static void keyboard_handle_modifiers(void *data,
const uint32_t mods_locked,
const uint32_t group)
{
- CLOG_INFO(LOG, 2, "modifiers");
+ CLOG_INFO(LOG,
+ 2,
+ "modifiers (depressed=%u, latched=%u, locked=%u, group=%u)",
+ mods_depressed,
+ mods_latched,
+ mods_locked,
+ group);
input_t *input = static_cast<input_t *>(data);
xkb_state_update_mask(input->xkb_state, mods_depressed, mods_latched, mods_locked, 0, 0, group);