Ubuntu

Mouse cursor theme does not change from default after login

Reported by mtvoid on 2012-07-13
46
This bug affects 8 people
Affects Status Importance Assigned to Milestone
LightDM GTK+ Greeter
Undecided
Unassigned
lightdm (Debian)
Confirmed
Unknown
lightdm-gtk-greeter (Debian)
Confirmed
Unknown
unity-greeter (Ubuntu)
Undecided
Unassigned

Bug Description

When using LightDM to login to a GNOME Shell session, the mouse cursor's appearance does not change from what it is in the lightdm login screen (black pointer from default X theme). Any custom mouse cursor theme actually does apply within any open application windows, but hovering the cursor over the window title bar, the root window, or the Shell interface changes it back to the default black pointer, leading to an inconsistent appearance.

Changed in lightdm (Debian):
status: Unknown → New
Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in lightdm (Ubuntu):
status: New → Confirmed
Jason Conti (jconti) wrote :

We have actually been looking into this issue recently in #ubuntu, so I thought I'd add my finding here.

As mentioned in the linked debian bug, logging into the session with gdm fixes the issue (unless you are logging into a session that uses compiz). And at the bottom of the report, lightdm-kde-greeter works as well.

The only difference I found is that both lightdm-gtk-greeter and unity-greeter set the cursor on the root window:

/* Set default cursor */
gdk_window_set_cursor (gdk_get_default_root_window (), gdk_cursor_new (GDK_LEFT_PTR));

(for lightdm-gtk-greeter)

And I found that commenting that line out, and instead setting the cursor on login_window:

--- lightdm-gtk-greeter-1.1.5.orig/src/lightdm-gtk-greeter.c
+++ lightdm-gtk-greeter-1.1.5/src/lightdm-gtk-greeter.c
@@ -717,7 +717,7 @@ main (int argc, char **argv)
         return EXIT_FAILURE;

     /* Set default cursor */
- gdk_window_set_cursor (gdk_get_default_root_window (), gdk_cursor_new (GDK_LEFT_PTR));
+ //gdk_window_set_cursor (gdk_get_default_root_window (), gdk_cursor_new (GDK_LEFT_PTR));

     /* Load background */
     value = g_key_file_get_value (config, "greeter", "background", NULL);
@@ -940,6 +940,9 @@ main (int argc, char **argv)
     gtk_widget_show (GTK_WIDGET (login_window));
     center_window (login_window);

+ gdk_window_set_cursor (gtk_widget_get_window (login_window), gdk_cursor_new (GDK_LEFT_PTR));
+
+
     gtk_widget_show (GTK_WIDGET (panel_window));
     GtkAllocation allocation;
     gtk_widget_get_allocation (GTK_WIDGET (panel_window), &allocation);

Rebuilding lightdm-gtk-greeter and then logging in, cursor updating should work as expected. I'm not really suggesting this as a fix because it has its own issues (unless you are over the login_window, the cursor with be the X), but it demonstrates the problem.

Test Case:
1) Log in with lightdm-gtk-greeter to Gnome Classic (no effects) [or gnome-shell or really anything without compiz]
2) Run: gsettings set org.gnome.desktop.interfaces cursor-size 48
3) Notice that every cursor except the default left pointer is resized

