mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-05-16 09:48:26 +00:00
wayland: Add support for Mod3 and more esoteric Xkb configurations
Adds support for Mod3, which is usually Level 5 shift, but can vary, as well as not altering the functionality of the more esoteric modifier keys, such as meta and hyper.
This commit is contained in:
parent
ebaa30d339
commit
73ee99978d
5 changed files with 119 additions and 46 deletions
|
@ -313,6 +313,7 @@ typedef Uint16 SDL_Keymod;
|
||||||
#define SDL_KMOD_NONE 0x0000u /**< no modifier is applicable. */
|
#define SDL_KMOD_NONE 0x0000u /**< no modifier is applicable. */
|
||||||
#define SDL_KMOD_LSHIFT 0x0001u /**< the left Shift key is down. */
|
#define SDL_KMOD_LSHIFT 0x0001u /**< the left Shift key is down. */
|
||||||
#define SDL_KMOD_RSHIFT 0x0002u /**< the right Shift key is down. */
|
#define SDL_KMOD_RSHIFT 0x0002u /**< the right Shift key is down. */
|
||||||
|
#define SDL_KMOD_LEVEL5 0x0004u /**< the Level 5 Shift key is down. */
|
||||||
#define SDL_KMOD_LCTRL 0x0040u /**< the left Ctrl (Control) key is down. */
|
#define SDL_KMOD_LCTRL 0x0040u /**< the left Ctrl (Control) key is down. */
|
||||||
#define SDL_KMOD_RCTRL 0x0080u /**< the right Ctrl (Control) key is down. */
|
#define SDL_KMOD_RCTRL 0x0080u /**< the right Ctrl (Control) key is down. */
|
||||||
#define SDL_KMOD_LALT 0x0100u /**< the left Alt key is down. */
|
#define SDL_KMOD_LALT 0x0100u /**< the left Alt key is down. */
|
||||||
|
|
|
@ -50,8 +50,8 @@ SDL_Keymap *SDL_CreateKeymap(void)
|
||||||
|
|
||||||
static SDL_Keymod NormalizeModifierStateForKeymap(SDL_Keymod modstate)
|
static SDL_Keymod NormalizeModifierStateForKeymap(SDL_Keymod modstate)
|
||||||
{
|
{
|
||||||
// The modifiers that affect the keymap are: SHIFT, CAPS, ALT, and MODE
|
// The modifiers that affect the keymap are: SHIFT, CAPS, ALT, MODE, and LEVEL5
|
||||||
modstate &= (SDL_KMOD_SHIFT | SDL_KMOD_CAPS | SDL_KMOD_ALT | SDL_KMOD_MODE);
|
modstate &= (SDL_KMOD_SHIFT | SDL_KMOD_CAPS | SDL_KMOD_ALT | SDL_KMOD_MODE | SDL_KMOD_LEVEL5);
|
||||||
|
|
||||||
// If either right or left Shift are set, set both in the output
|
// If either right or left Shift are set, set both in the output
|
||||||
if (modstate & SDL_KMOD_SHIFT) {
|
if (modstate & SDL_KMOD_SHIFT) {
|
||||||
|
|
|
@ -958,6 +958,9 @@ static void SDLTest_PrintModStateFlag(char *text, size_t maxlen, SDL_Keymod flag
|
||||||
case SDL_KMOD_RSHIFT:
|
case SDL_KMOD_RSHIFT:
|
||||||
SDL_snprintfcat(text, maxlen, "RSHIFT");
|
SDL_snprintfcat(text, maxlen, "RSHIFT");
|
||||||
break;
|
break;
|
||||||
|
case SDL_KMOD_LEVEL5:
|
||||||
|
SDL_snprintfcat(text, maxlen, "LEVEL5");
|
||||||
|
break;
|
||||||
case SDL_KMOD_LCTRL:
|
case SDL_KMOD_LCTRL:
|
||||||
SDL_snprintfcat(text, maxlen, "LCTRL");
|
SDL_snprintfcat(text, maxlen, "LCTRL");
|
||||||
break;
|
break;
|
||||||
|
@ -999,6 +1002,7 @@ static void SDLTest_PrintModState(char *text, size_t maxlen, SDL_Keymod keymod)
|
||||||
const SDL_Keymod kmod_flags[] = {
|
const SDL_Keymod kmod_flags[] = {
|
||||||
SDL_KMOD_LSHIFT,
|
SDL_KMOD_LSHIFT,
|
||||||
SDL_KMOD_RSHIFT,
|
SDL_KMOD_RSHIFT,
|
||||||
|
SDL_KMOD_LEVEL5,
|
||||||
SDL_KMOD_LCTRL,
|
SDL_KMOD_LCTRL,
|
||||||
SDL_KMOD_RCTRL,
|
SDL_KMOD_RCTRL,
|
||||||
SDL_KMOD_LALT,
|
SDL_KMOD_LALT,
|
||||||
|
|
|
@ -68,9 +68,14 @@
|
||||||
// Weston uses a ratio of 10 units per scroll tick
|
// Weston uses a ratio of 10 units per scroll tick
|
||||||
#define WAYLAND_WHEEL_AXIS_UNIT 10
|
#define WAYLAND_WHEEL_AXIS_UNIT 10
|
||||||
|
|
||||||
// xkbcommon as of 1.4.1 doesn't have a name macro for the mode key
|
// "Mod5" is typically level 3 shift, which SDL calls SDL_KMOD_MODE (AltGr).
|
||||||
#ifndef XKB_MOD_NAME_MODE
|
#ifndef XKB_MOD_NAME_MOD5
|
||||||
#define XKB_MOD_NAME_MODE "Mod5"
|
#define XKB_MOD_NAME_MOD5 "Mod5"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// "Mod3" is typically level 5 shift, but is often remapped.
|
||||||
|
#ifndef XKB_MOD_NAME_MOD3
|
||||||
|
#define XKB_MOD_NAME_MOD3 "Mod3"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Keyboard and mouse names to match XWayland
|
// Keyboard and mouse names to match XWayland
|
||||||
|
@ -1267,28 +1272,46 @@ static void Wayland_keymap_iter(struct xkb_keymap *keymap, xkb_keycode_t key, vo
|
||||||
{
|
{
|
||||||
Wayland_Keymap *sdlKeymap = (Wayland_Keymap *)data;
|
Wayland_Keymap *sdlKeymap = (Wayland_Keymap *)data;
|
||||||
const xkb_keysym_t *syms;
|
const xkb_keysym_t *syms;
|
||||||
SDL_Scancode scancode;
|
const SDL_Scancode scancode = SDL_GetScancodeFromTable(SDL_SCANCODE_TABLE_XFREE86_2, (key - 8));
|
||||||
|
|
||||||
scancode = SDL_GetScancodeFromTable(SDL_SCANCODE_TABLE_XFREE86_2, (key - 8));
|
|
||||||
if (scancode == SDL_SCANCODE_UNKNOWN) {
|
if (scancode == SDL_SCANCODE_UNKNOWN) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WAYLAND_xkb_state_key_get_syms(sdlKeymap->state, key, &syms) > 0) {
|
if (WAYLAND_xkb_state_key_get_syms(sdlKeymap->state, key, &syms) > 0) {
|
||||||
uint32_t keycode = SDL_KeySymToUcs4(syms[0]);
|
uint32_t keycode = SDL_KeySymToUcs4(syms[0]);
|
||||||
|
bool key_is_unknown = false;
|
||||||
|
|
||||||
if (!keycode) {
|
if (!keycode) {
|
||||||
const SDL_Scancode sc = SDL_GetScancodeFromKeySym(syms[0], key);
|
switch (syms[0]) {
|
||||||
|
// The default SDL scancode table sets this to right alt instead of AltGr/Mode, so handle it separately.
|
||||||
// Note: The default SDL scancode table sets this to right alt instead of AltGr/Mode, so handle it separately.
|
case XKB_KEY_ISO_Level3_Shift:
|
||||||
if (syms[0] != XKB_KEY_ISO_Level3_Shift) {
|
|
||||||
keycode = SDL_GetKeymapKeycode(NULL, sc, sdlKeymap->modstate);
|
|
||||||
} else {
|
|
||||||
keycode = SDLK_MODE;
|
keycode = SDLK_MODE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* The default SDL scancode table sets Meta L/R to the GUI keys, and Hyper R to app menu, which is
|
||||||
|
* correct as far as physical key placement goes, but these keys are functionally distinct from the
|
||||||
|
* default keycodes SDL returns for the scancodes, so they are set to unknown.
|
||||||
|
*
|
||||||
|
* SDL has no scancode mapping for Hyper L or Level 5 Shift.
|
||||||
|
*/
|
||||||
|
case XKB_KEY_Meta_L:
|
||||||
|
case XKB_KEY_Meta_R:
|
||||||
|
case XKB_KEY_Hyper_L:
|
||||||
|
case XKB_KEY_Hyper_R:
|
||||||
|
case XKB_KEY_ISO_Level5_Shift:
|
||||||
|
keycode = SDLK_UNKNOWN;
|
||||||
|
key_is_unknown = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
const SDL_Scancode sc = SDL_GetScancodeFromKeySym(syms[0], key);
|
||||||
|
keycode = SDL_GetKeymapKeycode(NULL, sc, sdlKeymap->modstate);
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!keycode) {
|
if (!keycode && !key_is_unknown) {
|
||||||
switch (scancode) {
|
switch (scancode) {
|
||||||
case SDL_SCANCODE_RETURN:
|
case SDL_SCANCODE_RETURN:
|
||||||
keycode = SDLK_RETURN;
|
keycode = SDLK_RETURN;
|
||||||
|
@ -1326,10 +1349,18 @@ static void Wayland_UpdateKeymap(struct SDL_WaylandInput *input)
|
||||||
{ SDL_KMOD_SHIFT, input->xkb.idx_shift },
|
{ SDL_KMOD_SHIFT, input->xkb.idx_shift },
|
||||||
{ SDL_KMOD_CAPS, input->xkb.idx_caps },
|
{ SDL_KMOD_CAPS, input->xkb.idx_caps },
|
||||||
{ SDL_KMOD_SHIFT | SDL_KMOD_CAPS, input->xkb.idx_shift | input->xkb.idx_caps },
|
{ SDL_KMOD_SHIFT | SDL_KMOD_CAPS, input->xkb.idx_shift | input->xkb.idx_caps },
|
||||||
{ SDL_KMOD_MODE, input->xkb.idx_mode },
|
{ SDL_KMOD_MODE, input->xkb.idx_mod5 },
|
||||||
{ SDL_KMOD_MODE | SDL_KMOD_SHIFT, input->xkb.idx_mode | input->xkb.idx_shift },
|
{ SDL_KMOD_MODE | SDL_KMOD_SHIFT, input->xkb.idx_mod5 | input->xkb.idx_shift },
|
||||||
{ SDL_KMOD_MODE | SDL_KMOD_CAPS, input->xkb.idx_mode | input->xkb.idx_caps },
|
{ SDL_KMOD_MODE | SDL_KMOD_CAPS, input->xkb.idx_mod5 | input->xkb.idx_caps },
|
||||||
{ SDL_KMOD_MODE | SDL_KMOD_SHIFT | SDL_KMOD_CAPS, input->xkb.idx_mode | input->xkb.idx_shift | input->xkb.idx_caps }
|
{ SDL_KMOD_MODE | SDL_KMOD_SHIFT | SDL_KMOD_CAPS, input->xkb.idx_mod5 | input->xkb.idx_shift | input->xkb.idx_caps },
|
||||||
|
{ SDL_KMOD_LEVEL5, input->xkb.idx_mod3 },
|
||||||
|
{ SDL_KMOD_LEVEL5 | SDL_KMOD_SHIFT, input->xkb.idx_mod3 | input->xkb.idx_shift },
|
||||||
|
{ SDL_KMOD_LEVEL5 | SDL_KMOD_CAPS, input->xkb.idx_mod3 | input->xkb.idx_caps },
|
||||||
|
{ SDL_KMOD_LEVEL5 | SDL_KMOD_SHIFT | SDL_KMOD_CAPS, input->xkb.idx_mod3 | input->xkb.idx_shift | input->xkb.idx_caps },
|
||||||
|
{ SDL_KMOD_LEVEL5 | SDL_KMOD_MODE, input->xkb.idx_mod3 | input->xkb.idx_mod5 },
|
||||||
|
{ SDL_KMOD_LEVEL5 | SDL_KMOD_MODE | SDL_KMOD_SHIFT, input->xkb.idx_mod3 | input->xkb.idx_mod5 | input->xkb.idx_shift },
|
||||||
|
{ SDL_KMOD_LEVEL5 | SDL_KMOD_MODE | SDL_KMOD_CAPS, input->xkb.idx_mod3 | input->xkb.idx_mod5 | input->xkb.idx_caps },
|
||||||
|
{ SDL_KMOD_LEVEL5 | SDL_KMOD_MODE | SDL_KMOD_SHIFT | SDL_KMOD_CAPS, input->xkb.idx_mod3 | input->xkb.idx_mod5 | input->xkb.idx_shift | input->xkb.idx_caps },
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!input->keyboard_is_virtual) {
|
if (!input->keyboard_is_virtual) {
|
||||||
|
@ -1350,7 +1381,7 @@ static void Wayland_UpdateKeymap(struct SDL_WaylandInput *input)
|
||||||
for (int i = 0; i < SDL_arraysize(keymod_masks); ++i) {
|
for (int i = 0; i < SDL_arraysize(keymod_masks); ++i) {
|
||||||
keymap.modstate = keymod_masks[i].sdl_mask;
|
keymap.modstate = keymod_masks[i].sdl_mask;
|
||||||
WAYLAND_xkb_state_update_mask(keymap.state,
|
WAYLAND_xkb_state_update_mask(keymap.state,
|
||||||
keymod_masks[i].xkb_mask & (input->xkb.idx_shift | input->xkb.idx_mode), 0, keymod_masks[i].xkb_mask & input->xkb.idx_caps,
|
keymod_masks[i].xkb_mask & (input->xkb.idx_shift | input->xkb.idx_mod5 | input->xkb.idx_mod3), 0, keymod_masks[i].xkb_mask & input->xkb.idx_caps,
|
||||||
0, 0, input->xkb.current_group);
|
0, 0, input->xkb.current_group);
|
||||||
WAYLAND_xkb_keymap_key_for_each(input->xkb.keymap,
|
WAYLAND_xkb_keymap_key_for_each(input->xkb.keymap,
|
||||||
Wayland_keymap_iter,
|
Wayland_keymap_iter,
|
||||||
|
@ -1413,7 +1444,8 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
|
||||||
input->xkb.idx_ctrl = 1 << GET_MOD_INDEX(CTRL);
|
input->xkb.idx_ctrl = 1 << GET_MOD_INDEX(CTRL);
|
||||||
input->xkb.idx_alt = 1 << GET_MOD_INDEX(ALT);
|
input->xkb.idx_alt = 1 << GET_MOD_INDEX(ALT);
|
||||||
input->xkb.idx_gui = 1 << GET_MOD_INDEX(LOGO);
|
input->xkb.idx_gui = 1 << GET_MOD_INDEX(LOGO);
|
||||||
input->xkb.idx_mode = 1 << GET_MOD_INDEX(MODE);
|
input->xkb.idx_mod3 = 1 << GET_MOD_INDEX(MOD3);
|
||||||
|
input->xkb.idx_mod5 = 1 << GET_MOD_INDEX(MOD5);
|
||||||
input->xkb.idx_num = 1 << GET_MOD_INDEX(NUM);
|
input->xkb.idx_num = 1 << GET_MOD_INDEX(NUM);
|
||||||
input->xkb.idx_caps = 1 << GET_MOD_INDEX(CAPS);
|
input->xkb.idx_caps = 1 << GET_MOD_INDEX(CAPS);
|
||||||
#undef GET_MOD_INDEX
|
#undef GET_MOD_INDEX
|
||||||
|
@ -1488,59 +1520,77 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
|
||||||
* Virtual keyboards can have arbitrary layouts, arbitrary scancodes/keycodes, etc...
|
* Virtual keyboards can have arbitrary layouts, arbitrary scancodes/keycodes, etc...
|
||||||
* Key presses from these devices must be looked up by their keysym value.
|
* Key presses from these devices must be looked up by their keysym value.
|
||||||
*/
|
*/
|
||||||
static SDL_Scancode Wayland_get_scancode_from_key(struct SDL_WaylandInput *input, uint32_t key)
|
static void Wayland_get_scancode_from_key(struct SDL_WaylandInput *input, uint32_t keycode, SDL_Scancode *scancode)
|
||||||
{
|
{
|
||||||
SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN;
|
const xkb_keysym_t *syms;
|
||||||
|
|
||||||
if (!input->keyboard_is_virtual) {
|
if (!input->keyboard_is_virtual) {
|
||||||
scancode = SDL_GetScancodeFromTable(SDL_SCANCODE_TABLE_XFREE86_2, key - 8);
|
*scancode = SDL_GetScancodeFromTable(SDL_SCANCODE_TABLE_XFREE86_2, keycode);
|
||||||
} else {
|
} else {
|
||||||
const xkb_keysym_t *syms;
|
if (WAYLAND_xkb_keymap_key_get_syms_by_level(input->xkb.keymap, keycode + 8, input->xkb.current_group, 0, &syms) > 0) {
|
||||||
if (WAYLAND_xkb_keymap_key_get_syms_by_level(input->xkb.keymap, key, input->xkb.current_group, 0, &syms) > 0) {
|
*scancode = SDL_GetScancodeFromKeySym(syms[0], keycode + 8);
|
||||||
scancode = SDL_GetScancodeFromKeySym(syms[0], key);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return scancode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Wayland_ReconcileModifiers(struct SDL_WaylandInput *input)
|
static void Wayland_ReconcileModifiers(struct SDL_WaylandInput *input, bool key_pressed)
|
||||||
{
|
{
|
||||||
// Handle pressed modifiers for virtual keyboards that may not send keystrokes.
|
/* Handle explicit pressed modifier state. This will correct the modifier state
|
||||||
if (input->keyboard_is_virtual) {
|
* if common modifier keys were remapped and the modifiers presumed to be set
|
||||||
|
* during a key press event were incorrect, or if the modifier was set to the
|
||||||
|
* pressed state via means other than pressing the physical key.
|
||||||
|
*/
|
||||||
|
if (!key_pressed) {
|
||||||
if (input->xkb.wl_pressed_modifiers & input->xkb.idx_shift) {
|
if (input->xkb.wl_pressed_modifiers & input->xkb.idx_shift) {
|
||||||
|
if (!(input->pressed_modifiers & SDL_KMOD_SHIFT)) {
|
||||||
input->pressed_modifiers |= SDL_KMOD_SHIFT;
|
input->pressed_modifiers |= SDL_KMOD_SHIFT;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
input->pressed_modifiers &= ~SDL_KMOD_SHIFT;
|
input->pressed_modifiers &= ~SDL_KMOD_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input->xkb.wl_pressed_modifiers & input->xkb.idx_ctrl) {
|
if (input->xkb.wl_pressed_modifiers & input->xkb.idx_ctrl) {
|
||||||
|
if (!(input->pressed_modifiers & SDL_KMOD_CTRL)) {
|
||||||
input->pressed_modifiers |= SDL_KMOD_CTRL;
|
input->pressed_modifiers |= SDL_KMOD_CTRL;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
input->pressed_modifiers &= ~SDL_KMOD_CTRL;
|
input->pressed_modifiers &= ~SDL_KMOD_CTRL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input->xkb.wl_pressed_modifiers & input->xkb.idx_alt) {
|
if (input->xkb.wl_pressed_modifiers & input->xkb.idx_alt) {
|
||||||
|
if (!(input->pressed_modifiers & SDL_KMOD_ALT)) {
|
||||||
input->pressed_modifiers |= SDL_KMOD_ALT;
|
input->pressed_modifiers |= SDL_KMOD_ALT;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
input->pressed_modifiers &= ~SDL_KMOD_ALT;
|
input->pressed_modifiers &= ~SDL_KMOD_ALT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input->xkb.wl_pressed_modifiers & input->xkb.idx_gui) {
|
if (input->xkb.wl_pressed_modifiers & input->xkb.idx_gui) {
|
||||||
|
if (!(input->pressed_modifiers & SDL_KMOD_GUI)) {
|
||||||
input->pressed_modifiers |= SDL_KMOD_GUI;
|
input->pressed_modifiers |= SDL_KMOD_GUI;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
input->pressed_modifiers &= ~SDL_KMOD_GUI;
|
input->pressed_modifiers &= ~SDL_KMOD_GUI;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input->xkb.wl_pressed_modifiers & input->xkb.idx_mode) {
|
if (input->xkb.wl_pressed_modifiers & input->xkb.idx_mod3) {
|
||||||
|
if (!(input->pressed_modifiers & SDL_KMOD_LEVEL5)) {
|
||||||
|
input->pressed_modifiers |= SDL_KMOD_LEVEL5;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
input->pressed_modifiers &= ~SDL_KMOD_LEVEL5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input->xkb.wl_pressed_modifiers & input->xkb.idx_mod5) {
|
||||||
|
if (!(input->pressed_modifiers & SDL_KMOD_MODE)) {
|
||||||
input->pressed_modifiers |= SDL_KMOD_MODE;
|
input->pressed_modifiers |= SDL_KMOD_MODE;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
input->pressed_modifiers &= ~SDL_KMOD_MODE;
|
input->pressed_modifiers &= ~SDL_KMOD_MODE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* If a latch or lock was activated by a keypress, the latch/lock will
|
||||||
* If a latch or lock was activated by a keypress, the latch/lock will
|
|
||||||
* be tied to the specific left/right key that initiated it. Otherwise,
|
* be tied to the specific left/right key that initiated it. Otherwise,
|
||||||
* the ambiguous left/right combo is used.
|
* the ambiguous left/right combo is used.
|
||||||
*
|
*
|
||||||
|
@ -1591,7 +1641,16 @@ static void Wayland_ReconcileModifiers(struct SDL_WaylandInput *input)
|
||||||
input->locked_modifiers &= ~SDL_KMOD_GUI;
|
input->locked_modifiers &= ~SDL_KMOD_GUI;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input->xkb.wl_locked_modifiers & input->xkb.idx_mode) {
|
/* The Mod3 modifier corresponds to no particular SDL keycode, so it is
|
||||||
|
* only activated by the backend modifier callback.
|
||||||
|
*/
|
||||||
|
if (input->xkb.wl_locked_modifiers & input->xkb.idx_mod3) {
|
||||||
|
input->locked_modifiers |= SDL_KMOD_LEVEL5;
|
||||||
|
} else {
|
||||||
|
input->locked_modifiers &= ~SDL_KMOD_LEVEL5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input->xkb.wl_locked_modifiers & input->xkb.idx_mod5) {
|
||||||
input->locked_modifiers |= SDL_KMOD_MODE;
|
input->locked_modifiers |= SDL_KMOD_MODE;
|
||||||
} else {
|
} else {
|
||||||
input->locked_modifiers &= ~SDL_KMOD_MODE;
|
input->locked_modifiers &= ~SDL_KMOD_MODE;
|
||||||
|
@ -1618,6 +1677,12 @@ static void Wayland_HandleModifierKeys(struct SDL_WaylandInput *input, SDL_Scanc
|
||||||
const SDL_Keycode keycode = SDL_GetKeyFromScancode(scancode, SDL_KMOD_NONE, false);
|
const SDL_Keycode keycode = SDL_GetKeyFromScancode(scancode, SDL_KMOD_NONE, false);
|
||||||
SDL_Keymod mod;
|
SDL_Keymod mod;
|
||||||
|
|
||||||
|
/* SDL clients expect modifier state to be activated at the same time as the
|
||||||
|
* source keypress, so we set pressed modifier state with the usual modifier
|
||||||
|
* keys here, as the explicit modifier event won't arrive until after the
|
||||||
|
* keypress event. If this is wrong, it will be corrected when the explicit
|
||||||
|
* modifier state is sent at a later time.
|
||||||
|
*/
|
||||||
switch (keycode) {
|
switch (keycode) {
|
||||||
case SDLK_LSHIFT:
|
case SDLK_LSHIFT:
|
||||||
mod = SDL_KMOD_LSHIFT;
|
mod = SDL_KMOD_LSHIFT;
|
||||||
|
@ -1656,7 +1721,7 @@ static void Wayland_HandleModifierKeys(struct SDL_WaylandInput *input, SDL_Scanc
|
||||||
input->pressed_modifiers &= ~mod;
|
input->pressed_modifiers &= ~mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
Wayland_ReconcileModifiers(input);
|
Wayland_ReconcileModifiers(input, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
|
static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
|
||||||
|
@ -1694,7 +1759,9 @@ static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
|
||||||
window->last_focus_event_time_ns = timestamp;
|
window->last_focus_event_time_ns = timestamp;
|
||||||
|
|
||||||
wl_array_for_each (key, keys) {
|
wl_array_for_each (key, keys) {
|
||||||
const SDL_Scancode scancode = Wayland_get_scancode_from_key(input, *key + 8);
|
SDL_Scancode scancode;
|
||||||
|
|
||||||
|
Wayland_get_scancode_from_key(input, *key, &scancode);
|
||||||
const SDL_Keycode keycode = SDL_GetKeyFromScancode(scancode, SDL_KMOD_NONE, false);
|
const SDL_Keycode keycode = SDL_GetKeyFromScancode(scancode, SDL_KMOD_NONE, false);
|
||||||
|
|
||||||
switch (keycode) {
|
switch (keycode) {
|
||||||
|
@ -1842,7 +1909,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
|
||||||
keyboard_input_get_text(text, input, key, false, &handled_by_ime);
|
keyboard_input_get_text(text, input, key, false, &handled_by_ime);
|
||||||
}
|
}
|
||||||
|
|
||||||
scancode = Wayland_get_scancode_from_key(input, key + 8);
|
Wayland_get_scancode_from_key(input, key, &scancode);
|
||||||
Wayland_HandleModifierKeys(input, scancode, state == WL_KEYBOARD_KEY_STATE_PRESSED);
|
Wayland_HandleModifierKeys(input, scancode, state == WL_KEYBOARD_KEY_STATE_PRESSED);
|
||||||
Uint64 timestamp = Wayland_GetKeyboardTimestamp(input, time);
|
Uint64 timestamp = Wayland_GetKeyboardTimestamp(input, time);
|
||||||
SDL_SendKeyboardKeyIgnoreModifiers(timestamp, input->keyboard_id, key, scancode, (state == WL_KEYBOARD_KEY_STATE_PRESSED));
|
SDL_SendKeyboardKeyIgnoreModifiers(timestamp, input->keyboard_id, key, scancode, (state == WL_KEYBOARD_KEY_STATE_PRESSED));
|
||||||
|
@ -1878,7 +1945,7 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
|
||||||
input->xkb.wl_pressed_modifiers = mods_depressed;
|
input->xkb.wl_pressed_modifiers = mods_depressed;
|
||||||
input->xkb.wl_locked_modifiers = mods_latched | mods_locked;
|
input->xkb.wl_locked_modifiers = mods_latched | mods_locked;
|
||||||
|
|
||||||
Wayland_ReconcileModifiers(input);
|
Wayland_ReconcileModifiers(input, false);
|
||||||
|
|
||||||
// If a key is repeating, update the text to apply the modifier.
|
// If a key is repeating, update the text to apply the modifier.
|
||||||
if (keyboard_repeat_is_set(&input->keyboard_repeat)) {
|
if (keyboard_repeat_is_set(&input->keyboard_repeat)) {
|
||||||
|
|
|
@ -114,7 +114,8 @@ struct SDL_WaylandInput
|
||||||
uint32_t idx_ctrl;
|
uint32_t idx_ctrl;
|
||||||
uint32_t idx_alt;
|
uint32_t idx_alt;
|
||||||
uint32_t idx_gui;
|
uint32_t idx_gui;
|
||||||
uint32_t idx_mode;
|
uint32_t idx_mod3;
|
||||||
|
uint32_t idx_mod5;
|
||||||
uint32_t idx_num;
|
uint32_t idx_num;
|
||||||
uint32_t idx_caps;
|
uint32_t idx_caps;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue