fix: prune per-monitor windows on monitor removal (v0.6.15)

Resume-unlock SIGSEGV: connect_monitor only adds windows to all_handles,
never removes them when a monitor powers off on suspend. gtk4-session-lock
unmaps and drops its own ref, but the GtkApplication and all_handles keep
theirs, so the orphaned window survives until unlock — where destroying it
dereferences its now-NULL monitor association and crashes.

Watch display.monitors() and prune handles whose monitor is no longer
valid, releasing the app ref via remove_window (the lib already unmapped
and dereffed the window — we must not destroy it ourselves).

Revert the earlier idle_add_local_once deferral: the logs proved it
ineffective (crash happens inside the idle trampoline). Diagnostic unlock
logging kept until a suspend/resume cycle confirms the fix.
This commit is contained in:
2026-06-02 16:32:29 +02:00
parent 85cf039506
commit 492a781d92
6 changed files with 64 additions and 9 deletions
+5
View File
@@ -27,6 +27,9 @@ pub struct LockscreenHandles {
pub password_entry: gtk::PasswordEntry,
pub unlock_callback: Rc<dyn Fn()>,
pub username: String,
/// The monitor this window was assigned to (session-lock path only).
/// Used to prune the window when its monitor is removed on suspend/resume.
pub monitor: Option<gdk::Monitor>,
state: Rc<RefCell<LockscreenState>>,
}
@@ -70,6 +73,7 @@ pub fn create_lockscreen_window(
password_entry: gtk::PasswordEntry::new(),
unlock_callback,
username: String::new(),
monitor: None,
state: Rc::new(RefCell::new(LockscreenState {
failed_attempts: 0,
fp_listener_rc: None,
@@ -360,6 +364,7 @@ pub fn create_lockscreen_window(
password_entry: password_entry.clone(),
unlock_callback,
username: user.username,
monitor: None,
state: state.clone(),
}
}