summary refs log tree commit diff
path: root/modules/services/x11/xserver.nix
diff options
context:
space:
mode:
authoraszlig <aszlig@redmoonstudios.org>2013-01-10 00:31:08 +0100
committeraszlig <aszlig@redmoonstudios.org>2013-01-10 00:54:00 +0100
commit0129717b17e982d714ea93edc9d35898a27275ad (patch)
treedd690899afc5c943cb0bd52da273ad58f0fc1eb4 /modules/services/x11/xserver.nix
parente4d949ec8801af8662c206d08d95ff41ba640d08 (diff)
downloadnixlib-0129717b17e982d714ea93edc9d35898a27275ad.tar
nixlib-0129717b17e982d714ea93edc9d35898a27275ad.tar.gz
nixlib-0129717b17e982d714ea93edc9d35898a27275ad.tar.bz2
nixlib-0129717b17e982d714ea93edc9d35898a27275ad.tar.lz
nixlib-0129717b17e982d714ea93edc9d35898a27275ad.tar.xz
nixlib-0129717b17e982d714ea93edc9d35898a27275ad.tar.zst
nixlib-0129717b17e982d714ea93edc9d35898a27275ad.zip
xserver: Allow to set XRandR multi head layout.
This is currently only a very simple implementation which just recurses a list
of heads that get chained together to the right of the corresponding previous
item of the list.

If I forgot about something in the already existing configuration options,
please let me know or if this commit is useless or a duplicate, feel free to
revert. But by looking at implementation before this commit, I only see zaphod
and/or quirky xinerama-like configuration options.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
Diffstat (limited to 'modules/services/x11/xserver.nix')
-rw-r--r--modules/services/x11/xserver.nix47
1 files changed, 47 insertions, 0 deletions
diff --git a/modules/services/x11/xserver.nix b/modules/services/x11/xserver.nix
index bfdeef81f206..d78a8787e79c 100644
--- a/modules/services/x11/xserver.nix
+++ b/modules/services/x11/xserver.nix
@@ -43,6 +43,36 @@ let
       pkgs.xorg.fontadobe75dpi
     ];
 
+  # Just enumerate all heads without discarding XRandR output information.
+  xrandrHeads = let
+    mkHead = num: output: {
+      name = "multihead${toString num}";
+      inherit output;
+    };
+  in imap mkHead cfg.xrandrHeads;
+
+  xrandrDeviceSection = flip concatMapStrings xrandrHeads (h: ''
+    Option "monitor-${h.output}" "${h.name}"
+  '');
+
+  # Here we chain every monitor from the left to right, so we have:
+  # m4 right of m3 right of m2 right of m1   .----.----.----.----.
+  # Which will end up in reverse ----------> | m1 | m2 | m3 | m4 |
+  #                                          `----^----^----^----'
+  xrandrMonitorSections = let
+    mkMonitor = previous: current: previous ++ singleton {
+      inherit (current) name;
+      value = ''
+        Section "Monitor"
+          Identifier "${current.name}"
+          ${optionalString (previous != []) ''
+          Option "RightOf" "${(head previous).name}"
+          ''}
+        EndSection
+      '';
+    };
+    monitors = foldl mkMonitor [] xrandrHeads;
+  in concatMapStrings (getAttr "value") monitors;
 
   configFile = pkgs.stdenv.mkDerivation {
     name = "xserver.conf";
@@ -256,6 +286,21 @@ in
         description = "Contents of the first Monitor section of the X server configuration file.";
       };
 
+      xrandrHeads = mkOption {
+        default = [];
+        example = [ "HDMI-0" "DVI-0" ];
+        type = with types; listOf string;
+        description = ''
+          Simple multiple monitor configuration, just specify a list of XRandR
+          outputs which will be mapped from left to right in the order of the
+          list.
+
+          Be careful using this option with multiple graphic adapters or with
+          drivers that have poor support for XRandR, unexpected things might
+          happen with those.
+        '';
+      };
+
       moduleSection = mkOption {
         default = "";
         example =
@@ -530,6 +575,7 @@ in
             Identifier "Device-${driver.name}[0]"
             Driver "${driver.driverName}"
             ${cfg.deviceSection}
+            ${xrandrDeviceSection}
           EndSection
 
           Section "Screen"
@@ -572,6 +618,7 @@ in
           EndSection
         '')}
 
+        ${xrandrMonitorSections}
         ${cfg.extraXorgOptions}
       '';