Patch lightdm-gtk-greeter as above or use gdm and the cursor will immediately resize. (Changing cursor-theme has the same sort of effect, but we were trying to figure out why cursor-size didn't work).

I think the compiz problem is that compiz also sets the cursor on the root window.

Jason Conti (jconti) wrote :

I should also note that setting the cursor explicitly to the LEFT_PTR in any gtk app will cause that app to show cursor updates properly when hovered over (which is why I think Firefox still works when you hover over it as mentioned in bug #86184 ):

#include <gdk/gdk.h>
#include <gtk/gtk.h>

int
main()
{
  gtk_init(NULL, NULL);

  GdkCursor *default_cursor = gdk_cursor_new(GDK_ARROW);

  GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  g_signal_connect(G_OBJECT(window), "destroy", gtk_main_quit, NULL);
  gtk_widget_realize(window);
  gtk_widget_show(window);

  gdk_window_set_cursor(gtk_widget_get_window(window), default_cursor);
  g_object_unref(default_cursor);

  gtk_main();
  return 0;
}

And we can force a cursor update by setting the LEFT_PTR on the root window (but this will also break future cursor updates if you had logged in with gdm or lightdm-gtk-greeter with the patch above):

#include <gdk/gdk.h>
#include <gtk/gtk.h>

gboolean idle_cb(gpointer user_data)
{
  gtk_main_quit();
  return FALSE;
}

int main()
{
  gtk_init (NULL, NULL);

  GdkCursor *cursor = gdk_cursor_new (GDK_LEFT_PTR);
  gdk_window_set_cursor (gdk_get_default_root_window (), cursor);
  g_object_unref (cursor);

  g_idle_add (idle_cb, NULL);

  gtk_main ();
  return 0;
}

swiftgeek (swiftgeek) on 2012-08-29
Changed in lightdm:
status: New → Confirmed
Changed in lightdm (Debian):
status: New → Confirmed
Padfoot (padfoot) wrote :

I use lightdm with the gtk-greeter on Arch to log in to an Xfce session, and I do not experience any of these issues.

I found that removing my default cursor theme from /usr/share/icons I began experiencing the theme changing problem.

After applying the patch above, it made absolutely no difference to the theme changing behaviour. So I think this issue is quite simply a default theme is not being set correctly.

The solution is to set a default cursor theme as follows:

# mkdir /usr/share/icons/default
# touch /usr/share/icons/default/index.theme

Now edit index.theme and add the following:

[Icon Theme]
Inherits=<CURSOR THEME NAME>

The chosen cursor theme will now be applied on both light dm and your root window in your session.

Cheers.

Padfoot (padfoot) wrote :

Just to add and clarify, this is not a lightdm issue. Your DE should be theming the root window cursor theme, not the DM.

I think you will find this does not occur in KDE as it is setting the theme when the KDE session is started, and with Gnome, I am guessing the theme is set with GDM hence why the issue occurs in Gnome with lightdm and not GDM.

Xfce being a lighter DE and usually started with GDM (prior to Gnome3), Xfce left the root window cursor theming to GDM.

So for setups outside of the above, you need you set the default cursor theme yourself as I described in the previous post.

So, to be clear, root window cursor theming is the job of the DE, not the DM. When using tools outside of the DE defaults, expect some things to not work as expected as the "3rd party" tools do not have the same integration as the DE defaults do.

Cheers.

swiftgeek (swiftgeek) wrote :

XFCE4 can change cursors.
Also this doesn't affects QT apps at all

Jason Conti (jconti) wrote :

@Padfoot: I'm not saying this is a lightdm-gtk-greeter bug, as I said above, it only triggers the issue. It could well be an xorg or GTK bug.

What I was saying is that if I log into Gnome with lightdm-gtk-greeter (or unity-greeter) and the cursor is set on the root window, cursor changing and resizing does not work correctly in Gnome (I was pretty sure I could reproduce it on XFCE too, but maybe I am mistaken, I will test again later). If the cursor is not set on the root window, it works as expected (with metacity or mutter, not with compiz).

I should clarify that changing the cursor theme or size does partially work, every cursor will change except the default LEFT_PTR cursor.

I posted what I found here in the hope that maybe somebody else would have an idea where to look for the actual bug.

If it does work in XFCE then that would be great, maybe I can figure out why (XFCE still uses gtk2 right? maybe it is a gtk3 bug, which would explain why it works hovering over Firefox works, though I was pretty sure I could reproduce it with other gtk2 windows too, have to test that again as well).

swiftgeek (swiftgeek) wrote :

I mean that lightdm triggers something at least in GTK2/3. Even opera's own toolkit which reuses somehow GTK (if u tell it to do so) isn't affected.

I can confirm that about LEFT_PTR also. I can change mouse theme in xfce4 but LEFT_PTR is unchanged.

Also before LightDM there was LXDM. And before that was slim (and qingy ). GDM never was an option since it was overbloated.

and since LightDM uses mouse - it's its job to theme cursor properly and do not taint user space.
lightdm-gtk-greeter.conf -> cursor-name=Obsidian

Jason Conti (jconti) wrote :

Just tested again and I can reproduce the problem in XFCE 4.10 in quantal as well. Login with unity-greeter, Settings/Mouse and Touchpad/Theme, change it to something like redglass size 48, every cursor changes but LEFT_PTR.

Logging in with GDM and the cursor changes correctly.

Logging in with lightdm-gtk-greeter, LEFT_PTR not correctly set.

Logging in with lightdm-gtk-greeter without setting the cursor on the root window, cursor changes correctly.

Maybe this is an Ubuntu specific issue, although using the code from my second comment above to set the cursor on the root window in a default Fedora 17 Gnome session, and cursor theme changes and resizing stops working for the default LEFT_PTR, so I am skeptical.

Padfoot (padfoot) wrote :

Maybe it is an Ubuntu specific issue.

Ubuntu is well known for adding a large number of patches to a large number of applications/libraries/tools etc to better integrate these tools into the Ubuntu way of doing things. This is why it is difficult to port Ubuntu specific code to other distros.

@ swiftgeek, the cursor-name option in lightdm-gtk-greeter.conf actually does nothing. lightdm-gtk-greeter does not select a cursor theme, it just uses the system default (X default or theme specified in /usr/share/icons/default/index.theme) - of course, Ubuntu may have a patch which includes this option, and that could be the cause of the issue. And yes, it does use a cursor and yes, it uses the default theme but this should not affect the desktop session, only the lightdm session. Once you login, the lightdm session is closed and a new session in your username for your chosen DE is opened. It is the environment created by the DE that should be theming the root window cursor theme for this session.

Perhaps we should be looking at things like /etc/profile.d and others that configure your DE. Could simply be an environment variable either not being set correctly or at all.

All I can confirm is that the issue does not exist for me using Arch and Xfce, which to me, indicates it is a configuration issue, nothiong else.

Cheers.

swiftgeek (swiftgeek) wrote :

ENV variable? rly? And I already have said that xfce4 is doing it's job -.-
AND ONLY LEFT_PTR is affected.

"And we can force a cursor update by setting the LEFT_PTR on the root window (but this will also break future cursor updates if you had logged in with gdm or lightdm-gtk-greeter with the patch above)"
Sounds like perfect description of what is happening »already«

Also "/usr/share/icons/" isn't the only one path for cursor theme.

swiftgeek (swiftgeek) wrote :

And webkit greeter doesn't have that issue.

swiftgeek (swiftgeek) wrote :

I don't think it could be possible to fully fix this without wallpaper being an another widget/window :(
Or there could be fully transparent window/widget just in background - so it would be possible to assign a mouse cursor.

swiftgeek (swiftgeek) wrote :

Since nobody is investigating it further... i made sth brain-dead simple
https://gist.github.com/3803351
next i want to have wallpaper/solid color there and maybe finally set a cursor theme specified in config.

Daniel Gnoutcheff (gnoutchd) wrote :
Download full text (3.4 KiB)

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. ...

Read more...

swiftgeek (swiftgeek) wrote :

So i guess that the reason of why webkit/gtk-builder are working is a crazy race condition :]

Would it be possible to patch gdk_window_set_cursor() and include fixed one in greeters (eg. as __gdk_window_set_cursor() )
and post fixed one on gnome's bugzilla?

On 02/24/2013 03:25 AM, swiftgeek wrote:
> So i guess that the reason of why webkit/gtk-builder are working is a
> crazy race condition :]

