Send modifiers keyboard.key additionaly to keyboard.modifiers

At the moment we just use keyboard.modifiers to maintain our clients
modifiers states. But we should also send the associated key codes.
Clients like wlvncc need them to actually send the keys to the remote
compositor.

We got no clear way to map our modifier enums to key codes. So I added
this zwp_virtual_keyboard_v1_key_mods method.

I think I tried most of the use-cases. The hardest part was arround the
Shift+Space that send Tab. We have to depress the Shift key, reset the
modifiers, send the Tab key, and finally depress back Shift and its
modifier.

I've tested a bit the Code with .code_mod (and .reset_mod), but I'm not
that sure what their behavior should be.

Signed-off-by: Maarten van Gompel <proycon@anaproy.nl>
This commit is contained in:
Willow Barraco
2025-04-17 18:00:31 +02:00
committed by Maarten van Gompel
parent f0c99d276a
commit b0eff37239

View File

@@ -274,12 +274,28 @@ kbd_get_layer_index(struct kbd *kb, struct layout *l)
return 0; return 0;
} }
void
zwp_virtual_keyboard_v1_key_mods(struct zwp_virtual_keyboard_v1 *vkbd, uint32_t time, uint32_t mods, enum wl_keyboard_key_state state)
{
if ((mods & Shift) == Shift)
zwp_virtual_keyboard_v1_key(vkbd, time, KEY_LEFTSHIFT, state);
if ((mods & CapsLock) == CapsLock)
zwp_virtual_keyboard_v1_key(vkbd, time, KEY_CAPSLOCK, state);
if ((mods & Ctrl) == Ctrl)
zwp_virtual_keyboard_v1_key(vkbd, time, KEY_LEFTCTRL, state);
if ((mods & Alt) == Alt)
zwp_virtual_keyboard_v1_key(vkbd, time, KEY_LEFTALT, state);
if ((mods & Super) == Super)
zwp_virtual_keyboard_v1_key(vkbd, time, KEY_LEFTMETA, state);
if ((mods & AltGr) == AltGr)
zwp_virtual_keyboard_v1_key(vkbd, time, KEY_RIGHTALT, state);
}
void void
kbd_unpress_key(struct kbd *kb, uint32_t time) kbd_unpress_key(struct kbd *kb, uint32_t time)
{ {
bool unlatch_shift, unlatch_ctrl, unlatch_alt, unlatch_super, unlatch_altgr; bool unlatch_shift, unlatch_ctrl, unlatch_alt, unlatch_super, unlatch_altgr, unlatch_tab;
unlatch_shift = unlatch_ctrl = unlatch_alt = unlatch_super = unlatch_altgr = false; unlatch_shift = unlatch_ctrl = unlatch_alt = unlatch_super = unlatch_altgr = unlatch_tab = false;
if (kb->last_press) { if (kb->last_press) {
unlatch_shift = (kb->mods & Shift) == Shift; unlatch_shift = (kb->mods & Shift) == Shift;
unlatch_ctrl = (kb->mods & Ctrl) == Ctrl; unlatch_ctrl = (kb->mods & Ctrl) == Ctrl;
@@ -287,22 +303,15 @@ kbd_unpress_key(struct kbd *kb, uint32_t time)
unlatch_super = (kb->mods & Super) == Super; unlatch_super = (kb->mods & Super) == Super;
unlatch_altgr = (kb->mods & AltGr) == AltGr; unlatch_altgr = (kb->mods & AltGr) == AltGr;
if (unlatch_shift) kb->mods ^= Shift;
if (unlatch_ctrl) kb->mods ^= Ctrl;
if (unlatch_alt) kb->mods ^= Alt;
if (unlatch_super) kb->mods ^= Super;
if (unlatch_altgr) kb->mods ^= AltGr;
if (unlatch_shift||unlatch_ctrl||unlatch_alt||unlatch_super||unlatch_altgr) {
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, kb->mods, 0, 0, 0);
}
if (kb->last_press->type == Copy) { if (kb->last_press->type == Copy) {
zwp_virtual_keyboard_v1_key(kb->vkbd, time, 127, // COMP key zwp_virtual_keyboard_v1_key(kb->vkbd, time, 127, // COMP key
WL_KEYBOARD_KEY_STATE_RELEASED); WL_KEYBOARD_KEY_STATE_RELEASED);
} else { } else {
if ((kb->shift_space_is_tab) && (kb->last_press->code == KEY_SPACE) && (unlatch_shift)) { if ((kb->shift_space_is_tab) && (kb->last_press->code == KEY_SPACE) && (unlatch_shift)) {
// shift + space is tab // shift + space is tab
unlatch_shift = false;
unlatch_tab = true;
kb->mods ^= Shift;
zwp_virtual_keyboard_v1_key(kb->vkbd, time, KEY_TAB, zwp_virtual_keyboard_v1_key(kb->vkbd, time, KEY_TAB,
WL_KEYBOARD_KEY_STATE_RELEASED); WL_KEYBOARD_KEY_STATE_RELEASED);
} else { } else {
@@ -312,10 +321,35 @@ kbd_unpress_key(struct kbd *kb, uint32_t time)
} }
} }
if (unlatch_shift) {
kb->mods ^= Shift;
zwp_virtual_keyboard_v1_key_mods(kb->vkbd, time, Shift, WL_KEYBOARD_KEY_STATE_RELEASED);
}
if (unlatch_ctrl) {
kb->mods ^= Ctrl;
zwp_virtual_keyboard_v1_key_mods(kb->vkbd, time, Ctrl, WL_KEYBOARD_KEY_STATE_RELEASED);
}
if (unlatch_alt) {
kb->mods ^= Alt;
zwp_virtual_keyboard_v1_key_mods(kb->vkbd, time, Alt, WL_KEYBOARD_KEY_STATE_RELEASED);
}
if (unlatch_super) {
kb->mods ^= Super;
zwp_virtual_keyboard_v1_key_mods(kb->vkbd, time, Super, WL_KEYBOARD_KEY_STATE_RELEASED);
}
if (unlatch_altgr) {
kb->mods ^= AltGr;
zwp_virtual_keyboard_v1_key_mods(kb->vkbd, time, AltGr, WL_KEYBOARD_KEY_STATE_RELEASED);
}
if (unlatch_shift||unlatch_ctrl||unlatch_alt||unlatch_super||unlatch_altgr||unlatch_tab) {
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, kb->mods, 0, 0, 0);
}
if (kb->compose >= 2) { if (kb->compose >= 2) {
kb->compose = 0; kb->compose = 0;
kbd_switch_layout(kb, kb->last_abc_layout, kb->last_abc_index); kbd_switch_layout(kb, kb->last_abc_layout, kb->last_abc_index);
} else if (unlatch_shift||unlatch_ctrl||unlatch_alt||unlatch_super||unlatch_altgr) { } else if (unlatch_shift||unlatch_ctrl||unlatch_alt||unlatch_super||unlatch_altgr||unlatch_tab) {
kbd_draw_layout(kb); kbd_draw_layout(kb);
} else { } else {
kbd_draw_key(kb, kb->last_press, Unpress); kbd_draw_key(kb, kb->last_press, Unpress);
@@ -392,6 +426,7 @@ kbd_press_key(struct kbd *kb, struct key *k, uint32_t time)
switch (k->type) { switch (k->type) {
case Code: case Code:
if (k->code_mod) { if (k->code_mod) {
zwp_virtual_keyboard_v1_key_mods(kb->vkbd, time, k->code_mod, WL_KEYBOARD_KEY_STATE_PRESSED);
if (k->reset_mod) { if (k->reset_mod) {
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, k->code_mod, 0, 0, zwp_virtual_keyboard_v1_modifiers(kb->vkbd, k->code_mod, 0, 0,
0); 0);
@@ -406,7 +441,8 @@ kbd_press_key(struct kbd *kb, struct key *k, uint32_t time)
kbd_draw_key(kb, k, Press); kbd_draw_key(kb, k, Press);
if ((kb->shift_space_is_tab) && (k->code == KEY_SPACE) && (kb->mods & Shift)) { if ((kb->shift_space_is_tab) && (k->code == KEY_SPACE) && (kb->mods & Shift)) {
// shift space is tab // shift space is tab
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, 0, 0, 0, 0); zwp_virtual_keyboard_v1_key_mods(kb->vkbd, time, Shift, WL_KEYBOARD_KEY_STATE_RELEASED);
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, kb->mods ^ Shift, 0, 0, 0);
zwp_virtual_keyboard_v1_key(kb->vkbd, time, KEY_TAB, zwp_virtual_keyboard_v1_key(kb->vkbd, time, KEY_TAB,
WL_KEYBOARD_KEY_STATE_PRESSED); WL_KEYBOARD_KEY_STATE_PRESSED);
} else { } else {
@@ -423,6 +459,11 @@ kbd_press_key(struct kbd *kb, struct key *k, uint32_t time)
break; break;
case Mod: case Mod:
kb->mods ^= k->code; kb->mods ^= k->code;
if (kb->mods & k->code) {
zwp_virtual_keyboard_v1_key_mods(kb->vkbd, time, k->code, WL_KEYBOARD_KEY_STATE_PRESSED);
} else {
zwp_virtual_keyboard_v1_key_mods(kb->vkbd, time, k->code, WL_KEYBOARD_KEY_STATE_RELEASED);
}
if ((k->code == Shift) || (k->code == CapsLock)) { if ((k->code == Shift) || (k->code == CapsLock)) {
kbd_draw_layout(kb); kbd_draw_layout(kb);
} else { } else {