From f6ae72071127e92dd82875c850a1e55dd88a9e6d Mon Sep 17 00:00:00 2001 From: Mx Kookie Date: Mon, 7 Dec 2020 16:33:47 +0100 Subject: libkookie: adding initial i3 abstraction This module (and associated configuration) sets up i3 on a computer, according to some parameters. At the moment, there is not much to configure, as the basics can be shared. However, I'll want to be able to change the tray, and i3bar based on the hardware, which is supported with this approach. --- infra/libkookie/build | 1 + infra/libkookie/configuration/default.nix | 5 ++ infra/libkookie/configuration/i3/laptop.nix | 15 ++++++ .../libkookie/configuration/users/spacekookie.nix | 11 ++++ infra/libkookie/modules/harness/users.nix | 42 +++++++++++++++ infra/libkookie/modules/workstation/ui/default.nix | 3 +- .../libkookie/modules/workstation/ui/i3/#core.nix# | 9 ---- .../modules/workstation/ui/i3/#default.nix# | 59 -------------------- .../libkookie/modules/workstation/ui/i3/.#core.nix | 1 - .../libkookie/modules/workstation/ui/i3/config.nix | 22 ++++++++ infra/libkookie/modules/workstation/ui/i3/core.nix | 27 ++++++++-- .../modules/workstation/ui/i3/default.nix | 36 +++++++------ infra/libkookie/modules/workstation/ui/i3/keys.nix | 63 ++++++++++++++++++++++ .../libkookie/modules/workstation/ui/i3/setup.nix | 13 +++++ .../modules/workstation/ui/i3/tools/default.nix | 8 +++ .../modules/workstation/ui/i3/tools/i3-move.nix | 17 ++++++ .../modules/workstation/ui/i3/tools/i3-rename.nix | 10 ++++ .../modules/workstation/ui/i3/tools/i3-scrcap.nix | 10 ++++ .../modules/workstation/ui/i3/tools/i3-switch.nix | 15 ++++++ infra/libkookie/modules/workstation/ui/i3/x.nix | 27 ++++++++++ 20 files changed, 303 insertions(+), 91 deletions(-) create mode 100644 infra/libkookie/configuration/default.nix create mode 100644 infra/libkookie/configuration/i3/laptop.nix create mode 100644 infra/libkookie/configuration/users/spacekookie.nix create mode 100644 infra/libkookie/modules/harness/users.nix delete mode 100644 infra/libkookie/modules/workstation/ui/i3/#core.nix# delete mode 100644 infra/libkookie/modules/workstation/ui/i3/#default.nix# delete mode 120000 infra/libkookie/modules/workstation/ui/i3/.#core.nix create mode 100644 infra/libkookie/modules/workstation/ui/i3/config.nix create mode 100644 infra/libkookie/modules/workstation/ui/i3/keys.nix create mode 100644 infra/libkookie/modules/workstation/ui/i3/setup.nix create mode 100644 infra/libkookie/modules/workstation/ui/i3/tools/default.nix create mode 100644 infra/libkookie/modules/workstation/ui/i3/tools/i3-move.nix create mode 100644 infra/libkookie/modules/workstation/ui/i3/tools/i3-rename.nix create mode 100644 infra/libkookie/modules/workstation/ui/i3/tools/i3-scrcap.nix create mode 100644 infra/libkookie/modules/workstation/ui/i3/tools/i3-switch.nix create mode 100644 infra/libkookie/modules/workstation/ui/i3/x.nix diff --git a/infra/libkookie/build b/infra/libkookie/build index 68193ecaf431..db80a0232159 100755 --- a/infra/libkookie/build +++ b/infra/libkookie/build @@ -18,6 +18,7 @@ function build { -I "nixpkgs-overlays=$DIR/overlays" \ -I "home-manager=$DIR/home-manager" \ -I "modules=$DIR/modules" \ + -I "configuration=$DIR/configuration" \ --out-link "$OUT" "$@" } diff --git a/infra/libkookie/configuration/default.nix b/infra/libkookie/configuration/default.nix new file mode 100644 index 000000000000..7902417a5d53 --- /dev/null +++ b/infra/libkookie/configuration/default.nix @@ -0,0 +1,5 @@ +{ config, ... }: + +{ + libkookie.userPath = ./users; +} diff --git a/infra/libkookie/configuration/i3/laptop.nix b/infra/libkookie/configuration/i3/laptop.nix new file mode 100644 index 000000000000..8e3fd2fb8a9a --- /dev/null +++ b/infra/libkookie/configuration/i3/laptop.nix @@ -0,0 +1,15 @@ +/** An i3 configuration tailored to medium screens + * + * These values are meant to be common defaults and can be overriden + * before being applied. + * + * By default this configuration enables WiFi and battery indicators, + * and uses a shortened ipv6 display. + */ + + +{ config, ... }: + +{ + +} diff --git a/infra/libkookie/configuration/users/spacekookie.nix b/infra/libkookie/configuration/users/spacekookie.nix new file mode 100644 index 000000000000..404152360bf4 --- /dev/null +++ b/infra/libkookie/configuration/users/spacekookie.nix @@ -0,0 +1,11 @@ +{ pkgs, lib, ... }: + +{ + createHome = true; + description = "Katharina Fey"; + home = lib.mkDefault "/home"; + uid = lib.mkDefault 1000; + group = "spacekookie"; + extraGroups = [ "wheel" "dialout" ]; + shell = lib.mkDefault pkgs.fish; +} diff --git a/infra/libkookie/modules/harness/users.nix b/infra/libkookie/modules/harness/users.nix new file mode 100644 index 000000000000..d663ec38d1aa --- /dev/null +++ b/infra/libkookie/modules/harness/users.nix @@ -0,0 +1,42 @@ +{ config, lib, pkgs, ... }: + +let cfg = config.libkookie; +in +{ + options.libkookie = { + activeUsers = with lib; mkOption { + type = with types; listOf str; + default = []; + description = '' + List of active users on this system. This is relevant for what + userspace tools get installed, and what SSH pubkeys are included. + ''; + }; + + userPath = with lib; mkOption { + type = types.path; + default = null; + description = '' + Base path to the user definitions. Because of the way that + libkookie is structured, user declarations don't like in the + ./module tree, but instead should be kept in the ./config tree. + + This way, the separation between the actual modules, and system + configuration for a particular system remains intact. + ''; + }; + }; + + config = { + users.mutableUsers = false; + users.users = (with lib; + let + pathify = with builtins; + name: cfg.userPath + (toPath "/" + name + ".nix"); + include = path: import path { inherit pkgs lib; }; + in + listToAttrs (map + (name: nameValuePair name (include (pathify name))) + cfg.activeUsers)); + }; +} diff --git a/infra/libkookie/modules/workstation/ui/default.nix b/infra/libkookie/modules/workstation/ui/default.nix index 6f9ed0ed76aa..fca94e163c2d 100644 --- a/infra/libkookie/modules/workstation/ui/default.nix +++ b/infra/libkookie/modules/workstation/ui/default.nix @@ -1,5 +1,6 @@ -{ ... }: { +{ lib, config, ... }: { imports = [ ./i3 ]; + } diff --git a/infra/libkookie/modules/workstation/ui/i3/#core.nix# b/infra/libkookie/modules/workstation/ui/i3/#core.nix# deleted file mode 100644 index bcf88bc5987d..000000000000 --- a/infra/libkookie/modules/workstation/ui/i3/#core.nix# +++ /dev/null @@ -1,9 +0,0 @@ -{ pkgs, ... }: - -let - wallpaper = config.libkookie.ui.i3.wallpaper; -in -{ - xsession.windowManager.i3 = import ./config.nix { inherit pkgs wallpaper; }; -{ - diff --git a/infra/libkookie/modules/workstation/ui/i3/#default.nix# b/infra/libkookie/modules/workstation/ui/i3/#default.nix# deleted file mode 100644 index 36bd6dcb530c..000000000000 --- a/infra/libkookie/modules/workstation/ui/i3/#default.nix# +++ /dev/null @@ -1,59 +0,0 @@ -/** - * A custom module to configure i3. Provides a simple interface to - * set a wallpaper and certain keybinding overrides. - * - * The special thing about this configuration is the way workspaces - * are handled. Instead of numerical workspaces, this configuration - * sets up scripts to manage named workspaces - */ - -{ config, lib, pkgs, home-manager, ... }: - -let - cfg = config.libkookie.ui.i3; - libkookie = config.libkookie; -in -with lib; -{ - options.libkookie.ui.i3 = { - enable = mkEnableOption "i3 + xfce display manager"; - - wallpaper = mkOption { - type = types.path; - description = '' - Specify the wallpaper to set. Default to the default - NixOS login screen wallpaper. - ''; - }; - - compton = mkEnableOption "windown composition with compton"; - - screenshotHandling = mkOption { - type = types.bool; - default = false; - description = '' - Install the gnome-screenshot tool and create a binding to it. - ''; - }; - - modifier = mkOption { - type = types.string; - default = "Mod4"; - description = '' - The modifier key used by i3. - By default this is Meta (Mod4). - To see which modifier keys you can use alternatively, - check the i3 documentation. - ''; - }; - }; - - config = mkIf cfg.enable { - home-manager.users = listToAttrs - (map (user: lib.nameValuePair "${user}" ({ ... }: { - imports = [ - ./core.nix - ]; - })) config.libkookie.activeUsers); - }; -} diff --git a/infra/libkookie/modules/workstation/ui/i3/.#core.nix b/infra/libkookie/modules/workstation/ui/i3/.#core.nix deleted file mode 120000 index 3288921bdfd1..000000000000 --- a/infra/libkookie/modules/workstation/ui/i3/.#core.nix +++ /dev/null @@ -1 +0,0 @@ -spacekookie@uwu.26091:1603268988 \ No newline at end of file diff --git a/infra/libkookie/modules/workstation/ui/i3/config.nix b/infra/libkookie/modules/workstation/ui/i3/config.nix new file mode 100644 index 000000000000..7d6e7e8932b1 --- /dev/null +++ b/infra/libkookie/modules/workstation/ui/i3/config.nix @@ -0,0 +1,22 @@ + +/** A base configuration template for i3 + * + * This set of configuration values is meant to work on _all_ + * systems. No device specifics are included. This set must be + * merged with device specific options before being applied + */ +{ config, pkgs, ... } @ args: + +let + cfg = config.libkookie.ui.i3; + xtraPkgs = pkgs // (import ./tools args); +in +rec { + # This is not configurable by design + modifier = "Mod4"; + + inherit (cfg) fonts; + + keybindings = (import ./keys.nix { inherit modifier; + pkgs = xtraPkgs; }); +} diff --git a/infra/libkookie/modules/workstation/ui/i3/core.nix b/infra/libkookie/modules/workstation/ui/i3/core.nix index 5969718f3d1b..603de1e6c39e 100644 --- a/infra/libkookie/modules/workstation/ui/i3/core.nix +++ b/infra/libkookie/modules/workstation/ui/i3/core.nix @@ -1,9 +1,26 @@ -{ pkgs, ... }: +{ lib, config, pkgs, home-manager, ... } @ args: -let - wallpaper = config.libkookie.ui.i3.wallpaper; +let baseCfg = (import ./config.nix args); in { - xsession.windowManager.i3 = import ./config.nix { inherit pkgs wallpaper; }; -{ + # FIXME: introduce a mechanism to allow pre-user overrides! this + # needs to be supported by the module _or_ we have some very generic + # mechanism in libkookie.harness to handle this. But as it stands + # right now, all users will have the same i3 config. + home-manager.users = with lib; + (listToAttrs (map (user: nameValuePair "${user}" ({ ... }: + { imports = [ ./setup.nix ]; })) config.libkookie.activeUsers)); + + # FIXME: add 32bit driver support only if steam support is enabled + hardware.opengl = { + enable = true; + driSupport = true; + extraPackages = with pkgs; [ + libGL xorg.xf86videoati xorg.xf86inputlibinput + ]; + driSupport32Bit = true; + }; + + services.xserver = (import ./x.nix args); +} diff --git a/infra/libkookie/modules/workstation/ui/i3/default.nix b/infra/libkookie/modules/workstation/ui/i3/default.nix index 1266b652fd64..1967558f1884 100644 --- a/infra/libkookie/modules/workstation/ui/i3/default.nix +++ b/infra/libkookie/modules/workstation/ui/i3/default.nix @@ -7,16 +7,20 @@ * sets up scripts to manage named workspaces */ -{ config, lib, pkgs, home-manager, ... }: +{ config, lib, pkgs, home-manager, ... } @ args: let cfg = config.libkookie.ui.i3; libkookie = config.libkookie; in with lib; -{ +{ options.libkookie.ui.i3 = { enable = mkEnableOption "i3 + xfce display manager"; + + compton = mkEnableOption "window composition with compton"; + + defaultSession = mkEnableOption "i3 as the default login session"; wallpaper = mkOption { type = types.path; @@ -26,16 +30,14 @@ with lib; ''; }; - compton = mkEnableOption "windown composition with compton"; - - screenshotHandling = mkOption { - type = types.bool; - default = false; + fonts = mkOption { + type = with types; listOf str; + default = ["monospace"]; description = '' - Install the gnome-screenshot tool and create a binding to it. + A set of fonts to use by the i3 module for rendering text ''; }; - + modifier = mkOption { type = types.string; default = "Mod4"; @@ -46,13 +48,15 @@ with lib; check the i3 documentation. ''; }; - }; - config = mkIf cfg.enable { - home-manager.users = listToAttrs (map (user: lib.nameValuePair "${user}" ({ ... }: { - imports = [ - ./core.nix - ]; - })) config.libkookie.activeUsers); + videoDrivers = with lib; mkOption { + type = with types; listOf str; + default = []; + description = '' + The set of video drivers to instantiate on a given system + ''; + }; }; + + config = mkIf cfg.enable (import ./core.nix args); } diff --git a/infra/libkookie/modules/workstation/ui/i3/keys.nix b/infra/libkookie/modules/workstation/ui/i3/keys.nix new file mode 100644 index 000000000000..05497926cc5c --- /dev/null +++ b/infra/libkookie/modules/workstation/ui/i3/keys.nix @@ -0,0 +1,63 @@ +{ pkgs, modifier }: + +{ + # Start a terminal + "${modifier}+Return" = "exec ${pkgs.kitty}/bin/kitty"; + + # Area screenshot support + "${modifier}+9" = "exec ${pkgs.libkookie-i3-scrcap}"; + + # Close individual windows + "${modifier}+Shift+q" = "kill"; + + # Full-screen window + "${modifier}+f" = "fullscreen"; + + # Start software on or workspace + "${modifier}+e" = "exec ${pkgs.dmenu}/bin/dmenu_run"; + + # Switch to workspace (optionally take current window) + "${modifier}+o" = "exec ${pkgs.libkookie-i3-switch}"; + "${modifier}+Shift+o" = "exec ${pkgs.libkookie-i3-move}"; + + # Rename workspaces + "${modifier}+Ctrl+r" = "exec ${pkgs.libkookie-i3-rename}"; + # Move focus around - vim style + "${modifier}+h" = "focus left"; + "${modifier}+t" = "focus up"; + "${modifier}+n" = "focus down"; + "${modifier}+s" = "focus right"; + + # Move focus around - boring style + "${modifier}+Up" = "focus up"; + "${modifier}+Down" = "focus down"; + "${modifier}+Left" = "focus left"; + "${modifier}+Right" = "focus right"; + + # Move windows - vim style + "${modifier}+Shift+h" = "move left"; + "${modifier}+Shift+t" = "move up"; + "${modifier}+Shift+n" = "move down"; + "${modifier}+Shift+s" = "move right"; + + # Move windows - boring style + "${modifier}+Shift+Up" = "move up"; + "${modifier}+Shift+Down" = "move down"; + "${modifier}+Shift+Left" = "move left"; + "${modifier}+Shift+Right" = "move right"; + + # Move workspaces between multi-monitor setups + "${modifier}+Ctrl+Shift+Up" = "move workspace to output up"; + "${modifier}+Ctrl+Shift+Down" = "move workspace to output down"; + "${modifier}+Ctrl+Shift+Left" = " move workspace to output left"; + "${modifier}+Ctrl+Shift+Right" = "move workspace to output right"; + + # Define split behaviours + "${modifier}+2" = "split h"; + "${modifier}+1" = "split v"; + + # Some layout modifiers + "${modifier}+3" = "layout default"; + "${modifier}+4" = "layout tabbed"; + "${modifier}+5" = "layout stacked"; +} diff --git a/infra/libkookie/modules/workstation/ui/i3/setup.nix b/infra/libkookie/modules/workstation/ui/i3/setup.nix new file mode 100644 index 000000000000..e1c0aff48971 --- /dev/null +++ b/infra/libkookie/modules/workstation/ui/i3/setup.nix @@ -0,0 +1,13 @@ +{ config, ... }: + +let cfg = config.libkookie.ui.i3; +in +{ + xsession.windowManager.i3 = { + enable = true; + package = pkgs.i3; + config = baseCfg; + }; + + # TODO: add i3status config handling +} diff --git a/infra/libkookie/modules/workstation/ui/i3/tools/default.nix b/infra/libkookie/modules/workstation/ui/i3/tools/default.nix new file mode 100644 index 000000000000..40ce022c6144 --- /dev/null +++ b/infra/libkookie/modules/workstation/ui/i3/tools/default.nix @@ -0,0 +1,8 @@ +{ pkgs, ... } @ args: + +{ + libkookie-i3-move = (import ./i3-move.nix args); + libkookie-i3-switch = (import ./i3-switch.nix args); + libkookie-i3-rename = (import ./i3-rename.nix args); + libkookie-i3-scrcap = (import ./i3-scrcap.nix args); +} diff --git a/infra/libkookie/modules/workstation/ui/i3/tools/i3-move.nix b/infra/libkookie/modules/workstation/ui/i3/tools/i3-move.nix new file mode 100644 index 000000000000..1ba4a45bcab6 --- /dev/null +++ b/infra/libkookie/modules/workstation/ui/i3/tools/i3-move.nix @@ -0,0 +1,17 @@ +/** A utility script to move a window to a workspace + * + * This tool relies on i3-msg, jq, and dmenu to move a window to a + * different workspace. In the future, maybe the display mechanism + * (dmenu) could be made configurable, so not to rely on nazi code. + */ + +{ pkgs, ... }: with pkgs; writeShellScript "libkookie-i3-move" '' + + WS=$(${i3}/bin/i3-msg -t get_workspaces | \ + ${jq}/bin/jq -M '.[] | .name' | tr -d '"' \ + | sort -u | ${dmenu}/bin/dmenu -b -i "$@") + + + ${i3}/bin/i3-msg -t command move workspace $WS + ${i3}/bin/i3-msg workspace $WS +'' diff --git a/infra/libkookie/modules/workstation/ui/i3/tools/i3-rename.nix b/infra/libkookie/modules/workstation/ui/i3/tools/i3-rename.nix new file mode 100644 index 000000000000..68bd32364452 --- /dev/null +++ b/infra/libkookie/modules/workstation/ui/i3/tools/i3-rename.nix @@ -0,0 +1,10 @@ +/** A utility to rename the current workspace + * + * This tool relies on i3-msg, jq, and dmenu to move a window to a + * different workspace. In the future, maybe the display mechanism + * (dmenu) could be made configurable, so not to rely on nazi code. + */ + +{ pkgs, ... }: with pkgs; writeShellScript "libkookie-i3-rename" '' + exec i3-input -F 'rename workspace to \"%s\"' -P 'New name: ' +'' diff --git a/infra/libkookie/modules/workstation/ui/i3/tools/i3-scrcap.nix b/infra/libkookie/modules/workstation/ui/i3/tools/i3-scrcap.nix new file mode 100644 index 000000000000..6146dabee67a --- /dev/null +++ b/infra/libkookie/modules/workstation/ui/i3/tools/i3-scrcap.nix @@ -0,0 +1,10 @@ +/** A utility script to take screenshots + * + * This tool relies on scrot to take screenshot, independent of a + * complete windowing compositor running. gnome-screenshot was + * used in the past, but has weird behaviour on non-gnome systems. + */ + +{ pkgs, ... }: with pkgs; writeShellScript "libkookie-i3-move" '' + ${scrot}/bin/scrot -s +'' diff --git a/infra/libkookie/modules/workstation/ui/i3/tools/i3-switch.nix b/infra/libkookie/modules/workstation/ui/i3/tools/i3-switch.nix new file mode 100644 index 000000000000..691e9470db83 --- /dev/null +++ b/infra/libkookie/modules/workstation/ui/i3/tools/i3-switch.nix @@ -0,0 +1,15 @@ +/** A utility script to switch to a workspace + * + * This tool relies on i3-msg, jq, and dmenu to switch to a different + * workspace. In the future, maybe the display mechanism (dmenu) + * could be made configurable, so not to rely on nazi code. + */ + +{ pkgs, ... }: with pkgs; writeShellScript "libkookie-i3-switch" '' + + WS=$(${i3}/bin/i3-msg -t get_workspaces | \ + ${jq}/bin/jq -M '.[] | .name' | tr -d '"' \ + | sort -u | ${dmenu}/bin/dmenu -b -i "$@") + + ${i3}/bin/i3-msg workspace $WS +'' diff --git a/infra/libkookie/modules/workstation/ui/i3/x.nix b/infra/libkookie/modules/workstation/ui/i3/x.nix new file mode 100644 index 000000000000..1313c138c8f1 --- /dev/null +++ b/infra/libkookie/modules/workstation/ui/i3/x.nix @@ -0,0 +1,27 @@ +{ lib, config, ... }: + +let cfg = config.libkookie.ui.i3; +in +{ + enable = true; + desktopManager = { + xfce = { + enable = true; + noDesktop = true; + enableXfwm = false; + }; + }; + + displayManager.defaultSession = lib.mkIf cfg.defaultSession "xfce+i3"; + + windowManager.i3.enable = true; + + useGlamor = true; + + inherit (cfg) videoDrivers; + + deviceSection = '' + Option "DRI" "2" + Option "TearFree" "true" + ''; +} -- cgit v1.2.3