I think the reason that lightdm-webkit-greeter is not affected is that
it links against GTK2, not GTK3. Both GTK2 and GTK3 define a
gdk_window_set_cursor() function: the GTK3 version uses XInput's
problematic XIDefineCursor function, while the GTK2 version does not.

As for the patch to lightdm-gtk-greeter: I think that works because with
the patch, gdk_window_set_cursor() is no longer called on the root
window, it's only called on windows created by the greeter itself.
These windows disappear once the greeter exits, so any device cursor
definitions would disappear with them.

It's not a problem when a program sets device cursors on it's own
windows: that only affects those windows and the program (presumably)
knows how to deal with them. It's when something sets a device cursor
on the *root* window that we have problems, because lots of programs
need to work with the root window and many of them don't use XInput2.

> Would it be possible to patch gdk_window_set_cursor() and include fixed one in greeters (eg. as __gdk_window_set_cursor() )
> and post fixed one on gnome's bugzilla?

Yeah, I'll take a shot at a patch. If we end up modifying the greeters,
though, I think it would be simpler to replace the call to
gdk_window_set_cursor() with a call to XDefineCursor(). The
implementation of gdk_window_set_cursor() is gnarlier than you might
think, since it deals with alternative windowing systems (Win32,
Wayland, HTML5, etc.) and stuff.

