Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package swaylock for openSUSE:Factory checked in at 2024-08-26 22:10:40 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/swaylock (Old) and /work/SRC/openSUSE:Factory/.swaylock.new.2698 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "swaylock" Mon Aug 26 22:10:40 2024 rev:10 rq:1196012 version:1.8.0 Changes: -------- --- /work/SRC/openSUSE:Factory/swaylock/swaylock.changes 2023-05-03 12:57:15.999828752 +0200 +++ /work/SRC/openSUSE:Factory/.swaylock.new.2698/swaylock.changes 2024-08-26 22:13:36.510481153 +0200 @@ -1,0 +2,27 @@ +Mon Aug 26 06:54:53 UTC 2024 - Michael Vetter <mvet...@suse.com> + +- Update to 1.8.0: + * Accept input while validating + * Link to manpage + * Synchronize highlight position between outputs + * Fix Wayland object leaks when outputs are destroyed + * Configure SIGUSR1 with sigaction() instead of signal() + * Make self-pipe nonblocking to prevent deadlock + * Fix output-specific images when output reappears + * Fix retry behaviour in while loop with mlock() + * Correct for image orientation when loading image + * Install pam config only if pam is enabled + * Check setgid too after dropping root + * Read password hash before fork + * Add --ready-fd + * Drop support for layer-shell + * Don't send READY=1 for readiness notifications + * Remove unnecessary wl_display_roundtrip() call + * Check initial wl_display_roundtrip() return value + * Document --ready-fd in man page + * build: bump version to v1.8.0 + * Don't drop the buffer until after surface commit + * Show cleared state when backspacing last character + * Clear password on ctrl+backpace and ctrl+delete + +------------------------------------------------------------------- Old: ---- swaylock-1.7.2.obscpio New: ---- swaylock-1.8.0.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ swaylock.spec ++++++ --- /var/tmp/diff_new_pack.vYmbTA/_old 2024-08-26 22:13:36.946499360 +0200 +++ /var/tmp/diff_new_pack.vYmbTA/_new 2024-08-26 22:13:36.946499360 +0200 @@ -1,7 +1,7 @@ # # spec file for package swaylock # -# Copyright (c) 2023 SUSE LLC +# Copyright (c) 2024 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: swaylock -Version: 1.7.2 +Version: 1.8.0 Release: 0 Summary: Screen locker for Wayland License: MIT ++++++ _service ++++++ --- /var/tmp/diff_new_pack.vYmbTA/_old 2024-08-26 22:13:36.978500696 +0200 +++ /var/tmp/diff_new_pack.vYmbTA/_new 2024-08-26 22:13:36.982500863 +0200 @@ -2,7 +2,7 @@ <service name="obs_scm" mode="manual"> <param name="scm">git</param> <param name="url">https://github.com/swaywm/swaylock.git</param> - <param name="revision">v1.7.2</param> + <param name="revision">v1.8.0</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> <param name="changesgenerate">disable</param> ++++++ swaylock-1.7.2.obscpio -> swaylock-1.8.0.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.7.2/README.md new/swaylock-1.8.0/README.md --- old/swaylock-1.7.2/README.md 2023-01-28 22:54:27.000000000 +0100 +++ new/swaylock-1.8.0/README.md 2024-08-23 22:39:33.000000000 +0200 @@ -1,13 +1,10 @@ # swaylock swaylock is a screen locking utility for Wayland compositors. It is compatible -with any Wayland compositor which implements one of the following Wayland -protocols: +with any Wayland compositor which implements the ext-session-lock-v1 Wayland +protocol. -- ext-session-lock-v1, or -- wlr-layer-shell and wlr-input-inhibitor - -See the man page, `swaylock(1)`, for instructions on using swaylock. +See the man page, [swaylock(1)](swaylock.1.scd), for instructions on using swaylock. ## Release Signatures diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.7.2/background-image.c new/swaylock-1.8.0/background-image.c --- old/swaylock-1.7.2/background-image.c 2023-01-28 22:54:27.000000000 +0100 +++ new/swaylock-1.8.0/background-image.c 2024-08-23 22:39:33.000000000 +0200 @@ -31,8 +31,12 @@ err->message); return NULL; } - image = gdk_cairo_image_surface_create_from_pixbuf(pixbuf); + // Correct for embedded image orientation; typical images are not + // rotated and will be handled efficiently + GdkPixbuf *oriented = gdk_pixbuf_apply_embedded_orientation(pixbuf); g_object_unref(pixbuf); + image = gdk_cairo_image_surface_create_from_pixbuf(oriented); + g_object_unref(oriented); #else image = cairo_image_surface_create_from_png(path); #endif // HAVE_GDK_PIXBUF diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.7.2/include/pool-buffer.h new/swaylock-1.8.0/include/pool-buffer.h --- old/swaylock-1.7.2/include/pool-buffer.h 2023-01-28 22:54:27.000000000 +0100 +++ new/swaylock-1.8.0/include/pool-buffer.h 2024-08-23 22:39:33.000000000 +0200 @@ -15,8 +15,10 @@ bool busy; }; +struct pool_buffer *create_buffer(struct wl_shm *shm, struct pool_buffer *buf, + int32_t width, int32_t height, uint32_t format); struct pool_buffer *get_next_buffer(struct wl_shm *shm, - struct pool_buffer pool[static 2], uint32_t width, uint32_t height); + struct pool_buffer pool[static 2], uint32_t width, uint32_t height); void destroy_buffer(struct pool_buffer *buffer); #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.7.2/include/swaylock.h new/swaylock-1.8.0/include/swaylock.h --- old/swaylock-1.7.2/include/swaylock.h 2023-01-28 22:54:27.000000000 +0100 +++ new/swaylock-1.8.0/include/swaylock.h 2024-08-23 22:39:33.000000000 +0200 @@ -7,16 +7,21 @@ #include "cairo.h" #include "pool-buffer.h" #include "seat.h" -#include "wlr-layer-shell-unstable-v1-client-protocol.h" +// Indicator state: status of authentication attempt enum auth_state { - AUTH_STATE_IDLE, - AUTH_STATE_CLEAR, - AUTH_STATE_INPUT, - AUTH_STATE_INPUT_NOP, - AUTH_STATE_BACKSPACE, - AUTH_STATE_VALIDATING, - AUTH_STATE_INVALID, + AUTH_STATE_IDLE, // nothing happening + AUTH_STATE_VALIDATING, // currently validating password + AUTH_STATE_INVALID, // displaying message: password was wrong +}; + +// Indicator state: status of password buffer / typing letters +enum input_state { + INPUT_STATE_IDLE, // nothing happening; other states decay to this after time + INPUT_STATE_CLEAR, // displaying message: password buffer was cleared + INPUT_STATE_LETTER, // pressed a key that input a letter + INPUT_STATE_BACKSPACE, // pressed backspace and removed a letter + INPUT_STATE_NEUTRAL, // pressed a key (like Ctrl) that did nothing }; struct swaylock_colorset { @@ -62,6 +67,7 @@ bool hide_keyboard_layout; bool show_failed_attempts; bool daemonize; + int ready_fd; bool indicator_idle_visible; }; @@ -73,13 +79,12 @@ struct swaylock_state { struct loop *eventloop; - struct loop_timer *clear_indicator_timer; // clears the indicator + struct loop_timer *input_idle_timer; // timer to reset input state to IDLE + struct loop_timer *auth_idle_timer; // timer to stop displaying AUTH_STATE_INVALID struct loop_timer *clear_password_timer; // clears the password buffer struct wl_display *display; struct wl_compositor *compositor; struct wl_subcompositor *subcompositor; - struct zwlr_layer_shell_v1 *layer_shell; - struct zwlr_input_inhibit_manager_v1 *input_inhibit_manager; struct wl_shm *shm; struct wl_list surfaces; struct wl_list images; @@ -88,7 +93,9 @@ struct swaylock_xkb xkb; cairo_surface_t *test_surface; cairo_t *test_cairo; // used to estimate font/text sizes - enum auth_state auth_state; + enum auth_state auth_state; // state of the authentication attempt + enum input_state input_state; // state of the password buffer and key inputs + uint32_t highlight_start; // position of highlight; 2048 = 1 full turn int failed_attempts; bool run_display, locked; struct ext_session_lock_manager_v1 *ext_session_lock_manager_v1; @@ -100,19 +107,20 @@ struct swaylock_state *state; struct wl_output *output; uint32_t output_global_name; - struct wl_surface *surface; - struct wl_surface *child; // surface made into subsurface + struct wl_surface *surface; // surface for background + struct wl_surface *child; // indicator surface made into subsurface struct wl_subsurface *subsurface; - struct zwlr_layer_surface_v1 *layer_surface; struct ext_session_lock_surface_v1 *ext_session_lock_surface_v1; - struct pool_buffer buffers[2]; struct pool_buffer indicator_buffers[2]; + bool created; bool frame_pending, dirty; uint32_t width, height; int32_t scale; enum wl_output_subpixel subpixel; char *output_name; struct wl_list link; + // Dimensions of last wl_buffer committed to background surface + int last_buffer_width, last_buffer_height; }; // There is exactly one swaylock_image for each -i argument @@ -130,7 +138,7 @@ void damage_surface(struct swaylock_surface *surface); void damage_state(struct swaylock_state *state); void clear_password_buffer(struct swaylock_password *pw); -void schedule_indicator_clear(struct swaylock_state *state); +void schedule_auth_idle(struct swaylock_state *state); void initialize_pw_backend(int argc, char **argv); void run_pw_backend_child(void); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.7.2/main.c new/swaylock-1.8.0/main.c --- old/swaylock-1.7.2/main.c 2023-01-28 22:54:27.000000000 +0100 +++ new/swaylock-1.8.0/main.c 2024-08-23 22:39:33.000000000 +0200 @@ -25,8 +25,6 @@ #include "pool-buffer.h" #include "seat.h" #include "swaylock.h" -#include "wlr-input-inhibitor-unstable-v1-client-protocol.h" -#include "wlr-layer-shell-unstable-v1-client-protocol.h" #include "ext-session-lock-v1-client-protocol.h" static uint32_t parse_color(const char *color) { @@ -96,24 +94,24 @@ static void destroy_surface(struct swaylock_surface *surface) { wl_list_remove(&surface->link); - if (surface->layer_surface != NULL) { - zwlr_layer_surface_v1_destroy(surface->layer_surface); - } if (surface->ext_session_lock_surface_v1 != NULL) { ext_session_lock_surface_v1_destroy(surface->ext_session_lock_surface_v1); } + if (surface->subsurface) { + wl_subsurface_destroy(surface->subsurface); + } + if (surface->child) { + wl_surface_destroy(surface->child); + } if (surface->surface != NULL) { wl_surface_destroy(surface->surface); } - destroy_buffer(&surface->buffers[0]); - destroy_buffer(&surface->buffers[1]); destroy_buffer(&surface->indicator_buffers[0]); destroy_buffer(&surface->indicator_buffers[1]); - wl_output_destroy(surface->output); + wl_output_release(surface->output); free(surface); } -static const struct zwlr_layer_surface_v1_listener layer_surface_listener; static const struct ext_session_lock_surface_v1_listener ext_session_lock_surface_v1_listener; static cairo_surface_t *select_image(struct swaylock_state *state, @@ -140,28 +138,10 @@ assert(surface->subsurface); wl_subsurface_set_sync(surface->subsurface); - if (state->ext_session_lock_v1) { - surface->ext_session_lock_surface_v1 = ext_session_lock_v1_get_lock_surface( - state->ext_session_lock_v1, surface->surface, surface->output); - ext_session_lock_surface_v1_add_listener(surface->ext_session_lock_surface_v1, - &ext_session_lock_surface_v1_listener, surface); - } else { - surface->layer_surface = zwlr_layer_shell_v1_get_layer_surface( - state->layer_shell, surface->surface, surface->output, - ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "lockscreen"); - - zwlr_layer_surface_v1_set_size(surface->layer_surface, 0, 0); - zwlr_layer_surface_v1_set_anchor(surface->layer_surface, - ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | - ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | - ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | - ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT); - zwlr_layer_surface_v1_set_exclusive_zone(surface->layer_surface, -1); - zwlr_layer_surface_v1_set_keyboard_interactivity( - surface->layer_surface, true); - zwlr_layer_surface_v1_add_listener(surface->layer_surface, - &layer_surface_listener, surface); - } + surface->ext_session_lock_surface_v1 = ext_session_lock_v1_get_lock_surface( + state->ext_session_lock_v1, surface->surface, surface->output); + ext_session_lock_surface_v1_add_listener(surface->ext_session_lock_surface_v1, + &ext_session_lock_surface_v1_listener, surface); if (surface_is_opaque(surface) && surface->state->args.mode != BACKGROUND_MODE_CENTER && @@ -173,33 +153,9 @@ wl_region_destroy(region); } - if (!state->ext_session_lock_v1) { - wl_surface_commit(surface->surface); - } -} - -static void layer_surface_configure(void *data, - struct zwlr_layer_surface_v1 *layer_surface, - uint32_t serial, uint32_t width, uint32_t height) { - struct swaylock_surface *surface = data; - surface->width = width; - surface->height = height; - zwlr_layer_surface_v1_ack_configure(layer_surface, serial); - render_frame_background(surface); - render_frame(surface); + surface->created = true; } -static void layer_surface_closed(void *data, - struct zwlr_layer_surface_v1 *layer_surface) { - struct swaylock_surface *surface = data; - destroy_surface(surface); -} - -static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { - .configure = layer_surface_configure, - .closed = layer_surface_closed, -}; - static void ext_session_lock_surface_v1_handle_configure(void *data, struct ext_session_lock_surface_v1 *lock_surface, uint32_t serial, uint32_t width, uint32_t height) { @@ -280,7 +236,10 @@ } static void handle_wl_output_done(void *data, struct wl_output *output) { - // Who cares + struct swaylock_surface *surface = data; + if (!surface->created && surface->state->run_display) { + create_surface(surface); + } } static void handle_wl_output_scale(void *data, struct wl_output *output, @@ -347,12 +306,6 @@ calloc(1, sizeof(struct swaylock_seat)); swaylock_seat->state = state; wl_seat_add_listener(seat, &seat_listener, swaylock_seat); - } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { - state->layer_shell = wl_registry_bind( - registry, name, &zwlr_layer_shell_v1_interface, 1); - } else if (strcmp(interface, zwlr_input_inhibit_manager_v1_interface.name) == 0) { - state->input_inhibit_manager = wl_registry_bind( - registry, name, &zwlr_input_inhibit_manager_v1_interface, 1); } else if (strcmp(interface, wl_output_interface.name) == 0) { struct swaylock_surface *surface = calloc(1, sizeof(struct swaylock_surface)); @@ -362,11 +315,6 @@ surface->output_global_name = name; wl_output_add_listener(surface->output, &_wl_output_listener, surface); wl_list_insert(&state->surfaces, &surface->link); - - if (state->run_display) { - create_surface(surface); - wl_display_roundtrip(state->display); - } } else if (strcmp(interface, ext_session_lock_manager_v1_interface.name) == 0) { state->ext_session_lock_manager_v1 = wl_registry_bind(registry, name, &ext_session_lock_manager_v1_interface, 1); @@ -579,6 +527,7 @@ {"debug", no_argument, NULL, 'd'}, {"ignore-empty-password", no_argument, NULL, 'e'}, {"daemonize", no_argument, NULL, 'f'}, + {"ready-fd", required_argument, NULL, 'R'}, {"help", no_argument, NULL, 'h'}, {"image", required_argument, NULL, 'i'}, {"disable-caps-lock-text", no_argument, NULL, 'L'}, @@ -645,6 +594,8 @@ "Show current count of failed authentication attempts.\n" " -f, --daemonize " "Detach from the controlling terminal after locking.\n" + " -R, --ready-fd <fd> " + "File descriptor to send readiness notifications to.\n" " -h, --help " "Show help message and quit.\n" " -i, --image [[<output>]:]<path> " @@ -754,7 +705,7 @@ optind = 1; while (1) { int opt_idx = 0; - c = getopt_long(argc, argv, "c:deFfhi:kKLlnrs:tuvC:", long_options, + c = getopt_long(argc, argv, "c:deFfhi:kKLlnrs:tuvC:R:", long_options, &opt_idx); if (c == -1) { break; @@ -788,6 +739,11 @@ state->args.daemonize = true; } break; + case 'R': + if (state) { + state->args.ready_fd = strtol(optarg, NULL, 10); + } + break; case 'i': if (state) { load_image(optarg, state); @@ -1122,7 +1078,7 @@ state.run_display = false; } else { state.auth_state = AUTH_STATE_INVALID; - schedule_indicator_clear(&state); + schedule_auth_idle(&state); ++state.failed_attempts; damage_state(&state); } @@ -1182,7 +1138,8 @@ .show_keyboard_layout = false, .hide_keyboard_layout = false, .show_failed_attempts = false, - .indicator_idle_visible = false + .indicator_idle_visible = false, + .ready_fd = -1, }; wl_list_init(&state.images); set_default_colors(&state.args.colors); @@ -1231,7 +1188,11 @@ if (pipe(sigusr_fds) != 0) { swaylock_log(LOG_ERROR, "Failed to pipe"); - return 1; + return EXIT_FAILURE; + } + if (fcntl(sigusr_fds[1], F_SETFL, O_NONBLOCK) == -1) { + swaylock_log(LOG_ERROR, "Failed to make pipe end nonblocking"); + return EXIT_FAILURE; } wl_list_init(&state.surfaces); @@ -1244,10 +1205,14 @@ "WAYLAND_DISPLAY environment variable."); return EXIT_FAILURE; } + state.eventloop = loop_create(); struct wl_registry *registry = wl_display_get_registry(state.display); wl_registry_add_listener(registry, ®istry_listener, &state); - wl_display_roundtrip(state.display); + if (wl_display_roundtrip(state.display) == -1) { + swaylock_log(LOG_ERROR, "wl_display_roundtrip() failed"); + return EXIT_FAILURE; + } if (!state.compositor) { swaylock_log(LOG_ERROR, "Missing wl_compositor"); @@ -1264,27 +1229,17 @@ return 1; } - if (state.ext_session_lock_manager_v1) { - swaylock_log(LOG_DEBUG, "Using ext-session-lock-v1"); - state.ext_session_lock_v1 = ext_session_lock_manager_v1_lock(state.ext_session_lock_manager_v1); - ext_session_lock_v1_add_listener(state.ext_session_lock_v1, - &ext_session_lock_v1_listener, &state); - } else if (state.layer_shell && state.input_inhibit_manager) { - swaylock_log(LOG_DEBUG, "Using wlr-layer-shell + wlr-input-inhibitor"); - zwlr_input_inhibit_manager_v1_get_inhibitor(state.input_inhibit_manager); - } else { - swaylock_log(LOG_ERROR, "Missing ext-session-lock-v1, wlr-layer-shell " - "and wlr-input-inhibitor"); + if (!state.ext_session_lock_manager_v1) { + swaylock_log(LOG_ERROR, "Missing ext-session-lock-v1"); return 1; } + state.ext_session_lock_v1 = ext_session_lock_manager_v1_lock(state.ext_session_lock_manager_v1); + ext_session_lock_v1_add_listener(state.ext_session_lock_v1, + &ext_session_lock_v1_listener, &state); + if (wl_display_roundtrip(state.display) == -1) { free(state.args.font); - if (state.input_inhibit_manager) { - swaylock_log(LOG_ERROR, "Exiting - failed to inhibit input:" - " is another lockscreen already running?"); - return 2; - } return 1; } @@ -1296,33 +1251,37 @@ create_surface(surface); } - if (state.ext_session_lock_manager_v1) { - while (!state.locked) { - if (wl_display_dispatch(state.display) < 0) { - swaylock_log(LOG_ERROR, "wl_display_dispatch() failed"); - return 2; - } - } - } else { - if (wl_display_roundtrip(state.display) < 0) { - swaylock_log(LOG_ERROR, "wl_display_roundtrip() failed"); + while (!state.locked) { + if (wl_display_dispatch(state.display) < 0) { + swaylock_log(LOG_ERROR, "wl_display_dispatch() failed"); return 2; } - state.locked = true; } + if (state.args.ready_fd >= 0) { + if (write(state.args.ready_fd, "\n", 1) != 1) { + swaylock_log(LOG_ERROR, "Failed to send readiness notification"); + return 2; + } + close(state.args.ready_fd); + state.args.ready_fd = -1; + } if (state.args.daemonize) { daemonize(); } - state.eventloop = loop_create(); loop_add_fd(state.eventloop, wl_display_get_fd(state.display), POLLIN, display_in, NULL); loop_add_fd(state.eventloop, get_comm_reply_fd(), POLLIN, comm_in, NULL); loop_add_fd(state.eventloop, sigusr_fds[0], POLLIN, term_in, NULL); - signal(SIGUSR1, do_sigusr); + + struct sigaction sa; + sa.sa_handler = do_sigusr; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + sigaction(SIGUSR1, &sa, NULL); state.run_display = true; while (state.run_display) { @@ -1333,10 +1292,8 @@ loop_poll(state.eventloop); } - if (state.ext_session_lock_v1) { - ext_session_lock_v1_unlock_and_destroy(state.ext_session_lock_v1); - wl_display_roundtrip(state.display); - } + ext_session_lock_v1_unlock_and_destroy(state.ext_session_lock_v1); + wl_display_roundtrip(state.display); free(state.args.font); cairo_destroy(state.test_cairo); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.7.2/meson.build new/swaylock-1.8.0/meson.build --- old/swaylock-1.7.2/meson.build 2023-01-28 22:54:27.000000000 +0100 +++ new/swaylock-1.8.0/meson.build 2024-08-23 22:39:33.000000000 +0200 @@ -1,7 +1,7 @@ project( 'swaylock', 'c', - version: '1.7.2', + version: '1.8.0', license: 'MIT', meson_version: '>=0.59.0', default_options: [ @@ -68,10 +68,7 @@ ) client_protocols = [ - wl_protocol_dir / 'stable/xdg-shell/xdg-shell.xml', wl_protocol_dir / 'staging/ext-session-lock/ext-session-lock-v1.xml', - 'wlr-layer-shell-unstable-v1.xml', - 'wlr-input-inhibitor-unstable-v1.xml', ] protos_src = [] @@ -130,10 +127,12 @@ install: true ) -install_data( - 'pam/swaylock', - install_dir: get_option('sysconfdir') / 'pam.d' -) +if libpam.found() + install_data( + 'pam/swaylock', + install_dir: get_option('sysconfdir') / 'pam.d' + ) +endif if scdoc.found() mandir = get_option('mandir') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.7.2/password-buffer.c new/swaylock-1.8.0/password-buffer.c --- old/swaylock-1.7.2/password-buffer.c 2023-01-28 22:54:27.000000000 +0100 +++ new/swaylock-1.8.0/password-buffer.c 2024-08-23 22:39:33.000000000 +0200 @@ -38,7 +38,6 @@ swaylock_log_errno(LOG_ERROR, "Unable to mlock() password memory."); return false; } - return false; } return true; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.7.2/password.c new/swaylock-1.8.0/password.c --- old/swaylock-1.7.2/password.c 2023-01-28 22:54:27.000000000 +0100 +++ new/swaylock-1.8.0/password.c 2024-08-23 22:39:33.000000000 +0200 @@ -46,28 +46,50 @@ pw->len += utf8_size; } -static void clear_indicator(void *data) { +static void set_input_idle(void *data) { struct swaylock_state *state = data; - state->clear_indicator_timer = NULL; + state->input_idle_timer = NULL; + state->input_state = INPUT_STATE_IDLE; + damage_state(state); +} + +static void set_auth_idle(void *data) { + struct swaylock_state *state = data; + state->auth_idle_timer = NULL; state->auth_state = AUTH_STATE_IDLE; damage_state(state); } -void schedule_indicator_clear(struct swaylock_state *state) { - if (state->clear_indicator_timer) { - loop_remove_timer(state->eventloop, state->clear_indicator_timer); +static void schedule_input_idle(struct swaylock_state *state) { + if (state->input_idle_timer) { + loop_remove_timer(state->eventloop, state->input_idle_timer); + } + state->input_idle_timer = loop_add_timer( + state->eventloop, 1500, set_input_idle, state); +} + +static void cancel_input_idle(struct swaylock_state *state) { + if (state->input_idle_timer) { + loop_remove_timer(state->eventloop, state->input_idle_timer); + state->input_idle_timer = NULL; } - state->clear_indicator_timer = loop_add_timer( - state->eventloop, 3000, clear_indicator, state); +} + +void schedule_auth_idle(struct swaylock_state *state) { + if (state->auth_idle_timer) { + loop_remove_timer(state->eventloop, state->auth_idle_timer); + } + state->auth_idle_timer = loop_add_timer( + state->eventloop, 3000, set_auth_idle, state); } static void clear_password(void *data) { struct swaylock_state *state = data; state->clear_password_timer = NULL; - state->auth_state = AUTH_STATE_CLEAR; + state->input_state = INPUT_STATE_CLEAR; + schedule_input_idle(state); clear_password_buffer(&state->password); damage_state(state); - schedule_indicator_clear(state); } static void schedule_password_clear(struct swaylock_state *state) { @@ -78,27 +100,39 @@ state->eventloop, 10000, clear_password, state); } +static void cancel_password_clear(struct swaylock_state *state) { + if (state->clear_password_timer) { + loop_remove_timer(state->eventloop, state->clear_password_timer); + state->clear_password_timer = NULL; + } +} + static void submit_password(struct swaylock_state *state) { if (state->args.ignore_empty && state->password.len == 0) { return; } + state->input_state = INPUT_STATE_IDLE; state->auth_state = AUTH_STATE_VALIDATING; + cancel_password_clear(state); + cancel_input_idle(state); if (!write_comm_request(&state->password)) { state->auth_state = AUTH_STATE_INVALID; - schedule_indicator_clear(state); + schedule_auth_idle(state); } damage_state(state); } +static void update_highlight(struct swaylock_state *state) { + // Advance a random amount between 1/4 and 3/4 of a full turn + state->highlight_start = + (state->highlight_start + (rand() % 1024) + 512) % 2048; +} + void swaylock_handle_key(struct swaylock_state *state, xkb_keysym_t keysym, uint32_t codepoint) { - // Ignore input events if validating - if (state->auth_state == AUTH_STATE_VALIDATING) { - return; - } switch (keysym) { case XKB_KEY_KP_Enter: /* fallthrough */ @@ -107,20 +141,29 @@ break; case XKB_KEY_Delete: case XKB_KEY_BackSpace: - if (backspace(&state->password)) { - state->auth_state = AUTH_STATE_BACKSPACE; + if (state->xkb.control) { + clear_password_buffer(&state->password); + state->input_state = INPUT_STATE_CLEAR; + cancel_password_clear(state); } else { - state->auth_state = AUTH_STATE_CLEAR; + if (backspace(&state->password) && state->password.len != 0) { + state->input_state = INPUT_STATE_BACKSPACE; + schedule_password_clear(state); + update_highlight(state); + } else { + state->input_state = INPUT_STATE_CLEAR; + cancel_password_clear(state); + } } + schedule_input_idle(state); damage_state(state); - schedule_indicator_clear(state); - schedule_password_clear(state); break; case XKB_KEY_Escape: clear_password_buffer(&state->password); - state->auth_state = AUTH_STATE_CLEAR; + state->input_state = INPUT_STATE_CLEAR; + cancel_password_clear(state); + schedule_input_idle(state); damage_state(state); - schedule_indicator_clear(state); break; case XKB_KEY_Caps_Lock: case XKB_KEY_Shift_L: @@ -133,10 +176,10 @@ case XKB_KEY_Alt_R: case XKB_KEY_Super_L: case XKB_KEY_Super_R: - state->auth_state = AUTH_STATE_INPUT_NOP; - damage_state(state); - schedule_indicator_clear(state); + state->input_state = INPUT_STATE_NEUTRAL; schedule_password_clear(state); + schedule_input_idle(state); + damage_state(state); break; case XKB_KEY_m: /* fallthrough */ case XKB_KEY_d: @@ -150,19 +193,21 @@ case XKB_KEY_u: if (state->xkb.control) { clear_password_buffer(&state->password); - state->auth_state = AUTH_STATE_CLEAR; + state->input_state = INPUT_STATE_CLEAR; + cancel_password_clear(state); + schedule_input_idle(state); damage_state(state); - schedule_indicator_clear(state); break; } // fallthrough default: if (codepoint) { append_ch(&state->password, codepoint); - state->auth_state = AUTH_STATE_INPUT; - damage_state(state); - schedule_indicator_clear(state); + state->input_state = INPUT_STATE_LETTER; schedule_password_clear(state); + schedule_input_idle(state); + update_highlight(state); + damage_state(state); } break; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.7.2/pool-buffer.c new/swaylock-1.8.0/pool-buffer.c --- old/swaylock-1.7.2/pool-buffer.c 2023-01-28 22:54:27.000000000 +0100 +++ new/swaylock-1.8.0/pool-buffer.c 2024-08-23 22:39:33.000000000 +0200 @@ -46,7 +46,7 @@ .release = buffer_release }; -static struct pool_buffer *create_buffer(struct wl_shm *shm, +struct pool_buffer *create_buffer(struct wl_shm *shm, struct pool_buffer *buf, int32_t width, int32_t height, uint32_t format) { uint32_t stride = width * 4; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.7.2/render.c new/swaylock-1.8.0/render.c --- old/swaylock-1.7.2/render.c 2023-01-28 22:54:27.000000000 +0100 +++ new/swaylock-1.8.0/render.c 2024-08-23 22:39:33.000000000 +0200 @@ -4,6 +4,7 @@ #include "cairo.h" #include "background-image.h" #include "swaylock.h" +#include "log.h" #define M_PI 3.14159265358979323846 const float TYPE_INDICATOR_RANGE = M_PI / 3.0f; @@ -11,12 +12,12 @@ static void set_color_for_state(cairo_t *cairo, struct swaylock_state *state, struct swaylock_colorset *colorset) { - if (state->auth_state == AUTH_STATE_VALIDATING) { + if (state->input_state == INPUT_STATE_CLEAR) { + cairo_set_source_u32(cairo, colorset->cleared); + } else if (state->auth_state == AUTH_STATE_VALIDATING) { cairo_set_source_u32(cairo, colorset->verifying); } else if (state->auth_state == AUTH_STATE_INVALID) { cairo_set_source_u32(cairo, colorset->wrong); - } else if (state->auth_state == AUTH_STATE_CLEAR) { - cairo_set_source_u32(cairo, colorset->cleared); } else { if (state->xkb.caps_lock && state->args.show_caps_lock_indicator) { cairo_set_source_u32(cairo, colorset->caps_lock); @@ -41,31 +42,43 @@ return; // not yet configured } - struct pool_buffer *buffer = get_next_buffer(state->shm, - surface->buffers, buffer_width, buffer_height); - if (buffer == NULL) { - return; - } + wl_surface_set_buffer_scale(surface->surface, surface->scale); - cairo_t *cairo = buffer->cairo; - cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST); + if (buffer_width != surface->last_buffer_width || + buffer_height != surface->last_buffer_height) { + struct pool_buffer buffer; + if (!create_buffer(state->shm, &buffer, buffer_width, buffer_height, + WL_SHM_FORMAT_ARGB8888)) { + swaylock_log(LOG_ERROR, + "Failed to create new buffer for frame background."); + return; + } - cairo_save(cairo); - cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); - cairo_set_source_u32(cairo, state->args.colors.background); - cairo_paint(cairo); - if (surface->image && state->args.mode != BACKGROUND_MODE_SOLID_COLOR) { - cairo_set_operator(cairo, CAIRO_OPERATOR_OVER); - render_background_image(cairo, surface->image, - state->args.mode, buffer_width, buffer_height); - } - cairo_restore(cairo); - cairo_identity_matrix(cairo); + cairo_t *cairo = buffer.cairo; + cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST); - wl_surface_set_buffer_scale(surface->surface, surface->scale); - wl_surface_attach(surface->surface, buffer->buffer, 0, 0); - wl_surface_damage_buffer(surface->surface, 0, 0, INT32_MAX, INT32_MAX); - wl_surface_commit(surface->surface); + cairo_save(cairo); + cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); + cairo_set_source_u32(cairo, state->args.colors.background); + cairo_paint(cairo); + if (surface->image && state->args.mode != BACKGROUND_MODE_SOLID_COLOR) { + cairo_set_operator(cairo, CAIRO_OPERATOR_OVER); + render_background_image(cairo, surface->image, + state->args.mode, buffer_width, buffer_height); + } + cairo_restore(cairo); + cairo_identity_matrix(cairo); + + wl_surface_attach(surface->surface, buffer.buffer, 0, 0); + wl_surface_damage_buffer(surface->surface, 0, 0, INT32_MAX, INT32_MAX); + wl_surface_commit(surface->surface); + destroy_buffer(&buffer); + + surface->last_buffer_width = buffer_width; + surface->last_buffer_height = buffer_height; + } else { + wl_surface_commit(surface->surface); + } } static void configure_font_drawing(cairo_t *cairo, struct swaylock_state *state, @@ -96,20 +109,20 @@ char *text = NULL; const char *layout_text = NULL; - if (state->args.show_indicator) { - switch (state->auth_state) { - case AUTH_STATE_VALIDATING: + bool draw_indicator = state->args.show_indicator && + (state->auth_state != AUTH_STATE_IDLE || + state->input_state != INPUT_STATE_IDLE || + state->args.indicator_idle_visible); + + if (draw_indicator) { + if (state->input_state == INPUT_STATE_CLEAR) { + // This message has highest priority + text = "Cleared"; + } else if (state->auth_state == AUTH_STATE_VALIDATING) { text = "Verifying"; - break; - case AUTH_STATE_INVALID: + } else if (state->auth_state == AUTH_STATE_INVALID) { text = "Wrong"; - break; - case AUTH_STATE_CLEAR: - text = "Cleared"; - break; - case AUTH_STATE_INPUT: - case AUTH_STATE_INPUT_NOP: - case AUTH_STATE_BACKSPACE: + } else { // Caps Lock has higher priority if (state->xkb.caps_lock && state->args.show_caps_lock_text) { text = "Caps Lock"; @@ -137,9 +150,6 @@ // will handle invalid index if none are active layout_text = xkb_keymap_layout_get_name(state->xkb.keymap, curr_layout); } - break; - default: - break; } } @@ -219,8 +229,7 @@ float type_indicator_border_thickness = TYPE_INDICATOR_BORDER_THICKNESS * surface->scale; - if (state->args.show_indicator && (state->auth_state != AUTH_STATE_IDLE || - state->args.indicator_idle_visible)) { + if (draw_indicator) { // Fill inner circle cairo_set_line_width(cairo, 0); cairo_arc(cairo, buffer_width / 2, buffer_diameter / 2, @@ -258,15 +267,13 @@ } // Typing indicator: Highlight random part on keypress - if (state->auth_state == AUTH_STATE_INPUT - || state->auth_state == AUTH_STATE_BACKSPACE) { - static double highlight_start = 0; - highlight_start += - (rand() % (int)(M_PI * 100)) / 100.0 + M_PI * 0.5; + if (state->input_state == INPUT_STATE_LETTER || + state->input_state == INPUT_STATE_BACKSPACE) { + double highlight_start = state->highlight_start * (M_PI / 1024.0); cairo_arc(cairo, buffer_width / 2, buffer_diameter / 2, arc_radius, highlight_start, highlight_start + TYPE_INDICATOR_RANGE); - if (state->auth_state == AUTH_STATE_INPUT) { + if (state->input_state == INPUT_STATE_LETTER) { if (state->xkb.caps_lock && state->args.show_caps_lock_indicator) { cairo_set_source_u32(cairo, state->args.colors.caps_lock_key_highlight); } else { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.7.2/shadow.c new/swaylock-1.8.0/shadow.c --- old/swaylock-1.7.2/shadow.c 2023-01-28 22:54:27.000000000 +0100 +++ new/swaylock-1.8.0/shadow.c 2024-08-23 22:39:33.000000000 +0200 @@ -1,4 +1,5 @@ #define _XOPEN_SOURCE // for crypt +#include <assert.h> #include <pwd.h> #include <shadow.h> #include <stdlib.h> @@ -14,40 +15,16 @@ #include "password-buffer.h" #include "swaylock.h" -void initialize_pw_backend(int argc, char **argv) { - if (geteuid() != 0) { - swaylock_log(LOG_ERROR, - "swaylock needs to be setuid to read /etc/shadow"); - exit(EXIT_FAILURE); - } - - if (!spawn_comm_child()) { - exit(EXIT_FAILURE); - } - - if (setgid(getgid()) != 0) { - swaylock_log_errno(LOG_ERROR, "Unable to drop root"); - exit(EXIT_FAILURE); - } - if (setuid(getuid()) != 0) { - swaylock_log_errno(LOG_ERROR, "Unable to drop root"); - exit(EXIT_FAILURE); - } - if (setuid(0) != -1) { - swaylock_log_errno(LOG_ERROR, "Unable to drop root (we shouldn't be " - "able to restore it after setuid)"); - exit(EXIT_FAILURE); - } -} +char *encpw = NULL; -void run_pw_backend_child(void) { +void initialize_pw_backend(int argc, char **argv) { /* This code runs as root */ struct passwd *pwent = getpwuid(getuid()); if (!pwent) { swaylock_log_errno(LOG_ERROR, "failed to getpwuid"); exit(EXIT_FAILURE); } - char *encpw = pwent->pw_passwd; + encpw = pwent->pw_passwd; if (strcmp(encpw, "x") == 0) { struct spwd *swent = getspnam(pwent->pw_name); if (!swent) { @@ -57,21 +34,34 @@ encpw = swent->sp_pwdp; } - /* We don't need any additional logging here because the parent process will - * also fail here and will handle logging for us. */ if (setgid(getgid()) != 0) { + swaylock_log_errno(LOG_ERROR, "Unable to drop root"); exit(EXIT_FAILURE); } if (setuid(getuid()) != 0) { + swaylock_log_errno(LOG_ERROR, "Unable to drop root"); exit(EXIT_FAILURE); } - if (setuid(0) != -1) { + if (setuid(0) != -1 || setgid(0) != -1) { + swaylock_log_errno(LOG_ERROR, "Unable to drop root (we shouldn't be " + "able to restore it after setuid/setgid)"); exit(EXIT_FAILURE); } /* This code does not run as root */ swaylock_log(LOG_DEBUG, "Prepared to authorize user %s", pwent->pw_name); + if (!spawn_comm_child()) { + exit(EXIT_FAILURE); + } + + /* Buffer is only used by the child */ + clear_buffer(encpw, strlen(encpw)); + encpw = NULL; +} + +void run_pw_backend_child(void) { + assert(encpw != NULL); while (1) { char *buf; ssize_t size = read_comm_request(&buf); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.7.2/swaylock.1.scd new/swaylock-1.8.0/swaylock.1.scd --- old/swaylock-1.7.2/swaylock.1.scd 2023-01-28 22:54:27.000000000 +0100 +++ new/swaylock-1.8.0/swaylock.1.scd 2024-08-23 22:39:33.000000000 +0200 @@ -35,6 +35,13 @@ Note: this is the default behavior of i3lock. +*-R, --ready-fd* <fd> + File descriptor to send readiness notifications to. + + When the session has been locked, a single newline is written to the FD. + At this point, the compositor guarantees that no security sensitive content + is visible on-screen. + *-h, --help* Show help message and quit. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.7.2/wlr-input-inhibitor-unstable-v1.xml new/swaylock-1.8.0/wlr-input-inhibitor-unstable-v1.xml --- old/swaylock-1.7.2/wlr-input-inhibitor-unstable-v1.xml 2023-01-28 22:54:27.000000000 +0100 +++ new/swaylock-1.8.0/wlr-input-inhibitor-unstable-v1.xml 1970-01-01 01:00:00.000000000 +0100 @@ -1,67 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<protocol name="wlr_input_inhibit_unstable_v1"> - <copyright> - Copyright © 2018 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. - </copyright> - - <interface name="zwlr_input_inhibit_manager_v1" version="1"> - <description summary="inhibits input events to other clients"> - Clients can use this interface to prevent input events from being sent to - any surfaces but its own, which is useful for example in lock screen - software. It is assumed that access to this interface will be locked down - to whitelisted clients by the compositor. - </description> - - <request name="get_inhibitor"> - <description summary="inhibit input to other clients"> - Activates the input inhibitor. As long as the inhibitor is active, the - compositor will not send input events to other clients. - </description> - <arg name="id" type="new_id" interface="zwlr_input_inhibitor_v1"/> - </request> - - <enum name="error"> - <entry name="already_inhibited" value="0" summary="an input inhibitor is already in use on the compositor"/> - </enum> - </interface> - - <interface name="zwlr_input_inhibitor_v1" version="1"> - <description summary="inhibits input to other clients"> - While this resource exists, input to clients other than the owner of the - inhibitor resource will not receive input events. The client that owns - this resource will receive all input events normally. The compositor will - also disable all of its own input processing (such as keyboard shortcuts) - while the inhibitor is active. - - The compositor may continue to send input events to selected clients, - such as an on-screen keyboard (via the input-method protocol). - </description> - - <request name="destroy" type="destructor"> - <description summary="destroy the input inhibitor object"> - Destroy the inhibitor and allow other clients to receive input. - </description> - </request> - </interface> -</protocol> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.7.2/wlr-layer-shell-unstable-v1.xml new/swaylock-1.8.0/wlr-layer-shell-unstable-v1.xml --- old/swaylock-1.7.2/wlr-layer-shell-unstable-v1.xml 2023-01-28 22:54:27.000000000 +0100 +++ new/swaylock-1.8.0/wlr-layer-shell-unstable-v1.xml 1970-01-01 01:00:00.000000000 +0100 @@ -1,285 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<protocol name="wlr_layer_shell_v1_unstable_v1"> - <copyright> - 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. - </copyright> - - <interface name="zwlr_layer_shell_v1" version="1"> - <description summary="create surfaces that are layers of the desktop"> - 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. - </description> - - <request name="get_layer_surface"> - <description summary="create a layer_surface from a surface"> - 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. - - 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. - </description> - <arg name="id" type="new_id" interface="zwlr_layer_surface_v1"/> - <arg name="surface" type="object" interface="wl_surface"/> - <arg name="output" type="object" interface="wl_output" allow-null="true"/> - <arg name="layer" type="uint" enum="layer" summary="layer to add this surface to"/> - <arg name="namespace" type="string" summary="namespace for the layer surface"/> - </request> - - <enum name="error"> - <entry name="role" value="0" summary="wl_surface has another role"/> - <entry name="invalid_layer" value="1" summary="layer value is invalid"/> - <entry name="already_constructed" value="2" summary="wl_surface has a buffer attached or committed"/> - </enum> - - <enum name="layer"> - <description summary="available layers for surfaces"> - 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. - </description> - - <entry name="background" value="0"/> - <entry name="bottom" value="1"/> - <entry name="top" value="2"/> - <entry name="overlay" value="3"/> - </enum> - </interface> - - <interface name="zwlr_layer_surface_v1" version="1"> - <description summary="layer metadata interface"> - 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 (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. - </description> - - <request name="set_size"> - <description summary="sets the size of the surface"> - 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. - </description> - <arg name="width" type="uint"/> - <arg name="height" type="uint"/> - </request> - - <request name="set_anchor"> - <description summary="configures the anchor point of the surface"> - Requests that the compositor anchor the surface to the specified edges - and corners. If two orthoginal 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. - </description> - <arg name="anchor" type="uint" enum="anchor"/> - </request> - - <request name="set_exclusive_zone"> - <description summary="configures the exclusive geometry of this surface"> - Requests that the compositor avoids occluding an area of the surface - 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 an - edge, rather than a corner. The zone is the number of surface-local - coordinates from the edge that are considered 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 excluzive 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. - </description> - <arg name="zone" type="int"/> - </request> - - <request name="set_margin"> - <description summary="sets a margin from the anchor point"> - 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. - </description> - <arg name="top" type="int"/> - <arg name="right" type="int"/> - <arg name="bottom" type="int"/> - <arg name="left" type="int"/> - </request> - - <request name="set_keyboard_interactivity"> - <description summary="requests keyboard events"> - Set to 1 to request that the seat send keyboard events to this layer - surface. For layers below the shell surface layer, the seat will use - normal focus semantics. For layers above the shell surface layers, the - seat will always give exclusive keyboard focus to the top-most layer - which has keyboard interactivity set to true. - - 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. - - Events is double-buffered, see wl_surface.commit. - </description> - <arg name="keyboard_interactivity" type="uint"/> - </request> - - <request name="get_popup"> - <description summary="assign this layer_surface as an xdg_popup parent"> - 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. - </description> - <arg name="popup" type="object" interface="xdg_popup"/> - </request> - - <request name="ack_configure"> - <description summary="ack a configure event"> - 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. - </description> - <arg name="serial" type="uint" summary="the serial from the configure event"/> - </request> - - <request name="destroy" type="destructor"> - <description summary="destroy the layer_surface"> - This request destroys the layer surface. - </description> - </request> - - <event name="configure"> - <description summary="suggest a surface change"> - 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. - </description> - <arg name="serial" type="uint"/> - <arg name="width" type="uint"/> - <arg name="height" type="uint"/> - </event> - - <event name="closed"> - <description summary="surface should be closed"> - 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. - </description> - </event> - - <enum name="error"> - <entry name="invalid_surface_state" value="0" summary="provided surface state is invalid"/> - <entry name="invalid_size" value="1" summary="size is invalid"/> - <entry name="invalid_anchor" value="2" summary="anchor bitfield is invalid"/> - </enum> - - <enum name="anchor" bitfield="true"> - <entry name="top" value="1" summary="the top edge of the anchor rectangle"/> - <entry name="bottom" value="2" summary="the bottom edge of the anchor rectangle"/> - <entry name="left" value="4" summary="the left edge of the anchor rectangle"/> - <entry name="right" value="8" summary="the right edge of the anchor rectangle"/> - </enum> - </interface> -</protocol> ++++++ swaylock.obsinfo ++++++ --- /var/tmp/diff_new_pack.vYmbTA/_old 2024-08-26 22:13:37.110506208 +0200 +++ /var/tmp/diff_new_pack.vYmbTA/_new 2024-08-26 22:13:37.114506375 +0200 @@ -1,5 +1,5 @@ name: swaylock -version: 1.7.2 -mtime: 1674942867 -commit: bd2dfec9ae0111b1858d5fab44f0f4fac4117d07 +version: 1.8.0 +mtime: 1724445573 +commit: de0731de6a44d99532fcd46c5894cff5f10e65a6