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/input/cursor.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'sway/input') diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 96ac7b33..ad4b1718 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -109,9 +109,6 @@ static struct sway_container *container_at_coords( } struct sway_container *c; - if ((c = floating_container_at(lx, ly, surface, sx, sy))) { - return c; - } if ((c = container_at(ws, lx, ly, surface, sx, sy))) { return c; } -- 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. --- include/sway/tree/view.h | 3 +++ sway/desktop/output.c | 33 ++------------------------------- sway/desktop/xdg_shell.c | 13 +++++++++++++ sway/desktop/xdg_shell_v6.c | 13 +++++++++++++ sway/input/seat.c | 7 +++++++ sway/tree/view.c | 6 ++++++ 6 files changed, 44 insertions(+), 31 deletions(-) (limited to 'sway/input') diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 9f6d36fe..e722ca5e 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -50,6 +50,7 @@ struct sway_view_impl { void (*for_each_popup)(struct sway_view *view, wlr_surface_iterator_func_t iterator, void *user_data); void (*close)(struct sway_view *view); + void (*close_popups)(struct sway_view *view); void (*destroy)(struct sway_view *view); }; @@ -248,6 +249,8 @@ void view_set_tiled(struct sway_view *view, bool tiled); void view_close(struct sway_view *view); +void view_close_popups(struct sway_view *view); + void view_damage_from(struct sway_view *view); /** 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, }; diff --git a/sway/input/seat.c b/sway/input/seat.c index 53a92989..8ed0dce2 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -737,6 +737,13 @@ void seat_set_focus_warp(struct sway_seat *seat, } } + // Close any popups on the old focus + if (last_focus && last_focus != container) { + if (last_focus->type == C_VIEW) { + view_close_popups(last_focus->sway_view); + } + } + if (last_focus) { if (last_workspace) { ipc_event_workspace(last_workspace, container, "focus"); diff --git a/sway/tree/view.c b/sway/tree/view.c index c1207821..5d9b625f 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -302,6 +302,12 @@ void view_close(struct sway_view *view) { } } +void view_close_popups(struct sway_view *view) { + if (view->impl->close_popups) { + view->impl->close_popups(view); + } +} + void view_damage_from(struct sway_view *view) { for (int i = 0; i < root_container.children->length; ++i) { struct sway_container *cont = root_container.children->items[i]; -- cgit v1.2.3 From 77d74dd34fd7126d6159234c883b50a5a021e24a Mon Sep 17 00:00:00 2001 From: chr0me Date: Wed, 1 Aug 2018 19:48:43 +0800 Subject: XCursor is not configured if no pointer device is available --- sway/input/seat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sway/input') diff --git a/sway/input/seat.c b/sway/input/seat.c index 53a92989..a4a449e4 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -393,7 +393,6 @@ struct sway_seat *seat_create(struct sway_input_manager *input, WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_TOUCH); - seat_configure_xcursor(seat); wl_list_insert(&input->seats, &seat->link); @@ -438,6 +437,7 @@ static void seat_apply_input_config(struct sway_seat *seat, static void seat_configure_pointer(struct sway_seat *seat, struct sway_seat_device *sway_device) { + seat_configure_xcursor(seat); wlr_cursor_attach_input_device(seat->cursor->cursor, sway_device->input_device->wlr_device); seat_apply_input_config(seat, sway_device); -- cgit v1.2.3 From dd1d6255f0e558f2d62e03f701440a57f65254b2 Mon Sep 17 00:00:00 2001 From: Ian Fan Date: Fri, 13 Jul 2018 17:16:32 +0100 Subject: ipc: add window::focus event --- sway/input/seat.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sway/input') diff --git a/sway/input/seat.c b/sway/input/seat.c index a4a449e4..c85e9242 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -766,6 +766,10 @@ void seat_set_focus_warp(struct sway_seat *seat, } } + if (container->type == C_VIEW) { + ipc_event_window(container, "focus"); + } + seat->has_focus = (container != NULL); update_debug_tree(); -- cgit v1.2.3 From b2ac234569ff98de583d9e7755526cadf960f772 Mon Sep 17 00:00:00 2001 From: Ian Fan Date: Wed, 18 Jul 2018 21:52:15 +0100 Subject: ipc: fix workspace::focus event behaviour --- sway/input/seat.c | 4 +++- sway/tree/layout.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'sway/input') diff --git a/sway/input/seat.c b/sway/input/seat.c index c85e9242..76050aa9 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -739,7 +739,9 @@ void seat_set_focus_warp(struct sway_seat *seat, if (last_focus) { if (last_workspace) { - ipc_event_workspace(last_workspace, container, "focus"); + if (last_workspace != new_workspace) { + ipc_event_workspace(last_workspace, new_workspace, "focus"); + } if (!workspace_is_visible(last_workspace) && workspace_is_empty(last_workspace)) { if (last_workspace == last_focus) { diff --git a/sway/tree/layout.c b/sway/tree/layout.c index a0f9b6de..9fbbccaf 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -598,7 +598,7 @@ void container_move(struct sway_container *container, next_ws = container_parent(next_ws, C_WORKSPACE); } if (last_ws && next_ws && last_ws != next_ws) { - ipc_event_workspace(last_ws, container, "focus"); + ipc_event_workspace(last_ws, next_ws, "focus"); workspace_detect_urgent(last_ws); workspace_detect_urgent(next_ws); } -- cgit v1.2.3 From 03eaf444a4a432e5712d40f93d849b51d2028b63 Mon Sep 17 00:00:00 2001 From: Ian Fan Date: Wed, 18 Jul 2018 21:55:14 +0100 Subject: ipc: prevent emitting a workspace::focus event when moving a container to a different workspace or output When a container is moved from, say, workspace 1 to workspace 2, workspace 2 is focused in order to arrange the windows before focus is moved back to workspace 1, which caused a workspace:focus event from workspace 2 to workspace 1 to be emitted. This commit inhibits that event. --- include/sway/input/seat.h | 2 +- sway/commands/move.c | 4 ++-- sway/input/cursor.c | 6 +++--- sway/input/seat.c | 6 +++--- sway/tree/layout.c | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) (limited to 'sway/input') diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h index 07febe2c..92387601 100644 --- a/include/sway/input/seat.h +++ b/include/sway/input/seat.h @@ -99,7 +99,7 @@ void seat_configure_xcursor(struct sway_seat *seat); void seat_set_focus(struct sway_seat *seat, struct sway_container *container); void seat_set_focus_warp(struct sway_seat *seat, - struct sway_container *container, bool warp); + struct sway_container *container, bool warp, bool notify); void seat_set_focus_surface(struct sway_seat *seat, struct wlr_surface *surface, bool unfocus); diff --git a/sway/commands/move.c b/sway/commands/move.c index 1aae3838..46ebcd83 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c @@ -98,7 +98,7 @@ static struct cmd_results *cmd_move_container(struct sway_container *current, container_move_to(current, destination); struct sway_container *focus = seat_get_focus_inactive( config->handler_context.seat, old_parent); - seat_set_focus(config->handler_context.seat, focus); + seat_set_focus_warp(config->handler_context.seat, focus, true, false); container_reap_empty(old_parent); container_reap_empty(destination->parent); @@ -135,7 +135,7 @@ static struct cmd_results *cmd_move_container(struct sway_container *current, struct sway_container *old_parent = current->parent; struct sway_container *old_ws = container_parent(current, C_WORKSPACE); container_move_to(current, focus); - seat_set_focus(config->handler_context.seat, old_parent); + seat_set_focus_warp(config->handler_context.seat, old_parent, true, false); container_reap_empty(old_parent); container_reap_empty(focus->parent); diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 96ac7b33..d6fdc1da 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -349,7 +349,7 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, output = container_parent(c, C_OUTPUT); } if (output != focus) { - seat_set_focus_warp(seat, c, false); + seat_set_focus_warp(seat, c, false, true); } } else if (c->type == C_VIEW) { // Focus c if the following are true: @@ -359,13 +359,13 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, if (!wlr_seat_keyboard_has_grab(cursor->seat->wlr_seat) && c != prev_c && view_is_visible(c->sway_view)) { - seat_set_focus_warp(seat, c, false); + seat_set_focus_warp(seat, c, false, true); } else { struct sway_container *next_focus = seat_get_focus_inactive(seat, &root_container); if (next_focus && next_focus->type == C_VIEW && view_is_visible(next_focus->sway_view)) { - seat_set_focus_warp(seat, next_focus, false); + seat_set_focus_warp(seat, next_focus, false, true); } } } diff --git a/sway/input/seat.c b/sway/input/seat.c index 76050aa9..fe3cbc53 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -617,7 +617,7 @@ static int handle_urgent_timeout(void *data) { } void seat_set_focus_warp(struct sway_seat *seat, - struct sway_container *container, bool warp) { + struct sway_container *container, bool warp, bool notify) { if (seat->focused_layer) { return; } @@ -739,7 +739,7 @@ void seat_set_focus_warp(struct sway_seat *seat, if (last_focus) { if (last_workspace) { - if (last_workspace != new_workspace) { + if (notify && last_workspace != new_workspace) { ipc_event_workspace(last_workspace, new_workspace, "focus"); } if (!workspace_is_visible(last_workspace) @@ -779,7 +779,7 @@ void seat_set_focus_warp(struct sway_seat *seat, void seat_set_focus(struct sway_seat *seat, struct sway_container *container) { - seat_set_focus_warp(seat, container, true); + seat_set_focus_warp(seat, container, true, true); } void seat_set_focus_surface(struct sway_seat *seat, diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 9fbbccaf..1f82e534 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -1001,13 +1001,13 @@ static void swap_focus(struct sway_container *con1, if (focus == con1 && (con2->parent->layout == L_TABBED || con2->parent->layout == L_STACKED)) { if (workspace_is_visible(ws2)) { - seat_set_focus_warp(seat, con2, false); + seat_set_focus_warp(seat, con2, false, true); } seat_set_focus(seat, ws1 != ws2 ? con2 : con1); } else if (focus == con2 && (con1->parent->layout == L_TABBED || con1->parent->layout == L_STACKED)) { if (workspace_is_visible(ws1)) { - seat_set_focus_warp(seat, con1, false); + seat_set_focus_warp(seat, con1, false, true); } seat_set_focus(seat, ws1 != ws2 ? con1 : con2); } else if (ws1 != ws2) { -- cgit v1.2.3