Skip to content

Commit

Permalink
Implement input method keyboard grab
Browse files Browse the repository at this point in the history
  • Loading branch information
affenull2345 committed Mar 1, 2023
1 parent 844200e commit 5b6185d
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 8 deletions.
56 changes: 48 additions & 8 deletions src/keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,29 @@ keyboard_keysyms_raw(PhocKeyboard *self,
keycode, layout_index, 0, keysyms);
}

static struct wlr_input_method_keyboard_grab_v2 *
phoc_keyboard_get_grab (PhocKeyboard *self)
{
PhocInputDevice *input_device = PHOC_INPUT_DEVICE (self);
PhocSeat *seat = phoc_input_device_get_seat (input_device);
struct wlr_input_device *device = phoc_input_device_get_device (input_device);
struct wlr_input_method_v2 *input_method = seat->im_relay.input_method;
struct wlr_virtual_keyboard_v1 *virtual_keyboard =
wlr_input_device_get_virtual_keyboard (device);

if (!input_method || !input_method->keyboard_grab)
return NULL;

// Do not forward virtual events back to the client that generated them
if (virtual_keyboard
&& wl_resource_get_client (input_method->keyboard_grab->resource)
== wl_resource_get_client (virtual_keyboard->resource)) {
return NULL;
}

return input_method->keyboard_grab;
}

static void
phoc_keyboard_handle_key (PhocKeyboard *self, struct wlr_event_keyboard_key *event)
{
Expand Down Expand Up @@ -339,24 +362,41 @@ phoc_keyboard_handle_key (PhocKeyboard *self, struct wlr_event_keyboard_key *eve

if (!handled) {
PhocInputDevice *input_device = PHOC_INPUT_DEVICE (self);
PhocSeat *seat = phoc_input_device_get_seat (input_device);
struct wlr_input_device *device = phoc_input_device_get_device (input_device);

wlr_seat_set_keyboard(seat->seat, device);
wlr_seat_keyboard_notify_key(seat->seat, event->time_msec,
event->keycode, event->state);
struct wlr_input_method_keyboard_grab_v2 *grab = phoc_keyboard_get_grab (self);

if (grab) {
wlr_input_method_keyboard_grab_v2_set_keyboard (grab, device->keyboard);
wlr_input_method_keyboard_grab_v2_send_key (grab,
event->time_msec,
event->keycode,
event->state);
} else {
PhocSeat *seat = phoc_input_device_get_seat (input_device);
wlr_seat_set_keyboard (seat->seat, device);
wlr_seat_keyboard_notify_key (seat->seat,
event->time_msec,
event->keycode,
event->state);
}
}
}

static void
phoc_keyboard_handle_modifiers(PhocKeyboard *self)
{
PhocInputDevice *input_device = PHOC_INPUT_DEVICE (self);
PhocSeat *seat = phoc_input_device_get_seat (input_device);
struct wlr_input_device *device = phoc_input_device_get_device (input_device);
struct wlr_input_method_keyboard_grab_v2 *grab = phoc_keyboard_get_grab (self);

wlr_seat_set_keyboard(seat->seat, device);
wlr_seat_keyboard_notify_modifiers(seat->seat, &device->keyboard->modifiers);
if (grab) {
wlr_input_method_keyboard_grab_v2_set_keyboard (grab, device->keyboard);
wlr_input_method_keyboard_grab_v2_send_modifiers (grab, &device->keyboard->modifiers);
} else {
PhocSeat *seat = phoc_input_device_get_seat (input_device);
wlr_seat_set_keyboard (seat->seat, device);
wlr_seat_keyboard_notify_modifiers (seat->seat, &device->keyboard->modifiers);
}
}


Expand Down
33 changes: 33 additions & 0 deletions src/text_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,36 @@ static void handle_im_commit(struct wl_listener *listener, void *data) {
wlr_text_input_v3_send_done(text_input->input);
}

static void
handle_im_keyboard_grab_destroy (struct wl_listener *listener, void *data)
{
PhocInputMethodRelay *relay =
wl_container_of (listener, relay, input_method_keyboard_grab_destroy);
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data;

wl_list_remove (&relay->input_method_keyboard_grab_destroy.link);

if (keyboard_grab->keyboard) {
// send modifier state to original client
wlr_seat_keyboard_notify_modifiers (keyboard_grab->input_method->seat,
&keyboard_grab->keyboard->modifiers);
}
}

static void
handle_im_grab_keyboard (struct wl_listener *listener, void *data)
{
PhocInputMethodRelay *relay =
wl_container_of (listener, relay, input_method_grab_keyboard);
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data;

// send modifier state to grab
struct wlr_keyboard *active_keyboard = wlr_seat_get_keyboard (relay->seat->seat);
wlr_input_method_keyboard_grab_v2_set_keyboard (keyboard_grab, active_keyboard);

wl_signal_add (&keyboard_grab->events.destroy, &relay->input_method_keyboard_grab_destroy);
relay->input_method_keyboard_grab_destroy.notify = handle_im_keyboard_grab_destroy;
}

static void text_input_clear_pending_focused_surface(
PhocTextInput *text_input) {
Expand Down Expand Up @@ -314,6 +344,9 @@ relay_handle_input_method (struct wl_listener *listener,
wl_signal_add(&relay->input_method->events.commit, &relay->input_method_commit);
relay->input_method_commit.notify = handle_im_commit;

wl_signal_add (&relay->input_method->events.grab_keyboard, &relay->input_method_grab_keyboard);
relay->input_method_grab_keyboard.notify = handle_im_grab_keyboard;

wl_signal_add(&relay->input_method->events.destroy, &relay->input_method_destroy);
relay->input_method_destroy.notify = handle_im_destroy;

Expand Down
3 changes: 3 additions & 0 deletions src/text_input.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ typedef struct _PhocInputMethodRelay {

struct wl_listener input_method_new;
struct wl_listener input_method_commit;
struct wl_listener input_method_grab_keyboard;
struct wl_listener input_method_destroy;

struct wl_listener input_method_keyboard_grab_destroy;
} PhocInputMethodRelay;

void phoc_input_method_relay_init (PhocSeat *seat, PhocInputMethodRelay *relay);
Expand Down

0 comments on commit 5b6185d

Please sign in to comment.