diff --git a/common/desktop_environment/hyprland/default.nix b/common/desktop_environment/hyprland/default.nix index 60b8c47..9726da5 100644 --- a/common/desktop_environment/hyprland/default.nix +++ b/common/desktop_environment/hyprland/default.nix @@ -29,12 +29,6 @@ with lib; default = { }; description = "Extra options for Hyprland configuration."; }; - swaync = { - enable = lib.mkEnableOption "Enable Swaync (notification center for Hyprland)"; - }; - waybar = { - enable = lib.mkEnableOption "Enable Waybar (status bar for Hyprland)"; - }; }; config = lib.mkIf cfg.enable { diff --git a/common/desktop_environment/hyprland/home_manager/default.nix b/common/desktop_environment/hyprland/home_manager/default.nix index 9533253..1dbebcb 100644 --- a/common/desktop_environment/hyprland/home_manager/default.nix +++ b/common/desktop_environment/hyprland/home_manager/default.nix @@ -3,7 +3,6 @@ imports = [ ./theme.nix ./hyprland.nix - # ./quickshell.nix ./waybar.nix ./hyprpolkitagent.nix ./wofi.nix diff --git a/common/desktop_environment/hyprland/home_manager/hyprland.nix b/common/desktop_environment/hyprland/home_manager/hyprland.nix index 409d94f..4f3de04 100644 --- a/common/desktop_environment/hyprland/home_manager/hyprland.nix +++ b/common/desktop_environment/hyprland/home_manager/hyprland.nix @@ -29,17 +29,8 @@ in # "waybar" # ]; - # Default monitor configuration - monitor = "monitor = , preferred, auto, 1"; - - # Make workspaces 7-10 always on MONITOR-2 (replace DP-2 if your secondary isn't DP-2) - # You can get the name of your monitor via `hyprctl monitors` - workspace = [ - "7, monitor:DP-2, persistent:true" - "8, monitor:DP-2, persistent:true" - "9, monitor:DP-2, persistent:true" - "10, monitor:DP-2, persistent:true" - ]; + # Default monitor configuration + monitor = "monitor = , preferred, auto, 1"; windowrulev2 = [ "float, class:^(?i)chrome-nngceckbapebfimnlniiiahkandclblb-Default$, initialtitle:^_crx_nngceckbapebfimnlniiiahkandclblb$" diff --git a/common/desktop_environment/hyprland/home_manager/quickshell.nix b/common/desktop_environment/hyprland/home_manager/quickshell.nix index 2f5032c..8d6f389 100644 --- a/common/desktop_environment/hyprland/home_manager/quickshell.nix +++ b/common/desktop_environment/hyprland/home_manager/quickshell.nix @@ -2,7 +2,6 @@ osConfig, lib, pkgs, - upkgs, ... }: let @@ -16,7 +15,8 @@ let in { home.packages = with pkgs; [ - upkgs.quickshell + quickshell + pulseaudio brightnessctl networkmanager @@ -27,67 +27,4 @@ in systemd hyprlock ]; - - # Ensure CLI quickshell can resolve modules when not using --config-path - home.sessionVariables = { - QML_IMPORT_PATH = "$HOME/.config/quickshell"; - QML2_IMPORT_PATH = "$HOME/.config/quickshell"; - }; - - # install config files - home.file = { - ".config/quickshell/shell.qml".source = ./quickshell/shell.qml; - ".config/quickshell/panels/TopBar.qml".source = ./quickshell/panels/TopBar.qml; - ".config/quickshell/notifications/NotificationServer.qml".source = - ./quickshell/notifications/NotificationServer.qml; - ".config/quickshell/notifications/NotificationPopup.qml".source = - ./quickshell/notifications/NotificationPopup.qml; - ".config/quickshell/notifications/NotificationCenter.qml".source = - ./quickshell/notifications/NotificationCenter.qml; - ".config/quickshell/widgets/status/Workspaces.qml".source = - ./quickshell/widgets/status/Workspaces.qml; - ".config/quickshell/widgets/status/Clock.qml".source = ./quickshell/widgets/status/Clock.qml; - ".config/quickshell/widgets/status/SystemTrayWidget.qml".source = - ./quickshell/widgets/status/SystemTrayWidget.qml; - ".config/quickshell/widgets/status/Battery.qml".source = ./quickshell/widgets/status/Battery.qml; - ".config/quickshell/widgets/controls/QuickSettings.qml".source = - ./quickshell/widgets/controls/QuickSettings.qml; - ".config/quickshell/widgets/controls/Audio.qml".source = ./quickshell/widgets/controls/Audio.qml; - ".config/quickshell/widgets/controls/Network.qml".source = - ./quickshell/widgets/controls/Network.qml; - ".config/quickshell/widgets/controls/Bluetooth.qml".source = - ./quickshell/widgets/controls/Bluetooth.qml; - ".config/quickshell/widgets/controls/Brightness.qml".source = - ./quickshell/widgets/controls/Brightness.qml; - ".config/quickshell/widgets/controls/PowerProfilesWidget.qml".source = - ./quickshell/widgets/controls/PowerProfilesWidget.qml; - ".config/quickshell/panels/qmldir".source = ./quickshell/panels/qmldir; - ".config/quickshell/notifications/qmldir".source = ./quickshell/notifications/qmldir; - ".config/quickshell/widgets/status/qmldir".source = ./quickshell/widgets/status/qmldir; - ".config/quickshell/widgets/controls/qmldir".source = ./quickshell/widgets/controls/qmldir; - # optional: .qmlls.ini should be gitignored; create empty to enable LSP - ".config/quickshell/.qmlls.ini".text = ""; - }; - - systemd.user.services.quickshell = { - Unit = { - Description = "Quickshell Desktop Shell"; - PartOf = [ "graphical-session.target" ]; - After = [ "graphical-session.target" ]; - }; - Service = { - ExecStart = "${upkgs.quickshell}/bin/quickshell --config-path %h/.config/quickshell"; - Restart = "on-failure"; - RestartSec = 2; - Environment = [ - "QML_IMPORT_PATH=%h/.config/quickshell" - "QT_QPA_PLATFORM=wayland" - # Ensure we find icons - "XDG_CURRENT_DESKTOP=quickshell" - ]; - }; - Install = { - WantedBy = [ "graphical-session.target" ]; - }; - }; } diff --git a/common/desktop_environment/hyprland/home_manager/swaync.nix b/common/desktop_environment/hyprland/home_manager/swaync.nix index b26fa58..6891a76 100644 --- a/common/desktop_environment/hyprland/home_manager/swaync.nix +++ b/common/desktop_environment/hyprland/home_manager/swaync.nix @@ -1,251 +1,237 @@ { - lib, - osConfig, ... }: -let - ccfg = import ../../../config.nix; - cfg_path = [ - ccfg.custom_config_key - "desktopEnvironment" - "hyprland" - "swaync" - ]; - cfg = lib.attrsets.getAttrFromPath cfg_path osConfig; -in { - config = lib.mkIf cfg.enable { - services.swaync = { - enable = true; - settings = { - ignore = [ - "com.spotify.Client" - ]; + services.swaync = { + enable = true; + settings = { + ignore = [ + "com.spotify.Client" + ]; - positionX = "right"; - positionY = "top"; - layer = "overlay"; - control-center-layer = "top"; - layer-shell = true; - cssPriority = "application"; + positionX = "right"; + positionY = "top"; + layer = "overlay"; + control-center-layer = "top"; + layer-shell = true; + cssPriority = "application"; - control-center-margin-top = 0; - control-center-margin-bottom = 0; - control-center-margin-right = 0; - control-center-margin-left = 0; + control-center-margin-top = 0; + control-center-margin-bottom = 0; + control-center-margin-right = 0; + control-center-margin-left = 0; - notification-2fa-action = true; - notification-inline-replies = false; - notification-icon-size = 64; - notification-body-image-height = 100; - notification-body-image-width = 200; + notification-2fa-action = true; + notification-inline-replies = false; + notification-icon-size = 64; + notification-body-image-height = 100; + notification-body-image-width = 200; - timeout = 10; - timeout-low = 5; - timeout-critical = 0; + timeout = 10; + timeout-low = 5; + timeout-critical = 0; - control-center-width = 500; - control-center-height = 600; - notification-window-width = 500; + control-center-width = 500; + control-center-height = 600; + notification-window-width = 500; - keyboard-shortcuts = true; - image-visibility = "when-available"; - transition-time = 200; - hide-on-clear = false; - hide-on-action = true; - script-fail-notify = true; + keyboard-shortcuts = true; + image-visibility = "when-available"; + transition-time = 200; + hide-on-clear = false; + hide-on-action = true; + script-fail-notify = true; - widgets = [ - "inhibitors" - "title" - "dnd" - "volume" - "backlight" - "mpris" - "buttons-grid#quick" - "notifications" - ]; + widgets = [ + "inhibitors" + "title" + "dnd" + "volume" + "backlight" + "mpris" + "buttons-grid#quick" + "notifications" + ]; - # Widget configurations - widget-config = { - inhibitors = { - text = "Inhibitors"; - button-text = "Clear All"; - clear-all-button = true; - }; - title = { - text = "Notifications"; - clear-all-button = true; - button-text = "Clear All"; - }; - dnd.text = "Do Not Disturb"; - mpris = { - image-size = 96; - image-radius = 12; - }; - volume = { - label = "󰕾"; - show-per-app = true; - }; - backlight = { - label = "󰃟"; - device = "intel_backlight"; - }; - "buttons-grid#quick" = { - columns = 4; # adjust: 3/4/5 - icon-size = 20; # tweak to taste - actions = [ - # Power - { - label = "󰐥"; - tooltip = "Shutdown"; - command = "confirm-action 'systemctl poweroff' 'Shutdown?'"; - } - { - label = "󰜉"; - tooltip = "Reboot"; - command = "confirm-action 'systemctl reboot' 'Reboot?'"; - } - { - label = "󰍃"; - tooltip = "Logout"; - command = "confirm-action 'hyprctl dispatch exit' 'Logout?'"; - } - ]; - }; + # Widget configurations + widget-config = { + inhibitors = { + text = "Inhibitors"; + button-text = "Clear All"; + clear-all-button = true; + }; + title = { + text = "Notifications"; + clear-all-button = true; + button-text = "Clear All"; + }; + dnd.text = "Do Not Disturb"; + mpris = { + image-size = 96; + image-radius = 12; + }; + volume = { + label = "󰕾"; + show-per-app = true; + }; + backlight = { + label = "󰃟"; + device = "intel_backlight"; + }; + "buttons-grid#quick" = { + columns = 4; # adjust: 3/4/5 + icon-size = 20; # tweak to taste + actions = [ + # Power + { + label = "󰐥"; + tooltip = "Shutdown"; + command = "confirm-action 'systemctl poweroff' 'Shutdown?'"; + } + { + label = "󰜉"; + tooltip = "Reboot"; + command = "confirm-action 'systemctl reboot' 'Reboot?'"; + } + { + label = "󰍃"; + tooltip = "Logout"; + command = "confirm-action 'hyprctl dispatch exit' 'Logout?'"; + } + ]; }; }; - - # Custom CSS for the control center - style = '' - .control-center { - background: #1a1b26; - border: 2px solid #7dcae4; - border-radius: 12px; - } - - .control-center-list { - background: transparent; - } - - .control-center .notification-row:focus, - .control-center .notification-row:hover { - opacity: 1; - background: #24283b; - } - - .notification { - border-radius: 8px; - margin: 6px 12px; - box-shadow: 0 0 0 1px rgba(125, 196, 228, 0.3), 0 1px 3px 1px rgba(0, 0, 0, 0.7), 0 2px 6px 2px rgba(0, 0, 0, 0.3); - padding: 0; - } - - /* Widget styling */ - .widget-title { - margin: 8px; - font-size: 1.5rem; - color: #c0caf5; - } - - .widget-dnd { - margin: 8px; - font-size: 1.1rem; - color: #c0caf5; - } - - .widget-dnd > switch { - font-size: initial; - border-radius: 8px; - background: #414868; - border: 1px solid #7dcae4; - } - - .widget-dnd > switch:checked { - background: #7dcae4; - } - - .widget-mpris { - color: #c0caf5; - background: #24283b; - padding: 8px; - margin: 8px; - border-radius: 8px; - } - - .widget-mpris-player { - padding: 8px; - margin: 8px; - } - - .widget-mpris-title { - font-weight: bold; - font-size: 1.25rem; - } - - .widget-mpris-subtitle { - font-size: 1.1rem; - color: #9ece6a; - } - - .widget-volume { - background: #24283b; - padding: 8px; - margin: 8px; - border-radius: 8px; - color: #c0caf5; - } - - .widget-backlight { - background: #24283b; - padding: 8px; - margin: 8px; - border-radius: 8px; - color: #c0caf5; - } - - .widget-menubar { - background: #24283b; - padding: 8px; - margin: 8px; - border-radius: 8px; - color: #c0caf5; - } - - .widget-menubar .menu-item button { - background: #1f2335; - color: #c0caf5; - border-radius: 8px; - padding: 6px 10px; - margin: 4px; - border: 1px solid #2e3440; - font-family: "JetBrainsMonoNL Nerd Font"; - } - - .widget-menubar .menu-item button:hover { - background: #414868; - border-color: #7dcae4; - } - - .topbar-buttons button { - border: none; - background: transparent; - color: #c0caf5; - font-size: 1.1rem; - border-radius: 8px; - margin: 0 4px; - padding: 8px; - } - - .topbar-buttons button:hover { - background: #414868; - } - - .topbar-buttons button:active { - background: #7dcae4; - color: #1a1b26; - } - ''; }; + + # Custom CSS for the control center + style = '' + .control-center { + background: #1a1b26; + border: 2px solid #7dcae4; + border-radius: 12px; + } + + .control-center-list { + background: transparent; + } + + .control-center .notification-row:focus, + .control-center .notification-row:hover { + opacity: 1; + background: #24283b; + } + + .notification { + border-radius: 8px; + margin: 6px 12px; + box-shadow: 0 0 0 1px rgba(125, 196, 228, 0.3), 0 1px 3px 1px rgba(0, 0, 0, 0.7), 0 2px 6px 2px rgba(0, 0, 0, 0.3); + padding: 0; + } + + /* Widget styling */ + .widget-title { + margin: 8px; + font-size: 1.5rem; + color: #c0caf5; + } + + .widget-dnd { + margin: 8px; + font-size: 1.1rem; + color: #c0caf5; + } + + .widget-dnd > switch { + font-size: initial; + border-radius: 8px; + background: #414868; + border: 1px solid #7dcae4; + } + + .widget-dnd > switch:checked { + background: #7dcae4; + } + + .widget-mpris { + color: #c0caf5; + background: #24283b; + padding: 8px; + margin: 8px; + border-radius: 8px; + } + + .widget-mpris-player { + padding: 8px; + margin: 8px; + } + + .widget-mpris-title { + font-weight: bold; + font-size: 1.25rem; + } + + .widget-mpris-subtitle { + font-size: 1.1rem; + color: #9ece6a; + } + + .widget-volume { + background: #24283b; + padding: 8px; + margin: 8px; + border-radius: 8px; + color: #c0caf5; + } + + .widget-backlight { + background: #24283b; + padding: 8px; + margin: 8px; + border-radius: 8px; + color: #c0caf5; + } + + .widget-menubar { + background: #24283b; + padding: 8px; + margin: 8px; + border-radius: 8px; + color: #c0caf5; + } + + .widget-menubar .menu-item button { + background: #1f2335; + color: #c0caf5; + border-radius: 8px; + padding: 6px 10px; + margin: 4px; + border: 1px solid #2e3440; + font-family: "JetBrainsMonoNL Nerd Font"; + } + + .widget-menubar .menu-item button:hover { + background: #414868; + border-color: #7dcae4; + } + + .topbar-buttons button { + border: none; + background: transparent; + color: #c0caf5; + font-size: 1.1rem; + border-radius: 8px; + margin: 0 4px; + padding: 8px; + } + + .topbar-buttons button:hover { + background: #414868; + } + + .topbar-buttons button:active { + background: #7dcae4; + color: #1a1b26; + } + ''; }; } diff --git a/common/desktop_environment/hyprland/home_manager/waybar.nix b/common/desktop_environment/hyprland/home_manager/waybar.nix index 25c5986..c67d449 100644 --- a/common/desktop_environment/hyprland/home_manager/waybar.nix +++ b/common/desktop_environment/hyprland/home_manager/waybar.nix @@ -1,267 +1,253 @@ { - lib, - osConfig, ... }: -let - ccfg = import ../../../config.nix; - cfg_path = [ - ccfg.custom_config_key - "desktopEnvironment" - "hyprland" - "waybar" - ]; - cfg = lib.attrsets.getAttrFromPath cfg_path osConfig; -in { - config = lib.mkIf cfg.enable { - programs.waybar = { - enable = true; - systemd.enable = true; - settings = { - mainBar = { - layer = "top"; - position = "top"; - height = 30; - spacing = 6; - margin-top = 0; - margin-bottom = 0; - margin-left = 10; - margin-right = 10; + programs.waybar = { + enable = true; + systemd.enable = true; + settings = { + mainBar = { + layer = "top"; + position = "top"; + height = 30; + spacing = 6; + margin-top = 0; + margin-bottom = 0; + margin-left = 10; + margin-right = 10; - modules-left = [ - "hyprland/workspaces" - ]; + modules-left = [ + "hyprland/workspaces" + ]; - modules-center = [ - "clock" - "temperature" - "cpu" - "memory" - "disk" - ]; + modules-center = [ + "clock" + "temperature" + "cpu" + "memory" + "disk" + ]; - modules-right = [ - "pulseaudio" - "network" - "bluetooth" - "custom/notifications" - "hyprland/language" - ]; + modules-right = [ + "pulseaudio" + "network" + "bluetooth" + "custom/notifications" + "hyprland/language" + ]; - # Workspaces configuration - "hyprland/workspaces" = { - format = "{icon}"; - format-icons = { - "1" = "一"; - "2" = "二"; - "3" = "三"; - "4" = "四"; - "5" = "五"; - "6" = "六"; - "7" = "七"; - "8" = "八"; - "9" = "九"; - "10" = "十"; - "11" = "十一"; - "12" = "十二"; - "13" = "十三"; - "14" = "十四"; - "15" = "十五"; - "16" = "十六"; - "17" = "十七"; - "18" = "十八"; - "19" = "十九"; - "20" = "二十"; - }; - show-special = false; + # Workspaces configuration + "hyprland/workspaces" = { + format = "{icon}"; + format-icons = { + "1" = "一"; + "2" = "二"; + "3" = "三"; + "4" = "四"; + "5" = "五"; + "6" = "六"; + "7" = "七"; + "8" = "八"; + "9" = "九"; + "10" = "十"; + "11" = "十一"; + "12" = "十二"; + "13" = "十三"; + "14" = "十四"; + "15" = "十五"; + "16" = "十六"; + "17" = "十七"; + "18" = "十八"; + "19" = "十九"; + "20" = "二十"; }; + show-special = false; + }; - pulseaudio = { - format = "{icon} {volume}%"; - format-bluetooth = "󰂰 {volume}%"; - format-bluetooth-muted = "󰂲 "; - format-muted = "󰖁 "; - format-source = "󰍬 {volume}%"; - format-source-muted = "󰍭 "; - format-icons = { - headphone = "󰋋"; - hands-free = "󰂑"; - headset = "󰂑"; - phone = "󰏲"; - portable = "󰦧"; - car = "󰄋"; - default = [ - "󰕿" - "󰖀" - "󰕾" - ]; - }; - scroll-step = 5; - on-click = "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"; - on-click-right = "swaync-client -t -sw"; + pulseaudio = { + format = "{icon} {volume}%"; + format-bluetooth = "󰂰 {volume}%"; + format-bluetooth-muted = "󰂲 "; + format-muted = "󰖁 "; + format-source = "󰍬 {volume}%"; + format-source-muted = "󰍭 "; + format-icons = { + headphone = "󰋋"; + hands-free = "󰂑"; + headset = "󰂑"; + phone = "󰏲"; + portable = "󰦧"; + car = "󰄋"; + default = [ + "󰕿" + "󰖀" + "󰕾" + ]; }; + scroll-step = 5; + on-click = "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"; + on-click-right = "swaync-client -t -sw"; + }; - "custom/notifications" = { - format = "{icon} {}"; - format-icons = { - notification = ""; - none = ""; - dnd-notification = "󰂛"; - dnd-none = "󰂛"; - inhibited-notification = ""; - inhibited-none = ""; - dnd-inhibited-notification = "󰂛"; - dnd-inhibited-none = "󰂛"; - }; - return-type = "json"; - exec-if = "which swaync-client"; - exec = "swaync-client -swb"; - on-click = "swaync-client -t -sw"; - on-click-right = "swaync-client -d -sw"; - escape = true; - tooltip = false; + "custom/notifications" = { + format = "{icon} {}"; + format-icons = { + notification = ""; + none = ""; + dnd-notification = "󰂛"; + dnd-none = "󰂛"; + inhibited-notification = ""; + inhibited-none = ""; + dnd-inhibited-notification = "󰂛"; + dnd-inhibited-none = "󰂛"; }; + return-type = "json"; + exec-if = "which swaync-client"; + exec = "swaync-client -swb"; + on-click = "swaync-client -t -sw"; + on-click-right = "swaync-client -d -sw"; + escape = true; + tooltip = false; + }; - # Clock - clock = { - format = "{:%b %d, %H:%M}"; - }; + # Clock + clock = { + format = "{:%b %d, %H:%M}"; + }; - temperature = { - thermal-zone = 2; - hwmon-path = "/sys/class/hwmon/hwmon2/temp1_input"; - critical-threshold = 80; - format-critical = "󰔏 {temperatureC}°C"; - format = "󰔏 {temperatureC}°C"; - }; + temperature = { + thermal-zone = 2; + hwmon-path = "/sys/class/hwmon/hwmon2/temp1_input"; + critical-threshold = 80; + format-critical = "󰔏 {temperatureC}°C"; + format = "󰔏 {temperatureC}°C"; + }; - cpu = { - format = "󰻠 {usage}%"; - tooltip = false; - on-click = "btop"; - }; + cpu = { + format = "󰻠 {usage}%"; + tooltip = false; + on-click = "btop"; + }; - memory = { - format = "󰍛 {}%"; - on-click = "btop"; - }; + memory = { + format = "󰍛 {}%"; + on-click = "btop"; + }; - disk = { - interval = 30; - format = "󰋊 {percentage_used}%"; - path = "/"; - on-click = "btop"; - }; + disk = { + interval = 30; + format = "󰋊 {percentage_used}%"; + path = "/"; + on-click = "btop"; + }; - network = { - format-wifi = "󰤨 {essid} ({signalStrength}%)"; - format-ethernet = "󰈀 {ipaddr}/{cidr}"; - tooltip-format = "{ifname} via {gwaddr} "; - format-linked = "󰈀 {ifname} (No IP)"; - format-disconnected = "󰖪 Disconnected"; - on-click = "wofi-wifi-menu"; - on-click-right = "nmcli radio wifi toggle"; - }; + network = { + format-wifi = "󰤨 {essid} ({signalStrength}%)"; + format-ethernet = "󰈀 {ipaddr}/{cidr}"; + tooltip-format = "{ifname} via {gwaddr} "; + format-linked = "󰈀 {ifname} (No IP)"; + format-disconnected = "󰖪 Disconnected"; + on-click = "wofi-wifi-menu"; + on-click-right = "nmcli radio wifi toggle"; + }; - bluetooth = { - format = "󰂯 {status}"; - format-connected = "󰂱 {device_alias}"; - format-connected-battery = "󰂱 {device_alias} {device_battery_percentage}%"; - 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 = "wofi-bluetooth-menu"; - on-click-right = "bluetoothctl power toggle"; - }; + bluetooth = { + format = "󰂯 {status}"; + format-connected = "󰂱 {device_alias}"; + format-connected-battery = "󰂱 {device_alias} {device_battery_percentage}%"; + 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 = "wofi-bluetooth-menu"; + on-click-right = "bluetoothctl power toggle"; + }; - # Keyboard input (language) - "hyprland/language" = { - format = "{}"; - format-en = "EN"; - format-ja = "JP"; - }; + # Keyboard input (language) + "hyprland/language" = { + format = "{}"; + format-en = "EN"; + format-ja = "JP"; }; }; - - style = '' - * { - font-family: "JetBrainsMonoNL Nerd Font"; - font-size: 12px; - border: none; - border-radius: 0; - min-height: 0; - } - - window#waybar { - background: transparent; - border-radius: 10px; - margin: 0px; - } - - .modules-left, - .modules-center, - .modules-right { - background: rgba(26, 27, 38, 0.8); - border-radius: 10px; - margin: 4px; - padding: 0 10px; - } - - #workspaces { - padding: 0 5px; - } - - #workspaces button { - padding: 0 8px; - background: transparent; - color: #c0caf5; - border-radius: 5px; - margin: 2px; - } - - #workspaces button:hover { - background: rgba(125, 196, 228, 0.2); - color: #7dcae4; - } - - #workspaces button.active { - background: #7dcae4; - color: #1a1b26; - } - - #pulseaudio, - #custom-notifications, - #clock, - #temperature, - #cpu, - #memory, - #disk, - #network, - #bluetooth, - #language { - padding: 0 8px; - color: #c0caf5; - margin: 2px; - } - - #temperature.critical { - color: #f7768e; - } - - #network.disconnected { - color: #f7768e; - } - - #bluetooth.disabled { - color: #565f89; - } - - #pulseaudio.muted { - color: #565f89; - } - ''; }; + + style = '' + * { + font-family: "JetBrainsMonoNL Nerd Font"; + font-size: 12px; + border: none; + border-radius: 0; + min-height: 0; + } + + window#waybar { + background: transparent; + border-radius: 10px; + margin: 0px; + } + + .modules-left, + .modules-center, + .modules-right { + background: rgba(26, 27, 38, 0.8); + border-radius: 10px; + margin: 4px; + padding: 0 10px; + } + + #workspaces { + padding: 0 5px; + } + + #workspaces button { + padding: 0 8px; + background: transparent; + color: #c0caf5; + border-radius: 5px; + margin: 2px; + } + + #workspaces button:hover { + background: rgba(125, 196, 228, 0.2); + color: #7dcae4; + } + + #workspaces button.active { + background: #7dcae4; + color: #1a1b26; + } + + #pulseaudio, + #custom-notifications, + #clock, + #temperature, + #cpu, + #memory, + #disk, + #network, + #bluetooth, + #language { + padding: 0 8px; + color: #c0caf5; + margin: 2px; + } + + #temperature.critical { + color: #f7768e; + } + + #network.disconnected { + color: #f7768e; + } + + #bluetooth.disabled { + color: #565f89; + } + + #pulseaudio.muted { + color: #565f89; + } + ''; }; } diff --git a/common/flake.lock b/common/flake.lock index a1d6c11..c2fa076 100644 --- a/common/flake.lock +++ b/common/flake.lock @@ -85,11 +85,11 @@ "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1755928099, - "narHash": "sha256-OILVkfhRCm8u18IZ2DKR8gz8CVZM2ZcJmQBXmjFLIfk=", + "lastModified": 1753592768, + "narHash": "sha256-oV695RvbAE4+R9pcsT9shmp6zE/+IZe6evHWX63f2Qg=", "owner": "rycee", "repo": "home-manager", - "rev": "4a44fb9f7555da362af9d499817084f4288a957f", + "rev": "fc3add429f21450359369af74c2375cb34a2d204", "type": "github" }, "original": { diff --git a/hosts/lio/flake.nix b/hosts/lio/flake.nix index dc9be42..4e0bfd5 100644 --- a/hosts/lio/flake.nix +++ b/hosts/lio/flake.nix @@ -29,13 +29,7 @@ nixosConfigurations = { "${configuration_name}" = ( lib.nixosSystem { - specialArgs = { - inherit inputs; - upkgs = import inputs.nixpkgs-unstable { - system = "x86_64-linux"; - config.allowUnfree = true; - }; - }; + specialArgs = { inherit inputs; }; modules = [ common.nixosModules.default ros_neovim.nixosModules.default @@ -43,12 +37,10 @@ ./hardware-configuration.nix (import ./containers.nix { inherit inputs; }) # ./jails_text.nix - ./hyprland_customizations.nix ( { config, pkgs, - upkgs, lib, ... }: @@ -88,11 +80,6 @@ # Allow emulation of aarch64-linux binaries for cross compiling boot.binfmt.emulatedSystems = [ "aarch64-linux" ]; - home-manager.extraSpecialArgs = { - inherit inputs; - inherit upkgs; - }; - ringofstorms_common = { systemName = configuration_name; boot.systemd.enable = true; @@ -103,8 +90,26 @@ }; desktopEnvironment.hyprland = { enable = true; - waybar.enable = true; - swaync.enable = true; + extraOptions = + let + main = "desc:ASUSTek COMPUTER INC ASUS PG43U 0x01010101"; + secondary = "desc:Samsung Electric Company C34J79x HTRM900776"; + in + { + # hyprctl monitors all + monitor = [ + "${main},3840x2160@97.98,0x0,1,transform,0" + "${secondary},3440x1440@99.98,-1440x-640,1,transform,1" + ]; + # Pin workspaces 1-6 to main monitor and rest on other monitor + workspace = + let + inherit (builtins) map toString; + inherit (lib) range; + mkWs = monitor: i: "${toString i},monitor:${monitor}"; + in + (map (mkWs main) (range 1 6)) ++ (map (mkWs secondary) (range 7 10)); + }; }; programs = { qFlipper.enable = true; diff --git a/hosts/lio/hyprland_customizations.nix b/hosts/lio/hyprland_customizations.nix deleted file mode 100644 index 5b979b6..0000000 --- a/hosts/lio/hyprland_customizations.nix +++ /dev/null @@ -1,137 +0,0 @@ -{ lib, pkgs, ... }: -let - # Exact descriptions as reported by: hyprctl -j monitors | jq '.[].description' - mainDesc = "ASUSTek COMPUTER INC ASUS PG43U 0x01010101"; - secondaryDesc = "Samsung Electric Company C34J79x HTRM900776"; - - mainMonitor = "desc:${mainDesc}"; - secondaryMonitor = "desc:${secondaryDesc}"; - - hyprlandExtraOptions = { - monitor = [ - "${mainMonitor},3840x2160@97.98,0x0,1,transform,0" - "${secondaryMonitor},3440x1440@99.98,-1440x-640,1,transform,1" - ]; - workspace = - let - inherit (builtins) map toString; - inherit (lib) range; - mkWs = monitor: i: "${toString i},monitor:${monitor},persistent:true"; - in - (map (mkWs mainMonitor) (range 1 6)) ++ (map (mkWs secondaryMonitor) (range 7 10)); - }; - - moveScript = pkgs.writeShellScriptBin "hyprland-move-workspaces" '' - #!/usr/bin/env bash - set -euo pipefail - - HYPRCTL='${pkgs.hyprland}/bin/hyprctl' - JQ='${pkgs.jq}/bin/jq' - SOCAT='${pkgs.socat}/bin/socat' - - MAIN_DESC='${mainDesc}' - SEC_DESC='${secondaryDesc}' - - get_socket() { - # socket2 carries the event stream - echo "${"$"}{XDG_RUNTIME_DIR}/hypr/${"$"}{HYPRLAND_INSTANCE_SIGNATURE}/.socket2.sock" - } - - wait_for_hypr() { - # Wait until hyprctl works (Hyprland is up) - until ''${HYPRCTL} -j monitors >/dev/null 2>&1; do - sleep 0.5 - done - } - - mon_name_by_desc() { - # Resolve Hyprland "name" (e.g., DP-2) from human-friendly description - local desc="${"$"}1" - ''${HYPRCTL} -j monitors \ - | ''${JQ} -r --arg d "${"$"}desc" '.[] | select(.description == $d) | .name' \ - | head -n1 - } - - place_workspaces() { - local mainName secName - mainName="$(mon_name_by_desc "${"$"}MAIN_DESC")" - secName="$(mon_name_by_desc "${"$"}SEC_DESC" || true)" - - # Always keep 1–6 on the main monitor - for ws in 1 2 3 4 5 6; do - ''${HYPRCTL} dispatch moveworkspacetomonitor "${"$"}ws" "${"$"}mainName" || true - done - - if [ -n "${"$"}{secName:-}" ]; then - # Secondary is present ➜ put 7–10 on secondary - for ws in 7 8 9 10; do - ''${HYPRCTL} dispatch moveworkspacetomonitor "${"$"}ws" "${"$"}secName" || true - done - else - # No secondary ➜ keep 7–10 on main - for ws in 7 8 9 10; do - ''${HYPRCTL} dispatch moveworkspacetomonitor "${"$"}ws" "${"$"}mainName" || true - done - fi - } - - watch_events() { - local sock - sock="$(get_socket)" - - # If socket2 is missing for some reason, fall back to polling - if [ ! -S "${"$"}sock" ]; then - while :; do - place_workspaces - sleep 5 - done - return - fi - - # Subscribe to Hyprland events and react to monitor changes - ''${SOCAT} - "UNIX-CONNECT:${"$"}sock" | while IFS= read -r line; do - case "${"$"}line" in - monitoradded*|monitorremoved*|activemonitor*|layoutchange*) - place_workspaces - ;; - esac - done - } - - if [ "${"$"}{1:-}" = "--oneshot" ]; then - wait_for_hypr - place_workspaces - else - wait_for_hypr - place_workspaces - watch_events - fi - ''; -in -{ - options = { }; - - config = { - environment.systemPackages = [ moveScript ]; - - # Pass the options to home-manager for hyprland (as you already do) - ringofstorms_common.desktopEnvironment.hyprland.extraOptions = hyprlandExtraOptions; - - # User-level systemd service that follows your Hyprland session and watches for monitor changes - systemd.user.services.hyprland-move-workspaces = { - description = "Keep workspaces 1–6 on main and 7–10 on secondary; react to monitor changes"; - wants = [ "graphical-session.target" ]; - after = [ "graphical-session.target" ]; - partOf = [ "graphical-session.target" ]; - - serviceConfig = { - Type = "simple"; - ExecStart = "${moveScript}/bin/hyprland-move-workspaces"; - Restart = "always"; - RestartSec = "2s"; - }; - - wantedBy = [ "graphical-session.target" ]; - }; - }; -}