OK, I think I've tracked down the cause of this bug.

Thanks to MPX (multi-pointer X), it turns out that each X window
(including the root window) may have *multiple* cursor icon settings.
Traditionally, under the core X11 protocol, a window could only define a
"standard cursor", which can be set by the XDefineCursor(3) function.
However, XInput2 introduces the possibility of having multiple mouse
pointers on the screen, and it allows windows to define a "device
cursor" for each pointer individually.  This can be done though XInput's
XIDefineCursor(3) function.  Crucially, if a given window has both a
standard cursor and a device cursor defined, then the device cursor will
override the standard cursor, at least for the particular "master
pointer device" that the device cursor was defined for.

Here is the relevant extract from the XInput2 protocol specification, which is 
shipped as /usr/share/doc/x11proto-input-dev/XI2proto.html in the 
x11proto-input-dev package:
> Whenever device enters a window W, the cursor shape is selected in the
> following order:
> - if the current window has a device cursor C(d) defined for device,
>   display this cursor C(d).
> - otherwise, if the current window has a cursor C(w) defined in the core
>   protocol’s window attributes, display cursor C(w).
> - repeat on parent window until a cursor has been found.

On a typical system with a single master pointer device, this means that
once a device pointer is set, the standard cursor setting loses its
effect.  So, if something sets a device pointer on the root window, then
any program that that tries to change the cursor icon by setting the
root window's standard cursor (which includes xsetroot, XFCE, and GNOME)
is sabotaged.

And the final piece: if XInput support is available, GTK3's
implementation of gdk_window_set_cursor will use XIDefineCursor.  Since
both unity-greeter and lightdm-gtk-greeter use gdk_window_set_cursor,
that means both greeters set a device cursor on the root window.  From
that point on, xsetroot and friends are SOL.

The behavior of the xserver is set in the protocol specification, so we
can't "fix" this problem there. I think the best solution is to get
unity-greeter and lightdm-gtk-greeter to use XDefineCursor instead of
XIDefineCursor.  This might be done by modifying gdk_window_set_cursor()
or by modifying the  greeters to use XDefineCursor directly instead of
deferring to gdk.  swiftgeek's approach might work too, but I think we
can do something simpler than that.

In the meantime, working around this bug is somewhat of a pain because
(1) XIUndefineCursor doesn't seem to work correctly on the root window
(probably an xserver bug, I'll follow up on that later) and (2) the
xserver currently prohibits removal of the initial "Virtual core
pointer" master pointer device, which is the pointer device that our
greeters are setting a device cursor for.  So, once the device cursor is
set on the root window, I don't think there's any way to get the
standard cursor setting to work again.

A workaround is to (re)set the device cursor instead.  My attached
xiset.c will set the device cursor on the root window to whatever the
default XCursor theme is.  (I originally wrote it while trying to
understand the behavior of gdk_window_set_cursor().)  I set my desired
Xcursor theme in ~/.Xdefaults and have my DE run this program at login.
It does the job for now. I've also heard of an "xicursorset" tool
floating around, which might do the job as well.

** Attachment added: "xiset.c"
   
https://bugs.launchpad.net/lightdm/+bug/1024482/+attachment/3544110/+files/xiset.c

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/1024482

Title:
  Mouse cursor theme does not change from default after login

To manage notifications about this bug go to:
https://bugs.launchpad.net/lightdm/+bug/1024482/+subscriptions

-- 
ubuntu-bugs mailing list
ubuntu-bugs@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to