Compare commits
3 commits
208e16e666
...
c007bb72d2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c007bb72d2 | ||
|
|
8aebae3016 | ||
|
|
f2aed4dc5f |
9 changed files with 714 additions and 475 deletions
|
|
@ -29,6 +29,12 @@ with lib;
|
||||||
default = { };
|
default = { };
|
||||||
description = "Extra options for Hyprland configuration.";
|
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 {
|
config = lib.mkIf cfg.enable {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
imports = [
|
imports = [
|
||||||
./theme.nix
|
./theme.nix
|
||||||
./hyprland.nix
|
./hyprland.nix
|
||||||
|
# ./quickshell.nix
|
||||||
./waybar.nix
|
./waybar.nix
|
||||||
./hyprpolkitagent.nix
|
./hyprpolkitagent.nix
|
||||||
./wofi.nix
|
./wofi.nix
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,15 @@ in
|
||||||
# Default monitor configuration
|
# Default monitor configuration
|
||||||
monitor = "monitor = , preferred, auto, 1";
|
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"
|
||||||
|
];
|
||||||
|
|
||||||
windowrulev2 = [
|
windowrulev2 = [
|
||||||
"float, class:^(?i)chrome-nngceckbapebfimnlniiiahkandclblb-Default$, initialtitle:^_crx_nngceckbapebfimnlniiiahkandclblb$"
|
"float, class:^(?i)chrome-nngceckbapebfimnlniiiahkandclblb-Default$, initialtitle:^_crx_nngceckbapebfimnlniiiahkandclblb$"
|
||||||
"center, class:^(?i)chrome-nngceckbapebfimnlniiiahkandclblb-Default$, initialtitle:^_crx_nngceckbapebfimnlniiiahkandclblb$"
|
"center, class:^(?i)chrome-nngceckbapebfimnlniiiahkandclblb-Default$, initialtitle:^_crx_nngceckbapebfimnlniiiahkandclblb$"
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
osConfig,
|
osConfig,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
|
upkgs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
|
|
@ -15,8 +16,7 @@ let
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
quickshell
|
upkgs.quickshell
|
||||||
|
|
||||||
pulseaudio
|
pulseaudio
|
||||||
brightnessctl
|
brightnessctl
|
||||||
networkmanager
|
networkmanager
|
||||||
|
|
@ -27,4 +27,67 @@ in
|
||||||
systemd
|
systemd
|
||||||
hyprlock
|
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" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,20 @@
|
||||||
{
|
{
|
||||||
|
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 = {
|
services.swaync = {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings = {
|
settings = {
|
||||||
|
|
@ -234,4 +247,5 @@
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,20 @@
|
||||||
{
|
{
|
||||||
|
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 = {
|
programs.waybar = {
|
||||||
enable = true;
|
enable = true;
|
||||||
systemd.enable = true;
|
systemd.enable = true;
|
||||||
|
|
@ -250,4 +263,5 @@
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
6
common/flake.lock
generated
6
common/flake.lock
generated
|
|
@ -85,11 +85,11 @@
|
||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1753592768,
|
"lastModified": 1755928099,
|
||||||
"narHash": "sha256-oV695RvbAE4+R9pcsT9shmp6zE/+IZe6evHWX63f2Qg=",
|
"narHash": "sha256-OILVkfhRCm8u18IZ2DKR8gz8CVZM2ZcJmQBXmjFLIfk=",
|
||||||
"owner": "rycee",
|
"owner": "rycee",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "fc3add429f21450359369af74c2375cb34a2d204",
|
"rev": "4a44fb9f7555da362af9d499817084f4288a957f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,13 @@
|
||||||
nixosConfigurations = {
|
nixosConfigurations = {
|
||||||
"${configuration_name}" = (
|
"${configuration_name}" = (
|
||||||
lib.nixosSystem {
|
lib.nixosSystem {
|
||||||
specialArgs = { inherit inputs; };
|
specialArgs = {
|
||||||
|
inherit inputs;
|
||||||
|
upkgs = import inputs.nixpkgs-unstable {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
config.allowUnfree = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
modules = [
|
modules = [
|
||||||
common.nixosModules.default
|
common.nixosModules.default
|
||||||
ros_neovim.nixosModules.default
|
ros_neovim.nixosModules.default
|
||||||
|
|
@ -37,10 +43,12 @@
|
||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
(import ./containers.nix { inherit inputs; })
|
(import ./containers.nix { inherit inputs; })
|
||||||
# ./jails_text.nix
|
# ./jails_text.nix
|
||||||
|
./hyprland_customizations.nix
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
pkgs,
|
pkgs,
|
||||||
|
upkgs,
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|
@ -80,6 +88,11 @@
|
||||||
# Allow emulation of aarch64-linux binaries for cross compiling
|
# Allow emulation of aarch64-linux binaries for cross compiling
|
||||||
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
|
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
|
||||||
|
|
||||||
|
home-manager.extraSpecialArgs = {
|
||||||
|
inherit inputs;
|
||||||
|
inherit upkgs;
|
||||||
|
};
|
||||||
|
|
||||||
ringofstorms_common = {
|
ringofstorms_common = {
|
||||||
systemName = configuration_name;
|
systemName = configuration_name;
|
||||||
boot.systemd.enable = true;
|
boot.systemd.enable = true;
|
||||||
|
|
@ -90,26 +103,8 @@
|
||||||
};
|
};
|
||||||
desktopEnvironment.hyprland = {
|
desktopEnvironment.hyprland = {
|
||||||
enable = true;
|
enable = true;
|
||||||
extraOptions =
|
waybar.enable = true;
|
||||||
let
|
swaync.enable = true;
|
||||||
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 = {
|
programs = {
|
||||||
qFlipper.enable = true;
|
qFlipper.enable = true;
|
||||||
|
|
|
||||||
137
hosts/lio/hyprland_customizations.nix
Normal file
137
hosts/lio/hyprland_customizations.nix
Normal file
|
|
@ -0,0 +1,137 @@
|
||||||
|
{ 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" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue