#424 [Proof of Concept] Seamless transition when suspending, resuming and logging out
Opened a month ago by jrelvas. Modified a month ago

Hey folks,

I've been looking into some "system integration" issues that have always bothered me during my spare time.

Among the biggest and most frustrating of these is the TTY cursor briefly showing up whenever you suspend/resume your machine and log off/switch sessions.

After tinkering for a bit, I managed to narrow down what caused this. Whenever the system performs any of these actions, it appears to briefly switch to /dev/tty1, where GDM (or another display manager) is running. However, the display manager is not active, so the system falls back to showing the TTY console.
Since the cursor is on by default for all TTYs, including the first one, the user will briefly see a black screen with nothing but the blinking cursor.

So, how do we fix this?

Disabling the TTY cursor by default is not an option because it'd either require the kernel parameters or build arguments to be changed. This would also affect all other TTYs, which should have cursors.

So here's the approach I took for prototyping a "fix". I created a systemd service which uses setterm on /dev/tty1 to disable the cursor, then modified gdm to depend on that service:

# /etc/systemd/system/disable-tty-cursor.service
[Unit]
Description=Disable TTY1 cursor

[Service]
Type=oneshot
StandardInput=tty
StandardOutput=tty
TTYPath=/dev/tty1
Environment=TERM=linux
ExecStart=/usr/bin/setterm --cursor off
# /etc/systemd/system/gdm.service.d/tty-cursor-fix.conf
[Unit]
Requires=disable-tty-cursor.service

This keeps the cursor visible during the boot process (when the user presses "ESC" while Plymouth is running to see the TTY), but its hidden before starting gdm, making suspend, resume and logging out seamless - the screen is black during the transition, with no visual glitches.

I'd like to know your thoughts on where this belongs. Should this be brought up with upstream, or is this something to be implemented downstream in Fedora?

Thanks in advance.


Looks like some additional steps are required for suspend/resume. VT seems to use whatever the kernel's defaults are, instead of TTY1's configuration.

Luckily, I found a really nasty hack which fixes this issue. You can bind and unbind the VT during runtime (effectively disabling it), so if we disable VT before suspend and re-enable it after, the cursor will no longer be visible:

# /etc/systemd/system/vt-suspend.service
[Unit]
Description=Suspend VT
Before=systemd-suspend.service

[Service]
Type=oneshot
ExecStart=/usr/bin/sh -c "echo 0 > /sys/devices/virtual/vtconsole/vtcon1/bind"

[Install]
WantedBy=systemd-suspend.service
# /etc/systemd/system/vt-resume.service
[Unit]
Description=Resume VT
After=systemd-suspend.service

[Service]
Type=oneshot
ExecStart=/usr/bin/sh -c "echo 1 > /sys/devices/virtual/vtconsole/vtcon1/bind"

[Install]
WantedBy=systemd-suspend.service

@rstrode @jadahl we might need your opinions on this one

maybe gdm should put the console in KD_GRAPHICS mode before jumping to it in its jump_to_vt function

Login to comment on this ticket.

Metadata