Show login UI on all monitors for compositor-agnostic focus

Wayland does not expose absolute pointer coordinates to clients,
so we cannot reliably detect which monitor has focus. Instead,
show the full lockscreen UI on every monitor — the compositor
assigns keyboard focus to the surface under the pointer via
ext-session-lock-v1.

Share a single FingerprintListener across all windows to avoid
multiple device claims. Also add makepkg build artifacts to
gitignore.
This commit is contained in:
nevaforget 2026-03-26 13:58:45 +01:00
parent 0eefe76a3a
commit b365572033
4 changed files with 24 additions and 26 deletions

6
.gitignore vendored
View File

@ -5,3 +5,9 @@ __pycache__/
dist/
build/
.pytest_cache/
# makepkg build artifacts
pkg/src/
pkg/pkg/
pkg/moonlock/
pkg/*.pkg.tar.*

View File

@ -4,7 +4,7 @@
# Maintainer: Dominik Kressler
pkgname=moonlock-git
pkgver=0.1.0
pkgver=0.0.0.r8.0eefe76
pkgrel=1
pkgdesc="A secure Wayland lockscreen with GTK4, PAM and fingerprint support"
arch=('any')

View File

@ -23,7 +23,8 @@ class LockscreenWindow(Gtk.ApplicationWindow):
"""Fullscreen lockscreen window with password and fingerprint auth."""
def __init__(self, application: Gtk.Application, unlock_callback: callable | None = None,
config: Config | None = None) -> None:
config: Config | None = None,
fingerprint_listener: FingerprintListener | None = None) -> None:
super().__init__(application=application)
self.add_css_class("lockscreen")
@ -33,8 +34,8 @@ class LockscreenWindow(Gtk.ApplicationWindow):
self._failed_attempts = 0
self._unlock_callback = unlock_callback
# Fingerprint listener
self._fp_listener = FingerprintListener()
# Fingerprint listener (shared across windows to avoid multiple device claims)
self._fp_listener = fingerprint_listener or FingerprintListener()
self._fp_available = (
self._config.fingerprint_enabled
and self._fp_listener.is_available(self._user.username)
@ -44,8 +45,8 @@ class LockscreenWindow(Gtk.ApplicationWindow):
self._setup_keyboard()
self._password_entry.grab_focus()
# Start fingerprint listener if available
if self._fp_available:
# Start fingerprint listener if available (only once across shared instances)
if self._fp_available and not self._fp_listener._running:
self._fp_listener.start(
self._user.username,
on_success=self._on_fingerprint_success,

View File

@ -17,7 +17,8 @@ gi.require_version("Gtk", "4.0")
gi.require_version("Gdk", "4.0")
from gi.repository import Gtk, Gdk
from moonlock.config import load_config, resolve_background_path
from moonlock.config import load_config
from moonlock.fingerprint import FingerprintListener
from moonlock.lockscreen import LockscreenWindow
# ext-session-lock-v1 via gtk4-layer-shell
@ -56,27 +57,17 @@ class MoonlockApp(Gtk.Application):
display = Gdk.Display.get_default()
monitors = display.get_monitors()
# Shared fingerprint listener across all windows (only one can claim the device)
fp_listener = FingerprintListener()
for i in range(monitors.get_n_items()):
monitor = monitors.get_item(i)
# Primary monitor gets the full UI
if i == 0:
window = LockscreenWindow(
application=self,
unlock_callback=self._unlock,
config=self._config,
)
else:
# Secondary monitors get the wallpaper without login UI
window = Gtk.ApplicationWindow(application=self)
window.add_css_class("lockscreen")
wallpaper = Gtk.Picture.new_for_filename(
str(resolve_background_path(self._config))
)
wallpaper.set_content_fit(Gtk.ContentFit.COVER)
wallpaper.set_hexpand(True)
wallpaper.set_vexpand(True)
window.set_child(wallpaper)
window = LockscreenWindow(
application=self,
unlock_callback=self._unlock,
config=self._config,
fingerprint_listener=fp_listener,
)
self._lock_instance.assign_window_to_monitor(window, monitor)
window.present()
self._windows.append(window)