System cursor theme and scaling not being followed by some apps (system packages, flatpak)

Hey everyone, I’m very new to NixOS. I installed the KDE version with Plasma 6, and some apps I installed are not following the system cursor theme (breeze, in this case) and they are also not scaling correctly (fractional scaling). Some examples are heroic games launcher (installed from flatpak), steam (system package) and GIMP (flatpak and system package). One odd thing about Steam is that it also shrinks my cursor when on the Steam window. Here’s my configuration.nix if it helps:

# Edit this configuration file to define what should be installed on
# your system.  Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).

{ config, pkgs, ... }:

{
  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
    ];

  # Bootloader.
  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;

  networking.hostName = "nixos"; # Define your hostname.
  # networking.wireless.enable = true;  # Enables wireless support via wpa_supplicant.

  # Configure network proxy if necessary
  # networking.proxy.default = "http://user:password@proxy:port/";
  # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";

  # Enable networking
  networking.networkmanager.enable = true;

  # Set your time zone.
  time.timeZone = "";

  # Select internationalisation properties.
  i18n.defaultLocale = "pt_BR.UTF-8";

  i18n.extraLocaleSettings = {
    LC_ADDRESS = "pt_BR.UTF-8";
    LC_IDENTIFICATION = "pt_BR.UTF-8";
    LC_MEASUREMENT = "pt_BR.UTF-8";
    LC_MONETARY = "pt_BR.UTF-8";
    LC_NAME = "pt_BR.UTF-8";
    LC_NUMERIC = "pt_BR.UTF-8";
    LC_PAPER = "pt_BR.UTF-8";
    LC_TELEPHONE = "pt_BR.UTF-8";
    LC_TIME = "pt_BR.UTF-8";
  };

  # Enable the X11 windowing system.
  # You can disable this if you're only using the Wayland session.
  services.xserver.enable = false;

  # Enable the KDE Plasma Desktop Environment.
  services.displayManager.sddm.enable = true;
  services.desktopManager.plasma6.enable = true;

  # Enable Wayland for sddm
  services.displayManager.sddm.wayland.enable = true;

  # Configure keymap in X11
  services.xserver = {
    layout = "us";
    xkbVariant = "intl";
  };

  # Configure console keymap
  console.keyMap = "us-acentos";

  # Enable CUPS to print documents.
  services.printing.enable = true;

  # Enable sound with pipewire.
  hardware.pulseaudio.enable = false;
  security.rtkit.enable = true;
  services.pipewire = {
    enable = true;
    alsa.enable = true;
    alsa.support32Bit = true;
    pulse.enable = true;
    # If you want to use JACK applications, uncomment this
    #jack.enable = true;

    # use the example session manager (no others are packaged yet so this is enabled by default,
    # no need to redefine it in your config for now)
    #media-session.enable = true;
  };

  # Enable touchpad support (enabled default in most desktopManager).
  # services.xserver.libinput.enable = true;

  # Define a user account. Don't forget to set a password with ‘passwd’.
  users.users.anon = {
    isNormalUser = true;
    description = "anon";
    extraGroups = [ "networkmanager" "wheel" ];
    packages = with pkgs; [
    #  kdePackages.kate
    #  thunderbird
    ];
  };

  # Install firefox.
  programs.firefox.enable = true;

  # Allow unfree packages
  nixpkgs.config.allowUnfree = true;
  
  # Install steam.
  programs.steam = {
  enable = true;
  remotePlay.openFirewall = true; # Open ports in the firewall for Steam Remote Play
  dedicatedServer.openFirewall = true; # Open ports in the firewall for Source Dedicated Server
  localNetworkGameTransfers.openFirewall = true; # Open ports in the firewall for Steam Local Network Game Transfers
};

  # Set neovim as default editor
  programs.neovim = {
  enable = true;
  defaultEditor = true;
};
 
  # flatpak theming? According to nixos manual
  xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
  xdg.portal.config.common.default = "gtk";

  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [
  #  vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
  #  wget
  fastfetch
  kdePackages.sddm-kcm    
  audacious
  tor-browser-bundle-bin
  libreoffice-qt6-fresh
  fish
  starship
  gitMinimal
  wl-clipboard
  ];

  # KDE Plasma 6 packages to exclude
  environment.plasma6.excludePackages = with pkgs.kdePackages; [
  elisa
  kate
  okular
];

  # NVIDIA
  # Enable OpenGL
  hardware.opengl = {
    enable = true;
  };

  # Load nvidia driver for Xorg and Wayland
  services.xserver.videoDrivers = ["nvidia"];

  hardware.nvidia = {

    # Modesetting is required.
    modesetting.enable = true;

    # Nvidia power management. Experimental, and can cause sleep/suspend to fail.
    # Enable this if you have graphical corruption issues or application crashes after waking
    # up from sleep. This fixes it by saving the entire VRAM memory to /tmp/ instead 
    # of just the bare essentials.
    powerManagement.enable = false;

    # Fine-grained power management. Turns off GPU when not in use.
    # Experimental and only works on modern Nvidia GPUs (Turing or newer).
    powerManagement.finegrained = false;

    # Use the NVidia open source kernel module (not to be confused with the
    # independent third-party "nouveau" open source driver).
    # Support is limited to the Turing and later architectures. Full list of 
    # supported GPUs is at: 
    # https://github.com/NVIDIA/open-gpu-kernel-modules#compatible-gpus 
    # Only available from driver 515.43.04+
    # Currently alpha-quality/buggy, so false is currently the recommended setting.
    open = false;

    # Enable the Nvidia settings menu,
	# accessible via `nvidia-settings`.
    nvidiaSettings = false;

    # Optionally, you may need to select the appropriate driver version for your specific GPU.
    package = config.boot.kernelPackages.nvidiaPackages.stable;
  };
  hardware.nvidia.prime = {
		offload = {
			enable = true;
			enableOffloadCmd = true;
		};
		# Make sure to use the correct Bus ID values for your system!
		intelBusId = "PCI:0:2:0";
		nvidiaBusId = "PCI:1:0:0";
                # amdgpuBusId = "PCI:54:0:0"; For AMD GPU
	};

  # Some programs need SUID wrappers, can be configured further or are
  # started in user sessions.
  # programs.mtr.enable = true;
  # programs.gnupg.agent = {
  #   enable = true;
  #   enableSSHSupport = true;
  # };

  # List services that you want to enable:

  # Enable the OpenSSH daemon.
  # services.openssh.enable = true;
  services.flatpak.enable = true;  

  # Open ports in the firewall.
  # networking.firewall.allowedTCPPorts = [ ... ];
  # networking.firewall.allowedUDPPorts = [ ... ];
  # Or disable the firewall altogether.
  # networking.firewall.enable = false;

  # This value determines the NixOS release from which the default
  # settings for stateful data, like file locations and database versions
  # on your system were taken. It‘s perfectly fine and recommended to leave
  # this value at the release version of the first install of this system.
  # Before changing this value read the documentation for this option
  # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
  system.stateVersion = "24.05"; # Did you read the comment?

}

