diff --git a/doc/face-unlock.1.scd b/doc/face-unlock.1.scd index a0d705b..29d1d43 100644 --- a/doc/face-unlock.1.scd +++ b/doc/face-unlock.1.scd @@ -267,7 +267,8 @@ so does the bubble, above the lock screen too. picture there, one at random from a folder, or _none_; *Blur the wallpaper* blurs it. If the agent dies while this screen is locked, the compositor keeps it locked, and the agent takes the lock back when it - starts again. + starts again. It needs Qt 6.10 or newer: with older Qt (Debian 13) the + menu does not offer it, and *lock* asks logind to lock. Hyprland only starts the agent's user service under uwsm. Without it, *enable* and *status* show what to add to its config. diff --git a/src/agent/main.cpp b/src/agent/main.cpp index 3bc7057..075fe0f 100644 --- a/src/agent/main.cpp +++ b/src/agent/main.cpp @@ -13,6 +13,8 @@ // --choose-lock-screen // open the window that asks which lock screen to use // where it is a program of its own, and print the answer +// --has-own-lock for the menu: exits 0 when this build has face-unlock's +// own lock screen (see SessionLock::built) #include "agentsocket.h" #include "bubblecontroller.h" @@ -233,6 +235,9 @@ void scheduleDemo(BubbleController *bubble) int main(int argc, char **argv) { + if (argc == 2 && std::strcmp(argv[1], "--has-own-lock") == 0) { + return SessionLock::built ? 0 : 1; + } forkForLock(argc, argv); QGuiApplication app(argc, argv); app.setApplicationName(QStringLiteral("face-unlock-agent")); diff --git a/src/agent/sessionlock.cpp b/src/agent/sessionlock.cpp index c5859bd..697f92c 100644 --- a/src/agent/sessionlock.cpp +++ b/src/agent/sessionlock.cpp @@ -64,12 +64,15 @@ public: { return m_configured; } +#if QT_VERSION >= QT_VERSION_CHECK(6, 10, 0) // Qt commits a new role at once, as xdg-shell wants. A lock surface must - // not be committed before it has acknowledged its first size. + // not be committed before it has acknowledged its first size. Older Qt + // cannot be stopped from that (see SessionLock::built). bool commitSurfaceRole() const override { return false; } +#endif void applyConfigure() override { window()->resizeFromApplyConfigure(m_size); @@ -83,7 +86,11 @@ protected: if (!m_configured) { m_configured = true; applyConfigure(); +#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0) window()->updateExposure(); +#else + window()->sendRecursiveExposeEvent(); +#endif } else { window()->applyConfigureWhenPossible(); } @@ -151,7 +158,7 @@ SessionLock::~SessionLock() bool SessionLock::available() { - return Wayland::hasGlobal("ext_session_lock_manager_v1"); + return built && Wayland::hasGlobal("ext_session_lock_manager_v1"); } QString SessionLock::markerPath() diff --git a/src/agent/sessionlock.h b/src/agent/sessionlock.h index abc0e77..3ae1d5b 100644 --- a/src/agent/sessionlock.h +++ b/src/agent/sessionlock.h @@ -20,6 +20,7 @@ #include #include #include +#include class BubbleController; class LockScreenController; @@ -37,7 +38,12 @@ public: SessionLock(QQmlEngine *engine, BubbleController *bubble, LockScreenController *screen, UserConfig *config, QObject *parent = nullptr); ~SessionLock() override; - // Whether the compositor offers ext-session-lock. + // Whether this build has it. Qt before 6.10 commits a window's surface + // before a lock surface may be committed, which the protocol forbids. + static constexpr bool built = QT_VERSION >= QT_VERSION_CHECK(6, 10, 0); + + // Whether it can lock here: built, and the compositor offers + // ext-session-lock. static bool available(); // From the lock request until the lock is gone again. diff --git a/src/face-unlock b/src/face-unlock index ce1c5e6..09c2e29 100644 --- a/src/face-unlock +++ b/src/face-unlock @@ -126,10 +126,15 @@ fu_do_enable() { ;; esac # Where the lock screen is a program of its own: face-unlock's, with the - # bubble, or that program with a line of text. Asked once. - if fu_own_lock_here && [[ -n ${WAYLAND_DISPLAY:-} && -z $(fu_config_get LockScreenStyle) ]]; then - fu_say " $(fu_msg "Pick your lock screen in the window.")" - fu_lock_choose || fu_note "$(fu_msg "No lock screen picked. You can do it later under Settings.")" + # bubble, or that program with a line of text. Asked once. Without + # face-unlock's own (older Qt) there is nothing to ask. + if [[ $FU_DESKTOP != plasma && $FU_DESKTOP != gnome && -z $(fu_config_get LockScreenStyle) ]]; then + if ! fu_own_lock_here; then + fu_lock_style_set yours + elif [[ -n ${WAYLAND_DISPLAY:-} ]]; then + fu_say " $(fu_msg "Pick your lock screen in the window.")" + fu_lock_choose || fu_note "$(fu_msg "No lock screen picked. You can do it later under Settings.")" + fi fi if fu_pam_lockers_here && fu_pam_lockers_enabled && [[ $(fu_config_get LockScreenStyle) != own ]]; then fu_note "$(fu_msg "The lock screen (%s) takes your face too. If it does not scan when you come back, press Enter on the empty password field." "$(fu_pam_lockers_list)")" diff --git a/src/lib/menu.sh b/src/lib/menu.sh index a691a67..debca4d 100644 --- a/src/lib/menu.sh +++ b/src/lib/menu.sh @@ -562,7 +562,7 @@ fu_ui_settings() { for spec in "${FU_SETTINGS[@]}"; do IFS='|' read -r scope key type default label choice need only <<< "$spec" [[ $only == lockers ]] && ! fu_pam_lockers_here && continue - [[ $only == ownlock && ( $FU_DESKTOP == plasma || $FU_DESKTOP == gnome ) ]] && continue + [[ $only == ownlock ]] && ! fu_own_lock_here && continue # A heading has its label where the key would be. [[ $scope == group ]] && label="$key" key='' scopes+=("$scope"); keys+=("$key"); types+=("$type"); defaults+=("$default") diff --git a/src/lib/system.sh b/src/lib/system.sh index 9845015..d210d49 100644 --- a/src/lib/system.sh +++ b/src/lib/system.sh @@ -313,8 +313,18 @@ fu_gnome_extension_disable() { FU_HYPRLOCK_SNIPPET="$FU_XDG_CONFIG/$FU_NAME/hyprlock.conf" FU_HYPRLOCK_MARK="# $FU_NAME: what face unlock is doing, at the top" +# fu_own_lock_here +# Whether face-unlock's own lock screen is on offer: where the lock screen is +# a program of its own, and the agent was built with it (Qt 6.10 and newer). +FU_OWN_LOCK='' + fu_own_lock_here() { - [[ $FU_DESKTOP != plasma && $FU_DESKTOP != gnome ]] + [[ $FU_DESKTOP != plasma && $FU_DESKTOP != gnome ]] || return 1 + if [[ -z $FU_OWN_LOCK ]]; then + FU_OWN_LOCK=no + "$FU_AGENT" --has-own-lock > /dev/null 2>&1 && FU_OWN_LOCK=yes + fi + [[ $FU_OWN_LOCK == yes ]] } # fu_hyprlock_text_on