diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/i3/default.nix | 69 | ||||
-rw-r--r-- | modules/i3/i3.conf | 43 | ||||
-rw-r--r-- | modules/i3/workspace.nix | 106 |
3 files changed, 160 insertions, 58 deletions
diff --git a/modules/i3/default.nix b/modules/i3/default.nix index 86ba462c..2c668cc4 100644 --- a/modules/i3/default.nix +++ b/modules/i3/default.nix @@ -1,9 +1,56 @@ -{ pkgs, config, ... }: +{ pkgs, lib, config, ... }: -with pkgs.lib; +with lib; +let + # The symbols if you press shift and a number key. + wsNumberSymbols = [ + "exclam" "at" "numbersign" "dollar" "percent" + "asciicircum" "ampersand" "asterisk" "parenleft" "parenright" + ]; + + wsCount = length wsNumberSymbols; + + headCount = length config.services.xserver.xrandrHeads; + wsPerHead = wsCount / headCount; + excessWs = wsCount - (headCount * wsPerHead); + getHeadAt = elemAt config.services.xserver.xrandrHeads; + + mkDefaultWorkspace = number: numberSymbol: { + name = toString number; + value = mkDefault { + label = null; + labelPrefix = "${toString number}: "; + keys.switchTo = "$mod+${toString number}"; + keys.moveTo = "$mod+Shift+${numberSymbol}"; + head = getHeadAt ((number - (excessWs + 1)) / wsPerHead); + }; + }; + + wsCfgList = mapAttrsToList (_: getAttr "config") config.aszlig.i3.workspaces; + wsConfig = concatStrings wsCfgList; + defaultWorkspaces = listToAttrs (imap mkDefaultWorkspace wsNumberSymbols); +in { - services.xserver.windowManager = { + options.aszlig.i3 = { + workspaces = mkOption { + type = types.attrsOf (types.submodule ./workspace.nix); + default = listToAttrs (imap mkDefaultWorkspace wsNumberSymbols); + description = '' + Workspace to monitor assignment. + + Workspaces are by default assigned starting from the leftmost monitor + being workspace 1 and the rightmost monitor being workspace 10. The + workspaces are divided by the number of available heads, so if you have + a dual head system, you'll end up having workspace 1 to 5 on the left + monitor and 6 to 10 on the right. + ''; + }; + }; + + config.aszlig.i3.workspaces = defaultWorkspaces; + + config.services.xserver.windowManager = { default = "i3"; i3.enable = true; @@ -17,6 +64,7 @@ with pkgs.lib; inherit (pkgs) dmenu xterm pvolctrl; inherit (pkgs.xorg) xsetroot; + inherit wsConfig; leftHead = head config.services.xserver.xrandrHeads; rightHead = last config.services.xserver.xrandrHeads; @@ -30,19 +78,6 @@ with pkgs.lib; in if config.networking.hostName == "mmrnmhrm" then { inherit leftHead rightHead; } else { leftHead = rightHead; rightHead = leftHead; } - ) // (let - wsConfig = if config.networking.hostName == "mmrnmhrm" - then [ "XMPP" null "chromium" null null - null null null null null ] - else [ null null null null null - "chromium" null null null null ]; - - mkWsName = num: name: let - mkPair = nameValuePair "ws${toString num}"; - in if name == null - then mkPair (toString num) - else mkPair "${toString num}: ${name}"; - - in listToAttrs (imap mkWsName wsConfig))); + )); }; } diff --git a/modules/i3/i3.conf b/modules/i3/i3.conf index d6273489..b6780f98 100644 --- a/modules/i3/i3.conf +++ b/modules/i3/i3.conf @@ -74,30 +74,6 @@ bindsym $mod+a focus parent # focus the child container bindsym $mod+semicolon focus child -# switch to workspace -bindsym $mod+1 workspace "@ws1@" -bindsym $mod+2 workspace "@ws2@" -bindsym $mod+3 workspace "@ws3@" -bindsym $mod+4 workspace "@ws4@" -bindsym $mod+5 workspace "@ws5@" -bindsym $mod+6 workspace "@ws6@" -bindsym $mod+7 workspace "@ws7@" -bindsym $mod+8 workspace "@ws8@" -bindsym $mod+9 workspace "@ws9@" -bindsym $mod+0 workspace "@ws10@" - -# move focused container to workspace -bindsym $mod+Shift+exclam move workspace "@ws1@" -bindsym $mod+Shift+at move workspace "@ws2@" -bindsym $mod+Shift+numbersign move workspace "@ws3@" -bindsym $mod+Shift+dollar move workspace "@ws4@" -bindsym $mod+Shift+percent move workspace "@ws5@" -bindsym $mod+Shift+asciicircum move workspace "@ws6@" -bindsym $mod+Shift+ampersand move workspace "@ws7@" -bindsym $mod+Shift+asterisk move workspace "@ws8@" -bindsym $mod+Shift+parenleft move workspace "@ws9@" -bindsym $mod+Shift+parenright move workspace "@ws10@" - # reload the configuration file bindsym $mod+Shift+L reload # restart i3 inplace (preserves your layout/session, can be used to upgrade i3) @@ -138,23 +114,8 @@ mode "resize" { bindsym $mod+r mode "resize" -# workspace assignments -workspace "@ws1@" output @leftHead@ -workspace "@ws2@" output @leftHead@ -workspace "@ws3@" output @leftHead@ -workspace "@ws4@" output @leftHead@ -workspace "@ws5@" output @leftHead@ -workspace "@ws6@" output @rightHead@ -workspace "@ws7@" output @rightHead@ -workspace "@ws8@" output @rightHead@ -workspace "@ws9@" output @rightHead@ -workspace "@ws10@" output @rightHead@ - -# default applications -assign [class="^Tkabber$"] 1: tkabber -#exec --no-startup-id tkabber -assign [class="^Chromium(?:-browser)?$"] 3: chromium -#exec chromium +# workspace configuration +@wsConfig@ # ratmenu should be as unintrusive as possible for_window [class="^ratmenu$"] floating enable diff --git a/modules/i3/workspace.nix b/modules/i3/workspace.nix new file mode 100644 index 00000000..5365bf74 --- /dev/null +++ b/modules/i3/workspace.nix @@ -0,0 +1,106 @@ +{ name, lib, config, ... }: + +with lib; + +let + finalLabel = + if config.label == null then name + else config.labelPrefix + config.label; + + mkDoc = anchor: "http://i3wm.org/docs/userguide.html#${anchor}"; +in +{ + options = { + labelPrefix = mkOption { + type = types.str; + default = ""; + example = "666: "; + description = '' + The value that will be put in front of the <option>label</option>. + So if you have a label called <replaceable>bar</replaceable> and a + <option>labelPrefix</option> called <replaceable>foo</replaceable> the + label for the workspace will be <replaceable>foobar</replaceable>. + ''; + }; + + label = mkOption { + type = types.nullOr types.str; + default = name; + description = '' + The label of this workspace, which is its name by default. If the value + is <replaceable>null</replaceable>, the resulting label of the workspace + is just its name and no <option>labelPrefix</option> is applied. + ''; + }; + + assign = mkOption { + type = types.listOf types.attrs; + default = []; + example = [ + { class = "^Chromium(?:-browser)?\$"; } + { instance = "^gajim\$"; } + ]; + description = let + anchor = "_automatically_putting_clients_on_specific_workspaces"; + in '' + Assign windows to this specific workspace using the attribute names + described by <link xlink:href="${mkDoc anchor}"/>. + ''; + }; + + head = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The XRandR head this workspace will be assigned to. + ''; + }; + + keys = let + commonDesc = '' + The <replaceable>$mod</replaceable> placeholder represents the default + modifier key. Details about the syntax of key combinations can be found + at <link xlink:href="${mkDoc "keybindings"}"/>. + ''; + in { + switchTo = mkOption { + type = types.nullOr types.str; + default = null; + example = "$mod+1"; + description = '' + Key combination to switch to this workspace. + '' + commonDesc; + }; + + moveTo = mkOption { + type = types.nullOr types.str; + default = null; + example = "$mod+Shift+exclam"; + description = '' + Key combination to move a container to this workspace. + '' + commonDesc; + }; + }; + + config = mkOption { + type = types.lines; + default = ""; + description = '' + Raw configuration options for this workspace. + ''; + }; + }; + + config.config = let + maybeOutput = optionalString (config.head != null) " output ${config.head}"; + mkAssign = mapAttrsToList (criteria: value: "${criteria}=\"${value}\""); + mkSym = sym: rest: optionalString (sym != null) "bindsym ${sym} ${rest}"; + in '' + workspace "${finalLabel}"${maybeOutput} + ${mkSym config.keys.switchTo "workspace \"${finalLabel}\""} + ${mkSym config.keys.moveTo "move workspace \"${finalLabel}\""} + ${concatMapStrings (assign: '' + assign [${concatStringsSep " " (mkAssign assign)}] ${finalLabel} + '') config.assign} + ''; +} |