From acd79e1505c06089e4fb9fb6c0c6e1d351ba9176 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 26 Jun 2018 20:32:09 -0400 Subject: Implement pid->workspace tracking When you spawn a process with the exec command, sway now notes the workspace you had focused and the pid of the child process, then assigns that workspace to the child when its window appears. Some of this is carried over from sway 0.15, but with some major refactoring and centralization of state. --- sway/desktop/xdg_shell.c | 3 --- sway/desktop/xdg_shell_v6.c | 3 --- sway/desktop/xwayland.c | 3 --- 3 files changed, 9 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 82db4076..47604c31 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -321,9 +321,6 @@ void handle_xdg_shell_surface(struct wl_listener *listener, void *data) { view_init(&xdg_shell_view->view, SWAY_VIEW_XDG_SHELL, &view_impl); xdg_shell_view->view.wlr_xdg_surface = xdg_surface; - // TODO: - // - Look up pid and open on appropriate workspace - xdg_shell_view->map.notify = handle_map; wl_signal_add(&xdg_surface->events.map, &xdg_shell_view->map); diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 0d3c1644..b28c4b9c 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -312,9 +312,6 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { view_init(&xdg_shell_v6_view->view, SWAY_VIEW_XDG_SHELL_V6, &view_impl); xdg_shell_v6_view->view.wlr_xdg_surface_v6 = xdg_surface; - // TODO: - // - Look up pid and open on appropriate workspace - xdg_shell_v6_view->map.notify = handle_map; wl_signal_add(&xdg_surface->events.map, &xdg_shell_v6_view->map); diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 4bb35f60..b3b1473d 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c @@ -446,9 +446,6 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { view_init(&xwayland_view->view, SWAY_VIEW_XWAYLAND, &view_impl); xwayland_view->view.wlr_xwayland_surface = xsurface; - // TODO: - // - Look up pid and open on appropriate workspace - wl_signal_add(&xsurface->events.destroy, &xwayland_view->destroy); xwayland_view->destroy.notify = handle_destroy; -- cgit v1.2.3 From f9491c9584d2c1fb789eee9c9e21fd6c274f4579 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Thu, 19 Jul 2018 13:18:04 +1000 Subject: Fix damage issue when moving and resizing --- sway/desktop/output.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index a9808406..a206ac6b 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -463,11 +463,12 @@ static void output_damage_whole_container_iterator(struct sway_container *con, void output_damage_whole_container(struct sway_output *output, struct sway_container *con) { + // Pad the box by 1px, because the width is a double and might be a fraction struct wlr_box box = { - .x = con->current.swayc_x - output->wlr_output->lx, - .y = con->current.swayc_y - output->wlr_output->ly, - .width = con->current.swayc_width, - .height = con->current.swayc_height, + .x = con->current.swayc_x - output->wlr_output->lx - 1, + .y = con->current.swayc_y - output->wlr_output->ly - 1, + .width = con->current.swayc_width + 2, + .height = con->current.swayc_height + 2, }; scale_box(&box, output->wlr_output->scale); wlr_output_damage_add_box(output->damage, &box); -- cgit v1.2.3 From 31f91bd483797feb411077da0e351ccfae9ecc10 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Thu, 19 Jul 2018 15:37:09 +1000 Subject: Improve resize performance by partially flushing the transaction queue When interactively resizing some views (eg. Nautilus), new transactions are added to the queue faster than the client can process them. Previously, we would wait for the entire queue to be ready before applying any of them, but in this case the transactions would time out, giving the client choppy performance. This changes the queue handling so it applies the transactions up to the first waiting transaction, without waiting for the entire queue to be ready. --- sway/desktop/transaction.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 19f41efc..2a89880a 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -222,24 +222,16 @@ static void transaction_apply(struct sway_transaction *transaction) { } } -/** - * For simplicity, we only progress the queue if it can be completely flushed. - */ static void transaction_progress_queue() { - // We iterate this list in reverse because we're more likely to find a - // waiting transactions at the end of the list. - for (int i = server.transactions->length - 1; i >= 0; --i) { - struct sway_transaction *transaction = server.transactions->items[i]; + while (server.transactions->length) { + struct sway_transaction *transaction = server.transactions->items[0]; if (transaction->num_waiting) { return; } - } - for (int i = 0; i < server.transactions->length; ++i) { - struct sway_transaction *transaction = server.transactions->items[i]; transaction_apply(transaction); transaction_destroy(transaction); + list_del(server.transactions, 0); } - server.transactions->length = 0; idle_inhibit_v1_check_active(server.idle_inhibit_manager_v1); } -- cgit v1.2.3 From ff445cc85597ee6bfae01f03d3c246e2326f3981 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Fri, 20 Jul 2018 09:28:22 +1000 Subject: Implement xdg shell request_move and request_resize events Also does a few other related things: * Now uses enum wlr_edges instead of our own enum resize_edge * Now uses wlr_xcursor_get_resize_name and removes our own find_resize_edge_name * Renames drag to move for consistency --- sway/desktop/xdg_shell.c | 33 +++++++++++++++++++++++++++++++++ sway/desktop/xdg_shell_v6.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) (limited to 'sway/desktop') diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 98c16faf..d6c3a9a7 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -1,4 +1,9 @@ #define _POSIX_C_SOURCE 199309L +#ifdef __linux__ +#include +#elif __FreeBSD__ +#include +#endif #include #include #include @@ -248,6 +253,24 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) transaction_commit_dirty(); } +static void handle_request_move(struct wl_listener *listener, void *data) { + struct sway_xdg_shell_view *xdg_shell_view = + wl_container_of(listener, xdg_shell_view, request_move); + struct sway_view *view = &xdg_shell_view->view; + struct wlr_xdg_toplevel_move_event *e = data; + struct sway_seat *seat = e->seat->seat->data; + seat_begin_move(seat, view->swayc); +} + +static void handle_request_resize(struct wl_listener *listener, void *data) { + struct sway_xdg_shell_view *xdg_shell_view = + wl_container_of(listener, xdg_shell_view, request_resize); + struct sway_view *view = &xdg_shell_view->view; + struct wlr_xdg_toplevel_resize_event *e = data; + struct sway_seat *seat = e->seat->seat->data; + seat_begin_resize(seat, view->swayc, BTN_LEFT, e->edges); +} + static void handle_unmap(struct wl_listener *listener, void *data) { struct sway_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, unmap); @@ -262,6 +285,8 @@ static void handle_unmap(struct wl_listener *listener, void *data) { wl_list_remove(&xdg_shell_view->commit.link); wl_list_remove(&xdg_shell_view->new_popup.link); wl_list_remove(&xdg_shell_view->request_fullscreen.link); + wl_list_remove(&xdg_shell_view->request_move.link); + wl_list_remove(&xdg_shell_view->request_resize.link); } static void handle_map(struct wl_listener *listener, void *data) { @@ -299,6 +324,14 @@ static void handle_map(struct wl_listener *listener, void *data) { xdg_shell_view->request_fullscreen.notify = handle_request_fullscreen; wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen, &xdg_shell_view->request_fullscreen); + + xdg_shell_view->request_move.notify = handle_request_move; + wl_signal_add(&xdg_surface->toplevel->events.request_move, + &xdg_shell_view->request_move); + + xdg_shell_view->request_resize.notify = handle_request_resize; + wl_signal_add(&xdg_surface->toplevel->events.request_resize, + &xdg_shell_view->request_resize); } static void handle_destroy(struct wl_listener *listener, void *data) { diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 4d76f0a7..241bd9b0 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -1,4 +1,9 @@ #define _POSIX_C_SOURCE 199309L +#ifdef __linux__ +#include +#elif __FreeBSD__ +#include +#endif #include #include #include @@ -243,6 +248,24 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) transaction_commit_dirty(); } +static void handle_request_move(struct wl_listener *listener, void *data) { + struct sway_xdg_shell_v6_view *xdg_shell_v6_view = + wl_container_of(listener, xdg_shell_v6_view, request_move); + struct sway_view *view = &xdg_shell_v6_view->view; + struct wlr_xdg_toplevel_v6_move_event *e = data; + struct sway_seat *seat = e->seat->seat->data; + seat_begin_move(seat, view->swayc); +} + +static void handle_request_resize(struct wl_listener *listener, void *data) { + struct sway_xdg_shell_v6_view *xdg_shell_v6_view = + wl_container_of(listener, xdg_shell_v6_view, request_resize); + struct sway_view *view = &xdg_shell_v6_view->view; + struct wlr_xdg_toplevel_v6_resize_event *e = data; + struct sway_seat *seat = e->seat->seat->data; + seat_begin_resize(seat, view->swayc, BTN_LEFT, e->edges); +} + static void handle_unmap(struct wl_listener *listener, void *data) { struct sway_xdg_shell_v6_view *xdg_shell_v6_view = wl_container_of(listener, xdg_shell_v6_view, unmap); @@ -257,6 +280,8 @@ static void handle_unmap(struct wl_listener *listener, void *data) { wl_list_remove(&xdg_shell_v6_view->commit.link); wl_list_remove(&xdg_shell_v6_view->new_popup.link); wl_list_remove(&xdg_shell_v6_view->request_fullscreen.link); + wl_list_remove(&xdg_shell_v6_view->request_move.link); + wl_list_remove(&xdg_shell_v6_view->request_resize.link); } static void handle_map(struct wl_listener *listener, void *data) { @@ -294,6 +319,14 @@ static void handle_map(struct wl_listener *listener, void *data) { xdg_shell_v6_view->request_fullscreen.notify = handle_request_fullscreen; wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen, &xdg_shell_v6_view->request_fullscreen); + + xdg_shell_v6_view->request_move.notify = handle_request_move; + wl_signal_add(&xdg_surface->toplevel->events.request_move, + &xdg_shell_v6_view->request_move); + + xdg_shell_v6_view->request_resize.notify = handle_request_resize; + wl_signal_add(&xdg_surface->toplevel->events.request_resize, + &xdg_shell_v6_view->request_resize); } static void handle_destroy(struct wl_listener *listener, void *data) { -- cgit v1.2.3 From 9df660ee3188386c907d8feb999636ce8d61d095 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 21 Jul 2018 11:23:48 +1000 Subject: Store last button and use it when views request to move or resize --- sway/desktop/xdg_shell.c | 13 ++++++------- sway/desktop/xdg_shell_v6.c | 13 ++++++------- 2 files changed, 12 insertions(+), 14 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index d6c3a9a7..c5d53d1d 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -1,9 +1,4 @@ #define _POSIX_C_SOURCE 199309L -#ifdef __linux__ -#include -#elif __FreeBSD__ -#include -#endif #include #include #include @@ -259,7 +254,9 @@ static void handle_request_move(struct wl_listener *listener, void *data) { struct sway_view *view = &xdg_shell_view->view; struct wlr_xdg_toplevel_move_event *e = data; struct sway_seat *seat = e->seat->seat->data; - seat_begin_move(seat, view->swayc); + if (e->serial == seat->last_button_serial) { + seat_begin_move(seat, view->swayc, seat->last_button); + } } static void handle_request_resize(struct wl_listener *listener, void *data) { @@ -268,7 +265,9 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { struct sway_view *view = &xdg_shell_view->view; struct wlr_xdg_toplevel_resize_event *e = data; struct sway_seat *seat = e->seat->seat->data; - seat_begin_resize(seat, view->swayc, BTN_LEFT, e->edges); + if (e->serial == seat->last_button_serial) { + seat_begin_resize(seat, view->swayc, seat->last_button, e->edges); + } } static void handle_unmap(struct wl_listener *listener, void *data) { diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 241bd9b0..4bd6af5e 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -1,9 +1,4 @@ #define _POSIX_C_SOURCE 199309L -#ifdef __linux__ -#include -#elif __FreeBSD__ -#include -#endif #include #include #include @@ -254,7 +249,9 @@ static void handle_request_move(struct wl_listener *listener, void *data) { struct sway_view *view = &xdg_shell_v6_view->view; struct wlr_xdg_toplevel_v6_move_event *e = data; struct sway_seat *seat = e->seat->seat->data; - seat_begin_move(seat, view->swayc); + if (e->serial == seat->last_button_serial) { + seat_begin_move(seat, view->swayc, seat->last_button); + } } static void handle_request_resize(struct wl_listener *listener, void *data) { @@ -263,7 +260,9 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { struct sway_view *view = &xdg_shell_v6_view->view; struct wlr_xdg_toplevel_v6_resize_event *e = data; struct sway_seat *seat = e->seat->seat->data; - seat_begin_resize(seat, view->swayc, BTN_LEFT, e->edges); + if (e->serial == seat->last_button_serial) { + seat_begin_resize(seat, view->swayc, seat->last_button, e->edges); + } } static void handle_unmap(struct wl_listener *listener, void *data) { -- cgit v1.2.3 From 011d1ebfa4219eb666487529a5a5e7189c14fd40 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 21 Jul 2018 12:13:00 +1000 Subject: Consider view's min/max sizes when resizing --- sway/desktop/xdg_shell.c | 12 ++++++++++++ sway/desktop/xdg_shell_v6.c | 12 ++++++++++++ 2 files changed, 24 insertions(+) (limited to 'sway/desktop') diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index c5d53d1d..76fe72ea 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -1,4 +1,5 @@ #define _POSIX_C_SOURCE 199309L +#include #include #include #include @@ -95,6 +96,16 @@ static struct sway_xdg_shell_view *xdg_shell_view_from_view( return (struct sway_xdg_shell_view *)view; } +static void get_constraints(struct sway_view *view, double *min_width, + double *max_width, double *min_height, double *max_height) { + struct wlr_xdg_toplevel_state *state = + &view->wlr_xdg_surface->toplevel->current; + *min_width = state->min_width > 0 ? state->min_width : DBL_MIN; + *max_width = state->max_width > 0 ? state->max_width : DBL_MAX; + *min_height = state->min_height > 0 ? state->min_height : DBL_MIN; + *max_height = state->max_height > 0 ? state->max_height : DBL_MAX; +} + static const char *get_string_prop(struct sway_view *view, enum sway_view_prop prop) { if (xdg_shell_view_from_view(view) == NULL) { return NULL; @@ -188,6 +199,7 @@ static void destroy(struct sway_view *view) { } static const struct sway_view_impl view_impl = { + .get_constraints = get_constraints, .get_string_prop = get_string_prop, .configure = configure, .set_activated = set_activated, diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 4bd6af5e..57b51908 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -1,4 +1,5 @@ #define _POSIX_C_SOURCE 199309L +#include #include #include #include @@ -94,6 +95,16 @@ static struct sway_xdg_shell_v6_view *xdg_shell_v6_view_from_view( return (struct sway_xdg_shell_v6_view *)view; } +static void get_constraints(struct sway_view *view, double *min_width, + double *max_width, double *min_height, double *max_height) { + struct wlr_xdg_toplevel_v6_state *state = + &view->wlr_xdg_surface_v6->toplevel->current; + *min_width = state->min_width > 0 ? state->min_width : DBL_MIN; + *max_width = state->max_width > 0 ? state->max_width : DBL_MAX; + *min_height = state->min_height > 0 ? state->min_height : DBL_MIN; + *max_height = state->max_height > 0 ? state->max_height : DBL_MAX; +} + static const char *get_string_prop(struct sway_view *view, enum sway_view_prop prop) { if (xdg_shell_v6_view_from_view(view) == NULL) { return NULL; @@ -184,6 +195,7 @@ static void destroy(struct sway_view *view) { } static const struct sway_view_impl view_impl = { + .get_constraints = get_constraints, .get_string_prop = get_string_prop, .configure = configure, .set_activated = set_activated, -- cgit v1.2.3 From cf5f5eaf8c67c9d06c491a82b0b235aa27bbfe5c Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sun, 22 Jul 2018 21:45:01 +1000 Subject: Deny move/resize events for tiled xdg shell views --- sway/desktop/xdg_shell.c | 6 ++++++ sway/desktop/xdg_shell_v6.c | 6 ++++++ 2 files changed, 12 insertions(+) (limited to 'sway/desktop') diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 76fe72ea..706b35c3 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -264,6 +264,9 @@ static void handle_request_move(struct wl_listener *listener, void *data) { struct sway_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, request_move); struct sway_view *view = &xdg_shell_view->view; + if (!container_is_floating(view->swayc)) { + return; + } struct wlr_xdg_toplevel_move_event *e = data; struct sway_seat *seat = e->seat->seat->data; if (e->serial == seat->last_button_serial) { @@ -275,6 +278,9 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { struct sway_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, request_resize); struct sway_view *view = &xdg_shell_view->view; + if (!container_is_floating(view->swayc)) { + return; + } struct wlr_xdg_toplevel_resize_event *e = data; struct sway_seat *seat = e->seat->seat->data; if (e->serial == seat->last_button_serial) { diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 57b51908..201b5b1e 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -259,6 +259,9 @@ static void handle_request_move(struct wl_listener *listener, void *data) { struct sway_xdg_shell_v6_view *xdg_shell_v6_view = wl_container_of(listener, xdg_shell_v6_view, request_move); struct sway_view *view = &xdg_shell_v6_view->view; + if (!container_is_floating(view->swayc)) { + return; + } struct wlr_xdg_toplevel_v6_move_event *e = data; struct sway_seat *seat = e->seat->seat->data; if (e->serial == seat->last_button_serial) { @@ -270,6 +273,9 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { struct sway_xdg_shell_v6_view *xdg_shell_v6_view = wl_container_of(listener, xdg_shell_v6_view, request_resize); struct sway_view *view = &xdg_shell_v6_view->view; + if (!container_is_floating(view->swayc)) { + return; + } struct wlr_xdg_toplevel_v6_resize_event *e = data; struct sway_seat *seat = e->seat->seat->data; if (e->serial == seat->last_button_serial) { -- cgit v1.2.3 From 5ba2ae9c6a4372cbf6f8867b711bb55ef6937cb4 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sun, 22 Jul 2018 22:14:36 +1000 Subject: Implement request_move and request_resize for xwayland views I discovered we have to send a click event when ending the move or resize operation to make xwayland's requests work correctly. --- sway/desktop/xwayland.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'sway/desktop') diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index bce0a37b..2546168b 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c @@ -305,6 +305,8 @@ static void handle_destroy(struct wl_listener *listener, void *data) { wl_list_remove(&xwayland_view->destroy.link); wl_list_remove(&xwayland_view->request_configure.link); wl_list_remove(&xwayland_view->request_fullscreen.link); + wl_list_remove(&xwayland_view->request_move.link); + wl_list_remove(&xwayland_view->request_resize.link); wl_list_remove(&xwayland_view->set_title.link); wl_list_remove(&xwayland_view->set_class.link); wl_list_remove(&xwayland_view->set_window_type.link); @@ -400,6 +402,37 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) transaction_commit_dirty(); } +static void handle_request_move(struct wl_listener *listener, void *data) { + struct sway_xwayland_view *xwayland_view = + wl_container_of(listener, xwayland_view, request_move); + struct sway_view *view = &xwayland_view->view; + struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; + if (!xsurface->mapped) { + return; + } + if (!container_is_floating(view->swayc)) { + return; + } + struct sway_seat *seat = input_manager_current_seat(input_manager); + seat_begin_move(seat, view->swayc, seat->last_button); +} + +static void handle_request_resize(struct wl_listener *listener, void *data) { + struct sway_xwayland_view *xwayland_view = + wl_container_of(listener, xwayland_view, request_resize); + struct sway_view *view = &xwayland_view->view; + struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; + if (!xsurface->mapped) { + return; + } + if (!container_is_floating(view->swayc)) { + return; + } + struct wlr_xwayland_resize_event *e = data; + struct sway_seat *seat = input_manager_current_seat(input_manager); + seat_begin_resize(seat, view->swayc, seat->last_button, e->edges); +} + static void handle_set_title(struct wl_listener *listener, void *data) { struct sway_xwayland_view *xwayland_view = wl_container_of(listener, xwayland_view, set_title); @@ -495,6 +528,14 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { &xwayland_view->request_fullscreen); xwayland_view->request_fullscreen.notify = handle_request_fullscreen; + wl_signal_add(&xsurface->events.request_move, + &xwayland_view->request_move); + xwayland_view->request_move.notify = handle_request_move; + + wl_signal_add(&xsurface->events.request_resize, + &xwayland_view->request_resize); + xwayland_view->request_resize.notify = handle_request_resize; + wl_signal_add(&xsurface->events.set_title, &xwayland_view->set_title); xwayland_view->set_title.notify = handle_set_title; -- cgit v1.2.3 From 238c8afc74241efdc44d1cf88322d322ce1226d9 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 22 Jul 2018 22:20:07 +0100 Subject: Handle set_{title,app_id} for xdg-shell and zxdg-shell-v6 This allows to update the title even if the view doesn't commit. This is useful e.g. when a terminal sets its toplevel title to the currently running command and when the view isn't visible. --- sway/desktop/xdg_shell.c | 26 +++++++++++++++++++++++++- sway/desktop/xdg_shell_v6.c | 26 +++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 706b35c3..62c3abc8 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -225,10 +225,24 @@ static void handle_commit(struct wl_listener *listener, void *data) { transaction_notify_view_ready(view, xdg_surface->configure_serial); } - view_update_title(view, false); view_damage_from(view); } +static void handle_set_title(struct wl_listener *listener, void *data) { + struct sway_xdg_shell_view *xdg_shell_view = + wl_container_of(listener, xdg_shell_view, set_title); + struct sway_view *view = &xdg_shell_view->view; + view_update_title(view, false); + view_execute_criteria(view); +} + +static void handle_set_app_id(struct wl_listener *listener, void *data) { + struct sway_xdg_shell_view *xdg_shell_view = + wl_container_of(listener, xdg_shell_view, set_app_id); + struct sway_view *view = &xdg_shell_view->view; + view_execute_criteria(view); +} + static void handle_new_popup(struct wl_listener *listener, void *data) { struct sway_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, new_popup); @@ -304,6 +318,8 @@ static void handle_unmap(struct wl_listener *listener, void *data) { wl_list_remove(&xdg_shell_view->request_fullscreen.link); wl_list_remove(&xdg_shell_view->request_move.link); wl_list_remove(&xdg_shell_view->request_resize.link); + wl_list_remove(&xdg_shell_view->set_title.link); + wl_list_remove(&xdg_shell_view->set_app_id.link); } static void handle_map(struct wl_listener *listener, void *data) { @@ -349,6 +365,14 @@ static void handle_map(struct wl_listener *listener, void *data) { xdg_shell_view->request_resize.notify = handle_request_resize; wl_signal_add(&xdg_surface->toplevel->events.request_resize, &xdg_shell_view->request_resize); + + xdg_shell_view->set_title.notify = handle_set_title; + wl_signal_add(&xdg_surface->toplevel->events.set_title, + &xdg_shell_view->set_title); + + xdg_shell_view->set_app_id.notify = handle_set_app_id; + wl_signal_add(&xdg_surface->toplevel->events.set_app_id, + &xdg_shell_view->set_app_id); } static void handle_destroy(struct wl_listener *listener, void *data) { diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 201b5b1e..7fb85410 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -220,10 +220,24 @@ static void handle_commit(struct wl_listener *listener, void *data) { transaction_notify_view_ready(view, xdg_surface_v6->configure_serial); } - view_update_title(view, false); view_damage_from(view); } +static void handle_set_title(struct wl_listener *listener, void *data) { + struct sway_xdg_shell_v6_view *xdg_shell_v6_view = + wl_container_of(listener, xdg_shell_v6_view, set_title); + struct sway_view *view = &xdg_shell_v6_view->view; + view_update_title(view, false); + view_execute_criteria(view); +} + +static void handle_set_app_id(struct wl_listener *listener, void *data) { + struct sway_xdg_shell_v6_view *xdg_shell_v6_view = + wl_container_of(listener, xdg_shell_v6_view, set_app_id); + struct sway_view *view = &xdg_shell_v6_view->view; + view_execute_criteria(view); +} + static void handle_new_popup(struct wl_listener *listener, void *data) { struct sway_xdg_shell_v6_view *xdg_shell_v6_view = wl_container_of(listener, xdg_shell_v6_view, new_popup); @@ -299,6 +313,8 @@ static void handle_unmap(struct wl_listener *listener, void *data) { wl_list_remove(&xdg_shell_v6_view->request_fullscreen.link); wl_list_remove(&xdg_shell_v6_view->request_move.link); wl_list_remove(&xdg_shell_v6_view->request_resize.link); + wl_list_remove(&xdg_shell_v6_view->set_title.link); + wl_list_remove(&xdg_shell_v6_view->set_app_id.link); } static void handle_map(struct wl_listener *listener, void *data) { @@ -344,6 +360,14 @@ static void handle_map(struct wl_listener *listener, void *data) { xdg_shell_v6_view->request_resize.notify = handle_request_resize; wl_signal_add(&xdg_surface->toplevel->events.request_resize, &xdg_shell_v6_view->request_resize); + + xdg_shell_v6_view->set_title.notify = handle_set_title; + wl_signal_add(&xdg_surface->toplevel->events.set_title, + &xdg_shell_v6_view->set_title); + + xdg_shell_v6_view->set_app_id.notify = handle_set_app_id; + wl_signal_add(&xdg_surface->toplevel->events.set_app_id, + &xdg_shell_v6_view->set_app_id); } static void handle_destroy(struct wl_listener *listener, void *data) { -- cgit v1.2.3 From 7ead2e85a7816a65e87bb7fded7414f571d56619 Mon Sep 17 00:00:00 2001 From: somdoron Date: Mon, 23 Jul 2018 19:29:32 +0300 Subject: fix crash on new output while swaylock is running --- sway/desktop/render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sway/desktop') diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 4c85e516..7da54594 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -838,7 +838,7 @@ void output_render(struct sway_output *output, struct timespec *when, struct sway_view *fullscreen_view = workspace->current.ws_fullscreen; struct sway_seat *seat = input_manager_current_seat(input_manager); - if (output_has_opaque_lockscreen(output, seat)) { + if (output_has_opaque_lockscreen(output, seat) && seat->focused_layer) { struct wlr_layer_surface *wlr_layer_surface = seat->focused_layer; struct sway_layer_surface *sway_layer_surface = layer_from_wlr_layer_surface(seat->focused_layer); -- cgit v1.2.3 From 24ad1c3983192b47345566fd876e26b45160d68e Mon Sep 17 00:00:00 2001 From: Pascal Pascher Date: Tue, 24 Jul 2018 22:16:06 +0200 Subject: Added meson option "enable_xwayland" (default: true) to enable/disable xwayland support --- sway/desktop/output.c | 15 +++++++++------ sway/desktop/render.c | 10 ++++++---- sway/desktop/xwayland.c | 2 ++ 3 files changed, 17 insertions(+), 10 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index a206ac6b..7cca23bd 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -128,7 +128,7 @@ void output_layer_for_each_surface(struct wl_list *layer_surfaces, user_data); } } - +#ifdef HAVE_XWAYLAND void output_unmanaged_for_each_surface(struct wl_list *unmanaged, struct sway_output *output, struct root_geometry *geo, wlr_surface_iterator_func_t iterator, void *user_data) { @@ -143,7 +143,7 @@ void output_unmanaged_for_each_surface(struct wl_list *unmanaged, iterator, user_data); } } - +#endif void output_drag_icons_for_each_surface(struct wl_list *drag_icons, struct sway_output *output, struct root_geometry *geo, wlr_surface_iterator_func_t iterator, void *user_data) { @@ -244,13 +244,13 @@ static void send_frame_done_layer(struct send_frame_done_data *data, output_layer_for_each_surface(layer_surfaces, &data->root_geo, send_frame_done_iterator, data); } - +#ifdef HAVE_XWAYLAND static void send_frame_done_unmanaged(struct send_frame_done_data *data, struct wl_list *unmanaged) { output_unmanaged_for_each_surface(unmanaged, data->output, &data->root_geo, send_frame_done_iterator, data); } - +#endif static void send_frame_done_drag_icons(struct send_frame_done_data *data, struct wl_list *drag_icons) { output_drag_icons_for_each_surface(drag_icons, data->output, &data->root_geo, @@ -291,11 +291,12 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { if (workspace->current.ws_fullscreen) { send_frame_done_container_iterator( workspace->current.ws_fullscreen->swayc, &data); - + #ifdef HAVE_XWAYLAND if (workspace->current.ws_fullscreen->type == SWAY_VIEW_XWAYLAND) { send_frame_done_unmanaged(&data, &root_container.sway_root->xwayland_unmanaged); } + #endif } else { send_frame_done_layer(&data, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]); @@ -304,9 +305,11 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { send_frame_done_container(&data, workspace); send_frame_done_container(&data, workspace->sway_workspace->floating); - + + #ifdef HAVE_XWAYLAND send_frame_done_unmanaged(&data, &root_container.sway_root->xwayland_unmanaged); + #endif send_frame_done_layer(&data, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); } diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 7da54594..46bfec6b 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -132,7 +132,7 @@ static void render_layer(struct sway_output *output, output_layer_for_each_surface(layer_surfaces, &data.root_geo, render_surface_iterator, &data); } - +#ifdef HAVE_XWAYLAND static void render_unmanaged(struct sway_output *output, pixman_region32_t *damage, struct wl_list *unmanaged) { struct render_data data = { @@ -143,7 +143,7 @@ static void render_unmanaged(struct sway_output *output, output_unmanaged_for_each_surface(unmanaged, output, &data.root_geo, render_surface_iterator, &data); } - +#endif static void render_drag_icons(struct sway_output *output, pixman_region32_t *damage, struct wl_list *drag_icons) { struct render_data data = { @@ -866,11 +866,12 @@ void output_render(struct sway_output *output, struct timespec *when, } else { render_view_surfaces(fullscreen_view, output, damage, 1.0f); } - + #ifdef HAVE_XWAYLAND if (fullscreen_view->type == SWAY_VIEW_XWAYLAND) { render_unmanaged(output, damage, &root_container.sway_root->xwayland_unmanaged); } + #endif } else { float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f}; @@ -888,9 +889,10 @@ void output_render(struct sway_output *output, struct timespec *when, render_container(output, damage, workspace, workspace->current.focused); render_floating(output, damage); - + #ifdef HAVE_XWAYLAND render_unmanaged(output, damage, &root_container.sway_root->xwayland_unmanaged); + #endif render_layer(output, damage, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); } diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 65d4fcd4..d940d47b 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c @@ -1,4 +1,5 @@ #define _POSIX_C_SOURCE 199309L +#ifdef HAVE_XWAYLAND #include #include #include @@ -591,3 +592,4 @@ void handle_xwayland_ready(struct wl_listener *listener, void *data) { xcb_disconnect(xcb_conn); } +#endif -- cgit v1.2.3 From 2bf893248a94c7f70a9557aad4a8228731041eeb Mon Sep 17 00:00:00 2001 From: Pascal Pascher Date: Tue, 24 Jul 2018 23:37:41 +0200 Subject: style fixes, exclude sway/desctop/xwayland.c when enable_xwayland: false --- sway/desktop/output.c | 10 +++++----- sway/desktop/render.c | 8 ++++---- sway/desktop/xwayland.c | 2 -- 3 files changed, 9 insertions(+), 11 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 7cca23bd..05daad7b 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -291,12 +291,12 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { if (workspace->current.ws_fullscreen) { send_frame_done_container_iterator( workspace->current.ws_fullscreen->swayc, &data); - #ifdef HAVE_XWAYLAND +#ifdef HAVE_XWAYLAND if (workspace->current.ws_fullscreen->type == SWAY_VIEW_XWAYLAND) { send_frame_done_unmanaged(&data, &root_container.sway_root->xwayland_unmanaged); } - #endif +#endif } else { send_frame_done_layer(&data, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]); @@ -305,11 +305,11 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { send_frame_done_container(&data, workspace); send_frame_done_container(&data, workspace->sway_workspace->floating); - - #ifdef HAVE_XWAYLAND + +#ifdef HAVE_XWAYLAND send_frame_done_unmanaged(&data, &root_container.sway_root->xwayland_unmanaged); - #endif +#endif send_frame_done_layer(&data, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); } diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 46bfec6b..2e6b6649 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -866,12 +866,12 @@ void output_render(struct sway_output *output, struct timespec *when, } else { render_view_surfaces(fullscreen_view, output, damage, 1.0f); } - #ifdef HAVE_XWAYLAND +#ifdef HAVE_XWAYLAND if (fullscreen_view->type == SWAY_VIEW_XWAYLAND) { render_unmanaged(output, damage, &root_container.sway_root->xwayland_unmanaged); } - #endif +#endif } else { float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f}; @@ -889,10 +889,10 @@ void output_render(struct sway_output *output, struct timespec *when, render_container(output, damage, workspace, workspace->current.focused); render_floating(output, damage); - #ifdef HAVE_XWAYLAND +#ifdef HAVE_XWAYLAND render_unmanaged(output, damage, &root_container.sway_root->xwayland_unmanaged); - #endif +#endif render_layer(output, damage, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); } diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index d940d47b..65d4fcd4 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c @@ -1,5 +1,4 @@ #define _POSIX_C_SOURCE 199309L -#ifdef HAVE_XWAYLAND #include #include #include @@ -592,4 +591,3 @@ void handle_xwayland_ready(struct wl_listener *listener, void *data) { xcb_disconnect(xcb_conn); } -#endif -- cgit v1.2.3 From 0e79b2114c0bd374c6b4a37fc2ee0e672b8fbb38 Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 25 Jul 2018 08:50:06 +0100 Subject: Improve rendering with a fullscreen opaque overlay surface The rendering code doesn't use the exclusive input surface at all anymore to decide to skip rendering of shell surfaces. This fixes a weird situation in which a client requests exclusive input but isn't an overlay layer surface. The renderer also renders all overlay surfaces in this situation, not just one. This simplifies the code and fixes rendering when there are more than one overlay surfaces (e.g. for a virtual keyboard to type the lockscreen password). --- sway/desktop/output.c | 26 ++++++++------------------ sway/desktop/render.c | 23 ++++++++--------------- 2 files changed, 16 insertions(+), 33 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index a206ac6b..cbd6ef86 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -181,21 +181,14 @@ struct sway_container *output_get_active_workspace(struct sway_output *output) { return workspace; } -bool output_has_opaque_lockscreen(struct sway_output *output, - struct sway_seat *seat) { - if (!seat->exclusive_client) { - return false; - } - +bool output_has_opaque_overlay_layer_surface(struct sway_output *output) { struct wlr_layer_surface *wlr_layer_surface; wl_list_for_each(wlr_layer_surface, &server.layer_shell->surfaces, link) { - if (wlr_layer_surface->output != output->wlr_output) { + if (wlr_layer_surface->output != output->wlr_output || + wlr_layer_surface->layer != ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY) { continue; } struct wlr_surface *wlr_surface = wlr_layer_surface->surface; - if (wlr_surface->resource->client != seat->exclusive_client) { - continue; - } struct sway_layer_surface *sway_layer_surface = layer_from_wlr_layer_surface(wlr_layer_surface); pixman_box32_t output_box = { @@ -221,16 +214,11 @@ struct send_frame_done_data { struct root_geometry root_geo; struct sway_output *output; struct timespec *when; - struct wl_client *exclusive_client; }; static void send_frame_done_iterator(struct wlr_surface *surface, int sx, int sy, void *_data) { struct send_frame_done_data *data = _data; - if (data->exclusive_client && - data->exclusive_client != surface->resource->client) { - return; - } bool intersects = output_get_surface_box(&data->root_geo, data->output, surface, sx, sy, NULL); @@ -279,14 +267,15 @@ static void send_frame_done_container(struct send_frame_done_data *data, } static void send_frame_done(struct sway_output *output, struct timespec *when) { - struct sway_seat *seat = input_manager_current_seat(input_manager); struct send_frame_done_data data = { .output = output, .when = when, - .exclusive_client = output_has_opaque_lockscreen(output, seat) ? - seat->exclusive_client : NULL, }; + if (output_has_opaque_overlay_layer_surface(output)) { + goto send_frame_overlay; + } + struct sway_container *workspace = output_get_active_workspace(output); if (workspace->current.ws_fullscreen) { send_frame_done_container_iterator( @@ -311,6 +300,7 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); } +send_frame_overlay: send_frame_done_layer(&data, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); send_frame_done_drag_icons(&data, &root_container.sway_root->drag_icons); diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 7da54594..d6c3fa8c 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -836,21 +836,12 @@ void output_render(struct sway_output *output, struct timespec *when, struct sway_container *workspace = output_get_active_workspace(output); struct sway_view *fullscreen_view = workspace->current.ws_fullscreen; - struct sway_seat *seat = input_manager_current_seat(input_manager); - - if (output_has_opaque_lockscreen(output, seat) && seat->focused_layer) { - struct wlr_layer_surface *wlr_layer_surface = seat->focused_layer; - struct sway_layer_surface *sway_layer_surface = - layer_from_wlr_layer_surface(seat->focused_layer); - struct render_data data = { - .output = output, - .damage = damage, - .alpha = 1.0f, - }; - output_surface_for_each_surface(wlr_layer_surface->surface, - sway_layer_surface->geo.x, sway_layer_surface->geo.y, - &data.root_geo, render_surface_iterator, &data); - } else if (fullscreen_view) { + + if (output_has_opaque_overlay_layer_surface(output)) { + goto render_overlay; + } + + if (fullscreen_view) { float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; int nrects; @@ -894,6 +885,8 @@ void output_render(struct sway_output *output, struct timespec *when, render_layer(output, damage, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); } + +render_overlay: render_layer(output, damage, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); render_drag_icons(output, damage, &root_container.sway_root->drag_icons); -- cgit v1.2.3 From f95cb9a7c17251c43b1d1058092e0a15d1fe8dd9 Mon Sep 17 00:00:00 2001 From: Pascal Pascher Date: Wed, 25 Jul 2018 13:32:20 +0200 Subject: reverted includes of "sway/config.h" and replaced with "config.h" from meson build --- sway/desktop/output.c | 1 + sway/desktop/render.c | 1 + 2 files changed, 2 insertions(+) (limited to 'sway/desktop') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 05daad7b..1512408e 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -14,6 +14,7 @@ #include #include #include "log.h" +#include "config.h" #include "sway/config.h" #include "sway/input/input-manager.h" #include "sway/input/seat.h" diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 2e6b6649..3e7bd94b 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -14,6 +14,7 @@ #include #include #include "log.h" +#include "config.h" #include "sway/config.h" #include "sway/debug.h" #include "sway/input/input-manager.h" -- cgit v1.2.3 From 27a20a488465468511de9b2307941ac1bc4db8bf Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Wed, 25 Jul 2018 20:56:23 +1000 Subject: Allow containers to be fullscreen --- sway/desktop/output.c | 14 ++++++++------ sway/desktop/render.c | 23 ++++++++++++++--------- sway/desktop/transaction.c | 2 +- sway/desktop/xdg_shell.c | 4 ++-- sway/desktop/xdg_shell_v6.c | 4 ++-- sway/desktop/xwayland.c | 4 ++-- 6 files changed, 29 insertions(+), 22 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 1764b4e3..cecd300a 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -279,13 +279,15 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { struct sway_container *workspace = output_get_active_workspace(output); if (workspace->current.ws_fullscreen) { - send_frame_done_container_iterator( - workspace->current.ws_fullscreen->swayc, &data); -#ifdef HAVE_XWAYLAND - if (workspace->current.ws_fullscreen->type == SWAY_VIEW_XWAYLAND) { - send_frame_done_unmanaged(&data, - &root_container.sway_root->xwayland_unmanaged); + if (workspace->current.ws_fullscreen->type == C_VIEW) { + send_frame_done_container_iterator( + workspace->current.ws_fullscreen, &data); + } else { + send_frame_done_container(&data, workspace->current.ws_fullscreen); } +#ifdef HAVE_XWAYLAND + send_frame_done_unmanaged(&data, + &root_container.sway_root->xwayland_unmanaged); #endif } else { send_frame_done_layer(&data, diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 15c5b94c..3e7b1a62 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -836,13 +836,13 @@ void output_render(struct sway_output *output, struct timespec *when, } struct sway_container *workspace = output_get_active_workspace(output); - struct sway_view *fullscreen_view = workspace->current.ws_fullscreen; + struct sway_container *fullscreen_con = workspace->current.ws_fullscreen; if (output_has_opaque_overlay_layer_surface(output)) { goto render_overlay; } - if (fullscreen_view) { + if (fullscreen_con) { float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; int nrects; @@ -853,16 +853,21 @@ void output_render(struct sway_output *output, struct timespec *when, } // TODO: handle views smaller than the output - if (fullscreen_view->swayc->instructions->length) { - render_saved_view(fullscreen_view, output, damage, 1.0f); + if (fullscreen_con->type == C_VIEW) { + if (fullscreen_con->instructions->length) { + render_saved_view(fullscreen_con->sway_view, + output, damage, 1.0f); } else { - render_view_surfaces(fullscreen_view, output, damage, 1.0f); + render_view_surfaces(fullscreen_con->sway_view, + output, damage, 1.0f); + } + } else { + render_container(output, damage, fullscreen_con, + fullscreen_con->current.focused); } #ifdef HAVE_XWAYLAND - if (fullscreen_view->type == SWAY_VIEW_XWAYLAND) { - render_unmanaged(output, damage, - &root_container.sway_root->xwayland_unmanaged); - } + render_unmanaged(output, damage, + &root_container.sway_root->xwayland_unmanaged); #endif } else { float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f}; diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 2a89880a..ee7a0704 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -110,6 +110,7 @@ static void copy_pending_state(struct sway_container *container, state->swayc_y = container->y; state->swayc_width = container->width; state->swayc_height = container->height; + state->is_fullscreen = container->is_fullscreen; state->has_gaps = container->has_gaps; state->current_gaps = container->current_gaps; state->gaps_inner = container->gaps_inner; @@ -122,7 +123,6 @@ static void copy_pending_state(struct sway_container *container, state->view_y = view->y; state->view_width = view->width; state->view_height = view->height; - state->is_fullscreen = view->is_fullscreen; state->border = view->border; state->border_thickness = view->border_thickness; state->border_top = view->border_top; diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index f3e4fef8..e6e1527e 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -267,7 +267,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) return; } - view_set_fullscreen(view, e->fullscreen); + container_set_fullscreen(view->swayc, e->fullscreen); struct sway_container *output = container_parent(view->swayc, C_OUTPUT); arrange_windows(output); @@ -338,7 +338,7 @@ static void handle_map(struct wl_listener *listener, void *data) { view_map(view, view->wlr_xdg_surface->surface); if (xdg_surface->toplevel->client_pending.fullscreen) { - view_set_fullscreen(view, true); + container_set_fullscreen(view->swayc, true); struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); arrange_windows(ws); } else { diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 46fd4769..5feee3e4 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -262,7 +262,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) return; } - view_set_fullscreen(view, e->fullscreen); + container_set_fullscreen(view->swayc, e->fullscreen); struct sway_container *output = container_parent(view->swayc, C_OUTPUT); arrange_windows(output); @@ -333,7 +333,7 @@ static void handle_map(struct wl_listener *listener, void *data) { view_map(view, view->wlr_xdg_surface_v6->surface); if (xdg_surface->toplevel->client_pending.fullscreen) { - view_set_fullscreen(view, true); + container_set_fullscreen(view->swayc, true); struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); arrange_windows(ws); } else { diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 65d4fcd4..390ca580 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c @@ -357,7 +357,7 @@ static void handle_map(struct wl_listener *listener, void *data) { view_map(view, xsurface->surface); if (xsurface->fullscreen) { - view_set_fullscreen(view, true); + container_set_fullscreen(view->swayc, true); struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); arrange_windows(ws); } else { @@ -395,7 +395,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) if (!xsurface->mapped) { return; } - view_set_fullscreen(view, xsurface->fullscreen); + container_set_fullscreen(view->swayc, xsurface->fullscreen); struct sway_container *output = container_parent(view->swayc, C_OUTPUT); arrange_windows(output); -- cgit v1.2.3 From 868dcde14ef2116fcbd5c2c66badf2bcc514bba3 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Thu, 26 Jul 2018 08:28:05 +1000 Subject: Fix indent --- sway/desktop/render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sway/desktop') diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 3e7b1a62..d2f1c9f2 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -857,7 +857,7 @@ void output_render(struct sway_output *output, struct timespec *when, if (fullscreen_con->instructions->length) { render_saved_view(fullscreen_con->sway_view, output, damage, 1.0f); - } else { + } else { render_view_surfaces(fullscreen_con->sway_view, output, damage, 1.0f); } -- cgit v1.2.3 From 073ac425d5bf6f6393eb91d9b5f84e3caa68f511 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 28 Jul 2018 15:19:14 +1000 Subject: Fix use after free in transactions In set_instructions_ready, calling set_instruction_ready may cause any number of transactions to get applied, which removes them from the list being iterated. The iteration variables need to be adjusted accordingly. --- sway/desktop/transaction.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sway/desktop') diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index ee7a0704..0a24c4fc 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -364,7 +364,13 @@ static void set_instructions_ready(struct sway_view *view, int index) { struct sway_transaction_instruction *instruction = view->swayc->instructions->items[i]; if (!instruction->ready) { + // set_instruction_ready can remove instructions from the list we're + // iterating + size_t length = view->swayc->instructions->length; set_instruction_ready(instruction); + size_t num_removed = length - view->swayc->instructions->length; + i -= num_removed; + index -= num_removed; } } } -- cgit v1.2.3 From 52cf410d3cfcf0cae81b47c90097867c4e4d8564 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 28 Jul 2018 17:43:18 +1000 Subject: Second attempt at fixing transaction use-after-free The solution used in 073ac425d5bf6f6393eb91d9b5f84e3caa68f511 doesn't work in all cases because the freed instruction might be ahead in the list, not necessarily behind. The new solution delays running the queue until after the loop has finished iterating, thus avoiding the problem completely. --- sway/desktop/transaction.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 0a24c4fc..ccda1963 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -344,13 +344,11 @@ static void set_instruction_ready( } - // If all views are ready, apply the transaction. // If the transaction has timed out then its num_waiting will be 0 already. if (transaction->num_waiting > 0 && --transaction->num_waiting == 0) { if (!txn_debug) { wlr_log(WLR_DEBUG, "Transaction %p is ready", transaction); wl_event_source_timer_update(transaction->timer, 0); - transaction_progress_queue(); } } } @@ -364,15 +362,10 @@ static void set_instructions_ready(struct sway_view *view, int index) { struct sway_transaction_instruction *instruction = view->swayc->instructions->items[i]; if (!instruction->ready) { - // set_instruction_ready can remove instructions from the list we're - // iterating - size_t length = view->swayc->instructions->length; set_instruction_ready(instruction); - size_t num_removed = length - view->swayc->instructions->length; - i -= num_removed; - index -= num_removed; } } + transaction_progress_queue(); } void transaction_notify_view_ready(struct sway_view *view, uint32_t serial) { -- cgit v1.2.3 From 32663b7b013e9c0fd37c1c86d6c26bc3156e1c3a Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 28 Jul 2018 09:22:37 +1000 Subject: Handle out-of-fd situations gracefully for transaction and urgent timers --- sway/desktop/transaction.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'sway/desktop') diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index ccda1963..a9c9cb58 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -316,7 +316,14 @@ static void transaction_commit(struct sway_transaction *transaction) { // Set up a timer which the views must respond within transaction->timer = wl_event_loop_add_timer(server.wl_event_loop, handle_timeout, transaction); - wl_event_source_timer_update(transaction->timer, txn_timeout_ms); + if (transaction->timer) { + wl_event_source_timer_update(transaction->timer, txn_timeout_ms); + } else { + wlr_log(WLR_ERROR, "Unable to create transaction timer. " + "There might not be any available file descriptors. " + "Some imperfect frames might be rendered."); + handle_timeout(transaction); + } } // The debug tree shows the pending/live tree. Here is a good place to -- cgit v1.2.3 From d6daf10cad540f7581e9a325a041333d1113cae5 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 28 Jul 2018 10:00:04 +1000 Subject: Show errno description in log --- sway/desktop/transaction.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index a9c9cb58..17e3f467 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -319,9 +319,9 @@ static void transaction_commit(struct sway_transaction *transaction) { if (transaction->timer) { wl_event_source_timer_update(transaction->timer, txn_timeout_ms); } else { - wlr_log(WLR_ERROR, "Unable to create transaction timer. " - "There might not be any available file descriptors. " - "Some imperfect frames might be rendered."); + wlr_log(WLR_ERROR, "Unable to create transaction timer (%s). " + "Some imperfect frames might be rendered.", + strerror(errno)); handle_timeout(transaction); } } -- cgit v1.2.3 From a4bcddcfdc67ef64edf3737342a99c4e41cae6d4 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 28 Jul 2018 10:24:04 +1000 Subject: Include errno.h --- sway/desktop/transaction.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sway/desktop') diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 17e3f467..7975366e 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -1,4 +1,5 @@ #define _POSIX_C_SOURCE 200809L +#include #include #include #include -- cgit v1.2.3 From 08cfba2192f5770d975c5fe70789a81aaee4dc7e Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Thu, 26 Jul 2018 18:36:46 +1000 Subject: Allow containers to float Things worth noting: * When a fullscreen view unmaps, the check to unset fullscreen on the workspace has been moved out of view_unmap and into container_destroy, because containers can be fullscreen too * The calls to `container_reap_empty_recursive(workspace)` have been removed from `container_set_floating`. That function reaps upwards so it wouldn't do anything. I'm probably the one who originally added it... * My fix (b14bd1b0b1536039e4f46fe94515c7c44e7afc61) for the tabbed child crash has a side effect where when you close a floating container, focus is not given to the tiled container again. I've removed my fix and removed the call to `send_cursor_motion` from `seat_set_focus_warp`. We should consider calling it from somewhere earlier in the call stack. --- sway/desktop/render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sway/desktop') diff --git a/sway/desktop/render.c b/sway/desktop/render.c index d2f1c9f2..c9fdfd95 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -779,7 +779,7 @@ static void render_floating_container(struct sway_output *soutput, } render_view(soutput, damage, con, colors); } else { - render_container(soutput, damage, con, false); + render_container(soutput, damage, con, con->current.focused); } } -- cgit v1.2.3 From d2172bd331937ab406175a6b4c5a76db6f406fbe Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 27 Jul 2018 18:17:47 +0100 Subject: wip: redesign output_unmanaged_for_each_surface iterator --- sway/desktop/output.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++----- sway/desktop/render.c | 31 ++++++++++++++++++++-- 2 files changed, 96 insertions(+), 8 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index cecd300a..9c2a1a07 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -105,6 +105,56 @@ void output_surface_for_each_surface(struct wlr_surface *surface, wlr_surface_for_each_surface(surface, iterator, user_data); } +struct surface_iterator_data { + sway_surface_iterator_func_t user_iterator; + void *user_data; + + struct sway_output *output; + double ox, oy; + int width, height; + float rotation; +}; + +void output_surface_for_each_surface2_iterator(struct wlr_surface *surface, + int sx, int sy, void *_data) { + struct surface_iterator_data *data = _data; + + struct root_geometry geo = { + .x = data->ox, + .y = data->oy, + .width = data->width, + .height = data->height, + .rotation = data->rotation, + }; + struct wlr_box box; + bool intersects = output_get_surface_box(&geo, data->output, + surface, sx, sy, &box); + if (!intersects) { + return; + } + + data->user_iterator(data->output, surface, &box, data->rotation, + data->user_data); +} + +void output_surface_for_each_surface2(struct sway_output *output, + struct wlr_surface *surface, double ox, double oy, float rotation, + sway_surface_iterator_func_t iterator, void *user_data) { + struct surface_iterator_data data = { + .user_iterator = iterator, + .user_data = user_data, + .output = output, + .ox = ox, + .oy = oy, + .width = surface->current.width, + .height = surface->current.height, + .rotation = rotation, + }; + + wlr_surface_for_each_surface(surface, + output_surface_for_each_surface2_iterator, &data); +} + void output_view_for_each_surface(struct sway_view *view, struct sway_output *output, struct root_geometry *geo, wlr_surface_iterator_func_t iterator, void *user_data) { @@ -129,10 +179,11 @@ void output_layer_for_each_surface(struct wl_list *layer_surfaces, user_data); } } + #ifdef HAVE_XWAYLAND -void output_unmanaged_for_each_surface(struct wl_list *unmanaged, - struct sway_output *output, struct root_geometry *geo, - wlr_surface_iterator_func_t iterator, void *user_data) { +void output_unmanaged_for_each_surface(struct sway_output *output, + struct wl_list *unmanaged, sway_surface_iterator_func_t iterator, + void *user_data) { struct sway_xwayland_unmanaged *unmanaged_surface; wl_list_for_each(unmanaged_surface, unmanaged, link) { struct wlr_xwayland_surface *xsurface = @@ -140,11 +191,12 @@ void output_unmanaged_for_each_surface(struct wl_list *unmanaged, double ox = unmanaged_surface->lx - output->swayc->current.swayc_x; double oy = unmanaged_surface->ly - output->swayc->current.swayc_y; - output_surface_for_each_surface(xsurface->surface, ox, oy, geo, + output_surface_for_each_surface2(output, xsurface->surface, ox, oy, 0, iterator, user_data); } } #endif + void output_drag_icons_for_each_surface(struct wl_list *drag_icons, struct sway_output *output, struct root_geometry *geo, wlr_surface_iterator_func_t iterator, void *user_data) { @@ -228,18 +280,27 @@ static void send_frame_done_iterator(struct wlr_surface *surface, } } +static void send_frame_done_iterator2(struct sway_output *output, + struct wlr_surface *surface, struct wlr_box *box, float rotation, + void *_data) { + struct send_frame_done_data *data = _data; + wlr_surface_send_frame_done(surface, data->when); +} + static void send_frame_done_layer(struct send_frame_done_data *data, struct wl_list *layer_surfaces) { output_layer_for_each_surface(layer_surfaces, &data->root_geo, send_frame_done_iterator, data); } + #ifdef HAVE_XWAYLAND static void send_frame_done_unmanaged(struct send_frame_done_data *data, struct wl_list *unmanaged) { - output_unmanaged_for_each_surface(unmanaged, data->output, &data->root_geo, - send_frame_done_iterator, data); + output_unmanaged_for_each_surface(data->output, unmanaged, + send_frame_done_iterator2, data); } #endif + static void send_frame_done_drag_icons(struct send_frame_done_data *data, struct wl_list *drag_icons) { output_drag_icons_for_each_surface(drag_icons, data->output, &data->root_geo, diff --git a/sway/desktop/render.c b/sway/desktop/render.c index c9fdfd95..8eea19e0 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -123,6 +123,31 @@ static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy, render_texture(wlr_output, output_damage, texture, &box, matrix, alpha); } +static void render_surface_iterator2(struct sway_output *output, + struct wlr_surface *surface, struct wlr_box *_box, float rotation, + void *_data) { + struct render_data *data = _data; + struct wlr_output *wlr_output = output->wlr_output; + pixman_region32_t *output_damage = data->damage; + float alpha = data->alpha; + + struct wlr_texture *texture = wlr_surface_get_texture(surface); + if (!texture) { + return; + } + + struct wlr_box box = *_box; + scale_box(&box, wlr_output->scale); + + float matrix[9]; + enum wl_output_transform transform = + wlr_output_transform_invert(surface->current.transform); + wlr_matrix_project_box(matrix, &box, transform, rotation, + wlr_output->transform_matrix); + + render_texture(wlr_output, output_damage, texture, &box, matrix, alpha); +} + static void render_layer(struct sway_output *output, pixman_region32_t *damage, struct wl_list *layer_surfaces) { struct render_data data = { @@ -133,6 +158,7 @@ static void render_layer(struct sway_output *output, output_layer_for_each_surface(layer_surfaces, &data.root_geo, render_surface_iterator, &data); } + #ifdef HAVE_XWAYLAND static void render_unmanaged(struct sway_output *output, pixman_region32_t *damage, struct wl_list *unmanaged) { @@ -141,10 +167,11 @@ static void render_unmanaged(struct sway_output *output, .damage = damage, .alpha = 1.0f, }; - output_unmanaged_for_each_surface(unmanaged, output, &data.root_geo, - render_surface_iterator, &data); + output_unmanaged_for_each_surface(output, unmanaged, + render_surface_iterator2, &data); } #endif + static void render_drag_icons(struct sway_output *output, pixman_region32_t *damage, struct wl_list *drag_icons) { struct render_data data = { -- cgit v1.2.3 From dbf6dd0daec9e712a002c3e01accbd0fee769fac Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 27 Jul 2018 18:44:36 +0100 Subject: wip: redesign output_drag_icons_for_each_surface iterator --- sway/desktop/output.c | 15 ++++++++------- sway/desktop/render.c | 4 ++-- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 9c2a1a07..e83a9a3d 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -197,17 +197,18 @@ void output_unmanaged_for_each_surface(struct sway_output *output, } #endif -void output_drag_icons_for_each_surface(struct wl_list *drag_icons, - struct sway_output *output, struct root_geometry *geo, - wlr_surface_iterator_func_t iterator, void *user_data) { +void output_drag_icons_for_each_surface(struct sway_output *output, + struct wl_list *drag_icons, sway_surface_iterator_func_t iterator, + void *user_data) { struct sway_drag_icon *drag_icon; wl_list_for_each(drag_icon, drag_icons, link) { double ox = drag_icon->x - output->swayc->x; double oy = drag_icon->y - output->swayc->y; if (drag_icon->wlr_drag_icon->mapped) { - output_surface_for_each_surface(drag_icon->wlr_drag_icon->surface, - ox, oy, geo, iterator, user_data); + output_surface_for_each_surface2(output, + drag_icon->wlr_drag_icon->surface, ox, oy, 0, + iterator, user_data); } } } @@ -303,8 +304,8 @@ static void send_frame_done_unmanaged(struct send_frame_done_data *data, static void send_frame_done_drag_icons(struct send_frame_done_data *data, struct wl_list *drag_icons) { - output_drag_icons_for_each_surface(drag_icons, data->output, &data->root_geo, - send_frame_done_iterator, data); + output_drag_icons_for_each_surface(data->output, drag_icons, + send_frame_done_iterator2, data); } static void send_frame_done_container_iterator(struct sway_container *con, diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 8eea19e0..1270b7cf 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -179,8 +179,8 @@ static void render_drag_icons(struct sway_output *output, .damage = damage, .alpha = 1.0f, }; - output_drag_icons_for_each_surface(drag_icons, output, &data.root_geo, - render_surface_iterator, &data); + output_drag_icons_for_each_surface(output, drag_icons, + render_surface_iterator2, &data); } static void render_rect(struct wlr_output *wlr_output, -- cgit v1.2.3 From a0dd9776172796f65b0fce0a8e5cfb66bdb2e2e5 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 27 Jul 2018 18:53:15 +0100 Subject: wip: redesign output_layer_for_each_surface iterator --- sway/desktop/output.c | 32 ++++++++++++++++---------------- sway/desktop/render.c | 4 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index e83a9a3d..5e309250 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -167,15 +167,15 @@ void output_view_for_each_surface(struct sway_view *view, view_for_each_surface(view, iterator, user_data); } -void output_layer_for_each_surface(struct wl_list *layer_surfaces, - struct root_geometry *geo, wlr_surface_iterator_func_t iterator, +void output_layer_for_each_surface(struct sway_output *output, + struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator, void *user_data) { struct sway_layer_surface *layer_surface; wl_list_for_each(layer_surface, layer_surfaces, link) { struct wlr_layer_surface *wlr_layer_surface = layer_surface->layer_surface; - output_surface_for_each_surface(wlr_layer_surface->surface, - layer_surface->geo.x, layer_surface->geo.y, geo, iterator, + output_surface_for_each_surface2(output, wlr_layer_surface->surface, + layer_surface->geo.x, layer_surface->geo.y, 0, iterator, user_data); } } @@ -288,10 +288,10 @@ static void send_frame_done_iterator2(struct sway_output *output, wlr_surface_send_frame_done(surface, data->when); } -static void send_frame_done_layer(struct send_frame_done_data *data, - struct wl_list *layer_surfaces) { - output_layer_for_each_surface(layer_surfaces, &data->root_geo, - send_frame_done_iterator, data); +static void send_frame_done_layer(struct sway_output *output, + struct wl_list *layer_surfaces, struct send_frame_done_data *data) { + output_layer_for_each_surface(output, layer_surfaces, + send_frame_done_iterator2, data); } #ifdef HAVE_XWAYLAND @@ -352,10 +352,10 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { &root_container.sway_root->xwayland_unmanaged); #endif } else { - send_frame_done_layer(&data, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]); - send_frame_done_layer(&data, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); + send_frame_done_layer(output, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &data); + send_frame_done_layer(output, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &data); send_frame_done_container(&data, workspace); send_frame_done_container(&data, workspace->sway_workspace->floating); @@ -364,13 +364,13 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { send_frame_done_unmanaged(&data, &root_container.sway_root->xwayland_unmanaged); #endif - send_frame_done_layer(&data, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); + send_frame_done_layer(output, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &data); } send_frame_overlay: - send_frame_done_layer(&data, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); + send_frame_done_layer(output, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &data); send_frame_done_drag_icons(&data, &root_container.sway_root->drag_icons); } diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 1270b7cf..35dc3edc 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -155,8 +155,8 @@ static void render_layer(struct sway_output *output, .damage = damage, .alpha = 1.0f, }; - output_layer_for_each_surface(layer_surfaces, &data.root_geo, - render_surface_iterator, &data); + output_layer_for_each_surface(output, layer_surfaces, + render_surface_iterator2, &data); } #ifdef HAVE_XWAYLAND -- cgit v1.2.3 From e9d674cfd294f13a32893dd584826ed7481e05e3 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 27 Jul 2018 18:59:14 +0100 Subject: wip: redesign output_view_for_each_surface iterator --- sway/desktop/output.c | 75 ++++++++++++++++++++++++++++++++++++++++++--------- sway/desktop/render.c | 3 +-- 2 files changed, 63 insertions(+), 15 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 5e309250..31033ee3 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -155,16 +155,22 @@ void output_surface_for_each_surface2(struct sway_output *output, output_surface_for_each_surface2_iterator, &data); } -void output_view_for_each_surface(struct sway_view *view, - struct sway_output *output, struct root_geometry *geo, - wlr_surface_iterator_func_t iterator, void *user_data) { - geo->x = view->swayc->current.view_x - output->swayc->current.swayc_x; - geo->y = view->swayc->current.view_y - output->swayc->current.swayc_y; - geo->width = view->swayc->current.view_width; - geo->height = view->swayc->current.view_height; - geo->rotation = 0; // TODO +void output_view_for_each_surface(struct sway_output *output, + struct sway_view *view, sway_surface_iterator_func_t iterator, + void *user_data) { + struct surface_iterator_data data = { + .user_iterator = iterator, + .user_data = user_data, + .output = output, + .ox = view->swayc->current.view_x - output->swayc->current.swayc_x, + .oy = view->swayc->current.view_y - output->swayc->current.swayc_y, + .width = view->swayc->current.view_width, + .height = view->swayc->current.view_height, + .rotation = 0, // TODO + }; - view_for_each_surface(view, iterator, user_data); + view_for_each_surface(view, + output_surface_for_each_surface2_iterator, &data); } void output_layer_for_each_surface(struct sway_output *output, @@ -319,8 +325,8 @@ static void send_frame_done_container_iterator(struct sway_container *con, return; } - output_view_for_each_surface(con->sway_view, data->output, &data->root_geo, - send_frame_done_iterator, data); + output_view_for_each_surface(data->output, con->sway_view, + send_frame_done_iterator2, data); } static void send_frame_done_container(struct send_frame_done_data *data, @@ -463,6 +469,50 @@ static void damage_surface_iterator(struct wlr_surface *surface, int sx, int sy, wlr_output_schedule_frame(output->wlr_output); } +static void damage_surface_iterator2(struct sway_output *output, + struct wlr_surface *surface, struct wlr_box *_box, float rotation, + void *_data) { + struct damage_data *data = _data; + bool whole = data->whole; + + struct wlr_box box = *_box; + scale_box(&box, output->wlr_output->scale); + + int center_x = box.x + box.width/2; + int center_y = box.y + box.height/2; + + if (pixman_region32_not_empty(&surface->buffer_damage)) { + enum wl_output_transform transform = + wlr_output_transform_invert(surface->current.transform); + + pixman_region32_t damage; + pixman_region32_init(&damage); + pixman_region32_copy(&damage, &surface->buffer_damage); + wlr_region_transform(&damage, &damage, transform, + surface->current.buffer_width, surface->current.buffer_height); + wlr_region_scale(&damage, &damage, + output->wlr_output->scale / (float)surface->current.scale); + if (ceil(output->wlr_output->scale) > surface->current.scale) { + // When scaling up a surface, it'll become blurry so we need to + // expand the damage region + wlr_region_expand(&damage, &damage, + ceil(output->wlr_output->scale) - surface->current.scale); + } + pixman_region32_translate(&damage, box.x, box.y); + wlr_region_rotated_bounds(&damage, &damage, rotation, + center_x, center_y); + wlr_output_damage_add(output->damage, &damage); + pixman_region32_fini(&damage); + } + + if (whole) { + wlr_box_rotated_bounds(&box, rotation, &box); + wlr_output_damage_add_box(output->damage, &box); + } + + wlr_output_schedule_frame(output->wlr_output); +} + void output_damage_surface(struct sway_output *output, double ox, double oy, struct wlr_surface *surface, bool whole) { struct damage_data data = { @@ -489,8 +539,7 @@ static void output_damage_view(struct sway_output *output, .whole = whole, }; - output_view_for_each_surface(view, output, &data.root_geo, - damage_surface_iterator, &data); + output_view_for_each_surface(output, view, damage_surface_iterator2, &data); } void output_damage_from_view(struct sway_output *output, diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 35dc3edc..18d076df 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -231,8 +231,7 @@ static void render_view_surfaces(struct sway_view *view, .view = view, .alpha = alpha, }; - output_view_for_each_surface(view, output, &data.root_geo, - render_surface_iterator, &data); + output_view_for_each_surface(output, view, render_surface_iterator2, &data); } static void render_saved_view(struct sway_view *view, -- cgit v1.2.3 From 8d5cc8625ce04c657eab6bd5f242a02e97ddd647 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 27 Jul 2018 19:16:36 +0100 Subject: Completely switch over to new iterators --- sway/desktop/output.c | 243 +++++++++++++++----------------------------------- sway/desktop/render.c | 49 ++-------- 2 files changed, 79 insertions(+), 213 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 31033ee3..e1d85b10 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -57,9 +57,21 @@ static void rotate_child_position(double *sx, double *sy, double sw, double sh, *sy = ry + ph/2 - sh/2; } -bool output_get_surface_box(struct root_geometry *geo, - struct sway_output *output, struct wlr_surface *surface, int sx, int sy, +struct surface_iterator_data { + sway_surface_iterator_func_t user_iterator; + void *user_data; + + struct sway_output *output; + double ox, oy; + int width, height; + float rotation; +}; + +static bool get_surface_box(struct surface_iterator_data *data, + struct wlr_surface *surface, int sx, int sy, struct wlr_box *surface_box) { + struct sway_output *output = data->output; + if (!wlr_surface_has_buffer(surface)) { return false; } @@ -68,12 +80,12 @@ bool output_get_surface_box(struct root_geometry *geo, int sh = surface->current.height; double _sx = sx, _sy = sy; - rotate_child_position(&_sx, &_sy, sw, sh, geo->width, geo->height, - geo->rotation); + rotate_child_position(&_sx, &_sy, sw, sh, data->width, data->height, + data->rotation); struct wlr_box box = { - .x = geo->x + _sx, - .y = geo->y + _sy, + .x = data->ox + _sx, + .y = data->oy + _sy, .width = sw, .height = sh, }; @@ -82,7 +94,7 @@ bool output_get_surface_box(struct root_geometry *geo, } struct wlr_box rotated_box; - wlr_box_rotated_bounds(&box, geo->rotation, &rotated_box); + wlr_box_rotated_bounds(&box, data->rotation, &rotated_box); struct wlr_box output_box = { .width = output->swayc->current.swayc_width, @@ -93,42 +105,12 @@ bool output_get_surface_box(struct root_geometry *geo, return wlr_box_intersection(&output_box, &rotated_box, &intersection); } -void output_surface_for_each_surface(struct wlr_surface *surface, - double ox, double oy, struct root_geometry *geo, - wlr_surface_iterator_func_t iterator, void *user_data) { - geo->x = ox; - geo->y = oy; - geo->width = surface->current.width; - geo->height = surface->current.height; - geo->rotation = 0; - - wlr_surface_for_each_surface(surface, iterator, user_data); -} - -struct surface_iterator_data { - sway_surface_iterator_func_t user_iterator; - void *user_data; - - struct sway_output *output; - double ox, oy; - int width, height; - float rotation; -}; - -void output_surface_for_each_surface2_iterator(struct wlr_surface *surface, +void output_surface_for_each_surface_iterator(struct wlr_surface *surface, int sx, int sy, void *_data) { struct surface_iterator_data *data = _data; - struct root_geometry geo = { - .x = data->ox, - .y = data->oy, - .width = data->width, - .height = data->height, - .rotation = data->rotation, - }; struct wlr_box box; - bool intersects = output_get_surface_box(&geo, data->output, - surface, sx, sy, &box); + bool intersects = get_surface_box(data, surface, sx, sy, &box); if (!intersects) { return; } @@ -137,7 +119,7 @@ void output_surface_for_each_surface2_iterator(struct wlr_surface *surface, data->user_data); } -void output_surface_for_each_surface2(struct sway_output *output, +void output_surface_for_each_surface(struct sway_output *output, struct wlr_surface *surface, double ox, double oy, float rotation, sway_surface_iterator_func_t iterator, void *user_data) { struct surface_iterator_data data = { @@ -152,7 +134,7 @@ void output_surface_for_each_surface2(struct sway_output *output, }; wlr_surface_for_each_surface(surface, - output_surface_for_each_surface2_iterator, &data); + output_surface_for_each_surface_iterator, &data); } void output_view_for_each_surface(struct sway_output *output, @@ -170,7 +152,7 @@ void output_view_for_each_surface(struct sway_output *output, }; view_for_each_surface(view, - output_surface_for_each_surface2_iterator, &data); + output_surface_for_each_surface_iterator, &data); } void output_layer_for_each_surface(struct sway_output *output, @@ -180,7 +162,7 @@ void output_layer_for_each_surface(struct sway_output *output, wl_list_for_each(layer_surface, layer_surfaces, link) { struct wlr_layer_surface *wlr_layer_surface = layer_surface->layer_surface; - output_surface_for_each_surface2(output, wlr_layer_surface->surface, + output_surface_for_each_surface(output, wlr_layer_surface->surface, layer_surface->geo.x, layer_surface->geo.y, 0, iterator, user_data); } @@ -197,7 +179,7 @@ void output_unmanaged_for_each_surface(struct sway_output *output, double ox = unmanaged_surface->lx - output->swayc->current.swayc_x; double oy = unmanaged_surface->ly - output->swayc->current.swayc_y; - output_surface_for_each_surface2(output, xsurface->surface, ox, oy, 0, + output_surface_for_each_surface(output, xsurface->surface, ox, oy, 0, iterator, user_data); } } @@ -212,7 +194,7 @@ void output_drag_icons_for_each_surface(struct sway_output *output, double oy = drag_icon->y - output->swayc->y; if (drag_icon->wlr_drag_icon->mapped) { - output_surface_for_each_surface2(output, + output_surface_for_each_surface(output, drag_icon->wlr_drag_icon->surface, ox, oy, 0, iterator, user_data); } @@ -270,50 +252,38 @@ bool output_has_opaque_overlay_layer_surface(struct sway_output *output) { return false; } -struct send_frame_done_data { - struct root_geometry root_geo; - struct sway_output *output; - struct timespec *when; -}; - -static void send_frame_done_iterator(struct wlr_surface *surface, - int sx, int sy, void *_data) { - struct send_frame_done_data *data = _data; - - bool intersects = output_get_surface_box(&data->root_geo, data->output, surface, - sx, sy, NULL); - if (intersects) { - wlr_surface_send_frame_done(surface, data->when); - } -} - -static void send_frame_done_iterator2(struct sway_output *output, +static void send_frame_done_iterator(struct sway_output *output, struct wlr_surface *surface, struct wlr_box *box, float rotation, void *_data) { - struct send_frame_done_data *data = _data; - wlr_surface_send_frame_done(surface, data->when); + struct timespec *when = _data; + wlr_surface_send_frame_done(surface, when); } static void send_frame_done_layer(struct sway_output *output, - struct wl_list *layer_surfaces, struct send_frame_done_data *data) { + struct wl_list *layer_surfaces, struct timespec *when) { output_layer_for_each_surface(output, layer_surfaces, - send_frame_done_iterator2, data); + send_frame_done_iterator, when); } #ifdef HAVE_XWAYLAND -static void send_frame_done_unmanaged(struct send_frame_done_data *data, - struct wl_list *unmanaged) { - output_unmanaged_for_each_surface(data->output, unmanaged, - send_frame_done_iterator2, data); +static void send_frame_done_unmanaged(struct sway_output *output, + struct wl_list *unmanaged, struct timespec *when) { + output_unmanaged_for_each_surface(output, unmanaged, + send_frame_done_iterator, when); } #endif -static void send_frame_done_drag_icons(struct send_frame_done_data *data, - struct wl_list *drag_icons) { - output_drag_icons_for_each_surface(data->output, drag_icons, - send_frame_done_iterator2, data); +static void send_frame_done_drag_icons(struct sway_output *output, + struct wl_list *drag_icons, struct timespec *when) { + output_drag_icons_for_each_surface(output, drag_icons, + send_frame_done_iterator, when); } +struct send_frame_done_data { + struct sway_output *output; + struct timespec *when; +}; + static void send_frame_done_container_iterator(struct sway_container *con, void *_data) { struct send_frame_done_data *data = _data; @@ -326,21 +296,20 @@ static void send_frame_done_container_iterator(struct sway_container *con, } output_view_for_each_surface(data->output, con->sway_view, - send_frame_done_iterator2, data); -} - -static void send_frame_done_container(struct send_frame_done_data *data, - struct sway_container *con) { - container_descendants(con, C_VIEW, - send_frame_done_container_iterator, data); + send_frame_done_iterator, data->when); } -static void send_frame_done(struct sway_output *output, struct timespec *when) { +static void send_frame_done_container(struct sway_output *output, + struct sway_container *con, struct timespec *when) { struct send_frame_done_data data = { .output = output, .when = when, }; + container_descendants(con, C_VIEW, + send_frame_done_container_iterator, &data); +} +static void send_frame_done(struct sway_output *output, struct timespec *when) { if (output_has_opaque_overlay_layer_surface(output)) { goto send_frame_overlay; } @@ -349,35 +318,38 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { if (workspace->current.ws_fullscreen) { if (workspace->current.ws_fullscreen->type == C_VIEW) { send_frame_done_container_iterator( - workspace->current.ws_fullscreen, &data); + workspace->current.ws_fullscreen, when); } else { - send_frame_done_container(&data, workspace->current.ws_fullscreen); + send_frame_done_container(output, workspace->current.ws_fullscreen, + when); } #ifdef HAVE_XWAYLAND - send_frame_done_unmanaged(&data, - &root_container.sway_root->xwayland_unmanaged); + send_frame_done_unmanaged(output, + &root_container.sway_root->xwayland_unmanaged, when); #endif } else { send_frame_done_layer(output, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &data); + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], when); send_frame_done_layer(output, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &data); + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], when); - send_frame_done_container(&data, workspace); - send_frame_done_container(&data, workspace->sway_workspace->floating); + send_frame_done_container(output, workspace, when); + send_frame_done_container(output, workspace->sway_workspace->floating, + when); #ifdef HAVE_XWAYLAND - send_frame_done_unmanaged(&data, - &root_container.sway_root->xwayland_unmanaged); + send_frame_done_unmanaged(output, + &root_container.sway_root->xwayland_unmanaged, when); #endif send_frame_done_layer(output, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &data); + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], when); } send_frame_overlay: send_frame_done_layer(output, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &data); - send_frame_done_drag_icons(&data, &root_container.sway_root->drag_icons); + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], when); + send_frame_done_drag_icons(output, &root_container.sway_root->drag_icons, + when); } static void damage_handle_frame(struct wl_listener *listener, void *data) { @@ -412,68 +384,11 @@ void output_damage_whole(struct sway_output *output) { wlr_output_damage_add_whole(output->damage); } -struct damage_data { - struct root_geometry root_geo; - struct sway_output *output; - bool whole; -}; - -static void damage_surface_iterator(struct wlr_surface *surface, int sx, int sy, - void *_data) { - struct damage_data *data = _data; - struct sway_output *output = data->output; - float rotation = data->root_geo.rotation; - bool whole = data->whole; - - struct wlr_box box; - bool intersects = output_get_surface_box(&data->root_geo, data->output, surface, - sx, sy, &box); - if (!intersects) { - return; - } - - scale_box(&box, output->wlr_output->scale); - - int center_x = box.x + box.width/2; - int center_y = box.y + box.height/2; - - if (pixman_region32_not_empty(&surface->buffer_damage)) { - enum wl_output_transform transform = - wlr_output_transform_invert(surface->current.transform); - - pixman_region32_t damage; - pixman_region32_init(&damage); - pixman_region32_copy(&damage, &surface->buffer_damage); - wlr_region_transform(&damage, &damage, transform, - surface->current.buffer_width, surface->current.buffer_height); - wlr_region_scale(&damage, &damage, - output->wlr_output->scale / (float)surface->current.scale); - if (ceil(output->wlr_output->scale) > surface->current.scale) { - // When scaling up a surface, it'll become blurry so we need to - // expand the damage region - wlr_region_expand(&damage, &damage, - ceil(output->wlr_output->scale) - surface->current.scale); - } - pixman_region32_translate(&damage, box.x, box.y); - wlr_region_rotated_bounds(&damage, &damage, rotation, - center_x, center_y); - wlr_output_damage_add(output->damage, &damage); - pixman_region32_fini(&damage); - } - - if (whole) { - wlr_box_rotated_bounds(&box, rotation, &box); - wlr_output_damage_add_box(output->damage, &box); - } - - wlr_output_schedule_frame(output->wlr_output); -} - -static void damage_surface_iterator2(struct sway_output *output, +static void damage_surface_iterator(struct sway_output *output, struct wlr_surface *surface, struct wlr_box *_box, float rotation, void *_data) { - struct damage_data *data = _data; - bool whole = data->whole; + bool *data = _data; + bool whole = *data; struct wlr_box box = *_box; scale_box(&box, output->wlr_output->scale); @@ -515,13 +430,8 @@ static void damage_surface_iterator2(struct sway_output *output, void output_damage_surface(struct sway_output *output, double ox, double oy, struct wlr_surface *surface, bool whole) { - struct damage_data data = { - .output = output, - .whole = whole, - }; - - output_surface_for_each_surface(surface, ox, oy, &data.root_geo, - damage_surface_iterator, &data); + output_surface_for_each_surface(output, surface, ox, oy, 0, + damage_surface_iterator, &whole); } static void output_damage_view(struct sway_output *output, @@ -534,12 +444,7 @@ static void output_damage_view(struct sway_output *output, return; } - struct damage_data data = { - .output = output, - .whole = whole, - }; - - output_view_for_each_surface(output, view, damage_surface_iterator2, &data); + output_view_for_each_surface(output, view, damage_surface_iterator, &whole); } void output_damage_from_view(struct sway_output *output, diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 18d076df..f25055b8 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -29,10 +29,7 @@ #include "sway/tree/workspace.h" struct render_data { - struct root_geometry root_geo; - struct sway_output *output; pixman_region32_t *damage; - struct sway_view *view; float alpha; }; @@ -92,38 +89,7 @@ damage_finish: pixman_region32_fini(&damage); } -static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy, - void *_data) { - struct render_data *data = _data; - struct wlr_output *wlr_output = data->output->wlr_output; - float rotation = data->root_geo.rotation; - pixman_region32_t *output_damage = data->damage; - float alpha = data->alpha; - - struct wlr_texture *texture = wlr_surface_get_texture(surface); - if (!texture) { - return; - } - - struct wlr_box box; - bool intersects = output_get_surface_box(&data->root_geo, data->output, - surface, sx, sy, &box); - if (!intersects) { - return; - } - - scale_box(&box, wlr_output->scale); - - float matrix[9]; - enum wl_output_transform transform = - wlr_output_transform_invert(surface->current.transform); - wlr_matrix_project_box(matrix, &box, transform, rotation, - wlr_output->transform_matrix); - - render_texture(wlr_output, output_damage, texture, &box, matrix, alpha); -} - -static void render_surface_iterator2(struct sway_output *output, +static void render_surface_iterator(struct sway_output *output, struct wlr_surface *surface, struct wlr_box *_box, float rotation, void *_data) { struct render_data *data = _data; @@ -151,36 +117,33 @@ static void render_surface_iterator2(struct sway_output *output, static void render_layer(struct sway_output *output, pixman_region32_t *damage, struct wl_list *layer_surfaces) { struct render_data data = { - .output = output, .damage = damage, .alpha = 1.0f, }; output_layer_for_each_surface(output, layer_surfaces, - render_surface_iterator2, &data); + render_surface_iterator, &data); } #ifdef HAVE_XWAYLAND static void render_unmanaged(struct sway_output *output, pixman_region32_t *damage, struct wl_list *unmanaged) { struct render_data data = { - .output = output, .damage = damage, .alpha = 1.0f, }; output_unmanaged_for_each_surface(output, unmanaged, - render_surface_iterator2, &data); + render_surface_iterator, &data); } #endif static void render_drag_icons(struct sway_output *output, pixman_region32_t *damage, struct wl_list *drag_icons) { struct render_data data = { - .output = output, .damage = damage, .alpha = 1.0f, }; output_drag_icons_for_each_surface(output, drag_icons, - render_surface_iterator2, &data); + render_surface_iterator, &data); } static void render_rect(struct wlr_output *wlr_output, @@ -226,12 +189,10 @@ static void premultiply_alpha(float color[4], float opacity) { static void render_view_surfaces(struct sway_view *view, struct sway_output *output, pixman_region32_t *damage, float alpha) { struct render_data data = { - .output = output, .damage = damage, - .view = view, .alpha = alpha, }; - output_view_for_each_surface(output, view, render_surface_iterator2, &data); + output_view_for_each_surface(output, view, render_surface_iterator, &data); } static void render_saved_view(struct sway_view *view, -- cgit v1.2.3 From fe0750fec107f692be4f47659b446ed3d8d8f3b6 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 27 Jul 2018 19:19:30 +0100 Subject: Remove output_surface_for_each_surface from header --- sway/desktop/output.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index e1d85b10..8272b35b 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -119,8 +119,8 @@ void output_surface_for_each_surface_iterator(struct wlr_surface *surface, data->user_data); } -void output_surface_for_each_surface(struct sway_output *output, - struct wlr_surface *surface, double ox, double oy, float rotation, +static void output_surface_for_each_surface(struct sway_output *output, + struct wlr_surface *surface, double ox, double oy, sway_surface_iterator_func_t iterator, void *user_data) { struct surface_iterator_data data = { .user_iterator = iterator, @@ -130,7 +130,7 @@ void output_surface_for_each_surface(struct sway_output *output, .oy = oy, .width = surface->current.width, .height = surface->current.height, - .rotation = rotation, + .rotation = 0, }; wlr_surface_for_each_surface(surface, @@ -163,7 +163,7 @@ void output_layer_for_each_surface(struct sway_output *output, struct wlr_layer_surface *wlr_layer_surface = layer_surface->layer_surface; output_surface_for_each_surface(output, wlr_layer_surface->surface, - layer_surface->geo.x, layer_surface->geo.y, 0, iterator, + layer_surface->geo.x, layer_surface->geo.y, iterator, user_data); } } @@ -179,7 +179,7 @@ void output_unmanaged_for_each_surface(struct sway_output *output, double ox = unmanaged_surface->lx - output->swayc->current.swayc_x; double oy = unmanaged_surface->ly - output->swayc->current.swayc_y; - output_surface_for_each_surface(output, xsurface->surface, ox, oy, 0, + output_surface_for_each_surface(output, xsurface->surface, ox, oy, iterator, user_data); } } @@ -195,7 +195,7 @@ void output_drag_icons_for_each_surface(struct sway_output *output, if (drag_icon->wlr_drag_icon->mapped) { output_surface_for_each_surface(output, - drag_icon->wlr_drag_icon->surface, ox, oy, 0, + drag_icon->wlr_drag_icon->surface, ox, oy, iterator, user_data); } } @@ -430,7 +430,7 @@ static void damage_surface_iterator(struct sway_output *output, void output_damage_surface(struct sway_output *output, double ox, double oy, struct wlr_surface *surface, bool whole) { - output_surface_for_each_surface(output, surface, ox, oy, 0, + output_surface_for_each_surface(output, surface, ox, oy, damage_surface_iterator, &whole); } -- cgit v1.2.3 From 9951b2ec334545f636c892742ed034d917146558 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 27 Jul 2018 19:23:38 +0100 Subject: Remove unused output_from_wlr_output --- sway/desktop/output.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 8272b35b..fc767cca 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -534,10 +534,6 @@ static void handle_scale(struct wl_listener *listener, void *data) { transaction_commit_dirty(); } -struct sway_output *output_from_wlr_output(struct wlr_output *wlr_output) { - return wlr_output->data; -} - void handle_new_output(struct wl_listener *listener, void *data) { struct sway_server *server = wl_container_of(listener, server, new_output); struct wlr_output *wlr_output = data; -- cgit v1.2.3 From 0ad865f0b7db2407e151796253b632036a240c7f Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 29 Jul 2018 14:34:48 +0100 Subject: Make output_surface_for_each_surface_iterator static --- sway/desktop/output.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index fc767cca..d9ccb00d 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -105,7 +105,7 @@ static bool get_surface_box(struct surface_iterator_data *data, return wlr_box_intersection(&output_box, &rotated_box, &intersection); } -void output_surface_for_each_surface_iterator(struct wlr_surface *surface, +static void output_for_each_surface_iterator(struct wlr_surface *surface, int sx, int sy, void *_data) { struct surface_iterator_data *data = _data; @@ -134,7 +134,7 @@ static void output_surface_for_each_surface(struct sway_output *output, }; wlr_surface_for_each_surface(surface, - output_surface_for_each_surface_iterator, &data); + output_for_each_surface_iterator, &data); } void output_view_for_each_surface(struct sway_output *output, @@ -152,7 +152,7 @@ void output_view_for_each_surface(struct sway_output *output, }; view_for_each_surface(view, - output_surface_for_each_surface_iterator, &data); + output_for_each_surface_iterator, &data); } void output_layer_for_each_surface(struct sway_output *output, -- cgit v1.2.3 From 9a7e436fad96e9a99f1c06fecedba93828bf4dc1 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 29 Jul 2018 11:05:11 +0100 Subject: Don't give focus if xwayland window has a type hint --- sway/desktop/xwayland.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 390ca580..398446f8 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c @@ -69,11 +69,13 @@ static void unmanaged_handle_map(struct wl_listener *listener, void *data) { surface->ly = xsurface->y; desktop_damage_surface(xsurface->surface, surface->lx, surface->ly, true); - struct sway_seat *seat = input_manager_current_seat(input_manager); - struct wlr_xwayland *xwayland = - seat->input->server->xwayland.wlr_xwayland; - wlr_xwayland_set_seat(xwayland, seat->wlr_seat); - seat_set_focus_surface(seat, xsurface->surface, false); + if (wlr_xwayland_or_surface_wants_focus(xsurface)) { + struct sway_seat *seat = input_manager_current_seat(input_manager); + struct wlr_xwayland *xwayland = + seat->input->server->xwayland.wlr_xwayland; + wlr_xwayland_set_seat(xwayland, seat->wlr_seat); + seat_set_focus_surface(seat, xsurface->surface, false); + } } static void unmanaged_handle_unmap(struct wl_listener *listener, void *data) { -- cgit v1.2.3 From b8efdeae298d59bf7015a9821e3d29cc4e9852e1 Mon Sep 17 00:00:00 2001 From: Brian Ashworth Date: Mon, 30 Jul 2018 01:59:20 -0400 Subject: Fix title textures on scale change --- sway/desktop/output.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index cecd300a..fb52e7b1 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -506,14 +506,10 @@ static void handle_transform(struct wl_listener *listener, void *data) { transaction_commit_dirty(); } -static void handle_scale_iterator(struct sway_container *view, void *data) { - view_update_marks_textures(view->sway_view); -} - static void handle_scale(struct wl_listener *listener, void *data) { struct sway_output *output = wl_container_of(listener, output, scale); arrange_layers(output); - container_descendants(output->swayc, C_VIEW, handle_scale_iterator, NULL); + container_update_textures_recursive(output->swayc); arrange_windows(output->swayc); transaction_commit_dirty(); } -- cgit v1.2.3 From 15c19572cf97d3386ed3b2f9154dd752ce0b0b49 Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 30 Jul 2018 19:44:07 +0100 Subject: Fix segfault with fullscreen --- sway/desktop/output.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 6b2eb0c2..31b53213 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -317,8 +317,9 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { struct sway_container *workspace = output_get_active_workspace(output); if (workspace->current.ws_fullscreen) { if (workspace->current.ws_fullscreen->type == C_VIEW) { - send_frame_done_container_iterator( - workspace->current.ws_fullscreen, when); + output_view_for_each_surface(output, + workspace->current.ws_fullscreen->sway_view, + send_frame_done_iterator, when); } else { send_frame_done_container(output, workspace->current.ws_fullscreen, when); -- cgit v1.2.3 From de86d65627e96cffe77f4abf11c4a0b982326ff9 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Tue, 31 Jul 2018 18:41:30 +1000 Subject: Fix popups Fixes the render and container_at order for popups. Fixes #2210 For rendering: * render_view_surfaces has been renamed to render_view_toplevels * render_view_toplevels now uses output_surface_for_each_surface (which is now public), as that function uses wlr_surface_for_each_surface which doesn't descend into popups * Views now have a for_each_popup iterator, which is used by the renderer to render the focused view's popups * When rendering a popup, toplevels (xdg subsurfaces) of that popup are also rendered For sending frame done, the logic has been updated to match the rendering logic: * send_frame_done_container no longer descends into popups * for_each_popup is used to send frame done to the focused view's popups and their child toplevels For container_at: * floating_container_at is now static, which means it had to be moved higher in the file. * container_at now considers popups for the focused view before checking containers. * tiling_container_at has been introduced, so that it doesn't call container_at recursively (it would check popups recursively if it did) --- sway/desktop/output.c | 52 ++++++++++++++++++++++++++++++++++++++++++--- sway/desktop/render.c | 37 ++++++++++++++++++++++++++++---- sway/desktop/xdg_shell.c | 9 ++++++++ sway/desktop/xdg_shell_v6.c | 10 +++++++++ 4 files changed, 101 insertions(+), 7 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 31b53213..4c9d978c 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -119,7 +119,7 @@ static void output_for_each_surface_iterator(struct wlr_surface *surface, data->user_data); } -static void output_surface_for_each_surface(struct sway_output *output, +void output_surface_for_each_surface(struct sway_output *output, struct wlr_surface *surface, double ox, double oy, sway_surface_iterator_func_t iterator, void *user_data) { struct surface_iterator_data data = { @@ -155,6 +155,23 @@ void output_view_for_each_surface(struct sway_output *output, output_for_each_surface_iterator, &data); } +void output_view_for_each_popup(struct sway_output *output, + struct sway_view *view, sway_surface_iterator_func_t iterator, + void *user_data) { + struct surface_iterator_data data = { + .user_iterator = iterator, + .user_data = user_data, + .output = output, + .ox = view->swayc->current.view_x - output->swayc->current.swayc_x, + .oy = view->swayc->current.view_y - output->swayc->current.swayc_y, + .width = view->swayc->current.view_width, + .height = view->swayc->current.view_height, + .rotation = 0, // TODO + }; + + view_for_each_popup(view, output_for_each_surface_iterator, &data); +} + void output_layer_for_each_surface(struct sway_output *output, struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator, void *user_data) { @@ -295,8 +312,9 @@ static void send_frame_done_container_iterator(struct sway_container *con, return; } - output_view_for_each_surface(data->output, con->sway_view, - send_frame_done_iterator, data->when); + // Toplevels only + output_surface_for_each_surface(data->output, con->sway_view->surface, + con->x, con->y, send_frame_done_iterator, data->when); } static void send_frame_done_container(struct sway_output *output, @@ -309,6 +327,27 @@ static void send_frame_done_container(struct sway_output *output, send_frame_done_container_iterator, &data); } +static void send_frame_done_popup_iterator(struct sway_output *output, + struct wlr_surface *surface, struct wlr_box *box, float rotation, + void *data) { + // Send frame done to this popup's surface + send_frame_done_iterator(output, surface, box, rotation, data); + + // Send frame done to this popup's child toplevels + output_surface_for_each_surface(output, surface, box->x, box->y, + send_frame_done_iterator, data); +} + +static void send_frame_done_popups(struct sway_output *output, + struct sway_view *view, struct timespec *when) { + struct send_frame_done_data data = { + .output = output, + .when = when, + }; + output_view_for_each_popup(output, view, + send_frame_done_popup_iterator, &data); +} + static void send_frame_done(struct sway_output *output, struct timespec *when) { if (output_has_opaque_overlay_layer_surface(output)) { goto send_frame_overlay; @@ -346,6 +385,13 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], when); } + struct sway_seat *seat = input_manager_current_seat(input_manager); + struct sway_container *focus = seat_get_focus(seat); + if (focus && focus->type == C_VIEW) { + send_frame_done_popups(output, focus->sway_view, when); + } + + send_frame_overlay: send_frame_done_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], when); diff --git a/sway/desktop/render.c b/sway/desktop/render.c index f25055b8..ea4361f2 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -186,13 +186,36 @@ static void premultiply_alpha(float color[4], float opacity) { color[2] *= color[3]; } -static void render_view_surfaces(struct sway_view *view, +static void render_view_toplevels(struct sway_view *view, struct sway_output *output, pixman_region32_t *damage, float alpha) { struct render_data data = { .damage = damage, .alpha = alpha, }; - output_view_for_each_surface(output, view, render_surface_iterator, &data); + // Render all toplevels without descending into popups + output_surface_for_each_surface(output, view->surface, + view->swayc->current.view_x, view->swayc->current.view_y, + render_surface_iterator, &data); +} + +static void render_popup_iterator(struct sway_output *output, + struct wlr_surface *surface, struct wlr_box *box, float rotation, + void *data) { + // Render this popup's surface + render_surface_iterator(output, surface, box, rotation, data); + + // Render this popup's child toplevels + output_surface_for_each_surface(output, surface, box->x, box->y, + render_surface_iterator, data); +} + +static void render_view_popups(struct sway_view *view, + struct sway_output *output, pixman_region32_t *damage, float alpha) { + struct render_data data = { + .damage = damage, + .alpha = alpha, + }; + output_view_for_each_popup(output, view, render_popup_iterator, &data); } static void render_saved_view(struct sway_view *view, @@ -241,7 +264,7 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage, if (view->swayc->instructions->length) { render_saved_view(view, output, damage, view->swayc->alpha); } else { - render_view_surfaces(view, output, damage, view->swayc->alpha); + render_view_toplevels(view, output, damage, view->swayc->alpha); } if (view->using_csd) { @@ -845,7 +868,7 @@ void output_render(struct sway_output *output, struct timespec *when, render_saved_view(fullscreen_con->sway_view, output, damage, 1.0f); } else { - render_view_surfaces(fullscreen_con->sway_view, + render_view_toplevels(fullscreen_con->sway_view, output, damage, 1.0f); } } else { @@ -881,6 +904,12 @@ void output_render(struct sway_output *output, struct timespec *when, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); } + struct sway_seat *seat = input_manager_current_seat(input_manager); + struct sway_container *focus = seat_get_focus(seat); + if (focus && focus->type == C_VIEW) { + render_view_popups(focus->sway_view, output, damage, focus->alpha); + } + render_overlay: render_layer(output, damage, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index e6e1527e..9f94bd74 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -179,6 +179,14 @@ static void for_each_surface(struct sway_view *view, user_data); } +static void for_each_popup(struct sway_view *view, + wlr_surface_iterator_func_t iterator, void *user_data) { + if (xdg_shell_view_from_view(view) == NULL) { + return; + } + wlr_xdg_surface_for_each_popup(view->wlr_xdg_surface, iterator, user_data); +} + static void _close(struct sway_view *view) { if (xdg_shell_view_from_view(view) == NULL) { return; @@ -207,6 +215,7 @@ static const struct sway_view_impl view_impl = { .set_fullscreen = set_fullscreen, .wants_floating = wants_floating, .for_each_surface = for_each_surface, + .for_each_popup = for_each_popup, .close = _close, .destroy = destroy, }; diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 5feee3e4..4502c386 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -175,6 +175,15 @@ static void for_each_surface(struct sway_view *view, user_data); } +static void for_each_popup(struct sway_view *view, + wlr_surface_iterator_func_t iterator, void *user_data) { + if (xdg_shell_v6_view_from_view(view) == NULL) { + return; + } + wlr_xdg_surface_v6_for_each_popup(view->wlr_xdg_surface_v6, iterator, + user_data); +} + static void _close(struct sway_view *view) { if (xdg_shell_v6_view_from_view(view) == NULL) { return; @@ -203,6 +212,7 @@ static const struct sway_view_impl view_impl = { .set_fullscreen = set_fullscreen, .wants_floating = wants_floating, .for_each_surface = for_each_surface, + .for_each_popup = for_each_popup, .close = _close, .destroy = destroy, }; -- cgit v1.2.3 From 7a59508da467a3b793e355e28ae67ce04633761c Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Tue, 31 Jul 2018 19:58:34 +1000 Subject: Close popups when changing focus Also reverts the send frame done changes from the previous commit. --- sway/desktop/output.c | 33 ++------------------------------- sway/desktop/xdg_shell.c | 13 +++++++++++++ sway/desktop/xdg_shell_v6.c | 13 +++++++++++++ 3 files changed, 28 insertions(+), 31 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 4c9d978c..66747a3f 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -312,9 +312,8 @@ static void send_frame_done_container_iterator(struct sway_container *con, return; } - // Toplevels only - output_surface_for_each_surface(data->output, con->sway_view->surface, - con->x, con->y, send_frame_done_iterator, data->when); + output_view_for_each_surface(data->output, con->sway_view, + send_frame_done_iterator, data->when); } static void send_frame_done_container(struct sway_output *output, @@ -327,27 +326,6 @@ static void send_frame_done_container(struct sway_output *output, send_frame_done_container_iterator, &data); } -static void send_frame_done_popup_iterator(struct sway_output *output, - struct wlr_surface *surface, struct wlr_box *box, float rotation, - void *data) { - // Send frame done to this popup's surface - send_frame_done_iterator(output, surface, box, rotation, data); - - // Send frame done to this popup's child toplevels - output_surface_for_each_surface(output, surface, box->x, box->y, - send_frame_done_iterator, data); -} - -static void send_frame_done_popups(struct sway_output *output, - struct sway_view *view, struct timespec *when) { - struct send_frame_done_data data = { - .output = output, - .when = when, - }; - output_view_for_each_popup(output, view, - send_frame_done_popup_iterator, &data); -} - static void send_frame_done(struct sway_output *output, struct timespec *when) { if (output_has_opaque_overlay_layer_surface(output)) { goto send_frame_overlay; @@ -385,13 +363,6 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], when); } - struct sway_seat *seat = input_manager_current_seat(input_manager); - struct sway_container *focus = seat_get_focus(seat); - if (focus && focus->type == C_VIEW) { - send_frame_done_popups(output, focus->sway_view, when); - } - - send_frame_overlay: send_frame_done_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], when); diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 9f94bd74..b364663d 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -197,6 +197,18 @@ static void _close(struct sway_view *view) { } } +static void close_popups_iterator(struct wlr_surface *surface, + int sx, int sy, void *data) { + struct wlr_xdg_surface *xdg_surface = + wlr_xdg_surface_from_wlr_surface(surface); + wlr_xdg_surface_send_close(xdg_surface); +} + +static void close_popups(struct sway_view *view) { + wlr_xdg_surface_for_each_popup(view->wlr_xdg_surface, + close_popups_iterator, NULL); +} + static void destroy(struct sway_view *view) { struct sway_xdg_shell_view *xdg_shell_view = xdg_shell_view_from_view(view); @@ -217,6 +229,7 @@ static const struct sway_view_impl view_impl = { .for_each_surface = for_each_surface, .for_each_popup = for_each_popup, .close = _close, + .close_popups = close_popups, .destroy = destroy, }; diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 4502c386..ffea03ad 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -194,6 +194,18 @@ static void _close(struct sway_view *view) { } } +static void close_popups_iterator(struct wlr_surface *surface, + int sx, int sy, void *data) { + struct wlr_xdg_surface_v6 *xdg_surface_v6 = + wlr_xdg_surface_v6_from_wlr_surface(surface); + wlr_xdg_surface_v6_send_close(xdg_surface_v6); +} + +static void close_popups(struct sway_view *view) { + wlr_xdg_surface_v6_for_each_popup(view->wlr_xdg_surface_v6, + close_popups_iterator, NULL); +} + static void destroy(struct sway_view *view) { struct sway_xdg_shell_v6_view *xdg_shell_v6_view = xdg_shell_v6_view_from_view(view); @@ -214,6 +226,7 @@ static const struct sway_view_impl view_impl = { .for_each_surface = for_each_surface, .for_each_popup = for_each_popup, .close = _close, + .close_popups = close_popups, .destroy = destroy, }; -- cgit v1.2.3 From d10ccc1eb144e4de2477398f6b11753f6b7df70b Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Wed, 1 Aug 2018 16:23:11 +1000 Subject: Correctly track saved surfaces during multiple transactions Fixes #2364. Suppose a view is 600px wide, and we tell it to resize to 601px during a resize operation. We create a transaction, save the 600px buffer and send the configure. This buffer is saved into the associated instruction, and is rendered while we wait for the view to commit a 601px buffer. Before the view commits the 601px buffer, suppose we tell it to resize to 602px. The new transaction will also save the buffer, but it's still the 600px buffer because we haven't received a new one yet. Then suppose the view commits its original 601px buffer. This completes the first transaction, so we apply the 601px width to the container. There's still the second (now only) transaction remaining, so we render the saved buffer from that. But this is still the 600px buffer, and we believe it's 601px. Whoops. The problem here is we can't stack buffers like this. So this commit removes the saved buffer from the instructions, places it in the view instead, and re-saves the latest buffer every time the view completes a transaction and still has further pending transactions. As saved buffers are now specific to views rather than instructions, the functions for saving and removing the saved buffer have been moved to view.c. The calls to save and restore the buffer have been relocated to more appropriate functions too, favouring transaction_commit and transaction_apply rather than transaction_add_container and transaction_destroy. --- sway/desktop/render.c | 16 +++++++-------- sway/desktop/transaction.c | 51 +++++++++++----------------------------------- 2 files changed, 19 insertions(+), 48 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/render.c b/sway/desktop/render.c index f25055b8..f0e47c95 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -199,17 +199,14 @@ static void render_saved_view(struct sway_view *view, struct sway_output *output, pixman_region32_t *damage, float alpha) { struct wlr_output *wlr_output = output->wlr_output; - int width, height; - struct wlr_texture *texture = - transaction_get_saved_texture(view, &width, &height); - if (!texture) { + if (!view->saved_buffer || !view->saved_buffer->texture) { return; } struct wlr_box box = { .x = view->swayc->current.view_x - output->swayc->current.swayc_x, .y = view->swayc->current.view_y - output->swayc->current.swayc_y, - .width = width, - .height = height, + .width = view->saved_buffer_width, + .height = view->saved_buffer_height, }; struct wlr_box output_box = { @@ -229,7 +226,8 @@ static void render_saved_view(struct sway_view *view, wlr_matrix_project_box(matrix, &box, WL_OUTPUT_TRANSFORM_NORMAL, 0, wlr_output->transform_matrix); - render_texture(wlr_output, damage, texture, &box, matrix, alpha); + render_texture(wlr_output, damage, view->saved_buffer->texture, + &box, matrix, alpha); } /** @@ -238,7 +236,7 @@ static void render_saved_view(struct sway_view *view, static void render_view(struct sway_output *output, pixman_region32_t *damage, struct sway_container *con, struct border_colors *colors) { struct sway_view *view = con->sway_view; - if (view->swayc->instructions->length) { + if (view->saved_buffer) { render_saved_view(view, output, damage, view->swayc->alpha); } else { render_view_surfaces(view, output, damage, view->swayc->alpha); @@ -841,7 +839,7 @@ void output_render(struct sway_output *output, struct timespec *when, // TODO: handle views smaller than the output if (fullscreen_con->type == C_VIEW) { - if (fullscreen_con->instructions->length) { + if (fullscreen_con->sway_view->saved_buffer) { render_saved_view(fullscreen_con->sway_view, output, damage, 1.0f); } else { diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 7975366e..94070363 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -41,8 +41,6 @@ struct sway_transaction_instruction { struct sway_transaction *transaction; struct sway_container *container; struct sway_container_state state; - struct wlr_buffer *saved_buffer; - int saved_buffer_width, saved_buffer_height; uint32_t serial; bool ready; }; @@ -57,27 +55,6 @@ static struct sway_transaction *transaction_create() { return transaction; } -static void remove_saved_view_buffer( - struct sway_transaction_instruction *instruction) { - if (instruction->saved_buffer) { - wlr_buffer_unref(instruction->saved_buffer); - instruction->saved_buffer = NULL; - } -} - -static void save_view_buffer(struct sway_view *view, - struct sway_transaction_instruction *instruction) { - if (!sway_assert(instruction->saved_buffer == NULL, - "Didn't expect instruction to have a saved buffer already")) { - remove_saved_view_buffer(instruction); - } - if (view->surface && wlr_surface_has_buffer(view->surface)) { - instruction->saved_buffer = wlr_buffer_ref(view->surface->buffer); - instruction->saved_buffer_width = view->surface->current.width; - instruction->saved_buffer_height = view->surface->current.height; - } -} - static void transaction_destroy(struct sway_transaction *transaction) { // Free instructions for (int i = 0; i < transaction->instructions->length; ++i) { @@ -93,7 +70,6 @@ static void transaction_destroy(struct sway_transaction *transaction) { if (con->destroying && !con->instructions->length) { container_free(con); } - remove_saved_view_buffer(instruction); free(instruction); } list_free(transaction->instructions); @@ -158,9 +134,6 @@ static void transaction_add_container(struct sway_transaction *transaction, copy_pending_state(container, &instruction->state); - if (container->type == C_VIEW) { - save_view_buffer(container->sway_view, instruction); - } list_add(transaction->instructions, instruction); } @@ -220,6 +193,15 @@ static void transaction_apply(struct sway_transaction *transaction) { memcpy(&container->current, &instruction->state, sizeof(struct sway_container_state)); + + if (container->type == C_VIEW) { + if (container->sway_view->saved_buffer) { + view_remove_saved_buffer(container->sway_view); + } + if (container->instructions->length > 1) { + view_save_buffer(container->sway_view); + } + } } } @@ -294,6 +276,9 @@ static void transaction_commit(struct sway_transaction *transaction) { // mapping and its default geometry doesn't intersect an output. struct timespec when; wlr_surface_send_frame_done(con->sway_view->surface, &when); + if (!con->sway_view->saved_buffer) { + view_save_buffer(con->sway_view); + } } list_add(con->instructions, instruction); } @@ -400,18 +385,6 @@ void transaction_notify_view_ready_by_size(struct sway_view *view, } } -struct wlr_texture *transaction_get_saved_texture(struct sway_view *view, - int *width, int *height) { - struct sway_transaction_instruction *instruction = - view->swayc->instructions->items[0]; - if (!instruction->saved_buffer) { - return NULL; - } - *width = instruction->saved_buffer_width; - *height = instruction->saved_buffer_height; - return instruction->saved_buffer->texture; -} - void transaction_commit_dirty(void) { if (!server.dirty_containers->length) { return; -- cgit v1.2.3 From abf33468c12df258b8135089d99e7bd4f10e4f28 Mon Sep 17 00:00:00 2001 From: Brian Ashworth Date: Sun, 22 Jul 2018 23:43:45 -0400 Subject: Arrange output in arrange_layers and commit dirty --- sway/desktop/layer_shell.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'sway/desktop') diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c index a7d96717..71a0163c 100644 --- a/sway/desktop/layer_shell.c +++ b/sway/desktop/layer_shell.c @@ -7,11 +7,13 @@ #include #include #include +#include "sway/desktop/transaction.h" #include "sway/input/input-manager.h" #include "sway/input/seat.h" #include "sway/layers.h" #include "sway/output.h" #include "sway/server.h" +#include "sway/tree/arrange.h" #include "sway/tree/layout.h" #include "log.h" @@ -212,6 +214,9 @@ void arrange_layers(struct sway_output *output) { wl_list_for_each(seat, &input_manager->seats, link) { seat_set_focus_layer(seat, topmost ? topmost->layer_surface : NULL); } + + arrange_windows(output->swayc); + transaction_commit_dirty(); } static void handle_output_destroy(struct wl_listener *listener, void *data) { -- cgit v1.2.3 From a4f7bf23b21d0d838a8a19261d5fd69719003a03 Mon Sep 17 00:00:00 2001 From: Brian Ashworth Date: Fri, 27 Jul 2018 11:19:42 -0400 Subject: Address first round review for swaynag --- sway/desktop/layer_shell.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c index 71a0163c..a2935883 100644 --- a/sway/desktop/layer_shell.c +++ b/sway/desktop/layer_shell.c @@ -214,9 +214,6 @@ void arrange_layers(struct sway_output *output) { wl_list_for_each(seat, &input_manager->seats, link) { seat_set_focus_layer(seat, topmost ? topmost->layer_surface : NULL); } - - arrange_windows(output->swayc); - transaction_commit_dirty(); } static void handle_output_destroy(struct wl_listener *listener, void *data) { @@ -250,6 +247,9 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { output_damage_surface(output, layer->geo.x, layer->geo.y, layer_surface->surface, false); } + + arrange_windows(output->swayc); + transaction_commit_dirty(); } static void unmap(struct sway_layer_surface *sway_layer) { @@ -287,6 +287,8 @@ static void handle_destroy(struct wl_listener *listener, void *data) { struct sway_output *output = sway_layer->layer_surface->output->data; if (output != NULL && output->swayc != NULL) { arrange_layers(output); + arrange_windows(output->swayc); + transaction_commit_dirty(); } wl_list_remove(&sway_layer->output_destroy.link); sway_layer->layer_surface->output = NULL; -- cgit v1.2.3 From 8314019f660cd28fc8cdb634f82b437105074258 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Thu, 2 Aug 2018 20:54:03 +1000 Subject: Fix race condition crashes when unmapping views This fixes two issues which were both introduced in #2396. First issue: The PR changes the location of the buffer save to transaction_apply, but puts it inside the should_configure block. For unmapping (destroying) views, should_configure returns false so it wasn't saving the buffer. If a frame was rendered between the unmap and the transaction applying then it would result in a crash. Second issue: If a destroying view is involved in two transactions, we must not release the buffer between the transactions because there is no live buffer to grab any more. --- sway/desktop/transaction.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 94070363..4e6af86a 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -195,11 +195,18 @@ static void transaction_apply(struct sway_transaction *transaction) { sizeof(struct sway_container_state)); if (container->type == C_VIEW) { - if (container->sway_view->saved_buffer) { - view_remove_saved_buffer(container->sway_view); - } - if (container->instructions->length > 1) { - view_save_buffer(container->sway_view); + if (container->destroying) { + if (container->instructions->length == 1 && + container->sway_view->saved_buffer) { + view_remove_saved_buffer(container->sway_view); + } + } else { + if (container->sway_view->saved_buffer) { + view_remove_saved_buffer(container->sway_view); + } + if (container->instructions->length > 1) { + view_save_buffer(container->sway_view); + } } } } @@ -276,9 +283,9 @@ static void transaction_commit(struct sway_transaction *transaction) { // mapping and its default geometry doesn't intersect an output. struct timespec when; wlr_surface_send_frame_done(con->sway_view->surface, &when); - if (!con->sway_view->saved_buffer) { - view_save_buffer(con->sway_view); - } + } + if (con->type == C_VIEW && !con->sway_view->saved_buffer) { + view_save_buffer(con->sway_view); } list_add(con->instructions, instruction); } -- cgit v1.2.3 From 9aa258d33a9baa42895214da7e82f4568fcb8f76 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 2 Aug 2018 09:05:46 -0400 Subject: Revert "Fix popups" This reverts commit de86d65627e96cffe77f4abf11c4a0b982326ff9. --- sway/desktop/output.c | 19 +------------------ sway/desktop/render.c | 37 ++++--------------------------------- sway/desktop/xdg_shell.c | 9 --------- sway/desktop/xdg_shell_v6.c | 10 ---------- 4 files changed, 5 insertions(+), 70 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 66747a3f..31b53213 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -119,7 +119,7 @@ static void output_for_each_surface_iterator(struct wlr_surface *surface, data->user_data); } -void output_surface_for_each_surface(struct sway_output *output, +static void output_surface_for_each_surface(struct sway_output *output, struct wlr_surface *surface, double ox, double oy, sway_surface_iterator_func_t iterator, void *user_data) { struct surface_iterator_data data = { @@ -155,23 +155,6 @@ void output_view_for_each_surface(struct sway_output *output, output_for_each_surface_iterator, &data); } -void output_view_for_each_popup(struct sway_output *output, - struct sway_view *view, sway_surface_iterator_func_t iterator, - void *user_data) { - struct surface_iterator_data data = { - .user_iterator = iterator, - .user_data = user_data, - .output = output, - .ox = view->swayc->current.view_x - output->swayc->current.swayc_x, - .oy = view->swayc->current.view_y - output->swayc->current.swayc_y, - .width = view->swayc->current.view_width, - .height = view->swayc->current.view_height, - .rotation = 0, // TODO - }; - - view_for_each_popup(view, output_for_each_surface_iterator, &data); -} - void output_layer_for_each_surface(struct sway_output *output, struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator, void *user_data) { diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 1f374740..f0e47c95 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -186,36 +186,13 @@ static void premultiply_alpha(float color[4], float opacity) { color[2] *= color[3]; } -static void render_view_toplevels(struct sway_view *view, +static void render_view_surfaces(struct sway_view *view, struct sway_output *output, pixman_region32_t *damage, float alpha) { struct render_data data = { .damage = damage, .alpha = alpha, }; - // Render all toplevels without descending into popups - output_surface_for_each_surface(output, view->surface, - view->swayc->current.view_x, view->swayc->current.view_y, - render_surface_iterator, &data); -} - -static void render_popup_iterator(struct sway_output *output, - struct wlr_surface *surface, struct wlr_box *box, float rotation, - void *data) { - // Render this popup's surface - render_surface_iterator(output, surface, box, rotation, data); - - // Render this popup's child toplevels - output_surface_for_each_surface(output, surface, box->x, box->y, - render_surface_iterator, data); -} - -static void render_view_popups(struct sway_view *view, - struct sway_output *output, pixman_region32_t *damage, float alpha) { - struct render_data data = { - .damage = damage, - .alpha = alpha, - }; - output_view_for_each_popup(output, view, render_popup_iterator, &data); + output_view_for_each_surface(output, view, render_surface_iterator, &data); } static void render_saved_view(struct sway_view *view, @@ -262,7 +239,7 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage, if (view->saved_buffer) { render_saved_view(view, output, damage, view->swayc->alpha); } else { - render_view_toplevels(view, output, damage, view->swayc->alpha); + render_view_surfaces(view, output, damage, view->swayc->alpha); } if (view->using_csd) { @@ -866,7 +843,7 @@ void output_render(struct sway_output *output, struct timespec *when, render_saved_view(fullscreen_con->sway_view, output, damage, 1.0f); } else { - render_view_toplevels(fullscreen_con->sway_view, + render_view_surfaces(fullscreen_con->sway_view, output, damage, 1.0f); } } else { @@ -902,12 +879,6 @@ void output_render(struct sway_output *output, struct timespec *when, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); } - struct sway_seat *seat = input_manager_current_seat(input_manager); - struct sway_container *focus = seat_get_focus(seat); - if (focus && focus->type == C_VIEW) { - render_view_popups(focus->sway_view, output, damage, focus->alpha); - } - render_overlay: render_layer(output, damage, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index b364663d..9d6b27e5 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -179,14 +179,6 @@ static void for_each_surface(struct sway_view *view, user_data); } -static void for_each_popup(struct sway_view *view, - wlr_surface_iterator_func_t iterator, void *user_data) { - if (xdg_shell_view_from_view(view) == NULL) { - return; - } - wlr_xdg_surface_for_each_popup(view->wlr_xdg_surface, iterator, user_data); -} - static void _close(struct sway_view *view) { if (xdg_shell_view_from_view(view) == NULL) { return; @@ -227,7 +219,6 @@ static const struct sway_view_impl view_impl = { .set_fullscreen = set_fullscreen, .wants_floating = wants_floating, .for_each_surface = for_each_surface, - .for_each_popup = for_each_popup, .close = _close, .close_popups = close_popups, .destroy = destroy, diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index ffea03ad..6e4aae62 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -175,15 +175,6 @@ static void for_each_surface(struct sway_view *view, user_data); } -static void for_each_popup(struct sway_view *view, - wlr_surface_iterator_func_t iterator, void *user_data) { - if (xdg_shell_v6_view_from_view(view) == NULL) { - return; - } - wlr_xdg_surface_v6_for_each_popup(view->wlr_xdg_surface_v6, iterator, - user_data); -} - static void _close(struct sway_view *view) { if (xdg_shell_v6_view_from_view(view) == NULL) { return; @@ -224,7 +215,6 @@ static const struct sway_view_impl view_impl = { .set_fullscreen = set_fullscreen, .wants_floating = wants_floating, .for_each_surface = for_each_surface, - .for_each_popup = for_each_popup, .close = _close, .close_popups = close_popups, .destroy = destroy, -- cgit v1.2.3 From 8392eae40f17e550338b8b7058d8e9c1a6ad4f78 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Thu, 2 Aug 2018 23:30:26 +1000 Subject: Revert "Revert "Fix popups"" This reverts commit 9aa258d33a9baa42895214da7e82f4568fcb8f76. Reverting the revert, so that popups can be fixed. --- sway/desktop/output.c | 19 ++++++++++++++++++- sway/desktop/render.c | 37 +++++++++++++++++++++++++++++++++---- sway/desktop/xdg_shell.c | 9 +++++++++ sway/desktop/xdg_shell_v6.c | 10 ++++++++++ 4 files changed, 70 insertions(+), 5 deletions(-) (limited to 'sway/desktop') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 31b53213..66747a3f 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -119,7 +119,7 @@ static void output_for_each_surface_iterator(struct wlr_surface *surface, data->user_data); } -static void output_surface_for_each_surface(struct sway_output *output, +void output_surface_for_each_surface(struct sway_output *output, struct wlr_surface *surface, double ox, double oy, sway_surface_iterator_func_t iterator, void *user_data) { struct surface_iterator_data data = { @@ -155,6 +155,23 @@ void output_view_for_each_surface(struct sway_output *output, output_for_each_surface_iterator, &data); } +void output_view_for_each_popup(struct sway_output *output, + struct sway_view *view, sway_surface_iterator_func_t iterator, + void *user_data) { + struct surface_iterator_data data = { + .user_iterator = iterator, + .user_data = user_data, + .output = output, + .ox = view->swayc->current.view_x - output->swayc->current.swayc_x, + .oy = view->swayc->current.view_y - output->swayc->current.swayc_y, + .width = view->swayc->current.view_width, + .height = view->swayc->current.view_height, + .rotation = 0, // TODO + }; + + view_for_each_popup(view, output_for_each_surface_iterator, &data); +} + void output_layer_for_each_surface(struct sway_output *output, struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator, void *user_data) { diff --git a/sway/desktop/render.c b/sway/desktop/render.c index f0e47c95..1f374740 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -186,13 +186,36 @@ static void premultiply_alpha(float color[4], float opacity) { color[2] *= color[3]; } -static void render_view_surfaces(struct sway_view *view, +static void render_view_toplevels(struct sway_view *view, struct sway_output *output, pixman_region32_t *damage, float alpha) { struct render_data data = { .damage = damage, .alpha = alpha, }; - output_view_for_each_surface(output, view, render_surface_iterator, &data); + // Render all toplevels without descending into popups + output_surface_for_each_surface(output, view->surface, + view->swayc->current.view_x, view->swayc->current.view_y, + render_surface_iterator, &data); +} + +static void render_popup_iterator(struct sway_output *output, + struct wlr_surface *surface, struct wlr_box *box, float rotation, + void *data) { + // Render this popup's surface + render_surface_iterator(output, surface, box, rotation, data); + + // Render this popup's child toplevels + output_surface_for_each_surface(output, surface, box->x, box->y, + render_surface_iterator, data); +} + +static void render_view_popups(struct sway_view *view, + struct sway_output *output, pixman_region32_t *damage, float alpha) { + struct render_data data = { + .damage = damage, + .alpha = alpha, + }; + output_view_for_each_popup(output, view, render_popup_iterator, &data); } static void render_saved_view(struct sway_view *view, @@ -239,7 +262,7 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage, if (view->saved_buffer) { render_saved_view(view, output, damage, view->swayc->alpha); } else { - render_view_surfaces(view, output, damage, view->swayc->alpha); + render_view_toplevels(view, output, damage, view->swayc->alpha); } if (view->using_csd) { @@ -843,7 +866,7 @@ void output_render(struct sway_output *output, struct timespec *when, render_saved_view(fullscreen_con->sway_view, output, damage, 1.0f); } else { - render_view_surfaces(fullscreen_con->sway_view, + render_view_toplevels(fullscreen_con->sway_view, output, damage, 1.0f); } } else { @@ -879,6 +902,12 @@ void output_render(struct sway_output *output, struct timespec *when, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); } + struct sway_seat *seat = input_manager_current_seat(input_manager); + struct sway_container *focus = seat_get_focus(seat); + if (focus && focus->type == C_VIEW) { + render_view_popups(focus->sway_view, output, damage, focus->alpha); + } + render_overlay: render_layer(output, damage, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 9d6b27e5..b364663d 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -179,6 +179,14 @@ static void for_each_surface(struct sway_view *view, user_data); } +static void for_each_popup(struct sway_view *view, + wlr_surface_iterator_func_t iterator, void *user_data) { + if (xdg_shell_view_from_view(view) == NULL) { + return; + } + wlr_xdg_surface_for_each_popup(view->wlr_xdg_surface, iterator, user_data); +} + static void _close(struct sway_view *view) { if (xdg_shell_view_from_view(view) == NULL) { return; @@ -219,6 +227,7 @@ static const struct sway_view_impl view_impl = { .set_fullscreen = set_fullscreen, .wants_floating = wants_floating, .for_each_surface = for_each_surface, + .for_each_popup = for_each_popup, .close = _close, .close_popups = close_popups, .destroy = destroy, diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 6e4aae62..ffea03ad 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -175,6 +175,15 @@ static void for_each_surface(struct sway_view *view, user_data); } +static void for_each_popup(struct sway_view *view, + wlr_surface_iterator_func_t iterator, void *user_data) { + if (xdg_shell_v6_view_from_view(view) == NULL) { + return; + } + wlr_xdg_surface_v6_for_each_popup(view->wlr_xdg_surface_v6, iterator, + user_data); +} + static void _close(struct sway_view *view) { if (xdg_shell_v6_view_from_view(view) == NULL) { return; @@ -215,6 +224,7 @@ static const struct sway_view_impl view_impl = { .set_fullscreen = set_fullscreen, .wants_floating = wants_floating, .for_each_surface = for_each_surface, + .for_each_popup = for_each_popup, .close = _close, .close_popups = close_popups, .destroy = destroy, -- cgit v1.2.3 From 787f08da7ff9ecb325def2e3a44dc5043d7e2753 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Thu, 2 Aug 2018 23:34:26 +1000 Subject: Convert toplevel coordinates to output-local --- sway/desktop/render.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sway/desktop') diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 1f374740..cdac9c72 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -194,7 +194,8 @@ static void render_view_toplevels(struct sway_view *view, }; // Render all toplevels without descending into popups output_surface_for_each_surface(output, view->surface, - view->swayc->current.view_x, view->swayc->current.view_y, + view->swayc->current.view_x - output->wlr_output->lx, + view->swayc->current.view_y - output->wlr_output->ly, render_surface_iterator, &data); } -- cgit v1.2.3