From d07f07fac27e5480d22ef60d034f02959e2b12b5 Mon Sep 17 00:00:00 2001 From: Daniel De Graaf Date: Sun, 13 Jun 2021 13:17:01 -0400 Subject: [PATCH] safe screen locking interface --- include/swaylock.h | 2 + main.c | 11 +++ meson.build | 1 + wp-screenlocker-unstable-v1.xml | 117 ++++++++++++++++++++++++++++++++ 4 files changed, 131 insertions(+) create mode 100644 wp-screenlocker-unstable-v1.xml diff --git a/include/swaylock.h b/include/swaylock.h index 3993fe5aa..6a2f7700a 100644 --- a/include/swaylock.h +++ b/include/swaylock.h @@ -79,6 +79,8 @@ struct swaylock_state { struct wl_subcompositor *subcompositor; struct zwlr_layer_shell_v1 *layer_shell; struct zwlr_input_inhibit_manager_v1 *input_inhibit_manager; + struct zwp_screenlocker_v1 *locker; + struct zwp_screenlocker_lock_v1 *locker_lock; struct wl_shm *shm; struct wl_list surfaces; struct wl_list images; diff --git a/main.c b/main.c index a8bd10654..a68a832cf 100644 --- a/main.c +++ b/main.c @@ -23,6 +23,7 @@ #include "pool-buffer.h" #include "seat.h" #include "swaylock.h" +#include "wp-screenlocker-unstable-v1-client-protocol.h" #include "wlr-input-inhibitor-unstable-v1-client-protocol.h" #include "wlr-layer-shell-unstable-v1-client-protocol.h" #include "xdg-output-unstable-v1-client-protocol.h" @@ -344,6 +345,11 @@ static void handle_global(void *data, struct wl_registry *registry, create_layer_surface(surface); wl_display_roundtrip(state->display); } + } else if (strcmp(interface, zwp_screenlocker_v1_interface.name) == 0) { + state->locker = wl_registry_bind( + registry, name, &zwp_screenlocker_v1_interface, 1); + state->locker_lock = zwp_screenlocker_v1_lock(state->locker); + zwp_screenlocker_lock_v1_set_persistent(state->locker_lock); } } @@ -1086,6 +1092,11 @@ static void display_in(int fd, short mask, void *data) { static void comm_in(int fd, short mask, void *data) { if (read_comm_reply()) { + if (state.locker_lock) { + zwp_screenlocker_lock_v1_unlock(state.locker_lock); + // ensure compositor sees this immediately + wl_display_roundtrip(state.display); + } // Authentication succeeded state.run_display = false; } else { diff --git a/meson.build b/meson.build index 62c188aa6..ffe64d233 100644 --- a/meson.build +++ b/meson.build @@ -88,6 +88,7 @@ client_protocols = [ [wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'], ['wlr-layer-shell-unstable-v1.xml'], ['wlr-input-inhibitor-unstable-v1.xml'], + ['wp-screenlocker-unstable-v1.xml'], ] foreach p : client_protocols diff --git a/wp-screenlocker-unstable-v1.xml b/wp-screenlocker-unstable-v1.xml new file mode 100644 index 000000000..41a2d254b --- /dev/null +++ b/wp-screenlocker-unstable-v1.xml @@ -0,0 +1,117 @@ + + + + + This interface provides notification of screen lock/unlock events and + (if supported) acting as a screenlocker. + + This is a privileged protocol; clients do not need access to this + protocol if they only want to display windows on the locked desktop. + + + + + + + + + This event will be sent on creation if the screen is currently locked. + + Windows on the unlocked desktop may still be visible due to a locking + animation. Frame callbacks should be used to identify when specific + surfaces are no longer visible. + + + + + + Windows on the locked desktop may still be visible due to a locking + animation. Frame callbacks should be used to identify when specific + surfaces are no longer visible. + + + + + + A new screen-locker should be started as soon as possible in order to + allow the user to unlock the session. + + + + + + Requesting a new lock handle will succeed if this client has permission + to lock the screen and either the screen is not currently locked or the + original locker of the screen is no longer present. If the screen was + not previously locked, the lock will be created as a temporary lock; see + zwp_screenlocker_lock_v1.set_persistent to change this. If a persistent + lock was abandoned, the lock will start out persistent. + + + + + + + + + This object is inert and should be destroyed. + + TODO: should the reason be an enum? Possible values: permission_denied, locker_exists. + + + + + + + The lock handle is active and only the locked desktop is visible on all + outputs. If a compositor implements a locking animation or similar + effect that results in both the locked and unlocked desktops being + visible, this event is sent after the effect completes. + + + + + + This avoids the screen unlocking if the client is killed or otherwise + disconnects without calling either set_temporary or unlock. It is valid + to call this on a newly created lock handle without waiting for an + event. + + This may be called immediately on creation of the lock handle or at any + point prior to calling unlock. For example, a lock triggered due to idle + may delay enabling persistance for a brief period after triggering the + lock where an immediate resumption of user activity does not require + authentication. + + + + + + This is intended for lockers that do not require authenticating or which + do not want to risk leaving the session in a locked state if the locking + process disconnects. + + + + + + Let the compositor know that it should unlock the screen. + + It is valid to call this on a newly created lock handle without waiting + for an event; this will either cancel the lock or do nothing if the lock + handle is inert. + + After this request has been sent by the client, this object will become + inert and should be destroyed. + + + + + + Destroying an active lock handle without first unlocking it will abandon + the lock, resulting in either a wp_screenlocker.lock_abandoned event or + an immediate unlock depending on if the lock is persistent. + + + +