From fe21a175760856b64fa11083d7bc98e00db659a2 Mon Sep 17 00:00:00 2001 From: Nathan Reiner Date: Sat, 22 Apr 2023 00:31:50 +0200 Subject: use ext-session-lock protocol --- Makefile | 16 +- config.mk | 2 +- protocols/wlr-layer-shell-unstable.xml | 390 --------------------------------- wayland.h | 3 +- wlock.c | 65 +++--- 5 files changed, 44 insertions(+), 432 deletions(-) delete mode 100644 protocols/wlr-layer-shell-unstable.xml diff --git a/Makefile b/Makefile index 6d998b3..261f886 100644 --- a/Makefile +++ b/Makefile @@ -1,23 +1,17 @@ include config.mk -PROTOCOLS = wlr-layer-shell-protocol.c xdg-shell-protocol.c +PROTOCOLS = ext-session-lock-protocol.c SRC = wlock.c util.c drw.c wayland.c OBJ = ${SRC:.c=.o} ${PROTOCOLS:.c=.o} -WLR_LAYER_SHELL = ./protocols/wlr-layer-shell-unstable.xml default_target: wlock -wlr-layer-shell-protocol.h: - wayland-scanner client-header < ${WLR_LAYER_SHELL} > $@ +ext-session-lock-protocol.h: + wayland-scanner client-header < ${EXT_SESSION_LOCK} > $@ -wlr-layer-shell-protocol.c: wlr-layer-shell-protocol.h - wayland-scanner private-code < ${WLR_LAYER_SHELL} > $@ +ext-session-lock-protocol.c: ext-session-lock-protocol.h + wayland-scanner private-code < ${EXT_SESSION_LOCK} > $@ -xdg-shell-protocol.h: - wayland-scanner client-header < ${XDG_SHELL} > $@ - -xdg-shell-protocol.c: xdg-shell-protocol.h - wayland-scanner private-code < ${XDG_SHELL} > $@ .c.o: ${CC} -c $< ${CPPFLAGS} diff --git a/config.mk b/config.mk index b703df8..0c43a1a 100644 --- a/config.mk +++ b/config.mk @@ -1,4 +1,4 @@ LDFLAGS = -lfreetype -lwayland-client -lrt -lxkbcommon -lm -lgrapheme -lcrypt CPPFLAGS = -DHAVE_SHADOW_H -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/harfbuzz -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/sysprof-4 -pthread -XDG_SHELL = /usr/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml +EXT_SESSION_LOCK = /usr/share/wayland-protocols/staging/ext-session-lock/ext-session-lock-v1.xml CC = cc diff --git a/protocols/wlr-layer-shell-unstable.xml b/protocols/wlr-layer-shell-unstable.xml deleted file mode 100644 index d62fd51..0000000 --- a/protocols/wlr-layer-shell-unstable.xml +++ /dev/null @@ -1,390 +0,0 @@ - - - - Copyright © 2017 Drew DeVault - - Permission to use, copy, modify, distribute, and sell this - software and its documentation for any purpose is hereby granted - without fee, provided that the above copyright notice appear in - all copies and that both that copyright notice and this permission - notice appear in supporting documentation, and that the name of - the copyright holders not be used in advertising or publicity - pertaining to distribution of the software without specific, - written prior permission. The copyright holders make no - representations about the suitability of this software for any - purpose. It is provided "as is" without express or implied - warranty. - - THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY - SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, - ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF - THIS SOFTWARE. - - - - - Clients can use this interface to assign the surface_layer role to - wl_surfaces. Such surfaces are assigned to a "layer" of the output and - rendered with a defined z-depth respective to each other. They may also be - anchored to the edges and corners of a screen and specify input handling - semantics. This interface should be suitable for the implementation of - many desktop shell components, and a broad number of other applications - that interact with the desktop. - - - - - Create a layer surface for an existing surface. This assigns the role of - layer_surface, or raises a protocol error if another role is already - assigned. - - Creating a layer surface from a wl_surface which has a buffer attached - or committed is a client error, and any attempts by a client to attach - or manipulate a buffer prior to the first layer_surface.configure call - must also be treated as errors. - - After creating a layer_surface object and setting it up, the client - must perform an initial commit without any buffer attached. - The compositor will reply with a layer_surface.configure event. - The client must acknowledge it and is then allowed to attach a buffer - to map the surface. - - You may pass NULL for output to allow the compositor to decide which - output to use. Generally this will be the one that the user most - recently interacted with. - - Clients can specify a namespace that defines the purpose of the layer - surface. - - - - - - - - - - - - - - - - - These values indicate which layers a surface can be rendered in. They - are ordered by z depth, bottom-most first. Traditional shell surfaces - will typically be rendered between the bottom and top layers. - Fullscreen shell surfaces are typically rendered at the top layer. - Multiple surfaces can share a single layer, and ordering within a - single layer is undefined. - - - - - - - - - - - - - This request indicates that the client will not use the layer_shell - object any more. Objects that have been created through this instance - are not affected. - - - - - - - An interface that may be implemented by a wl_surface, for surfaces that - are designed to be rendered as a layer of a stacked desktop-like - environment. - - Layer surface state (layer, size, anchor, exclusive zone, - margin, interactivity) is double-buffered, and will be applied at the - time wl_surface.commit of the corresponding wl_surface is called. - - Attaching a null buffer to a layer surface unmaps it. - - Unmapping a layer_surface means that the surface cannot be shown by the - compositor until it is explicitly mapped again. The layer_surface - returns to the state it had right after layer_shell.get_layer_surface. - The client can re-map the surface by performing a commit without any - buffer attached, waiting for a configure event and handling it as usual. - - - - - Sets the size of the surface in surface-local coordinates. The - compositor will display the surface centered with respect to its - anchors. - - If you pass 0 for either value, the compositor will assign it and - inform you of the assignment in the configure event. You must set your - anchor to opposite edges in the dimensions you omit; not doing so is a - protocol error. Both values are 0 by default. - - Size is double-buffered, see wl_surface.commit. - - - - - - - - Requests that the compositor anchor the surface to the specified edges - and corners. If two orthogonal edges are specified (e.g. 'top' and - 'left'), then the anchor point will be the intersection of the edges - (e.g. the top left corner of the output); otherwise the anchor point - will be centered on that edge, or in the center if none is specified. - - Anchor is double-buffered, see wl_surface.commit. - - - - - - - Requests that the compositor avoids occluding an area with other - surfaces. The compositor's use of this information is - implementation-dependent - do not assume that this region will not - actually be occluded. - - A positive value is only meaningful if the surface is anchored to one - edge or an edge and both perpendicular edges. If the surface is not - anchored, anchored to only two perpendicular edges (a corner), anchored - to only two parallel edges or anchored to all edges, a positive value - will be treated the same as zero. - - A positive zone is the distance from the edge in surface-local - coordinates to consider exclusive. - - Surfaces that do not wish to have an exclusive zone may instead specify - how they should interact with surfaces that do. If set to zero, the - surface indicates that it would like to be moved to avoid occluding - surfaces with a positive exclusive zone. If set to -1, the surface - indicates that it would not like to be moved to accommodate for other - surfaces, and the compositor should extend it all the way to the edges - it is anchored to. - - For example, a panel might set its exclusive zone to 10, so that - maximized shell surfaces are not shown on top of it. A notification - might set its exclusive zone to 0, so that it is moved to avoid - occluding the panel, but shell surfaces are shown underneath it. A - wallpaper or lock screen might set their exclusive zone to -1, so that - they stretch below or over the panel. - - The default value is 0. - - Exclusive zone is double-buffered, see wl_surface.commit. - - - - - - - Requests that the surface be placed some distance away from the anchor - point on the output, in surface-local coordinates. Setting this value - for edges you are not anchored to has no effect. - - The exclusive zone includes the margin. - - Margin is double-buffered, see wl_surface.commit. - - - - - - - - - - Types of keyboard interaction possible for layer shell surfaces. The - rationale for this is twofold: (1) some applications are not interested - in keyboard events and not allowing them to be focused can improve the - desktop experience; (2) some applications will want to take exclusive - keyboard focus. - - - - - This value indicates that this surface is not interested in keyboard - events and the compositor should never assign it the keyboard focus. - - This is the default value, set for newly created layer shell surfaces. - - This is useful for e.g. desktop widgets that display information or - only have interaction with non-keyboard input devices. - - - - - Request exclusive keyboard focus if this surface is above the shell surface layer. - - For the top and overlay layers, the seat will always give - exclusive keyboard focus to the top-most layer which has keyboard - interactivity set to exclusive. If this layer contains multiple - surfaces with keyboard interactivity set to exclusive, the compositor - determines the one receiving keyboard events in an implementation- - defined manner. In this case, no guarantee is made when this surface - will receive keyboard focus (if ever). - - For the bottom and background layers, the compositor is allowed to use - normal focus semantics. - - This setting is mainly intended for applications that need to ensure - they receive all keyboard events, such as a lock screen or a password - prompt. - - - - - This requests the compositor to allow this surface to be focused and - unfocused by the user in an implementation-defined manner. The user - should be able to unfocus this surface even regardless of the layer - it is on. - - Typically, the compositor will want to use its normal mechanism to - manage keyboard focus between layer shell surfaces with this setting - and regular toplevels on the desktop layer (e.g. click to focus). - Nevertheless, it is possible for a compositor to require a special - interaction to focus or unfocus layer shell surfaces (e.g. requiring - a click even if focus follows the mouse normally, or providing a - keybinding to switch focus between layers). - - This setting is mainly intended for desktop shell components (e.g. - panels) that allow keyboard interaction. Using this option can allow - implementing a desktop shell that can be fully usable without the - mouse. - - - - - - - Set how keyboard events are delivered to this surface. By default, - layer shell surfaces do not receive keyboard events; this request can - be used to change this. - - This setting is inherited by child surfaces set by the get_popup - request. - - Layer surfaces receive pointer, touch, and tablet events normally. If - you do not want to receive them, set the input region on your surface - to an empty region. - - Keyboard interactivity is double-buffered, see wl_surface.commit. - - - - - - - This assigns an xdg_popup's parent to this layer_surface. This popup - should have been created via xdg_surface::get_popup with the parent set - to NULL, and this request must be invoked before committing the popup's - initial state. - - See the documentation of xdg_popup for more details about what an - xdg_popup is and how it is used. - - - - - - - When a configure event is received, if a client commits the - surface in response to the configure event, then the client - must make an ack_configure request sometime before the commit - request, passing along the serial of the configure event. - - If the client receives multiple configure events before it - can respond to one, it only has to ack the last configure event. - - A client is not required to commit immediately after sending - an ack_configure request - it may even ack_configure several times - before its next surface commit. - - A client may send multiple ack_configure requests before committing, but - only the last request sent before a commit indicates which configure - event the client really is responding to. - - - - - - - This request destroys the layer surface. - - - - - - The configure event asks the client to resize its surface. - - Clients should arrange their surface for the new states, and then send - an ack_configure request with the serial sent in this configure event at - some point before committing the new surface. - - The client is free to dismiss all but the last configure event it - received. - - The width and height arguments specify the size of the window in - surface-local coordinates. - - The size is a hint, in the sense that the client is free to ignore it if - it doesn't resize, pick a smaller size (to satisfy aspect ratio or - resize in steps of NxM pixels). If the client picks a smaller size and - is anchored to two opposite anchors (e.g. 'top' and 'bottom'), the - surface will be centered on this axis. - - If the width or height arguments are zero, it means the client should - decide its own window dimension. - - - - - - - - - The closed event is sent by the compositor when the surface will no - longer be shown. The output may have been destroyed or the user may - have asked for it to be removed. Further changes to the surface will be - ignored. The client should destroy the resource after receiving this - event, and create a new surface if they so choose. - - - - - - - - - - - - - - - - - - - - - - Change the layer that the surface is rendered on. - - Layer is double-buffered, see wl_surface.commit. - - - - - diff --git a/wayland.h b/wayland.h index 2f6a6ba..577955e 100644 --- a/wayland.h +++ b/wayland.h @@ -2,8 +2,7 @@ #define WAYLAND_H #include -#include "xdg-shell-protocol.h" -#include "wlr-layer-shell-protocol.h" +#include "ext-session-lock-protocol.h" int allocate_shm_file(size_t size); diff --git a/wlock.c b/wlock.c index ae8f153..8fb8262 100644 --- a/wlock.c +++ b/wlock.c @@ -18,6 +18,7 @@ #include #include +#include "ext-session-lock-protocol.h" #include "util.h" #include "drw.h" #include "config.h" @@ -39,8 +40,8 @@ typedef struct { struct wl_registry *registry; struct wl_compositor *compositor; struct wl_shm *shm; - struct zdwl_manager_v1 *dwl_manager; - struct zwlr_layer_shell_v1 *layer; + struct ext_session_lock_manager_v1 *lock_manager; + struct ext_session_lock_v1 *session_lock; struct wl_seat *seat; struct wl_keyboard *keyboard; struct xkb_context *xkb_context; @@ -65,7 +66,7 @@ struct Monitor { Canvas *canvas; struct wl_output *output; struct wl_surface *surface; - struct zwlr_layer_surface_v1 *wlr_surface; + struct ext_session_lock_surface_v1 *lock_surface; Monitor *next; }; @@ -78,7 +79,8 @@ static void remove_monitor(Monitor *mon); static void registry_global(void *data, struct wl_registry *wl_registry, uint32_t name, const char *interface, uint32_t version); static void remove_global(void *data, struct wl_registry *wl_registry, uint32_t name); static void seat_capabilities(void *data, struct wl_seat *seat, uint32_t capabilities); -static void wlr_layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, uint32_t serial, uint32_t w, uint32_t h); +static void session_lock_surface_configure(void *data, struct ext_session_lock_surface_v1 *surface, uint32_t serial, uint32_t width, uint32_t height); +static void lock_failed(void *data, struct ext_session_lock_v1 *lock); static void keyboard_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int32_t fd, uint32_t size); static void keyboard_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state); static void keyboard_repeat_info(void *data, struct wl_keyboard *keyboard, int32_t rate, int32_t delay); @@ -92,11 +94,6 @@ static const struct wl_registry_listener registry_listnener = { .global_remove = remove_global }; -static const struct zwlr_layer_surface_v1_listener wlr_layer_surface_listener = { - .closed = dummy, - .configure = wlr_layer_surface_configure, -}; - static const struct wl_seat_listener seat_listener = { .capabilities = seat_capabilities, .name = dummy, @@ -111,6 +108,15 @@ static const struct wl_keyboard_listener keyboard_listener = { .repeat_info = keyboard_repeat_info, }; +static const struct ext_session_lock_surface_v1_listener session_lock_surface_listener = { + .configure = session_lock_surface_configure +}; + +static const struct ext_session_lock_v1_listener session_lock_listener = { + .locked = dummy, + .finished = lock_failed, +}; + Client client = { 0 }; Monitor *monitors = 0; char input_field[MAX_LINE_LENGTH] = ""; @@ -183,7 +189,7 @@ void remove_monitor(Monitor *mon) { wl_surface_destroy(mon->surface); - zwlr_layer_surface_v1_destroy(mon->wlr_surface); + ext_session_lock_surface_v1_destroy(mon->lock_surface); wl_output_destroy(mon->output); free_drw(mon->canvas); free(mon); @@ -198,7 +204,7 @@ registry_global(void *data, struct wl_registry *wl_registry, uint32_t name, cons match_then_bind(client.shm, wl_shm_interface, 1) or_match match_then_bind(client.compositor, wl_compositor_interface, 4) - or_match match_then_bind(client.layer, zwlr_layer_shell_v1_interface, 1) + or_match match_then_bind(client.lock_manager, ext_session_lock_manager_v1_interface, 1) or_match match_then_bind(client.seat, wl_seat_interface, 7) wl_seat_add_listener(client.seat, &seat_listener, &client); or_match match_then_bind(output, wl_output_interface, 1) @@ -250,13 +256,13 @@ seat_capabilities(void *data, struct wl_seat *seat, uint32_t capabilities) void -wlr_layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, uint32_t serial, uint32_t w, uint32_t h) +session_lock_surface_configure(void *data, struct ext_session_lock_surface_v1 *surface, uint32_t serial, uint32_t w, uint32_t h) { Monitor *mon = data; mon->width = w; mon->height = h; - zwlr_layer_surface_v1_ack_configure(surface, serial); + ext_session_lock_surface_v1_ack_configure(mon->lock_surface, serial); if (mon->canvas == 0) { mon->canvas = create_drw(client.shm, mon->width, mon->height); @@ -270,6 +276,13 @@ wlr_layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, u } +void +lock_failed(void *data, struct ext_session_lock_v1 *lock) +{ + die("failed to lock session"); +} + + void keyboard_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int32_t fd, uint32_t size) { @@ -377,22 +390,10 @@ handle_keyboard_event() void register_monitor(Monitor *mon) { - char namespace[] = "dmenu-wl"; - uint32_t layer = ZWLR_LAYER_SHELL_V1_LAYER_TOP; - uint32_t anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | - ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | - ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | - ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; - mon->surface = wl_compositor_create_surface(client.compositor); - mon->wlr_surface = zwlr_layer_shell_v1_get_layer_surface(client.layer, mon->surface, mon->output, layer, namespace); - - zwlr_layer_surface_v1_set_exclusive_zone(mon->wlr_surface, -1); - zwlr_layer_surface_v1_set_keyboard_interactivity(monitors->wlr_surface, 1); - - zwlr_layer_surface_v1_add_listener(mon->wlr_surface, &wlr_layer_surface_listener, mon); - - zwlr_layer_surface_v1_set_anchor(mon->wlr_surface, anchor); + mon->lock_surface = ext_session_lock_v1_get_lock_surface(client.session_lock, mon->surface, mon->output); + ext_session_lock_surface_v1_add_listener(mon->lock_surface, &session_lock_surface_listener, mon); + wl_display_roundtrip(client.display); wl_surface_commit(mon->surface); wl_display_roundtrip(client.display); @@ -402,6 +403,7 @@ register_monitor(Monitor *mon) void setup() { + printf("HERE 0\n"); Monitor *mon; username_font = create_font(fontpath, username_fontsize * 1.5); clock_font = create_font(fontpath, clock_fontsize * 1.5); @@ -410,6 +412,10 @@ setup() client.display = wl_display_connect(0); client.registry = wl_display_get_registry(client.display); wl_registry_add_listener(client.registry, ®istry_listnener, &client); + + wl_display_roundtrip(client.display); + client.session_lock = ext_session_lock_manager_v1_lock(client.lock_manager); + ext_session_lock_v1_add_listener(client.session_lock, &session_lock_listener, &client); wl_display_roundtrip(client.display); for (mon = monitors; mon; mon = mon->next) { @@ -499,5 +505,8 @@ main(int argc, char *argv[]) } } + ext_session_lock_v1_unlock_and_destroy(client.session_lock); + ext_session_lock_manager_v1_destroy(client.lock_manager); + wl_display_dispatch(client.display); } -- cgit v1.2.3-70-g09d2