Thanks in advance for your time!

This will be wayland/xwayland incompatibility. You probably have a high dpi monitor, so wayland does automatic scaling, while xwayland does not.

You can work around it somewhat with the XCURSOR_THEME and XCURSOR_SIZE variables, but if you ever connect a different dpi monitor things will get whacky.

Well, at least you have a direction to look into.

Weird, last I checked Plasma did fractional scaling perfectly well on Wayland with xwayland apps since even Plasma 5 LTS, I may be wrong though. Still, does this explain the weird cursor behaviour in some apps? (Steam scales fine when setting -forcedesktopscaling, running on xwayland, only the cursor looks wrong). Fedora and other distros are able to scale xwayland apps and apply the system theme. Is there something I’m missing? This issue says it’s been fixed but maybe I’m missing something

Add xsettingsd to systemPackages.

This almost fixed everything, thanks. But GIMP is still using a tiny cursor and not scaling, and Steam scales the cursor correctly but still shows the tiny cursor (like in GIMP) on the edges of the window. Putting images here to visualize it: imgur

That issue is unrelated, it’s about flatpak being unable to access host icons, and should not apply to steam.

It’s not about xwayland not being configured to use the same cursor size/icon as its host wayland compositor.

Yeah, I think that’s expected, as it would cause the cursor to be scaled.

