ext-session-lock: Do not use commit listener to arrange

Arranging lock surfaces rely on the sway_output width and height being
updated, but these are only updated after the commit has been completed
and all commit listeners have executed. This means that the lock
surfaces will not be appropriately scaled to match a change in output
dimensions, and may reveal what is under the lock background.

Replace the implicit arrange through the output commit listener with an
explicit arrange after the output configuration is finalized.

This might have regressed by other transition away from output commit
listeners for other arrange tasks, but even then it would have
erroneously relied on signalling order.

(cherry-picked from 785a459a55)
This commit is contained in:
Kenny Levinsen 2024-09-18 00:46:29 +02:00 committed by Simon Ser
parent 5686be82c6
commit 7f9baa05fa
3 changed files with 20 additions and 17 deletions

6
include/sway/lock.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef _SWAY_LOCK_H
#define _SWAY_LOCK_H
void arrange_locks(void);
#endif

View file

@ -15,6 +15,7 @@
#include "sway/desktop/transaction.h" #include "sway/desktop/transaction.h"
#include "sway/input/cursor.h" #include "sway/input/cursor.h"
#include "sway/layers.h" #include "sway/layers.h"
#include "sway/lock.h"
#include "sway/output.h" #include "sway/output.h"
#include "sway/server.h" #include "sway/server.h"
#include "sway/tree/arrange.h" #include "sway/tree/arrange.h"
@ -971,6 +972,7 @@ static bool apply_resolved_output_configs(struct matched_output_config *configs,
} }
arrange_root(); arrange_root();
arrange_locks();
update_output_manager_config(&server); update_output_manager_config(&server);
transaction_commit_dirty(); transaction_commit_dirty();

View file

@ -8,6 +8,7 @@
#include "sway/layers.h" #include "sway/layers.h"
#include "sway/output.h" #include "sway/output.h"
#include "sway/server.h" #include "sway/server.h"
#include "sway/lock.h"
struct sway_session_lock_output { struct sway_session_lock_output {
struct wlr_scene_tree *tree; struct wlr_scene_tree *tree;
@ -19,7 +20,6 @@ struct sway_session_lock_output {
struct wl_list link; // sway_session_lock::outputs struct wl_list link; // sway_session_lock::outputs
struct wl_listener destroy; struct wl_listener destroy;
struct wl_listener commit;
struct wlr_session_lock_surface_v1 *surface; struct wlr_session_lock_surface_v1 *surface;
@ -89,6 +89,17 @@ static void lock_output_reconfigure(struct sway_session_lock_output *output) {
} }
} }
void arrange_locks(void) {
if (server.session_lock.lock == NULL) {
return;
}
struct sway_session_lock_output *lock_output;
wl_list_for_each(lock_output, &server.session_lock.lock->outputs, link) {
lock_output_reconfigure(lock_output);
}
}
static void handle_new_surface(struct wl_listener *listener, void *data) { static void handle_new_surface(struct wl_listener *listener, void *data) {
struct sway_session_lock *lock = wl_container_of(listener, lock, new_surface); struct sway_session_lock *lock = wl_container_of(listener, lock, new_surface);
struct wlr_session_lock_surface_v1 *lock_surface = data; struct wlr_session_lock_surface_v1 *lock_surface = data;
@ -125,7 +136,6 @@ static void sway_session_lock_output_destroy(struct sway_session_lock_output *ou
wl_list_remove(&output->surface_map.link); wl_list_remove(&output->surface_map.link);
} }
wl_list_remove(&output->commit.link);
wl_list_remove(&output->destroy.link); wl_list_remove(&output->destroy.link);
wl_list_remove(&output->link); wl_list_remove(&output->link);
@ -138,18 +148,6 @@ static void lock_node_handle_destroy(struct wl_listener *listener, void *data) {
sway_session_lock_output_destroy(output); sway_session_lock_output_destroy(output);
} }
static void lock_output_handle_commit(struct wl_listener *listener, void *data) {
struct wlr_output_event_commit *event = data;
struct sway_session_lock_output *output =
wl_container_of(listener, output, commit);
if (event->state->committed & (
WLR_OUTPUT_STATE_MODE |
WLR_OUTPUT_STATE_SCALE |
WLR_OUTPUT_STATE_TRANSFORM)) {
lock_output_reconfigure(output);
}
}
static struct sway_session_lock_output *session_lock_output_create( static struct sway_session_lock_output *session_lock_output_create(
struct sway_session_lock *lock, struct sway_output *output) { struct sway_session_lock *lock, struct sway_output *output) {
struct sway_session_lock_output *lock_output = calloc(1, sizeof(*lock_output)); struct sway_session_lock_output *lock_output = calloc(1, sizeof(*lock_output));
@ -186,9 +184,6 @@ static struct sway_session_lock_output *session_lock_output_create(
lock_output->destroy.notify = lock_node_handle_destroy; lock_output->destroy.notify = lock_node_handle_destroy;
wl_signal_add(&tree->node.events.destroy, &lock_output->destroy); wl_signal_add(&tree->node.events.destroy, &lock_output->destroy);
lock_output->commit.notify = lock_output_handle_commit;
wl_signal_add(&output->wlr_output->events.commit, &lock_output->commit);
lock_output_reconfigure(lock_output); lock_output_reconfigure(lock_output);
wl_list_insert(&lock->outputs, &lock_output->link); wl_list_insert(&lock->outputs, &lock_output->link);