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

Implement input method keyboard grab #4932

Merged
merged 5 commits into from
Mar 12, 2021

Conversation

xdavidwu
Copy link
Contributor

@xdavidwu xdavidwu commented Jan 21, 2020

This implements input-method-unstable-v2 keyboard grab.

Depends on: #4740, swaywm/wlroots#1864

@emersion emersion changed the title Implement input method keyboard grab [WIP] Implement input method keyboard grab Jan 21, 2020
@xhebox
Copy link

xhebox commented Feb 13, 2020

There're two problems of handle_key patch in 7471b43, i've modified a patch.

  1. Update_short_cuts or what else code probably messed around the state, so that i can not receive release key event from the grab interface.

  2. Even if i move the check to the most front, bypass all sway code. There's something wrong with it:

-       if (!handled && wlr_device->keyboard->group) {
+       if (!handled && wlr_device->keyboard->group && !virtual_keyboard) {
                // Only handle device specific bindings for keyboards in a group

As virtual_keyboard and real keyboard compose a keyboard_group, sway early return here. But we only use virtual_keyboard under grab, so it's essentially one keyboard.

The workaround patch is attached at the end.

EDIT: There are problems in swaywm/wlroots#1864 too.

EDIT2: handle_modifier has similar problems on keyboard_group.

@@ -329,6 +329,18 @@
        seat_idle_notify_activity(seat, IDLE_SOURCE_KEYBOARD);
        bool input_inhibited = seat->exclusive_client != NULL;
 
+       struct wlr_input_method_keyboard_grab_v2 *kb_grab =
+               seat->im_relay.input_method ? seat->im_relay.input_method->im_keyboard_grab : NULL;
+       struct wlr_virtual_keyboard_v1 *virtual_keyboard =
+               wlr_device->keyboard->virtual_keyboard;
+
+       if (seat->im_relay.input_method && kb_grab && !virtual_keyboard) {
+               wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab,
+                       wlr_device->keyboard);
+               wlr_input_method_keyboard_grab_v2_send_key(kb_grab,
+                       event->time_msec, event->keycode, event->state);
+       } else {
+
        // Identify new keycode, raw keysym(s), and translated keysym(s)
        xkb_keycode_t keycode = event->keycode + 8;
 
@@ -423,7 +435,7 @@
                handled = true;
        }
 
-       if (!handled && wlr_device->keyboard->group) {
+       if (!handled && wlr_device->keyboard->group && !virtual_keyboard) {
                // Only handle device specific bindings for keyboards in a group
                free(device_identifier);
                return;
@@ -451,6 +463,8 @@
                }
        }
 
+       }
+
        transaction_commit_dirty();
 
        free(device_identifier);

@xdavidwu
Copy link
Contributor Author

Update_short_cuts or what else code probably messed around the state, so that i can not receive release key event from the grab interface.

Not all release events are missing, right? According to my tests, release events are sent successfully at most cases. Sometime release events seems still somewhat missing like I uses Mod4 as my binding modifiers, but when I switches workspace, sometime Mod4 seems like get stuck and needs an extra press to solve it after this patch. I am still investigating this situation.

The problems with keyboard grouping is explained at swaywm/wlroots#1864 (comment)

@xhebox
Copy link

xhebox commented Feb 14, 2020

My test IME will forward grab by virtual_keyboard immediately(i.e. just after receiving the key event).

Not all release events are missing, right?

Nope, all events are missing, with keyboard_group. I pressed the f, and seems it's marked as pressed, and I could not press f again. Extra presses never got me out the problem. I need a complete restart of sway.

Now with seat * keyboard_grouping none, it works almost perfectly. The problem must be related to the behavior of keyboard_group.

And the imperfect part is that, when I started IME in a terminal, and press CTRL+C, I missed the release event of CTRL+C(IME is killed by SIGINT). So the corresponding release event was not forwarded by virtual_keyboard. The result is that, I saw lots of ccccccccccccc in the terminal until i pressed c again.

This could be a responsibility of clients, but it will be nice if sway handle it.

EDIT: I am using musl-libc, with sway -d.

@xdavidwu
Copy link
Contributor Author

