From 515150229847c9ebdfd0cabb6f0026fca9d57a23 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sun, 4 Feb 2018 13:39:10 -0500 Subject: basic focus overhaul --- include/sway/input/seat.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'include/sway/input') diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h index b21cbccb..8d5d6b75 100644 --- a/include/sway/input/seat.h +++ b/include/sway/input/seat.h @@ -12,14 +12,26 @@ struct sway_seat_device { struct wl_list link; // sway_seat::devices }; +struct sway_seat_container { + struct sway_seat *seat; + swayc_t *container; + + struct wl_list link; // sway_seat::focus_stack + + struct wl_listener destroy; +}; + struct sway_seat { struct wlr_seat *wlr_seat; struct seat_config *config; struct sway_cursor *cursor; struct sway_input_manager *input; - swayc_t *focus; + + bool has_focus; + struct wl_list focus_stack; // list of containers in focus order struct wl_listener focus_destroy; + struct wl_listener new_container; struct wl_list devices; // sway_seat_device::link @@ -44,6 +56,8 @@ void sway_seat_configure_xcursor(struct sway_seat *seat); void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container); +swayc_t *sway_seat_get_focus(struct sway_seat *seat, swayc_t *container); + void sway_seat_set_config(struct sway_seat *seat, struct seat_config *seat_config); #endif -- cgit v1.2.3 From a7d49da23956c245f0e6b8f7dc9cb532eb14c4b9 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 7 Feb 2018 18:17:57 -0500 Subject: separate seat get focus and seat get focus inactive --- include/sway/input/seat.h | 4 +++- sway/commands.c | 4 +--- sway/commands/workspace.c | 2 +- sway/desktop/xdg_shell_v6.c | 2 +- sway/input/input-manager.c | 2 +- sway/input/seat.c | 32 +++++++++++++++++++------------- sway/tree/workspace.c | 8 ++++---- 7 files changed, 30 insertions(+), 24 deletions(-) (limited to 'include/sway/input') diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h index 8d5d6b75..26a7e5dc 100644 --- a/include/sway/input/seat.h +++ b/include/sway/input/seat.h @@ -56,7 +56,9 @@ void sway_seat_configure_xcursor(struct sway_seat *seat); void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container); -swayc_t *sway_seat_get_focus(struct sway_seat *seat, swayc_t *container); +swayc_t *sway_seat_get_focus(struct sway_seat *seat); + +swayc_t *sway_seat_get_focus_inactive(struct sway_seat *seat, swayc_t *container); void sway_seat_set_config(struct sway_seat *seat, struct seat_config *seat_config); diff --git a/sway/commands.c b/sway/commands.c index 6bb4db0b..d8d29a1c 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -282,9 +282,7 @@ struct cmd_results *handle_command(char *_exec) { } if (seat) { config->handler_context.current_container = - (seat->has_focus ? - sway_seat_get_focus(seat, &root_container) : - NULL); + sway_seat_get_focus(seat); struct cmd_results *res = handler->handle(argc-1, argv+1); if (res->status != CMD_SUCCESS) { free_argv(argc, argv); diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c index e7d6cc9f..fa891398 100644 --- a/sway/commands/workspace.c +++ b/sway/commands/workspace.c @@ -91,7 +91,7 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { } workspace_switch(ws); current_container = - sway_seat_get_focus(config->handler_context.seat, &root_container); + sway_seat_get_focus(config->handler_context.seat); swayc_t *new_output = swayc_parent_by_type(current_container, C_OUTPUT); if (config->mouse_warping && old_output != new_output) { diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 04d89015..b44d9e54 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -135,7 +135,7 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { wl_signal_add(&xdg_surface->events.destroy, &sway_surface->destroy); struct sway_seat *seat = input_manager_current_seat(input_manager); - swayc_t *focus = sway_seat_get_focus(seat, &root_container); + swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container); swayc_t *cont = new_view(focus, sway_view); sway_view->swayc = cont; diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c index a406636e..90eb8cf6 100644 --- a/sway/input/input-manager.c +++ b/sway/input/input-manager.c @@ -282,7 +282,7 @@ bool sway_input_manager_has_focus(struct sway_input_manager *input, swayc_t *container) { struct sway_seat *seat = NULL; wl_list_for_each(seat, &input->seats, link) { - if (seat->has_focus && sway_seat_get_focus(seat, &root_container) == container) { + if (sway_seat_get_focus(seat) == container) { return true; } } diff --git a/sway/input/seat.c b/sway/input/seat.c index cbf05abd..d2ffca64 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -137,16 +137,14 @@ static void seat_configure_keyboard(struct sway_seat *seat, struct wlr_keyboard *wlr_keyboard = seat_device->input_device->wlr_device->keyboard; sway_keyboard_configure(seat_device->keyboard); wlr_seat_set_keyboard(seat->wlr_seat, - seat_device->input_device->wlr_device); - if (seat->has_focus) { - swayc_t *focus = sway_seat_get_focus(seat, &root_container); - if (focus && focus->type == C_VIEW) { - // force notify reenter to pick up the new configuration - wlr_seat_keyboard_clear_focus(seat->wlr_seat); - wlr_seat_keyboard_notify_enter(seat->wlr_seat, - focus->sway_view->surface, wlr_keyboard->keycodes, - wlr_keyboard->num_keycodes, &wlr_keyboard->modifiers); - } + seat_device->input_device->wlr_device); + swayc_t *focus = sway_seat_get_focus(seat); + if (focus && focus->type == C_VIEW) { + // force notify reenter to pick up the new configuration + wlr_seat_keyboard_clear_focus(seat->wlr_seat); + wlr_seat_keyboard_notify_enter(seat->wlr_seat, + focus->sway_view->surface, wlr_keyboard->keycodes, + wlr_keyboard->num_keycodes, &wlr_keyboard->modifiers); } } @@ -266,12 +264,13 @@ void sway_seat_configure_xcursor(struct sway_seat *seat) { static void handle_focus_destroy(struct wl_listener *listener, void *data) { struct sway_seat *seat = wl_container_of(listener, seat, focus_destroy); swayc_t *container = data; + // TODO dont set focus to the parent, set focus to the next focus inactive + // of the parent sway_seat_set_focus(seat, container->parent); } void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container) { - swayc_t *last_focus = - (seat->has_focus ? sway_seat_get_focus(seat, &root_container) : NULL); + swayc_t *last_focus = sway_seat_get_focus(seat); if (container && last_focus == container) { return; @@ -314,7 +313,7 @@ void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container) { } } -swayc_t *sway_seat_get_focus(struct sway_seat *seat, swayc_t *container) { +swayc_t *sway_seat_get_focus_inactive(struct sway_seat *seat, swayc_t *container) { struct sway_seat_container *current = NULL; swayc_t *parent = NULL; wl_list_for_each(current, &seat->focus_stack, link) { @@ -338,6 +337,13 @@ swayc_t *sway_seat_get_focus(struct sway_seat *seat, swayc_t *container) { return NULL; } +swayc_t *sway_seat_get_focus(struct sway_seat *seat) { + if (!seat->has_focus) { + return NULL; + } + return sway_seat_get_focus_inactive(seat, &root_container); +} + void sway_seat_set_config(struct sway_seat *seat, struct seat_config *seat_config) { // clear configs diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index ce5b425c..29f07f74 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -63,8 +63,8 @@ static bool _workspace_by_name(swayc_t *view, void *data) { swayc_t *workspace_by_name(const char *name) { struct sway_seat *seat = input_manager_current_seat(input_manager); swayc_t *current_workspace = NULL, *current_output = NULL; - if (seat->has_focus) { - swayc_t *focus = sway_seat_get_focus(seat, &root_container); + swayc_t *focus = sway_seat_get_focus(seat); + if (focus) { current_workspace = swayc_parent_by_type(focus, C_WORKSPACE); current_output = swayc_parent_by_type(focus, C_OUTPUT); } @@ -103,7 +103,7 @@ swayc_t *workspace_create(const char *name) { } // Otherwise create a new one struct sway_seat *seat = input_manager_current_seat(input_manager); - swayc_t *focus = sway_seat_get_focus(seat, &root_container); + swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container); parent = focus; parent = swayc_parent_by_type(parent, C_OUTPUT); return new_workspace(parent, name); @@ -195,7 +195,7 @@ bool workspace_switch(swayc_t *workspace) { return false; } struct sway_seat *seat = input_manager_current_seat(input_manager); - swayc_t *focus = sway_seat_get_focus(seat, &root_container); + swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container); if (!seat || !focus) { return false; } -- cgit v1.2.3 From 946d9459c57fc38b2536d40a45b7d4c9186b6734 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 14 Feb 2018 14:30:27 -0500 Subject: get swayc in direction --- include/sway/input/seat.h | 3 + include/sway/layout.h | 14 ++++ sway/input/seat.c | 10 +++ sway/tree/layout.c | 174 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 201 insertions(+) (limited to 'include/sway/input') diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h index 26a7e5dc..f9244f43 100644 --- a/include/sway/input/seat.h +++ b/include/sway/input/seat.h @@ -60,6 +60,9 @@ swayc_t *sway_seat_get_focus(struct sway_seat *seat); swayc_t *sway_seat_get_focus_inactive(struct sway_seat *seat, swayc_t *container); +swayc_t *sway_seat_get_focus_by_type(struct sway_seat *seat, + enum swayc_types type); + void sway_seat_set_config(struct sway_seat *seat, struct seat_config *seat_config); #endif diff --git a/include/sway/layout.h b/include/sway/layout.h index 69a66674..e82c4442 100644 --- a/include/sway/layout.h +++ b/include/sway/layout.h @@ -4,6 +4,18 @@ #include #include "sway/container.h" +enum movement_direction { + MOVE_LEFT, + MOVE_RIGHT, + MOVE_UP, + MOVE_DOWN, + MOVE_PARENT, + MOVE_CHILD, + MOVE_NEXT, + MOVE_PREV, + MOVE_FIRST +}; + struct sway_container; struct sway_root { @@ -25,5 +37,7 @@ struct sway_container *remove_child(struct sway_container *child); enum swayc_layouts default_layout(struct sway_container *output); void sort_workspaces(struct sway_container *output); void arrange_windows(struct sway_container *container, double width, double height); +swayc_t *get_swayc_in_direction(swayc_t *container, + struct sway_seat *seat, enum movement_direction dir); #endif diff --git a/sway/input/seat.c b/sway/input/seat.c index 2abe8a1f..648e7914 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -358,6 +358,16 @@ swayc_t *sway_seat_get_focus(struct sway_seat *seat) { return sway_seat_get_focus_inactive(seat, &root_container); } +swayc_t *sway_seat_get_focus_by_type(struct sway_seat *seat, + enum swayc_types type) { + swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container); + if (focus->type == type) { + return focus; + } + + return swayc_parent_by_type(focus, type); +} + void sway_seat_set_config(struct sway_seat *seat, struct seat_config *seat_config) { // clear configs diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 3651d279..9768279a 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -10,6 +10,7 @@ #include "sway/layout.h" #include "sway/output.h" #include "sway/view.h" +#include "sway/input/seat.h" #include "list.h" #include "log.h" @@ -346,3 +347,176 @@ void apply_vert_layout(swayc_t *container, */ } } + +/** + * Get swayc in the direction of newly entered output. + */ +static swayc_t *get_swayc_in_output_direction(swayc_t *output, + enum movement_direction dir, struct sway_seat *seat) { + // XXX is this really a seat function or can we do it with the default + // seat? + if (!output) { + return NULL; + } + + swayc_t *ws = sway_seat_get_focus_inactive(seat, output); + if (ws->type != C_WORKSPACE) { + ws = swayc_parent_by_type(ws, C_WORKSPACE); + } + + if (ws && ws->children->length > 0) { + switch (dir) { + case MOVE_LEFT: + // get most right child of new output + return ws->children->items[ws->children->length-1]; + case MOVE_RIGHT: + // get most left child of new output + return ws->children->items[0]; + case MOVE_UP: + case MOVE_DOWN: + { + swayc_t *focused = sway_seat_get_focus_inactive(seat, ws); + if (focused && focused->parent) { + swayc_t *parent = focused->parent; + if (parent->layout == L_VERT) { + if (dir == MOVE_UP) { + // get child furthest down on new output + return parent->children->items[parent->children->length-1]; + } else if (dir == MOVE_DOWN) { + // get child furthest up on new output + return parent->children->items[0]; + } + } + return focused; + } + break; + } + default: + break; + } + } + + return output; +} + +static void get_absolute_center_position(swayc_t *container, int *x, int *y) { + *x = container->x + container->width/2; + *y = container->y + container->height/2; +} + +static swayc_t *get_swayc_in_direction_under(swayc_t *container, + enum movement_direction dir, struct sway_seat *seat, swayc_t *limit) { + if (dir == MOVE_CHILD) { + return sway_seat_get_focus_inactive(seat, container); + } + + swayc_t *parent = container->parent; + if (dir == MOVE_PARENT) { + if (parent->type == C_OUTPUT) { + return NULL; + } else { + return parent; + } + } + + if (dir == MOVE_PREV || dir == MOVE_NEXT) { + int focused_idx = index_child(container); + if (focused_idx == -1) { + return NULL; + } else { + int desired = (focused_idx + (dir == MOVE_NEXT ? 1 : -1)) % + parent->children->length; + if (desired < 0) { + desired += parent->children->length; + } + return parent->children->items[desired]; + } + } + + // If moving to an adjacent output we need a starting position (since this + // output might border to multiple outputs). + //struct wlc_point abs_pos; + //get_absolute_center_position(container, &abs_pos); + + + // TODO WLR fullscreen + /* + if (container->type == C_VIEW && swayc_is_fullscreen(container)) { + wlr_log(L_DEBUG, "Moving from fullscreen view, skipping to output"); + container = swayc_parent_by_type(container, C_OUTPUT); + get_absolute_center_position(container, &abs_pos); + swayc_t *output = swayc_adjacent_output(container, dir, &abs_pos, true); + return get_swayc_in_output_direction(output, dir); + } + if (container->type == C_WORKSPACE && container->fullscreen) { + sway_log(L_DEBUG, "Moving to fullscreen view"); + return container->fullscreen; + } + */ + + swayc_t *wrap_candidate = NULL; + while (true) { + // Test if we can even make a difference here + bool can_move = false; + int desired; + int idx = index_child(container); + if (parent->type == C_ROOT) { + struct wlr_output_layout *layout = root_container.sway_root->output_layout; + wlr_output_layout_adjacent_output(layout, container->sway_output->wlr_output); + //swayc_t *output = swayc_adjacent_output(container, dir, &abs_pos, true); + if (!output || output == container) { + return wrap_candidate; + } + wlr_log(L_DEBUG, "Moving between outputs"); + return get_swayc_in_output_direction(output, dir, seat); + } else { + if (dir == MOVE_LEFT || dir == MOVE_RIGHT) { + if (parent->layout == L_HORIZ || parent->layout == L_TABBED) { + can_move = true; + desired = idx + (dir == MOVE_LEFT ? -1 : 1); + } + } else { + if (parent->layout == L_VERT || parent->layout == L_STACKED) { + can_move = true; + desired = idx + (dir == MOVE_UP ? -1 : 1); + } + } + } + + if (can_move) { + // TODO handle floating + if (desired < 0 || desired >= parent->children->length) { + can_move = false; + int len = parent->children->length; + if (!wrap_candidate && len > 1) { + if (desired < 0) { + wrap_candidate = parent->children->items[len-1]; + } else { + wrap_candidate = parent->children->items[0]; + } + if (config->force_focus_wrapping) { + return wrap_candidate; + } + } + } else { + wlr_log(L_DEBUG, "%s cont %d-%p dir %i sibling %d: %p", __func__, + idx, container, dir, desired, parent->children->items[desired]); + return parent->children->items[desired]; + } + } + + if (!can_move) { + container = parent; + parent = parent->parent; + if (!parent || container == limit) { + // wrapping is the last chance + return wrap_candidate; + } + } + } +} + +swayc_t *get_swayc_in_direction(swayc_t *container, struct sway_seat *seat, + enum movement_direction dir) { + return get_swayc_in_direction_under(container, dir, seat, NULL); +} -- cgit v1.2.3 From 06c71f115bb0632ef1e75d881d509665198e1eef Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 14 Feb 2018 14:42:06 -0500 Subject: input device destroy --- include/sway/input/input-manager.h | 1 + sway/input/input-manager.c | 61 +++++++++++++++++++------------------- 2 files changed, 31 insertions(+), 31 deletions(-) (limited to 'include/sway/input') diff --git a/include/sway/input/input-manager.h b/include/sway/input/input-manager.h index 66ace262..a76c3880 100644 --- a/include/sway/input/input-manager.h +++ b/include/sway/input/input-manager.h @@ -16,6 +16,7 @@ struct sway_input_device { struct wlr_input_device *wlr_device; struct input_config *config; struct wl_list link; + struct wl_listener device_destroy; }; struct sway_input_manager { diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c index d789c7eb..f59daea3 100644 --- a/sway/input/input-manager.c +++ b/sway/input/input-manager.c @@ -160,7 +160,32 @@ static void sway_input_manager_libinput_config_pointer(struct sway_input_device } } -static void input_add_notify(struct wl_listener *listener, void *data) { +static void handle_device_destroy(struct wl_listener *listener, void *data) { + struct wlr_input_device *device = data; + + struct sway_input_device *input_device = + input_sway_device_from_wlr(input_manager, device); + + if (!sway_assert(input_device, "could not find sway device")) { + return; + } + + wlr_log(L_DEBUG, "removing device: '%s'", + input_device->identifier); + + struct sway_seat *seat = NULL; + wl_list_for_each(seat, &input_manager->seats, link) { + sway_seat_remove_device(seat, input_device); + } + + wl_list_remove(&input_device->link); + wl_list_remove(&input_device->device_destroy.link); + free_input_config(input_device->config); + free(input_device->identifier); + free(input_device); +} + +static void handle_new_input(struct wl_listener *listener, void *data) { struct sway_input_manager *input = wl_container_of(listener, input, input_add); struct wlr_input_device *device = data; @@ -226,32 +251,9 @@ static void input_add_notify(struct wl_listener *listener, void *data) { "device '%s' is not configured on any seats", input_device->identifier); } -} - -static void input_remove_notify(struct wl_listener *listener, void *data) { - struct sway_input_manager *input = - wl_container_of(listener, input, input_remove); - struct wlr_input_device *device = data; - - struct sway_input_device *input_device = - input_sway_device_from_wlr(input, device); - - if (!sway_assert(input_device, "could not find sway device")) { - return; - } - - wlr_log(L_DEBUG, "removing device: '%s'", - input_device->identifier); - - struct sway_seat *seat = NULL; - wl_list_for_each(seat, &input->seats, link) { - sway_seat_remove_device(seat, input_device); - } - wl_list_remove(&input_device->link); - free_input_config(input_device->config); - free(input_device->identifier); - free(input_device); + wl_signal_add(&device->events.destroy, &input_device->device_destroy); + input_device->device_destroy.notify = handle_device_destroy; } struct sway_input_manager *sway_input_manager_create( @@ -269,11 +271,8 @@ struct sway_input_manager *sway_input_manager_create( // create the default seat input_manager_get_seat(input, default_seat); - input->input_add.notify = input_add_notify; - wl_signal_add(&server->backend->events.input_add, &input->input_add); - - input->input_remove.notify = input_remove_notify; - wl_signal_add(&server->backend->events.input_remove, &input->input_remove); + input->input_add.notify = handle_new_input; + wl_signal_add(&server->backend->events.new_input, &input->input_add); return input; } -- cgit v1.2.3 From 66a975038c2f6cc3d2ebb5210d182b0440bc0a88 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 20 Feb 2018 19:01:02 -0500 Subject: add doc to sway_seat_get_focus_inactive() --- include/sway/input/seat.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/sway/input') diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h index f9244f43..1d55bec7 100644 --- a/include/sway/input/seat.h +++ b/include/sway/input/seat.h @@ -58,6 +58,15 @@ void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container); swayc_t *sway_seat_get_focus(struct sway_seat *seat); +/** + * Return the last container to be focused for the seat (or the most recently + * opened if no container has received focused) that is a child of the given + * container. The focus-inactive container of the root window is the focused + * container for the seat (if the seat does have focus). This function can be + * used to determine what container gets focused next if the focused container + * is destroyed, or focus moves to a container with children and we need to + * descend into the next leaf in focus order. + */ swayc_t *sway_seat_get_focus_inactive(struct sway_seat *seat, swayc_t *container); swayc_t *sway_seat_get_focus_by_type(struct sway_seat *seat, -- cgit v1.2.3 From 4b3aa59b8bfaa5d6136b54ba7f347f5d93fa210f Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 20 Feb 2018 19:09:38 -0500 Subject: rename new_input listener on input-manager --- include/sway/input/input-manager.h | 4 ++-- sway/input/input-manager.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'include/sway/input') diff --git a/include/sway/input/input-manager.h b/include/sway/input/input-manager.h index a76c3880..eab7dc90 100644 --- a/include/sway/input/input-manager.h +++ b/include/sway/input/input-manager.h @@ -20,11 +20,11 @@ struct sway_input_device { }; struct sway_input_manager { - struct wl_listener input_add; - struct wl_listener input_remove; struct sway_server *server; struct wl_list devices; struct wl_list seats; + + struct wl_listener new_input; }; struct sway_input_manager *sway_input_manager_create( diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c index e6708bad..27c2c72e 100644 --- a/sway/input/input-manager.c +++ b/sway/input/input-manager.c @@ -187,7 +187,7 @@ static void handle_device_destroy(struct wl_listener *listener, void *data) { static void handle_new_input(struct wl_listener *listener, void *data) { struct sway_input_manager *input = - wl_container_of(listener, input, input_add); + wl_container_of(listener, input, new_input); struct wlr_input_device *device = data; struct sway_input_device *input_device = @@ -271,8 +271,8 @@ struct sway_input_manager *sway_input_manager_create( // create the default seat input_manager_get_seat(input, default_seat); - input->input_add.notify = handle_new_input; - wl_signal_add(&server->backend->events.new_input, &input->input_add); + input->new_input.notify = handle_new_input; + wl_signal_add(&server->backend->events.new_input, &input->new_input); return input; } -- cgit v1.2.3