Files
nixos-config/modules/hyprland-workspaces.nix
T
daniil-berg f533bbeb05 feat(hyprland): add per-monitor workspace homing and monitor nav binds
New `local.hyprland.workspaceRules` option binds workspaces to monitor
connectors so each has a home screen; a consumer sets it from its own host
config (empty by default). Soft binding — an absent monitor's workspaces fall
back to an active one, so a laptop-only session still works.

`$mod+o` / `$mod SHIFT+o` focus and move the current workspace to the other
monitor. When rules are set, an `exec-once` nudges a single-monitor session to
workspace 1 rather than a support monitor's high default.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 09:32:59 +02:00

43 lines
1.9 KiB
Nix

# Per-monitor "home" for workspaces. Each rule pins a workspace to a monitor
# connector, so it opens there and Hyprland moves it back when that monitor
# reappears after an unplug. The connector names are host hardware, so the rule
# list is an option a consumer sets from its own host config (see the example in
# `hosts/example/home.nix`), not baked in here; empty by default, so the example
# host binds nothing.
#
# Soft binding: when a bound monitor is absent the workspace just falls back to
# an active one — every workspace stays reachable, so a laptop-only (no external)
# session works unchanged. The `default` keyword marks the workspace a monitor
# shows on connect.
{ config, lib, pkgs, ... }:
{
options.local.hyprland.workspaceRules = lib.mkOption {
type = with lib.types; listOf str;
default = [ ];
example = [
"1, monitor:HDMI-A-1, default:true"
"6, monitor:LVDS-1, default:true"
];
description = ''
Hyprland `workspace` rules binding workspaces to monitor connectors, so
each workspace has a home screen. Connector names are host-specific set
this from the inventory rather than here.
'';
};
config.wayland.windowManager.hyprland.settings = {
workspace = config.local.hyprland.workspaceRules;
# With a support monitor whose `default` workspace is high (e.g. a laptop
# holding 6-9), a solo session with that monitor as the only screen opens on
# that high workspace instead of 1. When rules are in effect, nudge a
# single-monitor startup back to workspace 1. No-op with no rules (1 is
# already the default). jq is pinned by store path so a consumer needn't
# have it installed; hyprctl is bare (a Hyprland session always has it, like
# the wallpaper exec-once assumes awww).
exec-once = lib.optional (config.local.hyprland.workspaceRules != [ ])
"sh -c '[ \"$(hyprctl monitors -j | ${pkgs.jq}/bin/jq length)\" -eq 1 ] && hyprctl dispatch workspace 1'";
};
}