GNOME Bugzilla – Bug 688757
Hide the cursor until mutter takes over
Last modified: 2021-06-14 18:21:36 UTC
To implement bug 687791 and be sure that the cursor isn't visible on startup, or with an application being launched on startup, we need to make sure the cursor isn't shown before gnome-settings-daemon takes over policy duties. This means that gnome-session should hide the cursor itself until gnome-settings-daemon is ready to handle the cursor.
So this is going to happen inside the gdm greeter session's invocation of gnome-session; but it seems to me that this is just pushing the problem slightly earlier; we basically need to boot the X server with the cursor hidden by default, right? Something like how gdm passes -background none, right?
Xorg already does that. The cursor will stay hidden until XDefineCursor() is called on the root window. This is what mutter does on startup, so we need to completely hide the cursor using XFixes before that happens.
Ah ok, so this is a gnome-settings-daemon/gnome-shell race condition on login. Makes sense then I guess. It sounds like though given the X dependency a patch might conflict with Matthias' outstanding branch: http://git.gnome.org/browse/gnome-session/log/?h=wip/cleanups
Maybe a helper would do, but we need it running before anything else, and wait for g-s-d to show up.
why don't we just remove the XDefineCursor call from mutter?
(In reply to comment #5) > why don't we just remove the XDefineCursor call from mutter? Because it would just delay the problem until an application is started, so you'd end up with a race. See bug 688228.
(In reply to comment #3) > Ah ok, so this is a gnome-settings-daemon/gnome-shell race condition on login. > There's no race condition - gsd completes its startup in an earlier phase of session startup, before gnome-shell is ever started
Assuming things work without this patch, I'm probably going to close this bug. If things don't work without this patch, then we can push it, but I'm curious why they don't work.
I'm not certain this is needed in gnome-session, but there's still a bug in transitioning from gdm to the user's session. The cursor appears briefly in the top left of the screen, and I don't know what's setting it. I'll try to make gnome-settings-daemon call the cursor code even earlier if I can (it used to be in an idle, now it's called sync when the plugins are initialised).
I wonder if it's this code: • void• gdm_slave_set_initial_cursor_position (GdmSlave *slave)• {• if (slave->priv->server_display != NULL) {• int x, y;• • determine_initial_cursor_position (slave, &x, &y);• XWarpPointer(slave->priv->server_display,• None,• DefaultRootWindow (slave->priv->server_display),• 0, 0,• 0, 0,• x, y);• }• }• •
When does that code run? The problem happens between me pressing "Enter" after typing my password, and just before the g-s-d code from the user session kicks in (I reckon, as the cursor hides then).
Might be https://bugzilla.freedesktop.org/show_bug.cgi?id=58398
Turns out there's nothing to handle the transition between gdm and the user session. With the above patch for X.org, g-s-d master, gdm with the "no set root cursor" patch, and a stock mutter, and no mouse usage, the cursor will show up between the gdm and the user session in the top-left corner. With a patched mutter, the cursor will be hidden. Of course, patching mutter isn't good enough, as using the mouse in gdm, and then switching to using the touchscreen should keep the cursor hidden during the transition. Is there anything we can do in gdm to make this work?
(In reply to comment #13) > Turns out there's nothing to handle the transition between gdm and the user > session. > > With the above patch for X.org, g-s-d master, gdm with the "no set root cursor" > patch, and a stock mutter, and no mouse usage, the cursor will show up between > the gdm and the user session in the top-left corner. > > With a patched mutter, the cursor will be hidden. Do you have any explanation for the behavior you've described here? It's hard to propose a way forward without understanding what is going on currently, and I don't. I assume that the X server is being recycled during the transition? Does that return things to the state where the initial cursor is empty? At that point, how is gdm relevant?
(In reply to comment #14) <snip> > Do you have any explanation for the behavior you've described here? It's hard > to propose a way forward without understanding what is going on currently, and > I don't. I assume that the X server is being recycled during the transition? > Does that return things to the state where the initial cursor is empty? At that > point, how is gdm relevant? The explanation is very simple. Between the gdm's gnome-settings-daemon getting killed and the session's g-s-d starting, there's a gap. That's when the cursor is visible. The X server is the same one between gdm and the session, so we don't get to reset the counter. I have no idea what could survive into the session to handle this transition.
Can you make gdm unset the root cursor image before starting the new session? (It sounds like the reason that the patched Mutter is "fixing" this problem is that it never sets the root cursor image *in the GDM session* because there happens to be no startup notification in the GDM session.)
(In reply to comment #16) > Can you make gdm unset the root cursor image before starting the new session? It cannot. Once the cursor is set, the only way to hide it is using the XFixesHideCursor() function, which means something needs to bridge the gap between the gdm chooser exiting and gnome-session/gnome-settings-daemon starting in the session. > (It sounds like the reason that the patched Mutter is "fixing" this problem is > that it never sets the root cursor image *in the GDM session* because there > happens to be no startup notification in the GDM session.) That's exactly what happens.
- The mutter that runs at the login screen shouldn't call XDefineCursor during startup - The gnome-settings-daemon that runs at the login screen should show the cursor when the user moves the mouse. - The gnome-settings-daemon that runs at the login screen should hide the cursor when the user stops moving the mouse. - Nothing needs to run after the login screen exits before the user session starts. The mouse should be hidden from the previous hide cursor call - The mutter that runs in the user session shouldn't call XDefineCursor during startup - The gnome-settings-daemon that runs in the user session should show the cursor when the user moves the mouse. - The gnome-settings-daemon that runs in the user session should hide the cursor when the user stops moving the mouse. basically, the mouse cursor is a software feature for people using mouse hardware. gnome-settings-daemon handles input devices, and so knows when to show and hide the cursor, since it knows when a user has a mouse. It runs the show, everything else should stop mucking with the cursor. Right? I think i'm missing the complication.
I guess what mutter does is irrelevant, too. gnome-settings-daemon just needs to run XFixesHideCursor() at startup. Then, run XFixesShowCursor() when the user moves the mouse. When the user stops moving the mouse call XFixesHideCursor() again.
(In reply to comment #17) > (In reply to comment #16) > > Can you make gdm unset the root cursor image before starting the new session? > > It cannot. Once the cursor is set, the only way to hide it is using the > XFixesHideCursor() function, which means something needs to bridge the gap > between the gdm chooser exiting and gnome-session/gnome-settings-daemon > starting in the session. You can always hide the cursor by setting it to an empty cursor image - which is what the -nocursor option to X effectively does. The reason that the X fixes API exists, as I understand it, is to be able to temporarily hide the cursor without interfering with the image set for the cursor.
(In reply to comment #18) > - The mutter that runs at the login screen shouldn't call XDefineCursor during > startup > - The gnome-settings-daemon that runs at the login screen should show the > cursor when the user moves the mouse. > - The gnome-settings-daemon that runs at the login screen should hide the > cursor when the user stops moving the mouse. > - Nothing needs to run after the login screen exits before the user session > starts. The mouse should be hidden from the previous hide cursor call > - The mutter that runs in the user session shouldn't call XDefineCursor during > startup > - The gnome-settings-daemon that runs in the user session should show the > cursor when the user moves the mouse. > - The gnome-settings-daemon that runs in the user session should hide the > cursor when the user stops moving the mouse. > > basically, the mouse cursor is a software feature for people using mouse > hardware. gnome-settings-daemon handles input devices, and so knows when to > show and hide the cursor, since it knows when a user has a mouse. It runs the > show, everything else should stop mucking with the cursor. > > Right? I think i'm missing the complication. I think you are missing the basic complication that the root cursor has an *image* - and someone has to be in charge of that image. Traditionally, that's the window manager. If we can't figure out how to manage visibility state of the cursor independently of the image, then we need to move the cursor image to g-s-d as well (without research, my memory is that the startup notification protocols would allow that) - but if we can keep the image control in the WM that seems easier. I do not want some solution that requires Mutter to not call XDefineCursor at some times and to call XDefineCursor at other times.
(In reply to comment #19) > I guess what mutter does is irrelevant, too. gnome-settings-daemon just needs > to run XFixesHideCursor() at startup. It already does. > Then, run XFixesShowCursor() when the > user moves the mouse. When the user stops moving the mouse call > XFixesHideCursor() again. If the caller to XFixesHideCursor dies (eg. if the gdm g-s-d dies) then the cursor will be shown again. Otherwise you could end up with the cursor being invisible because of a single app. (In reply to comment #20) > (In reply to comment #17) > > (In reply to comment #16) > > > Can you make gdm unset the root cursor image before starting the new session? > > > > It cannot. Once the cursor is set, the only way to hide it is using the > > XFixesHideCursor() function, which means something needs to bridge the gap > > between the gdm chooser exiting and gnome-session/gnome-settings-daemon > > starting in the session. > > You can always hide the cursor by setting it to an empty cursor image - which > is what the -nocursor option to X effectively does. The reason that the X fixes > API exists, as I understand it, is to be able to temporarily hide the cursor > without interfering with the image set for the cursor. I think that's probably the best way to do things. I would want to do that in gdm, when it transitions from gdm to the user session. Where would I plug that in?
(In reply to comment #21) > (In reply to comment #18) > > - The mutter that runs at the login screen shouldn't call XDefineCursor during > > startup > > - The gnome-settings-daemon that runs at the login screen should show the > > cursor when the user moves the mouse. > > - The gnome-settings-daemon that runs at the login screen should hide the > > cursor when the user stops moving the mouse. > > - Nothing needs to run after the login screen exits before the user session > > starts. The mouse should be hidden from the previous hide cursor call > > - The mutter that runs in the user session shouldn't call XDefineCursor during > > startup > > - The gnome-settings-daemon that runs in the user session should show the > > cursor when the user moves the mouse. > > - The gnome-settings-daemon that runs in the user session should hide the > > cursor when the user stops moving the mouse. > > > > basically, the mouse cursor is a software feature for people using mouse > > hardware. gnome-settings-daemon handles input devices, and so knows when to > > show and hide the cursor, since it knows when a user has a mouse. It runs the > > show, everything else should stop mucking with the cursor. > > > > Right? I think i'm missing the complication. > > I think you are missing the basic complication that the root cursor has an > *image* - and someone has to be in charge of that image. Traditionally, that's > the window manager. If we can't figure out how to manage visibility state of > the cursor independently of the image, then we need to move the cursor image to > g-s-d as well (without research, my memory is that the startup notification > protocols would allow that) - but if we can keep the image control in the WM > that seems easier. > > I do not want some solution that requires Mutter to not call XDefineCursor at > some times and to call XDefineCursor at other times. I don't fancy moving startup-notification to g-s-d, there's enough things as it is in there. Given that g-s-d starts before mutter in both the gdm and user sessions, g-s-d can use XFixes to hide the cursor before mutter resets it. The only time where we don't have an app running is in the transition between the gdm and user session. If gdm sets an empty image as the cursor when logging us in, problem solved (though you might want gdm asking g-s-d whether to hide it, or telling g-s-d to hide it because it will be logging a user in...).
(In reply to comment #22) > If the caller to XFixesHideCursor dies (eg. if the gdm g-s-d dies) then the > cursor will be shown again. Otherwise you could end up with the cursor being > invisible because of a single app. Ahhhhh, that's the bit I was missing. It's ref counted and tied to the display connection. (In reply to comment #20) > You can always hide the cursor by setting it to an empty cursor image Yea that seems like the easiest way to go. (In reply to comment #23) > If gdm sets an empty image as the cursor when logging us in, problem solved > (though you might want gdm asking g-s-d whether to hide it, > or telling g-s-d to hide it because it will be logging a user in...). Could just do it in the cursor plugin at deactivation time instead of doing it from gdm.
(In reply to comment #24) > (In reply to comment #23) > > If gdm sets an empty image as the cursor when logging us in, problem solved > > (though you might want gdm asking g-s-d whether to hide it, > > or telling g-s-d to hide it because it will be logging a user in...). > Could just do it in the cursor plugin at deactivation time instead of doing it > from gdm. The lifecycle of g-s-d isn't tied to that of the session unfortunately. I don't even know how it gets killed by gdm/gnome-session. This means that replacing an existing g-s-d (to debug for example) could have some pretty nasty side effects, requiring gnome-shell/mutter to restart to reset the cursor.
Bug #764994 may be related to this.
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 of gnome-session, then please follow https://wiki.gnome.org/GettingInTouch/BugReportingGuidelines and create a new ticket at https://gitlab.gnome.org/GNOME/gnome-session/-/issues/ Thank you for your understanding and your help.