Skip to content

Commit

Permalink
Implement input-method keyboard grab
Browse files Browse the repository at this point in the history
  • Loading branch information
xdavidwu committed Jul 10, 2020
1 parent ea3ba20 commit 6bbf0ee
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 4 deletions.
3 changes: 3 additions & 0 deletions include/sway/input/text_input.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ struct sway_input_method_relay {

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;
};

struct sway_text_input {
Expand Down
64 changes: 60 additions & 4 deletions sway/input/keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,40 @@ static void handle_key_event(struct sway_keyboard *keyboard,
}

if (!handled || event->state == WLR_KEY_RELEASED) {
if (seat->im_relay.input_method) {
struct wlr_input_method_keyboard_grab_v2 *kb_grab =
seat->im_relay.input_method->keyboard_grab;
struct wlr_virtual_keyboard_v1 *virtual_keyboard =
wlr_input_device_get_virtual_keyboard(wlr_device);

// If event is from virtual keyboard of the same client as grab,
// do not send it back. TODO see swaywm/wlroots#2322
if (kb_grab && !(virtual_keyboard &&
wl_resource_get_client(virtual_keyboard->resource) ==
wl_resource_get_client(kb_grab->resource))) {
// Do not send release event to grab if the press event was not
// sent to grab.
if (event->state == WLR_KEY_RELEASED) {
bool pressed_sent = update_shortcut_state(
&keyboard->state_pressed_sent, event->keycode,
event->state, keyinfo.keycode, 0);
if (pressed_sent) {
wlr_seat_set_keyboard(wlr_seat, wlr_device);
wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec,
event->keycode, event->state);
goto end;
}

}

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);
goto end;
}
}

bool pressed_sent = update_shortcut_state(
&keyboard->state_pressed_sent, event->keycode, event->state,
keyinfo.keycode, 0);
Expand All @@ -495,6 +529,7 @@ static void handle_key_event(struct sway_keyboard *keyboard,
}
}

end:
transaction_commit_dirty();

free(device_identifier);
Expand Down Expand Up @@ -612,10 +647,31 @@ static void handle_modifier_event(struct sway_keyboard *keyboard) {
struct wlr_input_device *wlr_device =
keyboard->seat_device->input_device->wlr_device;
if (!wlr_device->keyboard->group) {
struct wlr_seat *wlr_seat = keyboard->seat_device->sway_seat->wlr_seat;
wlr_seat_set_keyboard(wlr_seat, wlr_device);
wlr_seat_keyboard_notify_modifiers(wlr_seat,
&wlr_device->keyboard->modifiers);
struct sway_seat *seat = keyboard->seat_device->sway_seat;
bool sent_to_kb_grab = false;
if (seat->im_relay.input_method) {
struct wlr_input_method_keyboard_grab_v2 *kb_grab =
seat->im_relay.input_method->keyboard_grab;
struct wlr_virtual_keyboard_v1 *virtual_keyboard =
wlr_input_device_get_virtual_keyboard(wlr_device);

// If event is from virtual keyboard of the same client as grab,
// do not send it back. TODO see swaywm/wlroots#2322
if (kb_grab && !(virtual_keyboard &&
wl_resource_get_client(virtual_keyboard->resource) ==
wl_resource_get_client(kb_grab->resource))) {
wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab,
wlr_device->keyboard);
wlr_input_method_keyboard_grab_v2_send_modifiers(kb_grab,
&wlr_device->keyboard->modifiers);
sent_to_kb_grab = true;
}
}
if (!sent_to_kb_grab) {
wlr_seat_set_keyboard(seat->wlr_seat, wlr_device);
wlr_seat_keyboard_notify_modifiers(seat->wlr_seat,
&wlr_device->keyboard->modifiers);
}

uint32_t modifiers = wlr_keyboard_get_modifiers(wlr_device->keyboard);
determine_bar_visibility(modifiers);
Expand Down
34 changes: 34 additions & 0 deletions sway/input/text_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,37 @@ 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) {
struct sway_input_method_relay *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) {
struct sway_input_method_relay *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->wlr_seat);
wlr_input_method_keyboard_grab_v2_set_keyboard(keyboard_grab,
active_keyboard);
wlr_input_method_keyboard_grab_v2_send_modifiers(keyboard_grab,
&active_keyboard->modifiers);

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_set_pending_focused_surface(
struct sway_text_input *text_input, struct wlr_surface *surface) {
wl_list_remove(&text_input->pending_focused_surface_destroy.link);
Expand Down Expand Up @@ -236,6 +267,9 @@ static void 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

0 comments on commit 6bbf0ee

Please sign in to comment.