at 23.05-pre 28 kB view raw
1{ config, lib, utils, pkgs, ... }: 2 3with lib; 4 5let 6 7 # Abbreviations. 8 cfg = config.services.xserver; 9 xorg = pkgs.xorg; 10 11 12 # Map video driver names to driver packages. FIXME: move into card-specific modules. 13 knownVideoDrivers = { 14 # Alias so people can keep using "virtualbox" instead of "vboxvideo". 15 virtualbox = { modules = [ xorg.xf86videovboxvideo ]; driverName = "vboxvideo"; }; 16 17 # Alias so that "radeon" uses the xf86-video-ati driver. 18 radeon = { modules = [ xorg.xf86videoati ]; driverName = "ati"; }; 19 20 # modesetting does not have a xf86videomodesetting package as it is included in xorgserver 21 modesetting = {}; 22 }; 23 24 fontsForXServer = 25 config.fonts.fonts ++ 26 # We don't want these fonts in fonts.conf, because then modern, 27 # fontconfig-based applications will get horrible bitmapped 28 # Helvetica fonts. It's better to get a substitution (like Nimbus 29 # Sans) than that horror. But we do need the Adobe fonts for some 30 # old non-fontconfig applications. (Possibly this could be done 31 # better using a fontconfig rule.) 32 [ pkgs.xorg.fontadobe100dpi 33 pkgs.xorg.fontadobe75dpi 34 ]; 35 36 xrandrOptions = { 37 output = mkOption { 38 type = types.str; 39 example = "DVI-0"; 40 description = lib.mdDoc '' 41 The output name of the monitor, as shown by 42 {manpage}`xrandr(1)` invoked without arguments. 43 ''; 44 }; 45 46 primary = mkOption { 47 type = types.bool; 48 default = false; 49 description = lib.mdDoc '' 50 Whether this head is treated as the primary monitor, 51 ''; 52 }; 53 54 monitorConfig = mkOption { 55 type = types.lines; 56 default = ""; 57 example = '' 58 DisplaySize 408 306 59 Option "DPMS" "false" 60 ''; 61 description = lib.mdDoc '' 62 Extra lines to append to the `Monitor` section 63 verbatim. Available options are documented in the MONITOR section in 64 {manpage}`xorg.conf(5)`. 65 ''; 66 }; 67 }; 68 69 # Just enumerate all heads without discarding XRandR output information. 70 xrandrHeads = let 71 mkHead = num: config: { 72 name = "multihead${toString num}"; 73 inherit config; 74 }; 75 in imap1 mkHead cfg.xrandrHeads; 76 77 xrandrDeviceSection = let 78 monitors = forEach xrandrHeads (h: '' 79 Option "monitor-${h.config.output}" "${h.name}" 80 ''); 81 in concatStrings monitors; 82 83 # Here we chain every monitor from the left to right, so we have: 84 # m4 right of m3 right of m2 right of m1 .----.----.----.----. 85 # Which will end up in reverse ----------> | m1 | m2 | m3 | m4 | 86 # `----^----^----^----' 87 xrandrMonitorSections = let 88 mkMonitor = previous: current: singleton { 89 inherit (current) name; 90 value = '' 91 Section "Monitor" 92 Identifier "${current.name}" 93 ${optionalString (current.config.primary) '' 94 Option "Primary" "true" 95 ''} 96 ${optionalString (previous != []) '' 97 Option "RightOf" "${(head previous).name}" 98 ''} 99 ${current.config.monitorConfig} 100 EndSection 101 ''; 102 } ++ previous; 103 monitors = reverseList (foldl mkMonitor [] xrandrHeads); 104 in concatMapStrings (getAttr "value") monitors; 105 106 configFile = pkgs.runCommand "xserver.conf" 107 { fontpath = optionalString (cfg.fontPath != null) 108 ''FontPath "${cfg.fontPath}"''; 109 inherit (cfg) config; 110 preferLocalBuild = true; 111 } 112 '' 113 echo 'Section "Files"' >> $out 114 echo $fontpath >> $out 115 116 for i in ${toString fontsForXServer}; do 117 if test "''${i:0:''${#NIX_STORE}}" == "$NIX_STORE"; then 118 for j in $(find $i -name fonts.dir); do 119 echo " FontPath \"$(dirname $j)\"" >> $out 120 done 121 fi 122 done 123 124 for i in $(find ${toString cfg.modules} -type d); do 125 if test $(echo $i/*.so* | wc -w) -ne 0; then 126 echo " ModulePath \"$i\"" >> $out 127 fi 128 done 129 130 echo '${cfg.filesSection}' >> $out 131 echo 'EndSection' >> $out 132 echo >> $out 133 134 echo "$config" >> $out 135 ''; # */ 136 137 prefixStringLines = prefix: str: 138 concatMapStringsSep "\n" (line: prefix + line) (splitString "\n" str); 139 140 indent = prefixStringLines " "; 141in 142 143{ 144 145 imports = 146 [ ./display-managers/default.nix 147 ./window-managers/default.nix 148 ./desktop-managers/default.nix 149 (mkRemovedOptionModule [ "services" "xserver" "startGnuPGAgent" ] 150 "See the 16.09 release notes for more information.") 151 (mkRemovedOptionModule 152 [ "services" "xserver" "startDbusSession" ] 153 "The user D-Bus session is now always socket activated and this option can safely be removed.") 154 (mkRemovedOptionModule [ "services" "xserver" "useXFS" ] 155 "Use services.xserver.fontPath instead of useXFS") 156 (mkRemovedOptionModule [ "services" "xserver" "useGlamor" ] 157 "Option services.xserver.useGlamor was removed because it is unnecessary. Drivers that uses Glamor will use it automatically.") 158 ]; 159 160 161 ###### interface 162 163 options = { 164 165 services.xserver = { 166 167 enable = mkOption { 168 type = types.bool; 169 default = false; 170 description = lib.mdDoc '' 171 Whether to enable the X server. 172 ''; 173 }; 174 175 autorun = mkOption { 176 type = types.bool; 177 default = true; 178 description = lib.mdDoc '' 179 Whether to start the X server automatically. 180 ''; 181 }; 182 183 excludePackages = mkOption { 184 default = []; 185 example = literalExpression "[ pkgs.xterm ]"; 186 type = types.listOf types.package; 187 description = lib.mdDoc "Which X11 packages to exclude from the default environment"; 188 }; 189 190 exportConfiguration = mkOption { 191 type = types.bool; 192 default = false; 193 description = lib.mdDoc '' 194 Whether to symlink the X server configuration under 195 {file}`/etc/X11/xorg.conf`. 196 ''; 197 }; 198 199 enableTCP = mkOption { 200 type = types.bool; 201 default = false; 202 description = lib.mdDoc '' 203 Whether to allow the X server to accept TCP connections. 204 ''; 205 }; 206 207 autoRepeatDelay = mkOption { 208 type = types.nullOr types.int; 209 default = null; 210 description = lib.mdDoc '' 211 Sets the autorepeat delay (length of time in milliseconds that a key must be depressed before autorepeat starts). 212 ''; 213 }; 214 215 autoRepeatInterval = mkOption { 216 type = types.nullOr types.int; 217 default = null; 218 description = lib.mdDoc '' 219 Sets the autorepeat interval (length of time in milliseconds that should elapse between autorepeat-generated keystrokes). 220 ''; 221 }; 222 223 inputClassSections = mkOption { 224 type = types.listOf types.lines; 225 default = []; 226 example = literalExpression '' 227 [ ''' 228 Identifier "Trackpoint Wheel Emulation" 229 MatchProduct "ThinkPad USB Keyboard with TrackPoint" 230 Option "EmulateWheel" "true" 231 Option "EmulateWheelButton" "2" 232 Option "Emulate3Buttons" "false" 233 ''' 234 ] 235 ''; 236 description = lib.mdDoc "Content of additional InputClass sections of the X server configuration file."; 237 }; 238 239 modules = mkOption { 240 type = types.listOf types.path; 241 default = []; 242 example = literalExpression "[ pkgs.xf86_input_wacom ]"; 243 description = lib.mdDoc "Packages to be added to the module search path of the X server."; 244 }; 245 246 resolutions = mkOption { 247 type = types.listOf types.attrs; 248 default = []; 249 example = [ { x = 1600; y = 1200; } { x = 1024; y = 786; } ]; 250 description = lib.mdDoc '' 251 The screen resolutions for the X server. The first element 252 is the default resolution. If this list is empty, the X 253 server will automatically configure the resolution. 254 ''; 255 }; 256 257 videoDrivers = mkOption { 258 type = types.listOf types.str; 259 default = [ "amdgpu" "radeon" "nouveau" "modesetting" "fbdev" ]; 260 example = [ 261 "nvidia" "nvidiaLegacy390" "nvidiaLegacy340" "nvidiaLegacy304" 262 "amdgpu-pro" 263 ]; 264 # TODO(@oxij): think how to easily add the rest, like those nvidia things 265 relatedPackages = concatLists 266 (mapAttrsToList (n: v: 267 optional (hasPrefix "xf86video" n) { 268 path = [ "xorg" n ]; 269 title = removePrefix "xf86video" n; 270 }) pkgs.xorg); 271 description = lib.mdDoc '' 272 The names of the video drivers the configuration 273 supports. They will be tried in order until one that 274 supports your card is found. 275 Don't combine those with "incompatible" OpenGL implementations, 276 e.g. free ones (mesa-based) with proprietary ones. 277 278 For unfree "nvidia*", the supported GPU lists are on 279 https://www.nvidia.com/object/unix.html 280 ''; 281 }; 282 283 videoDriver = mkOption { 284 type = types.nullOr types.str; 285 default = null; 286 example = "i810"; 287 description = lib.mdDoc '' 288 The name of the video driver for your graphics card. This 289 option is obsolete; please set the 290 {option}`services.xserver.videoDrivers` instead. 291 ''; 292 }; 293 294 drivers = mkOption { 295 type = types.listOf types.attrs; 296 internal = true; 297 description = lib.mdDoc '' 298 A list of attribute sets specifying drivers to be loaded by 299 the X11 server. 300 ''; 301 }; 302 303 dpi = mkOption { 304 type = types.nullOr types.int; 305 default = null; 306 description = lib.mdDoc '' 307 Force global DPI resolution to use for X server. It's recommended to 308 use this only when DPI is detected incorrectly; also consider using 309 `Monitor` section in configuration file instead. 310 ''; 311 }; 312 313 updateDbusEnvironment = mkOption { 314 type = types.bool; 315 default = false; 316 description = lib.mdDoc '' 317 Whether to update the DBus activation environment after launching the 318 desktop manager. 319 ''; 320 }; 321 322 layout = mkOption { 323 type = types.str; 324 default = "us"; 325 description = lib.mdDoc '' 326 Keyboard layout, or multiple keyboard layouts separated by commas. 327 ''; 328 }; 329 330 xkbModel = mkOption { 331 type = types.str; 332 default = "pc104"; 333 example = "presario"; 334 description = lib.mdDoc '' 335 Keyboard model. 336 ''; 337 }; 338 339 xkbOptions = mkOption { 340 type = types.commas; 341 default = "terminate:ctrl_alt_bksp"; 342 example = "grp:caps_toggle,grp_led:scroll"; 343 description = lib.mdDoc '' 344 X keyboard options; layout switching goes here. 345 ''; 346 }; 347 348 xkbVariant = mkOption { 349 type = types.str; 350 default = ""; 351 example = "colemak"; 352 description = lib.mdDoc '' 353 X keyboard variant. 354 ''; 355 }; 356 357 xkbDir = mkOption { 358 type = types.path; 359 default = "${pkgs.xkeyboard_config}/etc/X11/xkb"; 360 defaultText = literalExpression ''"''${pkgs.xkeyboard_config}/etc/X11/xkb"''; 361 description = lib.mdDoc '' 362 Path used for -xkbdir xserver parameter. 363 ''; 364 }; 365 366 config = mkOption { 367 type = types.lines; 368 description = lib.mdDoc '' 369 The contents of the configuration file of the X server 370 ({file}`xorg.conf`). 371 372 This option is set by multiple modules, and the configs are 373 concatenated together. 374 375 In Xorg configs the last config entries take precedence, 376 so you may want to use `lib.mkAfter` on this option 377 to override NixOS's defaults. 378 ''; 379 }; 380 381 filesSection = mkOption { 382 type = types.lines; 383 default = ""; 384 example = ''FontPath "/path/to/my/fonts"''; 385 description = lib.mdDoc "Contents of the first `Files` section of the X server configuration file."; 386 }; 387 388 deviceSection = mkOption { 389 type = types.lines; 390 default = ""; 391 example = "VideoRAM 131072"; 392 description = lib.mdDoc "Contents of the first Device section of the X server configuration file."; 393 }; 394 395 screenSection = mkOption { 396 type = types.lines; 397 default = ""; 398 example = '' 399 Option "RandRRotation" "on" 400 ''; 401 description = lib.mdDoc "Contents of the first Screen section of the X server configuration file."; 402 }; 403 404 monitorSection = mkOption { 405 type = types.lines; 406 default = ""; 407 example = "HorizSync 28-49"; 408 description = lib.mdDoc "Contents of the first Monitor section of the X server configuration file."; 409 }; 410 411 extraConfig = mkOption { 412 type = types.lines; 413 default = ""; 414 description = lib.mdDoc "Additional contents (sections) included in the X server configuration file"; 415 }; 416 417 xrandrHeads = mkOption { 418 default = []; 419 example = [ 420 "HDMI-0" 421 { output = "DVI-0"; primary = true; } 422 { output = "DVI-1"; monitorConfig = "Option \"Rotate\" \"left\""; } 423 ]; 424 type = with types; listOf (coercedTo str (output: { 425 inherit output; 426 }) (submodule { options = xrandrOptions; })); 427 # Set primary to true for the first head if no other has been set 428 # primary already. 429 apply = heads: let 430 hasPrimary = any (x: x.primary) heads; 431 firstPrimary = head heads // { primary = true; }; 432 newHeads = singleton firstPrimary ++ tail heads; 433 in if heads != [] && !hasPrimary then newHeads else heads; 434 description = lib.mdDoc '' 435 Multiple monitor configuration, just specify a list of XRandR 436 outputs. The individual elements should be either simple strings or 437 an attribute set of output options. 438 439 If the element is a string, it is denoting the physical output for a 440 monitor, if it's an attribute set, you must at least provide the 441 {option}`output` option. 442 443 The monitors will be mapped from left to right in the order of the 444 list. 445 446 By default, the first monitor will be set as the primary monitor if 447 none of the elements contain an option that has set 448 {option}`primary` to `true`. 449 450 ::: {.note} 451 Only one monitor is allowed to be primary. 452 ::: 453 454 Be careful using this option with multiple graphic adapters or with 455 drivers that have poor support for XRandR, unexpected things might 456 happen with those. 457 ''; 458 }; 459 460 serverFlagsSection = mkOption { 461 default = ""; 462 type = types.lines; 463 example = 464 '' 465 Option "BlankTime" "0" 466 Option "StandbyTime" "0" 467 Option "SuspendTime" "0" 468 Option "OffTime" "0" 469 ''; 470 description = lib.mdDoc "Contents of the ServerFlags section of the X server configuration file."; 471 }; 472 473 moduleSection = mkOption { 474 type = types.lines; 475 default = ""; 476 example = 477 '' 478 SubSection "extmod" 479 EndSubsection 480 ''; 481 description = lib.mdDoc "Contents of the Module section of the X server configuration file."; 482 }; 483 484 serverLayoutSection = mkOption { 485 type = types.lines; 486 default = ""; 487 example = 488 '' 489 Option "AIGLX" "true" 490 ''; 491 description = lib.mdDoc "Contents of the ServerLayout section of the X server configuration file."; 492 }; 493 494 extraDisplaySettings = mkOption { 495 type = types.lines; 496 default = ""; 497 example = "Virtual 2048 2048"; 498 description = lib.mdDoc "Lines to be added to every Display subsection of the Screen section."; 499 }; 500 501 defaultDepth = mkOption { 502 type = types.int; 503 default = 0; 504 example = 8; 505 description = lib.mdDoc "Default colour depth."; 506 }; 507 508 fontPath = mkOption { 509 type = types.nullOr types.str; 510 default = null; 511 example = "unix/:7100"; 512 description = lib.mdDoc '' 513 Set the X server FontPath. Defaults to null, which 514 means the compiled in defaults will be used. See 515 man xorg.conf for details. 516 ''; 517 }; 518 519 tty = mkOption { 520 type = types.nullOr types.int; 521 default = 7; 522 description = lib.mdDoc "Virtual console for the X server."; 523 }; 524 525 display = mkOption { 526 type = types.nullOr types.int; 527 default = 0; 528 description = lib.mdDoc "Display number for the X server."; 529 }; 530 531 virtualScreen = mkOption { 532 type = types.nullOr types.attrs; 533 default = null; 534 example = { x = 2048; y = 2048; }; 535 description = lib.mdDoc '' 536 Virtual screen size for Xrandr. 537 ''; 538 }; 539 540 logFile = mkOption { 541 type = types.nullOr types.str; 542 default = "/dev/null"; 543 example = "/var/log/Xorg.0.log"; 544 description = lib.mdDoc '' 545 Controls the file Xorg logs to. 546 547 The default of `/dev/null` is set so that systemd services (like `displayManagers`) only log to the journal and don't create their own log files. 548 549 Setting this to `null` will not pass the `-logfile` argument to Xorg which allows it to log to its default logfile locations instead (see `man Xorg`). You probably only want this behaviour when running Xorg manually (e.g. via `startx`). 550 ''; 551 }; 552 553 verbose = mkOption { 554 type = types.nullOr types.int; 555 default = 3; 556 example = 7; 557 description = lib.mdDoc '' 558 Controls verbosity of X logging. 559 ''; 560 }; 561 562 enableCtrlAltBackspace = mkOption { 563 type = types.bool; 564 default = false; 565 description = lib.mdDoc '' 566 Whether to enable the DontZap option, which binds Ctrl+Alt+Backspace 567 to forcefully kill X. This can lead to data loss and is disabled 568 by default. 569 ''; 570 }; 571 572 terminateOnReset = mkOption { 573 type = types.bool; 574 default = true; 575 description = lib.mdDoc '' 576 Whether to terminate X upon server reset. 577 ''; 578 }; 579 }; 580 581 }; 582 583 584 585 ###### implementation 586 587 config = mkIf cfg.enable { 588 589 services.xserver.displayManager.lightdm.enable = 590 let dmConf = cfg.displayManager; 591 default = !(dmConf.gdm.enable 592 || dmConf.sddm.enable 593 || dmConf.xpra.enable 594 || dmConf.sx.enable 595 || dmConf.startx.enable); 596 in mkIf (default) (mkDefault true); 597 598 # so that the service won't be enabled when only startx is used 599 systemd.services.display-manager.enable = 600 let dmConf = cfg.displayManager; 601 noDmUsed = !(dmConf.gdm.enable 602 || dmConf.sddm.enable 603 || dmConf.xpra.enable 604 || dmConf.lightdm.enable); 605 in mkIf (noDmUsed) (mkDefault false); 606 607 hardware.opengl.enable = mkDefault true; 608 609 services.xserver.videoDrivers = mkIf (cfg.videoDriver != null) [ cfg.videoDriver ]; 610 611 # FIXME: somehow check for unknown driver names. 612 services.xserver.drivers = flip concatMap cfg.videoDrivers (name: 613 let driver = 614 attrByPath [name] 615 (if xorg ? ${"xf86video" + name} 616 then { modules = [xorg.${"xf86video" + name}]; } 617 else null) 618 knownVideoDrivers; 619 in optional (driver != null) ({ inherit name; modules = []; driverName = name; display = true; } // driver)); 620 621 assertions = [ 622 (let primaryHeads = filter (x: x.primary) cfg.xrandrHeads; in { 623 assertion = length primaryHeads < 2; 624 message = "Only one head is allowed to be primary in " 625 + "services.xserver.xrandrHeads, but there are " 626 + "${toString (length primaryHeads)} heads set to primary: " 627 + concatMapStringsSep ", " (x: x.output) primaryHeads; 628 }) 629 ]; 630 631 environment.etc = 632 (optionalAttrs cfg.exportConfiguration 633 { 634 "X11/xorg.conf".source = "${configFile}"; 635 # -xkbdir command line option does not seems to be passed to xkbcomp. 636 "X11/xkb".source = "${cfg.xkbDir}"; 637 }) 638 # localectl looks into 00-keyboard.conf 639 //{ 640 "X11/xorg.conf.d/00-keyboard.conf".text = '' 641 Section "InputClass" 642 Identifier "Keyboard catchall" 643 MatchIsKeyboard "on" 644 Option "XkbModel" "${cfg.xkbModel}" 645 Option "XkbLayout" "${cfg.layout}" 646 Option "XkbOptions" "${cfg.xkbOptions}" 647 Option "XkbVariant" "${cfg.xkbVariant}" 648 EndSection 649 ''; 650 } 651 # Needed since 1.18; see https://bugs.freedesktop.org/show_bug.cgi?id=89023#c5 652 // (let cfgPath = "/X11/xorg.conf.d/10-evdev.conf"; in 653 { 654 ${cfgPath}.source = xorg.xf86inputevdev.out + "/share" + cfgPath; 655 }); 656 657 environment.systemPackages = utils.removePackagesByName 658 [ xorg.xorgserver.out 659 xorg.xrandr 660 xorg.xrdb 661 xorg.setxkbmap 662 xorg.iceauth # required for KDE applications (it's called by dcopserver) 663 xorg.xlsclients 664 xorg.xset 665 xorg.xsetroot 666 xorg.xinput 667 xorg.xprop 668 xorg.xauth 669 pkgs.xterm 670 pkgs.xdg-utils 671 xorg.xf86inputevdev.out # get evdev.4 man page 672 pkgs.nixos-icons # needed for gnome and pantheon about dialog, nixos-manual and maybe more 673 ] config.services.xserver.excludePackages 674 ++ optional (elem "virtualbox" cfg.videoDrivers) xorg.xrefresh; 675 676 environment.pathsToLink = [ "/share/X11" ]; 677 678 xdg = { 679 autostart.enable = true; 680 menus.enable = true; 681 mime.enable = true; 682 icons.enable = true; 683 }; 684 685 # The default max inotify watches is 8192. 686 # Nowadays most apps require a good number of inotify watches, 687 # the value below is used by default on several other distros. 688 boot.kernel.sysctl."fs.inotify.max_user_instances" = mkDefault 524288; 689 boot.kernel.sysctl."fs.inotify.max_user_watches" = mkDefault 524288; 690 691 systemd.defaultUnit = mkIf cfg.autorun "graphical.target"; 692 693 systemd.services.display-manager = 694 { description = "X11 Server"; 695 696 after = [ "acpid.service" "systemd-logind.service" "systemd-user-sessions.service" ]; 697 698 restartIfChanged = false; 699 700 environment = 701 optionalAttrs config.hardware.opengl.setLdLibraryPath 702 { LD_LIBRARY_PATH = lib.makeLibraryPath [ pkgs.addOpenGLRunpath.driverLink ]; } 703 // cfg.displayManager.job.environment; 704 705 preStart = 706 '' 707 ${cfg.displayManager.job.preStart} 708 709 rm -f /tmp/.X0-lock 710 ''; 711 712 # TODO: move declaring the systemd service to its own mkIf 713 script = mkIf (config.systemd.services.display-manager.enable == true) "${cfg.displayManager.job.execCmd}"; 714 715 # Stop restarting if the display manager stops (crashes) 2 times 716 # in one minute. Starting X typically takes 3-4s. 717 startLimitIntervalSec = 30; 718 startLimitBurst = 3; 719 serviceConfig = { 720 Restart = "always"; 721 RestartSec = "200ms"; 722 SyslogIdentifier = "display-manager"; 723 }; 724 }; 725 726 services.xserver.displayManager.xserverArgs = 727 [ "-config ${configFile}" 728 "-xkbdir" "${cfg.xkbDir}" 729 ] ++ optional (cfg.display != null) ":${toString cfg.display}" 730 ++ optional (cfg.tty != null) "vt${toString cfg.tty}" 731 ++ optional (cfg.dpi != null) "-dpi ${toString cfg.dpi}" 732 ++ optional (cfg.logFile != null) "-logfile ${toString cfg.logFile}" 733 ++ optional (cfg.verbose != null) "-verbose ${toString cfg.verbose}" 734 ++ optional (!cfg.enableTCP) "-nolisten tcp" 735 ++ optional (cfg.autoRepeatDelay != null) "-ardelay ${toString cfg.autoRepeatDelay}" 736 ++ optional (cfg.autoRepeatInterval != null) "-arinterval ${toString cfg.autoRepeatInterval}" 737 ++ optional cfg.terminateOnReset "-terminate"; 738 739 services.xserver.modules = 740 concatLists (catAttrs "modules" cfg.drivers) ++ 741 [ xorg.xorgserver.out 742 xorg.xf86inputevdev.out 743 ]; 744 745 system.extraDependencies = singleton (pkgs.runCommand "xkb-validated" { 746 inherit (cfg) xkbModel layout xkbVariant xkbOptions; 747 nativeBuildInputs = with pkgs.buildPackages; [ xkbvalidate ]; 748 preferLocalBuild = true; 749 } '' 750 ${optionalString (config.environment.sessionVariables ? XKB_CONFIG_ROOT) 751 "export XKB_CONFIG_ROOT=${config.environment.sessionVariables.XKB_CONFIG_ROOT}" 752 } 753 xkbvalidate "$xkbModel" "$layout" "$xkbVariant" "$xkbOptions" 754 touch "$out" 755 ''); 756 757 services.xserver.config = 758 '' 759 Section "ServerFlags" 760 Option "AllowMouseOpenFail" "on" 761 Option "DontZap" "${if cfg.enableCtrlAltBackspace then "off" else "on"}" 762 ${indent cfg.serverFlagsSection} 763 EndSection 764 765 Section "Module" 766 ${indent cfg.moduleSection} 767 EndSection 768 769 Section "Monitor" 770 Identifier "Monitor[0]" 771 ${indent cfg.monitorSection} 772 EndSection 773 774 # Additional "InputClass" sections 775 ${flip (concatMapStringsSep "\n") cfg.inputClassSections (inputClassSection: '' 776 Section "InputClass" 777 ${indent inputClassSection} 778 EndSection 779 '')} 780 781 782 Section "ServerLayout" 783 Identifier "Layout[all]" 784 ${indent cfg.serverLayoutSection} 785 # Reference the Screen sections for each driver. This will 786 # cause the X server to try each in turn. 787 ${flip concatMapStrings (filter (d: d.display) cfg.drivers) (d: '' 788 Screen "Screen-${d.name}[0]" 789 '')} 790 EndSection 791 792 # For each supported driver, add a "Device" and "Screen" 793 # section. 794 ${flip concatMapStrings cfg.drivers (driver: '' 795 796 Section "Device" 797 Identifier "Device-${driver.name}[0]" 798 Driver "${driver.driverName or driver.name}" 799 ${indent cfg.deviceSection} 800 ${indent (driver.deviceSection or "")} 801 ${indent xrandrDeviceSection} 802 EndSection 803 ${optionalString driver.display '' 804 805 Section "Screen" 806 Identifier "Screen-${driver.name}[0]" 807 Device "Device-${driver.name}[0]" 808 ${optionalString (cfg.monitorSection != "") '' 809 Monitor "Monitor[0]" 810 ''} 811 812 ${indent cfg.screenSection} 813 ${indent (driver.screenSection or "")} 814 815 ${optionalString (cfg.defaultDepth != 0) '' 816 DefaultDepth ${toString cfg.defaultDepth} 817 ''} 818 819 ${optionalString 820 ( 821 driver.name != "virtualbox" 822 && 823 (cfg.resolutions != [] || 824 cfg.extraDisplaySettings != "" || 825 cfg.virtualScreen != null 826 ) 827 ) 828 (let 829 f = depth: 830 '' 831 SubSection "Display" 832 Depth ${toString depth} 833 ${optionalString (cfg.resolutions != []) 834 "Modes ${concatMapStrings (res: ''"${toString res.x}x${toString res.y}"'') cfg.resolutions}"} 835 ${indent cfg.extraDisplaySettings} 836 ${optionalString (cfg.virtualScreen != null) 837 "Virtual ${toString cfg.virtualScreen.x} ${toString cfg.virtualScreen.y}"} 838 EndSubSection 839 ''; 840 in concatMapStrings f [8 16 24] 841 )} 842 843 EndSection 844 ''} 845 '')} 846 847 ${xrandrMonitorSections} 848 849 ${cfg.extraConfig} 850 ''; 851 852 fonts.enableDefaultFonts = mkDefault true; 853 854 }; 855 856 # uses relatedPackages 857 meta.buildDocsInSandbox = false; 858}