1# X Window System {#sec-x11} 2 3The X Window System (X11) provides the basis of NixOS' graphical user 4interface. It can be enabled as follows: 5 6```nix 7{ 8 services.xserver.enable = true; 9} 10``` 11 12The X server will automatically detect and use the appropriate video 13driver from a set of X.org drivers (such as `vesa` and `intel`). You can 14also specify a driver manually, e.g. 15 16```nix 17{ 18 services.xserver.videoDrivers = [ "r128" ]; 19} 20``` 21 22to enable X.org's `xf86-video-r128` driver. 23 24You also need to enable at least one desktop or window manager. 25Otherwise, you can only log into a plain undecorated `xterm` window. 26Thus you should pick one or more of the following lines: 27 28```nix 29{ 30 services.xserver.desktopManager.plasma5.enable = true; 31 services.xserver.desktopManager.xfce.enable = true; 32 services.xserver.desktopManager.gnome.enable = true; 33 services.xserver.desktopManager.mate.enable = true; 34 services.xserver.windowManager.xmonad.enable = true; 35 services.xserver.windowManager.twm.enable = true; 36 services.xserver.windowManager.icewm.enable = true; 37 services.xserver.windowManager.i3.enable = true; 38 services.xserver.windowManager.herbstluftwm.enable = true; 39} 40``` 41 42NixOS's default *display manager* (the program that provides a graphical 43login prompt and manages the X server) is LightDM. You can select an 44alternative one by picking one of the following lines: 45 46```nix 47{ 48 services.displayManager.sddm.enable = true; 49 services.xserver.displayManager.gdm.enable = true; 50} 51``` 52 53You can set the keyboard layout (and optionally the layout variant): 54 55```nix 56{ 57 services.xserver.xkb.layout = "de"; 58 services.xserver.xkb.variant = "neo"; 59} 60``` 61 62The X server is started automatically at boot time. If you don't want 63this to happen, you can set: 64 65```nix 66{ 67 services.xserver.autorun = false; 68} 69``` 70 71The X server can then be started manually: 72 73```ShellSession 74# systemctl start display-manager.service 75``` 76 77On 64-bit systems, if you want OpenGL for 32-bit programs such as in 78Wine, you should also set the following: 79 80```nix 81{ 82 hardware.graphics.enable32Bit = true; 83} 84``` 85 86## Auto-login {#sec-x11-auto-login} 87 88The x11 login screen can be skipped entirely, automatically logging you 89into your window manager and desktop environment when you boot your 90computer. 91 92This is especially helpful if you have disk encryption enabled. Since 93you already have to provide a password to decrypt your disk, entering a 94second password to login can be redundant. 95 96To enable auto-login, you need to define your default window manager and 97desktop environment. If you wanted no desktop environment and i3 as your 98your window manager, you'd define: 99 100```nix 101{ 102 services.displayManager.defaultSession = "none+i3"; 103} 104``` 105 106Every display manager in NixOS supports auto-login, here is an example 107using lightdm for a user `alice`: 108 109```nix 110{ 111 services.xserver.displayManager.lightdm.enable = true; 112 services.displayManager.autoLogin.enable = true; 113 services.displayManager.autoLogin.user = "alice"; 114} 115``` 116 117## Running X without a display manager {#sec-x11-startx} 118 119It is possible to avoid a display manager entirely and starting the X server 120manually from a virtual terminal. Add to your configuration: 121```nix 122{ 123 services.xserver.displayManager.startx = { 124 enable = true; 125 generateScript = true; 126 }; 127} 128``` 129then you can start the X server with the `startx` command. 130 131The second option will generate a base `xinitrc` script that will run your 132window manager and set up the systemd user session. 133You can extend the script using the 134[extraCommands](#opt-services.xserver.displayManager.startx.extraCommands) 135option, for example: 136```nix 137{ 138 services.xserver.displayManager.startx = { 139 generateScript = true; 140 extraCommands = '' 141 xrdb -load .Xresources 142 xsetroot -solid '#666661' 143 xsetroot -cursor_name left_ptr 144 ''; 145 }; 146} 147``` 148or, alternatively, you can write your own from scratch in `~/.xinitrc`. 149 150In this case, remember you're responsible for starting the window manager, for 151example: 152```shell 153sxhkd & 154bspwm & 155``` 156and if you have enabled some systemd user service, you will probably want to 157also add these lines too: 158```shell 159# import required env variables from the current shell 160systemctl --user import-environment DISPLAY XDG_SESSION_ID 161# start all graphical user services 162systemctl --user start nixos-fake-graphical-session.target 163# start the user dbus daemon 164dbus-daemon --session --address="unix:path=/run/user/$(id -u)/bus" & 165``` 166 167## Intel Graphics drivers {#sec-x11--graphics-cards-intel} 168 169The default and recommended driver for Intel Graphics in X.org is `modesetting` 170(included in the xorg-server package itself). 171This is a generic driver which uses the kernel [mode 172setting](https://en.wikipedia.org/wiki/Mode_setting) (KMS) mechanism, it 173supports Glamor (2D graphics acceleration via OpenGL) and is actively 174maintained, it may perform worse in some cases (like in old chipsets). 175 176There is a second driver, `intel` (provided by the xf86-video-intel package), 177specific to older Intel iGPUs from generation 2 to 9. It is not recommended by 178most distributions: it lacks several modern features (for example, it doesn't 179support Glamor) and the package hasn't been officially updated since 2015. 180 181Third generation and older iGPUs (15-20+ years old) are not supported by the 182`modesetting` driver (X will crash upon startup). Thus, the `intel` driver is 183required for these chipsets. 184Otherwise, the results vary depending on the hardware, so you may have to try 185both drivers. Use the option 186[](#opt-services.xserver.videoDrivers) 187to set one. The recommended configuration for modern systems is: 188 189```nix 190{ 191 services.xserver.videoDrivers = [ "modesetting" ]; 192} 193``` 194::: {.note} 195The `modesetting` driver doesn't currently provide a `TearFree` option (this 196will become available in an upcoming X.org release), So, without using a 197compositor (for example, see [](#opt-services.picom.enable)) you will 198experience screen tearing. 199::: 200 201If you experience screen tearing no matter what, this configuration was 202reported to resolve the issue: 203 204```nix 205{ 206 services.xserver.videoDrivers = [ "intel" ]; 207 services.xserver.deviceSection = '' 208 Option "DRI" "2" 209 Option "TearFree" "true" 210 ''; 211} 212``` 213 214Note that this will likely downgrade the performance compared to 215`modesetting` or `intel` with DRI 3 (default). 216 217## Proprietary NVIDIA drivers {#sec-x11-graphics-cards-nvidia} 218 219NVIDIA provides a proprietary driver for its graphics cards that has 220better 3D performance than the X.org drivers. It is not enabled by 221default because it's not free software. You can enable it as follows: 222 223```nix 224{ 225 services.xserver.videoDrivers = [ "nvidia" ]; 226} 227``` 228 229If you have an older card, you may have to use one of the legacy drivers: 230 231```nix 232{ 233 hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.legacy_470; 234 hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.legacy_390; 235 hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.legacy_340; 236} 237``` 238 239You may need to reboot after enabling this driver to prevent a clash 240with other kernel modules. 241 242## Touchpads {#sec-x11-touchpads} 243 244Support for Synaptics touchpads (found in many laptops such as the Dell 245Latitude series) can be enabled as follows: 246 247```nix 248{ 249 services.libinput.enable = true; 250} 251``` 252 253The driver has many options (see [](#ch-options)). 254For instance, the following disables tap-to-click behavior: 255 256```nix 257{ 258 services.libinput.touchpad.tapping = false; 259} 260``` 261 262Note: the use of `services.xserver.synaptics` is deprecated since NixOS 26317.09. 264 265## GTK/Qt themes {#sec-x11-gtk-and-qt-themes} 266 267GTK themes can be installed either to user profile or system-wide (via 268`environment.systemPackages`). To make Qt 5 applications look similar to 269GTK ones, you can use the following configuration: 270 271```nix 272{ 273 qt.enable = true; 274 qt.platformTheme = "gtk2"; 275 qt.style = "gtk2"; 276} 277``` 278 279## Custom XKB layouts {#custom-xkb-layouts} 280 281It is possible to install custom [ XKB 282](https://en.wikipedia.org/wiki/X_keyboard_extension) keyboard layouts 283using the option `services.xserver.xkb.extraLayouts`. 284 285As a first example, we are going to create a layout based on the basic 286US layout, with an additional layer to type some greek symbols by 287pressing the right-alt key. 288 289Create a file called `us-greek` with the following content (under a 290directory called `symbols`; it's an XKB peculiarity that will help with 291testing): 292 293``` 294xkb_symbols "us-greek" 295{ 296 include "us(basic)" // includes the base US keys 297 include "level3(ralt_switch)" // configures right alt as a third level switch 298 299 key <LatA> { [ a, A, Greek_alpha ] }; 300 key <LatB> { [ b, B, Greek_beta ] }; 301 key <LatG> { [ g, G, Greek_gamma ] }; 302 key <LatD> { [ d, D, Greek_delta ] }; 303 key <LatZ> { [ z, Z, Greek_zeta ] }; 304}; 305``` 306 307A minimal layout specification must include the following: 308 309```nix 310{ 311 services.xserver.xkb.extraLayouts.us-greek = { 312 description = "US layout with alt-gr greek"; 313 languages = [ "eng" ]; 314 symbolsFile = /yourpath/symbols/us-greek; 315 }; 316} 317``` 318 319::: {.note} 320The name (after `extraLayouts.`) should match the one given to the 321`xkb_symbols` block. 322::: 323 324Applying this customization requires rebuilding several packages, and a 325broken XKB file can lead to the X session crashing at login. Therefore, 326you're strongly advised to **test your layout before applying it**: 327 328```ShellSession 329$ nix-shell -p xorg.xkbcomp 330$ setxkbmap -I/yourpath us-greek -print | xkbcomp -I/yourpath - $DISPLAY 331``` 332 333You can inspect the predefined XKB files for examples: 334 335```ShellSession 336$ echo "$(nix-build --no-out-link '<nixpkgs>' -A xorg.xkeyboardconfig)/etc/X11/xkb/" 337``` 338 339Once the configuration is applied, and you did a logout/login cycle, the 340layout should be ready to use. You can try it by e.g. running 341`setxkbmap us-greek` and then type `<alt>+a` (it may not get applied in 342your terminal straight away). To change the default, the usual 343`services.xserver.xkb.layout` option can still be used. 344 345A layout can have several other components besides `xkb_symbols`, for 346example we will define new keycodes for some multimedia key and bind 347these to some symbol. 348 349Use the *xev* utility from `pkgs.xorg.xev` to find the codes of the keys 350of interest, then create a `media-key` file to hold the keycodes 351definitions 352 353``` 354xkb_keycodes "media" 355{ 356 <volUp> = 123; 357 <volDown> = 456; 358} 359``` 360 361Now use the newly define keycodes in `media-sym`: 362 363``` 364xkb_symbols "media" 365{ 366 key.type = "ONE_LEVEL"; 367 key <volUp> { [ XF86AudioLowerVolume ] }; 368 key <volDown> { [ XF86AudioRaiseVolume ] }; 369} 370``` 371 372As before, to install the layout do 373 374```nix 375{ 376 services.xserver.xkb.extraLayouts.media = { 377 description = "Multimedia keys remapping"; 378 languages = [ "eng" ]; 379 symbolsFile = /path/to/media-key; 380 keycodesFile = /path/to/media-sym; 381 }; 382} 383``` 384 385::: {.note} 386The function `pkgs.writeText <filename> <content>` can be useful if you 387prefer to keep the layout definitions inside the NixOS configuration. 388::: 389 390Unfortunately, the Xorg server does not (currently) support setting a 391keymap directly but relies instead on XKB rules to select the matching 392components (keycodes, types, ...) of a layout. This means that 393components other than symbols won't be loaded by default. As a 394workaround, you can set the keymap using `setxkbmap` at the start of the 395session with: 396 397```nix 398{ 399 services.xserver.displayManager.sessionCommands = "setxkbmap -keycodes media"; 400} 401``` 402 403If you are manually starting the X server, you should set the argument 404`-xkbdir /etc/X11/xkb`, otherwise X won't find your layout files. For 405example with `xinit` run 406 407```ShellSession 408$ xinit -- -xkbdir /etc/X11/xkb 409``` 410 411To learn how to write layouts take a look at the XKB [documentation 412](https://www.x.org/releases/current/doc/xorg-docs/input/XKB-Enhancing.html#Defining_New_Layouts). 413More example layouts can also be found [here 414](https://wiki.archlinux.org/index.php/X_KeyBoard_extension#Basic_examples).