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.
This commit is contained in:
Alexander Orzechowski 2022-02-21 20:03:25 -05:00
parent 85d1c98476
commit f7290007b2
5 changed files with 43 additions and 33 deletions

View file

@ -38,8 +38,8 @@ struct sway_view_impl {
const char *(*get_string_prop)(struct sway_view *view, const char *(*get_string_prop)(struct sway_view *view,
enum sway_view_prop prop); enum sway_view_prop prop);
uint32_t (*get_int_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, bool (*configure)(struct sway_view *view, uint32_t *serial,
int width, int height); double lx, double ly, int width, int height);
void (*set_activated)(struct sway_view *view, bool activated); void (*set_activated)(struct sway_view *view, bool activated);
void (*set_tiled)(struct sway_view *view, bool tiled); void (*set_tiled)(struct sway_view *view, bool tiled);
void (*set_fullscreen)(struct sway_view *view, bool fullscreen); 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, void view_get_constraints(struct sway_view *view, double *min_width,
double *max_width, double *min_height, double *max_height); double *max_width, double *min_height, double *max_height);
uint32_t view_configure(struct sway_view *view, double lx, double ly, int width, bool view_configure(struct sway_view *view, uint32_t *serial,
int height); double lx, double ly, int width, int height);
bool view_inhibit_idle(struct sway_view *view); bool view_inhibit_idle(struct sway_view *view);

View file

@ -405,24 +405,28 @@ static void transaction_commit(struct sway_transaction *transaction) {
bool hidden = node_is_view(node) && !node->destroying && bool hidden = node_is_view(node) && !node->destroying &&
!view_is_visible(node->sway_container->view); !view_is_visible(node->sway_container->view);
if (should_configure(node, instruction)) { 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_x,
instruction->container_state.content_y, instruction->container_state.content_y,
instruction->container_state.content_width, instruction->container_state.content_width,
instruction->container_state.content_height); 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 if (successful) {
// means we can send a frame done event to make the client redraw it if (!hidden) {
// as soon as possible. Additionally, this is required if a view is instruction->waiting = true;
// mapping and its default geometry doesn't intersect an output. ++transaction->num_waiting;
struct timespec now; }
clock_gettime(CLOCK_MONOTONIC, &now);
wlr_surface_send_frame_done( // From here on we are rendering a saved buffer of the view, which
node->sway_container->view->surface, &now); // 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) && if (!hidden && node_is_view(node) &&
wl_list_empty(&node->sway_container->view->saved_buffers)) { wl_list_empty(&node->sway_container->view->saved_buffers)) {

View file

@ -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, static bool configure(struct sway_view *view, uint32_t *serial,
int width, int height) { double lx, double ly, int width, int height) {
struct sway_xdg_shell_view *xdg_shell_view = struct sway_xdg_shell_view *xdg_shell_view =
xdg_shell_view_from_view(view); xdg_shell_view_from_view(view);
if (xdg_shell_view == NULL) { 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) { static void set_activated(struct sway_view *view, bool activated) {

View file

@ -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, static bool configure(struct sway_view *view, uint32_t *serial,
int height) { double lx, double ly, int width, int height) {
struct sway_xwayland_view *xwayland_view = xwayland_view_from_view(view); struct sway_xwayland_view *xwayland_view = xwayland_view_from_view(view);
if (xwayland_view == NULL) { if (xwayland_view == NULL) {
return 0; return false;
} }
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
wlr_xwayland_surface_configure(xsurface, lx, ly, width, height); wlr_xwayland_surface_configure(xsurface, lx, ly, width, height);
// xwayland doesn't give us a serial for the configure // xwayland doesn't give us a serial for the configure
return 0; return true;
} }
static void set_activated(struct sway_view *view, bool activated) { 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; view->natural_height = ev->height;
container_floating_resize_and_center(view->container); 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_y,
view->container->pending.content_width, view->container->pending.content_width,
view->container->pending.content_height); view->container->pending.content_height);
node_set_dirty(&view->container->node);
if (successful) {
node_set_dirty(&view->container->node);
}
} else { } 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_y,
view->container->current.content_width, view->container->current.content_width,
view->container->current.content_height); view->container->current.content_height);

View file

@ -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, bool view_configure(struct sway_view *view, uint32_t *serial,
int height) { double lx, double ly, int width, int height) {
if (view->impl->configure) { 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) { bool view_inhibit_idle(struct sway_view *view) {