That too is expected since XCURSOR_THEME (or the relevant xsetting with xsettingsd with KDE) isn’t set, so the default X icon should be used.

If you use xsettingsd instead of the variables, make sure your Xresources are configured correctly.

In fairness, I have no idea if plasma does something fancy to force xwayland to do scaling correctly, my experience comes from the various wlroots compositors that do not. It’s also possible other distros have some additional rcfiles that fix this.

Either way, doesn’t hurt trying to set the cursor size/theme with those variables/xresources for the plasma session to verify if this is indeed the issue.

1 Like

GIMP uses gtk2 which doesn’t support scaling. Although even though gtk3 supports scaling, it doesn’t support fractional scaling so both gtk2 and gtk3 won’t scale anything but fonts as long as you have less than 2x scaling.

idk about steam, I don’t use it.

1 Like

Cursor seem to be ok in GIMP for me though so maybe you have manually set cursor size somewhere before. It’s 24 in plasma settings for me and I see plasma correctly scales it to 32 in dump_xsettings and xrdb -query:

   dump_xsettings
Gdk/UnscaledDPI 132710
Gdk/WindowScalingFactor 1
Gtk/ButtonImages 1
Gtk/CursorThemeName "breeze_cursors"
Gtk/CursorThemeSize 32
Gtk/DecorationLayout "icon:minimize,maximize,close"
Gtk/EnableAnimations 1
Gtk/FontName "Sans Serif,  10"
Gtk/MenuImages 1
Gtk/PrimaryButtonWarpsSlider 1
Gtk/ToolbarStyle 3
Net/IconThemeName "Papirus"
Net/SoundThemeName "ocean"
Net/ThemeName "Adapta-Eta"
   xrdb -query
Xcursor.size:   32
Xcursor.theme:  breeze_cursors
Xft.antialias:  1
Xft.dpi:        129
Xft.hinting:    1
Xft.hintstyle:  hintslight
Xft.rgba:       rgb

It’s 24 for me too, though a bit different in xsettings:

dump_xsettings
Gdk/UnscaledDPI 122880
Gdk/WindowScalingFactor 1
Gtk/ButtonImages 1
Gtk/CursorThemeName "breeze_cursors"
Gtk/CursorThemeSize 30
Gtk/DecorationLayout "icon:minimize,maximize,close"
Gtk/EnableAnimations 1
Gtk/FontName "Noto Sans,  12"
Gtk/MenuImages 1
Gtk/PrimaryButtonWarpsSlider 1
Gtk/ToolbarStyle 3
Net/IconThemeName "breeze-dark"
Net/SoundThemeName "ocean"
Net/ThemeName "Breeze-Dark"

I don’t know if xrdb -query works in ephemeral shell but it outputs nothing for me.

[nix-shell:~]$ xrdb -query

[nix-shell:~]$

Do you have xrdb without nix-shell? If you don’t, plasma would be unable to call it on launch and set the settings.

1 Like

It works now. Thank you very much. I would’ve never figured this out just googling endlessly. Everything is working as expected (by the way, yes, I installed the package you said and after a reboot everything is working)

For anyone coming here in the future, I got everything working, thanks to everyone in this thread and especially @ilya-fedin for helping me figure this out.
At the end of the day, all I had to do was add xsettingsd and xorg.xrdb to environment.systemPackages and, after a reboot, everything is working as expected.

2 Likes