From bb6d34e7a5e270c6998f95f45c1e518d9c053714 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 17 Nov 2017 12:45:07 +0100 Subject: [PATCH 01/16] rootston: add per-seat views --- include/rootston/desktop.h | 3 +- include/rootston/seat.h | 20 +++++++-- include/rootston/view.h | 8 ++-- rootston/cursor.c | 16 +++---- rootston/desktop.c | 69 ++++++++++------------------- rootston/input.c | 2 +- rootston/keyboard.c | 19 ++++---- rootston/output.c | 4 +- rootston/seat.c | 91 +++++++++++++++++++++++++++++++------- rootston/wl_shell.c | 29 ++++++------ rootston/xdg_shell_v6.c | 4 +- rootston/xwayland.c | 19 +++----- 12 files changed, 161 insertions(+), 123 deletions(-) diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h index b809db43..12ab5898 100644 --- a/include/rootston/desktop.h +++ b/include/rootston/desktop.h @@ -23,7 +23,7 @@ struct roots_output { }; struct roots_desktop { - struct wlr_list *views; + struct wl_list views; // roots_view::link struct wl_list outputs; struct timespec last_frame; @@ -59,6 +59,7 @@ struct roots_desktop *desktop_create(struct roots_server *server, struct roots_config *config); void desktop_destroy(struct roots_desktop *desktop); +void view_init(struct roots_view *view, struct roots_desktop *desktop); void view_destroy(struct roots_view *view); struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, struct wlr_surface **surface, double *sx, double *sy); diff --git a/include/rootston/seat.h b/include/rootston/seat.h index bef515a4..a8397d89 100644 --- a/include/rootston/seat.h +++ b/include/rootston/seat.h @@ -9,8 +9,7 @@ struct roots_drag_icon { struct wl_list link; // roots_seat::drag_icons bool mapped; - int32_t sx; - int32_t sy; + int32_t sx, sy; struct wl_listener surface_destroy; struct wl_listener surface_commit; @@ -20,10 +19,11 @@ 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 wl_list link; - struct roots_view *focus; + struct wl_list views; // roots_seat_view::link + struct roots_seat_view *focus; struct wl_list keyboards; struct wl_list pointers; @@ -31,6 +31,14 @@ struct roots_seat { struct wl_list tablet_tools; }; +struct roots_seat_view { + struct roots_seat *seat; + struct roots_view *view; + struct wl_list link; // roots_seat::views + + struct wl_listener destroy; +}; + struct roots_pointer { struct roots_seat *seat; struct wlr_input_device *device; @@ -70,6 +78,10 @@ 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_add_view(struct roots_seat *seat, struct roots_view *view); + +void roots_seat_remove_view(struct roots_seat *seat, struct roots_view *view); + void roots_seat_configure_cursor(struct roots_seat *seat); void roots_seat_configure_xcursor(struct roots_seat *seat); diff --git a/include/rootston/view.h b/include/rootston/view.h index 99b4ed78..69034d60 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -9,7 +9,6 @@ struct roots_wl_shell_surface { struct roots_view *view; - // TODO: Maybe destroy listener should go in roots_view struct wl_listener destroy; struct wl_listener request_move; struct wl_listener request_resize; @@ -22,7 +21,6 @@ struct roots_wl_shell_surface { struct roots_xdg_surface_v6 { struct roots_view *view; - // TODO: Maybe destroy listener should go in roots_view struct wl_listener commit; struct wl_listener destroy; struct wl_listener request_move; @@ -33,7 +31,6 @@ struct roots_xdg_surface_v6 { struct roots_xwayland_surface { struct roots_view *view; - // TODO: Maybe destroy listener should go in roots_view struct wl_listener destroy; struct wl_listener request_configure; struct wl_listener request_move; @@ -51,6 +48,7 @@ enum roots_view_type { struct roots_view { struct roots_desktop *desktop; + struct wl_list link; // roots_desktop::views double x, y; float rotation; @@ -80,6 +78,10 @@ struct roots_view { }; struct wlr_surface *wlr_surface; + struct { + struct wl_signal destroy; + } events; + // TODO: This would probably be better as a field that's updated on a // configure event from the xdg_shell // If not then this should follow the typical type/impl pattern we use diff --git a/rootston/cursor.c b/rootston/cursor.c index 5949a364..0dbc413c 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -60,7 +60,7 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t t 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, + view_move(seat->focus->view, cursor->view_x + dx, cursor->view_y + dy); } break; @@ -68,8 +68,8 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t t 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; + double active_x = seat->focus->view->x; + double active_y = seat->focus->view->y; int width = cursor->view_width; int height = cursor->view_height; if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { @@ -98,18 +98,18 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t t height = 0; } - if (active_x != seat->focus->x || - active_y != seat->focus->y) { - view_move_resize(seat->focus, active_x, active_y, + if (active_x != seat->focus->view->x || + active_y != seat->focus->view->y) { + view_move_resize(seat->focus->view, active_x, active_y, width, height); } else { - view_resize(seat->focus, width, height); + view_resize(seat->focus->view, width, height); } } break; case ROOTS_CURSOR_ROTATE: if (seat->focus) { - struct roots_view *view = seat->focus; + struct roots_view *view = seat->focus->view; 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, diff --git a/rootston/desktop.c b/rootston/desktop.c index 1695d007..c607043b 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -18,29 +18,6 @@ #include "rootston/seat.h" #include "rootston/xcursor.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; - 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) { - struct roots_view *_view = desktop->views->items[i]; - if (view == _view) { - wlr_list_del(desktop->views, i); - break; - } - } - free(view); -} - void view_get_box(const struct roots_view *view, struct wlr_box *box) { box->x = view->x; box->y = view->y; @@ -201,6 +178,25 @@ bool view_center(struct roots_view *view) { return true; } +void view_destroy(struct roots_view *view) { + wl_signal_emit(&view->events.destroy, view); + + wl_list_remove(&view->link); + free(view); +} + +void view_init(struct roots_view *view, struct roots_desktop *desktop) { + view->desktop = desktop; + wl_signal_init(&view->events.destroy); + + wl_list_insert(&desktop->views, &view->link); + + struct roots_seat *seat; + wl_list_for_each(seat, &desktop->server->input->seats, link) { + roots_seat_add_view(seat, view); + } +} + void view_setup(struct roots_view *view) { struct roots_input *input = view->desktop->server->input; // TODO what seat gets focus? the one with the last input event? @@ -215,25 +211,11 @@ void view_setup(struct roots_view *view) { view_update_output(view, &before); } -void view_teardown(struct roots_view *view) { - // TODO replace me with a signal - /* - 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); - */ -} - struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, struct wlr_surface **surface, double *sx, double *sy) { - for (ssize_t i = desktop->views->length - 1; i >= 0; --i) { - struct roots_view *view = desktop->views->items[i]; - + // TODO: use the seat + struct roots_view *view; + wl_list_for_each(view, &desktop->views, link) { if (view->type == ROOTS_WL_SHELL_VIEW && view->wl_shell_surface->state == WLR_WL_SHELL_SURFACE_STATE_POPUP) { @@ -322,11 +304,7 @@ struct roots_desktop *desktop_create(struct roots_server *server, return NULL; } - desktop->views = wlr_list_create(); - if (desktop->views == NULL) { - free(desktop); - return NULL; - } + wl_list_init(&desktop->views); wl_list_init(&desktop->outputs); desktop->output_add.notify = output_add_notify; @@ -342,7 +320,6 @@ struct roots_desktop *desktop_create(struct roots_server *server, ROOTS_XCURSOR_SIZE); if (desktop->xcursor_manager == NULL) { wlr_log(L_ERROR, "Cannot create XCursor manager"); - wlr_list_free(desktop->views); free(desktop); return NULL; } diff --git a/rootston/input.c b/rootston/input.c index 35a5af97..b2cd6472 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -116,7 +116,7 @@ bool input_view_has_focus(struct roots_input *input, struct roots_view *view) { } struct roots_seat *seat; wl_list_for_each(seat, &input->seats, link) { - if (seat->focus == view) { + if (seat->focus != NULL && seat->focus->view == view) { return true; } } diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 39f46a32..d16d2b75 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -87,19 +87,20 @@ static const char *exec_prefix = "exec "; static void keyboard_binding_execute(struct roots_keyboard *keyboard, const char *command) { - struct roots_server *server = keyboard->input->server; + struct roots_seat *seat = keyboard->seat; if (strcmp(command, "exit") == 0) { - wl_display_terminate(server->wl_display); + wl_display_terminate(keyboard->input->server->wl_display); } else if (strcmp(command, "close") == 0) { - if (server->desktop->views->length > 0) { - struct roots_view *view = - server->desktop->views->items[server->desktop->views->length-1]; - view_close(view); + if (!wl_list_empty(&seat->views)) { + struct roots_seat_view *first_seat_view = wl_container_of( + seat->views.next, first_seat_view, link); + view_close(first_seat_view->view); } } else if (strcmp(command, "next_window") == 0) { - if (server->desktop->views->length > 0) { - struct roots_view *view = server->desktop->views->items[0]; - roots_seat_focus_view(keyboard->seat, view); + if (!wl_list_empty(&seat->views)) { + struct roots_seat_view *last_seat_view = wl_container_of( + seat->views.prev, last_seat_view, link); + roots_seat_focus_view(seat, last_seat_view->view); } } else if (strncmp(exec_prefix, command, strlen(exec_prefix)) == 0) { const char *shell_cmd = command + strlen(exec_prefix); diff --git a/rootston/output.c b/rootston/output.c index 28312c2c..41514b60 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -186,8 +186,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { wlr_output_make_current(wlr_output); wlr_renderer_begin(server->renderer, wlr_output); - for (size_t i = 0; i < desktop->views->length; ++i) { - struct roots_view *view = desktop->views->items[i]; + struct roots_view *view; + wl_list_for_each_reverse(view, &desktop->views, link) { render_view(view, desktop, wlr_output, &now); } diff --git a/rootston/seat.c b/rootston/seat.c index 1fa37c44..08f1997c 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -246,6 +246,7 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { wl_list_init(&seat->touch); wl_list_init(&seat->tablet_tools); wl_list_init(&seat->drag_icons); + wl_list_init(&seat->views); seat->input = input; @@ -480,8 +481,7 @@ bool roots_seat_has_meta_pressed(struct roots_seat *seat) { } 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) { + if (seat->focus != NULL && seat->focus->view == view) { return; } @@ -490,12 +490,24 @@ void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { return; } - struct roots_view *prev_focus = seat->focus; - seat->focus = view; + bool found = false; + struct roots_seat_view *seat_view; + wl_list_for_each(seat_view, &seat->views, link) { + if (seat_view->view == view) { + found = true; + break; + } + } + if (!found) { + return; + } + + struct roots_seat_view *prev_focus = seat->focus; + seat->focus = seat_view; // unfocus the old view if it is not focused by some other seat - if (prev_focus && !input_view_has_focus(seat->input, prev_focus)) { - view_activate(prev_focus, false); + if (prev_focus && !input_view_has_focus(seat->input, prev_focus->view)) { + view_activate(prev_focus->view, false); } if (!seat->focus) { @@ -503,20 +515,65 @@ void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { 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) { - index = i; + view_activate(view, true); + wl_list_remove(&seat_view->view->link); + wl_list_insert(&seat->input->server->desktop->views, + &seat_view->view->link); + + wl_list_remove(&seat_view->link); + wl_list_insert(&seat->views, &seat_view->link); + wlr_seat_keyboard_notify_enter(seat->seat, view->wlr_surface); +} + +static void seat_view_destroy(struct roots_seat_view *seat_view) { + struct roots_seat *seat = seat_view->seat; + + if (seat->focus == seat_view) { + seat->focus = NULL; + seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + } + + wl_list_remove(&seat_view->destroy.link); + wl_list_remove(&seat_view->link); + free(seat_view); + + // Focus first view + if (!wl_list_empty(&seat->views)) { + struct roots_seat_view *first_seat_view = wl_container_of( + seat->views.next, first_seat_view, link); + roots_seat_focus_view(seat, first_seat_view->view); + } +} + +static void seat_view_handle_destroy(struct wl_listener *listener, void *data) { + struct roots_seat_view *seat_view = + wl_container_of(listener, seat_view, destroy); + seat_view_destroy(seat_view); +} + +void roots_seat_add_view(struct roots_seat *seat, struct roots_view *view) { + struct roots_seat_view *seat_view = + calloc(1, sizeof(struct roots_seat_view)); + if (seat_view == NULL) { + return; + } + seat_view->seat = seat; + seat_view->view = view; + + wl_list_insert(&seat->views, &seat_view->link); + + seat_view->destroy.notify = seat_view_handle_destroy; + wl_signal_add(&view->events.destroy, &seat_view->destroy); +} + +void roots_seat_remove_view(struct roots_seat *seat, struct roots_view *view) { + struct roots_seat_view *seat_view; + wl_list_for_each(seat_view, &seat->views, link) { + if (seat_view->view == view) { + seat_view_destroy(seat_view); break; } } - - 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) { diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index 96f461fe..7359c878 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -77,7 +77,6 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { static void handle_destroy(struct wl_listener *listener, void *data) { struct roots_wl_shell_surface *roots_surface = wl_container_of(listener, roots_surface, destroy); - view_teardown(roots_surface->view); wl_list_remove(&roots_surface->destroy.link); wl_list_remove(&roots_surface->request_move.link); wl_list_remove(&roots_surface->request_resize.link); @@ -88,14 +87,6 @@ static void handle_destroy(struct wl_listener *listener, void *data) { free(roots_surface); } -static int shell_surface_compare_equals(const void *item, const void *cmp_to) { - const struct roots_view *view = item; - if (view->type == ROOTS_WL_SHELL_VIEW && view->wl_shell_surface == cmp_to) { - return 0; - } - return -1; -} - void handle_wl_shell_surface(struct wl_listener *listener, void *data) { struct roots_desktop *desktop = wl_container_of(listener, desktop, wl_shell_surface); @@ -138,17 +129,23 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { view->wlr_surface = surface->surface; view->resize = resize; view->close = close; - view->desktop = desktop; roots_surface->view = view; - wlr_list_add(desktop->views, view); + view_init(view, desktop); + view_setup(view); if (surface->state == WLR_WL_SHELL_SURFACE_STATE_TRANSIENT) { - // we need to map it relative to the parent - int i = wlr_list_seq_find(desktop->views, shell_surface_compare_equals, - surface->parent); - if (i != -1) { - struct roots_view *parent = desktop->views->items[i]; + // We need to map it relative to the parent + bool found = false; + struct roots_view *parent; + wl_list_for_each(parent, &desktop->views, link) { + if (parent->type == ROOTS_WL_SHELL_VIEW && + parent->wl_shell_surface == surface->parent) { + found = true; + break; + } + } + if (found) { view_move(view, parent->x + surface->transient_state->x, parent->y + surface->transient_state->y); diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 6517c8b4..656231c7 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -161,7 +161,6 @@ static void handle_commit(struct wl_listener *listener, void *data) { static void handle_destroy(struct wl_listener *listener, void *data) { struct roots_xdg_surface_v6 *roots_xdg_surface = wl_container_of(listener, roots_xdg_surface, destroy); - view_teardown(roots_xdg_surface->view); wl_list_remove(&roots_xdg_surface->commit.link); wl_list_remove(&roots_xdg_surface->destroy.link); wl_list_remove(&roots_xdg_surface->request_move.link); @@ -219,9 +218,8 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { view->move_resize = move_resize; view->maximize = maximize; view->close = close; - view->desktop = desktop; roots_surface->view = view; - wlr_list_add(desktop->views, view); + view_init(view, desktop); view_setup(view); } diff --git a/rootston/xwayland.c b/rootston/xwayland.c index f4e100dc..f5cb7857 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -95,7 +95,6 @@ static void maximize(struct roots_view *view, bool maximized) { static void handle_destroy(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, destroy); - view_teardown(roots_surface->view); wl_list_remove(&roots_surface->destroy.link); wl_list_remove(&roots_surface->request_configure.link); wl_list_remove(&roots_surface->request_move.link); @@ -174,29 +173,24 @@ static void handle_request_maximize(struct wl_listener *listener, void *data) { static void handle_map_notify(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, map_notify); + struct wlr_xwayland_surface *xsurface = data; struct roots_view *view = roots_surface->view; - struct wlr_xwayland_surface *xsurface = view->xwayland_surface; - struct roots_desktop *desktop = view->desktop; + //struct roots_desktop *desktop = view->desktop; view->wlr_surface = xsurface->surface; view->x = (double)xsurface->x; view->y = (double)xsurface->y; - wlr_list_push(desktop->views, roots_surface->view); + // TODO: add view to desktop } static void handle_unmap_notify(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, unmap_notify); - struct roots_desktop *desktop = roots_surface->view->desktop; + //struct roots_desktop *desktop = roots_surface->view->desktop; roots_surface->view->wlr_surface = NULL; - for (size_t i = 0; i < desktop->views->length; i++) { - if (desktop->views->items[i] == roots_surface->view) { - wlr_list_del(desktop->views, i); - break; - } - } + // TODO: remove view from desktop } void handle_xwayland_surface(struct wl_listener *listener, void *data) { @@ -242,7 +236,6 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { view->xwayland_surface = surface; view->roots_xwayland_surface = roots_surface; view->wlr_surface = surface->surface; - view->desktop = desktop; view->activate = activate; view->resize = resize; view->move = move; @@ -250,7 +243,7 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { view->maximize = maximize; view->close = close; roots_surface->view = view; - wlr_list_add(desktop->views, view); + view_init(view, desktop); if (!surface->override_redirect) { view_setup(view); From 1523082d5d74ca40f468bec04c23ed47049bb4d7 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 17 Nov 2017 12:47:30 +0100 Subject: [PATCH 02/16] Remove outdated comment --- rootston/desktop.c | 1 - 1 file changed, 1 deletion(-) diff --git a/rootston/desktop.c b/rootston/desktop.c index c607043b..5c2ae50c 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -213,7 +213,6 @@ void view_setup(struct roots_view *view) { struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, struct wlr_surface **surface, double *sx, double *sy) { - // TODO: use the seat struct roots_view *view; wl_list_for_each(view, &desktop->views, link) { if (view->type == ROOTS_WL_SHELL_VIEW && From 3b74db467b7f628ad45ee319424448a02dc052ec Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sun, 19 Nov 2017 09:33:55 -0500 Subject: [PATCH 03/16] data-device: wlr-drag-icon --- include/rootston/seat.h | 16 ------ include/wlr/types/wlr_data_device.h | 25 ++++++++- include/wlr/types/wlr_seat.h | 2 + rootston/cursor.c | 86 ----------------------------- rootston/output.c | 4 +- rootston/seat.c | 1 - types/wlr_data_device.c | 84 ++++++++++++++++++++++++++-- types/wlr_seat.c | 1 + 8 files changed, 107 insertions(+), 112 deletions(-) diff --git a/include/rootston/seat.h b/include/rootston/seat.h index aebd4399..dad8bbc4 100644 --- a/include/rootston/seat.h +++ b/include/rootston/seat.h @@ -4,27 +4,11 @@ #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; - - bool is_pointer; - int32_t touch_id; - - 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; // coordinates of the first touch point if it exists int32_t touch_id; diff --git a/include/wlr/types/wlr_data_device.h b/include/wlr/types/wlr_data_device.h index 189ab59b..7ee6cec1 100644 --- a/include/wlr/types/wlr_data_device.h +++ b/include/wlr/types/wlr_data_device.h @@ -53,6 +53,27 @@ struct wlr_data_source { } events; }; +struct wlr_drag_icon { + struct wlr_surface *surface; + struct wlr_seat_client *client; + struct wl_list link; // wlr_seat::drag_icons + bool mapped; + + bool is_pointer; + int32_t touch_id; + + int32_t sx; + int32_t sy; + + struct { + struct wl_signal destroy; + } events; + + struct wl_listener surface_destroy; + struct wl_listener surface_commit; + struct wl_listener seat_client_unbound; +}; + struct wlr_drag { struct wlr_seat_pointer_grab pointer_grab; struct wlr_seat_keyboard_grab keyboard_grab; @@ -64,7 +85,7 @@ struct wlr_drag { bool is_pointer_grab; - struct wlr_surface *icon; + struct wlr_drag_icon *icon; struct wlr_surface *focus; struct wlr_data_source *source; @@ -72,9 +93,9 @@ struct wlr_drag { int32_t grab_touch_id; struct wl_listener point_destroy; - struct wl_listener icon_destroy; struct wl_listener source_destroy; struct wl_listener seat_client_unbound; + struct wl_listener icon_destroy; }; /** diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index dbd03401..b5c06718 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -165,6 +165,8 @@ struct wlr_seat { struct wl_global *wl_global; struct wl_display *display; struct wl_list clients; + struct wl_list drag_icons; // wlr_drag_icon::link + char *name; uint32_t capabilities; struct timespec last_event; diff --git a/rootston/cursor.c b/rootston/cursor.c index 10bb4dd3..d0b40876 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -355,104 +355,18 @@ void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor, cursor->cursor_client = event->seat_client->client; } -static void handle_drag_icon_commit(struct wl_listener *listener, void *data) { - struct roots_drag_icon *drag_icon = - wl_container_of(listener, drag_icon, surface_commit); - drag_icon->sx += drag_icon->surface->current->sx; - drag_icon->sy += drag_icon->surface->current->sy; -} - -static void handle_drag_icon_destroy(struct wl_listener *listener, void *data) { - struct roots_drag_icon *drag_icon = - wl_container_of(listener, drag_icon, surface_destroy); - wl_list_remove(&drag_icon->link); - wl_list_remove(&drag_icon->surface_destroy.link); - wl_list_remove(&drag_icon->surface_commit.link); - free(drag_icon); -} - -static struct roots_drag_icon *seat_add_drag_icon(struct roots_seat *seat, - struct wlr_surface *icon_surface) { - if (!icon_surface) { - return NULL; - } - - struct roots_drag_icon *iter_icon; - wl_list_for_each(iter_icon, &seat->drag_icons, link) { - if (iter_icon->surface == icon_surface) { - // already in the list - return iter_icon; - } - } - - struct roots_drag_icon *drag_icon = - calloc(1, sizeof(struct roots_drag_icon)); - drag_icon->mapped = true; - drag_icon->surface = icon_surface; - wl_list_insert(&seat->drag_icons, &drag_icon->link); - - wl_signal_add(&icon_surface->events.destroy, - &drag_icon->surface_destroy); - drag_icon->surface_destroy.notify = handle_drag_icon_destroy; - - wl_signal_add(&icon_surface->events.commit, - &drag_icon->surface_commit); - drag_icon->surface_commit.notify = handle_drag_icon_commit; - - return drag_icon; -} - -static void seat_unmap_drag_icon(struct roots_seat *seat, - struct wlr_surface *icon_surface) { - if (!icon_surface) { - return; - } - - struct roots_drag_icon *icon; - wl_list_for_each(icon, &seat->drag_icons, link) { - if (icon->surface == icon_surface) { - icon->mapped = false; - } - } -} - void roots_cursor_handle_pointer_grab_begin(struct roots_cursor *cursor, struct wlr_seat_pointer_grab *grab) { - if (grab->interface == &wlr_data_device_pointer_drag_interface) { - struct wlr_drag *drag = grab->data; - struct roots_drag_icon *icon = - seat_add_drag_icon(cursor->seat, drag->icon); - if (icon) { - icon->is_pointer = true; - } - } } void roots_cursor_handle_pointer_grab_end(struct roots_cursor *cursor, struct wlr_seat_pointer_grab *grab) { - if (grab->interface == &wlr_data_device_pointer_drag_interface) { - struct wlr_drag *drag = grab->data; - seat_unmap_drag_icon(cursor->seat, drag->icon); - } } void roots_cursor_handle_touch_grab_begin(struct roots_cursor *cursor, struct wlr_seat_touch_grab *grab) { - if (grab->interface == &wlr_data_device_touch_drag_interface) { - struct wlr_drag *drag = grab->data; - struct roots_drag_icon *icon = - seat_add_drag_icon(cursor->seat, drag->icon); - if (icon) { - icon->is_pointer = false; - icon->touch_id = drag->grab_touch_id; - } - } } void roots_cursor_handle_touch_grab_end(struct roots_cursor *cursor, struct wlr_seat_touch_grab *grab) { - if (grab->interface == &wlr_data_device_touch_drag_interface) { - struct wlr_drag *drag = grab->data; - seat_unmap_drag_icon(cursor->seat, drag->icon); - } } diff --git a/rootston/output.c b/rootston/output.c index 6c8f2519..b551dcf4 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -191,10 +191,10 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { render_view(view, desktop, wlr_output, &now); } - struct roots_drag_icon *drag_icon = NULL; + struct wlr_drag_icon *drag_icon = NULL; struct roots_seat *seat = NULL; wl_list_for_each(seat, &server->input->seats, link) { - wl_list_for_each(drag_icon, &seat->drag_icons, link) { + wl_list_for_each(drag_icon, &seat->seat->drag_icons, link) { if (!drag_icon->mapped) { continue; } diff --git a/rootston/seat.c b/rootston/seat.c index 1855ca49..96c6fb0d 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -277,7 +277,6 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { 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; diff --git a/types/wlr_data_device.c b/types/wlr_data_device.c index 6328fd09..ab10bb2e 100644 --- a/types/wlr_data_device.c +++ b/types/wlr_data_device.c @@ -452,6 +452,7 @@ static void wlr_drag_end(struct wlr_drag *drag) { wlr_drag_set_focus(drag, NULL, 0, 0); if (drag->icon) { + drag->icon->mapped = false; wl_list_remove(&drag->icon_destroy.link); } @@ -614,8 +615,74 @@ static void drag_handle_drag_source_destroy(struct wl_listener *listener, wlr_drag_end(drag); } +static void wlr_drag_icon_destroy(struct wlr_drag_icon *icon) { + if (!icon) { + return; + } + wl_signal_emit(&icon->events.destroy, icon); + wl_list_remove(&icon->surface_commit.link); + wl_list_remove(&icon->surface_destroy.link); + wl_list_remove(&icon->seat_client_unbound.link); + wl_list_remove(&icon->link); + free(icon); +} + +static void handle_drag_icon_surface_destroy(struct wl_listener *listener, + void *data) { + struct wlr_drag_icon *icon = + wl_container_of(listener, icon, surface_destroy); + wlr_drag_icon_destroy(icon); +} + +static void handle_drag_icon_surface_commit(struct wl_listener *listener, + void *data) { + struct wlr_drag_icon *icon = + wl_container_of(listener, icon, surface_commit); + icon->sx += icon->surface->current->sx; + icon->sy += icon->surface->current->sy; +} + +static void handle_drag_icon_seat_client_unbound(struct wl_listener *listener, + void *data) { + struct wlr_drag_icon *icon = + wl_container_of(listener, icon, seat_client_unbound); + struct wlr_seat_client *client = data; + + if (client == icon->client) { + wlr_drag_icon_destroy(icon); + } +} + +static struct wlr_drag_icon *wlr_drag_icon_create( + struct wlr_surface *icon_surface, struct wlr_seat_client *client, + bool is_pointer, int32_t touch_id) { + struct wlr_drag_icon *icon = calloc(1, sizeof(struct wlr_drag_icon)); + if (!icon) { + return NULL; + } + + icon->surface = icon_surface; + icon->client = client; + icon->is_pointer = is_pointer; + icon->touch_id = touch_id; + wl_list_insert(&client->seat->drag_icons, &icon->link); + + wl_signal_init(&icon->events.destroy); + + wl_signal_add(&icon->surface->events.destroy, &icon->surface_destroy); + icon->surface_destroy.notify = handle_drag_icon_surface_destroy; + + wl_signal_add(&icon->surface->events.commit, &icon->surface_commit); + icon->surface_commit.notify = handle_drag_icon_surface_commit; + + wl_signal_add(&client->seat->events.client_unbound, &icon->seat_client_unbound); + icon->seat_client_unbound.notify = handle_drag_icon_seat_client_unbound; + + return icon; +} + static bool seat_client_start_drag(struct wlr_seat_client *client, - struct wlr_data_source *source, struct wlr_surface *icon, + struct wlr_data_source *source, struct wlr_surface *icon_surface, struct wlr_surface *origin, uint32_t serial) { struct wlr_drag *drag = calloc(1, sizeof(struct wlr_drag)); if (drag == NULL) { @@ -649,11 +716,20 @@ static bool seat_client_start_drag(struct wlr_seat_client *client, return true; } - if (icon) { + if (icon_surface) { + int32_t touch_id = (point ? point->touch_id : 0); + struct wlr_drag_icon *icon = + wlr_drag_icon_create(icon_surface, client, drag->is_pointer_grab, + touch_id); + + if (!icon) { + free(drag); + return false; + } + drag->icon = icon; drag->icon_destroy.notify = drag_handle_icon_destroy; wl_signal_add(&icon->events.destroy, &drag->icon_destroy); - drag->icon = icon; } if (source) { @@ -712,8 +788,6 @@ static void data_device_start_drag(struct wl_client *client, } } - // TODO touch grab - if (!seat_client_start_drag(seat_client, source, icon, origin, serial)) { wl_resource_post_no_memory(device_resource); return; diff --git a/types/wlr_seat.c b/types/wlr_seat.c index 4438f5cc..3bdd11ef 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -404,6 +404,7 @@ struct wlr_seat *wlr_seat_create(struct wl_display *display, const char *name) { wlr_seat->display = display; wlr_seat->name = strdup(name); wl_list_init(&wlr_seat->clients); + wl_list_init(&wlr_seat->drag_icons); wl_signal_init(&wlr_seat->events.client_bound); wl_signal_init(&wlr_seat->events.client_unbound); From 90d2eca218be2beff2465433f0d2937a3d4de267 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sun, 19 Nov 2017 10:07:30 -0500 Subject: [PATCH 04/16] rootston: xwayland ready listener --- include/rootston/desktop.h | 1 + rootston/main.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h index b809db43..10e5bbc6 100644 --- a/include/rootston/desktop.h +++ b/include/rootston/desktop.h @@ -50,6 +50,7 @@ struct roots_desktop { #ifdef HAS_XWAYLAND struct wlr_xwayland *xwayland; struct wl_listener xwayland_surface; + struct wl_listener xwayland_ready; #endif }; diff --git a/rootston/main.c b/rootston/main.c index 814d3aef..46548094 100644 --- a/rootston/main.c +++ b/rootston/main.c @@ -59,8 +59,9 @@ int main(int argc, char **argv) { ready(NULL, NULL); #else if (server.desktop->xwayland != NULL) { - struct wl_listener xwayland_ready = { .notify = ready }; - wl_signal_add(&server.desktop->xwayland->events.ready, &xwayland_ready); + wl_signal_add(&server.desktop->xwayland->events.ready, + &server.desktop->xwayland_ready); + server.desktop->xwayland_ready.notify = ready; } else { ready(NULL, NULL); } From 8f38b0504b5abcfd84247c348eb363e85d30c744 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sun, 19 Nov 2017 10:14:57 -0500 Subject: [PATCH 05/16] wlr-data-device: map icon by default --- types/wlr_data_device.c | 1 + 1 file changed, 1 insertion(+) diff --git a/types/wlr_data_device.c b/types/wlr_data_device.c index ab10bb2e..91f31c97 100644 --- a/types/wlr_data_device.c +++ b/types/wlr_data_device.c @@ -665,6 +665,7 @@ static struct wlr_drag_icon *wlr_drag_icon_create( icon->client = client; icon->is_pointer = is_pointer; icon->touch_id = touch_id; + icon->mapped = true; wl_list_insert(&client->seat->drag_icons, &icon->link); wl_signal_init(&icon->events.destroy); From bd8cdf1e9ff0ba6a0e8f7c36fec7f7540c94fded Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sun, 19 Nov 2017 10:20:32 -0500 Subject: [PATCH 06/16] rootston: remove grab listeners --- include/rootston/cursor.h | 18 --------------- rootston/cursor.c | 16 ------------- rootston/seat.c | 48 --------------------------------------- 3 files changed, 82 deletions(-) diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h index f0c9be89..e2a371bf 100644 --- a/include/rootston/cursor.h +++ b/include/rootston/cursor.h @@ -53,12 +53,6 @@ struct roots_cursor { struct wl_listener tool_axis; struct wl_listener tool_tip; - struct wl_listener pointer_grab_begin; - struct wl_listener pointer_grab_end; - - struct wl_listener touch_grab_begin; - struct wl_listener touch_grab_end; - struct wl_listener request_set_cursor; }; @@ -96,16 +90,4 @@ void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor, struct wlr_seat_pointer_request_set_cursor_event *event); -void roots_cursor_handle_pointer_grab_begin(struct roots_cursor *cursor, - struct wlr_seat_pointer_grab *grab); - -void roots_cursor_handle_pointer_grab_end(struct roots_cursor *cursor, - struct wlr_seat_pointer_grab *grab); - -void roots_cursor_handle_touch_grab_begin(struct roots_cursor *cursor, - struct wlr_seat_touch_grab *grab); - -void roots_cursor_handle_touch_grab_end(struct roots_cursor *cursor, - struct wlr_seat_touch_grab *grab); - #endif diff --git a/rootston/cursor.c b/rootston/cursor.c index d0b40876..e2615bec 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -354,19 +354,3 @@ void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor, event->hotspot_y); cursor->cursor_client = event->seat_client->client; } - -void roots_cursor_handle_pointer_grab_begin(struct roots_cursor *cursor, - struct wlr_seat_pointer_grab *grab) { -} - -void roots_cursor_handle_pointer_grab_end(struct roots_cursor *cursor, - struct wlr_seat_pointer_grab *grab) { -} - -void roots_cursor_handle_touch_grab_begin(struct roots_cursor *cursor, - struct wlr_seat_touch_grab *grab) { -} - -void roots_cursor_handle_touch_grab_end(struct roots_cursor *cursor, - struct wlr_seat_touch_grab *grab) { -} diff --git a/rootston/seat.c b/rootston/seat.c index 96c6fb0d..c24ee787 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -96,38 +96,6 @@ static void handle_request_set_cursor(struct wl_listener *listener, roots_cursor_handle_request_set_cursor(cursor, event); } -static void handle_pointer_grab_begin(struct wl_listener *listener, - void *data) { - struct roots_cursor *cursor = - wl_container_of(listener, cursor, pointer_grab_begin); - struct wlr_seat_pointer_grab *grab = data; - roots_cursor_handle_pointer_grab_begin(cursor, grab); -} - -static void handle_pointer_grab_end(struct wl_listener *listener, - void *data) { - struct roots_cursor *cursor = - wl_container_of(listener, cursor, pointer_grab_end); - struct wlr_seat_pointer_grab *grab = data; - roots_cursor_handle_pointer_grab_end(cursor, grab); -} - -static void handle_touch_grab_begin(struct wl_listener *listener, - void *data) { - struct roots_cursor *cursor = - wl_container_of(listener, cursor, touch_grab_begin); - struct wlr_seat_touch_grab *grab = data; - roots_cursor_handle_touch_grab_begin(cursor, grab); -} - -static void handle_touch_grab_end(struct wl_listener *listener, - void *data) { - struct roots_cursor *cursor = - wl_container_of(listener, cursor, touch_grab_end); - struct wlr_seat_touch_grab *grab = data; - roots_cursor_handle_touch_grab_end(cursor, grab); -} - static void seat_reset_device_mappings(struct roots_seat *seat, struct wlr_input_device *device) { struct wlr_cursor *cursor = seat->cursor->cursor; @@ -249,22 +217,6 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { wl_signal_add(&seat->seat->events.request_set_cursor, &seat->cursor->request_set_cursor); seat->cursor->request_set_cursor.notify = handle_request_set_cursor; - - wl_signal_add(&seat->seat->events.pointer_grab_begin, - &seat->cursor->pointer_grab_begin); - seat->cursor->pointer_grab_begin.notify = handle_pointer_grab_begin; - - wl_signal_add(&seat->seat->events.pointer_grab_end, - &seat->cursor->pointer_grab_end); - seat->cursor->pointer_grab_end.notify = handle_pointer_grab_end; - - wl_signal_add(&seat->seat->events.touch_grab_begin, - &seat->cursor->touch_grab_begin); - seat->cursor->touch_grab_begin.notify = handle_touch_grab_begin; - - wl_signal_add(&seat->seat->events.touch_grab_end, - &seat->cursor->touch_grab_end); - seat->cursor->touch_grab_end.notify = handle_touch_grab_end; } struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { From af23192ede63243b057ac9d98fd796e609e668a2 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sun, 19 Nov 2017 11:10:27 -0500 Subject: [PATCH 07/16] wlr-seat: remove client bound and unbound signal --- include/wlr/types/wlr_data_device.h | 4 ++-- include/wlr/types/wlr_seat.h | 7 +++--- types/wlr_data_device.c | 35 +++++++++++++---------------- types/wlr_seat.c | 7 ++---- 4 files changed, 23 insertions(+), 30 deletions(-) diff --git a/include/wlr/types/wlr_data_device.h b/include/wlr/types/wlr_data_device.h index 7ee6cec1..12b25e45 100644 --- a/include/wlr/types/wlr_data_device.h +++ b/include/wlr/types/wlr_data_device.h @@ -71,7 +71,7 @@ struct wlr_drag_icon { struct wl_listener surface_destroy; struct wl_listener surface_commit; - struct wl_listener seat_client_unbound; + struct wl_listener seat_client_destroy; }; struct wlr_drag { @@ -94,7 +94,7 @@ struct wlr_drag { struct wl_listener point_destroy; struct wl_listener source_destroy; - struct wl_listener seat_client_unbound; + struct wl_listener seat_client_destroy; struct wl_listener icon_destroy; }; diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index b5c06718..6d59315b 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -21,6 +21,10 @@ struct wlr_seat_client { struct wl_resource *touch; struct wl_resource *data_device; + struct { + struct wl_signal destroy; + } events; + struct wl_list link; }; @@ -182,9 +186,6 @@ struct wlr_seat { struct wl_listener selection_data_source_destroy; struct { - struct wl_signal client_bound; - struct wl_signal client_unbound; - struct wl_signal pointer_grab_begin; struct wl_signal pointer_grab_end; diff --git a/types/wlr_data_device.c b/types/wlr_data_device.c index 91f31c97..a8d69cc0 100644 --- a/types/wlr_data_device.c +++ b/types/wlr_data_device.c @@ -352,15 +352,13 @@ static void data_device_release(struct wl_client *client, wl_resource_destroy(resource); } -static void drag_client_seat_unbound(struct wl_listener *listener, void *data) { +static void handle_drag_seat_client_destroy(struct wl_listener *listener, + void *data) { struct wlr_drag *drag = - wl_container_of(listener, drag, seat_client_unbound); - struct wlr_seat_client *unbound_client = data; + wl_container_of(listener, drag, seat_client_destroy); - if (drag->focus_client == unbound_client) { - drag->focus_client = NULL; - wl_list_remove(&drag->seat_client_unbound.link); - } + drag->focus_client = NULL; + wl_list_remove(&drag->seat_client_destroy.link); } static void wlr_drag_set_focus(struct wlr_drag *drag, @@ -370,7 +368,7 @@ static void wlr_drag_set_focus(struct wlr_drag *drag, } if (drag->focus_client && drag->focus_client->data_device) { - wl_list_remove(&drag->seat_client_unbound.link); + wl_list_remove(&drag->seat_client_destroy.link); wl_data_device_send_leave(drag->focus_client->data_device); drag->focus_client = NULL; drag->focus = NULL; @@ -430,9 +428,9 @@ static void wlr_drag_set_focus(struct wlr_drag *drag, drag->focus = surface; drag->focus_client = focus_client; - drag->seat_client_unbound.notify = drag_client_seat_unbound; - wl_signal_add(&focus_client->seat->events.client_unbound, - &drag->seat_client_unbound); + drag->seat_client_destroy.notify = handle_drag_seat_client_destroy; + wl_signal_add(&focus_client->events.destroy, + &drag->seat_client_destroy); } static void wlr_drag_end(struct wlr_drag *drag) { @@ -622,7 +620,7 @@ static void wlr_drag_icon_destroy(struct wlr_drag_icon *icon) { wl_signal_emit(&icon->events.destroy, icon); wl_list_remove(&icon->surface_commit.link); wl_list_remove(&icon->surface_destroy.link); - wl_list_remove(&icon->seat_client_unbound.link); + wl_list_remove(&icon->seat_client_destroy.link); wl_list_remove(&icon->link); free(icon); } @@ -642,15 +640,12 @@ static void handle_drag_icon_surface_commit(struct wl_listener *listener, icon->sy += icon->surface->current->sy; } -static void handle_drag_icon_seat_client_unbound(struct wl_listener *listener, +static void handle_drag_icon_seat_client_destroy(struct wl_listener *listener, void *data) { struct wlr_drag_icon *icon = - wl_container_of(listener, icon, seat_client_unbound); - struct wlr_seat_client *client = data; + wl_container_of(listener, icon, seat_client_destroy); - if (client == icon->client) { - wlr_drag_icon_destroy(icon); - } + wlr_drag_icon_destroy(icon); } static struct wlr_drag_icon *wlr_drag_icon_create( @@ -676,8 +671,8 @@ static struct wlr_drag_icon *wlr_drag_icon_create( wl_signal_add(&icon->surface->events.commit, &icon->surface_commit); icon->surface_commit.notify = handle_drag_icon_surface_commit; - wl_signal_add(&client->seat->events.client_unbound, &icon->seat_client_unbound); - icon->seat_client_unbound.notify = handle_drag_icon_seat_client_unbound; + wl_signal_add(&client->events.destroy, &icon->seat_client_destroy); + icon->seat_client_destroy.notify = handle_drag_icon_seat_client_destroy; return icon; } diff --git a/types/wlr_seat.c b/types/wlr_seat.c index 3bdd11ef..ff1cbf7f 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -181,7 +181,7 @@ static void wl_seat_get_touch(struct wl_client *client, static void wlr_seat_client_resource_destroy(struct wl_resource *resource) { struct wlr_seat_client *client = wl_resource_get_user_data(resource); - wl_signal_emit(&client->seat->events.client_unbound, client); + wl_signal_emit(&client->events.destroy, client); if (client == client->seat->pointer_state.focused_client) { client->seat->pointer_state.focused_client = NULL; @@ -240,7 +240,7 @@ static void wl_seat_bind(struct wl_client *client, void *_wlr_seat, wl_seat_send_name(seat_client->wl_resource, wlr_seat->name); } wl_seat_send_capabilities(seat_client->wl_resource, wlr_seat->capabilities); - wl_signal_emit(&wlr_seat->events.client_bound, seat_client); + wl_signal_init(&seat_client->events.destroy); } static void default_pointer_enter(struct wlr_seat_pointer_grab *grab, @@ -406,9 +406,6 @@ struct wlr_seat *wlr_seat_create(struct wl_display *display, const char *name) { wl_list_init(&wlr_seat->clients); wl_list_init(&wlr_seat->drag_icons); - wl_signal_init(&wlr_seat->events.client_bound); - wl_signal_init(&wlr_seat->events.client_unbound); - wl_signal_init(&wlr_seat->events.request_set_cursor); wl_signal_init(&wlr_seat->events.selection); From a8b31da52c32a65793d6e941b869d5f2d6736775 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 19 Nov 2017 18:15:11 +0100 Subject: [PATCH 08/16] Remove roots_seat_{add,remove}_view --- include/rootston/seat.h | 8 ++- rootston/cursor.c | 25 ++++----- rootston/desktop.c | 5 -- rootston/input.c | 2 +- rootston/seat.c | 113 ++++++++++++++++++++++------------------ 5 files changed, 78 insertions(+), 75 deletions(-) diff --git a/include/rootston/seat.h b/include/rootston/seat.h index 609d0c74..14ba9224 100644 --- a/include/rootston/seat.h +++ b/include/rootston/seat.h @@ -15,7 +15,7 @@ struct roots_seat { double touch_x, touch_y; struct wl_list views; // roots_seat_view::link - struct roots_seat_view *focus; + bool has_focus; struct wl_list keyboards; struct wl_list pointers; @@ -63,16 +63,14 @@ 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_add_view(struct roots_seat *seat, struct roots_view *view); - -void roots_seat_remove_view(struct roots_seat *seat, struct roots_view *view); - 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); +struct roots_view *roots_seat_get_focused_view(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); diff --git a/rootston/cursor.c b/rootston/cursor.c index 7bb46692..046fd4f4 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -58,19 +58,21 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, } break; case ROOTS_CURSOR_MOVE: - if (seat->focus) { + view = roots_seat_get_focused_view(seat); + if (view != NULL) { double dx = cursor->cursor->x - cursor->offs_x; double dy = cursor->cursor->y - cursor->offs_y; - view_move(seat->focus->view, cursor->view_x + dx, + view_move(view, cursor->view_x + dx, cursor->view_y + dy); } break; case ROOTS_CURSOR_RESIZE: - if (seat->focus) { + view = roots_seat_get_focused_view(seat); + if (view != NULL) { double dx = cursor->cursor->x - cursor->offs_x; double dy = cursor->cursor->y - cursor->offs_y; - double active_x = seat->focus->view->x; - double active_y = seat->focus->view->y; + double active_x = view->x; + double active_y = view->y; int width = cursor->view_width; int height = cursor->view_height; if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { @@ -99,18 +101,18 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, height = 0; } - if (active_x != seat->focus->view->x || - active_y != seat->focus->view->y) { - view_move_resize(seat->focus->view, active_x, active_y, + if (active_x != view->x || + active_y != view->y) { + view_move_resize(view, active_x, active_y, width, height); } else { - view_resize(seat->focus->view, width, height); + view_resize(view, width, height); } } break; case ROOTS_CURSOR_ROTATE: - if (seat->focus) { - struct roots_view *view = seat->focus->view; + view = roots_seat_get_focused_view(seat); + if (view != NULL) { 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, @@ -124,7 +126,6 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, } break; } - } static void roots_cursor_press_button(struct roots_cursor *cursor, diff --git a/rootston/desktop.c b/rootston/desktop.c index aa924068..bea492ba 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -190,11 +190,6 @@ void view_init(struct roots_view *view, struct roots_desktop *desktop) { wl_signal_init(&view->events.destroy); wl_list_insert(&desktop->views, &view->link); - - struct roots_seat *seat; - wl_list_for_each(seat, &desktop->server->input->seats, link) { - roots_seat_add_view(seat, view); - } } void view_setup(struct roots_view *view) { diff --git a/rootston/input.c b/rootston/input.c index 9f779415..d698c952 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -116,7 +116,7 @@ bool input_view_has_focus(struct roots_input *input, struct roots_view *view) { } struct roots_seat *seat; wl_list_for_each(seat, &input->seats, link) { - if (seat->focus != NULL && seat->focus->view == view) { + if (view == roots_seat_get_focused_view(seat)) { return true; } } diff --git a/rootston/seat.c b/rootston/seat.c index 6df8cc44..d5844ea6 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -485,56 +485,20 @@ bool roots_seat_has_meta_pressed(struct roots_seat *seat) { return false; } -void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { - if (seat->focus != NULL && seat->focus->view == view) { - return; +struct roots_view *roots_seat_get_focused_view(struct roots_seat *seat) { + if (!seat->has_focus || wl_list_empty(&seat->views)) { + return NULL; } - - if (view && view->type == ROOTS_XWAYLAND_VIEW && - view->xwayland_surface->override_redirect) { - return; - } - - bool found = false; - struct roots_seat_view *seat_view; - wl_list_for_each(seat_view, &seat->views, link) { - if (seat_view->view == view) { - found = true; - break; - } - } - if (!found) { - return; - } - - struct roots_seat_view *prev_focus = seat->focus; - seat->focus = seat_view; - - // unfocus the old view if it is not focused by some other seat - if (prev_focus && !input_view_has_focus(seat->input, prev_focus->view)) { - view_activate(prev_focus->view, false); - } - - if (!seat->focus) { - seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; - return; - } - - view_activate(view, true); - wl_list_remove(&seat_view->view->link); - wl_list_insert(&seat->input->server->desktop->views, - &seat_view->view->link); - - wl_list_remove(&seat_view->link); - wl_list_insert(&seat->views, &seat_view->link); - wlr_seat_keyboard_notify_enter(seat->seat, view->wlr_surface); + struct roots_seat_view *seat_view = + wl_container_of(seat->views.next, seat_view, link); + return seat_view->view; } static void seat_view_destroy(struct roots_seat_view *seat_view) { struct roots_seat *seat = seat_view->seat; - if (seat->focus == seat_view) { - seat->focus = NULL; + if (seat_view->view == roots_seat_get_focused_view(seat)) { + seat->has_focus = false; seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; } @@ -556,11 +520,12 @@ static void seat_view_handle_destroy(struct wl_listener *listener, void *data) { seat_view_destroy(seat_view); } -void roots_seat_add_view(struct roots_seat *seat, struct roots_view *view) { +static struct roots_seat_view *seat_add_view(struct roots_seat *seat, + struct roots_view *view) { struct roots_seat_view *seat_view = calloc(1, sizeof(struct roots_seat_view)); if (seat_view == NULL) { - return; + return NULL; } seat_view->seat = seat; seat_view->view = view; @@ -569,16 +534,60 @@ void roots_seat_add_view(struct roots_seat *seat, struct roots_view *view) { seat_view->destroy.notify = seat_view_handle_destroy; wl_signal_add(&view->events.destroy, &seat_view->destroy); + + return seat_view; } -void roots_seat_remove_view(struct roots_seat *seat, struct roots_view *view) { - struct roots_seat_view *seat_view; - wl_list_for_each(seat_view, &seat->views, link) { - if (seat_view->view == view) { - seat_view_destroy(seat_view); - break; +void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { + struct roots_view *prev_focus = roots_seat_get_focused_view(seat); + if (view == prev_focus) { + return; + } + + if (view && view->type == ROOTS_XWAYLAND_VIEW && + view->xwayland_surface->override_redirect) { + return; + } + + struct roots_seat_view *seat_view = NULL; + if (view != NULL) { + bool found = false; + wl_list_for_each(seat_view, &seat->views, link) { + if (seat_view->view == view) { + found = true; + break; + } + } + if (!found) { + seat_view = seat_add_view(seat, view); + if (seat_view == NULL) { + wlr_log(L_ERROR, "Allocation failed"); + return; + } } } + + seat->has_focus = false; + + // unfocus the old view if it is not focused by some other seat + if (prev_focus != NULL && !input_view_has_focus(seat->input, prev_focus)) { + view_activate(prev_focus, false); + } + + if (view == NULL) { + seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + return; + } + + view_activate(view, true); + wl_list_remove(&seat_view->view->link); + wl_list_insert(&seat->input->server->desktop->views, + &seat_view->view->link); + + seat->has_focus = true; + wl_list_remove(&seat_view->link); + wl_list_insert(&seat->views, &seat_view->link); + wlr_seat_keyboard_notify_enter(seat->seat, view->wlr_surface); } void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) { From bf41e7a794cf4bde3612ec23744400388b9d6756 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 19 Nov 2017 19:14:31 +0100 Subject: [PATCH 09/16] Make the close command use roots_seat_get_focus, rename a few symbols --- include/rootston/seat.h | 4 ++-- rootston/cursor.c | 6 +++--- rootston/input.c | 2 +- rootston/keyboard.c | 7 +++---- rootston/seat.c | 16 ++++++++-------- 5 files changed, 17 insertions(+), 18 deletions(-) diff --git a/include/rootston/seat.h b/include/rootston/seat.h index 14ba9224..d9a44c2d 100644 --- a/include/rootston/seat.h +++ b/include/rootston/seat.h @@ -28,7 +28,7 @@ struct roots_seat_view { struct roots_view *view; struct wl_list link; // roots_seat::views - struct wl_listener destroy; + struct wl_listener view_destroy; }; struct roots_pointer { @@ -69,7 +69,7 @@ void roots_seat_configure_xcursor(struct roots_seat *seat); bool roots_seat_has_meta_pressed(struct roots_seat *seat); -struct roots_view *roots_seat_get_focused_view(struct roots_seat *seat); +struct roots_view *roots_seat_get_focus(struct roots_seat *seat); void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view); diff --git a/rootston/cursor.c b/rootston/cursor.c index 046fd4f4..3bb2a700 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -58,7 +58,7 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, } break; case ROOTS_CURSOR_MOVE: - view = roots_seat_get_focused_view(seat); + view = roots_seat_get_focus(seat); if (view != NULL) { double dx = cursor->cursor->x - cursor->offs_x; double dy = cursor->cursor->y - cursor->offs_y; @@ -67,7 +67,7 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, } break; case ROOTS_CURSOR_RESIZE: - view = roots_seat_get_focused_view(seat); + view = roots_seat_get_focus(seat); if (view != NULL) { double dx = cursor->cursor->x - cursor->offs_x; double dy = cursor->cursor->y - cursor->offs_y; @@ -111,7 +111,7 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, } break; case ROOTS_CURSOR_ROTATE: - view = roots_seat_get_focused_view(seat); + view = roots_seat_get_focus(seat); if (view != NULL) { int ox = view->x + view->wlr_surface->current->width/2, oy = view->y + view->wlr_surface->current->height/2; diff --git a/rootston/input.c b/rootston/input.c index d698c952..ce20e840 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -116,7 +116,7 @@ bool input_view_has_focus(struct roots_input *input, struct roots_view *view) { } struct roots_seat *seat; wl_list_for_each(seat, &input->seats, link) { - if (view == roots_seat_get_focused_view(seat)) { + if (view == roots_seat_get_focus(seat)) { return true; } } diff --git a/rootston/keyboard.c b/rootston/keyboard.c index d16d2b75..b8c7aca6 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -91,10 +91,9 @@ static void keyboard_binding_execute(struct roots_keyboard *keyboard, if (strcmp(command, "exit") == 0) { wl_display_terminate(keyboard->input->server->wl_display); } else if (strcmp(command, "close") == 0) { - if (!wl_list_empty(&seat->views)) { - struct roots_seat_view *first_seat_view = wl_container_of( - seat->views.next, first_seat_view, link); - view_close(first_seat_view->view); + struct roots_view *focus = roots_seat_get_focus(seat); + if (focus != NULL) { + view_close(focus); } } else if (strcmp(command, "next_window") == 0) { if (!wl_list_empty(&seat->views)) { diff --git a/rootston/seat.c b/rootston/seat.c index d5844ea6..61399850 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -485,7 +485,7 @@ bool roots_seat_has_meta_pressed(struct roots_seat *seat) { return false; } -struct roots_view *roots_seat_get_focused_view(struct roots_seat *seat) { +struct roots_view *roots_seat_get_focus(struct roots_seat *seat) { if (!seat->has_focus || wl_list_empty(&seat->views)) { return NULL; } @@ -497,12 +497,12 @@ struct roots_view *roots_seat_get_focused_view(struct roots_seat *seat) { static void seat_view_destroy(struct roots_seat_view *seat_view) { struct roots_seat *seat = seat_view->seat; - if (seat_view->view == roots_seat_get_focused_view(seat)) { + if (seat_view->view == roots_seat_get_focus(seat)) { seat->has_focus = false; seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; } - wl_list_remove(&seat_view->destroy.link); + wl_list_remove(&seat_view->view_destroy.link); wl_list_remove(&seat_view->link); free(seat_view); @@ -516,7 +516,7 @@ static void seat_view_destroy(struct roots_seat_view *seat_view) { static void seat_view_handle_destroy(struct wl_listener *listener, void *data) { struct roots_seat_view *seat_view = - wl_container_of(listener, seat_view, destroy); + wl_container_of(listener, seat_view, view_destroy); seat_view_destroy(seat_view); } @@ -532,14 +532,14 @@ static struct roots_seat_view *seat_add_view(struct roots_seat *seat, wl_list_insert(&seat->views, &seat_view->link); - seat_view->destroy.notify = seat_view_handle_destroy; - wl_signal_add(&view->events.destroy, &seat_view->destroy); + seat_view->view_destroy.notify = seat_view_handle_destroy; + wl_signal_add(&view->events.destroy, &seat_view->view_destroy); return seat_view; } void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { - struct roots_view *prev_focus = roots_seat_get_focused_view(seat); + struct roots_view *prev_focus = roots_seat_get_focus(seat); if (view == prev_focus) { return; } @@ -569,7 +569,7 @@ void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { seat->has_focus = false; - // unfocus the old view if it is not focused by some other seat + // deactivate the old view if it is not focused by some other seat if (prev_focus != NULL && !input_view_has_focus(seat->input, prev_focus)) { view_activate(prev_focus, false); } From 97ddd2d1df439a5b074e4dfa2865479646b8f3a6 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 19 Nov 2017 19:21:18 +0100 Subject: [PATCH 10/16] Add roots_seat_cycle_focus --- include/rootston/seat.h | 4 +++- rootston/cursor.c | 4 ++-- rootston/desktop.c | 2 +- rootston/keyboard.c | 6 +----- rootston/seat.c | 13 +++++++++++-- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/include/rootston/seat.h b/include/rootston/seat.h index d9a44c2d..7822bb70 100644 --- a/include/rootston/seat.h +++ b/include/rootston/seat.h @@ -71,7 +71,9 @@ bool roots_seat_has_meta_pressed(struct roots_seat *seat); struct roots_view *roots_seat_get_focus(struct roots_seat *seat); -void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view); +void roots_seat_set_focus(struct roots_seat *seat, struct roots_view *view); + +void roots_seat_cycle_focus(struct roots_seat *seat); void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view); diff --git a/rootston/cursor.c b/rootston/cursor.c index 3bb2a700..71075aa9 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -142,7 +142,7 @@ static void roots_cursor_press_button(struct roots_cursor *cursor, if (state == WLR_BUTTON_PRESSED && view && roots_seat_has_meta_pressed(seat)) { - roots_seat_focus_view(seat, view); + roots_seat_set_focus(seat, view); uint32_t edges; switch (button) { @@ -193,7 +193,7 @@ static void roots_cursor_press_button(struct roots_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); + roots_seat_set_focus(seat, view); break; } } diff --git a/rootston/desktop.c b/rootston/desktop.c index bea492ba..cf5a8cdc 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -197,7 +197,7 @@ void view_setup(struct roots_view *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); + roots_seat_set_focus(seat, view); } view_center(view); diff --git a/rootston/keyboard.c b/rootston/keyboard.c index b8c7aca6..f3fc9a85 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -96,11 +96,7 @@ static void keyboard_binding_execute(struct roots_keyboard *keyboard, view_close(focus); } } else if (strcmp(command, "next_window") == 0) { - if (!wl_list_empty(&seat->views)) { - struct roots_seat_view *last_seat_view = wl_container_of( - seat->views.prev, last_seat_view, link); - roots_seat_focus_view(seat, last_seat_view->view); - } + roots_seat_cycle_focus(seat); } else if (strncmp(exec_prefix, command, strlen(exec_prefix)) == 0) { const char *shell_cmd = command + strlen(exec_prefix); pid_t pid = fork(); diff --git a/rootston/seat.c b/rootston/seat.c index 61399850..df6b8590 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -510,7 +510,7 @@ static void seat_view_destroy(struct roots_seat_view *seat_view) { if (!wl_list_empty(&seat->views)) { struct roots_seat_view *first_seat_view = wl_container_of( seat->views.next, first_seat_view, link); - roots_seat_focus_view(seat, first_seat_view->view); + roots_seat_set_focus(seat, first_seat_view->view); } } @@ -538,7 +538,7 @@ static struct roots_seat_view *seat_add_view(struct roots_seat *seat, return seat_view; } -void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { +void roots_seat_set_focus(struct roots_seat *seat, struct roots_view *view) { struct roots_view *prev_focus = roots_seat_get_focus(seat); if (view == prev_focus) { return; @@ -590,6 +590,15 @@ void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { wlr_seat_keyboard_notify_enter(seat->seat, view->wlr_surface); } +void roots_seat_cycle_focus(struct roots_seat *seat) { + if (wl_list_empty(&seat->views)) { + return; + } + struct roots_seat_view *last_seat_view = wl_container_of( + seat->views.prev, last_seat_view, link); + roots_seat_set_focus(seat, last_seat_view->view); +} + void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) { struct roots_cursor *cursor = seat->cursor; cursor->mode = ROOTS_CURSOR_MOVE; From 9687950de158d39904c8bec7e41d397baefd541a Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 19 Nov 2017 19:30:48 +0100 Subject: [PATCH 11/16] Raise the view on the desktop even if already focused in the seat --- rootston/seat.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/rootston/seat.c b/rootston/seat.c index df6b8590..70ecec7e 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -539,6 +539,13 @@ static struct roots_seat_view *seat_add_view(struct roots_seat *seat, } void roots_seat_set_focus(struct roots_seat *seat, struct roots_view *view) { + // Make sure the view will be rendered on top of others, even if it's + // already focused in this seat + if (view != NULL) { + wl_list_remove(&view->link); + wl_list_insert(&seat->input->server->desktop->views, &view->link); + } + struct roots_view *prev_focus = roots_seat_get_focus(seat); if (view == prev_focus) { return; @@ -569,7 +576,7 @@ void roots_seat_set_focus(struct roots_seat *seat, struct roots_view *view) { seat->has_focus = false; - // deactivate the old view if it is not focused by some other seat + // Deactivate the old view if it is not focused by some other seat if (prev_focus != NULL && !input_view_has_focus(seat->input, prev_focus)) { view_activate(prev_focus, false); } @@ -580,9 +587,6 @@ void roots_seat_set_focus(struct roots_seat *seat, struct roots_view *view) { } view_activate(view, true); - wl_list_remove(&seat_view->view->link); - wl_list_insert(&seat->input->server->desktop->views, - &seat_view->view->link); seat->has_focus = true; wl_list_remove(&seat_view->link); From 0191f3f711b642aa496204e770eaa0dc1914f26d Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 19 Nov 2017 21:54:11 +0100 Subject: [PATCH 12/16] Improve roots_seat_cycle_focus --- rootston/seat.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/rootston/seat.c b/rootston/seat.c index 70ecec7e..737bbd67 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -598,9 +598,25 @@ void roots_seat_cycle_focus(struct roots_seat *seat) { if (wl_list_empty(&seat->views)) { return; } - struct roots_seat_view *last_seat_view = wl_container_of( - seat->views.prev, last_seat_view, link); - roots_seat_set_focus(seat, last_seat_view->view); + + struct roots_seat_view *first_seat_view = wl_container_of( + seat->views.next, first_seat_view, link); + if (!seat->has_focus) { + roots_seat_set_focus(seat, first_seat_view->view); + return; + } + if (wl_list_length(&seat->views) < 2) { + return; + } + + // Focus the next view + struct roots_seat_view *next_seat_view = wl_container_of( + first_seat_view->link.next, next_seat_view, link); + roots_seat_set_focus(seat, next_seat_view->view); + + // Move the first view to the end of the list + wl_list_remove(&first_seat_view->link); + wl_list_insert(seat->views.prev, &first_seat_view->link); } void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) { From 0672d9cb52b55e582866a2bd3238d806cd241352 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sun, 19 Nov 2017 17:55:02 -0500 Subject: [PATCH 13/16] bug: properly send WM_STATE --- xwayland/xwm.c | 5 +++-- xwayland/xwm.h | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/xwayland/xwm.c b/xwayland/xwm.c index dff9fac2..36722591 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -42,6 +42,7 @@ const char *atom_map[ATOM_LAST] = { "_NET_WM_STATE_FULLSCREEN", "_NET_WM_STATE_MAXIMIZED_VERT", "_NET_WM_STATE_MAXIMIZED_HORZ", + "WM_STATE", }; /* General helpers */ @@ -641,8 +642,8 @@ static void xsurface_set_wm_state(struct wlr_xwayland_surface *xsurface, xcb_change_property(xwm->xcb_conn, XCB_PROP_MODE_REPLACE, xsurface->window_id, - xwm->atoms[NET_WM_STATE], - xwm->atoms[NET_WM_STATE], + xwm->atoms[WM_STATE], + xwm->atoms[WM_STATE], 32, // format 2, property); } diff --git a/xwayland/xwm.h b/xwayland/xwm.h index 547cd5eb..c350b6e2 100644 --- a/xwayland/xwm.h +++ b/xwayland/xwm.h @@ -30,6 +30,7 @@ enum atom_name { _NET_WM_STATE_FULLSCREEN, _NET_WM_STATE_MAXIMIZED_VERT, _NET_WM_STATE_MAXIMIZED_HORZ, + WM_STATE, ATOM_LAST, }; From 4d6b3618b8f8a953bd811b4cbf0975e6c00d96b8 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Mon, 20 Nov 2017 07:40:22 -0500 Subject: [PATCH 14/16] rootston: remove unmapped surface from desktop --- rootston/output.c | 2 +- rootston/xwayland.c | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/rootston/output.c b/rootston/output.c index 3b08d7bf..83ff37fd 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -38,7 +38,7 @@ static void rotate_child_position(double *sx, double *sy, double sw, double sh, static void render_surface(struct wlr_surface *surface, struct roots_desktop *desktop, struct wlr_output *wlr_output, struct timespec *when, double lx, double ly, float rotation) { - if (surface->texture->valid) { + if (wlr_surface_has_buffer(surface)) { int width = surface->current->width; int height = surface->current->height; int render_width = width * wlr_output->scale; diff --git a/rootston/xwayland.c b/rootston/xwayland.c index f5cb7857..c92c424b 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -175,22 +175,21 @@ static void handle_map_notify(struct wl_listener *listener, void *data) { wl_container_of(listener, roots_surface, map_notify); struct wlr_xwayland_surface *xsurface = data; struct roots_view *view = roots_surface->view; - //struct roots_desktop *desktop = view->desktop; + struct roots_desktop *desktop = view->desktop; view->wlr_surface = xsurface->surface; view->x = (double)xsurface->x; view->y = (double)xsurface->y; - // TODO: add view to desktop + wl_list_insert(&desktop->views, &view->link); } static void handle_unmap_notify(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, unmap_notify); - //struct roots_desktop *desktop = roots_surface->view->desktop; roots_surface->view->wlr_surface = NULL; - // TODO: remove view from desktop + wl_list_remove(&roots_surface->view->link); } void handle_xwayland_surface(struct wl_listener *listener, void *data) { From c3e0fbdb8f0cb16d99e70d14bb5cef6bd48d4591 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 20 Nov 2017 08:20:52 -0500 Subject: [PATCH 15/16] Remove meson hack --- dummy.c | 2 -- meson.build | 1 - 2 files changed, 3 deletions(-) delete mode 100644 dummy.c diff --git a/dummy.c b/dummy.c deleted file mode 100644 index 870fde8a..00000000 --- a/dummy.c +++ /dev/null @@ -1,2 +0,0 @@ -// This is used to make meson happy -void dummy(void); diff --git a/meson.build b/meson.build index 642dc38d..8ace085c 100644 --- a/meson.build +++ b/meson.build @@ -131,7 +131,6 @@ wlr_deps = [ lib_wlr = library( 'wlroots', - files('dummy.c'), link_whole: wlr_parts, dependencies: wlr_deps, include_directories: wlr_inc, From 6a06c3d9073507168df370f9f58642ce2eae1825 Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 20 Nov 2017 18:05:24 +0100 Subject: [PATCH 16/16] Fix segfault when closing xwayland views --- rootston/desktop.c | 3 --- rootston/wl_shell.c | 2 ++ rootston/xdg_shell_v6.c | 2 ++ rootston/xwayland.c | 6 ++++++ 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/rootston/desktop.c b/rootston/desktop.c index cf5a8cdc..65730807 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -181,15 +181,12 @@ bool view_center(struct roots_view *view) { void view_destroy(struct roots_view *view) { wl_signal_emit(&view->events.destroy, view); - wl_list_remove(&view->link); free(view); } void view_init(struct roots_view *view, struct roots_desktop *desktop) { view->desktop = desktop; wl_signal_init(&view->events.destroy); - - wl_list_insert(&desktop->views, &view->link); } void view_setup(struct roots_view *view) { diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index 7359c878..d0f5989b 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -83,6 +83,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) { wl_list_remove(&roots_surface->request_set_maximized.link); wl_list_remove(&roots_surface->set_state.link); wl_list_remove(&roots_surface->surface_commit.link); + wl_list_remove(&roots_surface->view->link); view_destroy(roots_surface->view); free(roots_surface); } @@ -131,6 +132,7 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { view->close = close; roots_surface->view = view; view_init(view, desktop); + wl_list_insert(&desktop->views, &view->link); view_setup(view); diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 656231c7..ea19753b 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -165,6 +165,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) { wl_list_remove(&roots_xdg_surface->destroy.link); wl_list_remove(&roots_xdg_surface->request_move.link); wl_list_remove(&roots_xdg_surface->request_resize.link); + wl_list_remove(&roots_xdg_surface->view->link); view_destroy(roots_xdg_surface->view); free(roots_xdg_surface); } @@ -220,6 +221,7 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { view->close = close; roots_surface->view = view; view_init(view, desktop); + wl_list_insert(&desktop->views, &view->link); view_setup(view); } diff --git a/rootston/xwayland.c b/rootston/xwayland.c index c92c424b..dfa602b1 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -95,6 +95,8 @@ static void maximize(struct roots_view *view, bool maximized) { static void handle_destroy(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, destroy); + struct wlr_xwayland_surface *xwayland_surface = + roots_surface->view->xwayland_surface; wl_list_remove(&roots_surface->destroy.link); wl_list_remove(&roots_surface->request_configure.link); wl_list_remove(&roots_surface->request_move.link); @@ -102,6 +104,9 @@ static void handle_destroy(struct wl_listener *listener, void *data) { wl_list_remove(&roots_surface->request_maximize.link); wl_list_remove(&roots_surface->map_notify.link); wl_list_remove(&roots_surface->unmap_notify.link); + if (xwayland_surface->mapped) { + wl_list_remove(&roots_surface->view->link); + } view_destroy(roots_surface->view); free(roots_surface); } @@ -243,6 +248,7 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { view->close = close; roots_surface->view = view; view_init(view, desktop); + wl_list_insert(&desktop->views, &view->link); if (!surface->override_redirect) { view_setup(view);