From 4c17a62c237ecad62cd71ff6d263007c2cb7ac68 Mon Sep 17 00:00:00 2001 From: Kirill Primak Date: Fri, 30 Jul 2021 14:17:01 +0300 Subject: [PATCH] transaction: lock/unlock views --- sway/desktop/transaction.c | 45 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index a65f4ab20..2d101ab7b 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -216,7 +216,6 @@ static void transaction_add_node(struct sway_transaction *transaction, static void apply_output_state(struct sway_output *output, struct sway_output_state *state) { - output_damage_whole(output); list_free(output->current.workspaces); memcpy(&output->current, state, sizeof(struct sway_output_state)); output_damage_whole(output); @@ -224,7 +223,6 @@ static void apply_output_state(struct sway_output *output, static void apply_workspace_state(struct sway_workspace *ws, struct sway_workspace_state *state) { - output_damage_whole(ws->current.output); list_free(ws->current.floating); list_free(ws->current.tiling); memcpy(&ws->current, state, sizeof(struct sway_workspace_state)); @@ -284,6 +282,39 @@ static void transaction_apply(struct sway_transaction *transaction) { "(%.1f frames if 60Hz)", transaction, ms, ms / (1000.0f / 60)); } + // Damage the old layout state + for (int i = 0; i < transaction->instructions->length; ++i) { + struct sway_transaction_instruction *instruction = + transaction->instructions->items[i]; + struct sway_node *node = instruction->node; + + switch (node->type) { + case N_ROOT: + break; + case N_OUTPUT: + output_damage_whole(node->sway_output); + break; + case N_WORKSPACE: + output_damage_whole(node->sway_workspace->output); + break; + case N_CONTAINER: + container_damage_whole(node->sway_container); + break; + } + } + + // Unlock views to commit instruction states + for (int i = 0; i < transaction->instructions->length; ++i) { + struct sway_transaction_instruction *instruction = + transaction->instructions->items[i]; + struct sway_node *node = instruction->node; + + if (node->type == N_CONTAINER && node->sway_container->view && + node->sway_container->view->surface_locked) { + view_unlock_cached(node->sway_container->view); + } + } + // Apply the instruction state to the node's current state for (int i = 0; i < transaction->instructions->length; ++i) { struct sway_transaction_instruction *instruction = @@ -402,6 +433,10 @@ static void transaction_commit(struct sway_transaction *transaction) { wlr_surface_send_frame_done( node->sway_container->view->surface, &now); } + if (!hidden && node_is_view(node) && + !node->sway_container->view->surface_locked) { + view_lock_pending(node->sway_container->view); + } node->instruction = instruction; } transaction->num_configures = transaction->num_waiting; @@ -500,6 +535,12 @@ void transaction_notify_view_ready(struct sway_view *view) { if (instruction != NULL && !instruction->ready) { if (instruction->acked) { set_instruction_ready(instruction); + } else { + // If this is not the commit we needed, force the view + // to send another one as soon as possible. + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + wlr_surface_send_frame_done(view->surface, &now); } } }