GNOME Bugzilla – Bug 745141
Flicker at user login time with wayland sessions
Last modified: 2021-07-05 13:43:43 UTC
When a user logs into a wayland session, there's a noticeable flicker. This is because GDM changes VTs up front, before starting wayland. We need to change that.
Created attachment 297850 [details] [review] native: don't leak logind session proxy It's currently getting leaked in error paths
Created attachment 297851 [details] [review] native: Change VT explicitly after taking control of it In order to prevent flicker at user login time, we can't change VTs until after the VT is put in KD_GRAPHICS mode (by the logind TakeControl call). At the moment, GDM takes responsibility for changing the VT, up front. This responsibility needs to be shifted to the display server, so it can happen at the appropriate time. This commit changes mutter to explicitly activate the VT after taking control of the session.
so one problem we're going to run into is weston doesn't do the vt activation either. So if we fix GDM once mutter is fixed, then we'll break weston from GDM (since we won't jump to the vt weston is running on). Maybe a better tactic would be to change logind to activate the session automatically when TakeControl is called (or when the drm device is taken)
Created attachment 297852 [details] [review] logind: switch to VT of session on TakeControl A display server that uses logind for managing its display will call org.freedesktop.login1.Session.TakeControl to get the VT in KD_GRAPHICS mode and to become the designated controller of the session. Once it is the session controller, it can then request devices associated with the seat from logind using the org.freedesktop.login1.Session.TakeDevice call. In almost all cases, the first device a display server will request is the DRM device, which logind will open and assign master ownership to. In order to prevent flicker at startup, the display server can't switch to the VT of the session until after the VT is switched into KD_GRAPHICS mode by the TakeControl call. In order to use the DRM device provided by TakeDevice, the VT of the session should be active. This means that in almost all cases display servers should call org.freedesktop.login1.Session.Activate immediately after calling TakeControl, and immediately before calling TakeDevice. In practice, some display servers fail to explicitly activate the session after taking control of it, and instead rely on the display manager to change the VT before the display server is started, which leads to undesirable flicker. This commit eliminates the need for the Activate call, by doing it implicitly as part of TakeControl. This change will allow display managers to remove their code to explicitly change VTs up front, without worrying about breaking display servers that rely on the VT getting changed for them. See also
I guess i'll send the above to dvdhrm / systemd-devel and see what he thinks.
Review of attachment 297850 [details] [review]: Oops. Also, if you want to start using g_autoptr, I won't stop you :)
I see the problem, but the patch does not work. If you have another session like a console (like kmscon or systemd-console) running in background, and it restarts on crash, you really don't want it to activate the VT. Furthermore, I don't want to encode policy in the logind API. TakeControl() should not imply any other operation. Use Activate() explicitly, if you want to activate the session. The gdm situation is a bit different. You usually don't want gnome to activate the session when it starts (I guess..). However, if started through a login-manager, you definitely want it to activate. But the login-manager cannot activate the session as it has to wait for KD_GRAPHICS to be set. I see two solutions: either make gnome always activate the session after startup. This is was Xorg does, too. Or make gnome-startup synchronous, so gdm knows when the session is up and running so it can activate it. Given that we use .desktop files for sessions, I always wanted to make use of the dbus-activation specified by the desktop-file-spec. So far, it's only used for Apps, but we could also use it for sessions started via .desktop files (though probably with a slightly different API). This way, startup would be synchronous and gdm knew when gnome is up. It's all on hold right now, as I want to finish kdbus first. However, this stuff is definitely next on my TODO list. Short fix: add --activate to gnome-session and add it to the .desktop file so gdm passes it to gnome. If set, gnome automatically activates the session on startup.
Hey thanks, (In reply to David Herrmann from comment #7) > I see the problem, but the patch does not work. If you have > another session like a console (like kmscon or systemd-console) > running in background, and it restarts on crash, you really > don't want it to activate the VT. Makes sense. > The gdm situation is a bit different. You usually don't want > gnome to activate the session when it starts (I guess..). Why not? > However, if started through a login-manager, you definitely > want it to activate. But the login-manager cannot activate the > session as it has to wait for KD_GRAPHICS to be set. Right that's the crux of the problem. GDM actually supports activating up front or letting the display server activate when it's got control. We currently activate up front for wayland sessions, and let Xorg activate itself. I want to get rid of the activate-up-front code, because of the inherent flicker, but ideally I don't want to prevent weston from getting switched to when a user logs into it. I was hoping to find a solution that doesn't require fixing all the wayland compositors. > I see two solutions: either make gnome always activate the > session after startup. This is was Xorg does, too. Or make > gnome-startup synchronous, so gdm knows when the session is up > and running so it can activate it. What do you think about a new org.freedesktop.login1.Session.Controller boolean property that GDM could monitor for? It knows about the sessions it's managing, so if it got a notification for when the session took control, it could activate it then. > Given that we use .desktop files for sessions, I always wanted to make use > of the dbus-activation specified by the desktop-file-spec. So far, it's only > used for Apps, but we could also use it for sessions started via .desktop > files (though probably with a slightly different API). This way, startup > would be synchronous and gdm knew when gnome is up. interesting idea. > Short fix: add --activate to gnome-session and add it to the .desktop file > so gdm passes it to gnome. If set, gnome automatically activates the session > on startup. Oh, I see what you're saying, you don't want to switch until the whole session is loaded, not just showable. So, historically we haven't been able to start the whole session in the background because GLX suspends clients when the session isn't active. also up until the 3.15.90 the login screen shared an X server with the user session . I guess we don't have those limitations with wayland, so we could indeed wait for the whole session to start before doing the switch. If we go that route, I guess there's no getting around fixing weston, et al, individually, though. Well, I suppose we could add a new X-GDM-ActivatesAutomatically=true or something to /usr/share/wayland-sessions/gnome-wayland.desktop and continue to do the flickery activation up front unless that key is true. Daniel, what's your take? Should we just have a flag day and fix weston, gnome-session and gdm at the same time, or should we introduce a new flag that compliant environments have to opt into?
Attachment 297850 [details] pushed as cbad65f - native: don't leak logind session proxy
I chatted with Daniel on IRC about this: <halfline> daniels: hey do you mind chiming in on https://bugzilla.gnome.org/show_bug.cgi?id=745141 ? Trying to figure out what to do (re getting rid of flicker at startup) <daniels> halfline: hrm, i honestly don't know a lot about the logind api, so would have to dig into it a bit <halfline> daniels: well, let me just summarize. basically right now, GDM allocates a VT and jumps to it, then starts the wayland session <halfline> daniels: but that has inherent flicker because the VT that gets allocates is is KD_TEXT mode <halfline> (so it shows a black screen with a cursor) <halfline> daniels: when a wayland compositor first starts up it asks logind to put the console into KD_GRAPHICS mode <halfline> if you VT switch after that happens, then there's no flicker introduced <halfline> because a VT switch in KD_GRAPHICS mode won't change what the user sees on screen until the screen is explicitly changed <halfline> daniels: so i'd like to change GDM to not jump to the VT upfront <halfline> but that means the wayland compositor has to be changed to do it <halfline> otherwise, the user will log in, and it will just sit there at the login screen with the wayland session running on another vt that never gets switched to <daniels> halfline: yeah, i got the jist of that - just got a bit lost in the Activate/TakeDevice/etc dance <halfline> Activate just means "switch to my vt" <daniels> so it's a matter of calling VT_ACTIVATE yourself and not assuming the initiator will do that for you? <daniels> or logind::Activate rather than VT_ACTIVATE <halfline> yea exactly <halfline> X server already does this of course <halfline> so for X servers GDM doesn't do it up front <halfline> and so X is less flickery than wayland <halfline> TakeDevice is just a way to request an fd to a device that would normally require root access to open <halfline> examples of devices are /dev/dri/card0 /dev/input/foo etc <halfline> in the case of /dev/dri/card0, logind will call drmSetMaster() on it before handing it over <halfline> "or logind::Activate rather than VT_ACTIVATE" <-- actually either one is fine, they do the same thing <halfline> (except systems without VTs) <halfline> systems/seats <daniels> halfline: ack - calling Activate from weston only when it's ready definitely makes a lot of sense - i'd be tempted to say include it in the .desktop indeed, rather than a flag day <daniels> halfline: since the failure case for the .desktop mode is 'i get an additional flicker when i start a compositor with an incomplete .desktop file' <halfline> okay <halfline> disadvantage of that is, "functional" wayland sessions will have to have X-GDM-ActivatedAutomatically in them <halfline> which is a bit unfortunate <halfline> but maybe we can come up with a standardized key name down the road when other display managers start supporting wayland <daniels> indeed <daniels> if that's the biggest problem we have ... :) <halfline> alright, i'll copy and paste this irc conversation into the bug <halfline> thanks <daniels> np, ta :)
So I guess I'll add X-GDM-ActivatesAutomatically and then make gnome-session activate the session when session hits the RUNNING state.
why would gnome-session activate the session, not mutter?
So we switch to a fully loaded session. We could do it in mutter too (that's attachment 297851 [details] [review] ) but doing it in gnome-session might give us a nicer user experience.
Just to follow up here... I ended up having to change GDM to switch VTs up front with Xorg, too. This is because the logind code in the X server doesn't really work properly if the VT isn't in the foreground (it sort half-gives up if the devices are paused and then goes back to fallback code which fails some of the time becasue of a race with logind giving acl ownership to /dev/dri/card0). Anyway, given both wayland and Xorg now are in the "switch VTs up front" code path, I went ahead and added a short-term change to GDM to set KD_GRAPHICS mode itself before doing the VT switch. So now there's no flicker for wayland or X. I still think we should do the gnome-sesion fix and get wayland (and eventually X again, too, of course) on the other code path, so leaving bug open for now.
Review of attachment 297851 [details] [review]: Please push this mutter patch instead of doing a gnome-session patch.
we can push it, but at the moment there is no upside to doing it afaict. 1) GDM will still switch VTs up front, until we add X-GDM-ActivatesAutomatically=true feature to GDM and to the session file 2) Even if we did make those changes, there's no user visible difference, since we've made the switch-vts-up-front code flicker free, now. and there's a downside: 3) The gnome-session patch would have user visible benefit (which you don't like or something? explain, please.), and this patch will conflict with it.
mutter, the one in charge of its repaint loop and knowing when the frame is painted, should only switch after it knows it has KMS and is OK. I think it makes a lot more sense for the display server to do the activation rather than gnome-session.
but mutter doesn't know when the session is fully running? mutter only knows when the session is ready to display something, not a fully loaded, ready to go desktop. gnome-session does know that.
My initial reaction was that it should be both - Mutter sends the event, but also gated on g-s signalling ready, but presumably g-s wouldn't signal that if it hasn't seen any wl_outputs or RandR outputs, which would presumably then give us both if signalled from g-s. So that indeed seems like the thing to do.
Comment on attachment 297850 [details] [review] native: don't leak logind session proxy Attachment 297850 [details] was pushed as cbad65f a while ago, updating patch status.
GNOME is going to shut down bugzilla.gnome.org in favor of gitlab.gnome.org. As part of that, we are mass-closing older open tickets in bugzilla.gnome.org which have not seen updates for a longer time (resources are unfortunately quite limited so not every ticket can get handled). If you can still reproduce the situation described in this ticket in a recent and supported software version, then please follow https://wiki.gnome.org/GettingInTouch/BugReportingGuidelines and create a new ticket at https://gitlab.gnome.org/GNOME/mutter/-/issues/ Thank you for your understanding and your help.