And the imperfect part is that, when I started IME(forward grab by virtual_keyboard) in a terminal, and press CTRL+C, I missed the release event of CTRL+C. So the corresponding release event was not forwarded by virtual_keyboard. The result is that, I am seeing lots of ccccccccccccc in the terminal untile i pressed c again.

Terminals kill the IME at the time it received press event, and when release event arrives, IME is already gone. Currently virtual-keyboard implementation does not send missing release event when it is gone. I think IME should handle SIGINT to be safe.

@xhebox
Copy link

xhebox commented Feb 14, 2020

Yep, if virtual-keyboard handle it, then we need some records at the side of wlroots. Sounds like what you say pressed event sent state tracking. And with pressed event sent state tracking, grab could be moved to wlroots too.

Whatever it is not a big problem compared to missing events. Both solutions are ok though. It is just, program could be killed by various signals, it's hard to handle all cases. Exceptions could kill IME too.

Even IME handle this smoothly. If SIGKILL signal the program at similar time point, then program has no way to handle it at all. It is not asynchronously safe.

@xdavidwu
Copy link
Contributor Author

I have just made virtual keyboard not to group when from same client as input method and also check and remove on grab start. It should make it work with keyboard grouping enabled but I think this can still be improved.

@xdavidwu xdavidwu force-pushed the input-method-keyboard-grab branch from 91551bb to 691da5a Compare February 27, 2020 04:49
@emersion
Copy link
Member

Tested with wlhangul, seems to work fine.

@xdavidwu xdavidwu force-pushed the input-method-keyboard-grab branch from 691da5a to b0558db Compare March 11, 2020 13:37
@Leo1003 Leo1003 force-pushed the input-method-keyboard-grab branch from b0558db to a789c11 Compare March 24, 2020 15:37
@emersion
Copy link
Member

emersion commented Apr 6, 2020

This PR needs a rebase.

@xdavidwu xdavidwu force-pushed the input-method-keyboard-grab branch 2 times, most recently from 321f7f2 to 02c876d Compare April 14, 2020 14:24
@xdavidwu
Copy link
Contributor Author

Commit to ungroup virtual keyboard is dropped. It is not needed after #5204.

@xdavidwu xdavidwu force-pushed the input-method-keyboard-grab branch from 02c876d to f77d7ca Compare May 12, 2020 14:03
@xdavidwu xdavidwu force-pushed the input-method-keyboard-grab branch from f77d7ca to ed0398c Compare July 8, 2020 06:48
@emersion
Copy link
Member

emersion commented Jul 8, 2020

Is this still WIP?

@xdavidwu xdavidwu force-pushed the input-method-keyboard-grab branch 2 times, most recently from dc15b85 to 6bbf0ee Compare July 10, 2020 09:00
@xdavidwu xdavidwu changed the title [WIP] Implement input method keyboard grab Implement input method keyboard grab Jul 10, 2020
@xdavidwu xdavidwu marked this pull request as ready for review July 10, 2020 09:04
@emersion emersion self-requested a review July 31, 2020 13:23
simnalamburt added a commit to simnalamburt/kime that referenced this pull request Feb 5, 2021
With input-method-unstable-v2, it's impossible to finish preedit texts
before deactivate.

    I think this is a bug in IME. Focus changes deactivates the
    input-method and I think there is no way to know it is going to be
    deactivated in advance. Which means IME does not have chance to
    commit string to old text-input. Also, by the protocol, there is no
    way to distinguish the text-input behind. With these, I think IME
    should reset their internal states (for example, to-be-committed
    string) on deactivate. This is what my wlchewing does, and so it
    does not have this bug.

    @xdavidwu

Reference:
  swaywm/sway#4932 (comment)
Riey pushed a commit to Riey/kime that referenced this pull request Feb 5, 2021
With input-method-unstable-v2, it's impossible to finish preedit texts
before deactivate.

    I think this is a bug in IME. Focus changes deactivates the
    input-method and I think there is no way to know it is going to be
    deactivated in advance. Which means IME does not have chance to
    commit string to old text-input. Also, by the protocol, there is no
    way to distinguish the text-input behind. With these, I think IME
    should reset their internal states (for example, to-be-committed
    string) on deactivate. This is what my wlchewing does, and so it
    does not have this bug.

    @xdavidwu

