diff --git a/flake.lock b/flake.lock index efb63dd..0f1eb63 100644 --- a/flake.lock +++ b/flake.lock @@ -724,11 +724,11 @@ ] }, "locked": { - "lastModified": 1736066484, - "narHash": "sha256-uTstP36WaFrw+TEHb8nLF14hFPzQBOhmIxzioHCDaL8=", + "lastModified": 1736785676, + "narHash": "sha256-TY0jUwR3EW0fnS0X5wXMAVy6h4Z7Y6a3m+Yq++C9AyE=", "owner": "nix-community", "repo": "home-manager", - "rev": "5ad12b6ea06b84e48f6b677957c74f32d47bdee0", + "rev": "fc52a210b60f2f52c74eac41a8647c1573d2071d", "type": "github" }, "original": { @@ -852,6 +852,62 @@ "type": "github" } }, + "niri": { + "inputs": { + "niri-stable": "niri-stable", + "niri-unstable": "niri-unstable", + "nixpkgs": "nixpkgs_8", + "nixpkgs-stable": "nixpkgs-stable_3", + "xwayland-satellite-stable": "xwayland-satellite-stable", + "xwayland-satellite-unstable": "xwayland-satellite-unstable" + }, + "locked": { + "lastModified": 1736884105, + "narHash": "sha256-WHxMcVuEmJvToC5DEVnSLwUrpHgJyqUqd/O8gZuaQsU=", + "owner": "sodiboo", + "repo": "niri-flake", + "rev": "a4e712bccfbe0526327c10b67f765b49cbbd7701", + "type": "github" + }, + "original": { + "owner": "sodiboo", + "repo": "niri-flake", + "type": "github" + } + }, + "niri-stable": { + "flake": false, + "locked": { + "lastModified": 1736614405, + "narHash": "sha256-AJ1rlgNOPb3/+DbS5hkhm21t6Oz8IgqLllwmZt0lyzk=", + "owner": "YaLTeR", + "repo": "niri", + "rev": "e05bc269e678ecf828b96ae79c991c13b00b38a5", + "type": "github" + }, + "original": { + "owner": "YaLTeR", + "ref": "v25.01", + "repo": "niri", + "type": "github" + } + }, + "niri-unstable": { + "flake": false, + "locked": { + "lastModified": 1736879117, + "narHash": "sha256-elG0TiWNFwgfTLrTTZVZQp3dEN6F6Qds6UF6BVxCIHs=", + "owner": "YaLTeR", + "repo": "niri", + "rev": "a3cbe3514ba195bf74815008f75819944f888527", + "type": "github" + }, + "original": { + "owner": "YaLTeR", + "repo": "niri", + "type": "github" + } + }, "nix-filter": { "locked": { "lastModified": 1705332318, @@ -870,7 +926,7 @@ "nix-gaming": { "inputs": { "flake-parts": "flake-parts_5", - "nixpkgs": "nixpkgs_8", + "nixpkgs": "nixpkgs_9", "umu": "umu" }, "locked": { @@ -1002,13 +1058,29 @@ "type": "github" } }, + "nixpkgs-stable_3": { + "locked": { + "lastModified": 1736754065, + "narHash": "sha256-hcETjfECLklW1ND8svDvN0Nw6H/1qtuoz3rbFNQ1Lrk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "67e9c880898889470f153157a96b595e758167fc", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-24.11", + "repo": "nixpkgs", + "type": "github" + } + }, "nixpkgs-unstable": { "locked": { - "lastModified": 1735915915, - "narHash": "sha256-Q4HuFAvoKAIiTRZTUxJ0ZXeTC7lLfC9/dggGHNXNlCw=", + "lastModified": 1736755442, + "narHash": "sha256-a3MMEY7i/wdF0gb7WFNTn6onzaiMOvwj7OerRVenA8o=", "owner": "nixos", "repo": "nixpkgs", - "rev": "a27871180d30ebee8aa6b11bf7fef8a52f024733", + "rev": "ef56e777fedaa4da8c66a150081523c5de1e0171", "type": "github" }, "original": { @@ -1019,6 +1091,22 @@ } }, "nixpkgs_10": { + "locked": { + "lastModified": 1736916166, + "narHash": "sha256-puPDoVKxkuNmYIGMpMQiK8bEjaACcCksolsG36gdaNQ=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "e24b4c09e963677b1beea49d411cd315a024ad3a", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-24.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_11": { "locked": { "lastModified": 1734424634, "narHash": "sha256-cHar1vqHOOyC7f1+tVycPoWTfKIaqkoe1Q6TnKzuti4=", @@ -1034,7 +1122,7 @@ "type": "github" } }, - "nixpkgs_11": { + "nixpkgs_12": { "locked": { "lastModified": 1734424634, "narHash": "sha256-cHar1vqHOOyC7f1+tVycPoWTfKIaqkoe1Q6TnKzuti4=", @@ -1148,16 +1236,16 @@ }, "nixpkgs_8": { "locked": { - "lastModified": 1723856861, - "narHash": "sha256-OTDg91+Zzs2SpU3csK4xVdSQFoG8cK1lNUwKmTqERyE=", + "lastModified": 1736798957, + "narHash": "sha256-qwpCtZhSsSNQtK4xYGzMiyEDhkNzOCz/Vfu4oL2ETsQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "cd7b95ee3725af7113bacbce91dd6549cee58ca5", + "rev": "9abb87b552b7f55ac8916b6fc9e5cb486656a2f3", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixpkgs-unstable", + "ref": "nixos-unstable", "repo": "nixpkgs", "type": "github" } @@ -1221,10 +1309,11 @@ "lanzaboote": "lanzaboote", "lix-module": "lix-module", "mpd-mpris": "mpd-mpris", + "niri": "niri", "nix-gaming": "nix-gaming", "nixos-hardware": "nixos-hardware", "nixos-m1": "nixos-m1", - "nixpkgs": "nixpkgs_9", + "nixpkgs": "nixpkgs_10", "nixpkgs-unstable": "nixpkgs-unstable", "rust-overlay": "rust-overlay_3", "secrets": "secrets", @@ -1536,11 +1625,44 @@ "type": "github" } }, + "xwayland-satellite-stable": { + "flake": false, + "locked": { + "lastModified": 1730166465, + "narHash": "sha256-nq7bouXQXaaPPo/E+Jbq+wNHnatD4dY8OxSrRqzvy6s=", + "owner": "Supreeeme", + "repo": "xwayland-satellite", + "rev": "a713cf46cb7db84a0d1b57c3a397c610cad3cf98", + "type": "github" + }, + "original": { + "owner": "Supreeeme", + "ref": "v0.5", + "repo": "xwayland-satellite", + "type": "github" + } + }, + "xwayland-satellite-unstable": { + "flake": false, + "locked": { + "lastModified": 1736487362, + "narHash": "sha256-4kGoOA7FgK9N2mzS+TFEn41kUUNY6KwdiA/0rqlr868=", + "owner": "Supreeeme", + "repo": "xwayland-satellite", + "rev": "8f55e27f63a749881c4bbfbb6b1da028342a91d1", + "type": "github" + }, + "original": { + "owner": "Supreeeme", + "repo": "xwayland-satellite", + "type": "github" + } + }, "youmubot": { "inputs": { "crane": "crane_5", "flake-utils": "flake-utils_9", - "nixpkgs": "nixpkgs_10", + "nixpkgs": "nixpkgs_11", "rust-overlay": "rust-overlay_4" }, "locked": { @@ -1560,7 +1682,7 @@ }, "zen-browser": { "inputs": { - "nixpkgs": "nixpkgs_11", + "nixpkgs": "nixpkgs_12", "zen-browser-aarch64": "zen-browser-aarch64", "zen-browser-generic": "zen-browser-generic", "zen-browser-specific": "zen-browser-specific" diff --git a/flake.nix b/flake.nix index b3422e6..19e21d2 100644 --- a/flake.nix +++ b/flake.nix @@ -50,6 +50,7 @@ conduit.url = "gitlab:famedly/conduit/v0.9.0"; nix-gaming.url = github:fufexan/nix-gaming; zen-browser.url = "github:youwen5/zen-browser-flake"; + niri.url = "github:sodiboo/niri-flake"; # --- Sources kakoune.url = github:mawww/kakoune; @@ -121,6 +122,7 @@ (common-nix stable) inputs.secrets.nixosModules.common inputs.nix-gaming.nixosModules.pipewireLowLatency + inputs.niri.nixosModules.niri ]; }; diff --git a/home/common.nix b/home/common.nix index 4d34941..a8d6035 100644 --- a/home/common.nix +++ b/home/common.nix @@ -5,7 +5,9 @@ ./kakoune/kak.nix ./fish/fish.nix ./modules/programs/my-broot.nix + ./modules/programs/my-waybar.nix ./modules/programs/my-sway + ./modules/programs/my-niri.nix ./modules/programs/my-kitty ./modules/programs/openconnect-epfl.nix ./common-linux.nix diff --git a/home/fish/fish.nix b/home/fish/fish.nix index 23a49cd..58babb5 100644 --- a/home/fish/fish.nix +++ b/home/fish/fish.nix @@ -13,6 +13,9 @@ let if which sway &>/dev/null set -a CHOICES "sway" end + if which niri-session &>/dev/null + set -a CHOICES "Niri" + end if which startplasma-wayland &>/dev/null set -a CHOICES "KDE Plasma" end @@ -22,6 +25,8 @@ let case "sway" systemctl --user unset-environment NIXOS_OZONE_WL exec sway + case "Niri" + exec niri-session case "KDE Plasma" exec ${pkgs.kdePackages.plasma-workspace}/libexec/plasma-dbus-run-session-if-needed startplasma-wayland case '*' diff --git a/home/kagami-pc-home.nix b/home/kagami-pc-home.nix index 2d0d7ab..659c13d 100644 --- a/home/kagami-pc-home.nix +++ b/home/kagami-pc-home.nix @@ -37,42 +37,24 @@ # Enable X11 configuration linux.graphical.type = "wayland"; linux.graphical.wallpaper = ./images/pixiv_18776904.png; - linux.graphical.startup = with pkgs; [ - zen-browser-bin - thunderbird - vesktop - ]; - linux.graphical.defaults.webBrowser = "zen.desktop"; + linux.graphical.defaults.webBrowser.package = pkgs.zen-browser-bin; + linux.graphical.defaults.webBrowser.desktopFile = "zen.desktop"; + programs.my-niri.enable = true; programs.my-sway.enable = true; programs.my-sway.fontSize = 15.0; - programs.my-sway.enableLaptopBars = false; - programs.my-sway.enableMpd = true; + programs.my-sway.enableLaptop = true; + programs.my-waybar.enableMpd = true; # Keyboard options wayland.windowManager.sway.config.input."type:keyboard".xkb_layout = "jp"; wayland.windowManager.sway.config.input."type:pointer".accel_profile = "flat"; # 144hz adaptive refresh ON! - wayland.windowManager.sway.config.output = - let - scale = 1.5; - top_x = builtins.ceil (3840 / scale); - top_y = 0; - in - with config.common.monitors; { - ${home_4k.name} = { - scale = toString scale; - position = "0 0"; - }; - ${home_1440.name} = { - position = "${toString top_x} ${toString top_y}"; - }; - }; nki.programs.kitty.enable = true; nki.programs.kitty.fontSize = 14; - programs.my-sway.waybar.makeBars = with config.common.monitors; barWith: [ + programs.my-waybar.makeBars = with config.common.monitors; barWith: [ # For primary - (barWith { extraSettings = { output = [ home_4k.name ]; }; }) + (barWith { extraSettings = { output = [ home_4k.meta.connection ]; }; }) # For secondary, hide mpd - (barWith { showMedia = false; showConnectivity = false; extraSettings = { output = [ home_1440.name ]; }; }) + (barWith { showMedia = false; showConnectivity = false; extraSettings = { output = [ home_1440.meta.connection ]; }; }) ]; # Yellow light! diff --git a/home/macbook-nixos.nix b/home/macbook-nixos.nix index d8dc729..ddd03e0 100644 --- a/home/macbook-nixos.nix +++ b/home/macbook-nixos.nix @@ -50,8 +50,8 @@ in # Enable sway programs.my-sway.enable = true; programs.my-sway.fontSize = 14.0; - programs.my-sway.enableLaptopBars = true; - programs.my-sway.enableMpd = false; + programs.my-sway.enableLaptop = true; + programs.my-waybar.enableMpd = false; programs.my-sway.discord = "${discord}/bin/armcord"; # Keyboard options wayland.windowManager.sway.config.input."type:keyboard".xkb_layout = "jp"; diff --git a/home/modules/linux/graphical/default.nix b/home/modules/linux/graphical/default.nix index 499088a..bf572d9 100644 --- a/home/modules/linux/graphical/default.nix +++ b/home/modules/linux/graphical/default.nix @@ -17,6 +17,24 @@ let echo $wifi_output end ''; + + mkPackageWithDesktopOption = opts: mkOption ({ + type = types.submodule { + options = { + package = mkOption { + type = types.package; + description = "The package for " + description; + }; + desktopFile = mkOption { + type = types.nullOr types.str; + default = null; + description = "The desktop file name for " + description + ", defaults to [packagename].desktop"; + }; + }; + }; + } // opts); + + desktopFileOf = cfg: if cfg.desktopFile == null then "${cfg.package}/share/applications/${cfg.package.pname}.desktop" else cfg.desktopFile; in { imports = [ ./x11.nix ./wayland.nix ./alacritty.nix ]; @@ -35,21 +53,23 @@ in type = types.listOf types.package; description = "List of packages to include in ~/.config/autostart"; default = with pkgs; [ - librewolf + cfg.defaults.webBrowser.package thunderbird vesktop ]; }; - defaults.webBrowser = mkOption { - type = types.str; - default = "librewolf.desktop"; - description = "Desktop file of the default web browser"; + defaults = { + webBrowser = mkPackageWithDesktopOption { description = "default web browser"; }; + terminal = mkPackageWithDesktopOption { description = "default terminal"; default.package = pkgs.kitty; }; }; }; config = mkIf (cfg.type != null) { # Packages home.packages = (with pkgs; [ + cfg.defaults.webBrowser.package + cfg.defaults.terminal.package + ## GUI stuff evince # PDF reader gparted @@ -97,15 +117,6 @@ in ]; }; - # Yellow light! - services.wlsunset = { - enable = true; - - # Lausanne - latitude = "46.31"; - longitude = "6.38"; - }; - # Cursor home.pointerCursor = { package = pkgs.suwako-cursors; @@ -150,14 +161,14 @@ in "application/x-extension-rss" = [ "thunderbird.desktop" ]; # Default web browser stuff - "text/html" = [ cfg.defaults.webBrowser ]; - "x-scheme-handler/about" = [ cfg.defaults.webBrowser ]; - "x-scheme-handler/unknown" = [ cfg.defaults.webBrowser ]; - "x-scheme-handler/http" = [ cfg.defaults.webBrowser ]; - "x-scheme-handler/https" = [ cfg.defaults.webBrowser ]; - "x-scheme-handler/ftp" = [ cfg.defaults.webBrowser ]; - "x-scheme-handler/ftps" = [ cfg.defaults.webBrowser ]; - "x-scheme-handler/file" = [ cfg.defaults.webBrowser ]; + "text/html" = [ (desktopFileOf cfg.defaults.webBrowser) ]; + "x-scheme-handler/about" = [ (desktopFileOf cfg.defaults.webBrowser) ]; + "x-scheme-handler/unknown" = [ (desktopFileOf cfg.defaults.webBrowser) ]; + "x-scheme-handler/http" = [ (desktopFileOf cfg.defaults.webBrowser) ]; + "x-scheme-handler/https" = [ (desktopFileOf cfg.defaults.webBrowser) ]; + "x-scheme-handler/ftp" = [ (desktopFileOf cfg.defaults.webBrowser) ]; + "x-scheme-handler/ftps" = [ (desktopFileOf cfg.defaults.webBrowser) ]; + "x-scheme-handler/file" = [ (desktopFileOf cfg.defaults.webBrowser) ]; # Torrent "application/x-bittorrent" = [ "deluge.desktop" ]; @@ -222,7 +233,6 @@ in qt.style.package = [ pkgs.kdePackages.breeze ]; qt.style.name = "Breeze"; - xdg.configFile = let f = pkg: { @@ -255,6 +265,26 @@ in # dconf.settings."desktop/ibus/general/hotkey" = { # triggers = hm.gvariant.mkArray hm.gvariant.type.string [ "z" ]; # }; + + # Some graphical targets + systemd.user.targets = { + # For system trays, usually after graphical-session and graphical-session-pre + tray = { + Unit.Description = lib.mkDefault "System tray"; + Unit.After = [ "graphical-session-pre.target" ]; + Unit.Before = [ "graphical-session.target" ]; + Unit.BindsTo = [ "graphical-session.target" ]; + Install.WantedBy = [ "graphical-session.target" ]; + }; + # XWayland target + xwayland = { + Unit.Description = "XWayland support"; + Unit.After = [ "graphical-session-pre.target" ]; + Unit.Before = [ "graphical-session.target" ]; + Unit.BindsTo = [ "graphical-session.target" ]; + Install.WantedBy = [ "graphical-session.target" ]; + }; + }; }; } diff --git a/home/modules/linux/graphical/wayland.nix b/home/modules/linux/graphical/wayland.nix index 3c6cbd9..d44d534 100644 --- a/home/modules/linux/graphical/wayland.nix +++ b/home/modules/linux/graphical/wayland.nix @@ -11,9 +11,9 @@ let style = ./swaync.css; }; systemd.user.services.swaync.Install.WantedBy = lib.mkForce [ "sway-session.target" ]; - systemd.user.services.swaync.Unit.PartOf = lib.mkForce [ "sway-session.target" ]; + systemd.user.services.swaync.Unit.PartOf = lib.mkForce [ "graphical-session.target" ]; - programs.my-sway.waybar = { + programs.my-waybar = { extraSettings = [{ modules-right = mkAfter [ "custom/swaync" ]; modules."custom/swaync" = { @@ -66,6 +66,7 @@ let name = "rofi-rbw-script"; runtimeInputs = with pkgs; [ rofi wtype rofi-rbw ]; text = "rofi-rbw"; + meta.mainProgram = "rofi-rbw-script"; }; in with lib; @@ -100,6 +101,16 @@ with lib; ANKI_WAYLAND = "1"; }; + # Yellow light! + services.wlsunset = { + enable = true; + + # Lausanne + latitude = "46.31"; + longitude = "6.38"; + }; + + # Notification system # services.dunst = { # enable = true; @@ -119,9 +130,6 @@ with lib; # settings.experimental.per_monitor_dpi = "true"; # }; - - # Forward wallpaper settings to sway - programs.my-sway.wallpaper = config.linux.graphical.wallpaper; }; } diff --git a/home/modules/monitors.nix b/home/modules/monitors.nix index 70b7013..f9180a5 100644 --- a/home/modules/monitors.nix +++ b/home/modules/monitors.nix @@ -5,32 +5,47 @@ let # Internal "framework" = { name = "BOE 0x0BCA Unknown"; - mode = "2256x1504@60Hz"; + meta.mode = { width = 2256; height = 1504; refresh = 60.0; }; scale = 1.25; }; + "yoga" = { + name = "AU Optronics 0xD291 Unknown"; + meta.connection = "eDP-1"; + meta.mode = { width = 1920; height = 1080; refresh = 60.026; }; + scale = 1; + }; # External ## Work @ EPFL "work" = { name = "LG Electronics LG ULTRAFINE 301MAXSGHD10"; - mode = "3840x2160@60Hz"; + meta.mode = { width = 3840; height = 2160; refresh = 60.0; }; scale = 1.25; }; "home_4k" = { name = "AOC U28G2G6B PPYP2JA000013"; - mode = "3840x2160@60Hz"; scale = 1.5; adaptive_sync = "on"; - # render_bit_depth = "10"; + meta = { + connection = "DP-2"; + mode = { width = 3840; height = 2160; refresh = 60.0; }; + fixedPosition = { x = 0; y = 0; }; + niriName = "PNP(AOC) U28G2G6B PPYP2JA000013"; + }; }; "home_1440" = { name = "AOC Q27G2G3R3B VXJP6HA000442"; - mode = "2560x1440@165Hz"; adaptive_sync = "on"; + meta = { + connection = "DP-3"; + mode = { width = 2560; height = 1440; refresh = 165.0; }; + fixedPosition = { x = 2560; y = 0; }; + niriName = "PNP(AOC) Q27G2G3R3B VXJP6HA000442"; + }; }; "viewsonic_1080" = { name = "ViewSonic Corporation XG2402 SERIES V4K182501054"; - mode = "1920x1080@144Hz"; + meta.mode = { width = 1920; height = 1080; refresh = 144.0; }; adaptive_sync = "on"; }; @@ -38,9 +53,13 @@ let eachMonitor = _name: monitor: { name = monitor.name; - value = builtins.removeAttrs monitor [ "scale" "name" ] // (if monitor ? scale then { + value = builtins.removeAttrs monitor [ "scale" "name" "meta" ] // (lib.optionalAttrs (monitor ? scale) { scale = toString monitor.scale; - } else { }); + }) // { + mode = with monitor.meta.mode; "${toString width}x${toString height}@${toString refresh}Hz"; + } // (lib.optionalAttrs (monitor.meta ? fixedPosition) { + position = with monitor.meta.fixedPosition; "${toString x} ${toString y}"; + }); }; in { diff --git a/home/modules/programs/my-kitty/default.nix b/home/modules/programs/my-kitty/default.nix index a1c03c0..45801dd 100644 --- a/home/modules/programs/my-kitty/default.nix +++ b/home/modules/programs/my-kitty/default.nix @@ -19,6 +19,11 @@ with lib; options.nki.programs.kitty = { enable = mkEnableOption "Enable kitty"; + setDefault = mkOption { + type = types.bool; + description = "Set kitty as default terminal"; + default = true; + }; package = mkOption { type = types.package; @@ -51,6 +56,10 @@ with lib; }; }; + config.linux.graphical = mkIf (cfg.enable && cfg.setDefault) { + defaults.terminal.package = cfg.package; + }; + config.programs.kitty = mkIf cfg.enable { enable = true; @@ -65,7 +74,7 @@ with lib; # Background color and transparency background = if isNull cfg.background then { - background_opacity = "0.85"; + background_opacity = "0.93"; dynamic_background_opacity = true; } else { background_image = "${cfg.background}"; diff --git a/home/modules/programs/my-niri.nix b/home/modules/programs/my-niri.nix new file mode 100644 index 0000000..d62a175 --- /dev/null +++ b/home/modules/programs/my-niri.nix @@ -0,0 +1,388 @@ +{ config, osConfig, lib, pkgs, ... }: +let + cfg = config.programs.my-niri; + + sh = config.lib.niri.actions.spawn "sh" "-c"; + playerctl = lib.getExe pkgs.playerctl; + amixer = lib.getExe' pkgs.alsa-utils "amixer"; + brightnessctl = lib.getExe pkgs.brightnessctl; + app-menu = "${pkgs.dmenu}/bin/dmenu_path | ${pkgs.bemenu}/bin/bemenu | ${pkgs.findutils}/bin/xargs swaymsg exec --"; + + wallpaper = config.linux.graphical.wallpaper; + + xwayland-display = ":0"; + +in +{ + options.programs.my-niri = { + enable = lib.mkEnableOption "My own niri configuration"; + + enableLaptop = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Enable laptop options"; + }; + + lock-command = lib.mkOption { + type = lib.types.listOf lib.types.str; + description = "The command to lock the screen"; + default = [ "${pkgs.swaylock}/bin/swaylock" ] + ++ (if wallpaper == "" then [ "" ] else [ "-i" "${wallpaper}" "-s" "fill" ]) + ++ [ "-l" "-k" ]; + }; + + workspaces = lib.mkOption { + type = lib.types.attrsOf + (lib.types.submodule { + options = { + name = lib.mkOption { type = lib.types.str; description = "workspace name"; }; + fixed = lib.mkOption { + type = lib.types.bool; + default = true; + description = "whether workspace always exists"; + }; + monitor = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = "Default monitor to spawn workspace in"; + }; + }; + }); + description = "A mapping of ordering to workspace names, for fixed workspaces"; + }; + }; + + config = lib.mkIf cfg.enable { + programs.my-niri.workspaces = { + # Default workspaces, always there + "01" = { name = "🌏 web"; }; + "02" = { name = "💬 chat"; }; + "03" = { name = "⚙️ code"; }; + "04" = { name = "🎶 music"; }; + "05" = { name = "🔧 extra"; }; + "06" = { name = "🧰 6"; }; + "07" = { name = "🔩 7"; }; + "08" = { name = "🛠️ 8"; }; + "09" = { name = "🔨 9"; }; + "10" = { name = "🎲 misc"; }; + "99" = { name = "📧 Email"; }; + }; + systemd.user.services.swaync.Install.WantedBy = [ "niri.service" ]; + systemd.user.services.swaync.Unit.After = [ "niri.service" ]; + systemd.user.targets.tray.Unit.After = [ "niri.service" ]; + systemd.user.services.waybar.Unit.After = [ "niri.service" ]; + systemd.user.services.waybar.Install.WantedBy = [ "niri.service" ]; + systemd.user.targets.xwayland.Unit.After = [ "niri.service" ]; + + # xwayland-satellite + systemd.user.services.niri-xwayland-satellite = lib.mkIf cfg.enable { + Unit = { + Description = "XWayland Client for niri"; + PartOf = [ "xwayland.target" ]; + Before = [ "xwayland.target" "xdg-desktop-autostart.target" ]; + After = [ "niri.service" ]; + }; + Install.UpheldBy = [ "niri.service" ]; + Service.Slice = "session.slice"; + Service.Type = "notify"; + Service.ExecStart = "${lib.getExe pkgs.xwayland-satellite} ${xwayland-display}"; + }; + + programs.niri.settings = { + environment = { + QT_QPA_PLATFORM = "wayland"; + QT_WAYLAND_DISABLE_WINDOWDECORATION = "1"; + QT_IM_MODULE = "fcitx"; + GTK_IM_MODULE = "fcitx"; # Til text-input is merged + # export NIXOS_OZONE_WL=1 # Until text-input is merged + DISPLAY = xwayland-display; + } // lib.optionalAttrs osConfig.services.desktopManager.plasma6.enable { + XDG_MENU_PREFIX = "plasma-"; + }; + input.keyboard.xkb = { layout = "jp"; }; + input.touchpad = lib.mkIf cfg.enableLaptop { + tap = true; + dwt = true; + natural-scroll = true; + middle-emulation = true; + }; + input.mouse = { + accel-profile = "flat"; + }; + input.warp-mouse-to-focus = true; + input.focus-follows-mouse = { + enable = true; + max-scroll-amount = "0%"; + }; + + outputs = + let + eachMonitor = _: monitor: { + name = monitor.meta.niriName or monitor.name; # Niri might not find the monitor by name + value = { + mode = monitor.meta.mode; + position = monitor.meta.fixedPosition or null; + scale = monitor.scale or 1; + variable-refresh-rate = (monitor.adaptive_sync or "off") == "on"; + }; + }; + in + lib.mapAttrs' eachMonitor config.common.monitors; + + spawn-at-startup = [ + # Wallpaper + { command = [ (lib.getExe pkgs.swaybg) "-i" "${wallpaper}" "-m" "fill" ]; } + # Waybar + { command = [ "systemctl" "--user" "start" "xdg-desktop-portal-gtk.service" "xdg-desktop-portal.service" ]; } + ]; + + layout = { + gaps = 16; + preset-column-widths = [ + { proportion = 1. / 3.; } + { proportion = 1. / 2.; } + { proportion = 2. / 3.; } + ]; + default-column-width.proportion = 1. / 2.; + + focus-ring = { + width = 4; + active.gradient = { from = "#00447AFF"; to = "#71C4FFAA"; angle = 45; }; + inactive.color = "#505050"; + }; + border.enable = false; + struts = let v = 8; in { left = v; right = v; bottom = v; top = v; }; + }; + + prefer-no-csd = true; + + workspaces = + let + fixedWorkspaces = lib.filterAttrs (_: w: w.fixed) cfg.workspaces; + workspaceConfig = lib.mapAttrs + (_: w: { inherit (w) name; } // (lib.optionalAttrs (w.monitor != null) { + open-on-output = w.monitor; + })) + fixedWorkspaces; + in + workspaceConfig; + + window-rules = [ + # Rounded Corners + { + geometry-corner-radius = let v = 8.0; in { bottom-left = v; bottom-right = v; top-left = v; top-right = v; }; + clip-to-geometry = true; + } + # Workspace assignments + { + open-on-workspace = cfg.workspaces."01".name; + open-maximized = true; + matches = [ + { at-startup = true; app-id = "^firefox$"; } + { at-startup = true; app-id = "^librewolf$"; } + { at-startup = true; app-id = "^zen$"; } + ]; + } + { + open-on-workspace = cfg.workspaces."02".name; + open-maximized = true; + matches = [ + { title = "^((d|D)iscord|((A|a)rm(c|C)ord))$"; } + { title = "VencordDesktop"; } + { app-id = "VencordDesktop"; } + { title = "vesktop"; } + { app-id = "vesktop"; } + + { title = "Slack"; } + ]; + } + { + open-on-workspace = cfg.workspaces."99".name; + open-maximized = true; + matches = [ + { app-id = "thunderbird"; } + { app-id = "evolution"; } + ]; + } + # Floating + { + open-floating = true; + matches = [ + { app-id = ".*float.*"; } + { app-id = "org\\.freedesktop\\.impl\\.portal\\.desktop\\..*"; } + { title = ".*float.*"; } + { title = "Extension: .*Bitwarden.*"; } + { app-id = "Rofi"; } + ]; + } + + # xwaylandvideobridge + { + matches = [{ app-id = "^xwaylandvideobridge$"; }]; + open-floating = true; + focus-ring.enable = false; + opacity = 0.0; + default-floating-position = { + x = 0; + y = 0; + relative-to = "bottom-right"; + }; + min-width = 1; + max-width = 1; + min-height = 1; + max-height = 1; + } + + # Kitty dimming + { + matches = [{ app-id = "kitty"; }]; + excludes = [{ is-focused = true; }]; + opacity = 0.95; + } + ]; + + layer-rules = [ + { + matches = [{ namespace = "^swaync-.*"; }]; + block-out-from = "screen-capture"; + } + ]; + + binds = with config.lib.niri.actions; { + # Mod-Shift-/, which is usually the same as Mod-?, + # shows a list of important hotkeys. + "Mod+Shift+Slash".action = show-hotkey-overlay; + + # Some basic spawns + "Mod+Return".action = spawn (lib.getExe config.linux.graphical.defaults.terminal.package); + "Mod+Space".action = spawn (lib.getExe pkgs.rofi) "-show" "drun"; + "Mod+R".action = sh app-menu; + "Mod+Semicolon".action = spawn cfg.lock-command; + "Mod+Shift+P".action = spawn "rofi-rbw-script"; + + # Audio and Volume + "XF86AudioPrev" = { action = spawn playerctl "previous"; allow-when-locked = true; }; + "XF86AudioPlay" = { action = spawn playerctl "play-pause"; allow-when-locked = true; }; + "Shift+XF86AudioPlay" = { action = spawn playerctl "stop"; allow-when-locked = true; }; + "XF86AudioNext" = { action = spawn playerctl "next"; allow-when-locked = true; }; + "XF86AudioRecord" = { action = spawn amixer "-q" "set" "Capture" "toggle"; allow-when-locked = true; }; + "XF86AudioMute" = { action = spawn amixer "-q" "set" "Master" "toggle"; allow-when-locked = true; }; + "XF86AudioLowerVolume" = { action = spawn amixer "-q" "set" "Master" "3%-"; allow-when-locked = true; }; + "XF86AudioRaiseVolume" = { action = spawn amixer "-q" "set" "Master" "3%+"; allow-when-locked = true; }; + + # Backlight + "XF86MonBrightnessDown".action = spawn brightnessctl "s" "10%-"; + "XF86MonBrightnessUp".action = spawn brightnessctl "s" "10%+"; + "Shift+XF86MonBrightnessDown".action = spawn brightnessctl "-d" "kbd_backlight" "s" "25%-"; + "Shift+XF86MonBrightnessUp".action = spawn brightnessctl "-d" "kbd_backlight" "s" "25%+"; + + "Mod+Shift+Q".action = close-window; + + "Mod+Left".action = focus-column-or-monitor-left; + "Mod+Right".action = focus-column-or-monitor-right; + "Mod+Up".action = focus-window-or-workspace-up; + "Mod+Down".action = focus-window-or-workspace-down; + "Mod+H".action = focus-column-or-monitor-left; + "Mod+L".action = focus-column-or-monitor-right; + "Mod+K".action = focus-window-or-workspace-up; + "Mod+J".action = focus-window-or-workspace-down; + + "Mod+Shift+Left".action = move-column-left-or-to-monitor-left; + "Mod+Shift+Right".action = move-column-right-or-to-monitor-right; + "Mod+Shift+Up".action = move-window-up-or-to-workspace-up; + "Mod+Shift+Down".action = move-window-down-or-to-workspace-down; + "Mod+Shift+H".action = move-column-left-or-to-monitor-left; + "Mod+Shift+L".action = move-column-right-or-to-monitor-right; + "Mod+Shift+K".action = move-window-up-or-to-workspace-up; + "Mod+Shift+J".action = move-window-down-or-to-workspace-down; + + "Mod+Bracketleft".action = focus-column-first; + "Mod+Bracketright".action = focus-column-last; + "Mod+Shift+Bracketleft".action = move-column-to-first; + "Mod+Shift+Bracketright".action = move-column-to-last; + + # For compat with my current sway + "Mod+Ctrl+H".action = move-workspace-to-monitor-left; + "Mod+Ctrl+L".action = move-workspace-to-monitor-right; + + "Mod+I".action = focus-workspace-down; + "Mod+O".action = focus-workspace-up; + "Mod+Shift+I".action = move-column-to-workspace-down; + "Mod+Shift+O".action = move-column-to-workspace-up; + "Mod+Ctrl+I".action = move-workspace-down; + "Mod+Ctrl+O".action = move-workspace-up; + + # Mouse bindings + "Mod+WheelScrollDown" = { action = focus-workspace-down; cooldown-ms = 150; }; + "Mod+WheelScrollUp" = { action = focus-workspace-up; cooldown-ms = 150; }; + "Mod+Ctrl+WheelScrollDown" = { action = move-column-to-workspace-down; cooldown-ms = 150; }; + "Mod+Ctrl+WheelScrollUp" = { action = move-column-to-workspace-up; cooldown-ms = 150; }; + + "Mod+WheelScrollRight".action = focus-column-right; + "Mod+WheelScrollLeft".action = focus-column-left; + "Mod+Ctrl+WheelScrollRight".action = move-column-right; + "Mod+Ctrl+WheelScrollLeft".action = move-column-left; + + # You can refer to workspaces by index. However, keep in mind that + # niri is a dynamic workspace system, so these commands are kind of + # "best effort". Trying to refer to a workspace index bigger than + # the current workspace count will instead refer to the bottommost + # (empty) workspace. + # + # For example, with 2 workspaces + 1 empty, indices 3, 4, 5 and so on + # will all refer to the 3rd workspace. + "Mod+1".action = focus-workspace (cfg.workspaces."01".name); + "Mod+2".action = focus-workspace (cfg.workspaces."02".name); + "Mod+3".action = focus-workspace (cfg.workspaces."03".name); + "Mod+4".action = focus-workspace (cfg.workspaces."04".name); + "Mod+5".action = focus-workspace (cfg.workspaces."05".name); + "Mod+6".action = focus-workspace (cfg.workspaces."06".name); + "Mod+7".action = focus-workspace (cfg.workspaces."07".name); + "Mod+8".action = focus-workspace (cfg.workspaces."08".name); + "Mod+9".action = focus-workspace (cfg.workspaces."09".name); + "Mod+0".action = focus-workspace (cfg.workspaces."10".name); + "Mod+Shift+1".action = move-column-to-workspace (cfg.workspaces."01".name); + "Mod+Shift+2".action = move-column-to-workspace (cfg.workspaces."02".name); + "Mod+Shift+3".action = move-column-to-workspace (cfg.workspaces."03".name); + "Mod+Shift+4".action = move-column-to-workspace (cfg.workspaces."04".name); + "Mod+Shift+5".action = move-column-to-workspace (cfg.workspaces."05".name); + "Mod+Shift+6".action = move-column-to-workspace (cfg.workspaces."06".name); + "Mod+Shift+7".action = move-column-to-workspace (cfg.workspaces."07".name); + "Mod+Shift+8".action = move-column-to-workspace (cfg.workspaces."08".name); + "Mod+Shift+9".action = move-column-to-workspace (cfg.workspaces."09".name); + "Mod+Shift+0".action = move-column-to-workspace (cfg.workspaces."10".name); + + "Mod+asciicircum".action = focus-workspace (cfg.workspaces."99".name); + "Mod+Shift+asciicircum".action = move-column-to-workspace (cfg.workspaces."99".name); + + "Mod+Tab".action = focus-workspace-previous; + + "Mod+Comma".action = consume-or-expel-window-left; + "Mod+Period".action = consume-or-expel-window-right; + + "Mod+W".action = switch-preset-column-width; + "Mod+Shift+W".action = switch-preset-window-height; + "Mod+Ctrl+W".action = reset-window-height; + "Mod+F".action = maximize-column; + "Mod+Shift+F".action = fullscreen-window; + "Mod+E".action = center-column; + + "Mod+Minus".action = set-column-width "-10%"; + "Mod+At".action = set-column-width "+10%"; + "Mod+Shift+Minus".action = set-window-height "-10%"; + "Mod+Shift+At".action = set-window-height "+10%"; + + "Mod+V".action = switch-focus-between-floating-and-tiling; + "Mod+Shift+V".action = toggle-window-floating; + "Mod+Shift+Space".action = toggle-window-floating; # Sway compat + + "Print".action = screenshot; + "Ctrl+Print".action = screenshot-screen; + "Shift+Print".action = screenshot-window; + + "Mod+Shift+E".action = quit; + }; + }; + }; +} + diff --git a/home/modules/programs/my-sway/default.nix b/home/modules/programs/my-sway/default.nix index 428c56e..e073abf 100644 --- a/home/modules/programs/my-sway/default.nix +++ b/home/modules/programs/my-sway/default.nix @@ -44,10 +44,7 @@ let ${pkgs.grim}/bin/grim -g (${pkgs.slurp}/bin/slurp) - | ${pkgs.swappy}/bin/swappy -f - ''; - - ignored-devices = [ "Surface_Headphones" ]; - playerctl = "${pkgs.playerctl}/bin/playerctl --ignore-player=${strings.concatStringsSep "," ignored-devices}"; - + playerctl = "${pkgs.playerctl}/bin/playerctl"; in { # imports = [ ./ibus.nix ]; @@ -66,17 +63,23 @@ in wallpaper = mkOption { type = types.oneOf [ types.path types.str ]; description = "Path to the wallpaper to be used"; - default = ""; + default = config.linux.graphical.wallpaper; }; terminal = mkOption { type = types.str; description = "The command to the terminal emulator to be used"; - default = "${config.programs.kitty.package}/bin/kitty"; + default = lib.getExe config.linux.graphical.defaults.terminal.package; }; browser = mkOption { type = types.str; description = "The command for the browser"; - default = "${pkgs.firefox-wayland}/bin/firefox"; + default = lib.getExe config.linux.graphical.defaults.webBrowser.package; + }; + + enableLaptop = lib.mkOption { + type = lib.types.bool; + description = "Whether to enable laptop-specific stuff"; + default = true; }; lockCmd = mkOption { @@ -86,34 +89,20 @@ in + (if cfg.wallpaper == "" then "" else " -i ${cfg.wallpaper} -s fill") + " -l -k"; }; - enableLaptopBars = mkOption { - type = types.bool; - description = "Whether to enable laptop-specific bars (battery)"; - default = true; - }; - enableMpd = mkOption { - type = types.bool; - description = "Whether to enable mpd on waybar"; - default = false; - }; + }; - waybar = { - makeBars = mkOption { - type = types.raw; - description = "Create bars with the barWith function, return a list of bars"; - default = barWith: [ (barWith { }) ]; - }; - extraSettings = mkOption { - type = types.listOf types.raw; - description = "Extra settings to be included with every default bar"; - default = [ ]; - }; - extraStyle = mkOption { - type = types.lines; - description = "Additional style for the default waybar"; - default = ""; - }; - }; + config.systemd.user.targets.sway-session = mkIf cfg.enable { + Unit.Before = [ "tray.target" "xwayland.target" "xdg-desktop-portal.service" "xdg-desktop-autostart.target" ]; + Unit.Upholds = [ "waybar.service" ]; + Unit.Wants = [ "xdg-desktop-autostart.target" ]; + }; + + # Enable waybar + config.programs.my-waybar = mkIf cfg.enable { + enable = true; + fontSize = mkDefault cfg.fontSize; + enableLaptopBars = mkDefault cfg.enableLaptop; + terminal = mkDefault cfg.terminal; }; config.wayland.windowManager.sway = mkIf cfg.enable { @@ -126,10 +115,10 @@ in ] ++ lib.optionals osConfig.services.desktopManager.plasma6.enable [ "XDG_MENU_PREFIX" ]; - systemd.extraCommands = options.wayland.windowManager.sway.systemd.extraCommands.default - ++ [ - "systemctl --user restart xdg-desktop-portal.service" - ]; + # systemd.extraCommands = options.wayland.windowManager.sway.systemd.extraCommands.default + # ++ [ + # "systemctl --user restart xdg-desktop-portal.service" + # ]; checkConfig = false; # Not working atm config = { @@ -158,10 +147,10 @@ in menu = "${pkgs.dmenu}/bin/dmenu_path | ${pkgs.bemenu}/bin/bemenu | ${pkgs.findutils}/bin/xargs swaymsg exec --"; # Startup startup = [ - # Dex for autostart - { command = "${pkgs.dex}/bin/dex -ae sway"; } - # Waybar - { command = "systemctl --user restart waybar"; always = true; } + # # Dex for autostart + # { command = "${pkgs.dex}/bin/dex -ae sway"; } + # # Waybar + # { command = "systemctl --user restart waybar"; always = true; } # IME { command = "fcitx5"; } ]; @@ -293,6 +282,7 @@ in "${builtins.elemAt workspaces 0}" = [ { app_id = "^firefox$"; } { app_id = "^librewolf$"; } + { app_id = "^zen$"; } ]; "${builtins.elemAt workspaces 1}" = [ { class = "^((d|D)iscord|((A|a)rm(c|C)ord))$"; } @@ -366,7 +356,7 @@ in wrapperFeatures.gtk = true; extraConfig = - (if cfg.enableLaptopBars then '' + (if cfg.enableLaptop then '' # Lock screen on lid close bindswitch lid:off exec ${cfg.lockCmd} @@ -409,369 +399,6 @@ in ]; }; - config.programs.waybar = - let - barWith = { showMedia ? true, showConnectivity ? true, extraSettings ? { }, ... }: mkMerge ([{ - position = "top"; - modules-left = [ - "sway/workspaces" - "sway/mode" - "sway/window" - ]; - modules-center = [ - ]; - modules-right = - lib.optional showMedia (if cfg.enableMpd then "mpd" else "custom/media") - ++ [ - "tray" - "pulseaudio" - ] ++ lib.optionals showConnectivity [ - "bluetooth" - "network" - ] ++ [ - "cpu" - "memory" - "temperature" - ] ++ lib.optionals cfg.enableLaptopBars [ "battery" "battery#bat2" ] - ++ [ - "clock" - ]; - - modules = { - "sway/workspaces" = { - format = "{name}"; - }; - "sway/mode" = { - format = "{}"; - }; - "sway/window" = { - max-length = 70; - format = "{title}"; - "rewrite" = { - "(.*) — Mozilla Firefox" = "[🌎] $1"; - "(.*) - Mozilla Thunderbird" = "[📧] $1"; - "(.*) - Kakoune" = "[⌨️] $1"; - "(.*) - fish" = "[>_] $1"; - "(.*) - Discord" = "[🗨️] $1"; - # ArmCord thing - "• Discord \\| (.*)" = "[🗨️] $1"; - "\\((\\d+)\\) Discord \\| (.*)" = "[🗨️] {$1} $2"; - }; - }; - "tray" = { - icon-size = 21; - spacing = 10; - }; - "clock" = { - # format = "{:📅 %Y-%m-%d | 🕰️ %H:%M [%Z]}"; - format = "📅 {0:%Y-%m-%d} |️ 🕰️ {0:%H:%M [%Z]}"; - tooltip-format = "\n{calendar}"; - timezones = [ - "Europe/Zurich" - "America/Toronto" - "Asia/Tokyo" - "Asia/Ho_Chi_Minh" - ]; - calendar = { - mode = "year"; - mode-mon-col = 3; - weeks-pos = "right"; - on-scroll = 1; - on-click-right = "mode"; - format = { - months = "{}"; - days = "{}"; - weeks = "W{}"; - weekdays = "日 月 火 水 木 金 土"; # See https://github.com/Alexays/Waybar/issues/3132 - today = "{}"; - }; - }; - actions = { - on-click-middle = "mode"; - on-click-right = "tz_up"; - on-scroll-up = "shift_up"; - on-scroll-down = "shift_down"; - }; - }; - "cpu" = { - format = "{usage}% "; - }; - "memory" = { - format = "{}% "; - }; - "temperature" = { - # thermal-zone = 2; - # hwmon-path" = "/sys/class/hwmon/hwmon2/temp1_input"; - critical-threshold = 80; - # format-critical = "{temperatureC}°C "; - format = "{temperatureC}°C "; - }; - "backlight" = { - # device = "acpi_video1"; - format = "{percent}% {icon}"; - states = [ 0 50 ]; - format-icons = [ "" "" ]; - }; - "battery" = mkIf cfg.enableLaptopBars { - states = { - good = 95; - warning = 30; - critical = 15; - }; - format = "{capacity}% {icon}"; - # format-good = ""; # An empty format will hide the module - # format-full = ""; - format-icons = [ "" "" "" "" "" ]; - }; - "battery#bat2" = mkIf cfg.enableLaptopBars { - bat = "BAT2"; - }; - "network" = { - # interface = wlp2s0 # (Optional) To force the use of this interface - format-wifi = "{essid} ({signalStrength}%) "; - format-ethernet = "{ifname}: {ipaddr}/{cidr} "; - format-disconnected = "Disconnected ⚠"; - interval = 7; - }; - "bluetooth" = { - format = " {status}"; - format-connected = " {device_alias}"; - format-connected-battery = " {device_alias} {device_battery_percentage}%"; - # format-device-preference= [ "device1", "device2" ], // preference list deciding the displayed devic; - tooltip-format = "{controller_alias}\t{controller_address}\n\n{num_connections} connected"; - tooltip-format-connected = "{controller_alias}\t{controller_address}\n\n{num_connections} connected\n\n{device_enumerate}"; - tooltip-format-enumerate-connected = "{device_alias}\t{device_address}"; - tooltip-format-enumerate-connected-battery = "{device_alias}\t{device_address}\t{device_battery_percentage}%"; - on-click = "${pkgs.blueman}/bin/blueman-manager"; - }; - "pulseaudio" = { - # scroll-step = 1; - format = "{volume}% {icon}"; - format-bluetooth = "{volume}% {icon}"; - format-muted = ""; - format-icons = { - headphones = ""; - handsfree = ""; - headset = ""; - phone = ""; - portable = ""; - car = ""; - default = [ "" "" ]; - }; - on-click = "${pkgs.pavucontrol}/bin/pavucontrol"; - }; - "mpd" = { - "format" = "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} - {album} - {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) 🎧"; - "format-disconnected" = "Disconnected 🎧"; - "format-stopped" = "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped 🎧"; - "interval" = 2; - "consume-icons" = { - "on" = " "; # Icon shows only when "consume" is on - }; - "random-icons" = { - "off" = " "; # Icon grayed out when "random" is off; - "on" = " "; - }; - "repeat-icons" = { - "on" = " "; - }; - "single-icons" = { - "on" = "1 "; - }; - "state-icons" = { - "paused" = ""; - "playing" = ""; - }; - "tooltip-format" = "MPD (connected)"; - "tooltip-format-disconnected" = "MPD (disconnected)"; - "on-click" = "${pkgs.mpc_cli}/bin/mpc toggle"; - "on-click-right" = "${pkgs.mpc_cli}/bin/mpc stop"; - "on-click-middle" = "${cfg.terminal} --class=kitty_ncmpcpp ${pkgs.ncmpcpp}/bin/ncmpcpp"; - }; - "custom/media" = { - "format" = "{icon}{}"; - "return-type" = "json"; - "format-icons" = { - "Playing" = " "; - "Paused" = " "; - }; - "max-length" = 80; - "exec" = "${playerctl} -a metadata --format '{\"text\": \"{{artist}} - {{markup_escape(title)}}\", \"tooltip\": \"{{playerName}} : {{markup_escape(title)}}\", \"alt\": \"{{status}}\", \"class\": \"{{status}}\"}' -F"; - "on-click" = "${playerctl} play-pause"; - }; - }; - }] ++ - cfg.waybar.extraSettings - ++ [ extraSettings ]); - in - mkIf cfg.enable { - enable = true; - systemd.enable = true; - systemd.target = "sway-session.target"; - settings = cfg.waybar.makeBars barWith; - style = '' - * { - border: none; - border-radius: 0; - font-family: monospace, 'Font Awesome 5', 'Symbols Nerd Font Mono', 'SFNS Display', Helvetica, Arial, sans-serif; - font-size: ${toString (cfg.fontSize * 1.1)}px; - min-height: 0; - } - - window#waybar { - background: rgba(43, 48, 59, 0.8); - border-bottom: 3px solid rgba(100, 114, 125, 0.5); - color: #ffffff; - } - - window#waybar.hidden { - opacity: 0.0; - } - /* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */ - #workspaces button { - padding: 0 5px; - background: transparent; - color: #ffffff; - border-bottom: 3px solid transparent; - } - - #workspaces button.focused { - background: #64727D; - border-bottom: 3px solid #ffffff; - } - - #workspaces button.urgent { - background-color: #eb4d4b; - } - - #window, #sway, #sway-window { - padding-left: 1em; - margin-bottom: 0.4em; - } - - #mode { - background: #64727D; - border-bottom: 3px solid #ffffff; - } - - /* #clock, #battery, #cpu, #memory, #temperature, #backlight, #network, #pulseaudio, #bluetooth, #custom-media, #tray, #mode, #idle_inhibitor, #mpd { */ - .modules-right > * > * { - margin: 0.2em 0 0.4em 0; - padding: 0.2em 0.5em; - border: 1px solid rgba(0, 0, 0, 0.25); - border-radius: 0.3em; - } - - .modules-right > *:not(:last-child) > * { - margin-right: 0.4em; - } - - #clock { - background-color: #64727D; - } - - #battery { - background-color: #ffffff; - color: #000000; - } - - #battery.charging { - color: #ffffff; - background-color: #26A65B; - } - - @keyframes blink { - to { - background-color: #ffffff; - color: #000000; - } - } - - #battery.critical:not(.charging) { - background: #f53c3c; - color: #ffffff; - animation-name: blink; - animation-duration: 0.5s; - animation-timing-function: linear; - animation-iteration-count: infinite; - animation-direction: alternate; - } - - #cpu { - background: #2ecc71; - color: #000000; - } - - #memory { - background: #9b59b6; - } - - #backlight { - background: #90b1b1; - } - - #network { - background: #2980b9; - } - - #network.disconnected { - background: #f53c3c; - } - - #pulseaudio { - background: #f1c40f; - color: #000000; - } - - #pulseaudio.muted { - background: #90b1b1; - } - - #bluetooth { - background: DarkSlateBlue; - color: white; - } - - #custom-media { - background: #66cc99; - color: #2a5c45; - } - - .custom-spotify { - background: #66cc99; - } - - .custom-vlc { - background: #ffa000; - } - - #temperature { - background: #f0932b; - } - - #temperature.critical { - background: #eb4d4b; - } - - #tray { - background-color: #2980b9; - } - - #idle_inhibitor { - background-color: #2d3436; - } - - #idle_inhibitor.activated { - background-color: #ecf0f1; - color: #2d3436; - } - - #mpd { - background-color: teal; - color: white; - } - '' + cfg.waybar.extraStyle; - }; config.home.packages = mkIf cfg.enable (with pkgs; [ # Needed for QT_QPA_PLATFORM kdePackages.qtwayland diff --git a/home/modules/programs/my-waybar.nix b/home/modules/programs/my-waybar.nix new file mode 100644 index 0000000..f8282f5 --- /dev/null +++ b/home/modules/programs/my-waybar.nix @@ -0,0 +1,427 @@ +{ lib, config, pkgs, ... }: +let + cfg = config.programs.my-waybar; +in +{ + options.programs.my-waybar = { + enable = lib.mkEnableOption "custom configuration for waybar"; + fontSize = lib.mkOption { + type = lib.types.float; + description = "The default font size"; + }; + terminal = lib.mkOption { + type = lib.types.str; + description = "The command to the terminal emulator to be used"; + default = "${config.programs.kitty.package}/bin/kitty"; + }; + + enableLaptopBars = lib.mkOption { + type = lib.types.bool; + description = "Whether to enable laptop-specific bars (battery)"; + default = true; + }; + enableMpd = lib.mkOption { + type = lib.types.bool; + description = "Whether to enable mpd on waybar"; + default = false; + }; + + makeBars = lib.mkOption { + type = lib.types.raw; + description = "Create bars with the barWith function, return a list of bars"; + default = barWith: [ (barWith { }) ]; + }; + extraSettings = lib.mkOption { + type = lib.types.listOf lib.types.raw; + description = "Extra settings to be included with every default bar"; + default = [ ]; + }; + extraStyle = lib.mkOption { + type = lib.types.lines; + description = "Additional style for the default waybar"; + default = ""; + }; + }; + config.systemd.user.services.waybar = lib.mkIf cfg.enable { + Unit.Before = [ "tray.target" ]; + }; + config.programs.waybar = + let + barWith = { showMedia ? true, showConnectivity ? true, extraSettings ? { }, ... }: lib.mkMerge ([{ + layer = "top"; + position = "top"; + modules-left = [ + "sway/workspaces" + "sway/mode" + "sway/window" + "niri/workspaces" + "niri/window" + ]; + modules-center = [ + ]; + modules-right = + lib.optional showMedia (if cfg.enableMpd then "mpd" else "custom/media") + ++ [ + "tray" + "pulseaudio" + ] ++ lib.optionals showConnectivity [ + "bluetooth" + "network" + ] ++ [ + "cpu" + "memory" + "temperature" + ] ++ lib.optionals cfg.enableLaptopBars [ "battery" "battery#bat2" ] + ++ [ + "clock" + ]; + + modules = { + "sway/workspaces" = { + format = "{name}"; + }; + "sway/mode" = { + format = "{}"; + }; + "sway/window" = { + max-length = 70; + format = "{title}"; + "rewrite" = { + "(.*) — Mozilla Firefox" = "[🌎] $1"; + "(.*) - Mozilla Thunderbird" = "[📧] $1"; + "(.*) - Kakoune" = "[⌨️] $1"; + "(.*) - fish" = "[>_] $1"; + "(.*) - Discord" = "[🗨️] $1"; + # ArmCord thing + "• Discord \\| (.*)" = "[🗨️] $1"; + "\\((\\d+)\\) Discord \\| (.*)" = "[🗨️] {$1} $2"; + }; + }; + "niri/window" = { + format = "{title}"; + "rewrite" = { + "(.*) — Mozilla Firefox" = "[🌎] $1"; + "(.*) - Mozilla Thunderbird" = "[📧] $1"; + "(.*) - Kakoune" = "[⌨️] $1"; + "(.*) - fish" = "[>_] $1"; + "(.*) - Discord" = "[🗨️] $1"; + # ArmCord thing + "• Discord \\| (.*)" = "[🗨️] $1"; + "\\((\\d+)\\) Discord \\| (.*)" = "[🗨️] {$1} $2"; + }; + }; + "tray" = { + icon-size = 21; + spacing = 10; + }; + "clock" = { + # format = "{:📅 %Y-%m-%d | 🕰️ %H:%M [%Z]}"; + format = "📅 {0:%Y-%m-%d} |️ 🕰️ {0:%H:%M [%Z]}"; + tooltip-format = "\n{calendar}"; + timezones = [ + "Europe/Zurich" + "America/Toronto" + "Asia/Tokyo" + "Asia/Ho_Chi_Minh" + ]; + calendar = { + mode = "year"; + mode-mon-col = 3; + weeks-pos = "right"; + on-scroll = 1; + on-click-right = "mode"; + format = { + months = "{}"; + days = "{}"; + weeks = "W{}"; + weekdays = "日 月 火 水 木 金 土"; # See https://github.com/Alexays/Waybar/issues/3132 + today = "{}"; + }; + }; + actions = { + on-click-middle = "mode"; + on-click-right = "tz_up"; + on-scroll-up = "shift_up"; + on-scroll-down = "shift_down"; + }; + }; + "cpu" = { + format = "{usage}% "; + }; + "memory" = { + format = "{}% "; + }; + "temperature" = { + # thermal-zone = 2; + # hwmon-path" = "/sys/class/hwmon/hwmon2/temp1_input"; + critical-threshold = 80; + # format-critical = "{temperatureC}°C "; + format = "{temperatureC}°C "; + }; + "backlight" = { + # device = "acpi_video1"; + format = "{percent}% {icon}"; + states = [ 0 50 ]; + format-icons = [ "" "" ]; + }; + "battery" = lib.mkIf cfg.enableLaptopBars { + states = { + good = 95; + warning = 30; + critical = 15; + }; + format = "{capacity}% {icon}"; + # format-good = ""; # An empty format will hide the module + # format-full = ""; + format-icons = [ "" "" "" "" "" ]; + }; + "battery#bat2" = lib.mkIf cfg.enableLaptopBars { + bat = "BAT2"; + }; + "network" = { + # interface = wlp2s0 # (Optional) To force the use of this interface + format-wifi = "{essid} ({signalStrength}%) "; + format-ethernet = "{ifname}: {ipaddr}/{cidr} "; + format-disconnected = "Disconnected ⚠"; + interval = 7; + }; + "bluetooth" = { + format = " {status}"; + format-connected = " {device_alias}"; + format-connected-battery = " {device_alias} {device_battery_percentage}%"; + # format-device-preference= [ "device1", "device2" ], // preference list deciding the displayed devic; + tooltip-format = "{controller_alias}\t{controller_address}\n\n{num_connections} connected"; + tooltip-format-connected = "{controller_alias}\t{controller_address}\n\n{num_connections} connected\n\n{device_enumerate}"; + tooltip-format-enumerate-connected = "{device_alias}\t{device_address}"; + tooltip-format-enumerate-connected-battery = "{device_alias}\t{device_address}\t{device_battery_percentage}%"; + on-click = "${pkgs.blueman}/bin/blueman-manager"; + }; + "pulseaudio" = { + # scroll-step = 1; + format = "{volume}% {icon}"; + format-bluetooth = "{volume}% {icon}"; + format-muted = ""; + format-icons = { + headphones = ""; + handsfree = ""; + headset = ""; + phone = ""; + portable = ""; + car = ""; + default = [ "" "" ]; + }; + on-click = "${pkgs.pavucontrol}/bin/pavucontrol"; + }; + "mpd" = { + "format" = "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} - {album} - {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) 🎧"; + "format-disconnected" = "Disconnected 🎧"; + "format-stopped" = "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped 🎧"; + "interval" = 2; + "consume-icons" = { + "on" = " "; # Icon shows only when "consume" is on + }; + "random-icons" = { + "off" = " "; # Icon grayed out when "random" is off; + "on" = " "; + }; + "repeat-icons" = { + "on" = " "; + }; + "single-icons" = { + "on" = "1 "; + }; + "state-icons" = { + "paused" = ""; + "playing" = ""; + }; + "tooltip-format" = "MPD (connected)"; + "tooltip-format-disconnected" = "MPD (disconnected)"; + "on-click" = "${pkgs.mpc_cli}/bin/mpc toggle"; + "on-click-right" = "${pkgs.mpc_cli}/bin/mpc stop"; + "on-click-middle" = "${cfg.terminal} --class=kitty_ncmpcpp ${pkgs.ncmpcpp}/bin/ncmpcpp"; + }; + "custom/media" = { + "format" = "{icon}{}"; + "return-type" = "json"; + "format-icons" = { + "Playing" = " "; + "Paused" = " "; + }; + "max-length" = 80; + "exec" = "${lib.getExe pkgs.playerctl} -a metadata --format '{\"text\": \"{{artist}} - {{markup_escape(title)}}\", \"tooltip\": \"{{playerName}} : {{markup_escape(title)}}\", \"alt\": \"{{status}}\", \"class\": \"{{status}}\"}' -F"; + "on-click" = "${lib.getExe pkgs.playerctl} play-pause"; + }; + }; + }] ++ + cfg.extraSettings + ++ [ extraSettings ]); + in + lib.mkIf cfg.enable { + enable = true; + systemd.enable = true; + systemd.target = "sway-session.target"; + settings = cfg.makeBars barWith; + style = '' + * { + border: none; + border-radius: 0; + font-family: monospace, 'Font Awesome 5', 'Symbols Nerd Font Mono', 'SFNS Display', Helvetica, Arial, sans-serif; + font-size: ${toString (cfg.fontSize * 1.1)}px; + min-height: 0; + } + + window#waybar { + background: rgba(43, 48, 59, 0.8); + border-bottom: 3px solid rgba(100, 114, 125, 0.5); + color: #ffffff; + } + + window#waybar.hidden { + opacity: 0.0; + } + /* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */ + #workspaces button { + padding: 0 5px; + background: transparent; + color: #ffffff; + border-bottom: 3px solid transparent; + } + + #workspaces button.focused { + background: #64727D; + border-bottom: 3px solid #ffffff; + } + + #workspaces button.urgent { + background-color: #eb4d4b; + } + + #window, #sway, #sway-window { + padding-left: 1em; + margin-bottom: 0.4em; + } + + #mode { + background: #64727D; + border-bottom: 3px solid #ffffff; + } + + /* #clock, #battery, #cpu, #memory, #temperature, #backlight, #network, #pulseaudio, #bluetooth, #custom-media, #tray, #mode, #idle_inhibitor, #mpd { */ + .modules-right > * > * { + margin: 0.2em 0 0.4em 0; + padding: 0.2em 0.5em; + border: 1px solid rgba(0, 0, 0, 0.25); + border-radius: 0.3em; + } + + .modules-right > *:not(:last-child) > * { + margin-right: 0.4em; + } + + #clock { + background-color: #64727D; + } + + #battery { + background-color: #ffffff; + color: #000000; + } + + #battery.charging { + color: #ffffff; + background-color: #26A65B; + } + + @keyframes blink { + to { + background-color: #ffffff; + color: #000000; + } + } + + #battery.critical:not(.charging) { + background: #f53c3c; + color: #ffffff; + animation-name: blink; + animation-duration: 0.5s; + animation-timing-function: linear; + animation-iteration-count: infinite; + animation-direction: alternate; + } + + #cpu { + background: #2ecc71; + color: #000000; + } + + #memory { + background: #9b59b6; + } + + #backlight { + background: #90b1b1; + } + + #network { + background: #2980b9; + } + + #network.disconnected { + background: #f53c3c; + } + + #pulseaudio { + background: #f1c40f; + color: #000000; + } + + #pulseaudio.muted { + background: #90b1b1; + } + + #bluetooth { + background: DarkSlateBlue; + color: white; + } + + #custom-media { + background: #66cc99; + color: #2a5c45; + } + + .custom-spotify { + background: #66cc99; + } + + .custom-vlc { + background: #ffa000; + } + + #temperature { + background: #f0932b; + } + + #temperature.critical { + background: #eb4d4b; + } + + #tray { + background-color: #2980b9; + } + + #idle_inhibitor { + background-color: #2d3436; + } + + #idle_inhibitor.activated { + background-color: #ecf0f1; + color: #2d3436; + } + + #mpd { + background-color: teal; + color: white; + } + '' + cfg.extraStyle; + }; +} diff --git a/home/nki-framework.nix b/home/nki-framework.nix index 02ab99b..3c995eb 100644 --- a/home/nki-framework.nix +++ b/home/nki-framework.nix @@ -29,12 +29,10 @@ # Graphical set up linux.graphical.type = "wayland"; linux.graphical.wallpaper = ./images/wallpaper_0.png; - linux.graphical.defaults.webBrowser = "librewolf.desktop"; + linux.graphical.defaults.webBrowser.package = pkgs.librewolf; # Enable sway programs.my-sway.enable = true; programs.my-sway.fontSize = 14.0; - programs.my-sway.terminal = "${config.programs.kitty.package}/bin/kitty"; - programs.my-sway.browser = "librewolf"; wayland.windowManager.sway.config = { # Keyboard support input."*".xkb_layout = "jp"; @@ -48,7 +46,11 @@ tap = "enabled"; }; }; - programs.my-sway.waybar.extraSettings = + programs.my-niri.enable = true; + programs.niri.settings = { + input.keyboard.xkb.options = "ctrl:swapcaps"; + }; + programs.my-waybar.extraSettings = let change-mode = pkgs.writeScript "change-mode" '' #!/usr/bin/env ${lib.getExe pkgs.fish} diff --git a/home/nki-x1c1.nix b/home/nki-x1c1.nix index dbad824..0824a89 100644 --- a/home/nki-x1c1.nix +++ b/home/nki-x1c1.nix @@ -1,5 +1,20 @@ { pkgs, config, lib, ... }: +let + iio-sway = pkgs.stdenv.mkDerivation { + name = "iio-sway"; + version = "0.0.1"; + src = pkgs.fetchFromGitHub { + owner = "okeri"; + repo = "iio-sway"; + rev = "e07477d1b2478fede1446e97424a94c80767819d"; + hash = "sha256-JGacKajslCOvd/BFfFSf7s1/hgF6rJqJ6H6xNnsuMb4="; + }; + buildInputs = with pkgs; [ dbus ]; + nativeBuildInputs = with pkgs; [ meson ninja pkg-config ]; + meta.mainProgram = "iio-sway"; + }; +in { imports = [ # Common configuration @@ -30,12 +45,11 @@ linux.graphical.type = "wayland"; linux.graphical.wallpaper = ./images/wallpaper_0.png; linux.graphical.startup = with pkgs; [ zen-browser-bin thunderbird vesktop slack ]; - linux.graphical.defaults.webBrowser = "zen.desktop"; + linux.graphical.defaults.webBrowser.package = pkgs.zen-browser-bin; + linux.graphical.defaults.webBrowser.desktopFile = "zen.desktop"; # Enable sway programs.my-sway.enable = true; programs.my-sway.fontSize = 14.0; - programs.my-sway.terminal = "${config.programs.kitty.package}/bin/kitty"; - programs.my-sway.browser = "librewolf"; wayland.windowManager.sway.config = { # Keyboard support input."*".xkb_layout = "jp"; @@ -50,25 +64,25 @@ startup = [ # rotation - ( - let - iio-sway = pkgs.stdenv.mkDerivation { - name = "iio-sway"; - version = "0.0.1"; - src = pkgs.fetchFromGitHub { - owner = "okeri"; - repo = "iio-sway"; - rev = "e07477d1b2478fede1446e97424a94c80767819d"; - hash = "sha256-JGacKajslCOvd/BFfFSf7s1/hgF6rJqJ6H6xNnsuMb4="; - }; - buildInputs = with pkgs; [ dbus ]; - nativeBuildInputs = with pkgs; [ meson ninja pkg-config ]; - }; - in - { command = "${iio-sway}/bin/iio-sway"; } - ) + { command = "${lib.getExe iio-sway}"; } ]; }; + programs.my-niri.enable = true; + # Assign some of the workspaces to big screen + programs.my-niri.workspaces = lib.genAttrs [ "06" "07" "08" "09" "10" ] (_: { monitor = config.common.monitors.work.name; }); + programs.niri.settings = { + # input.keyboard.xkb.options = "ctrl:swapcaps"; + input.mouse = lib.mkForce { + # Make M575 fast for now + accel-profile = "adaptive"; + accel-speed = 0.4; + }; + input.touch.map-to-output = "eDP-1"; + switch-events = with config.lib.niri.actions; { + tablet-mode-on.action = spawn "systemctl" "--user" "kill" "--signal" "SIGUSR2" "wvkbd"; + tablet-mode-off.action = spawn "systemctl" "--user" "kill" "--signal" "SIGUSR1" "wvkbd"; + }; + }; ## Virtual keyboard systemd.user.services.wvkbd = { Unit = { @@ -100,7 +114,7 @@ settings = [ { profile.name = "undocked"; - profile.outputs = [{ criteria = "LVDS-1"; }]; + profile.outputs = [{ criteria = "eDP-1"; }]; } { profile.name = "work-both"; diff --git a/modules/common/linux/default.nix b/modules/common/linux/default.nix index 3b53a0d..36bef19 100644 --- a/modules/common/linux/default.nix +++ b/modules/common/linux/default.nix @@ -45,12 +45,19 @@ let # services.gnome.evolution-data-server.plugins = with pkgs; [ evolution-ews ]; }; - wlr = { ... }: mkIf config.common.linux.enable { + wlr = { lib, config, ... }: mkIf config.common.linux.enable { # swaync disable notifications on screencast xdg.portal.wlr.settings.screencast = { exec_before = ''which swaync-client && swaync-client --inhibitor-add "xdg-desktop-portal-wlr" || true''; exec_after = ''which swaync-client && swaync-client --inhibitor-remove "xdg-desktop-portal-wlr" || true''; }; + + # Niri stuff + # https://github.com/sodiboo/niri-flake/blob/main/docs.md + programs.niri.enable = true; + programs.niri.package = pkgs.niri-stable; + # Override gnome-keyring disabling + services.gnome.gnome-keyring.enable = lib.mkForce false; }; logitech = { pkgs, ... }: mkIf cfg.enable { @@ -343,6 +350,13 @@ in extraPortals = [ pkgs.kdePackages.xdg-desktop-portal-kde pkgs.xdg-desktop-portal-gtk ]; config.sway.default = [ "wlr" "kde" "kwallet" ]; + config.niri = { + default = [ "gnome" "gtk" ]; + "org.freedesktop.impl.portal.Access" = "gtk"; + "org.freedesktop.impl.portal.Notification" = "gtk"; + "org.freedesktop.impl.portal.Secret" = "kwallet"; + "org.freedesktop.impl.portal.FileChooser" = "kde"; + }; }; # D-Bus services.dbus.packages = with pkgs; [ gcr ]; diff --git a/overlay.nix b/overlay.nix index 4ad7209..1e60c41 100644 --- a/overlay.nix +++ b/overlay.nix @@ -120,6 +120,7 @@ in inputs.mpd-mpris.overlays.default inputs.rust-overlay.overlays.default inputs.youmubot.overlays.default + inputs.niri.overlays.niri overlay-unstable overlay-needs-unstable