From 4c97f8647b9543abefbed3ece209d335de6aa9d6 Mon Sep 17 00:00:00 2001 From: srdusr <99972264+srdusr@users.noreply.github.com> Date: Thu, 6 Mar 2025 23:13:00 +0200 Subject: Fix total input death after VT switch back (libinput never resumed) The kernel revokes every input device fd across a VT switch away. libinput has a documented pair of calls for this exact case, suspend()/resume() (libinput_suspend/libinput_resume), which reopen every device through the session once it is reactivated. This codebase never called either one, so after switching back to the compositor's VT, libinput's device list stayed pointed at fds the kernel had already revoked - reads on them don't error, they just silently stop producing events, forever. Rendering, DRM/KMS, and libseat's own session activation all recovered on their own, which is what made this look like a display bug rather than an input one; it took three real forced reboots today, with no visible input from keyboard or mouse for 30+ minutes after switching back to tty1 each time, to isolate it as this specific missing call. register_libinput now returns the Libinput context (a clone of the one already handed to LibinputInputBackend - it's a reference-counted handle, not a deep copy, and LibinputInputBackend only exposes an immutable accessor once it's moved into the calloop event source). register_session_notifier takes that handle and calls suspend() on PauseSession, resume() on ActivateSession. --- crates/wayland/src/udev/platform.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'crates/wayland/src/udev/platform.rs') diff --git a/crates/wayland/src/udev/platform.rs b/crates/wayland/src/udev/platform.rs index cbcee64..1d2ef0e 100644 --- a/crates/wayland/src/udev/platform.rs +++ b/crates/wayland/src/udev/platform.rs @@ -269,8 +269,8 @@ impl UdevPlatform { let handle = event_loop.handle(); register_drm_fd(&handle, &card)?; - register_libinput(&handle, &session, &seat_name)?; - register_session_notifier(&handle, notifier)?; + let libinput_handle = register_libinput(&handle, &session, &seat_name)?; + register_session_notifier(&handle, notifier, libinput_handle)?; if let Err(e) = register_udev_monitor(&handle, &seat_name) { log::warn!("udev: connector hotplug unavailable ({e}); monitors are fixed at startup"); } -- cgit v1.2.3