transaction: split acking and committing

This fixes the problems with e.g. wlr_xdg_toplevel_set_resizing()
interfering with serial checking and causing false timeouts.
This commit is contained in:
Kirill Primak 2021-07-30 11:58:04 +03:00
parent 258f167528
commit ce8dae9328
5 changed files with 52 additions and 15 deletions

View file

@ -35,20 +35,26 @@ void transaction_commit_dirty(void);
void transaction_commit_dirty_client(void);
/**
* Notify the transaction system that a view is ready for the new layout.
*
* When all views in the transaction are ready, the layout will be applied.
* Notify the transaction system that a view has acknowledged a configure.
*/
void transaction_notify_view_ready_by_serial(struct sway_view *view,
void transaction_notify_view_acked_by_serial(struct sway_view *view,
uint32_t serial);
/**
* Notify the transaction system that a view is ready for the new layout, but
* Notify the transaction system that a view has acknowledged a configure, but
* identifying the instruction by geometry rather than by serial.
*
* This is used by xwayland views, as they don't have serials.
* This is used by Xwayland views, as they don't have serials.
*/
void transaction_notify_view_ready_by_geometry(struct sway_view *view,
void transaction_notify_view_acked_by_geometry(struct sway_view *view,
double x, double y, int width, int height);
/**
* Notify the transaction system that a view is ready for the new layout. This
* call has no effect if the view hasn't acknowledged a configure yet.
*
* When all views in the transaction are ready, the layout will be applied.
*/
void transaction_notify_view_ready(struct sway_view *view);
#endif

View file

@ -116,6 +116,7 @@ struct sway_view {
struct sway_xdg_shell_view {
struct sway_view view;
struct wl_listener ack_configure;
struct wl_listener commit;
struct wl_listener request_move;
struct wl_listener request_resize;

View file

@ -35,6 +35,8 @@ struct sway_transaction_instruction {
struct sway_container_state container_state;
};
uint32_t serial;
bool acked;
bool ready;
bool server_request;
bool waiting;
};
@ -444,6 +446,8 @@ static void set_instruction_ready(
struct sway_transaction_instruction *instruction) {
struct sway_transaction *transaction = instruction->transaction;
instruction->ready = true;
if (debug.txn_timings) {
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
@ -468,16 +472,16 @@ static void set_instruction_ready(
transaction_progress();
}
void transaction_notify_view_ready_by_serial(struct sway_view *view,
void transaction_notify_view_acked_by_serial(struct sway_view *view,
uint32_t serial) {
struct sway_transaction_instruction *instruction =
view->container->node.instruction;
if (instruction != NULL && instruction->serial == serial) {
set_instruction_ready(instruction);
instruction->acked = true;
}
}
void transaction_notify_view_ready_by_geometry(struct sway_view *view,
void transaction_notify_view_acked_by_geometry(struct sway_view *view,
double x, double y, int width, int height) {
struct sway_transaction_instruction *instruction =
view->container->node.instruction;
@ -486,7 +490,17 @@ void transaction_notify_view_ready_by_geometry(struct sway_view *view,
(int)instruction->container_state.content_y == (int)y &&
instruction->container_state.content_width == width &&
instruction->container_state.content_height == height) {
set_instruction_ready(instruction);
instruction->acked = true;
}
}
void transaction_notify_view_ready(struct sway_view *view) {
struct sway_transaction_instruction *instruction =
view->container->node.instruction;
if (instruction != NULL && !instruction->ready) {
if (instruction->acked) {
set_instruction_ready(instruction);
}
}
}

View file

@ -279,6 +279,17 @@ static const struct sway_view_impl view_impl = {
.destroy = destroy,
};
static void handle_ack_configure(struct wl_listener *listener, void *data) {
struct sway_xdg_shell_view *xdg_shell_view =
wl_container_of(listener, xdg_shell_view, ack_configure);
struct sway_view *view = &xdg_shell_view->view;
struct wlr_xdg_surface_configure *configure = data;
if (view->container->node.instruction) {
transaction_notify_view_acked_by_serial(view,
configure->serial);
}
}
static void handle_commit(struct wl_listener *listener, void *data) {
struct sway_xdg_shell_view *xdg_shell_view =
wl_container_of(listener, xdg_shell_view, commit);
@ -308,8 +319,7 @@ static void handle_commit(struct wl_listener *listener, void *data) {
}
if (view->container->node.instruction) {
transaction_notify_view_ready_by_serial(view,
xdg_surface->configure_serial);
transaction_notify_view_ready(view);
}
view_damage_from(view);
@ -418,6 +428,7 @@ static void handle_unmap(struct wl_listener *listener, void *data) {
view_unmap(view);
wl_list_remove(&xdg_shell_view->ack_configure.link);
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);
@ -458,6 +469,10 @@ static void handle_map(struct wl_listener *listener, void *data) {
transaction_commit_dirty();
xdg_shell_view->ack_configure.notify = handle_ack_configure;
wl_signal_add(&xdg_surface->events.ack_configure,
&xdg_shell_view->ack_configure);
xdg_shell_view->commit.notify = handle_commit;
wl_signal_add(&xdg_surface->surface->events.commit,
&xdg_shell_view->commit);

View file

@ -418,8 +418,9 @@ static void handle_commit(struct wl_listener *listener, void *data) {
}
if (view->container->node.instruction) {
transaction_notify_view_ready_by_geometry(view,
xsurface->x, xsurface->y, state->width, state->height);
transaction_notify_view_acked_by_geometry(view,
xsurface->x, xsurface->y, state->width, state->height);
transaction_notify_view_ready(view);
}
view_damage_from(view);