From 53021f8ed428a1a023769339e6162bfebbe4c7a2 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 2 Nov 2017 20:13:10 -0400 Subject: rootston: break up input.h --- rootston/keyboard.c | 1 + 1 file changed, 1 insertion(+) (limited to 'rootston/keyboard.c') diff --git a/rootston/keyboard.c b/rootston/keyboard.c index e174b731..9458a05c 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -10,6 +10,7 @@ #include #include #include "rootston/input.h" +#include "rootston/keyboard.h" static ssize_t keyboard_pressed_keysym_index(struct roots_keyboard *keyboard, xkb_keysym_t keysym) { -- cgit v1.2.3 From 9bd0f47efd9a0c851d1715f3b9427b5f51b6d8a3 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 3 Nov 2017 06:18:20 -0400 Subject: rootston: refactor keyboard --- include/rootston/keyboard.h | 10 ++++++++-- rootston/input.c | 4 ++-- rootston/keyboard.c | 35 ++++++++++++++++++++++------------- 3 files changed, 32 insertions(+), 17 deletions(-) (limited to 'rootston/keyboard.c') diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index 33017b56..f4acc0aa 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -16,7 +16,13 @@ struct roots_keyboard { xkb_keysym_t pressed_keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; }; -void keyboard_add(struct wlr_input_device *device, struct roots_input *input); -void keyboard_remove(struct wlr_input_device *device, struct roots_input *input); +struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, + struct roots_input *input); +void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input); + +void roots_keyboard_handle_key(struct roots_keyboard *keyboard, + struct wlr_event_keyboard_key *event); + +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard); #endif diff --git a/rootston/input.c b/rootston/input.c index c8d46a69..2f50c708 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -36,7 +36,7 @@ static void input_add_notify(struct wl_listener *listener, void *data) { device->vendor, device->product, device_type(device->type)); switch (device->type) { case WLR_INPUT_DEVICE_KEYBOARD: - keyboard_add(device, input); + roots_keyboard_create(device, input); break; case WLR_INPUT_DEVICE_POINTER: pointer_add(device, input); @@ -57,7 +57,7 @@ static void input_remove_notify(struct wl_listener *listener, void *data) { struct roots_input *input = wl_container_of(listener, input, input_remove); switch (device->type) { case WLR_INPUT_DEVICE_KEYBOARD: - keyboard_remove(device, input); + roots_keyboard_destroy(device, input); break; case WLR_INPUT_DEVICE_POINTER: pointer_remove(device, input); diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 9458a05c..ece95245 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -123,10 +123,8 @@ static void keyboard_keysym_release(struct roots_keyboard *keyboard, } } -static void keyboard_key_notify(struct wl_listener *listener, void *data) { - struct wlr_event_keyboard_key *event = data; - struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, key); - +void roots_keyboard_handle_key(struct roots_keyboard *keyboard, + struct wlr_event_keyboard_key *event) { uint32_t keycode = event->keycode + 8; const xkb_keysym_t *syms; int syms_len = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state, @@ -149,9 +147,13 @@ static void keyboard_key_notify(struct wl_listener *listener, void *data) { } } -static void keyboard_modifiers_notify(struct wl_listener *listener, void *data) { - struct roots_keyboard *r_keyboard = - wl_container_of(listener, r_keyboard, modifiers); +static void handle_keyboard_key(struct wl_listener *listener, void *data) { + struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, key); + struct wlr_event_keyboard_key *event = data; + roots_keyboard_handle_key(keyboard, event); +} + +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) { struct wlr_seat *seat = r_keyboard->input->wl_seat; struct wlr_keyboard *keyboard = r_keyboard->device->keyboard; wlr_seat_set_keyboard(seat, r_keyboard->device); @@ -160,7 +162,12 @@ static void keyboard_modifiers_notify(struct wl_listener *listener, void *data) keyboard->modifiers.latched, keyboard->modifiers.locked, keyboard->modifiers.group); +} +static void handle_keyboard_modifiers(struct wl_listener *listener, void *data) { + struct roots_keyboard *r_keyboard = + wl_container_of(listener, r_keyboard, modifiers); + roots_keyboard_handle_modifiers(r_keyboard); } static void keyboard_config_merge(struct keyboard_config *config, @@ -185,19 +192,19 @@ static void keyboard_config_merge(struct keyboard_config *config, } } -void keyboard_add(struct wlr_input_device *device, struct roots_input *input) { +struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, struct roots_input *input) { struct roots_keyboard *keyboard = calloc(sizeof(struct roots_keyboard), 1); if (keyboard == NULL) { - return; + return NULL; } device->data = keyboard; keyboard->device = device; keyboard->input = input; - keyboard->key.notify = keyboard_key_notify; + keyboard->key.notify = handle_keyboard_key; wl_signal_add(&device->keyboard->events.key, &keyboard->key); - keyboard->modifiers.notify = keyboard_modifiers_notify; + keyboard->modifiers.notify = handle_keyboard_modifiers; wl_signal_add(&device->keyboard->events.modifiers, &keyboard->modifiers); wl_list_insert(&input->keyboards, &keyboard->link); @@ -226,14 +233,16 @@ void keyboard_add(struct wlr_input_device *device, struct roots_input *input) { struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); if (context == NULL) { wlr_log(L_ERROR, "Cannot create XKB context"); - return; + return NULL; } wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS)); xkb_context_unref(context); + + return keyboard; } -void keyboard_remove(struct wlr_input_device *device, struct roots_input *input) { +void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input) { struct roots_keyboard *keyboard = device->data; wl_list_remove(&keyboard->key.link); wl_list_remove(&keyboard->modifiers.link); -- cgit v1.2.3 From 5354fe8729b8c52f8f3ff63f23f932c49bf8c880 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 3 Nov 2017 09:01:34 -0400 Subject: move keyboard to seat --- backend/libinput/keyboard.c | 1 + backend/wayland/wl_seat.c | 12 +++++-- backend/x11/backend.c | 1 + include/rootston/input.h | 1 + include/rootston/keyboard.h | 15 +++++--- include/rootston/seat.h | 26 ++++++++++++++ include/wlr/interfaces/wlr_keyboard.h | 3 +- include/wlr/types/wlr_keyboard.h | 11 ++++++ rootston/input.c | 33 ++++++++++++++++-- rootston/keyboard.c | 38 ++++++-------------- rootston/meson.build | 1 + rootston/seat.c | 66 +++++++++++++++++++++++++++++++++++ types/wlr_keyboard.c | 11 +++--- 13 files changed, 176 insertions(+), 43 deletions(-) create mode 100644 include/rootston/seat.h create mode 100644 rootston/seat.c (limited to 'rootston/keyboard.c') diff --git a/backend/libinput/keyboard.c b/backend/libinput/keyboard.c index 065d8ead..9a24c791 100644 --- a/backend/libinput/keyboard.c +++ b/backend/libinput/keyboard.c @@ -54,6 +54,7 @@ void handle_keyboard_key(struct libinput_event *event, struct libinput_event_keyboard *kbevent = libinput_event_get_keyboard_event(event); struct wlr_event_keyboard_key wlr_event = { 0 }; + wlr_event.device = wlr_dev; wlr_event.time_msec = usec_to_msec(libinput_event_keyboard_get_time_usec(kbevent)); wlr_event.keycode = libinput_event_keyboard_get_key(kbevent); diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index deed215e..146296ae 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -151,6 +151,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, assert(dev && dev->keyboard); struct wlr_event_keyboard_key wlr_event; + wlr_event.device = dev; wlr_event.keycode = key; wlr_event.state = state; wlr_event.time_msec = time; @@ -162,8 +163,15 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboar uint32_t mods_locked, uint32_t group) { struct wlr_input_device *dev = data; assert(dev && dev->keyboard); - wlr_keyboard_notify_modifiers(dev->keyboard, mods_depressed, mods_latched, - mods_locked, group); + struct wlr_event_keyboard_modifiers wlr_event; + wlr_event.device = dev; + wlr_event.keyboard = dev->keyboard; + wlr_event.mods_depressed = mods_depressed; + wlr_event.mods_latched = mods_latched; + wlr_event.mods_locked = mods_locked; + wlr_event.group = group; + + wlr_keyboard_notify_modifiers(dev->keyboard, &wlr_event); } static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, diff --git a/backend/x11/backend.c b/backend/x11/backend.c index 97b0dd8c..f76b314e 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -50,6 +50,7 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e case XCB_KEY_RELEASE: { xcb_key_press_event_t *ev = (xcb_key_press_event_t *)event; struct wlr_event_keyboard_key key = { + .device = &x11->keyboard_dev, .time_msec = ev->time, .keycode = ev->detail - 8, .state = event->response_type == XCB_KEY_PRESS ? diff --git a/include/rootston/input.h b/include/rootston/input.h index 6d07de43..7b1358f8 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -67,6 +67,7 @@ struct roots_input { struct wl_list pointers; struct wl_list touch; struct wl_list tablet_tools; + struct wl_list seats; struct wl_listener input_add; struct wl_listener input_remove; diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index f4acc0aa..cb639ba1 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -8,21 +8,28 @@ struct roots_keyboard { struct roots_input *input; + struct roots_seat *seat; struct wlr_input_device *device; - struct wl_listener key; - struct wl_listener modifiers; + struct wl_list seat_link; + // XXX temporary struct wl_list link; + struct wl_listener keyboard_key; + struct wl_listener keyboard_modifiers; + xkb_keysym_t pressed_keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; }; struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, struct roots_input *input); -void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input); + +void roots_keyboard_destroy(struct wlr_input_device *device, + struct roots_input *input); void roots_keyboard_handle_key(struct roots_keyboard *keyboard, struct wlr_event_keyboard_key *event); -void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard); +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard, + struct wlr_event_keyboard_modifiers *event); #endif diff --git a/include/rootston/seat.h b/include/rootston/seat.h new file mode 100644 index 00000000..f6db63cc --- /dev/null +++ b/include/rootston/seat.h @@ -0,0 +1,26 @@ +#ifndef _ROOTSTON_SEAT_H +#define _ROOTSTON_SEAT_H + +#include + +#include "rootston/input.h" +#include "rootston/keyboard.h" + +struct roots_seat { + struct roots_input *input; + struct wlr_seat *seat; + struct wl_list keyboards; + struct wl_list link; +}; + +struct roots_seat *roots_seat_create(struct roots_input *input, char *name); + +void roots_seat_destroy(struct roots_seat *seat); + +void roots_seat_add_keyboard(struct roots_seat *seat, + struct roots_keyboard *keyboard); + +void roots_seat_remove_keyboard(struct roots_seat *seat, + struct roots_keyboard *keyboard); + +#endif diff --git a/include/wlr/interfaces/wlr_keyboard.h b/include/wlr/interfaces/wlr_keyboard.h index 570f5721..5848416d 100644 --- a/include/wlr/interfaces/wlr_keyboard.h +++ b/include/wlr/interfaces/wlr_keyboard.h @@ -14,7 +14,6 @@ void wlr_keyboard_destroy(struct wlr_keyboard *keyboard); void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, struct wlr_event_keyboard_key *event); void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group); + struct wlr_event_keyboard_modifiers *event); #endif diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h index af837ff5..c42cea9c 100644 --- a/include/wlr/types/wlr_keyboard.h +++ b/include/wlr/types/wlr_keyboard.h @@ -63,12 +63,23 @@ enum wlr_key_state { }; struct wlr_event_keyboard_key { + struct wlr_input_device *device; + struct wlr_keyboard *keyboard; uint32_t time_msec; uint32_t keycode; bool update_state; enum wlr_key_state state; }; +struct wlr_event_keyboard_modifiers { + struct wlr_input_device *device; + struct wlr_keyboard *keyboard; + uint32_t mods_depressed; + uint32_t mods_latched; + uint32_t mods_locked; + uint32_t group; +}; + void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, struct xkb_keymap *keymap); void wlr_keyboard_led_update(struct wlr_keyboard *keyboard, uint32_t leds); diff --git a/rootston/input.c b/rootston/input.c index 2f50c708..51a64720 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -12,6 +12,7 @@ #include "rootston/keyboard.h" #include "rootston/pointer.h" #include "rootston/touch.h" +#include "rootston/seat.h" static const char *device_type(enum wlr_input_device_type type) { switch (type) { @@ -29,15 +30,42 @@ static const char *device_type(enum wlr_input_device_type type) { return NULL; } +static struct roots_seat *input_get_seat(struct roots_input *input, char *name) { + struct roots_seat *seat = NULL; + wl_list_for_each(seat, &input->seats, link) { + if (strcmp(seat->seat->name, name) == 0) { + return seat; + } + } + + seat = roots_seat_create(input, name); + return seat; +} + static void input_add_notify(struct wl_listener *listener, void *data) { struct wlr_input_device *device = data; struct roots_input *input = wl_container_of(listener, input, input_add); + + char *seat_name = "seat0"; + struct device_config *dc = config_get_device(input->config, device); + if (dc) { + seat_name = dc->seat; + } + + struct roots_seat *seat = input_get_seat(input, seat_name); + if (!seat) { + wlr_log(L_ERROR, "could not create roots seat"); + return; + } + wlr_log(L_DEBUG, "New input device: %s (%d:%d) %s", device->name, device->vendor, device->product, device_type(device->type)); switch (device->type) { - case WLR_INPUT_DEVICE_KEYBOARD: - roots_keyboard_create(device, input); + case WLR_INPUT_DEVICE_KEYBOARD: { + struct roots_keyboard *keyboard = roots_keyboard_create(device, input); + roots_seat_add_keyboard(seat, keyboard); break; + } case WLR_INPUT_DEVICE_POINTER: pointer_add(device, input); break; @@ -123,6 +151,7 @@ struct roots_input *input_create(struct roots_server *server, wl_list_init(&input->pointers); wl_list_init(&input->touch); wl_list_init(&input->tablet_tools); + wl_list_init(&input->seats); input->input_add.notify = input_add_notify; wl_signal_add(&server->backend->events.input_add, &input->input_add); diff --git a/rootston/keyboard.c b/rootston/keyboard.c index ece95245..0865f551 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -10,6 +10,7 @@ #include #include #include "rootston/input.h" +#include "rootston/seat.h" #include "rootston/keyboard.h" static ssize_t keyboard_pressed_keysym_index(struct roots_keyboard *keyboard, @@ -85,8 +86,8 @@ static bool keyboard_keysym_press(struct roots_keyboard *keyboard, } if (keysym == XKB_KEY_Escape) { - wlr_seat_pointer_end_grab(keyboard->input->wl_seat); - wlr_seat_keyboard_end_grab(keyboard->input->wl_seat); + wlr_seat_pointer_end_grab(keyboard->seat->seat); + wlr_seat_keyboard_end_grab(keyboard->seat->seat); } uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); @@ -141,20 +142,15 @@ void roots_keyboard_handle_key(struct roots_keyboard *keyboard, } if (!handled) { - wlr_seat_set_keyboard(keyboard->input->wl_seat, keyboard->device); - wlr_seat_keyboard_notify_key(keyboard->input->wl_seat, event->time_msec, + wlr_seat_set_keyboard(keyboard->seat->seat, keyboard->device); + wlr_seat_keyboard_notify_key(keyboard->seat->seat, event->time_msec, event->keycode, event->state); } } -static void handle_keyboard_key(struct wl_listener *listener, void *data) { - struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, key); - struct wlr_event_keyboard_key *event = data; - roots_keyboard_handle_key(keyboard, event); -} - -void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) { - struct wlr_seat *seat = r_keyboard->input->wl_seat; +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard, + struct wlr_event_keyboard_modifiers *event) { + struct wlr_seat *seat = r_keyboard->seat->seat; struct wlr_keyboard *keyboard = r_keyboard->device->keyboard; wlr_seat_set_keyboard(seat, r_keyboard->device); wlr_seat_keyboard_notify_modifiers(seat, @@ -164,12 +160,6 @@ void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) { keyboard->modifiers.group); } -static void handle_keyboard_modifiers(struct wl_listener *listener, void *data) { - struct roots_keyboard *r_keyboard = - wl_container_of(listener, r_keyboard, modifiers); - roots_keyboard_handle_modifiers(r_keyboard); -} - static void keyboard_config_merge(struct keyboard_config *config, struct keyboard_config *fallback) { if (fallback == NULL) { @@ -192,7 +182,8 @@ static void keyboard_config_merge(struct keyboard_config *config, } } -struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, struct roots_input *input) { +struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, + struct roots_input *input) { struct roots_keyboard *keyboard = calloc(sizeof(struct roots_keyboard), 1); if (keyboard == NULL) { return NULL; @@ -201,12 +192,7 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, st keyboard->device = device; keyboard->input = input; - keyboard->key.notify = handle_keyboard_key; - wl_signal_add(&device->keyboard->events.key, &keyboard->key); - - keyboard->modifiers.notify = handle_keyboard_modifiers; - wl_signal_add(&device->keyboard->events.modifiers, &keyboard->modifiers); - + // XXX temporary wl_list_insert(&input->keyboards, &keyboard->link); struct keyboard_config config; @@ -244,8 +230,6 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, st void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input) { struct roots_keyboard *keyboard = device->data; - wl_list_remove(&keyboard->key.link); - wl_list_remove(&keyboard->modifiers.link); wl_list_remove(&keyboard->link); free(keyboard); } diff --git a/rootston/meson.build b/rootston/meson.build index d84422d8..0367e43f 100644 --- a/rootston/meson.build +++ b/rootston/meson.build @@ -8,6 +8,7 @@ sources = [ 'main.c', 'output.c', 'pointer.c', + 'seat.c', 'tablet_tool.c', 'touch.c', 'xcursor.c', diff --git a/rootston/seat.c b/rootston/seat.c new file mode 100644 index 00000000..2103e0d2 --- /dev/null +++ b/rootston/seat.c @@ -0,0 +1,66 @@ +#include +#include + +#include "rootston/input.h" +#include "rootston/seat.h" +#include "rootston/keyboard.h" + +static void handle_keyboard_key(struct wl_listener *listener, void *data) { + struct roots_keyboard *keyboard = + wl_container_of(listener, keyboard, keyboard_key); + struct wlr_event_keyboard_key *event = data; + roots_keyboard_handle_key(keyboard, event); +} + +static void handle_keyboard_modifiers(struct wl_listener *listener, + void *data) { + struct roots_keyboard *keyboard = + wl_container_of(listener, keyboard, keyboard_modifiers); + struct wlr_event_keyboard_modifiers *event = data; + roots_keyboard_handle_modifiers(keyboard, event); +} + +struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { + struct roots_seat *seat = calloc(1, sizeof(struct roots_seat)); + if (!seat) { + return NULL; + } + + seat->seat = wlr_seat_create(input->server->wl_display, name); + wlr_seat_set_capabilities(seat->seat, + WL_SEAT_CAPABILITY_KEYBOARD | + WL_SEAT_CAPABILITY_POINTER | + WL_SEAT_CAPABILITY_TOUCH); + seat->input = input; + wl_list_insert(&input->seats, &seat->link); + wl_list_init(&seat->keyboards); + + return seat; +} + +void roots_seat_destroy(struct roots_seat *seat) { + // TODO +} + +void roots_seat_add_keyboard(struct roots_seat *seat, + struct roots_keyboard *keyboard) { + if (keyboard->seat) { + roots_seat_remove_keyboard(keyboard->seat, keyboard); + } + keyboard->seat = seat; + wl_list_insert(&seat->keyboards, &keyboard->seat_link); + + keyboard->keyboard_key.notify = handle_keyboard_key; + wl_signal_add(&keyboard->device->keyboard->events.key, + &keyboard->keyboard_key); + + keyboard->keyboard_modifiers.notify = handle_keyboard_modifiers; + wl_signal_add(&keyboard->device->keyboard->events.modifiers, + &keyboard->keyboard_modifiers); +} + +void roots_seat_remove_keyboard(struct roots_seat *seat, + struct roots_keyboard *keyboard) { + // TODO +} + diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index c27264ef..c2fd9e0c 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -41,19 +41,18 @@ static void keyboard_modifier_update(struct wlr_keyboard *keyboard) { keyboard->modifiers.latched = latched; keyboard->modifiers.locked = locked; keyboard->modifiers.group = group; - - wl_signal_emit(&keyboard->events.modifiers, keyboard); } void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group) { + struct wlr_event_keyboard_modifiers *event) { if (!keyboard->xkb_state) { return; } - xkb_state_update_mask(keyboard->xkb_state, mods_depressed, mods_latched, - mods_locked, 0, 0, group); + xkb_state_update_mask(keyboard->xkb_state, event->mods_depressed, + event->mods_latched, event->mods_locked, 0, 0, event->group); keyboard_modifier_update(keyboard); + + wl_signal_emit(&keyboard->events.modifiers, event); } void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, -- cgit v1.2.3 From c88990d2c2c66835f9098dc642b6d679529a84a8 Mon Sep 17 00:00:00 2001 From: Markus Ongyerth Date: Tue, 7 Nov 2017 12:32:55 +0100 Subject: fix the keybind handling in rootston. As mentioned in https://github.com/swaywm/wlroots/issues/393 keybinds did't trigger / were checked with "odd" keys and modifiers. This commit sends the keycode through two paths, one to get the keycode and modifiers *after* xkb handles them, a secondary path to get a "raw" keysym without modifiers and then add the modifiers rootston knows about. This will result in the `[Alt]+[Shift]+2` combination I mention earlier going through the keybind detection twice. 1) `[Alt]+[at]` 2) `[Alt]+[Shift]+2` When either combination is found, the appropriate keybind is executed. The xkb handled version will be prefered over the "raw" version. --- rootston/keyboard.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 8 deletions(-) (limited to 'rootston/keyboard.c') diff --git a/rootston/keyboard.c b/rootston/keyboard.c index e174b731..6b1fde86 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -60,7 +60,7 @@ static void keyboard_binding_execute(struct roots_keyboard *keyboard, * should be propagated to clients. */ static bool keyboard_keysym_press(struct roots_keyboard *keyboard, - xkb_keysym_t keysym) { + xkb_keysym_t keysym, uint32_t modifiers) { ssize_t i = keyboard_pressed_keysym_index(keyboard, keysym); if (i < 0) { i = keyboard_pressed_keysym_index(keyboard, XKB_KEY_NoSymbol); @@ -88,7 +88,6 @@ static bool keyboard_keysym_press(struct roots_keyboard *keyboard, wlr_seat_keyboard_end_grab(keyboard->input->wl_seat); } - uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); struct wl_list *bindings = &keyboard->input->server->config->bindings; struct binding_config *bc; wl_list_for_each(bc, bindings, link) { @@ -122,25 +121,70 @@ static void keyboard_keysym_release(struct roots_keyboard *keyboard, } } -static void keyboard_key_notify(struct wl_listener *listener, void *data) { - struct wlr_event_keyboard_key *event = data; - struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, key); +static bool keyboard_keysyms_simple(struct roots_keyboard *keyboard, + uint32_t keycode, enum wlr_key_state state) +{ + uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); + const xkb_keysym_t *syms; + xkb_layout_index_t layout_index = xkb_state_key_get_layout( + keyboard->device->keyboard->xkb_state, + keycode); + int syms_len = xkb_keymap_key_get_syms_by_level(keyboard->device->keyboard->keymap, + keycode, layout_index, 0, &syms); - uint32_t keycode = event->keycode + 8; + bool handled = false; + for (int i = 0; i < syms_len; i++) { + if (state) { + bool keysym_handled = keyboard_keysym_press(keyboard, + syms[i], modifiers); + handled = handled || keysym_handled; + } else { // WLR_KEY_RELEASED + keyboard_keysym_release(keyboard, syms[i]); + } + } + + return handled; +} + +static bool keyboard_keysyms_xkb(struct roots_keyboard *keyboard, + uint32_t keycode, enum wlr_key_state state) +{ + uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); const xkb_keysym_t *syms; int syms_len = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state, keycode, &syms); + uint32_t consumed = xkb_state_key_get_consumed_mods2( + keyboard->device->keyboard->xkb_state, + keycode, + XKB_CONSUMED_MODE_XKB); + + modifiers = modifiers & ~consumed; bool handled = false; for (int i = 0; i < syms_len; i++) { - if (event->state == WLR_KEY_PRESSED) { - bool keysym_handled = keyboard_keysym_press(keyboard, syms[i]); + if (state) { + bool keysym_handled = keyboard_keysym_press(keyboard, + syms[i], modifiers); handled = handled || keysym_handled; } else { // WLR_KEY_RELEASED keyboard_keysym_release(keyboard, syms[i]); } } + return handled; +} + +static void keyboard_key_notify(struct wl_listener *listener, void *data) { + struct wlr_event_keyboard_key *event = data; + struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, key); + + uint32_t keycode = event->keycode + 8; + + bool handled = keyboard_keysyms_xkb(keyboard, keycode, event->state); + + if (!handled) + handled |= keyboard_keysyms_simple(keyboard, keycode, event->state); + if (!handled) { wlr_seat_set_keyboard(keyboard->input->wl_seat, keyboard->device); wlr_seat_keyboard_notify_key(keyboard->input->wl_seat, event->time_msec, -- cgit v1.2.3 From 8ca76ff7f27175e275cbebcc788a1e09ce831293 Mon Sep 17 00:00:00 2001 From: Markus Ongyerth Date: Tue, 7 Nov 2017 12:55:19 +0100 Subject: explains 2 way keybind trying. --- rootston/keyboard.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'rootston/keyboard.c') diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 6b1fde86..86f10374 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -121,14 +121,21 @@ static void keyboard_keysym_release(struct roots_keyboard *keyboard, } } +/** + * Process keypresses from the keyboard as if modifiers didn't change keysyms. + * + * This avoids the xkb keysym translation based on modifiers considered pressed + * in the state and uses the list of modifiers saved on the rootston side. + * + * This will trigger the keybind: [Alt]+[Shift]+2 + */ static bool keyboard_keysyms_simple(struct roots_keyboard *keyboard, uint32_t keycode, enum wlr_key_state state) { uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); const xkb_keysym_t *syms; xkb_layout_index_t layout_index = xkb_state_key_get_layout( - keyboard->device->keyboard->xkb_state, - keycode); + keyboard->device->keyboard->xkb_state, keycode); int syms_len = xkb_keymap_key_get_syms_by_level(keyboard->device->keyboard->keymap, keycode, layout_index, 0, &syms); @@ -146,6 +153,15 @@ static bool keyboard_keysyms_simple(struct roots_keyboard *keyboard, return handled; } +/** + * Process keypresses from the keyboard as xkb sees them. + * + * This uses the xkb keysyms translation based on pressed modifiers and clears + * the consumed modifiers from the list of modifiers passed to keybind + * detection. + * + * (On US layout) this will trigger: [Alt]+[at] + */ static bool keyboard_keysyms_xkb(struct roots_keyboard *keyboard, uint32_t keycode, enum wlr_key_state state) { @@ -154,9 +170,7 @@ static bool keyboard_keysyms_xkb(struct roots_keyboard *keyboard, int syms_len = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state, keycode, &syms); uint32_t consumed = xkb_state_key_get_consumed_mods2( - keyboard->device->keyboard->xkb_state, - keycode, - XKB_CONSUMED_MODE_XKB); + keyboard->device->keyboard->xkb_state, keycode, XKB_CONSUMED_MODE_XKB); modifiers = modifiers & ~consumed; -- cgit v1.2.3 From 23991861a461acabafde3c8d63c4355320e67db3 Mon Sep 17 00:00:00 2001 From: Markus Ongyerth Date: Tue, 7 Nov 2017 16:50:34 +0100 Subject: works in review comments --- rootston/keyboard.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'rootston/keyboard.c') diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 86f10374..6c419df8 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -121,7 +121,7 @@ static void keyboard_keysym_release(struct roots_keyboard *keyboard, } } -/** +/* * Process keypresses from the keyboard as if modifiers didn't change keysyms. * * This avoids the xkb keysym translation based on modifiers considered pressed @@ -130,8 +130,7 @@ static void keyboard_keysym_release(struct roots_keyboard *keyboard, * This will trigger the keybind: [Alt]+[Shift]+2 */ static bool keyboard_keysyms_simple(struct roots_keyboard *keyboard, - uint32_t keycode, enum wlr_key_state state) -{ + uint32_t keycode, enum wlr_key_state state) { uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); const xkb_keysym_t *syms; xkb_layout_index_t layout_index = xkb_state_key_get_layout( @@ -153,7 +152,7 @@ static bool keyboard_keysyms_simple(struct roots_keyboard *keyboard, return handled; } -/** +/* * Process keypresses from the keyboard as xkb sees them. * * This uses the xkb keysyms translation based on pressed modifiers and clears @@ -163,8 +162,7 @@ static bool keyboard_keysyms_simple(struct roots_keyboard *keyboard, * (On US layout) this will trigger: [Alt]+[at] */ static bool keyboard_keysyms_xkb(struct roots_keyboard *keyboard, - uint32_t keycode, enum wlr_key_state state) -{ + uint32_t keycode, enum wlr_key_state state) { uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); const xkb_keysym_t *syms; int syms_len = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state, @@ -196,8 +194,10 @@ static void keyboard_key_notify(struct wl_listener *listener, void *data) { bool handled = keyboard_keysyms_xkb(keyboard, keycode, event->state); - if (!handled) - handled |= keyboard_keysyms_simple(keyboard, keycode, event->state); + if (!handled) { + bool key_handled = keyboard_keysyms_simple(keyboard, keycode, event->state); + handled = handled || key_handled; + } if (!handled) { wlr_seat_set_keyboard(keyboard->input->wl_seat, keyboard->device); -- cgit v1.2.3 From 09c60924235805d07b7915ba879685545a3442aa Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 7 Nov 2017 15:56:11 -0500 Subject: multiseat: somewhat working --- include/rootston/cursor.h | 35 +++++ include/rootston/input.h | 54 +------- include/rootston/keyboard.h | 1 + include/rootston/seat.h | 30 +++++ include/wlr/types/wlr_wl_shell.h | 4 +- include/wlr/types/wlr_xdg_shell_v6.h | 6 +- rootston/desktop.c | 36 +++--- rootston/input.c | 62 ++------- rootston/keyboard.c | 26 ++-- rootston/meson.build | 2 +- rootston/output.c | 32 ++--- rootston/roots_cursor.c | 239 +++++++++++++++++++++++++++++++++-- rootston/seat.c | 134 +++++++++++++++++++- rootston/wl_shell.c | 13 +- rootston/xdg_shell_v6.c | 14 +- rootston/xwayland.c | 32 ++--- types/wlr_wl_shell.c | 8 +- types/wlr_xdg_shell_v6.c | 12 +- 18 files changed, 521 insertions(+), 219 deletions(-) (limited to 'rootston/keyboard.c') diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h index 8a8d33f2..18d5f720 100644 --- a/include/rootston/cursor.h +++ b/include/rootston/cursor.h @@ -3,10 +3,45 @@ #include "rootston/seat.h" +enum roots_cursor_mode { + ROOTS_CURSOR_PASSTHROUGH = 0, + ROOTS_CURSOR_MOVE = 1, + ROOTS_CURSOR_RESIZE = 2, + ROOTS_CURSOR_ROTATE = 3, +}; + +enum roots_cursor_resize_edge { + ROOTS_CURSOR_RESIZE_EDGE_TOP = 1, + ROOTS_CURSOR_RESIZE_EDGE_BOTTOM = 2, + ROOTS_CURSOR_RESIZE_EDGE_LEFT = 4, + ROOTS_CURSOR_RESIZE_EDGE_RIGHT = 8, +}; + +struct roots_input_event { + uint32_t serial; + struct wlr_cursor *cursor; + struct wlr_input_device *device; +}; + struct roots_cursor { struct roots_seat *seat; struct wlr_cursor *cursor; + enum roots_cursor_mode mode; + + // state from input (review if this is necessary) + struct wlr_xcursor_theme *xcursor_theme; + struct wlr_seat *wl_seat; + struct wl_client *cursor_client; + int offs_x, offs_y; + int view_x, view_y, view_width, view_height; + float view_rotation; + uint32_t resize_edges; + // Ring buffer of input events that could trigger move/resize/rotate + int input_events_idx; + struct wl_list touch_points; + struct roots_input_event input_events[16]; + struct wl_listener motion; struct wl_listener motion_absolute; struct wl_listener button; diff --git a/include/rootston/input.h b/include/rootston/input.h index 7b1358f8..7463ba3a 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -5,64 +5,15 @@ #include #include #include +#include "rootston/cursor.h" #include "rootston/config.h" #include "rootston/view.h" #include "rootston/server.h" -enum roots_cursor_mode { - ROOTS_CURSOR_PASSTHROUGH = 0, - ROOTS_CURSOR_MOVE = 1, - ROOTS_CURSOR_RESIZE = 2, - ROOTS_CURSOR_ROTATE = 3, -}; - -enum roots_cursor_resize_edge { - ROOTS_CURSOR_RESIZE_EDGE_TOP = 1, - ROOTS_CURSOR_RESIZE_EDGE_BOTTOM = 2, - ROOTS_CURSOR_RESIZE_EDGE_LEFT = 4, - ROOTS_CURSOR_RESIZE_EDGE_RIGHT = 8, -}; - -struct roots_input_event { - uint32_t serial; - struct wlr_cursor *cursor; - struct wlr_input_device *device; -}; - -struct roots_drag_icon { - struct wlr_surface *surface; - struct wl_list link; // roots_input::drag_icons - bool mapped; - - int32_t sx; - int32_t sy; - - struct wl_listener surface_destroy; - struct wl_listener surface_commit; -}; - struct roots_input { struct roots_config *config; struct roots_server *server; - // TODO: multiseat, multicursor - struct wlr_cursor *cursor; - struct wlr_xcursor_theme *xcursor_theme; - struct wlr_seat *wl_seat; - struct wl_list drag_icons; - struct wl_client *cursor_client; - - enum roots_cursor_mode mode; - struct roots_view *active_view; - int offs_x, offs_y; - int view_x, view_y, view_width, view_height; - float view_rotation; - uint32_t resize_edges; - - // Ring buffer of input events that could trigger move/resize/rotate - int input_events_idx; - struct roots_input_event input_events[16]; - struct wl_list keyboards; struct wl_list pointers; struct wl_list touch; @@ -117,4 +68,7 @@ struct wlr_xcursor *get_rotate_xcursor(struct wlr_xcursor_theme *theme); void set_view_focus(struct roots_input *input, struct roots_desktop *desktop, struct roots_view *view); +struct roots_seat *input_seat_from_wlr_seat(struct roots_input *input, + struct wlr_seat *seat); + #endif diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index cb639ba1..e3caf8fb 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -10,6 +10,7 @@ struct roots_keyboard { struct roots_input *input; struct roots_seat *seat; struct wlr_input_device *device; + struct keyboard_config *config; struct wl_list seat_link; // XXX temporary struct wl_list link; diff --git a/include/rootston/seat.h b/include/rootston/seat.h index b7c8b477..b5593651 100644 --- a/include/rootston/seat.h +++ b/include/rootston/seat.h @@ -6,11 +6,26 @@ #include "rootston/input.h" #include "rootston/keyboard.h" +struct roots_drag_icon { + struct wlr_surface *surface; + struct wl_list link; // roots_seat::drag_icons + bool mapped; + + int32_t sx; + int32_t sy; + + struct wl_listener surface_destroy; + struct wl_listener surface_commit; +}; + struct roots_seat { struct roots_input *input; struct wlr_seat *seat; struct roots_cursor *cursor; struct wl_list link; + struct wl_list drag_icons; + + struct roots_view *focus; struct wl_list keyboards; struct wl_list pointers; @@ -57,4 +72,19 @@ void roots_seat_add_device(struct roots_seat *seat, void roots_seat_remove_device(struct roots_seat *seat, struct wlr_input_device *device); +void roots_seat_configure_cursor(struct roots_seat *seat); + +void roots_seat_configure_xcursor(struct roots_seat *seat); + +bool roots_seat_has_meta_pressed(struct roots_seat *seat); + +void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view); + +void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view); + +void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view, + uint32_t edges); + +void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view); + #endif diff --git a/include/wlr/types/wlr_wl_shell.h b/include/wlr/types/wlr_wl_shell.h index 4e814817..ab3b4b10 100644 --- a/include/wlr/types/wlr_wl_shell.h +++ b/include/wlr/types/wlr_wl_shell.h @@ -93,14 +93,14 @@ struct wlr_wl_shell_surface { struct wlr_wl_shell_surface_move_event { struct wl_client *client; struct wlr_wl_shell_surface *surface; - struct wlr_seat_handle *seat_handle; + struct wlr_seat_client *seat; uint32_t serial; }; struct wlr_wl_shell_surface_resize_event { struct wl_client *client; struct wlr_wl_shell_surface *surface; - struct wlr_seat_handle *seat_handle; + struct wlr_seat_client *seat; uint32_t serial; enum wl_shell_surface_resize edges; }; diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index b0de41e2..e17393f6 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -138,14 +138,14 @@ struct wlr_xdg_surface_v6 { struct wlr_xdg_toplevel_v6_move_event { struct wl_client *client; struct wlr_xdg_surface_v6 *surface; - struct wlr_seat_handle *seat_handle; + struct wlr_seat_client *seat; uint32_t serial; }; struct wlr_xdg_toplevel_v6_resize_event { struct wl_client *client; struct wlr_xdg_surface_v6 *surface; - struct wlr_seat_handle *seat_handle; + struct wlr_seat_client *seat; uint32_t serial; uint32_t edges; }; @@ -153,7 +153,7 @@ struct wlr_xdg_toplevel_v6_resize_event { struct wlr_xdg_toplevel_v6_show_window_menu_event { struct wl_client *client; struct wlr_xdg_surface_v6 *surface; - struct wlr_seat_handle *seat_handle; + struct wlr_seat_client *seat; uint32_t serial; uint32_t x; uint32_t y; diff --git a/rootston/desktop.c b/rootston/desktop.c index 29f78ac7..e752e639 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -14,15 +14,19 @@ #include #include #include "rootston/server.h" -#include "rootston/server.h" +#include "rootston/seat.h" +// TODO replace me with a signal void view_destroy(struct roots_view *view) { struct roots_desktop *desktop = view->desktop; struct roots_input *input = desktop->server->input; - if (input->active_view == view) { - input->active_view = NULL; - input->mode = ROOTS_CURSOR_PASSTHROUGH; + struct roots_seat *seat; + wl_list_for_each(seat, &input->seats, link) { + if (seat->focus == view) { + seat->focus = NULL; + seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + } } for (size_t i = 0; i < desktop->views->length; ++i) { @@ -89,15 +93,9 @@ bool view_center(struct roots_view *view) { view_get_size(view, &size); struct roots_desktop *desktop = view->desktop; - struct wlr_cursor *cursor = desktop->server->input->cursor; struct wlr_output *output = - wlr_output_layout_output_at(desktop->layout, cursor->x, cursor->y); - - if (!output) { - output = wlr_output_layout_get_center_output(desktop->layout); - } - + wlr_output_layout_get_center_output(desktop->layout); if (!output) { // empty layout return false; @@ -121,19 +119,15 @@ void view_setup(struct roots_view *view) { view_center(view); struct roots_input *input = view->desktop->server->input; - set_view_focus(input, view->desktop, view); + // TODO what seat gets focus? the one with the last input event? + struct roots_seat *seat; + wl_list_for_each(seat, &input->seats, link) { + roots_seat_focus_view(seat, view); + } } void view_teardown(struct roots_view *view) { - struct wlr_list *views = view->desktop->views; - if (views->length < 2 || views->items[views->length-1] != view) { - return; - } - - struct roots_view *prev_view = views->items[views->length-2]; - struct roots_input *input = prev_view->desktop->server->input; - set_view_focus(input, prev_view->desktop, prev_view); - wlr_seat_keyboard_notify_enter(input->wl_seat, prev_view->wlr_surface); + // TODO replace me with a signal } struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, diff --git a/rootston/input.c b/rootston/input.c index 4a567763..8e45d6d3 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -84,43 +84,6 @@ struct roots_input *input_create(struct roots_server *server, input->config = config; input->server = server; - input->xcursor_theme = wlr_xcursor_theme_load("default", 16); - if (input->xcursor_theme == NULL) { - wlr_log(L_ERROR, "Cannot load xcursor theme"); - free(input); - return NULL; - } - - struct wlr_xcursor *xcursor = get_default_xcursor(input->xcursor_theme); - if (xcursor == NULL) { - wlr_log(L_ERROR, "Cannot load xcursor from theme"); - wlr_xcursor_theme_destroy(input->xcursor_theme); - free(input); - return NULL; - } - - if (server->desktop->xwayland != NULL) { - struct wlr_xcursor_image *xcursor_image = xcursor->images[0]; - wlr_xwayland_set_cursor(server->desktop->xwayland, - xcursor_image->buffer, xcursor_image->width, xcursor_image->width, - xcursor_image->height, xcursor_image->hotspot_x, - xcursor_image->hotspot_y); - } - - input->wl_seat = wlr_seat_create(server->wl_display, "seat0"); - if (input->wl_seat == NULL) { - wlr_log(L_ERROR, "Cannot create seat"); - wlr_xcursor_theme_destroy(input->xcursor_theme); - free(input); - return NULL; - } - wlr_seat_set_capabilities(input->wl_seat, WL_SEAT_CAPABILITY_KEYBOARD - | WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_TOUCH); - - wl_list_init(&input->keyboards); - wl_list_init(&input->pointers); - wl_list_init(&input->touch); - wl_list_init(&input->tablet_tools); wl_list_init(&input->seats); input->input_add.notify = input_add_notify; @@ -128,23 +91,20 @@ struct roots_input *input_create(struct roots_server *server, input->input_remove.notify = input_remove_notify; wl_signal_add(&server->backend->events.input_remove, &input->input_remove); - input->cursor = wlr_cursor_create(); - cursor_initialize(input); - - struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_cursor_set_image(input->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); - - wlr_cursor_attach_output_layout(input->cursor, server->desktop->layout); - wlr_cursor_map_to_region(input->cursor, config->cursor.mapped_box); - cursor_load_config(config, input->cursor, - input, server->desktop); - - wl_list_init(&input->drag_icons); - return input; } void input_destroy(struct roots_input *input) { // TODO } + +struct roots_seat *input_seat_from_wlr_seat(struct roots_input *input, + struct wlr_seat *wlr_seat) { + struct roots_seat *seat = NULL; + wl_list_for_each(seat, &input->seats, link) { + if (seat->seat == wlr_seat) { + return seat; + } + } + return seat; +} diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 0865f551..ef5eb8ab 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -39,7 +39,7 @@ static void keyboard_binding_execute(struct roots_keyboard *keyboard, } else if (strcmp(command, "next_window") == 0) { if (server->desktop->views->length > 0) { struct roots_view *view = server->desktop->views->items[0]; - set_view_focus(keyboard->input, server->desktop, view); + roots_seat_focus_view(keyboard->seat, view); } } else if (strncmp(exec_prefix, command, strlen(exec_prefix)) == 0) { const char *shell_cmd = command + strlen(exec_prefix); @@ -192,13 +192,9 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, keyboard->device = device; keyboard->input = input; - // XXX temporary - wl_list_insert(&input->keyboards, &keyboard->link); - - struct keyboard_config config; - memset(&config, 0, sizeof(config)); - keyboard_config_merge(&config, config_get_keyboard(input->config, device)); - keyboard_config_merge(&config, config_get_keyboard(input->config, NULL)); + struct keyboard_config *config = calloc(1, sizeof(struct keyboard_config)); + keyboard_config_merge(config, config_get_keyboard(input->config, device)); + keyboard_config_merge(config, config_get_keyboard(input->config, NULL)); struct keyboard_config env_config = { .rules = getenv("XKB_DEFAULT_RULES"), @@ -207,15 +203,16 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, .variant = getenv("XKB_DEFAULT_VARIANT"), .options = getenv("XKB_DEFAULT_OPTIONS"), }; - keyboard_config_merge(&config, &env_config); + keyboard_config_merge(config, &env_config); + keyboard->config = config; struct xkb_rule_names rules; memset(&rules, 0, sizeof(rules)); - rules.rules = config.rules; - rules.model = config.model; - rules.layout = config.layout; - rules.variant = config.variant; - rules.options = config.options; + rules.rules = config->rules; + rules.model = config->model; + rules.layout = config->layout; + rules.variant = config->variant; + rules.options = config->options; struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); if (context == NULL) { wlr_log(L_ERROR, "Cannot create XKB context"); @@ -231,5 +228,6 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input) { struct roots_keyboard *keyboard = device->data; wl_list_remove(&keyboard->link); + free(keyboard->config); free(keyboard); } diff --git a/rootston/meson.build b/rootston/meson.build index baed5330..062f56fc 100644 --- a/rootston/meson.build +++ b/rootston/meson.build @@ -1,6 +1,6 @@ sources = [ 'config.c', - 'cursor.c', + #'cursor.c', 'roots_cursor.c', 'desktop.c', 'ini.c', diff --git a/rootston/output.c b/rootston/output.c index baa7b6cc..329c29be 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -151,15 +151,18 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { } struct roots_drag_icon *drag_icon = NULL; - wl_list_for_each(drag_icon, &server->input->drag_icons, link) { - if (!drag_icon->mapped) { - continue; + struct roots_seat *seat = NULL; + wl_list_for_each(seat, &server->input->seats, link) { + wl_list_for_each(drag_icon, &seat->drag_icons, link) { + if (!drag_icon->mapped) { + continue; + } + struct wlr_surface *icon = drag_icon->surface; + struct wlr_cursor *cursor = seat->cursor->cursor; + double icon_x = cursor->x + drag_icon->sx; + double icon_y = cursor->y + drag_icon->sy; + render_surface(icon, desktop, wlr_output, &now, icon_x, icon_y, 0); } - struct wlr_surface *icon = drag_icon->surface; - struct wlr_cursor *cursor = server->input->cursor; - double icon_x = cursor->x + drag_icon->sx; - double icon_y = cursor->y + drag_icon->sy; - render_surface(icon, desktop, wlr_output, &now, icon_x, icon_y, 0); } wlr_renderer_end(server->renderer); @@ -224,14 +227,11 @@ void output_add_notify(struct wl_listener *listener, void *data) { wlr_output_layout_add_auto(desktop->layout, wlr_output); } - cursor_load_config(config, input->cursor, input, desktop); - - struct wlr_xcursor *xcursor = get_default_xcursor(input->xcursor_theme); - struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_cursor_set_image(input->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); - - wlr_cursor_warp(input->cursor, NULL, input->cursor->x, input->cursor->y); + struct roots_seat *seat; + wl_list_for_each(seat, &input->seats, link) { + roots_seat_configure_cursor(seat); + roots_seat_configure_xcursor(seat); + } } void output_remove_notify(struct wl_listener *listener, void *data) { diff --git a/rootston/roots_cursor.c b/rootston/roots_cursor.c index 72eff996..92c0cc9e 100644 --- a/rootston/roots_cursor.c +++ b/rootston/roots_cursor.c @@ -1,4 +1,11 @@ +#define _XOPEN_SOURCE 700 #include +#include +#ifdef __linux__ +#include +#elif __FreeBSD__ +#include +#endif #include #include "rootston/cursor.h" @@ -19,47 +26,261 @@ void roots_cursor_destroy(struct roots_cursor *cursor) { // TODO } +static void cursor_set_xcursor_image(struct roots_cursor *cursor, + struct wlr_xcursor_image *image) { + wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); +} + +static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t time) { + struct roots_desktop *desktop = cursor->seat->input->server->desktop; + struct roots_seat *seat = cursor->seat; + struct roots_view *view; + struct wlr_surface *surface; + double sx, sy; + switch (cursor->mode) { + case ROOTS_CURSOR_PASSTHROUGH: + view = view_at(desktop, cursor->cursor->x, cursor->cursor->y, + &surface, &sx, &sy); + bool set_compositor_cursor = !view && cursor->cursor_client; + if (view) { + struct wl_client *view_client = + wl_resource_get_client(view->wlr_surface->resource); + set_compositor_cursor = view_client != cursor->cursor_client; + } + if (set_compositor_cursor) { + struct wlr_xcursor *xcursor = get_default_xcursor(cursor->xcursor_theme); + cursor_set_xcursor_image(cursor, xcursor->images[0]); + cursor->cursor_client = NULL; + } + if (view) { + wlr_seat_pointer_notify_enter(seat->seat, surface, sx, sy); + wlr_seat_pointer_notify_motion(seat->seat, time, sx, sy); + } else { + wlr_seat_pointer_clear_focus(seat->seat); + } + break; + case ROOTS_CURSOR_MOVE: + if (seat->focus) { + double dx = cursor->cursor->x - cursor->offs_x; + double dy = cursor->cursor->y - cursor->offs_y; + view_move(seat->focus, cursor->view_x + dx, + cursor->view_y + dy); + } + break; + case ROOTS_CURSOR_RESIZE: + if (seat->focus) { + double dx = cursor->cursor->x - cursor->offs_x; + double dy = cursor->cursor->y - cursor->offs_y; + double active_x = seat->focus->x; + double active_y = seat->focus->y; + int width = cursor->view_width; + int height = cursor->view_height; + if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { + active_y = cursor->view_y + dy; + height -= dy; + if (height < 0) { + active_y += height; + } + } else if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_BOTTOM) { + height += dy; + } + if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_LEFT) { + active_x = cursor->view_x + dx; + width -= dx; + if (width < 0) { + active_x += width; + } + } else if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) { + width += dx; + } + + if (width < 0) { + width = 0; + } + if (height < 0) { + height = 0; + } + + if (active_x != seat->focus->x || + active_y != seat->focus->y) { + view_move_resize(seat->focus, active_x, active_y, + width, height); + } else { + view_resize(seat->focus, width, height); + } + } + break; + case ROOTS_CURSOR_ROTATE: + if (seat->focus) { + struct roots_view *view = seat->focus; + int ox = view->x + view->wlr_surface->current->width/2, + oy = view->y + view->wlr_surface->current->height/2; + int ux = cursor->offs_x - ox, + uy = cursor->offs_y - oy; + int vx = cursor->cursor->x - ox, + vy = cursor->cursor->y - oy; + float angle = atan2(vx*uy - vy*ux, vx*ux + vy*uy); + int steps = 12; + angle = round(angle/M_PI*steps) / (steps/M_PI); + view->rotation = cursor->view_rotation + angle; + } + break; + } + +} + +static void roots_cursor_press_button(struct roots_cursor *cursor, + struct wlr_input_device *device, uint32_t time, uint32_t button, + uint32_t state) { + struct roots_seat *seat = cursor->seat; + struct roots_desktop *desktop = seat->input->server->desktop; + struct wlr_surface *surface; + double sx, sy; + struct roots_view *view = view_at(desktop, + cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); + + if (state == WLR_BUTTON_PRESSED && view && roots_seat_has_meta_pressed(seat)) { + // TODO + roots_seat_focus_view(seat, view); + + uint32_t edges; + switch (button) { + case BTN_LEFT: + // TODO + roots_seat_begin_move(seat, view); + break; + case BTN_RIGHT: + edges = 0; + if (sx < view->wlr_surface->current->width/2) { + edges |= ROOTS_CURSOR_RESIZE_EDGE_LEFT; + } else { + edges |= ROOTS_CURSOR_RESIZE_EDGE_RIGHT; + } + if (sy < view->wlr_surface->current->height/2) { + edges |= ROOTS_CURSOR_RESIZE_EDGE_TOP; + } else { + edges |= ROOTS_CURSOR_RESIZE_EDGE_BOTTOM; + } + roots_seat_begin_resize(seat, view, edges); + break; + case BTN_MIDDLE: + roots_seat_begin_rotate(seat, view); + break; + } + return; + } + + // TODO + uint32_t serial = + wlr_seat_pointer_notify_button(seat->seat, time, button, state); + + int i; + switch (state) { + case WLR_BUTTON_RELEASED: + seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + roots_cursor_update_position(cursor, time); + break; + case WLR_BUTTON_PRESSED: + // TODO + i = cursor->input_events_idx; + cursor->input_events[i].serial = serial; + cursor->input_events[i].cursor = cursor->cursor; + cursor->input_events[i].device = device; + cursor->input_events_idx = (i + 1) + % (sizeof(cursor->input_events) / sizeof(cursor->input_events[0])); + roots_seat_focus_view(seat, view); + break; + } +} + void roots_cursor_handle_motion(struct roots_cursor *cursor, struct wlr_event_pointer_motion *event) { - wlr_log(L_DEBUG, "TODO: cursor handle motion"); + wlr_cursor_move(cursor->cursor, event->device, + event->delta_x, event->delta_y); + roots_cursor_update_position(cursor, event->time_msec); } void roots_cursor_handle_motion_absolute(struct roots_cursor *cursor, struct wlr_event_pointer_motion_absolute *event) { - wlr_log(L_DEBUG, "TODO: cursor handle motion absolute"); + wlr_cursor_warp_absolute(cursor->cursor, event->device, + event->x_mm / event->width_mm, event->y_mm / event->height_mm); + roots_cursor_update_position(cursor, event->time_msec); } void roots_cursor_handle_button(struct roots_cursor *cursor, struct wlr_event_pointer_button *event) { - wlr_log(L_DEBUG, "TODO: cursor handle button"); + roots_cursor_press_button(cursor, event->device, event->time_msec, + event->button, event->state); } void roots_cursor_handle_axis(struct roots_cursor *cursor, struct wlr_event_pointer_axis *event) { - wlr_log(L_DEBUG, "TODO: cursor handle axis"); + wlr_seat_pointer_notify_axis(cursor->seat->seat, event->time_msec, + event->orientation, event->delta); } void roots_cursor_handle_touch_down(struct roots_cursor *cursor, struct wlr_event_touch_down *event) { - wlr_log(L_DEBUG, "TODO: cursor handle touch down"); + struct roots_touch_point *point = + calloc(1, sizeof(struct roots_touch_point)); + if (!point) { + wlr_log(L_ERROR, "could not allocate memory for touch point"); + return; + } + + point->device = event->device->data; + point->slot = event->slot; + point->x = event->x_mm / event->width_mm; + point->y = event->y_mm / event->height_mm; + wlr_cursor_warp_absolute(cursor->cursor, event->device, point->x, point->y); + roots_cursor_update_position(cursor, event->time_msec); + wl_list_insert(&cursor->touch_points, &point->link); + roots_cursor_press_button(cursor, event->device, + event->time_msec, BTN_LEFT, 1); } void roots_cursor_handle_touch_up(struct roots_cursor *cursor, struct wlr_event_touch_up *event) { - wlr_log(L_DEBUG, "TODO: cursor handle touch up"); + struct roots_touch_point *point; + wl_list_for_each(point, &cursor->touch_points, link) { + if (point->slot == event->slot) { + wl_list_remove(&point->link); + free(point); + break; + } + } + roots_cursor_press_button(cursor, event->device, + event->time_msec, BTN_LEFT, 0); } void roots_cursor_handle_touch_motion(struct roots_cursor *cursor, struct wlr_event_touch_motion *event) { - wlr_log(L_DEBUG, "TODO: cursor handle touch motion"); + struct roots_touch_point *point; + wl_list_for_each(point, &cursor->touch_points, link) { + if (point->slot == event->slot) { + point->x = event->x_mm / event->width_mm; + point->y = event->y_mm / event->height_mm; + wlr_cursor_warp_absolute(cursor->cursor, event->device, + point->x, point->y); + roots_cursor_update_position(cursor, event->time_msec); + break; + } + } } void roots_cursor_handle_tool_axis(struct roots_cursor *cursor, struct wlr_event_tablet_tool_axis *event) { - wlr_log(L_DEBUG, "TODO: cursor handle tool axis"); + if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X) && + (event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { + wlr_cursor_warp_absolute(cursor->cursor, event->device, + event->x_mm / event->width_mm, event->y_mm / event->height_mm); + roots_cursor_update_position(cursor, event->time_msec); + } } void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, struct wlr_event_tablet_tool_tip *event) { - wlr_log(L_DEBUG, "TODO: cursor handle tool tip"); + roots_cursor_press_button(cursor, event->device, + event->time_msec, BTN_LEFT, event->state); } diff --git a/rootston/seat.c b/rootston/seat.c index 957843ec..ec7709fa 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -1,6 +1,7 @@ #include #include #include +#include #include @@ -110,7 +111,7 @@ static void seat_set_device_output_mappings(struct roots_seat *seat, } } -static void roots_seat_configure_cursor(struct roots_seat *seat) { +void roots_seat_configure_cursor(struct roots_seat *seat) { struct roots_config *config = seat->input->config; struct roots_desktop *desktop = seat->input->server->desktop; struct wlr_cursor *cursor = seat->cursor->cursor; @@ -156,10 +157,44 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { if (!seat->cursor) { return; } + seat->cursor->seat = seat; struct wlr_cursor *wlr_cursor = seat->cursor->cursor; struct roots_desktop *desktop = seat->input->server->desktop; wlr_cursor_attach_output_layout(wlr_cursor, desktop->layout); + seat->cursor->xcursor_theme = wlr_xcursor_theme_load("default", 16); + if (seat->cursor->xcursor_theme == NULL) { + wlr_log(L_ERROR, "Cannot load xcursor theme"); + roots_cursor_destroy(seat->cursor); + seat->cursor = NULL; + return; + } + + struct wlr_xcursor *xcursor = get_default_xcursor(seat->cursor->xcursor_theme); + if (xcursor == NULL) { + wlr_log(L_ERROR, "Cannot load xcursor from theme"); + wlr_xcursor_theme_destroy(seat->cursor->xcursor_theme); + roots_cursor_destroy(seat->cursor); + seat->cursor = NULL; + return; + } + + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_cursor_set_image(seat->cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); + + // XXX: xwayland will always have the theme of the last created seat + if (seat->input->server->desktop->xwayland != NULL) { + wlr_xwayland_set_cursor(seat->input->server->desktop->xwayland, + image->buffer, image->width, image->width, + image->height, image->hotspot_x, + image->hotspot_y); + } + + wl_list_init(&seat->cursor->touch_points); + + roots_seat_configure_cursor(seat); + // add input signals wl_signal_add(&wlr_cursor->events.motion, &seat->cursor->motion); seat->cursor->motion.notify = handle_cursor_motion; @@ -196,6 +231,12 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { return NULL; } + wl_list_init(&seat->keyboards); + wl_list_init(&seat->pointers); + wl_list_init(&seat->touch); + wl_list_init(&seat->tablet_tools); + wl_list_init(&seat->drag_icons); + seat->input = input; roots_seat_init_cursor(seat); @@ -218,11 +259,6 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { wl_list_insert(&input->seats, &seat->link); - wl_list_init(&seat->keyboards); - wl_list_init(&seat->pointers); - wl_list_init(&seat->touch); - wl_list_init(&seat->tablet_tools); - return seat; } @@ -231,6 +267,7 @@ void roots_seat_destroy(struct roots_seat *seat) { } static void seat_add_keyboard(struct roots_seat *seat, struct wlr_input_device *device) { + assert(device->type == WLR_INPUT_DEVICE_KEYBOARD); struct roots_keyboard *keyboard = roots_keyboard_create(device, seat->input); keyboard->seat = seat; @@ -319,3 +356,88 @@ void roots_seat_remove_device(struct roots_seat *seat, struct wlr_input_device *device) { // TODO } + +void roots_seat_configure_xcursor(struct roots_seat *seat) { + struct wlr_xcursor *xcursor = get_default_xcursor(seat->cursor->xcursor_theme); + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_cursor_set_image(seat->cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); + + wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, + seat->cursor->cursor->y); +} + +bool roots_seat_has_meta_pressed(struct roots_seat *seat) { + struct roots_keyboard *keyboard; + wl_list_for_each(keyboard, &seat->keyboards, seat_link) { + if (!keyboard->config->meta_key) { + continue; + } + + uint32_t modifiers = + wlr_keyboard_get_modifiers(keyboard->device->keyboard); + if ((modifiers ^ keyboard->config->meta_key) == 0) { + return true; + } + } + + return false; +} + +void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { + struct roots_desktop *desktop = seat->input->server->desktop; + if (seat->focus == view) { + return; + } + seat->focus = view; + seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + if (!view) { + return; + } + + if (view->type == ROOTS_XWAYLAND_VIEW && + view->xwayland_surface->override_redirect) { + return; + } + + size_t index = 0; + for (size_t i = 0; i < desktop->views->length; ++i) { + struct roots_view *_view = desktop->views->items[i]; + if (_view != view) { + view_activate(_view, false); + } else { + index = i; + } + } + view_activate(view, true); + // TODO: list_swap + wlr_list_del(desktop->views, index); + wlr_list_add(desktop->views, view); + wlr_seat_keyboard_notify_enter(seat->seat, view->wlr_surface); +} + +void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) { + struct roots_cursor *cursor = seat->cursor; + cursor->mode = ROOTS_CURSOR_MOVE; + cursor->offs_x = cursor->cursor->x; + cursor->offs_y = cursor->cursor->y; + cursor->view_x = view->x; + cursor->view_y = view->y; + wlr_seat_pointer_clear_focus(seat->seat); + + struct wlr_xcursor *xcursor = get_move_xcursor(seat->cursor->xcursor_theme); + if (xcursor != NULL) { + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); + } +} + +void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view, + uint32_t edges) { + // TODO +} + +void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view) { + // TODO +} diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index e38eb697..81b9e640 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -29,11 +29,11 @@ static void handle_request_move(struct wl_listener *listener, void *data) { struct roots_view *view = roots_surface->view; struct roots_input *input = view->desktop->server->input; struct wlr_wl_shell_surface_move_event *e = data; - const struct roots_input_event *event = get_input_event(input, e->serial); - if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_move(input, event->cursor, view); + roots_seat_begin_move(seat, view); } static void handle_request_resize(struct wl_listener *listener, void *data) { @@ -42,11 +42,12 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { struct roots_view *view = roots_surface->view; struct roots_input *input = view->desktop->server->input; struct wlr_wl_shell_surface_resize_event *e = data; - const struct roots_input_event *event = get_input_event(input, e->serial); - if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); + // TODO verify input event + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_resize(input, event->cursor, view, e->edges); + roots_seat_begin_resize(seat, view, e->edges); } static void handle_surface_commit(struct wl_listener *listener, void *data) { diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index ca33c582..4a694349 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -98,11 +98,12 @@ static void handle_request_move(struct wl_listener *listener, void *data) { struct roots_view *view = roots_xdg_surface->view; struct roots_input *input = view->desktop->server->input; struct wlr_xdg_toplevel_v6_move_event *e = data; - const struct roots_input_event *event = get_input_event(input, e->serial); - if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); + // TODO verify event serial + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_move(input, event->cursor, view); + roots_seat_begin_move(seat, view); } static void handle_request_resize(struct wl_listener *listener, void *data) { @@ -111,11 +112,12 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { struct roots_view *view = roots_xdg_surface->view; struct roots_input *input = view->desktop->server->input; struct wlr_xdg_toplevel_v6_resize_event *e = data; - const struct roots_input_event *event = get_input_event(input, e->serial); - if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + // TODO verify event serial + struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_resize(input, event->cursor, view, e->edges); + roots_seat_begin_resize(seat, view, e->edges); } static void handle_commit(struct wl_listener *listener, void *data) { diff --git a/rootston/xwayland.c b/rootston/xwayland.c index e3fc1c84..b53b98a9 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -114,22 +114,8 @@ static void handle_request_configure(struct wl_listener *listener, void *data) { // seat based on seat pointer focus, but interactive moving and resizing is not // yet seat aware. Even then, we can only guess because X11 events don't give us // enough wayland info to know for sure. -static struct wlr_cursor *guess_cursor_for_view(struct roots_view *view) { - struct roots_input *input = view->desktop->server->input; - size_t len = sizeof(input->input_events) / sizeof(*input->input_events); - for (size_t i = 0; i < len; i++) { - struct wlr_cursor *cursor = input->input_events[i].cursor; - if (cursor) { - int width = view->xwayland_surface->surface->current->width; - int height = view->xwayland_surface->surface->current->height; - if (cursor->x > view->x && cursor->y > view->y && - cursor->x < view->x + width && - cursor->y < view->y + height) { - return cursor; - } - } - } - +static struct roots_seat *guess_seat_for_view(struct roots_view *view) { + // TODO return NULL; } @@ -137,28 +123,26 @@ static void handle_request_move(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, request_move); struct roots_view *view = roots_surface->view; - struct roots_input *input = view->desktop->server->input; - struct wlr_cursor *cursor = guess_cursor_for_view(view); + struct roots_seat *seat = guess_seat_for_view(view); - if (!cursor || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_move(input, cursor, view); + roots_seat_begin_move(seat, view); } static void handle_request_resize(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, request_resize); struct roots_view *view = roots_surface->view; - struct roots_input *input = view->desktop->server->input; - struct wlr_cursor *cursor = guess_cursor_for_view(view); + struct roots_seat *seat = guess_seat_for_view(view); struct wlr_xwayland_resize_event *e = data; - if (!cursor || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_resize(input, cursor, view, e->edges); + roots_seat_begin_resize(seat, view, e->edges); } static void handle_map_notify(struct wl_listener *listener, void *data) { diff --git a/types/wlr_wl_shell.c b/types/wlr_wl_shell.c index fe61075e..ce32d186 100644 --- a/types/wlr_wl_shell.c +++ b/types/wlr_wl_shell.c @@ -110,7 +110,7 @@ static void shell_surface_protocol_move(struct wl_client *client, uint32_t serial) { wlr_log(L_DEBUG, "got shell surface move"); struct wlr_wl_shell_surface *surface = wl_resource_get_user_data(resource); - struct wlr_seat_handle *seat_handle = + struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); struct wlr_wl_shell_surface_move_event *event = @@ -121,7 +121,7 @@ static void shell_surface_protocol_move(struct wl_client *client, } event->client = client; event->surface = surface; - event->seat_handle = seat_handle; + event->seat = seat; event->serial = serial; wl_signal_emit(&surface->events.request_move, event); @@ -177,7 +177,7 @@ static void shell_surface_protocol_resize(struct wl_client *client, uint32_t serial, enum wl_shell_surface_resize edges) { wlr_log(L_DEBUG, "got shell surface resize"); struct wlr_wl_shell_surface *surface = wl_resource_get_user_data(resource); - struct wlr_seat_handle *seat_handle = + struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); struct wlr_wl_shell_surface_resize_event *event = @@ -188,7 +188,7 @@ static void shell_surface_protocol_resize(struct wl_client *client, } event->client = client; event->surface = surface; - event->seat_handle = seat_handle; + event->seat = seat; event->serial = serial; event->edges = edges; diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index fc45bc17..0c41b66f 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -557,7 +557,7 @@ static void xdg_toplevel_protocol_show_window_menu(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial, int32_t x, int32_t y) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); - struct wlr_seat_handle *seat_handle = + struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); if (!surface->configured) { @@ -576,7 +576,7 @@ static void xdg_toplevel_protocol_show_window_menu(struct wl_client *client, event->client = client; event->surface = surface; - event->seat_handle = seat_handle; + event->seat = seat; event->serial = serial; event->x = x; event->y = y; @@ -590,7 +590,7 @@ static void xdg_toplevel_protocol_move(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); - struct wlr_seat_handle *seat_handle = + struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); if (!surface->configured) { @@ -609,7 +609,7 @@ static void xdg_toplevel_protocol_move(struct wl_client *client, event->client = client; event->surface = surface; - event->seat_handle = seat_handle; + event->seat = seat; event->serial = serial; wl_signal_emit(&surface->events.request_move, event); @@ -621,7 +621,7 @@ static void xdg_toplevel_protocol_resize(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial, uint32_t edges) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); - struct wlr_seat_handle *seat_handle = + struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); if (!surface->configured) { @@ -640,7 +640,7 @@ static void xdg_toplevel_protocol_resize(struct wl_client *client, event->client = client; event->surface = surface; - event->seat_handle = seat_handle; + event->seat = seat; event->serial = serial; event->edges = edges; -- cgit v1.2.3 From a00b7f1e9bb992734f2498e597a86f1ca29b1d59 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 8 Nov 2017 09:04:33 -0500 Subject: rootston: remove devices from seat --- include/rootston/keyboard.h | 5 +---- rootston/keyboard.c | 3 +-- rootston/seat.c | 42 ++++++++++++++++++++++++++++++++++++------ 3 files changed, 38 insertions(+), 12 deletions(-) (limited to 'rootston/keyboard.c') diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index e3caf8fb..4dd70a65 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -11,8 +11,6 @@ struct roots_keyboard { struct roots_seat *seat; struct wlr_input_device *device; struct keyboard_config *config; - struct wl_list seat_link; - // XXX temporary struct wl_list link; struct wl_listener keyboard_key; @@ -24,8 +22,7 @@ struct roots_keyboard { struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, struct roots_input *input); -void roots_keyboard_destroy(struct wlr_input_device *device, - struct roots_input *input); +void roots_keyboard_destroy(struct roots_keyboard *keyboard); void roots_keyboard_handle_key(struct roots_keyboard *keyboard, struct wlr_event_keyboard_key *event); diff --git a/rootston/keyboard.c b/rootston/keyboard.c index ef5eb8ab..a770f00f 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -225,8 +225,7 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, return keyboard; } -void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input) { - struct roots_keyboard *keyboard = device->data; +void roots_keyboard_destroy(struct roots_keyboard *keyboard) { wl_list_remove(&keyboard->link); free(keyboard->config); free(keyboard); diff --git a/rootston/seat.c b/rootston/seat.c index 7fcffc29..e860c093 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -271,7 +271,7 @@ static void seat_add_keyboard(struct roots_seat *seat, struct wlr_input_device * struct roots_keyboard *keyboard = roots_keyboard_create(device, seat->input); keyboard->seat = seat; - wl_list_insert(&seat->keyboards, &keyboard->seat_link); + wl_list_insert(&seat->keyboards, &keyboard->link); keyboard->keyboard_key.notify = handle_keyboard_key; wl_signal_add(&keyboard->device->keyboard->events.key, @@ -354,17 +354,39 @@ void roots_seat_add_device(struct roots_seat *seat, static void seat_remove_keyboard(struct roots_seat *seat, struct wlr_input_device *device) { - // TODO + struct roots_keyboard *keyboard; + wl_list_for_each(keyboard, &seat->keyboards, link) { + if (keyboard->device == device) { + roots_keyboard_destroy(keyboard); + return; + } + } } static void seat_remove_pointer(struct roots_seat *seat, struct wlr_input_device *device) { - // TODO + struct roots_pointer *pointer; + wl_list_for_each(pointer, &seat->pointers, link) { + if (pointer->device == device) { + wl_list_remove(&pointer->link); + wlr_cursor_detach_input_device(seat->cursor->cursor, device); + free(pointer); + return; + } + } } static void seat_remove_touch(struct roots_seat *seat, struct wlr_input_device *device) { - // TODO + struct roots_touch *touch; + wl_list_for_each(touch, &seat->touch, link) { + if (touch->device == device) { + wl_list_remove(&touch->link); + wlr_cursor_detach_input_device(seat->cursor->cursor, device); + free(touch); + return; + } + } } static void seat_remove_tablet_pad(struct roots_seat *seat, @@ -374,7 +396,15 @@ static void seat_remove_tablet_pad(struct roots_seat *seat, static void seat_remove_tablet_tool(struct roots_seat *seat, struct wlr_input_device *device) { - // TODO + struct roots_tablet_tool *tablet_tool; + wl_list_for_each(tablet_tool, &seat->tablet_tools, link) { + if (tablet_tool->device == device) { + wl_list_remove(&tablet_tool->link); + wlr_cursor_detach_input_device(seat->cursor->cursor, device); + free(tablet_tool); + return; + } + } } void roots_seat_remove_device(struct roots_seat *seat, @@ -410,7 +440,7 @@ void roots_seat_configure_xcursor(struct roots_seat *seat) { bool roots_seat_has_meta_pressed(struct roots_seat *seat) { struct roots_keyboard *keyboard; - wl_list_for_each(keyboard, &seat->keyboards, seat_link) { + wl_list_for_each(keyboard, &seat->keyboards, link) { if (!keyboard->config->meta_key) { continue; } -- cgit v1.2.3 From 882e6206393f1931fea3de8fd2b87b91314ed6d0 Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 8 Nov 2017 19:02:56 +0100 Subject: Always read state from wlr_keyboard in the seat --- include/wlr/types/wlr_seat.h | 12 ++----- rootston/desktop.c | 1 - rootston/keyboard.c | 23 +++++-------- types/wlr_data_device.c | 5 ++- types/wlr_seat.c | 78 ++++++++++++++++++++------------------------ types/wlr_xdg_shell_v6.c | 7 ++-- 6 files changed, 52 insertions(+), 74 deletions(-) (limited to 'rootston/keyboard.c') diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index b8b467d2..09d3e282 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -45,9 +45,7 @@ struct wlr_keyboard_grab_interface { struct wlr_surface *surface); void (*key)(struct wlr_seat_keyboard_grab *grab, uint32_t time, uint32_t key, uint32_t state); - void (*modifiers)(struct wlr_seat_keyboard_grab *grab, - uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group); + void (*modifiers)(struct wlr_seat_keyboard_grab *grab); void (*cancel)(struct wlr_seat_keyboard_grab *grab); }; @@ -296,17 +294,13 @@ void wlr_seat_keyboard_notify_key(struct wlr_seat *seat, uint32_t time, * Send the modifier state to focused keyboard resources. Compositors should use * `wlr_seat_keyboard_notify_modifiers()` to respect any keyboard grabs. */ -void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group); +void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat); /** * Notify the seat that the modifiers for the keyboard have changed. Defers to * any keyboard grabs. */ -void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group); +void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat); /** * Notify the seat that the keyboard focus has changed and request it to be the diff --git a/rootston/desktop.c b/rootston/desktop.c index 29f78ac7..b36a6932 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -133,7 +133,6 @@ void view_teardown(struct roots_view *view) { struct roots_view *prev_view = views->items[views->length-2]; struct roots_input *input = prev_view->desktop->server->input; set_view_focus(input, prev_view->desktop, prev_view); - wlr_seat_keyboard_notify_enter(input->wl_seat, prev_view->wlr_surface); } struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 6c419df8..bde912aa 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -135,8 +135,8 @@ static bool keyboard_keysyms_simple(struct roots_keyboard *keyboard, const xkb_keysym_t *syms; xkb_layout_index_t layout_index = xkb_state_key_get_layout( keyboard->device->keyboard->xkb_state, keycode); - int syms_len = xkb_keymap_key_get_syms_by_level(keyboard->device->keyboard->keymap, - keycode, layout_index, 0, &syms); + int syms_len = xkb_keymap_key_get_syms_by_level( + keyboard->device->keyboard->keymap, keycode, layout_index, 0, &syms); bool handled = false; for (int i = 0; i < syms_len; i++) { @@ -195,7 +195,8 @@ static void keyboard_key_notify(struct wl_listener *listener, void *data) { bool handled = keyboard_keysyms_xkb(keyboard, keycode, event->state); if (!handled) { - bool key_handled = keyboard_keysyms_simple(keyboard, keycode, event->state); + bool key_handled = keyboard_keysyms_simple(keyboard, keycode, + event->state); handled = handled || key_handled; } @@ -207,17 +208,11 @@ static void keyboard_key_notify(struct wl_listener *listener, void *data) { } static void keyboard_modifiers_notify(struct wl_listener *listener, void *data) { - struct roots_keyboard *r_keyboard = - wl_container_of(listener, r_keyboard, modifiers); - struct wlr_seat *seat = r_keyboard->input->wl_seat; - struct wlr_keyboard *keyboard = r_keyboard->device->keyboard; - wlr_seat_set_keyboard(seat, r_keyboard->device); - wlr_seat_keyboard_notify_modifiers(seat, - keyboard->modifiers.depressed, - keyboard->modifiers.latched, - keyboard->modifiers.locked, - keyboard->modifiers.group); - + struct roots_keyboard *keyboard = + wl_container_of(listener, keyboard, modifiers); + struct wlr_seat *seat = keyboard->input->wl_seat; + wlr_seat_set_keyboard(seat, keyboard->device); + wlr_seat_keyboard_notify_modifiers(seat); } static void keyboard_config_merge(struct keyboard_config *config, diff --git a/types/wlr_data_device.c b/types/wlr_data_device.c index ee83260e..ea28ef50 100644 --- a/types/wlr_data_device.c +++ b/types/wlr_data_device.c @@ -531,9 +531,8 @@ static void keyboard_drag_key(struct wlr_seat_keyboard_grab *grab, // no keyboard input during drags } -static void keyboard_drag_modifiers(struct wlr_seat_keyboard_grab *grab, - uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group) { +static void keyboard_drag_modifiers(struct wlr_seat_keyboard_grab *grab) { + //struct wlr_keyboard *keyboard = grab->seat->keyboard_state.keyboard; // TODO change the dnd action based on what modifier is pressed on the // keyboard } diff --git a/types/wlr_seat.c b/types/wlr_seat.c index ae991383..9de1b3a0 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -284,11 +284,8 @@ static void default_keyboard_key(struct wlr_seat_keyboard_grab *grab, wlr_seat_keyboard_send_key(grab->seat, time, key, state); } -static void default_keyboard_modifiers(struct wlr_seat_keyboard_grab *grab, - uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group) { - wlr_seat_keyboard_send_modifiers(grab->seat, mods_depressed, - mods_latched, mods_locked, group); +static void default_keyboard_modifiers(struct wlr_seat_keyboard_grab *grab) { + wlr_seat_keyboard_send_modifiers(grab->seat); } static void default_keyboard_cancel(struct wlr_seat_keyboard_grab *grab) { @@ -708,24 +705,26 @@ static void keyboard_resource_destroy_notify(struct wl_listener *listener, wlr_seat_keyboard_clear_focus(state->seat); } -void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group) { +void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat) { struct wlr_seat_client *client = seat->keyboard_state.focused_client; if (!client || !client->keyboard) { return; } - uint32_t serial = wl_display_next_serial(seat->display); + struct wlr_keyboard *keyboard = seat->keyboard_state.keyboard; + if (!keyboard) { + return; + } + uint32_t serial = wl_display_next_serial(seat->display); wl_keyboard_send_modifiers(client->keyboard, serial, - mods_depressed, mods_latched, - mods_locked, group); + keyboard->modifiers.depressed, keyboard->modifiers.latched, + keyboard->modifiers.locked, keyboard->modifiers.group); } -void wlr_seat_keyboard_enter(struct wlr_seat *wlr_seat, +void wlr_seat_keyboard_enter(struct wlr_seat *seat, struct wlr_surface *surface) { - if (wlr_seat->keyboard_state.focused_surface == surface) { + if (seat->keyboard_state.focused_surface == surface) { // this surface already got an enter notify return; } @@ -734,24 +733,24 @@ void wlr_seat_keyboard_enter(struct wlr_seat *wlr_seat, if (surface) { struct wl_client *wl_client = wl_resource_get_client(surface->resource); - client = wlr_seat_client_for_wl_client(wlr_seat, wl_client); + client = wlr_seat_client_for_wl_client(seat, wl_client); } struct wlr_seat_client *focused_client = - wlr_seat->keyboard_state.focused_client; + seat->keyboard_state.focused_client; struct wlr_surface *focused_surface = - wlr_seat->keyboard_state.focused_surface; + seat->keyboard_state.focused_surface; // leave the previously entered surface if (focused_client && focused_client->keyboard && focused_surface) { - uint32_t serial = wl_display_next_serial(wlr_seat->display); + uint32_t serial = wl_display_next_serial(seat->display); wl_keyboard_send_leave(focused_client->keyboard, serial, focused_surface->resource); } // enter the current surface - if (client && client->keyboard) { - struct wlr_keyboard *keyboard = wlr_seat->keyboard_state.keyboard; + if (client && client->keyboard && seat->keyboard_state.keyboard) { + struct wlr_keyboard *keyboard = seat->keyboard_state.keyboard; struct wl_array keys; wl_array_init(&keys); @@ -763,55 +762,50 @@ void wlr_seat_keyboard_enter(struct wlr_seat *wlr_seat, n++; } } - uint32_t serial = wl_display_next_serial(wlr_seat->display); + uint32_t serial = wl_display_next_serial(seat->display); wl_keyboard_send_enter(client->keyboard, serial, surface->resource, &keys); wl_array_release(&keys); - wlr_seat_keyboard_send_modifiers(wlr_seat, - keyboard->modifiers.depressed, keyboard->modifiers.latched, - keyboard->modifiers.locked, keyboard->modifiers.group); + wlr_seat_keyboard_send_modifiers(seat); wlr_seat_client_send_selection(client); } // reinitialize the focus destroy events - wl_list_remove(&wlr_seat->keyboard_state.surface_destroy.link); - wl_list_init(&wlr_seat->keyboard_state.surface_destroy.link); - wl_list_remove(&wlr_seat->keyboard_state.resource_destroy.link); - wl_list_init(&wlr_seat->keyboard_state.resource_destroy.link); + wl_list_remove(&seat->keyboard_state.surface_destroy.link); + wl_list_init(&seat->keyboard_state.surface_destroy.link); + wl_list_remove(&seat->keyboard_state.resource_destroy.link); + wl_list_init(&seat->keyboard_state.resource_destroy.link); if (surface) { wl_signal_add(&surface->events.destroy, - &wlr_seat->keyboard_state.surface_destroy); + &seat->keyboard_state.surface_destroy); wl_resource_add_destroy_listener(surface->resource, - &wlr_seat->keyboard_state.resource_destroy); - wlr_seat->keyboard_state.resource_destroy.notify = + &seat->keyboard_state.resource_destroy); + seat->keyboard_state.resource_destroy.notify = keyboard_resource_destroy_notify; - wlr_seat->keyboard_state.surface_destroy.notify = + seat->keyboard_state.surface_destroy.notify = keyboard_surface_destroy_notify; } - wlr_seat->keyboard_state.focused_client = client; - wlr_seat->keyboard_state.focused_surface = surface; + seat->keyboard_state.focused_client = client; + seat->keyboard_state.focused_surface = surface; } -void wlr_seat_keyboard_notify_enter(struct wlr_seat *wlr_seat, struct +void wlr_seat_keyboard_notify_enter(struct wlr_seat *seat, struct wlr_surface *surface) { - struct wlr_seat_keyboard_grab *grab = wlr_seat->keyboard_state.grab; + struct wlr_seat_keyboard_grab *grab = seat->keyboard_state.grab; grab->interface->enter(grab, surface); } -void wlr_seat_keyboard_clear_focus(struct wlr_seat *wlr_seat) { +void wlr_seat_keyboard_clear_focus(struct wlr_seat *seat) { struct wl_array keys; wl_array_init(&keys); - wlr_seat_keyboard_enter(wlr_seat, NULL); + wlr_seat_keyboard_enter(seat, NULL); } -void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group) { +void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat) { struct wlr_seat_keyboard_grab *grab = seat->keyboard_state.grab; - grab->interface->modifiers(grab, - mods_depressed, mods_latched, mods_locked, group); + grab->interface->modifiers(grab); } void wlr_seat_keyboard_notify_key(struct wlr_seat *seat, uint32_t time, diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index fc45bc17..ef4ae42e 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -111,11 +111,8 @@ static void xdg_keyboard_grab_key(struct wlr_seat_keyboard_grab *grab, uint32_t wlr_seat_keyboard_send_key(grab->seat, time, key, state); } -static void xdg_keyboard_grab_modifiers(struct wlr_seat_keyboard_grab *grab, - uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group) { - wlr_seat_keyboard_send_modifiers(grab->seat, mods_depressed, mods_latched, - mods_locked, group); +static void xdg_keyboard_grab_modifiers(struct wlr_seat_keyboard_grab *grab) { + wlr_seat_keyboard_send_modifiers(grab->seat); } static void xdg_keyboard_grab_cancel(struct wlr_seat_keyboard_grab *grab) { -- cgit v1.2.3 From 739361aa70d61cbc9e062d6a90df09f258a1bbcb Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 9 Nov 2017 17:29:28 -0500 Subject: wlr-keyboard: take out modifiers event struct (for now) --- backend/libinput/keyboard.c | 1 - backend/wayland/wl_seat.c | 12 ++---------- backend/x11/backend.c | 1 - include/rootston/keyboard.h | 3 +-- include/wlr/interfaces/wlr_keyboard.h | 3 ++- include/wlr/types/wlr_keyboard.h | 11 ----------- rootston/keyboard.c | 3 +-- rootston/seat.c | 3 +-- types/wlr_keyboard.c | 11 ++++++----- 9 files changed, 13 insertions(+), 35 deletions(-) (limited to 'rootston/keyboard.c') diff --git a/backend/libinput/keyboard.c b/backend/libinput/keyboard.c index 9a24c791..065d8ead 100644 --- a/backend/libinput/keyboard.c +++ b/backend/libinput/keyboard.c @@ -54,7 +54,6 @@ void handle_keyboard_key(struct libinput_event *event, struct libinput_event_keyboard *kbevent = libinput_event_get_keyboard_event(event); struct wlr_event_keyboard_key wlr_event = { 0 }; - wlr_event.device = wlr_dev; wlr_event.time_msec = usec_to_msec(libinput_event_keyboard_get_time_usec(kbevent)); wlr_event.keycode = libinput_event_keyboard_get_key(kbevent); diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index 74eaf9bd..a2da8df5 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -151,7 +151,6 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, assert(dev && dev->keyboard); struct wlr_event_keyboard_key wlr_event; - wlr_event.device = dev; wlr_event.keycode = key; wlr_event.state = state; wlr_event.time_msec = time; @@ -163,15 +162,8 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboar uint32_t mods_locked, uint32_t group) { struct wlr_input_device *dev = data; assert(dev && dev->keyboard); - struct wlr_event_keyboard_modifiers wlr_event; - wlr_event.device = dev; - wlr_event.keyboard = dev->keyboard; - wlr_event.mods_depressed = mods_depressed; - wlr_event.mods_latched = mods_latched; - wlr_event.mods_locked = mods_locked; - wlr_event.group = group; - - wlr_keyboard_notify_modifiers(dev->keyboard, &wlr_event); + wlr_keyboard_notify_modifiers(dev->keyboard, mods_depressed, mods_latched, + mods_locked, group); } static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, diff --git a/backend/x11/backend.c b/backend/x11/backend.c index f76b314e..97b0dd8c 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -50,7 +50,6 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e case XCB_KEY_RELEASE: { xcb_key_press_event_t *ev = (xcb_key_press_event_t *)event; struct wlr_event_keyboard_key key = { - .device = &x11->keyboard_dev, .time_msec = ev->time, .keycode = ev->detail - 8, .state = event->response_type == XCB_KEY_PRESS ? diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index 4dd70a65..51977f08 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -27,7 +27,6 @@ void roots_keyboard_destroy(struct roots_keyboard *keyboard); void roots_keyboard_handle_key(struct roots_keyboard *keyboard, struct wlr_event_keyboard_key *event); -void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard, - struct wlr_event_keyboard_modifiers *event); +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard); #endif diff --git a/include/wlr/interfaces/wlr_keyboard.h b/include/wlr/interfaces/wlr_keyboard.h index 5848416d..570f5721 100644 --- a/include/wlr/interfaces/wlr_keyboard.h +++ b/include/wlr/interfaces/wlr_keyboard.h @@ -14,6 +14,7 @@ void wlr_keyboard_destroy(struct wlr_keyboard *keyboard); void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, struct wlr_event_keyboard_key *event); void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, - struct wlr_event_keyboard_modifiers *event); + uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, + uint32_t group); #endif diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h index 4bd5b9b6..e2d50b03 100644 --- a/include/wlr/types/wlr_keyboard.h +++ b/include/wlr/types/wlr_keyboard.h @@ -66,23 +66,12 @@ enum wlr_key_state { }; struct wlr_event_keyboard_key { - struct wlr_input_device *device; - struct wlr_keyboard *keyboard; uint32_t time_msec; uint32_t keycode; bool update_state; enum wlr_key_state state; }; -struct wlr_event_keyboard_modifiers { - struct wlr_input_device *device; - struct wlr_keyboard *keyboard; - uint32_t mods_depressed; - uint32_t mods_latched; - uint32_t mods_locked; - uint32_t group; -}; - void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, struct xkb_keymap *keymap); void wlr_keyboard_led_update(struct wlr_keyboard *keyboard, uint32_t leds); diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 9692ea7d..da75b44f 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -204,8 +204,7 @@ void roots_keyboard_handle_key(struct roots_keyboard *keyboard, } } -void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard, - struct wlr_event_keyboard_modifiers *event) { +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) { struct wlr_seat *seat = r_keyboard->seat->seat; wlr_seat_set_keyboard(seat, r_keyboard->device); wlr_seat_keyboard_notify_modifiers(seat); diff --git a/rootston/seat.c b/rootston/seat.c index ce8ad10b..97d5c7e4 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -22,8 +22,7 @@ static void handle_keyboard_modifiers(struct wl_listener *listener, void *data) { struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, keyboard_modifiers); - struct wlr_event_keyboard_modifiers *event = data; - roots_keyboard_handle_modifiers(keyboard, event); + roots_keyboard_handle_modifiers(keyboard); } static void handle_cursor_motion(struct wl_listener *listener, void *data) { diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index a301c6e0..98ebeed5 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -41,6 +41,8 @@ static void keyboard_modifier_update(struct wlr_keyboard *keyboard) { keyboard->modifiers.latched = latched; keyboard->modifiers.locked = locked; keyboard->modifiers.group = group; + + wl_signal_emit(&keyboard->events.modifiers, keyboard); } static void keyboard_key_update(struct wlr_keyboard *keyboard, @@ -68,15 +70,14 @@ static void keyboard_key_update(struct wlr_keyboard *keyboard, } void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, - struct wlr_event_keyboard_modifiers *event) { + uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, + uint32_t group) { if (!keyboard->xkb_state) { return; } - xkb_state_update_mask(keyboard->xkb_state, event->mods_depressed, - event->mods_latched, event->mods_locked, 0, 0, event->group); + xkb_state_update_mask(keyboard->xkb_state, mods_depressed, mods_latched, + mods_locked, 0, 0, group); keyboard_modifier_update(keyboard); - - wl_signal_emit(&keyboard->events.modifiers, event); } void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, -- cgit v1.2.3 From d6513cef5dc3f2c20e1bf11ff6a468b60ce35aca Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 9 Nov 2017 17:47:59 -0500 Subject: rootston: add missing properties to kb config merge --- rootston/keyboard.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'rootston/keyboard.c') diff --git a/rootston/keyboard.c b/rootston/keyboard.c index da75b44f..72567eef 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -230,6 +230,12 @@ static void keyboard_config_merge(struct keyboard_config *config, if (config->options == NULL) { config->options = fallback->options; } + if (config->meta_key == 0) { + config->meta_key = fallback->meta_key; + } + if (config->name == NULL) { + config->name = fallback->name; + } } struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, -- cgit v1.2.3 From 1472dbda74dea5387a4d0e531b641734131dc705 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 9 Nov 2017 18:32:54 -0500 Subject: rootston: roots_keyboard null check --- rootston/keyboard.c | 4 ++++ rootston/seat.c | 5 +++++ 2 files changed, 9 insertions(+) (limited to 'rootston/keyboard.c') diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 72567eef..bb748550 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -249,6 +249,10 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, keyboard->input = input; struct keyboard_config *config = calloc(1, sizeof(struct keyboard_config)); + if (config == NULL) { + free(keyboard); + return NULL; + } keyboard_config_merge(config, config_get_keyboard(input->config, device)); keyboard_config_merge(config, config_get_keyboard(input->config, NULL)); diff --git a/rootston/seat.c b/rootston/seat.c index 97d5c7e4..72e94aec 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -306,6 +306,11 @@ void roots_seat_destroy(struct roots_seat *seat) { static void seat_add_keyboard(struct roots_seat *seat, struct wlr_input_device *device) { assert(device->type == WLR_INPUT_DEVICE_KEYBOARD); struct roots_keyboard *keyboard = roots_keyboard_create(device, seat->input); + if (keyboard == NULL) { + wlr_log(L_ERROR, "could not allocate keyboard for seat"); + return; + } + keyboard->seat = seat; wl_list_insert(&seat->keyboards, &keyboard->link); -- cgit v1.2.3 From 1db3b5512821b1d6f936897f598e0f4d12233e8e Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sat, 11 Nov 2017 10:59:04 -0500 Subject: rootston: prefix config structs and functions --- include/rootston/config.h | 18 +++++++++--------- include/rootston/keyboard.h | 2 +- rootston/config.c | 42 ++++++++++++++++++++++-------------------- rootston/input.c | 3 ++- rootston/keyboard.c | 15 ++++++++------- rootston/main.c | 2 +- rootston/output.c | 6 ++++-- rootston/seat.c | 8 ++++---- 8 files changed, 51 insertions(+), 45 deletions(-) (limited to 'rootston/keyboard.c') diff --git a/include/rootston/config.h b/include/rootston/config.h index d2a25b5b..71ee61c7 100644 --- a/include/rootston/config.h +++ b/include/rootston/config.h @@ -3,7 +3,7 @@ #include #include -struct output_config { +struct roots_output_config { char *name; enum wl_output_transform transform; int x, y; @@ -15,7 +15,7 @@ struct output_config { } mode; }; -struct device_config { +struct roots_device_config { char *name; char *mapped_output; struct wlr_box *mapped_box; @@ -23,7 +23,7 @@ struct device_config { struct wl_list link; }; -struct binding_config { +struct roots_binding_config { uint32_t modifiers; xkb_keysym_t *keysyms; size_t keysyms_len; @@ -31,7 +31,7 @@ struct binding_config { struct wl_list link; }; -struct keyboard_config { +struct roots_keyboard_config { char *name; uint32_t meta_key; char *rules; @@ -63,7 +63,7 @@ struct roots_config { * arguments can specify the location of the config file. If it is not * specified, the default location will be used. */ -struct roots_config *parse_args(int argc, char *argv[]); +struct roots_config *roots_config_create_from_args(int argc, char *argv[]); /** * Destroy the config and free its resources. @@ -74,21 +74,21 @@ void roots_config_destroy(struct roots_config *config); * Get configuration for the output. If the output is not configured, returns * NULL. */ -struct output_config *config_get_output(struct roots_config *config, +struct roots_output_config *roots_config_get_output(struct roots_config *config, struct wlr_output *output); /** * Get configuration for the device. If the device is not configured, returns * NULL. */ -struct device_config *config_get_device(struct roots_config *config, +struct roots_device_config *roots_config_get_device(struct roots_config *config, struct wlr_input_device *device); /** * Get configuration for the keyboard. If the keyboard is not configured, * returns NULL. A NULL device returns the default config for keyboards. */ -struct keyboard_config *config_get_keyboard(struct roots_config *config, - struct wlr_input_device *device); +struct roots_keyboard_config *roots_config_get_keyboard( + struct roots_config *config, struct wlr_input_device *device); #endif diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index 51977f08..15e7c9c4 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -10,7 +10,7 @@ struct roots_keyboard { struct roots_input *input; struct roots_seat *seat; struct wlr_input_device *device; - struct keyboard_config *config; + struct roots_keyboard_config *config; struct wl_list link; struct wl_listener keyboard_key; diff --git a/rootston/config.c b/rootston/config.c index 73bb6eb0..9530ba37 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -115,7 +115,8 @@ static uint32_t parse_modifier(const char *symname) { void add_binding_config(struct wl_list *bindings, const char* combination, const char* command) { - struct binding_config *bc = calloc(1, sizeof(struct binding_config)); + struct roots_binding_config *bc = + calloc(1, sizeof(struct roots_binding_config)); xkb_keysym_t keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; char *symnames = strdup(combination); @@ -151,7 +152,7 @@ void add_binding_config(struct wl_list *bindings, const char* combination, static void config_handle_keyboard(struct roots_config *config, const char *device_name, const char *name, const char *value) { - struct keyboard_config *kc; + struct roots_keyboard_config *kc; bool found = false; wl_list_for_each(kc, &config->keyboards, link) { if (strcmp(kc->name, device_name) == 0) { @@ -161,7 +162,7 @@ static void config_handle_keyboard(struct roots_config *config, } if (!found) { - kc = calloc(1, sizeof(struct keyboard_config)); + kc = calloc(1, sizeof(struct roots_keyboard_config)); kc->name = strdup(device_name); wl_list_insert(&config->keyboards, &kc->link); } @@ -207,7 +208,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, } } else if (strncmp(output_prefix, section, strlen(output_prefix)) == 0) { const char *output_name = section + strlen(output_prefix); - struct output_config *oc; + struct roots_output_config *oc; bool found = false; wl_list_for_each(oc, &config->outputs, link) { @@ -218,7 +219,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, } if (!found) { - oc = calloc(1, sizeof(struct output_config)); + oc = calloc(1, sizeof(struct roots_output_config)); oc->name = strdup(output_name); oc->transform = WL_OUTPUT_TRANSFORM_NORMAL; oc->scale = 1; @@ -281,7 +282,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, } else if (strncmp(device_prefix, section, strlen(device_prefix)) == 0) { const char *device_name = section + strlen(device_prefix); - struct device_config *dc; + struct roots_device_config *dc; bool found = false; wl_list_for_each(dc, &config->devices, link) { if (strcmp(dc->name, device_name) == 0) { @@ -291,7 +292,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, } if (!found) { - dc = calloc(1, sizeof(struct device_config)); + dc = calloc(1, sizeof(struct roots_device_config)); dc->name = strdup(device_name); dc->seat = strdup("seat0"); wl_list_insert(&config->devices, &dc->link); @@ -323,7 +324,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, return 1; } -struct roots_config *parse_args(int argc, char *argv[]) { +struct roots_config *roots_config_create_from_args(int argc, char *argv[]) { struct roots_config *config = calloc(1, sizeof(struct roots_config)); if (config == NULL) { return NULL; @@ -370,7 +371,8 @@ struct roots_config *parse_args(int argc, char *argv[]) { add_binding_config(&config->bindings, "Logo+Shift+E", "exit"); add_binding_config(&config->bindings, "Ctrl+q", "close"); add_binding_config(&config->bindings, "Alt+Tab", "next_window"); - struct keyboard_config *kc = calloc(1, sizeof(struct keyboard_config)); + struct roots_keyboard_config *kc = + calloc(1, sizeof(struct roots_keyboard_config)); kc->meta_key = WLR_MODIFIER_LOGO; kc->name = strdup(""); wl_list_insert(&config->keyboards, &kc->link); @@ -386,13 +388,13 @@ struct roots_config *parse_args(int argc, char *argv[]) { } void roots_config_destroy(struct roots_config *config) { - struct output_config *oc, *otmp = NULL; + struct roots_output_config *oc, *otmp = NULL; wl_list_for_each_safe(oc, otmp, &config->outputs, link) { free(oc->name); free(oc); } - struct device_config *dc, *dtmp = NULL; + struct roots_device_config *dc, *dtmp = NULL; wl_list_for_each_safe(dc, dtmp, &config->devices, link) { free(dc->name); free(dc->seat); @@ -401,7 +403,7 @@ void roots_config_destroy(struct roots_config *config) { free(dc); } - struct keyboard_config *kc, *ktmp = NULL; + struct roots_keyboard_config *kc, *ktmp = NULL; wl_list_for_each_safe(kc, ktmp, &config->bindings, link) { free(kc->name); free(kc->rules); @@ -412,7 +414,7 @@ void roots_config_destroy(struct roots_config *config) { free(kc); } - struct binding_config *bc, *btmp = NULL; + struct roots_binding_config *bc, *btmp = NULL; wl_list_for_each_safe(bc, btmp, &config->bindings, link) { free(bc->keysyms); free(bc->command); @@ -425,9 +427,9 @@ void roots_config_destroy(struct roots_config *config) { free(config); } -struct output_config *config_get_output(struct roots_config *config, +struct roots_output_config *roots_config_get_output(struct roots_config *config, struct wlr_output *output) { - struct output_config *o_config; + struct roots_output_config *o_config; wl_list_for_each(o_config, &config->outputs, link) { if (strcmp(o_config->name, output->name) == 0) { return o_config; @@ -437,9 +439,9 @@ struct output_config *config_get_output(struct roots_config *config, return NULL; } -struct device_config *config_get_device(struct roots_config *config, +struct roots_device_config *roots_config_get_device(struct roots_config *config, struct wlr_input_device *device) { - struct device_config *d_config; + struct roots_device_config *d_config; wl_list_for_each(d_config, &config->devices, link) { if (strcmp(d_config->name, device->name) == 0) { return d_config; @@ -449,9 +451,9 @@ struct device_config *config_get_device(struct roots_config *config, return NULL; } -struct keyboard_config *config_get_keyboard(struct roots_config *config, - struct wlr_input_device *device) { - struct keyboard_config *kc; +struct roots_keyboard_config *roots_config_get_keyboard( + struct roots_config *config, struct wlr_input_device *device) { + struct roots_keyboard_config *kc; wl_list_for_each(kc, &config->keyboards, link) { if ((device != NULL && strcmp(kc->name, device->name) == 0) || (device == NULL && strcmp(kc->name, "") == 0)) { diff --git a/rootston/input.c b/rootston/input.c index e96565e0..35a5af97 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -44,7 +44,8 @@ static void input_add_notify(struct wl_listener *listener, void *data) { struct roots_input *input = wl_container_of(listener, input, input_add); char *seat_name = "seat0"; - struct device_config *dc = config_get_device(input->config, device); + struct roots_device_config *dc = + roots_config_get_device(input->config, device); if (dc) { seat_name = dc->seat; } diff --git a/rootston/keyboard.c b/rootston/keyboard.c index bb748550..c118e55c 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -92,7 +92,7 @@ static bool keyboard_keysym_press(struct roots_keyboard *keyboard, uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); struct wl_list *bindings = &keyboard->input->server->config->bindings; - struct binding_config *bc; + struct roots_binding_config *bc; wl_list_for_each(bc, bindings, link) { if (modifiers ^ bc->modifiers) { continue; @@ -210,8 +210,8 @@ void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) { wlr_seat_keyboard_notify_modifiers(seat); } -static void keyboard_config_merge(struct keyboard_config *config, - struct keyboard_config *fallback) { +static void keyboard_config_merge(struct roots_keyboard_config *config, + struct roots_keyboard_config *fallback) { if (fallback == NULL) { return; } @@ -248,15 +248,16 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, keyboard->device = device; keyboard->input = input; - struct keyboard_config *config = calloc(1, sizeof(struct keyboard_config)); + struct roots_keyboard_config *config = + calloc(1, sizeof(struct roots_keyboard_config)); if (config == NULL) { free(keyboard); return NULL; } - keyboard_config_merge(config, config_get_keyboard(input->config, device)); - keyboard_config_merge(config, config_get_keyboard(input->config, NULL)); + keyboard_config_merge(config, roots_config_get_keyboard(input->config, device)); + keyboard_config_merge(config, roots_config_get_keyboard(input->config, NULL)); - struct keyboard_config env_config = { + struct roots_keyboard_config env_config = { .rules = getenv("XKB_DEFAULT_RULES"), .model = getenv("XKB_DEFAULT_MODEL"), .layout = getenv("XKB_DEFAULT_LAYOUT"), diff --git a/rootston/main.c b/rootston/main.c index 2a054e6c..d55bc682 100644 --- a/rootston/main.c +++ b/rootston/main.c @@ -13,7 +13,7 @@ struct roots_server server = { 0 }; int main(int argc, char **argv) { - assert(server.config = parse_args(argc, argv)); + assert(server.config = roots_config_create_from_args(argc, argv)); assert(server.wl_display = wl_display_create()); assert(server.wl_event_loop = wl_display_get_event_loop(server.wl_display)); diff --git a/rootston/output.c b/rootston/output.c index f192cb48..d853c45f 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -181,7 +181,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { output->last_frame = desktop->last_frame = now; } -static void set_mode(struct wlr_output *output, struct output_config *oc) { +static void set_mode(struct wlr_output *output, + struct roots_output_config *oc) { struct wlr_output_mode *mode, *best = NULL; int mhz = (int)(oc->mode.refresh_rate * 1000); wl_list_for_each(mode, &output->modes, link) { @@ -225,7 +226,8 @@ void output_add_notify(struct wl_listener *listener, void *data) { wl_signal_add(&wlr_output->events.frame, &output->frame); wl_list_insert(&desktop->outputs, &output->link); - struct output_config *output_config = config_get_output(config, wlr_output); + struct roots_output_config *output_config = + roots_config_get_output(config, wlr_output); if (output_config) { if (output_config->mode.width) { set_mode(wlr_output, output_config); diff --git a/rootston/seat.c b/rootston/seat.c index 3530fb75..4602aad5 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -117,8 +117,8 @@ static void seat_reset_device_mappings(struct roots_seat *seat, struct wlr_input struct roots_config *config = seat->input->config; wlr_cursor_map_input_to_output(cursor, device, NULL); - struct device_config *dconfig; - if ((dconfig = config_get_device(config, device))) { + struct roots_device_config *dconfig; + if ((dconfig = roots_config_get_device(config, device))) { wlr_cursor_map_input_to_region(cursor, device, dconfig->mapped_box); } } @@ -127,8 +127,8 @@ static void seat_set_device_output_mappings(struct roots_seat *seat, struct wlr_input_device *device, struct wlr_output *output) { struct wlr_cursor *cursor = seat->cursor->cursor; struct roots_config *config = seat->input->config; - struct device_config *dconfig; - dconfig = config_get_device(config, device); + struct roots_device_config *dconfig; + dconfig = roots_config_get_device(config, device); if (dconfig && dconfig->mapped_output && strcmp(dconfig->mapped_output, output->name) == 0) { wlr_cursor_map_input_to_output(cursor, device, output); -- cgit v1.2.3 From bb79ada49f43be5417bdd55fda3a7cf07c2a69df Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 16 Nov 2017 10:30:54 +0100 Subject: Fix a bunch of mistakes detected with scan-build --- backend/libinput/events.c | 5 +++-- backend/session/session.c | 2 +- rootston/config.c | 2 +- rootston/cursor.c | 2 +- rootston/keyboard.c | 1 + rootston/seat.c | 1 - types/wlr_data_device.c | 5 ++++- types/wlr_keyboard.c | 5 ++++- types/wlr_screenshooter.c | 3 +++ types/wlr_wl_shell.c | 2 +- 10 files changed, 19 insertions(+), 9 deletions(-) (limited to 'rootston/keyboard.c') diff --git a/backend/libinput/events.c b/backend/libinput/events.c index 5da45c67..3ca41124 100644 --- a/backend/libinput/events.c +++ b/backend/libinput/events.c @@ -66,10 +66,11 @@ static void handle_device_added(struct wlr_libinput_backend *backend, int product = libinput_device_get_id_product(libinput_dev); const char *name = libinput_device_get_name(libinput_dev); struct wl_list *wlr_devices = calloc(1, sizeof(struct wl_list)); - wl_list_init(wlr_devices); if (!wlr_devices) { - goto fail; + wlr_log(L_ERROR, "Allocation failed"); + return; } + wl_list_init(wlr_devices); wlr_log(L_DEBUG, "Added %s [%d:%d]", name, vendor, product); if (libinput_device_has_capability(libinput_dev, LIBINPUT_DEVICE_CAP_KEYBOARD)) { diff --git a/backend/session/session.c b/backend/session/session.c index 760830c3..657558fd 100644 --- a/backend/session/session.c +++ b/backend/session/session.c @@ -249,7 +249,7 @@ static size_t explicit_find_gpus(struct wlr_session *session, } } while ((ptr = strtok_r(NULL, ":", &save))); - free(ptr); + free(gpus); return i; } diff --git a/rootston/config.c b/rootston/config.c index 7ffbb786..727b52d0 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -405,7 +405,7 @@ void roots_config_destroy(struct roots_config *config) { } struct roots_keyboard_config *kc, *ktmp = NULL; - wl_list_for_each_safe(kc, ktmp, &config->bindings, link) { + wl_list_for_each_safe(kc, ktmp, &config->keyboards, link) { free(kc->name); free(kc->rules); free(kc->model); diff --git a/rootston/cursor.c b/rootston/cursor.c index ecd5e9a0..5949a364 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -18,9 +18,9 @@ struct roots_cursor *roots_cursor_create(struct roots_seat *seat) { } cursor->cursor = wlr_cursor_create(); if (!cursor->cursor) { + free(cursor); return NULL; } - return cursor; } diff --git a/rootston/keyboard.c b/rootston/keyboard.c index c118e55c..fb648ae5 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -141,6 +141,7 @@ static bool keyboard_keysyms_xkb(struct roots_keyboard *keyboard, uint32_t consumed = xkb_state_key_get_consumed_mods2( keyboard->device->keyboard->xkb_state, keycode, XKB_CONSUMED_MODE_XKB); + // TODO: actually use this value modifiers = modifiers & ~consumed; bool handled = false; diff --git a/rootston/seat.c b/rootston/seat.c index 6d8dc749..1fa37c44 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -252,7 +252,6 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { seat->seat = wlr_seat_create(input->server->wl_display, name); if (!seat->seat) { free(seat); - roots_cursor_destroy(seat->cursor); return NULL; } diff --git a/types/wlr_data_device.c b/types/wlr_data_device.c index df18317b..4d926236 100644 --- a/types/wlr_data_device.c +++ b/types/wlr_data_device.c @@ -636,7 +636,10 @@ static void data_device_start_drag(struct wl_client *client, if (!seat_client_start_drag(seat_client, source, icon)) { wl_resource_post_no_memory(device_resource); - } else { + return; + } + + if (source) { source->seat_client = seat_client; } } diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index 98ebeed5..c4f2ed52 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -105,7 +105,10 @@ void wlr_keyboard_init(struct wlr_keyboard *kb, } void wlr_keyboard_destroy(struct wlr_keyboard *kb) { - if (kb && kb->impl && kb->impl->destroy) { + if (kb == NULL) { + return; + } + if (kb->impl && kb->impl->destroy) { kb->impl->destroy(kb); } else { wl_list_remove(&kb->events.key.listener_list); diff --git a/types/wlr_screenshooter.c b/types/wlr_screenshooter.c index a78c7ad7..94b45384 100644 --- a/types/wlr_screenshooter.c +++ b/types/wlr_screenshooter.c @@ -85,6 +85,7 @@ static void screenshooter_shoot(struct wl_client *client, struct wlr_screenshot *screenshot = calloc(1, sizeof(struct wlr_screenshot)); if (!screenshot) { + free(pixels); wl_resource_post_no_memory(screenshooter_resource); return; } @@ -96,6 +97,7 @@ static void screenshooter_shoot(struct wl_client *client, wl_resource_get_version(screenshooter_resource), id); if (screenshot->resource == NULL) { free(screenshot); + free(pixels); wl_resource_post_no_memory(screenshooter_resource); return; } @@ -109,6 +111,7 @@ static void screenshooter_shoot(struct wl_client *client, if (!state) { wl_resource_destroy(screenshot->resource); free(screenshot); + free(pixels); wl_resource_post_no_memory(screenshooter_resource); return; } diff --git a/types/wlr_wl_shell.c b/types/wlr_wl_shell.c index 31032fef..abe967d7 100644 --- a/types/wlr_wl_shell.c +++ b/types/wlr_wl_shell.c @@ -347,7 +347,7 @@ static void shell_surface_protocol_set_popup(struct wl_client *client, transient_state->flags = flags; struct wlr_wl_shell_surface_popup_state *popup_state = - calloc(1, sizeof(struct wlr_wl_shell_surface_transient_state)); + calloc(1, sizeof(struct wlr_wl_shell_surface_popup_state)); if (popup_state == NULL) { free(transient_state); wl_client_post_no_memory(client); -- cgit v1.2.3 From 53d4cb47ffae0f8632ba7aea1687fdf75dd7deb8 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 16 Nov 2017 16:13:23 +0100 Subject: Refactor rootston keyboard --- include/rootston/keyboard.h | 3 +- rootston/keyboard.c | 159 ++++++++++++++++++++++++-------------------- 2 files changed, 90 insertions(+), 72 deletions(-) (limited to 'rootston/keyboard.c') diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index 15e7c9c4..39650d7c 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -16,7 +16,8 @@ struct roots_keyboard { struct wl_listener keyboard_key; struct wl_listener keyboard_modifiers; - xkb_keysym_t pressed_keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; + xkb_keysym_t pressed_keysyms_translated[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; + xkb_keysym_t pressed_keysyms_raw[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; }; struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, diff --git a/rootston/keyboard.c b/rootston/keyboard.c index fb648ae5..566a1d7e 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -13,16 +13,35 @@ #include "rootston/seat.h" #include "rootston/keyboard.h" -static ssize_t keyboard_pressed_keysym_index(struct roots_keyboard *keyboard, +static ssize_t pressed_keysyms_index(xkb_keysym_t *pressed_keysyms, xkb_keysym_t keysym) { - for (size_t i = 0; i < ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP; i++) { - if (keyboard->pressed_keysyms[i] == keysym) { + for (size_t i = 0; i < ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP; ++i) { + if (pressed_keysyms[i] == keysym) { return i; } } return -1; } +static void pressed_keysyms_add(xkb_keysym_t *pressed_keysyms, + xkb_keysym_t keysym) { + ssize_t i = pressed_keysyms_index(pressed_keysyms, keysym); + if (i < 0) { + i = pressed_keysyms_index(pressed_keysyms, XKB_KEY_NoSymbol); + if (i >= 0) { + pressed_keysyms[i] = keysym; + } + } +} + +static void pressed_keysyms_remove(xkb_keysym_t *pressed_keysyms, + xkb_keysym_t keysym) { + ssize_t i = pressed_keysyms_index(pressed_keysyms, keysym); + if (i >= 0) { + pressed_keysyms[i] = XKB_KEY_NoSymbol; + } +} + static const char *exec_prefix = "exec "; static void keyboard_binding_execute(struct roots_keyboard *keyboard, @@ -56,21 +75,13 @@ static void keyboard_binding_execute(struct roots_keyboard *keyboard, } /** - * Process a keypress from the keyboard. + * Execute a built-in, hardcoded compositor action when a keysym is pressed. * * Returns true if the keysym was handled by a binding and false if the event * should be propagated to clients. */ -static bool keyboard_keysym_press(struct roots_keyboard *keyboard, +static bool keyboard_press_keysym(struct roots_keyboard *keyboard, xkb_keysym_t keysym) { - ssize_t i = keyboard_pressed_keysym_index(keyboard, keysym); - if (i < 0) { - i = keyboard_pressed_keysym_index(keyboard, XKB_KEY_NoSymbol); - if (i >= 0) { - keyboard->pressed_keysyms[i] = keysym; - } - } - if (keysym >= XKB_KEY_XF86Switch_VT_1 && keysym <= XKB_KEY_XF86Switch_VT_12) { struct roots_server *server = keyboard->input->server; @@ -90,7 +101,35 @@ static bool keyboard_keysym_press(struct roots_keyboard *keyboard, wlr_seat_keyboard_end_grab(keyboard->seat->seat); } - uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); + return false; +} + +/** + * Press or release keysyms. + * + * Returns true if the keysym was handled by a binding and false if the event + * should be propagated to clients. + */ +static bool keyboard_handle_keysyms(struct roots_keyboard *keyboard, + xkb_keysym_t *pressed_keysyms, uint32_t modifiers, + const xkb_keysym_t *keysyms, size_t keysyms_len, + enum wlr_key_state state) { + bool handled = false; + for (size_t i = 0; i < keysyms_len; ++i) { + if (state == WLR_KEY_PRESSED) { + pressed_keysyms_add(pressed_keysyms, keysyms[i]); + handled |= keyboard_press_keysym(keyboard, keysyms[i]); + } else { // WLR_KEY_RELEASED + pressed_keysyms_remove(pressed_keysyms, keysyms[i]); + } + } + if (handled) { + return true; + } + if (state != WLR_KEY_PRESSED) { + return false; + } + struct wl_list *bindings = &keyboard->input->server->config->bindings; struct roots_binding_config *bc; wl_list_for_each(bc, bindings, link) { @@ -100,7 +139,7 @@ static bool keyboard_keysym_press(struct roots_keyboard *keyboard, bool ok = true; for (size_t i = 0; i < bc->keysyms_len; i++) { - ssize_t j = keyboard_pressed_keysym_index(keyboard, bc->keysyms[i]); + ssize_t j = pressed_keysyms_index(pressed_keysyms, bc->keysyms[i]); if (j < 0) { ok = false; break; @@ -116,86 +155,64 @@ static bool keyboard_keysym_press(struct roots_keyboard *keyboard, return false; } -static void keyboard_keysym_release(struct roots_keyboard *keyboard, - xkb_keysym_t keysym) { - ssize_t i = keyboard_pressed_keysym_index(keyboard, keysym); - if (i >= 0) { - keyboard->pressed_keysyms[i] = XKB_KEY_NoSymbol; - } -} /* - * Process keypresses from the keyboard as xkb sees them. + * Get keysyms and modifiers from the keyboard as xkb sees them. * * This uses the xkb keysyms translation based on pressed modifiers and clears * the consumed modifiers from the list of modifiers passed to keybind * detection. * - * (On US layout) this will trigger: [Alt]+[at] + * On US layout, this will trigger: Alt + @ */ -static bool keyboard_keysyms_xkb(struct roots_keyboard *keyboard, - uint32_t keycode, enum wlr_key_state state) { - uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); - const xkb_keysym_t *syms; - int syms_len = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state, - keycode, &syms); - uint32_t consumed = xkb_state_key_get_consumed_mods2( +static size_t keyboard_keysyms_translated(struct roots_keyboard *keyboard, + xkb_keycode_t keycode, const xkb_keysym_t **keysyms, + uint32_t *modifiers) { + *modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); + xkb_mod_mask_t consumed = xkb_state_key_get_consumed_mods2( keyboard->device->keyboard->xkb_state, keycode, XKB_CONSUMED_MODE_XKB); + *modifiers = *modifiers & ~consumed; - // TODO: actually use this value - modifiers = modifiers & ~consumed; - - bool handled = false; - for (int i = 0; i < syms_len; i++) { - if (state) { - bool keysym_handled = - keyboard_keysym_press(keyboard, syms[i]); - handled = handled || keysym_handled; - } else { // WLR_KEY_RELEASED - keyboard_keysym_release(keyboard, syms[i]); - } - } - - return handled; + return xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state, + keycode, keysyms); } + /* - * Process keypresses from the keyboard as if modifiers didn't change keysyms. + * Get keysyms and modifiers from the keyboard as if modifiers didn't change + * keysyms. * * This avoids the xkb keysym translation based on modifiers considered pressed - * in the state and uses the list of modifiers saved on the rootston side. + * in the state. * - * This will trigger the keybind: [Alt]+[Shift]+2 + * This will trigger the keybind: Alt + Shift + 2 */ -static bool keyboard_keysyms_simple(struct roots_keyboard *keyboard, - uint32_t keycode, enum wlr_key_state state) { - const xkb_keysym_t *syms; +static size_t keyboard_keysyms_raw(struct roots_keyboard *keyboard, + xkb_keycode_t keycode, const xkb_keysym_t **keysyms, + uint32_t *modifiers) { + *modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); + xkb_layout_index_t layout_index = xkb_state_key_get_layout( keyboard->device->keyboard->xkb_state, keycode); - int syms_len = xkb_keymap_key_get_syms_by_level( - keyboard->device->keyboard->keymap, keycode, layout_index, 0, &syms); - - bool handled = false; - for (int i = 0; i < syms_len; i++) { - if (state) { - bool keysym_handled = keyboard_keysym_press(keyboard, syms[i]); - handled = handled || keysym_handled; - } else { // WLR_KEY_RELEASED - keyboard_keysym_release(keyboard, syms[i]); - } - } - - return handled; + return xkb_keymap_key_get_syms_by_level(keyboard->device->keyboard->keymap, + keycode, layout_index, 0, keysyms); } void roots_keyboard_handle_key(struct roots_keyboard *keyboard, struct wlr_event_keyboard_key *event) { - uint32_t keycode = event->keycode + 8; - - bool handled = keyboard_keysyms_xkb(keyboard, keycode, event->state); + xkb_keycode_t keycode = event->keycode + 8; + uint32_t modifiers; + const xkb_keysym_t *keysyms; + size_t keysyms_len = keyboard_keysyms_translated(keyboard, keycode, + &keysyms, &modifiers); + bool handled = keyboard_handle_keysyms(keyboard, + keyboard->pressed_keysyms_translated, modifiers, keysyms, keysyms_len, + event->state); if (!handled) { - bool key_handled = keyboard_keysyms_simple(keyboard, keycode, + keysyms_len = keyboard_keysyms_raw(keyboard, keycode, &keysyms, + &modifiers); + handled = keyboard_handle_keysyms(keyboard, + keyboard->pressed_keysyms_raw, modifiers, keysyms, keysyms_len, event->state); - handled = handled || key_handled; } if (!handled) { -- cgit v1.2.3 From a52ca9482a7583bee22c8435b96a6141d44939f4 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 16 Nov 2017 18:58:33 +0100 Subject: Various keyboard fixes * Ensure keysyms state is always updated * Check if pressed keysyms are exactly the binding keysyms * Do not include modifiers in list of keysyms, these are special cases --- rootston/keyboard.c | 107 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 76 insertions(+), 31 deletions(-) (limited to 'rootston/keyboard.c') diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 566a1d7e..39f46a32 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -23,6 +23,16 @@ static ssize_t pressed_keysyms_index(xkb_keysym_t *pressed_keysyms, return -1; } +static size_t pressed_keysyms_length(xkb_keysym_t *pressed_keysyms) { + size_t n = 0; + for (size_t i = 0; i < ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP; ++i) { + if (pressed_keysyms[i] != XKB_KEY_NoSymbol) { + ++n; + } + } + return n; +} + static void pressed_keysyms_add(xkb_keysym_t *pressed_keysyms, xkb_keysym_t keysym) { ssize_t i = pressed_keysyms_index(pressed_keysyms, keysym); @@ -42,6 +52,37 @@ static void pressed_keysyms_remove(xkb_keysym_t *pressed_keysyms, } } +static bool keysym_is_modifier(xkb_keysym_t keysym) { + switch (keysym) { + case XKB_KEY_Shift_L: case XKB_KEY_Shift_R: + case XKB_KEY_Control_L: case XKB_KEY_Control_R: + case XKB_KEY_Caps_Lock: + case XKB_KEY_Shift_Lock: + case XKB_KEY_Meta_L: case XKB_KEY_Meta_R: + case XKB_KEY_Alt_L: case XKB_KEY_Alt_R: + case XKB_KEY_Super_L: case XKB_KEY_Super_R: + case XKB_KEY_Hyper_L: case XKB_KEY_Hyper_R: + return true; + default: + return false; + } +} + +static void pressed_keysyms_update(xkb_keysym_t *pressed_keysyms, + const xkb_keysym_t *keysyms, size_t keysyms_len, + enum wlr_key_state state) { + for (size_t i = 0; i < keysyms_len; ++i) { + if (keysym_is_modifier(keysyms[i])) { + continue; + } + if (state == WLR_KEY_PRESSED) { + pressed_keysyms_add(pressed_keysyms, keysyms[i]); + } else { // WLR_KEY_RELEASED + pressed_keysyms_remove(pressed_keysyms, keysyms[i]); + } + } +} + static const char *exec_prefix = "exec "; static void keyboard_binding_execute(struct roots_keyboard *keyboard, @@ -75,12 +116,13 @@ static void keyboard_binding_execute(struct roots_keyboard *keyboard, } /** - * Execute a built-in, hardcoded compositor action when a keysym is pressed. + * Execute a built-in, hardcoded compositor binding. These are triggered from a + * single keysym. * * Returns true if the keysym was handled by a binding and false if the event * should be propagated to clients. */ -static bool keyboard_press_keysym(struct roots_keyboard *keyboard, +static bool keyboard_execute_compositor_binding(struct roots_keyboard *keyboard, xkb_keysym_t keysym) { if (keysym >= XKB_KEY_XF86Switch_VT_1 && keysym <= XKB_KEY_XF86Switch_VT_12) { @@ -105,35 +147,27 @@ static bool keyboard_press_keysym(struct roots_keyboard *keyboard, } /** - * Press or release keysyms. + * Execute keyboard bindings. These include compositor bindings and user-defined + * bindings. * * Returns true if the keysym was handled by a binding and false if the event * should be propagated to clients. */ -static bool keyboard_handle_keysyms(struct roots_keyboard *keyboard, +static bool keyboard_execute_binding(struct roots_keyboard *keyboard, xkb_keysym_t *pressed_keysyms, uint32_t modifiers, - const xkb_keysym_t *keysyms, size_t keysyms_len, - enum wlr_key_state state) { - bool handled = false; + const xkb_keysym_t *keysyms, size_t keysyms_len) { for (size_t i = 0; i < keysyms_len; ++i) { - if (state == WLR_KEY_PRESSED) { - pressed_keysyms_add(pressed_keysyms, keysyms[i]); - handled |= keyboard_press_keysym(keyboard, keysyms[i]); - } else { // WLR_KEY_RELEASED - pressed_keysyms_remove(pressed_keysyms, keysyms[i]); + if (keyboard_execute_compositor_binding(keyboard, keysyms[i])) { + return true; } } - if (handled) { - return true; - } - if (state != WLR_KEY_PRESSED) { - return false; - } + // User-defined bindings + size_t n = pressed_keysyms_length(pressed_keysyms); struct wl_list *bindings = &keyboard->input->server->config->bindings; struct roots_binding_config *bc; wl_list_for_each(bc, bindings, link) { - if (modifiers ^ bc->modifiers) { + if (modifiers ^ bc->modifiers || n != bc->keysyms_len) { continue; } @@ -162,7 +196,7 @@ static bool keyboard_handle_keysyms(struct roots_keyboard *keyboard, * the consumed modifiers from the list of modifiers passed to keybind * detection. * - * On US layout, this will trigger: Alt + @ + * On US layout, pressing Alt+Shift+2 will trigger Alt+@. */ static size_t keyboard_keysyms_translated(struct roots_keyboard *keyboard, xkb_keycode_t keycode, const xkb_keysym_t **keysyms, @@ -183,7 +217,7 @@ static size_t keyboard_keysyms_translated(struct roots_keyboard *keyboard, * This avoids the xkb keysym translation based on modifiers considered pressed * in the state. * - * This will trigger the keybind: Alt + Shift + 2 + * This will trigger keybinds such as Alt+Shift+2. */ static size_t keyboard_keysyms_raw(struct roots_keyboard *keyboard, xkb_keycode_t keycode, const xkb_keysym_t **keysyms, @@ -200,19 +234,30 @@ void roots_keyboard_handle_key(struct roots_keyboard *keyboard, struct wlr_event_keyboard_key *event) { xkb_keycode_t keycode = event->keycode + 8; + bool handled = false; uint32_t modifiers; const xkb_keysym_t *keysyms; - size_t keysyms_len = keyboard_keysyms_translated(keyboard, keycode, - &keysyms, &modifiers); - bool handled = keyboard_handle_keysyms(keyboard, - keyboard->pressed_keysyms_translated, modifiers, keysyms, keysyms_len, + size_t keysyms_len; + + // Handle translated keysyms + + keysyms_len = keyboard_keysyms_translated(keyboard, keycode, &keysyms, + &modifiers); + pressed_keysyms_update(keyboard->pressed_keysyms_translated, keysyms, + keysyms_len, event->state); + if (event->state == WLR_KEY_PRESSED) { + handled = keyboard_execute_binding(keyboard, + keyboard->pressed_keysyms_translated, modifiers, keysyms, + keysyms_len); + } + + // Handle raw keysyms + keysyms_len = keyboard_keysyms_raw(keyboard, keycode, &keysyms, &modifiers); + pressed_keysyms_update(keyboard->pressed_keysyms_raw, keysyms, keysyms_len, event->state); - if (!handled) { - keysyms_len = keyboard_keysyms_raw(keyboard, keycode, &keysyms, - &modifiers); - handled = keyboard_handle_keysyms(keyboard, - keyboard->pressed_keysyms_raw, modifiers, keysyms, keysyms_len, - event->state); + if (event->state == WLR_KEY_PRESSED && !handled) { + handled = keyboard_execute_binding(keyboard, + keyboard->pressed_keysyms_raw, modifiers, keysyms, keysyms_len); } if (!handled) { -- cgit v1.2.3