Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send modifiers to the Wayland server when a modifier key event needs to be forwarded #1292

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

fortime
Copy link

@fortime fortime commented Mar 5, 2025

I'm using kwin 6 with wayland enabled, and I'm writing a virtual keyboard using the org.fcitx.Fcitx5.VirtualKeyboardBackend1 interface. Currently, a modifier key event is forwarded to the wayland server through wl_keyboard::key. This doesn't work, at least in kwin 6. I think the correct way is using wl_keyboard::modifiers.

My virtual keyboard works well with this patch.

This paragraph is composed using my virtual keyboard. Uppercase letters can be inputted since Shift works. 中文輸入也可以。

… key event needs to be forwarded.

Signed-off-by: fortime <[email protected]>
@fortime
Copy link
Author

fortime commented Mar 11, 2025

@wengxt can you have a review on this pr?

@wengxt
Copy link
Member

wengxt commented Mar 11, 2025

the implementation should map modifier key -> key code from keymap with xkbcommon, instead of hardcode key code.

@fortime
Copy link
Author

fortime commented Mar 11, 2025

the implementation should map modifier key -> key code from keymap with xkbcommon, instead of hardcode key code.

Sorry, I'm new to xkbcommon. I can't find out which api I should use.

I have tried to use xkb_keymap_key_get_name to get a name associated to a keycode, and then use xkb_keymap_mod_get_index to get the modifier index. But, the name associated to a keycode and the name of a modifier are different.

For example, the name of keycode 50 is "LFSH", and I use "LFSH" to get the modifier index, it returns XKB_MOD_INVALID.

@wengxt
Copy link
Member

wengxt commented Mar 11, 2025

The reason to use xkbcommon for it , is because, for example, xkb option may allow to do things like "swap capslock & ctrl", in that case, key code will be same for the key. Your implementation will be sending the wrong key.

The logic should be like:

  1. A loop to enumerate over all key code, can be done with either: for ( keycode : range(xkb_keymap_min_keycode, xkb_keymap_max_keycode)), or xkb_keymap_key_for_each.
  2. For each keycode, query with xkb_keymap_key_get_syms_by_level & xkb_keymap_key_get_mods_for_level, this allows you to query the mods(key state, modifier) & syms what a keycode can produce. You may want to pre-compute on keymap update instead of re-calculate every time you need to.
  3. Send the corresponding key code.

@fortime
Copy link
Author

fortime commented Mar 12, 2025

2. For each keycode, query with xkb_keymap_key_get_syms_by_level & xkb_keymap_key_get_mods_for_level, this allows you to query the mods(key state, modifier) & syms what a keycode can produce. You may want to pre-compute on keymap update instead of re-calculate every time you need to.

Do you mean I should use key sym to check if it is a modifier?

  1. In the beginning, I should hardcode a key sym to a modifier name (or a modifier index) mapping. Such as "Caps_Lock" -> "Lock".
  2. Then, I loop over all key codes to find out all (key code + modifiers)s generating those key syms.
  3. Finally, when a key code is forwarded, I use this key code and currently effectively modifiers to check if it is a modifier event.

Is it correct?

@wengxt
Copy link
Member

wengxt commented Mar 12, 2025

@fortime well.. you shouldn't really assume, Control_L/R keysyms can produce Control modifier state. They are actually two separate concept.

The code to pick the key when xkb_keymap_key_get_syms_by_level has the desired keysym and verify with xkb_state_update_key can really produce the relevant mask

…update_mask` and `xkb_state_update_key` to find all keycodes which changes modifiers.

Signed-off-by: fortime <[email protected]>
@fortime
Copy link
Author

fortime commented Mar 17, 2025

@wengxt can you check whether it is the logic you mean in the new commit?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants