From f7290007b2ddb1e0df90e5941fd538f7286bb523 Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Mon, 21 Feb 2022 20:03:25 -0500 Subject: [PATCH] Fix ambiguity of 0 serial for surface configures There is a bug where the transaction code will still wait for a client commit even though the instruction configure is unsuccessful. Unfortunately a serial of 0 is both used as a valid serial and to denote an unsuccessful commit. Fix this my making relevant configure functions return a boolean and taking in a serial pointer. --- include/sway/tree/view.h | 8 ++++---- sway/desktop/transaction.c | 30 +++++++++++++++++------------- sway/desktop/xdg_shell.c | 11 ++++++----- sway/desktop/xwayland.c | 18 +++++++++++------- sway/tree/view.c | 9 +++++---- 5 files changed, 43 insertions(+), 33 deletions(-) diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 95708a049..d1eadcbf5 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -38,8 +38,8 @@ struct sway_view_impl { const char *(*get_string_prop)(struct sway_view *view, enum sway_view_prop prop); uint32_t (*get_int_prop)(struct sway_view *view, enum sway_view_prop prop); - uint32_t (*configure)(struct sway_view *view, double lx, double ly, - int width, int height); + bool (*configure)(struct sway_view *view, uint32_t *serial, + double lx, double ly, int width, int height); void (*set_activated)(struct sway_view *view, bool activated); void (*set_tiled)(struct sway_view *view, bool tiled); void (*set_fullscreen)(struct sway_view *view, bool fullscreen); @@ -244,8 +244,8 @@ const char *view_get_shell(struct sway_view *view); void view_get_constraints(struct sway_view *view, double *min_width, double *max_width, double *min_height, double *max_height); -uint32_t view_configure(struct sway_view *view, double lx, double ly, int width, - int height); +bool view_configure(struct sway_view *view, uint32_t *serial, + double lx, double ly, int width, int height); bool view_inhibit_idle(struct sway_view *view); diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index f5a3a053f..062b286e4 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -405,24 +405,28 @@ static void transaction_commit(struct sway_transaction *transaction) { bool hidden = node_is_view(node) && !node->destroying && !view_is_visible(node->sway_container->view); if (should_configure(node, instruction)) { - instruction->serial = view_configure(node->sway_container->view, + bool successful = view_configure(node->sway_container->view, + &instruction->serial, instruction->container_state.content_x, instruction->container_state.content_y, instruction->container_state.content_width, instruction->container_state.content_height); - if (!hidden) { - instruction->waiting = true; - ++transaction->num_waiting; - } - // From here on we are rendering a saved buffer of the view, which - // means we can send a frame done event to make the client redraw it - // as soon as possible. Additionally, this is required if a view is - // mapping and its default geometry doesn't intersect an output. - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - wlr_surface_send_frame_done( - node->sway_container->view->surface, &now); + if (successful) { + if (!hidden) { + instruction->waiting = true; + ++transaction->num_waiting; + } + + // From here on we are rendering a saved buffer of the view, which + // means we can send a frame done event to make the client redraw it + // as soon as possible. Additionally, this is required if a view is + // mapping and its default geometry doesn't intersect an output. + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + wlr_surface_send_frame_done( + node->sway_container->view->surface, &now); + } } if (!hidden && node_is_view(node) && wl_list_empty(&node->sway_container->view->saved_buffers)) { diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 6af67207b..e0db7556c 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -141,15 +141,16 @@ static const char *get_string_prop(struct sway_view *view, } } -static uint32_t configure(struct sway_view *view, double lx, double ly, - int width, int height) { +static bool configure(struct sway_view *view, uint32_t *serial, + double lx, double ly, int width, int height) { struct sway_xdg_shell_view *xdg_shell_view = xdg_shell_view_from_view(view); if (xdg_shell_view == NULL) { - return 0; + return false; } - return wlr_xdg_toplevel_set_size(view->wlr_xdg_toplevel, - width, height); + + *serial = wlr_xdg_toplevel_set_size(top, width, height); + return true; } static void set_activated(struct sway_view *view, bool activated) { diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 2f11b5fc4..dd23c24b5 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c @@ -246,18 +246,18 @@ static uint32_t get_int_prop(struct sway_view *view, enum sway_view_prop prop) { } } -static uint32_t configure(struct sway_view *view, double lx, double ly, int width, - int height) { +static bool configure(struct sway_view *view, uint32_t *serial, + double lx, double ly, int width, int height) { struct sway_xwayland_view *xwayland_view = xwayland_view_from_view(view); if (xwayland_view == NULL) { - return 0; + return false; } struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; wlr_xwayland_surface_configure(xsurface, lx, ly, width, height); // xwayland doesn't give us a serial for the configure - return 0; + return true; } static void set_activated(struct sway_view *view, bool activated) { @@ -544,13 +544,17 @@ static void handle_request_configure(struct wl_listener *listener, void *data) { view->natural_height = ev->height; container_floating_resize_and_center(view->container); - configure(view, view->container->pending.content_x, + bool successful = configure(view, NULL, + view->container->pending.content_x, view->container->pending.content_y, view->container->pending.content_width, view->container->pending.content_height); - node_set_dirty(&view->container->node); + + if (successful) { + node_set_dirty(&view->container->node); + } } else { - configure(view, view->container->current.content_x, + configure(view, NULL, view->container->current.content_x, view->container->current.content_y, view->container->current.content_width, view->container->current.content_height); diff --git a/sway/tree/view.c b/sway/tree/view.c index 7d9e038d2..9213d34ad 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -164,12 +164,13 @@ void view_get_constraints(struct sway_view *view, double *min_width, } } -uint32_t view_configure(struct sway_view *view, double lx, double ly, int width, - int height) { +bool view_configure(struct sway_view *view, uint32_t *serial, + double lx, double ly, int width, int height) { if (view->impl->configure) { - return view->impl->configure(view, lx, ly, width, height); + return view->impl->configure(view, serial, lx, ly, width, height); } - return 0; + + return false; } bool view_inhibit_idle(struct sway_view *view) {