From 0668c0a3e8324b4919c1ab02a98caa0096f7c7de Mon Sep 17 00:00:00 2001 From: Kenny Levinsen Date: Thu, 23 May 2024 14:34:24 +0200 Subject: [PATCH] idle_inhibit: Ignore inhibitors when locked When a session is locked, no views are visible and there is no way to interact with the user session. This means that all inhibitors based on visibility - with the exception being inhibitors on the session lock surfaces themselves - become inert, allowing the session to go idle. The only inhibitor type on normal views that one could argue should remain active is INHIBIT_IDLE_OPEN, but for now we disable all view inhibitors regardless of type. --- sway/desktop/idle_inhibit_v1.c | 14 ++++++++++++++ sway/lock.c | 7 +++++++ sway/tree/view.c | 4 ++++ 3 files changed, 25 insertions(+) diff --git a/sway/desktop/idle_inhibit_v1.c b/sway/desktop/idle_inhibit_v1.c index f3af7aa1bc..d241cdaf44 100644 --- a/sway/desktop/idle_inhibit_v1.c +++ b/sway/desktop/idle_inhibit_v1.c @@ -1,5 +1,6 @@ #include #include +#include #include "log.h" #include "sway/desktop/idle_inhibit_v1.h" #include "sway/input/seat.h" @@ -103,6 +104,19 @@ void sway_idle_inhibit_v1_user_inhibitor_destroy( } bool sway_idle_inhibit_v1_is_active(struct sway_idle_inhibitor_v1 *inhibitor) { + if (server.session_lock.lock) { + // A session lock is active. In this case, only application inhibitors + // on the session lock surface can have any effect. + if (inhibitor->mode != INHIBIT_IDLE_APPLICATION) { + return false; + } + struct wlr_surface *wlr_surface = inhibitor->wlr_inhibitor->surface; + if (!wlr_session_lock_surface_v1_try_from_wlr_surface(wlr_surface)) { + return false; + } + return wlr_surface->mapped; + } + switch (inhibitor->mode) { case INHIBIT_IDLE_APPLICATION:; // If there is no view associated with the inhibitor, assume visible diff --git a/sway/lock.c b/sway/lock.c index 289e8ca46a..28618cc264 100644 --- a/sway/lock.c +++ b/sway/lock.c @@ -239,6 +239,9 @@ static void handle_unlock(struct wl_listener *listener, void *data) { struct sway_output *output = root->outputs->items[i]; arrange_layers(output); } + + // Views are now visible, so check if we need to activate inhibition again. + sway_idle_inhibit_v1_check_active(); } static void handle_abandon(struct wl_listener *listener, void *data) { @@ -302,6 +305,10 @@ static void handle_session_lock(struct wl_listener *listener, void *data) { wlr_session_lock_v1_send_locked(lock); server.session_lock.lock = sway_lock; + + // The lock screen covers everything, so check if any active inhibition got + // deactivated due to lost visibility. + sway_idle_inhibit_v1_check_active(); } static void handle_session_lock_destroy(struct wl_listener *listener, void *data) { diff --git a/sway/tree/view.c b/sway/tree/view.c index 4f757acf1d..6232070ce3 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -190,6 +190,10 @@ uint32_t view_configure(struct sway_view *view, double lx, double ly, int width, } bool view_inhibit_idle(struct sway_view *view) { + if (server.session_lock.lock) { + return false; + } + struct sway_idle_inhibitor_v1 *user_inhibitor = sway_idle_inhibit_v1_user_inhibitor_for_view(view);