aboutsummaryrefslogtreecommitdiff
path: root/sway/desktop
diff options
context:
space:
mode:
authorKenny Levinsen <kl@kl.wtf>2021-02-14 20:56:57 +0100
committerTudor Brindus <me@tbrindus.ca>2021-02-15 16:58:19 -0500
commit37d7bc69986f0c22eef629d5e0446f22800fa515 (patch)
tree7afe6b36cf64aa53c98f7dc739ead84c2892ece7 /sway/desktop
parentc88f7ad1d0a59fc0994ae353551133733de6ee07 (diff)
downloadsway-37d7bc69986f0c22eef629d5e0446f22800fa515.tar.xz
transaction: Only wait for ack from visible views
Transactions currently wait for all configures to be acked, regardless fo what they were sent to. This includes views that are hidden in tabbed or stacked containers. If these views do not ack the configure in response to a single frame callback, they can cause transaction timeouts. Check if a container is hidden before registering the configure serial and saving any view buffers. Closes: https://github.com/swaywm/sway/issues/6023
Diffstat (limited to 'sway/desktop')
-rw-r--r--sway/desktop/transaction.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c
index ead662f9..bea9d539 100644
--- a/sway/desktop/transaction.c
+++ b/sway/desktop/transaction.c
@@ -35,6 +35,7 @@ struct sway_transaction_instruction {
struct sway_container_state container_state;
};
uint32_t serial;
+ bool waiting;
};
static struct sway_transaction *transaction_create(void) {
@@ -420,13 +421,18 @@ static void transaction_commit(struct sway_transaction *transaction) {
struct sway_transaction_instruction *instruction =
transaction->instructions->items[i];
struct sway_node *node = instruction->node;
+ bool hidden = node_is_view(node) &&
+ !view_is_visible(node->sway_container->view);
if (should_configure(node, instruction)) {
instruction->serial = view_configure(node->sway_container->view,
instruction->container_state.content_x,
instruction->container_state.content_y,
instruction->container_state.content_width,
instruction->container_state.content_height);
- ++transaction->num_waiting;
+ 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
@@ -437,7 +443,8 @@ static void transaction_commit(struct sway_transaction *transaction) {
wlr_surface_send_frame_done(
node->sway_container->view->surface, &now);
}
- if (node_is_view(node) && wl_list_empty(&node->sway_container->view->saved_buffers)) {
+ if (!hidden && node_is_view(node) &&
+ wl_list_empty(&node->sway_container->view->saved_buffers)) {
view_save_buffer(node->sway_container->view);
memcpy(&node->sway_container->view->saved_geometry,
&node->sway_container->view->geometry,
@@ -490,7 +497,8 @@ static void set_instruction_ready(
}
// If the transaction has timed out then its num_waiting will be 0 already.
- if (transaction->num_waiting > 0 && --transaction->num_waiting == 0) {
+ if (instruction->waiting && transaction->num_waiting > 0 &&
+ --transaction->num_waiting == 0) {
sway_log(SWAY_DEBUG, "Transaction %p is ready", transaction);
wl_event_source_timer_update(transaction->timer, 0);
}