Reference:
  swaywm/sway#4932 (comment)
@simnalamburt
Copy link

Thank you! I could workaround the "Focus change bug" and fix the "Key repeat bug". This PR is currently being thoroughly tested by bunch of Korean sway users and now we're all experiencing no more bugs!

Is there any left blocker before merging this PR? Looks like the keymap spamming issue has been fixed with latest commit since it doesn't occur anymore!

simnalamburt added a commit to simnalamburt/kime that referenced this pull request Feb 5, 2021
Key repeat of bypassed key shouldn't be handled by IME.

Reference:
  swaywm/sway#4932 (comment)
simnalamburt added a commit to simnalamburt/kime that referenced this pull request Feb 5, 2021
Key repeat of bypassed key shouldn't be handled by IME.

Reference:
  swaywm/sway#4932 (comment)
simnalamburt added a commit to simnalamburt/kime that referenced this pull request Feb 5, 2021
Key repeat of bypassed key shouldn't be handled by IME.

Reference:
  swaywm/sway#4932 (comment)
@Riey
Copy link

Riey commented Feb 6, 2021

I'm maintain new Korean IME kime and I met several repeat bugs of course it's IME bug but problem is its repeat was triggered in client side which is unexpected behavior for me

Why client get RepeatInfo even keyboard is grabbed? is it necessary?

@tadeokondrak
Copy link
Contributor

tadeokondrak commented Feb 8, 2021

I think there still is a different focus change bug in sway that lets an unfocused surface disable text-input, but it's related to text-input and not input-method, and is not related to keyboard grab.

EDIT: #6004 for layer-shell, #6005 for the above issue.

@simnalamburt
Copy link

Yeah I think this patch itself is enough tested and reviewed by bunch of people who desperately want to use IME with sway. :)

@fosskers
Copy link

I've seen the patched AUR package with this added. How is this actually configured and used? Please and thanks :)

@simnalamburt
Copy link

Just install patched version of sway and turn on the IME which have input-method-unstable-v2 supports like kime, fcitx5. Then it automatically works.

For Arch Linux with kime:

# Install two AUR: sway-im and kime-bin
paru -S sway-im kime-bin

# Run kime
systemd-run --user -du kime kime-wayland

# Run sway
sway
Reference

@fosskers
Copy link

fosskers commented Mar 1, 2021

I did manage to get fcitx5 working without a patched sway. Although I still can't type in alacritty for some reason.

@tadeokondrak
Copy link
Contributor

I did manage to get fcitx5 working without a patched sway. Although I still can't type in alacritty for some reason.

This is because some applications also support IME input without going through the window system, using (for example) D-Bus instead of X11 or Wayland. Alacritty only supports X11 (xim) and Wayland (text-input-v3) IMEs directly, as far as I know.

Copy link
Member

@emersion emersion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been trying to review this for quite some time. I'm really sorry for the huge delay, once again.

Overall the logic looks correct to me.

I have trouble with the changes in handle_key_event. This function is already a little bit tricky to follow, and the changes introduce more complexity (duplicated wlr_seat_keyboard_notify_key, goto end). I've left some comments to see if we can improve that a bit.

In other news, we're trying to revive the IM standardization efforts in the wayland-protocols repo. If you have feedback about text-input or input-method, please feel free to leave a comment:

https://gitlab.freedesktop.org/wayland/wayland-protocols/-/issues/39

sway/input/keyboard.c Outdated Show resolved Hide resolved
sway/input/keyboard.c Outdated Show resolved Hide resolved
@xdavidwu xdavidwu force-pushed the input-method-keyboard-grab branch from 9755086 to e397ebc Compare March 12, 2021 03:25
sway/input/keyboard.c Outdated Show resolved Hide resolved
Copy link
Member

@emersion emersion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, thanks a lot!

@emersion emersion merged commit e5913f8 into swaywm:master Mar 12, 2021
agx pushed a commit to agx/phoc that referenced this pull request Mar 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

9 participants