mirror of
https://github.com/swaywm/sway.git
synced 2026-04-23 06:46:27 -04:00
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:
parent
258f167528
commit
ce8dae9328
5 changed files with 52 additions and 15 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue