I noticed that XMonad uses the wrong cursor theme when dragging or resizing a window. After asking the XMonad community on Matrix, I figured the problem is more likely found in my nix configuration.
When resizing or moving a window, the cursor theme changes to one different from what I had configured. The cursor theme is configured via NixOS for the displayManager (lightdm) options and home-manager for the entire session/user.
An interesting thing is that XMonad seems to inherit the cursor theme I have set up for lightdm. If I don’t set any theme for lightdm’s cursor, XMonad will not use the right theme at the root window. A quick search can find that XMonad does not set the root window’s cursor glyph, but I have found no similar example on the cursor theme.
Here’s a minimal (100LoC) configuration that spins up a vm to demonstrate the issue. VM in my dotfiles on Codeberg. The file is self-contained beside using niv to pin sources.
Steps to reproduce the issue:
Clone the dotfiles repo (and switch to the xmonad-cursor-theme-repr branch)
At the root of the repo, run nix-build --attr nixosConfigurations.vm.config.system.build.vm and then run the vm.
In the VM, use shift+meta+enter to open at least one terminal window, then hold the meta key and drag it with left click. You should see the cursor theme being inconsistent.
Note: the theme has a circular dragging cursor glyph (you can visualize it using xsetroot -cursor_name fleur and then xsetroot -cursor_name left_ptr to undo)
Top-level options declared under this submodule are backend independent options. Options declared under namespaces such as x11 are backend specific options. By default, only backend independent cursor configurations are generated. If you need configurations for specific backends, you can toggle them via the enable option. For example, home.pointerCursor.x11.enable will enable x11 cursor configurations.
Note that this will merely generate the cursor configurations. To apply the configurations, the relevant subsytems must also be configured. For example, home.pointerCursor.gtk.enable will generate the gtk cursor configuration, but gtk.enable needs to be set for it to be applied.
So you most likely need to enable the gtk/x11 home-manager config modules, otherwise there is just some inert cursor configuration somewhere.
It changes when you start resizing stuff because the moment something changes the cursor, the X11 defaults become applied, since the lightdm greeter (presumably gtk) is no longer overriding that. Cursor handling has always been a PITA on the Linux desktop, every toolkit wanting to do it themselves…
I would have assumed those. There’s also a chance you’re not setting up the shell sourcing correctly, which might matter depending on how your session is initialized; do you use any of the programs.*sh modules?
Honestly at that point it’s worth working in reverse, and checking if all the relevant configuration files are created and sourced. I’d dig into the home-manager modules to see what the effect of setting those options is and then figure out whether that actually matches your local configuration. Most likely you’re missing an xrdb merge somewhere.
And yeah, home-manager modules can be a bit of a mess. Part of it is simply because Linux desktop session management is a discordant cacophony of different things not agreeing about how things should be done, especially in WM land.
I do, I have programs.fish.enable set to true for both NixOS and home-manager.
However, in the vm I have my login shell set to bash and the problem is still there. It seems unlikely I have messed that up somehow as I’m following the default configuration.
I just tried to test this actually!
I read the home-manager source code for the xsession module (modules/xsession.nix).
Here’s what I have tried, and to be honest it all looks normal to me and I have no idea what’s wrong.
I switched to gdm from lightdm in the vm to test since it doesn’t set cursor and makes the problem more apparent.
Make sure the file ~/.xprofile is generated with the right content
Append echo "====test=====" | systemd-cat in ~/.xprofile, I could see the line in journalctl, the command has indeed been run.
Rename the file to ~/.xsessionrc because a post online said it’s sourced earlier. I also tried having both ~/.xsessionrc and ~/.xprofile with the same content (didn’t work)
My XMonad is managed by NixOS module and I found the option services.xserver.displayManager.sessionCommands. I quote, “Shell commands executed just before the window or desktop manager is started.” I referenced the content of ~/.xprofile in this option. The grabbing cursor is still incorrect, however this did set the root window cursor (problem visible due to gdm not setting the cursor).
You can check if X actually has the settings set with xrdb -query -all.
That said, if the root cursor is set correctly now, does it return to the wrong cursor after grabbing, or are you just seeing the wrong cursor used for grabbing? There’s a chance the cursor package itself just isn’t working correctly.
If it just returns to the wrong cursor, what terminal are you using? Or, more specifically, what toolkit is the window that’s responsible for changing your cursor to the wrong one using?
Good call. It indeed has the cursor set correctly.
To check this I tried the Bibata cursor package, and I’m having the same problem.
On my host machine, everything from digikam to firefox and kitty is affected. I’m not exactly sure which toolkit each of these use, probably both qt and gtk in this case?
I tried to run this but it says “No schemas installed”.
I also just tried to put the cursor package to environment.systemPackages and that didn’t fix it either.
Should I try the command right above with seat? I’m not familiar with it.
No, that’s just setting the equivalent of xresources with sway.
At least kitty directly uses X11, so that’s a good testbed.
So at this point it’s just the wrong cursor for grabbing windows? I think that must be xmonad related, clearly setting the sessionCommands now loads the Xresources settings correctly. At the very least I have no idea what else could be wrong.
You may need programs.dconf.enable
FWIW, don’t trust anything anyone says about x init scripts. That, too, is a horrible mess - Xorg themselves defined multiple different “specs” (really just “what was done at the time on someone’s corporate network”) for what scripts should be executed when (startx and xinit, as well as xdm), and ultimately all of that ends up implemented by distro maintainers because it’s all just shell scripts calling each other. It all differs based on whether and which display manager you use, and what your distro does.
When I still used X I dug through NixOS’ xinit code, and how it interacts with the various display managers, and eventually the upstream docs and scripts from Xorg, but it’s all quite horrible and I don’t remember the details.
It’s why I switched to gtkgreet (notReGreet since it attempts to reimplement the Xorg mess), the beast I know and whatnot, but I admittedly miss lightdm’s “flicker-free” features…