While mucking around in gtk/gdk, I discovered a better workaround for
this bug. While logged in as some user with sudo access, run the commands:

echo "GDK_CORE_DEVICE_EVENTS=true" | sudo tee ~lightdm/.pam_environment
sudo chown lightdm:lightdm ~lightdm/.pam_environment

This ensures that the next time any one of the lightdm greeters are run,
it will have an environment variable named GDK_CORE_DEVICE_EVENTS set.
This in turn causes gdk to disable its use of XInput2, thus avoiding
this bug. Once those commands are run, xsetroot and friends should work
upon the next login.

HTH!

swiftgeek (swiftgeek) wrote :

Or in case of systemd (tmpfiles.d)
f /run/lightdm/.pam_environment 0644 lightdm lightdm - GDK_CORE_DEVICE_EVENTS=true

affects: lightdm → unity-greeter
no longer affects: lightdm (Ubuntu)
affects: unity-greeter → unity-greeter (Ubuntu)

Control: tag -1 confirmed
On Sun, Mar 23, 2014 at 11:10:34PM +0000, Ken Milmore wrote:
> LightDM causes problems with mouse cursors and startup notifications on the
> Xfce desktop (and possibly elsewhere). These seem to be caused by the lightdm
> greeter setting a device-specific cursor on the root window (i.e. a cursor set
> through XIDefineCursor, called in this case through gdk_window_set_cursor).
> This cusror overrides any "normal" cursors set in the desktop environment with
> XDefineCursor.
>
> On Xfce in particular, the most noticeable effect is that application startup
> notifications do not work - no busy cursor is shown when an application is
> launched from the desktop or menus. Also, if a pointer theme is set, this is
> overridden on the root window which continues to show the pointer which was set
> by lightdm.
>
> An easy way to demonstrate this problem is to run "xsetroot -cursor_name watch"
> from a terminal window. A "busy" cursor should appear when the pointer is
> moved over the desktop; but instead the default arrow cursor remains.
>
> This problem appears to have already been reported in several other places:
>
> https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=694353
> https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=671121
> https://bugs.launchpad.net/ubuntu/+source/unity-greeter/+bug/1024482
>
> The discussion following on from the Ubuntu bug report seems to have got to the
> root of the problem: When a "device cursor" has been set, it overrides any
> "ordinary" cursor defined on the window. Unfortunately nobody seems to have
> applied a fix yet.

Thanks for the report and the patch. Since there's already a large
discussion on the launchpad bug, I'm CC:ing it in order to make
discussion there.
>
> I would like to suggest that the attached patch be applied, which I have
> tested on Wheezy with Xfce. It sets the root cursor using XDefineCursor, which
> avoids the problems caused by the XInput2 cursor precedence rules. A fairly
> thorough explanation of why this should work appears on comment 15 of the
> Ubuntu bug report.
>
> I think the patch should also apply against Jessie/Sid, although I haven't had
> a chance to test it on those platforms yet.

I'm not completely sure it's the right solution here. I mean, it might
be the wisest short-term one, but it'll also break XInput2 features. I
guess not much people already use them and I'm not sure how well they
work, but I guess the best way to fix the issue would be to use XInput2
API correctly everywhere, so the “right” cursor is always found.

I'm not sure what that means concerning “global” cursors like the
notification one (I guess it has no reason to be defined until we arrive
at the root window), but I guess that's something which should be
discussed at the GTK level.

Regards,
--
Yves-Alexis Perez

Changed in lightdm-gtk-greeter (Debian):
status: Unknown → Confirmed
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers

Bug attachments

Remote bug watches

Bug watches keep track of this bug in other bug trackers.