]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
logind: fix abnormal switching causing the screen to go black
authorxinpeng wang <wangxinpeng@uniontech.com>
Wed, 25 Oct 2023 03:19:58 +0000 (11:19 +0800)
committerLuca Boccassi <luca.boccassi@gmail.com>
Fri, 27 Oct 2023 09:19:58 +0000 (10:19 +0100)
After logind receives the SIGRTMIN signal from the kernel, it will execute
manager_vt_switch---session_leave_vt---session_device_pause_all,The device
permissions of the session are removed here;under normal circumstances, the
tty value read from /sys/class/tty/tty0/active changes and switchesto a new
session,give the new session resume device permissions.
But under abnormal circumstances (such as switching quickly on a device using
wayland; and sometimes the kernel will suddenly send a SIGRTMIN signal, but
nothing changes),In these cases, logind does not give session resume device
permission, causing the device to have a black screen and suspended animation.

src/login/logind-seat.c

index c92e59ae51261d83be486ac5d81d26fa294f2b96..8d875d2ea772061a46355668d44aad3e648d77a8 100644 (file)
@@ -225,8 +225,20 @@ int seat_set_active(Seat *s, Session *session) {
         assert(s);
         assert(!session || session->seat == s);
 
-        if (session == s->active)
+        /* When logind receives the SIGRTMIN signal from the kernel, it will
+         * execute session_leave_vt and stop all devices of the session; at
+         * this time, if the session is active and there is no change in the
+         * session, then the session does not have the permissions of the device,
+         * and the machine will have a black screen and suspended animation.
+         * Therefore, if the active session has executed session_leave_vt ,
+         * A resume is required here. */
+        if (session == s->active) {
+                if (session) {
+                        log_debug("Active session remains unchanged, resuming session devices.");
+                        session_device_resume_all(session);
+                }
                 return 0;
+        }
 
         old_active = s->active;
         s->active = session;