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);
|
void transaction_commit_dirty_client(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify the transaction system that a view is ready for the new layout.
|
* Notify the transaction system that a view has acknowledged a configure.
|
||||||
*
|
|
||||||
* When all views in the transaction are ready, the layout will be applied.
|
|
||||||
*/
|
*/
|
||||||
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);
|
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.
|
* 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);
|
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
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,7 @@ struct sway_view {
|
||||||
struct sway_xdg_shell_view {
|
struct sway_xdg_shell_view {
|
||||||
struct sway_view view;
|
struct sway_view view;
|
||||||
|
|
||||||
|
struct wl_listener ack_configure;
|
||||||
struct wl_listener commit;
|
struct wl_listener commit;
|
||||||
struct wl_listener request_move;
|
struct wl_listener request_move;
|
||||||
struct wl_listener request_resize;
|
struct wl_listener request_resize;
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@ struct sway_transaction_instruction {
|
||||||
struct sway_container_state container_state;
|
struct sway_container_state container_state;
|
||||||
};
|
};
|
||||||
uint32_t serial;
|
uint32_t serial;
|
||||||
|
bool acked;
|
||||||
|
bool ready;
|
||||||
bool server_request;
|
bool server_request;
|
||||||
bool waiting;
|
bool waiting;
|
||||||
};
|
};
|
||||||
|
|
@ -444,6 +446,8 @@ static void set_instruction_ready(
|
||||||
struct sway_transaction_instruction *instruction) {
|
struct sway_transaction_instruction *instruction) {
|
||||||
struct sway_transaction *transaction = instruction->transaction;
|
struct sway_transaction *transaction = instruction->transaction;
|
||||||
|
|
||||||
|
instruction->ready = true;
|
||||||
|
|
||||||
if (debug.txn_timings) {
|
if (debug.txn_timings) {
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
|
@ -468,16 +472,16 @@ static void set_instruction_ready(
|
||||||
transaction_progress();
|
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) {
|
uint32_t serial) {
|
||||||
struct sway_transaction_instruction *instruction =
|
struct sway_transaction_instruction *instruction =
|
||||||
view->container->node.instruction;
|
view->container->node.instruction;
|
||||||
if (instruction != NULL && instruction->serial == serial) {
|
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) {
|
double x, double y, int width, int height) {
|
||||||
struct sway_transaction_instruction *instruction =
|
struct sway_transaction_instruction *instruction =
|
||||||
view->container->node.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 &&
|
(int)instruction->container_state.content_y == (int)y &&
|
||||||
instruction->container_state.content_width == width &&
|
instruction->container_state.content_width == width &&
|
||||||
instruction->container_state.content_height == height) {
|
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,
|
.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) {
|
static void handle_commit(struct wl_listener *listener, void *data) {
|
||||||
struct sway_xdg_shell_view *xdg_shell_view =
|
struct sway_xdg_shell_view *xdg_shell_view =
|
||||||
wl_container_of(listener, xdg_shell_view, commit);
|
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) {
|
if (view->container->node.instruction) {
|
||||||
transaction_notify_view_ready_by_serial(view,
|
transaction_notify_view_ready(view);
|
||||||
xdg_surface->configure_serial);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
view_damage_from(view);
|
view_damage_from(view);
|
||||||
|
|
@ -418,6 +428,7 @@ static void handle_unmap(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
view_unmap(view);
|
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->commit.link);
|
||||||
wl_list_remove(&xdg_shell_view->new_popup.link);
|
wl_list_remove(&xdg_shell_view->new_popup.link);
|
||||||
wl_list_remove(&xdg_shell_view->request_fullscreen.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();
|
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;
|
xdg_shell_view->commit.notify = handle_commit;
|
||||||
wl_signal_add(&xdg_surface->surface->events.commit,
|
wl_signal_add(&xdg_surface->surface->events.commit,
|
||||||
&xdg_shell_view->commit);
|
&xdg_shell_view->commit);
|
||||||
|
|
|
||||||
|
|
@ -418,8 +418,9 @@ static void handle_commit(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (view->container->node.instruction) {
|
if (view->container->node.instruction) {
|
||||||
transaction_notify_view_ready_by_geometry(view,
|
transaction_notify_view_acked_by_geometry(view,
|
||||||
xsurface->x, xsurface->y, state->width, state->height);
|
xsurface->x, xsurface->y, state->width, state->height);
|
||||||
|
transaction_notify_view_ready(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
view_damage_from(view);
|
view_damage_from(view);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue