Compare commits
No commits in common. "c007bb72d2ef201dcfbb854656f6810d448d85bf" and "208e16e66685f4d9a56b32c51bf2588c458f591f" have entirely different histories.
c007bb72d2
...
208e16e666
9 changed files with 475 additions and 714 deletions
|
|
@ -29,12 +29,6 @@ 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,7 +3,6 @@
|
||||||
imports = [
|
imports = [
|
||||||
./theme.nix
|
./theme.nix
|
||||||
./hyprland.nix
|
./hyprland.nix
|
||||||
# ./quickshell.nix
|
|
||||||
./waybar.nix
|
./waybar.nix
|
||||||
./hyprpolkitagent.nix
|
./hyprpolkitagent.nix
|
||||||
./wofi.nix
|
./wofi.nix
|
||||||
|
|
|
||||||
|
|
@ -29,17 +29,8 @@ in
|
||||||
# "waybar"
|
# "waybar"
|
||||||
# ];
|
# ];
|
||||||
|
|
||||||
# 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$"
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
osConfig,
|
osConfig,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
upkgs,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
|
|
@ -16,7 +15,8 @@ let
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
upkgs.quickshell
|
quickshell
|
||||||
|
|
||||||
pulseaudio
|
pulseaudio
|
||||||
brightnessctl
|
brightnessctl
|
||||||
networkmanager
|
networkmanager
|
||||||
|
|
@ -27,67 +27,4 @@ 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,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 = {
|
||||||
services.swaync = {
|
enable = true;
|
||||||
enable = true;
|
settings = {
|
||||||
settings = {
|
ignore = [
|
||||||
ignore = [
|
"com.spotify.Client"
|
||||||
"com.spotify.Client"
|
];
|
||||||
];
|
|
||||||
|
|
||||||
positionX = "right";
|
positionX = "right";
|
||||||
positionY = "top";
|
positionY = "top";
|
||||||
layer = "overlay";
|
layer = "overlay";
|
||||||
control-center-layer = "top";
|
control-center-layer = "top";
|
||||||
layer-shell = true;
|
layer-shell = true;
|
||||||
cssPriority = "application";
|
cssPriority = "application";
|
||||||
|
|
||||||
control-center-margin-top = 0;
|
control-center-margin-top = 0;
|
||||||
control-center-margin-bottom = 0;
|
control-center-margin-bottom = 0;
|
||||||
control-center-margin-right = 0;
|
control-center-margin-right = 0;
|
||||||
control-center-margin-left = 0;
|
control-center-margin-left = 0;
|
||||||
|
|
||||||
notification-2fa-action = true;
|
notification-2fa-action = true;
|
||||||
notification-inline-replies = false;
|
notification-inline-replies = false;
|
||||||
notification-icon-size = 64;
|
notification-icon-size = 64;
|
||||||
notification-body-image-height = 100;
|
notification-body-image-height = 100;
|
||||||
notification-body-image-width = 200;
|
notification-body-image-width = 200;
|
||||||
|
|
||||||
timeout = 10;
|
timeout = 10;
|
||||||
timeout-low = 5;
|
timeout-low = 5;
|
||||||
timeout-critical = 0;
|
timeout-critical = 0;
|
||||||
|
|
||||||
control-center-width = 500;
|
control-center-width = 500;
|
||||||
control-center-height = 600;
|
control-center-height = 600;
|
||||||
notification-window-width = 500;
|
notification-window-width = 500;
|
||||||
|
|
||||||
keyboard-shortcuts = true;
|
keyboard-shortcuts = true;
|
||||||
image-visibility = "when-available";
|
image-visibility = "when-available";
|
||||||
transition-time = 200;
|
transition-time = 200;
|
||||||
hide-on-clear = false;
|
hide-on-clear = false;
|
||||||
hide-on-action = true;
|
hide-on-action = true;
|
||||||
script-fail-notify = true;
|
script-fail-notify = true;
|
||||||
|
|
||||||
widgets = [
|
widgets = [
|
||||||
"inhibitors"
|
"inhibitors"
|
||||||
"title"
|
"title"
|
||||||
"dnd"
|
"dnd"
|
||||||
"volume"
|
"volume"
|
||||||
"backlight"
|
"backlight"
|
||||||
"mpris"
|
"mpris"
|
||||||
"buttons-grid#quick"
|
"buttons-grid#quick"
|
||||||
"notifications"
|
"notifications"
|
||||||
];
|
];
|
||||||
|
|
||||||
# Widget configurations
|
# Widget configurations
|
||||||
widget-config = {
|
widget-config = {
|
||||||
inhibitors = {
|
inhibitors = {
|
||||||
text = "Inhibitors";
|
text = "Inhibitors";
|
||||||
button-text = "Clear All";
|
button-text = "Clear All";
|
||||||
clear-all-button = true;
|
clear-all-button = true;
|
||||||
};
|
};
|
||||||
title = {
|
title = {
|
||||||
text = "Notifications";
|
text = "Notifications";
|
||||||
clear-all-button = true;
|
clear-all-button = true;
|
||||||
button-text = "Clear All";
|
button-text = "Clear All";
|
||||||
};
|
};
|
||||||
dnd.text = "Do Not Disturb";
|
dnd.text = "Do Not Disturb";
|
||||||
mpris = {
|
mpris = {
|
||||||
image-size = 96;
|
image-size = 96;
|
||||||
image-radius = 12;
|
image-radius = 12;
|
||||||
};
|
};
|
||||||
volume = {
|
volume = {
|
||||||
label = "";
|
label = "";
|
||||||
show-per-app = true;
|
show-per-app = true;
|
||||||
};
|
};
|
||||||
backlight = {
|
backlight = {
|
||||||
label = "";
|
label = "";
|
||||||
device = "intel_backlight";
|
device = "intel_backlight";
|
||||||
};
|
};
|
||||||
"buttons-grid#quick" = {
|
"buttons-grid#quick" = {
|
||||||
columns = 4; # adjust: 3/4/5
|
columns = 4; # adjust: 3/4/5
|
||||||
icon-size = 20; # tweak to taste
|
icon-size = 20; # tweak to taste
|
||||||
actions = [
|
actions = [
|
||||||
# Power
|
# Power
|
||||||
{
|
{
|
||||||
label = "";
|
label = "";
|
||||||
tooltip = "Shutdown";
|
tooltip = "Shutdown";
|
||||||
command = "confirm-action 'systemctl poweroff' 'Shutdown?'";
|
command = "confirm-action 'systemctl poweroff' 'Shutdown?'";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
label = "";
|
label = "";
|
||||||
tooltip = "Reboot";
|
tooltip = "Reboot";
|
||||||
command = "confirm-action 'systemctl reboot' 'Reboot?'";
|
command = "confirm-action 'systemctl reboot' 'Reboot?'";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
label = "";
|
label = "";
|
||||||
tooltip = "Logout";
|
tooltip = "Logout";
|
||||||
command = "confirm-action 'hyprctl dispatch exit' '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;
|
||||||
|
}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 = {
|
||||||
programs.waybar = {
|
enable = true;
|
||||||
enable = true;
|
systemd.enable = true;
|
||||||
systemd.enable = true;
|
settings = {
|
||||||
settings = {
|
mainBar = {
|
||||||
mainBar = {
|
layer = "top";
|
||||||
layer = "top";
|
position = "top";
|
||||||
position = "top";
|
height = 30;
|
||||||
height = 30;
|
spacing = 6;
|
||||||
spacing = 6;
|
margin-top = 0;
|
||||||
margin-top = 0;
|
margin-bottom = 0;
|
||||||
margin-bottom = 0;
|
margin-left = 10;
|
||||||
margin-left = 10;
|
margin-right = 10;
|
||||||
margin-right = 10;
|
|
||||||
|
|
||||||
modules-left = [
|
modules-left = [
|
||||||
"hyprland/workspaces"
|
"hyprland/workspaces"
|
||||||
];
|
];
|
||||||
|
|
||||||
modules-center = [
|
modules-center = [
|
||||||
"clock"
|
"clock"
|
||||||
"temperature"
|
"temperature"
|
||||||
"cpu"
|
"cpu"
|
||||||
"memory"
|
"memory"
|
||||||
"disk"
|
"disk"
|
||||||
];
|
];
|
||||||
|
|
||||||
modules-right = [
|
modules-right = [
|
||||||
"pulseaudio"
|
"pulseaudio"
|
||||||
"network"
|
"network"
|
||||||
"bluetooth"
|
"bluetooth"
|
||||||
"custom/notifications"
|
"custom/notifications"
|
||||||
"hyprland/language"
|
"hyprland/language"
|
||||||
];
|
];
|
||||||
|
|
||||||
# Workspaces configuration
|
# Workspaces configuration
|
||||||
"hyprland/workspaces" = {
|
"hyprland/workspaces" = {
|
||||||
format = "{icon}";
|
format = "{icon}";
|
||||||
format-icons = {
|
format-icons = {
|
||||||
"1" = "一";
|
"1" = "一";
|
||||||
"2" = "二";
|
"2" = "二";
|
||||||
"3" = "三";
|
"3" = "三";
|
||||||
"4" = "四";
|
"4" = "四";
|
||||||
"5" = "五";
|
"5" = "五";
|
||||||
"6" = "六";
|
"6" = "六";
|
||||||
"7" = "七";
|
"7" = "七";
|
||||||
"8" = "八";
|
"8" = "八";
|
||||||
"9" = "九";
|
"9" = "九";
|
||||||
"10" = "十";
|
"10" = "十";
|
||||||
"11" = "十一";
|
"11" = "十一";
|
||||||
"12" = "十二";
|
"12" = "十二";
|
||||||
"13" = "十三";
|
"13" = "十三";
|
||||||
"14" = "十四";
|
"14" = "十四";
|
||||||
"15" = "十五";
|
"15" = "十五";
|
||||||
"16" = "十六";
|
"16" = "十六";
|
||||||
"17" = "十七";
|
"17" = "十七";
|
||||||
"18" = "十八";
|
"18" = "十八";
|
||||||
"19" = "十九";
|
"19" = "十九";
|
||||||
"20" = "二十";
|
"20" = "二十";
|
||||||
};
|
|
||||||
show-special = false;
|
|
||||||
};
|
};
|
||||||
|
show-special = false;
|
||||||
|
};
|
||||||
|
|
||||||
pulseaudio = {
|
pulseaudio = {
|
||||||
format = "{icon} {volume}%";
|
format = "{icon} {volume}%";
|
||||||
format-bluetooth = " {volume}%";
|
format-bluetooth = " {volume}%";
|
||||||
format-bluetooth-muted = " ";
|
format-bluetooth-muted = " ";
|
||||||
format-muted = " ";
|
format-muted = " ";
|
||||||
format-source = " {volume}%";
|
format-source = " {volume}%";
|
||||||
format-source-muted = " ";
|
format-source-muted = " ";
|
||||||
format-icons = {
|
format-icons = {
|
||||||
headphone = "";
|
headphone = "";
|
||||||
hands-free = "";
|
hands-free = "";
|
||||||
headset = "";
|
headset = "";
|
||||||
phone = "";
|
phone = "";
|
||||||
portable = "";
|
portable = "";
|
||||||
car = "";
|
car = "";
|
||||||
default = [
|
default = [
|
||||||
""
|
""
|
||||||
""
|
""
|
||||||
""
|
""
|
||||||
];
|
];
|
||||||
};
|
|
||||||
scroll-step = 5;
|
|
||||||
on-click = "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle";
|
|
||||||
on-click-right = "swaync-client -t -sw";
|
|
||||||
};
|
};
|
||||||
|
scroll-step = 5;
|
||||||
|
on-click = "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle";
|
||||||
|
on-click-right = "swaync-client -t -sw";
|
||||||
|
};
|
||||||
|
|
||||||
"custom/notifications" = {
|
"custom/notifications" = {
|
||||||
format = "{icon} {}";
|
format = "{icon} {}";
|
||||||
format-icons = {
|
format-icons = {
|
||||||
notification = "";
|
notification = "";
|
||||||
none = "";
|
none = "";
|
||||||
dnd-notification = "";
|
dnd-notification = "";
|
||||||
dnd-none = "";
|
dnd-none = "";
|
||||||
inhibited-notification = "";
|
inhibited-notification = "";
|
||||||
inhibited-none = "";
|
inhibited-none = "";
|
||||||
dnd-inhibited-notification = "";
|
dnd-inhibited-notification = "";
|
||||||
dnd-inhibited-none = "";
|
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;
|
|
||||||
};
|
};
|
||||||
|
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
|
||||||
clock = {
|
clock = {
|
||||||
format = "{:%b %d, %H:%M}";
|
format = "{:%b %d, %H:%M}";
|
||||||
};
|
};
|
||||||
|
|
||||||
temperature = {
|
temperature = {
|
||||||
thermal-zone = 2;
|
thermal-zone = 2;
|
||||||
hwmon-path = "/sys/class/hwmon/hwmon2/temp1_input";
|
hwmon-path = "/sys/class/hwmon/hwmon2/temp1_input";
|
||||||
critical-threshold = 80;
|
critical-threshold = 80;
|
||||||
format-critical = " {temperatureC}°C";
|
format-critical = " {temperatureC}°C";
|
||||||
format = " {temperatureC}°C";
|
format = " {temperatureC}°C";
|
||||||
};
|
};
|
||||||
|
|
||||||
cpu = {
|
cpu = {
|
||||||
format = " {usage}%";
|
format = " {usage}%";
|
||||||
tooltip = false;
|
tooltip = false;
|
||||||
on-click = "btop";
|
on-click = "btop";
|
||||||
};
|
};
|
||||||
|
|
||||||
memory = {
|
memory = {
|
||||||
format = " {}%";
|
format = " {}%";
|
||||||
on-click = "btop";
|
on-click = "btop";
|
||||||
};
|
};
|
||||||
|
|
||||||
disk = {
|
disk = {
|
||||||
interval = 30;
|
interval = 30;
|
||||||
format = " {percentage_used}%";
|
format = " {percentage_used}%";
|
||||||
path = "/";
|
path = "/";
|
||||||
on-click = "btop";
|
on-click = "btop";
|
||||||
};
|
};
|
||||||
|
|
||||||
network = {
|
network = {
|
||||||
format-wifi = " {essid} ({signalStrength}%)";
|
format-wifi = " {essid} ({signalStrength}%)";
|
||||||
format-ethernet = " {ipaddr}/{cidr}";
|
format-ethernet = " {ipaddr}/{cidr}";
|
||||||
tooltip-format = "{ifname} via {gwaddr} ";
|
tooltip-format = "{ifname} via {gwaddr} ";
|
||||||
format-linked = " {ifname} (No IP)";
|
format-linked = " {ifname} (No IP)";
|
||||||
format-disconnected = " Disconnected";
|
format-disconnected = " Disconnected";
|
||||||
on-click = "wofi-wifi-menu";
|
on-click = "wofi-wifi-menu";
|
||||||
on-click-right = "nmcli radio wifi toggle";
|
on-click-right = "nmcli radio wifi toggle";
|
||||||
};
|
};
|
||||||
|
|
||||||
bluetooth = {
|
bluetooth = {
|
||||||
format = " {status}";
|
format = " {status}";
|
||||||
format-connected = " {device_alias}";
|
format-connected = " {device_alias}";
|
||||||
format-connected-battery = " {device_alias} {device_battery_percentage}%";
|
format-connected-battery = " {device_alias} {device_battery_percentage}%";
|
||||||
tooltip-format = "{controller_alias}\t{controller_address}\n\n{num_connections} connected";
|
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-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 = "{device_alias}\t{device_address}";
|
||||||
tooltip-format-enumerate-connected-battery = "{device_alias}\t{device_address}\t{device_battery_percentage}%";
|
tooltip-format-enumerate-connected-battery = "{device_alias}\t{device_address}\t{device_battery_percentage}%";
|
||||||
on-click = "wofi-bluetooth-menu";
|
on-click = "wofi-bluetooth-menu";
|
||||||
on-click-right = "bluetoothctl power toggle";
|
on-click-right = "bluetoothctl power toggle";
|
||||||
};
|
};
|
||||||
|
|
||||||
# Keyboard input (language)
|
# Keyboard input (language)
|
||||||
"hyprland/language" = {
|
"hyprland/language" = {
|
||||||
format = "{}";
|
format = "{}";
|
||||||
format-en = "EN";
|
format-en = "EN";
|
||||||
format-ja = "JP";
|
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;
|
||||||
|
}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
6
common/flake.lock
generated
6
common/flake.lock
generated
|
|
@ -85,11 +85,11 @@
|
||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1755928099,
|
"lastModified": 1753592768,
|
||||||
"narHash": "sha256-OILVkfhRCm8u18IZ2DKR8gz8CVZM2ZcJmQBXmjFLIfk=",
|
"narHash": "sha256-oV695RvbAE4+R9pcsT9shmp6zE/+IZe6evHWX63f2Qg=",
|
||||||
"owner": "rycee",
|
"owner": "rycee",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "4a44fb9f7555da362af9d499817084f4288a957f",
|
"rev": "fc3add429f21450359369af74c2375cb34a2d204",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
||||||
|
|
@ -29,13 +29,7 @@
|
||||||
nixosConfigurations = {
|
nixosConfigurations = {
|
||||||
"${configuration_name}" = (
|
"${configuration_name}" = (
|
||||||
lib.nixosSystem {
|
lib.nixosSystem {
|
||||||
specialArgs = {
|
specialArgs = { inherit inputs; };
|
||||||
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
|
||||||
|
|
@ -43,12 +37,10 @@
|
||||||
./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,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|
@ -88,11 +80,6 @@
|
||||||
# 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;
|
||||||
|
|
@ -103,8 +90,26 @@
|
||||||
};
|
};
|
||||||
desktopEnvironment.hyprland = {
|
desktopEnvironment.hyprland = {
|
||||||
enable = true;
|
enable = true;
|
||||||
waybar.enable = true;
|
extraOptions =
|
||||||
swaync.enable = true;
|
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 = {
|
programs = {
|
||||||
qFlipper.enable = true;
|
qFlipper.enable = true;
|
||||||
|
|
|
||||||
|
|
@ -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" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue