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