From 5bcbc0b4a95c8b9fe0f74fee9de59a8afbe401a6 Mon Sep 17 00:00:00 2001 From: Ronan Pigott Date: Thu, 15 Oct 2020 15:52:55 -0600 Subject: [PATCH 1/5] seat: use default output mapping if there is no input config --- sway/input/seat.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sway/input/seat.c b/sway/input/seat.c index 32b496ced..04b480d8e 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -660,17 +660,16 @@ static void seat_apply_input_config(struct sway_seat *seat, struct sway_seat_device *sway_device) { struct input_config *ic = input_device_get_config(sway_device->input_device); - if (ic == NULL) { - return; - } sway_log(SWAY_DEBUG, "Applying input config to %s", sway_device->input_device->identifier); - const char *mapped_to_output = ic->mapped_to_output; - struct wlr_box *mapped_to_region = ic->mapped_to_region; + const char *mapped_to_output = ic == NULL ? NULL : ic->mapped_to_output; + struct wlr_box *mapped_to_region = ic == NULL ? NULL : ic->mapped_to_region; + enum input_config_mapped_to mapped_to = + ic == NULL ? MAPPED_TO_DEFAULT : ic->mapped_to; - switch (ic->mapped_to) { + switch (mapped_to) { case MAPPED_TO_DEFAULT: mapped_to_output = sway_device->input_device->wlr_device->output_name; if (mapped_to_output == NULL) { From 181798c2feb69c930a5800c4a26e1c29797d4ef2 Mon Sep 17 00:00:00 2001 From: Tudor Brindus Date: Sun, 18 Oct 2020 00:07:41 -0400 Subject: [PATCH 2/5] xwayland: listen to `set_geometry` event Closes #5735, refs #3007. This makes the "Search everywhere" dialog in JetBrains IDEs movable. --- include/sway/tree/view.h | 1 + sway/desktop/xwayland.c | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 9fe710d70..dac348ee4 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -174,6 +174,7 @@ struct sway_xwayland_unmanaged { struct wl_listener request_configure; struct wl_listener request_fullscreen; struct wl_listener commit; + struct wl_listener set_geometry; struct wl_listener map; struct wl_listener unmap; struct wl_listener destroy; diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index e35473bf0..cee0ab104 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c @@ -47,6 +47,15 @@ static void unmanaged_handle_commit(struct wl_listener *listener, void *data) { wl_container_of(listener, surface, commit); struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface; + desktop_damage_surface(xsurface->surface, surface->lx, surface->ly, + false); +} + +static void unmanaged_handle_set_geometry(struct wl_listener *listener, void *data) { + struct sway_xwayland_unmanaged *surface = + wl_container_of(listener, surface, set_geometry); + struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface; + if (xsurface->x != surface->lx || xsurface->y != surface->ly) { // Surface has moved desktop_damage_surface(xsurface->surface, surface->lx, surface->ly, @@ -55,9 +64,6 @@ static void unmanaged_handle_commit(struct wl_listener *listener, void *data) { surface->ly = xsurface->y; desktop_damage_surface(xsurface->surface, surface->lx, surface->ly, true); - } else { - desktop_damage_surface(xsurface->surface, xsurface->x, xsurface->y, - false); } } @@ -68,6 +74,9 @@ static void unmanaged_handle_map(struct wl_listener *listener, void *data) { wl_list_insert(root->xwayland_unmanaged.prev, &surface->link); + wl_signal_add(&xsurface->events.set_geometry, &surface->set_geometry); + surface->set_geometry.notify = unmanaged_handle_set_geometry; + wl_signal_add(&xsurface->surface->events.commit, &surface->commit); surface->commit.notify = unmanaged_handle_commit; @@ -89,6 +98,7 @@ static void unmanaged_handle_unmap(struct wl_listener *listener, void *data) { struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface; desktop_damage_surface(xsurface->surface, xsurface->x, xsurface->y, true); wl_list_remove(&surface->link); + wl_list_remove(&surface->set_geometry.link); wl_list_remove(&surface->commit.link); struct sway_seat *seat = input_manager_current_seat(); @@ -174,7 +184,6 @@ static struct sway_xwayland_unmanaged *create_unmanaged( return surface; } - static struct sway_xwayland_view *xwayland_view_from_view( struct sway_view *view) { if (!sway_assert(view->type == SWAY_VIEW_XWAYLAND, From 33affb33d2d083b6ab8500175210370141e0a113 Mon Sep 17 00:00:00 2001 From: Ronan Pigott Date: Fri, 2 Oct 2020 12:42:48 -0700 Subject: [PATCH 3/5] tiling_drag: emit window move ipc events --- sway/input/seatop_move_tiling.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sway/input/seatop_move_tiling.c b/sway/input/seatop_move_tiling.c index 09689183e..2d3abc9a6 100644 --- a/sway/input/seatop_move_tiling.c +++ b/sway/input/seatop_move_tiling.c @@ -5,6 +5,7 @@ #include "sway/desktop.h" #include "sway/input/cursor.h" #include "sway/input/seat.h" +#include "sway/ipc-server.h" #include "sway/output.h" #include "sway/tree/arrange.h" #include "sway/tree/node.h" @@ -261,6 +262,7 @@ static void finalize_move(struct sway_seat *seat) { container_split(target, new_layout); } container_add_sibling(target, con, after); + ipc_event_window(con, "move"); } } else { // Target is a workspace which requires splitting From 5bd6a5ce3ff3cb879463646d4f88745420335b23 Mon Sep 17 00:00:00 2001 From: Tudor Brindus Date: Sun, 18 Oct 2020 15:55:52 -0400 Subject: [PATCH 4/5] transaction: don't reconfigure X views unless integral coords changed Sway logical coordinates are doubles, but they get truncated to integers when sent to Xwayland through `xcb_configure_window`. X11 apps will not respond to duplicate configure requests (from their truncated point of view) and cause transactions to time out. Fixes #5035. --- sway/desktop/transaction.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 2b268e2c2..0d0e0635a 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -397,8 +397,12 @@ static bool should_configure(struct sway_node *node, // Xwayland views are position-aware and need to be reconfigured // when their position changes. if (node->sway_container->view->type == SWAY_VIEW_XWAYLAND) { - if (cstate->content_x != istate->content_x || - cstate->content_y != istate->content_y) { + // Sway logical coordinates are doubles, but they get truncated to + // integers when sent to Xwayland through `xcb_configure_window`. + // X11 apps will not respond to duplicate configure requests (from their + // truncated point of view) and cause transactions to time out. + if ((int)cstate->content_x != (int)istate->content_x || + (int)cstate->content_y != (int)istate->content_y) { return true; } } From 8355884fbd4ea04203614172424b27c5b74018ab Mon Sep 17 00:00:00 2001 From: Tudor Brindus Date: Sun, 18 Oct 2020 16:26:01 -0400 Subject: [PATCH 5/5] transaction: validate X transaction completions by geometry, not size Xwayland views are aware of their coordinates, so validating transaction completions should take into account the reported coordinates of the view. Prior to this commit they didn't, and matching dimensions would suffice to validate the transaction. Also introduced `transaction_notify_view_ready_immediately` to support the fix from d0f7e0f without jumping through hoops to figure out the geometry of an `xdg_shell` view. --- include/sway/desktop/transaction.h | 12 +++++++++--- sway/desktop/transaction.c | 14 ++++++++++++-- sway/desktop/xdg_shell.c | 3 +-- sway/desktop/xwayland.c | 8 ++++---- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/include/sway/desktop/transaction.h b/include/sway/desktop/transaction.h index 66e8c9a25..175489c57 100644 --- a/include/sway/desktop/transaction.h +++ b/include/sway/desktop/transaction.h @@ -38,11 +38,17 @@ void transaction_notify_view_ready_by_serial(struct sway_view *view, /** * Notify the transaction system that a view is ready for the new layout, but - * identifying the instruction by width and height rather than by serial. + * identifying the instruction by geometry rather than by serial. * * This is used by xwayland views, as they don't have serials. */ -void transaction_notify_view_ready_by_size(struct sway_view *view, - int width, int height); +void transaction_notify_view_ready_by_geometry(struct sway_view *view, + double x, double y, int width, int height); + +/** + * Unconditionally notify the transaction system that a view is ready for the + * new layout. + */ +void transaction_notify_view_ready_immediately(struct sway_view *view); #endif diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 0d0e0635a..e186bf897 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -510,17 +510,27 @@ void transaction_notify_view_ready_by_serial(struct sway_view *view, } } -void transaction_notify_view_ready_by_size(struct sway_view *view, - int width, int height) { +void transaction_notify_view_ready_by_geometry(struct sway_view *view, + double x, double y, int width, int height) { struct sway_transaction_instruction *instruction = view->container->node.instruction; if (instruction != NULL && + (int)instruction->container_state.content_x == (int)x && + (int)instruction->container_state.content_y == (int)y && instruction->container_state.content_width == width && instruction->container_state.content_height == height) { set_instruction_ready(instruction); } } +void transaction_notify_view_ready_immediately(struct sway_view *view) { + struct sway_transaction_instruction *instruction = + view->container->node.instruction; + if (instruction != NULL) { + set_instruction_ready(instruction); + } +} + void transaction_commit_dirty(void) { if (!server.dirty_nodes->length) { return; diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 03f372416..4d133a126 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -302,8 +302,7 @@ static void handle_commit(struct wl_listener *listener, void *data) { memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box)); desktop_damage_view(view); transaction_commit_dirty(); - transaction_notify_view_ready_by_size(view, - new_geo.width, new_geo.height); + transaction_notify_view_ready_immediately(view); } else { memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box)); } diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index cee0ab104..186502b2d 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c @@ -401,8 +401,8 @@ static void handle_commit(struct wl_listener *listener, void *data) { if (view->container->node.instruction) { get_geometry(view, &view->geometry); - transaction_notify_view_ready_by_size(view, - state->width, state->height); + transaction_notify_view_ready_by_geometry(view, + xsurface->x, xsurface->y, state->width, state->height); } else { struct wlr_box new_geo; get_geometry(view, &new_geo); @@ -418,8 +418,8 @@ static void handle_commit(struct wl_listener *listener, void *data) { memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box)); desktop_damage_view(view); transaction_commit_dirty(); - transaction_notify_view_ready_by_size(view, - new_geo.width, new_geo.height); + transaction_notify_view_ready_by_geometry(view, + xsurface->x, xsurface->y, new_geo.width, new_geo.height); } else { memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box)); }