Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package swaylock for openSUSE:Factory checked in at 2022-03-08 20:32:00 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/swaylock (Old) and /work/SRC/openSUSE:Factory/.swaylock.new.2349 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "swaylock" Tue Mar 8 20:32:00 2022 rev:4 rq:960160 version:1.6 Changes: -------- --- /work/SRC/openSUSE:Factory/swaylock/swaylock.changes 2020-01-23 15:55:14.711105649 +0100 +++ /work/SRC/openSUSE:Factory/.swaylock.new.2349/swaylock.changes 2022-03-11 11:36:27.546280855 +0100 @@ -1,0 +2,12 @@ +Tue Mar 8 08:31:37 UTC 2022 - Michael Vetter <mvet...@suse.com> + +- Update to 1.6: + * Support for the new ext-session-lock-v1 protocol + * Add --indicator-{x,y}-position CLI options + * Support for key repeat + * Fix a potential use-after-free + * Fix indicator buffer not resizing after display powers off + * Prevent attaching and committing the surface twice +- Remove swaylock-version.patch: fixed + +------------------------------------------------------------------- Old: ---- 1.5.tar.gz swaylock-version.patch New: ---- 1.6.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ swaylock.spec ++++++ --- /var/tmp/diff_new_pack.riqQvG/_old 2022-03-11 11:36:27.982281365 +0100 +++ /var/tmp/diff_new_pack.riqQvG/_new 2022-03-11 11:36:27.986281370 +0100 @@ -1,7 +1,7 @@ # # spec file for package swaylock # -# Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,15 +17,13 @@ Name: swaylock -Version: 1.5 +Version: 1.6 Release: 0 Summary: Screen locker for Wayland License: MIT Group: System/GUI/Other URL: https://github.com/swaywm/swaylock Source0: https://github.com/swaywm/swaylock/archive/%{version}.tar.gz -# https://github.com/swaywm/swaylock/pull/128 -Patch0: swaylock-version.patch BuildRequires: meson >= 0.48.0 BuildRequires: pam-devel BuildRequires: pkgconfig @@ -73,7 +71,6 @@ %prep %setup -q -%patch0 -p1 %build export CFLAGS="%{optflags} -I/usr/include/wayland" ++++++ 1.5.tar.gz -> 1.6.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.5/.editorconfig new/swaylock-1.6/.editorconfig --- old/swaylock-1.5/.editorconfig 1970-01-01 01:00:00.000000000 +0100 +++ new/swaylock-1.6/.editorconfig 2022-02-10 09:54:57.000000000 +0100 @@ -0,0 +1,22 @@ +# For the full list of code style requirements, see sway's CONTRIBUTING.md + +root = true + +[*] +charset = utf-8 +end_of_line = lf + +[*.{c,h,cmake,txt}] +indent_style = tab +indent_size = 4 + +[*.{xml,yml}] +indent_style = space +indent_size = 2 + +[config] +indent_style = space +indent_size = 4 + +[*.md] +trim_trailing_whitespace = false diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.5/README.md new/swaylock-1.6/README.md --- old/swaylock-1.5/README.md 2020-01-22 17:19:47.000000000 +0100 +++ new/swaylock-1.6/README.md 2022-02-10 09:54:57.000000000 +0100 @@ -3,16 +3,14 @@ swaylock is a screen locking utility for Wayland compositors. It is compatible with any Wayland compositor which implements the following Wayland protocols: -- wlr-layer-shell -- wlr-input-inhibitor +- wlr-layer-shell + wlr-input-inhibitor, or ext-session-lock-v1 - xdg-output -- xdg-shell See the man page, `swaylock(1)`, for instructions on using swaylock. ## Release Signatures -Releases are signed with [B22DA89A](http://pgp.mit.edu/pks/lookup?op=vindex&search=0x52CB6609B22DA89A) +Releases are signed with [E88F5E48](https://keys.openpgp.org/search?q=34FF9526CFEF0E97A340E2E40FDE7BE0E88F5E48) and published [on GitHub](https://github.com/swaywm/swaylock/releases). swaylock releases are managed independently of sway releases. @@ -23,9 +21,6 @@ Swaylock is available in many distributions. Try installing the "swaylock" package for yours. -If you're interested in packaging swaylock for your distribution, stop by the -IRC channel or shoot an email to s...@cmpwn.com for advice. - ### Compiling from Source Install dependencies: @@ -40,9 +35,8 @@ * [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (optional: man pages) \* * git \* -_\*Compile-time dep_ - -_\*\*optional: required for background images other than PNG_ +_\* Compile-time dep_ +_\*\* Optional: required for background images other than PNG_ Run these commands: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.5/completions/bash/swaylock new/swaylock-1.6/completions/bash/swaylock --- old/swaylock-1.5/completions/bash/swaylock 2020-01-22 17:19:47.000000000 +0100 +++ new/swaylock-1.6/completions/bash/swaylock 2022-02-10 09:54:57.000000000 +0100 @@ -45,6 +45,8 @@ --indicator-idle-visible --indicator-radius --indicator-thickness + --indicator-x-position + --indicator-y-position --inside-caps-lock-color --inside-clear-color --inside-color diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.5/completions/fish/swaylock.fish new/swaylock-1.6/completions/fish/swaylock.fish --- old/swaylock-1.5/completions/fish/swaylock.fish 2020-01-22 17:19:47.000000000 +0100 +++ new/swaylock-1.6/completions/fish/swaylock.fish 2022-02-10 09:54:57.000000000 +0100 @@ -18,6 +18,8 @@ complete -c swaylock -l indicator-idle-visible --description "Sets the indicator to show even if idle." complete -c swaylock -l indicator-radius --description "Sets the indicator radius." complete -c swaylock -l indicator-thickness --description "Sets the indicator thickness." +complete -c swaylock -l indicator-x-position --description "Sets the horizontal position of the indicator." +complete -c swaylock -l indicator-y-position --description "Sets the vertical position of the indicator." complete -c swaylock -l inside-caps-lock-color --description "Sets the color of the inside of the indicator when Caps Lock is active." complete -c swaylock -l inside-clear-color --description "Sets the color of the inside of the indicator when cleared." complete -c swaylock -l inside-color --description "Sets the color of the inside of the indicator." diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.5/completions/zsh/_swaylock new/swaylock-1.6/completions/zsh/_swaylock --- old/swaylock-1.5/completions/zsh/_swaylock 2020-01-22 17:19:47.000000000 +0100 +++ new/swaylock-1.6/completions/zsh/_swaylock 2022-02-10 09:54:57.000000000 +0100 @@ -22,6 +22,8 @@ '(--indicator-idle-visible)'--indicator-idle-visible'[Sets the indicator to show even if idle]' \ '(--indicator-radius)'--indicator-radius'[Sets the indicator radius]:radius:' \ '(--indicator-thickness)'--indicator-thickness'[Sets the indicator thickness]:thickness:' \ + '(--indicator-x-position)'--indicator-x-position'[Sets the horizontal position of the indicator]' \ + '(--indicator-y-position)'--indicator-y-position'[Sets the vertical position of the indicator]' \ '(--inside-caps-lock-color)'--inside-caps-lock-color'[Sets the color of the inside of the indicator when Caps Lock is active]:color:' \ '(--inside-clear-color)'--inside-clear-color'[Sets the color of the inside of the indicator when cleared]:color:' \ '(--inside-color)'--inside-color'[Sets the color of the inside of the indicator]:color:' \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.5/include/seat.h new/swaylock-1.6/include/seat.h --- old/swaylock-1.5/include/seat.h 2020-01-22 17:19:47.000000000 +0100 +++ new/swaylock-1.6/include/seat.h 2022-02-10 09:54:57.000000000 +0100 @@ -1,6 +1,11 @@ #ifndef _SWAYLOCK_SEAT_H #define _SWAYLOCK_SEAT_H #include <xkbcommon/xkbcommon.h> +#include <stdint.h> +#include <stdbool.h> + +struct loop; +struct loop_timer; struct swaylock_xkb { bool caps_lock; @@ -14,6 +19,11 @@ struct swaylock_state *state; struct wl_pointer *pointer; struct wl_keyboard *keyboard; + int32_t repeat_period_ms; + int32_t repeat_delay_ms; + uint32_t repeat_sym; + uint32_t repeat_codepoint; + struct loop_timer *repeat_timer; }; extern const struct wl_seat_listener seat_listener; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.5/include/swaylock.h new/swaylock-1.6/include/swaylock.h --- old/swaylock-1.5/include/swaylock.h 2020-01-22 17:19:47.000000000 +0100 +++ new/swaylock-1.6/include/swaylock.h 2022-02-10 09:54:57.000000000 +0100 @@ -89,6 +89,8 @@ int failed_attempts; bool run_display; struct zxdg_output_manager_v1 *zxdg_output_manager; + struct ext_session_lock_manager_v1 *ext_session_lock_manager_v1; + struct ext_session_lock_v1 *ext_session_lock_v1; }; struct swaylock_surface { @@ -101,6 +103,7 @@ struct wl_surface *child; // 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]; struct pool_buffer *current_buffer; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.5/loop.c new/swaylock-1.6/loop.c --- old/swaylock-1.5/loop.c 2020-01-22 17:19:47.000000000 +0100 +++ new/swaylock-1.6/loop.c 2022-02-10 09:54:57.000000000 +0100 @@ -21,6 +21,7 @@ void (*callback)(void *data); void *data; struct timespec expiry; + bool removed; struct wl_list link; // struct loop_timer::link }; @@ -80,7 +81,11 @@ ms = 0; } - poll(loop->fds, loop->fd_length, ms); + int ret = poll(loop->fds, loop->fd_length, ms); + if (ret < 0) { + swaylock_log_errno(LOG_ERROR, "poll failed"); + exit(1); + } // Dispatch fds size_t fd_index = 0; @@ -104,12 +109,19 @@ clock_gettime(CLOCK_MONOTONIC, &now); struct loop_timer *timer = NULL, *tmp_timer = NULL; wl_list_for_each_safe(timer, tmp_timer, &loop->timers, link) { + if (timer->removed) { + wl_list_remove(&timer->link); + free(timer); + continue; + } + bool expired = timer->expiry.tv_sec < now.tv_sec || (timer->expiry.tv_sec == now.tv_sec && timer->expiry.tv_nsec < now.tv_nsec); if (expired) { timer->callback(timer->data); - loop_remove_timer(loop, timer); + wl_list_remove(&timer->link); + free(timer); } } } @@ -184,8 +196,7 @@ struct loop_timer *timer = NULL, *tmp_timer = NULL; wl_list_for_each_safe(timer, tmp_timer, &loop->timers, link) { if (timer == remove) { - wl_list_remove(&timer->link); - free(timer); + timer->removed = true; return true; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.5/main.c new/swaylock-1.6/main.c --- old/swaylock-1.5/main.c 2020-01-22 17:19:47.000000000 +0100 +++ new/swaylock-1.6/main.c 2022-02-10 09:54:57.000000000 +0100 @@ -26,6 +26,7 @@ #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" +#include "ext-session-lock-v1-client-protocol.h" static uint32_t parse_color(const char *color) { if (color[0] == '#') { @@ -97,16 +98,22 @@ 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->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); 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, struct swaylock_surface *surface); @@ -118,7 +125,7 @@ return (surface->state->args.colors.background & 0xff) == 0xff; } -static void create_layer_surface(struct swaylock_surface *surface) { +static void create_surface(struct swaylock_surface *surface) { struct swaylock_state *state = surface->state; surface->image = select_image(state, surface); @@ -132,22 +139,28 @@ assert(surface->subsurface); wl_subsurface_set_sync(surface->subsurface); - surface->layer_surface = zwlr_layer_shell_v1_get_layer_surface( - state->layer_shell, surface->surface, surface->output, - ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "lockscreen"); - assert(surface->layer_surface); - - 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); + 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); + } if (surface_is_opaque(surface) && surface->state->args.mode != BACKGROUND_MODE_CENTER && @@ -159,7 +172,9 @@ wl_region_destroy(region); } - wl_surface_commit(surface->surface); + if (!state->ext_session_lock_v1) { + wl_surface_commit(surface->surface); + } } static void layer_surface_configure(void *data, @@ -168,8 +183,8 @@ struct swaylock_surface *surface = data; surface->width = width; surface->height = height; - surface->indicator_width = 1; - surface->indicator_height = 1; + surface->indicator_width = 0; + surface->indicator_height = 0; zwlr_layer_surface_v1_ack_configure(layer_surface, serial); render_frame_background(surface); render_frame(surface); @@ -186,6 +201,23 @@ .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) { + struct swaylock_surface *surface = data; + surface->width = width; + surface->height = height; + surface->indicator_width = 0; + surface->indicator_height = 0; + ext_session_lock_surface_v1_ack_configure(lock_surface, serial); + render_frame_background(surface); + render_frame(surface); +} + +static const struct ext_session_lock_surface_v1_listener ext_session_lock_surface_v1_listener = { + .configure = ext_session_lock_surface_v1_handle_configure, +}; + static const struct wl_callback_listener surface_frame_listener; static void surface_frame_handle_done(void *data, struct wl_callback *callback, @@ -211,6 +243,11 @@ }; void damage_surface(struct swaylock_surface *surface) { + if (surface->width == 0 || surface->height == 0) { + // Not yet configured + return; + } + surface->dirty = true; if (surface->frame_pending) { return; @@ -300,12 +337,27 @@ .description = handle_xdg_output_description, }; +static void ext_session_lock_v1_handle_locked(void *data, struct ext_session_lock_v1 *lock) { + // Who cares +} + +static void ext_session_lock_v1_handle_finished(void *data, struct ext_session_lock_v1 *lock) { + swaylock_log(LOG_ERROR, "Failed to lock session -- " + "is another lockscreen running?"); + exit(2); +} + +static const struct ext_session_lock_v1_listener ext_session_lock_v1_listener = { + .locked = ext_session_lock_v1_handle_locked, + .finished = ext_session_lock_v1_handle_finished, +}; + static void handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { struct swaylock_state *state = data; if (strcmp(interface, wl_compositor_interface.name) == 0) { state->compositor = wl_registry_bind(registry, name, - &wl_compositor_interface, 3); + &wl_compositor_interface, 4); } else if (strcmp(interface, wl_subcompositor_interface.name) == 0) { state->subcompositor = wl_registry_bind(registry, name, &wl_subcompositor_interface, 1); @@ -314,7 +366,7 @@ &wl_shm_interface, 1); } else if (strcmp(interface, wl_seat_interface.name) == 0) { struct wl_seat *seat = wl_registry_bind( - registry, name, &wl_seat_interface, 3); + registry, name, &wl_seat_interface, 4); struct swaylock_seat *swaylock_seat = calloc(1, sizeof(struct swaylock_seat)); swaylock_seat->state = state; @@ -339,9 +391,12 @@ wl_list_insert(&state->surfaces, &surface->link); if (state->run_display) { - create_layer_surface(surface); + 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); } } @@ -1057,7 +1112,7 @@ char *flag = malloc(nread + 3); if (flag == NULL) { free(line); - free(config); + fclose(config); swaylock_log(LOG_ERROR, "Failed to allocate memory"); return 0; } @@ -1180,20 +1235,34 @@ struct wl_registry *registry = wl_display_get_registry(state.display); wl_registry_add_listener(registry, ®istry_listener, &state); wl_display_roundtrip(state.display); - assert(state.compositor && state.layer_shell && state.shm); - if (!state.input_inhibit_manager) { - free(state.args.font); - swaylock_log(LOG_ERROR, "Compositor does not support the input " - "inhibitor protocol, refusing to run insecurely"); + + if (!state.compositor || !state.shm) { + swaylock_log(LOG_ERROR, "Missing wl_compositor or wl_shm"); + 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"); return 1; } - zwlr_input_inhibit_manager_v1_get_inhibitor(state.input_inhibit_manager); if (wl_display_roundtrip(state.display) == -1) { free(state.args.font); - swaylock_log(LOG_ERROR, "Exiting - failed to inhibit input:" - " is another lockscreen already running?"); - return 2; + if (state.input_inhibit_manager) { + swaylock_log(LOG_ERROR, "Exiting - failed to inhibit input:" + " is another lockscreen already running?"); + return 2; + } + return 1; } if (state.zxdg_output_manager) { @@ -1212,7 +1281,7 @@ struct swaylock_surface *surface; wl_list_for_each(surface, &state.surfaces, link) { - create_layer_surface(surface); + create_surface(surface); } if (state.args.daemonize) { @@ -1235,6 +1304,11 @@ loop_poll(state.eventloop); } + if (state.ext_session_lock_v1) { + ext_session_lock_v1_unlock_and_destroy(state.ext_session_lock_v1); + wl_display_flush(state.display); + } + free(state.args.font); return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.5/meson.build new/swaylock-1.6/meson.build --- old/swaylock-1.5/meson.build 2020-01-22 17:19:47.000000000 +0100 +++ new/swaylock-1.6/meson.build 2022-02-10 09:54:57.000000000 +0100 @@ -1,9 +1,9 @@ project( 'swaylock', 'c', - version: '1.4', + version: '1.6', license: 'MIT', - meson_version: '>=0.48.0', + meson_version: '>=0.59.0', default_options: [ 'c_std=c11', 'warning_level=2', @@ -29,53 +29,49 @@ add_project_arguments( '-DSYSCONFDIR="/@0@"'.format(join_paths(prefix, sysconfdir)), - language : 'c') + language : 'c', +) if is_freebsd add_project_arguments('-D_C11_SOURCE', language: 'c') endif wayland_client = dependency('wayland-client') -wayland_protos = dependency('wayland-protocols', version: '>=1.14') -xkbcommon = dependency('xkbcommon') -cairo = dependency('cairo') -gdk_pixbuf = dependency('gdk-pixbuf-2.0', required: get_option('gdk-pixbuf')) -bash_comp = dependency('bash-completion', required: false) -fish_comp = dependency('fish', required: false) -libpam = cc.find_library('pam', required: get_option('pam')) -crypt = cc.find_library('crypt', required: not libpam.found()) -math = cc.find_library('m') +wayland_protos = dependency('wayland-protocols', version: '>=1.25', fallback: 'wayland-protocols') +wayland_scanner = dependency('wayland-scanner', version: '>=1.15.0') +xkbcommon = dependency('xkbcommon') +cairo = dependency('cairo') +gdk_pixbuf = dependency('gdk-pixbuf-2.0', required: get_option('gdk-pixbuf')) +bash_comp = dependency('bash-completion', required: false) +fish_comp = dependency('fish', required: false) +libpam = cc.find_library('pam', required: get_option('pam')) +crypt = cc.find_library('crypt', required: not libpam.found()) +math = cc.find_library('m') git = find_program('git', required: false) scdoc = find_program('scdoc', required: get_option('man-pages')) -wayland_scanner = find_program('wayland-scanner') +wayland_scanner_prog = find_program(wayland_scanner.get_variable('wayland_scanner')) version = '"@0@"'.format(meson.project_version()) if git.found() - git_commit_hash = run_command([git.path(), 'describe', '--always', '--tags']) - git_branch = run_command([git.path(), 'rev-parse', '--abbrev-ref', 'HEAD']) + git_commit_hash = run_command([git, 'describe', '--always', '--tags'], check: false) + git_branch = run_command([git, 'rev-parse', '--abbrev-ref', 'HEAD'], check: false) if git_commit_hash.returncode() == 0 and git_branch.returncode() == 0 version = '"@0@ (" __DATE__ ", branch \'@1@\')"'.format(git_commit_hash.stdout().strip(), git_branch.stdout().strip()) endif endif add_project_arguments('-DSWAYLOCK_VERSION=@0@'.format(version), language: 'c') -wl_protocol_dir = wayland_protos.get_pkgconfig_variable('pkgdatadir') - -if wayland_client.version().version_compare('>=1.14.91') - code_type = 'private-code' -else - code_type = 'code' -endif +wl_protocol_dir = wayland_protos.get_variable('pkgdatadir') wayland_scanner_code = generator( - wayland_scanner, + wayland_scanner_prog, output: '@BASENAME@-protocol.c', - arguments: [code_type, '@INPUT@', '@OUTPUT@'], + arguments: ['private-code', '@INPUT@', '@OUTPUT@'], ) wayland_scanner_client = generator( - wayland_scanner, + wayland_scanner_prog, output: '@BASENAME@-client-protocol.h', arguments: ['client-header', '@INPUT@', '@OUTPUT@'], ) @@ -86,6 +82,7 @@ client_protocols = [ [wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'], [wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.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'], ] @@ -160,7 +157,6 @@ ) if scdoc.found() - sh = find_program('sh') mandir = get_option('mandir') man_files = [ 'swaylock.1.scd', @@ -174,9 +170,9 @@ output, input: filename, output: output, - command: [ - sh, '-c', '@0@ < @INPUT@ > @1@'.format(scdoc.path(), output) - ], + command: scdoc, + feed: true, + capture: true, install: true, install_dir: '@0@/man@1@'.format(mandir, section) ) @@ -199,7 +195,7 @@ 'completions/bash/swaylock', ) if bash_comp.found() - bash_install_dir = bash_comp.get_pkgconfig_variable('completionsdir') + bash_install_dir = bash_comp.get_variable('completionsdir') else bash_install_dir = datadir + '/bash-completion/completions' endif @@ -212,7 +208,7 @@ 'completions/fish/swaylock.fish', ) if fish_comp.found() - fish_install_dir = fish_comp.get_pkgconfig_variable('completionsdir') + fish_install_dir = fish_comp.get_variable('completionsdir') else fish_install_dir = datadir + '/fish/vendor_completions.d' endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.5/pam.c new/swaylock-1.6/pam.c --- old/swaylock-1.5/pam.c 2020-01-22 17:19:47.000000000 +0100 +++ new/swaylock-1.6/pam.c 2022-02-10 09:54:57.000000000 +0100 @@ -112,6 +112,8 @@ pw_buf = NULL; } + pam_setcred(auth_handle, PAM_REFRESH_CRED); + if (pam_end(auth_handle, pam_status) != PAM_SUCCESS) { swaylock_log(LOG_ERROR, "pam_end failed"); exit(EXIT_FAILURE); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.5/pool-buffer.c new/swaylock-1.6/pool-buffer.c --- old/swaylock-1.5/pool-buffer.c 2020-01-22 17:19:47.000000000 +0100 +++ new/swaylock-1.6/pool-buffer.c 2022-02-10 09:54:57.000000000 +0100 @@ -72,18 +72,22 @@ uint32_t stride = width * 4; size_t size = stride * height; - char *name; - int fd = create_pool_file(size, &name); - assert(fd != -1); - void *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - struct wl_shm_pool *pool = wl_shm_create_pool(shm, fd, size); - buf->buffer = wl_shm_pool_create_buffer(pool, 0, - width, height, stride, format); - wl_shm_pool_destroy(pool); - close(fd); - unlink(name); - free(name); - fd = -1; + void *data = NULL; + if (size > 0) { + char *name; + int fd = create_pool_file(size, &name); + assert(fd != -1); + data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + struct wl_shm_pool *pool = wl_shm_create_pool(shm, fd, size); + buf->buffer = wl_shm_pool_create_buffer(pool, 0, + width, height, stride, format); + wl_buffer_add_listener(buf->buffer, &buffer_listener, buf); + wl_shm_pool_destroy(pool); + close(fd); + unlink(name); + free(name); + fd = -1; + } buf->size = size; buf->width = width; @@ -92,8 +96,6 @@ buf->surface = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, stride); buf->cairo = cairo_create(buf->surface); - - wl_buffer_add_listener(buf->buffer, &buffer_listener, buf); return buf; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.5/render.c new/swaylock-1.6/render.c --- old/swaylock-1.5/render.c 2020-01-22 17:19:47.000000000 +0100 +++ new/swaylock-1.6/render.c 2022-02-10 09:54:57.000000000 +0100 @@ -64,7 +64,7 @@ wl_surface_set_buffer_scale(surface->surface, surface->scale); wl_surface_attach(surface->surface, surface->current_buffer->buffer, 0, 0); - wl_surface_damage(surface->surface, 0, 0, surface->width, surface->height); + wl_surface_damage_buffer(surface->surface, 0, 0, INT32_MAX, INT32_MAX); wl_surface_commit(surface->surface); } @@ -134,12 +134,18 @@ if (state->args.show_indicator && (state->auth_state != AUTH_STATE_IDLE || state->args.indicator_idle_visible)) { - // Draw circle + // Fill inner circle + cairo_set_line_width(cairo, 0); + cairo_arc(cairo, buffer_width / 2, buffer_diameter / 2, + arc_radius - arc_thickness / 2, 0, 2 * M_PI); + set_color_for_state(cairo, state, &state->args.colors.inside); + cairo_fill_preserve(cairo); + cairo_stroke(cairo); + + // Draw ring cairo_set_line_width(cairo, arc_thickness); cairo_arc(cairo, buffer_width / 2, buffer_diameter / 2, arc_radius, 0, 2 * M_PI); - set_color_for_state(cairo, state, &state->args.colors.inside); - cairo_fill_preserve(cairo); set_color_for_state(cairo, state, &state->args.colors.ring); cairo_stroke(cairo); @@ -269,7 +275,7 @@ arc_radius + arc_thickness / 2, 0, 2 * M_PI); cairo_stroke(cairo); - // display layout text seperately + // display layout text separately if (layout_text) { cairo_text_extents_t extents; cairo_font_extents_t fe; @@ -304,18 +310,23 @@ new_width = extents.width + 2 * box_padding; } } + } - if (buffer_width != new_width || buffer_height != new_height) { - destroy_buffer(surface->current_buffer); - surface->indicator_width = new_width; - surface->indicator_height = new_height; - render_frame(surface); - } + // Ensure buffer size is multiple of buffer scale - required by protocol + new_height += surface->scale - (new_height % surface->scale); + new_width += surface->scale - (new_width % surface->scale); + + if (buffer_width != new_width || buffer_height != new_height) { + destroy_buffer(surface->current_buffer); + surface->indicator_width = new_width; + surface->indicator_height = new_height; + render_frame(surface); + return; } wl_surface_set_buffer_scale(surface->child, surface->scale); wl_surface_attach(surface->child, surface->current_buffer->buffer, 0, 0); - wl_surface_damage(surface->child, 0, 0, surface->current_buffer->width, surface->current_buffer->height); + wl_surface_damage_buffer(surface->child, 0, 0, INT32_MAX, INT32_MAX); wl_surface_commit(surface->child); wl_surface_commit(surface->surface); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.5/seat.c new/swaylock-1.6/seat.c --- old/swaylock-1.5/seat.c 2020-01-22 17:19:47.000000000 +0100 +++ new/swaylock-1.6/seat.c 2022-02-10 09:54:57.000000000 +0100 @@ -6,25 +6,27 @@ #include "log.h" #include "swaylock.h" #include "seat.h" +#include "loop.h" static void keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, uint32_t format, int32_t fd, uint32_t size) { - struct swaylock_state *state = data; + struct swaylock_seat *seat = data; + struct swaylock_state *state = seat->state; if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { close(fd); swaylock_log(LOG_ERROR, "Unknown keymap format %d, aborting", format); exit(1); } - char *map_shm = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + char *map_shm = mmap(NULL, size - 1, PROT_READ, MAP_PRIVATE, fd, 0); if (map_shm == MAP_FAILED) { close(fd); swaylock_log(LOG_ERROR, "Unable to initialize keymap shm, aborting"); exit(1); } - struct xkb_keymap *keymap = xkb_keymap_new_from_string( - state->xkb.context, map_shm, XKB_KEYMAP_FORMAT_TEXT_V1, + struct xkb_keymap *keymap = xkb_keymap_new_from_buffer( + state->xkb.context, map_shm, size - 1, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS); - munmap(map_shm, size); + munmap(map_shm, size - 1); close(fd); assert(keymap); struct xkb_state *xkb_state = xkb_state_new(keymap); @@ -45,9 +47,18 @@ // Who cares } +static void keyboard_repeat(void *data) { + struct swaylock_seat *seat = data; + struct swaylock_state *state = seat->state; + seat->repeat_timer = loop_add_timer( + state->eventloop, seat->repeat_period_ms, keyboard_repeat, seat); + swaylock_handle_key(state, seat->repeat_sym, seat->repeat_codepoint); +} + static void keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t _key_state) { - struct swaylock_state *state = data; + struct swaylock_seat *seat = data; + struct swaylock_state *state = seat->state; enum wl_keyboard_key_state key_state = _key_state; xkb_keysym_t sym = xkb_state_key_get_one_sym(state->xkb.state, key + 8); uint32_t keycode = key_state == WL_KEYBOARD_KEY_STATE_PRESSED ? @@ -56,12 +67,29 @@ if (key_state == WL_KEYBOARD_KEY_STATE_PRESSED) { swaylock_handle_key(state, sym, codepoint); } + + if (seat->repeat_timer) { + loop_remove_timer(seat->state->eventloop, seat->repeat_timer); + seat->repeat_timer = NULL; + } + + if (key_state == WL_KEYBOARD_KEY_STATE_PRESSED && seat->repeat_period_ms > 0) { + seat->repeat_sym = sym; + seat->repeat_codepoint = codepoint; + seat->repeat_timer = loop_add_timer( + seat->state->eventloop, seat->repeat_delay_ms, keyboard_repeat, seat); + } } static void keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) { - struct swaylock_state *state = data; + struct swaylock_seat *seat = data; + struct swaylock_state *state = seat->state; + if (state->xkb.state == NULL) { + return; + } + int layout_same = xkb_state_layout_index_is_active(state->xkb.state, group, XKB_STATE_LAYOUT_EFFECTIVE); if (!layout_same) { @@ -82,7 +110,14 @@ static void keyboard_repeat_info(void *data, struct wl_keyboard *wl_keyboard, int32_t rate, int32_t delay) { - // TODO + struct swaylock_seat *seat = data; + if (rate <= 0) { + seat->repeat_period_ms = -1; + } else { + // Keys per second -> milliseconds between keys + seat->repeat_period_ms = 1000 / rate; + } + seat->repeat_delay_ms = delay; } static const struct wl_keyboard_listener keyboard_listener = { @@ -168,7 +203,7 @@ } if ((caps & WL_SEAT_CAPABILITY_KEYBOARD)) { seat->keyboard = wl_seat_get_keyboard(wl_seat); - wl_keyboard_add_listener(seat->keyboard, &keyboard_listener, seat->state); + wl_keyboard_add_listener(seat->keyboard, &keyboard_listener, seat); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.5/swaylock.1.scd new/swaylock-1.6/swaylock.1.scd --- old/swaylock-1.5/swaylock.1.scd 2020-01-22 17:19:47.000000000 +0100 +++ new/swaylock-1.6/swaylock.1.scd 2022-02-10 09:54:57.000000000 +0100 @@ -101,6 +101,12 @@ *--indicator-thickness* <thickness> Sets the indicator thickness. The default value is 10. +*--indicator-x-position* <x> + Sets the horizontal position of the indicator. + +*--indicator-y-position* <y> + Sets the vertical position of the indicator. + *--inside-color* <rrggbb[aa]> Sets the color of the inside of the indicator. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swaylock-1.5/wlr-layer-shell-unstable-v1.xml new/swaylock-1.6/wlr-layer-shell-unstable-v1.xml --- old/swaylock-1.5/wlr-layer-shell-unstable-v1.xml 2020-01-22 17:19:47.000000000 +0100 +++ new/swaylock-1.6/wlr-layer-shell-unstable-v1.xml 2022-02-10 09:54:57.000000000 +0100 @@ -140,7 +140,7 @@ 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 accomodate for other + 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.