Skip to content

jtaw5649/hyprspaces

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

40 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

hyprspaces

hyprspaces is a Hyprland plugin that keeps paired workspaces in sync across multiple monitors.

Install

Plugin + forked Waybar

yay -S hyprspaces waybar-hyprspaces-fork-bin
hyprspaces-install

Plugin only

yay -S hyprspaces
hyprspaces-install --skip-waybar

Switch Waybar mode

hyprspaces-waybar-use-fork
hyprspaces-waybar-use-stock

After a Hyprland update

Hyprland plugins must be rebuilt whenever Hyprland itself is updated. If the plugin fails to load, a desktop notification will appear with instructions.

yay -S hyprspaces
hyprspaces-install

Uninstall

hyprspaces-uninstall

Useful flags:

  • --keep-fork: keep ~/.local/share/hyprspaces/waybar-fork
  • --skip-waybar: skip stock switchback and shim cleanup
  • --purge-config: remove managed settings/bindings snippets

What it does

Each paired workspace index is shown simultaneously across all managed monitors. Switching to pair 3 puts workspace 3 on the primary monitor, workspace 13 on the secondary, workspace 23 on the third, and so on.

Default bindings:

  • Super + 1..0: switch all monitors to a paired workspace index
  • Super + Shift + 1..0: move focused window to the same paired index on the current side
  • Super + mouse wheel: cycle paired workspaces
  • Super + Shift + arrow: move window in the given direction
  • monitor hotplug: automatically rebalance managed workspaces

Configuration

Plugin options live under plugin:hyprspaces:

Option Type Default Description
paired_offset int 10 Workspace offset per monitor slot
primary_monitor string "" Primary monitor name (auto-detected if empty)
secondary_monitor string "" Secondary monitor name (auto-detected if empty)
monitors string "" Ordered comma-separated monitor names for 3+ monitor support
keep_focused int 1 Restore focus to the original monitor after pair switch
enable_wrapping int 1 Wrap around when cycling past the first or last pair
follow_moved_window int 0 Auto-switch to target pair when using move-window with a pair index
persistent_workspaces int 0 Pre-create all managed workspaces during rebalance
workspace_names string "" Pair index names in 1:Web,2:Dev,3:Chat format

Monitor setup

For 2 monitors, primary_monitor and secondary_monitor are sufficient. If both are omitted, the plugin auto-selects the first two active monitors.

For 3+ monitors, set monitors to an ordered comma-separated list of monitor names:

plugin {
    hyprspaces {
        monitors = DP-1,DP-2,HDMI-A-1
    }
}

Monitor slot 0 gets workspaces 1..offset, slot 1 gets offset+1..offset*2, slot 2 gets offset*2+1..offset*3, and so on. When monitors is set, primary_monitor and secondary_monitor are ignored.

Dispatchers

Dispatcher Arguments Description
hyprspaces:switch <N> or previous Switch all monitors to pair N, or return to the previous pair
hyprspaces:cycle next or prev Cycle to the next or previous pair
hyprspaces:move-window <N> or l|r|u|d Move focused window to pair N on the current side, or directionally
hyprspaces:move-window-follow <N> Move focused window to pair N and switch to that pair
hyprspaces:rebalance Force-rebalance all managed workspaces onto correct monitors
hyprspaces:swap-sides Swap windows between current and next monitor for the active pair
hyprspaces:move-to-side Move focused window to the next monitor within the active pair
hyprspaces:focus-side Cycle focus to the next monitor
hyprspaces:toggle-special [name] Toggle a special workspace on all monitors simultaneously
hyprspaces:bring-window <N> Pull the last window from pair N on the same side to the current workspace

Examples:

hyprctl dispatch hyprspaces:switch 3
hyprctl dispatch hyprspaces:switch previous
hyprctl dispatch hyprspaces:cycle next
hyprctl dispatch hyprspaces:move-window 4
hyprctl dispatch hyprspaces:move-window r
hyprctl dispatch hyprspaces:swap-sides
hyprctl dispatch hyprspaces:toggle-special
hyprctl dispatch hyprspaces:bring-window 2
hyprctl dispatch hyprspaces:rebalance

Socket2 events

All dispatchers emit events on Hyprland's socket2 under the hyprspaces topic:

Event Format
Pair switch hyprspaces>>switch,<N>
Cycle (emitted as a switch event)
Move window hyprspaces>>move-window,<N or direction>
Move window follow hyprspaces>>move-window-follow,<N>
Rebalance hyprspaces>>rebalance
Swap sides hyprspaces>>swap,<N>
Move to side hyprspaces>>move-to-side
Focus side hyprspaces>>focus-side
Toggle special hyprspaces>>toggle-special,<name>
Bring window hyprspaces>>bring-window,<N>
Topology change hyprspaces>>rebalance (also emitted on monitor hotplug and config reload)

Listen with:

socat -U - UNIX-CONNECT:$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock | grep hyprspaces

Example: react to pair switches in a script:

socat -U - UNIX-CONNECT:$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock | while IFS= read -r line; do
    case "$line" in
        hyprspaces\>\>switch,*) echo "Switched to pair ${line##*,}" ;;
        hyprspaces\>\>rebalance) echo "Workspaces rebalanced" ;;
    esac
done

A reference waybar config is available at config/waybar-example.jsonc.

Hyprctl command

Query plugin state:

hyprctl hyprspaces        # plain text
hyprctl -j hyprspaces     # JSON

JSON output includes: version, activePair, previousPair, pairedOffset, primaryMonitor, secondaryMonitor, monitorCount, monitors (each with name and activeWorkspace), workspaceNames, keepFocused, enableWrapping, followMovedWindow, persistentWorkspaces.

Waybar fork

  • fork: https://github.com/jtaw5649/Waybar (hyprspaces-paired-workspaces)
  • upstream base module: https://github.com/Alexays/Waybar/blob/master/src/modules/hyprland/workspaces.cpp
  • added behavior: active-per-monitor, hyprspaces-paired-offset, paired-offset-aware persistent workspace creation, hyprspaces-special-overlay

Special workspace indicator flow (fork mode):

  • keep show-special: false to avoid a separate scratchpad button in the workspace row
  • set hyprspaces-special-overlay: true to mark the active numbered workspace when a special workspace is visible on that monitor
  • define format-icons.special-active to choose the icon shown during special overlay state
  • style with #workspaces button.special-active / #workspaces button.special-active.active
  • hyprspaces-waybar-use-fork writes show-special: false and hyprspaces-special-overlay: true automatically

Credit:

  • the hyprland/workspaces implementation in this fork is based on Waybar's upstream module
  • all credit for the original module architecture and baseline behavior goes to Waybar maintainers and contributors
  • Waybar is MIT-licensed: https://github.com/Alexays/Waybar/blob/master/LICENSE

The switch commands manage:

  • ~/.config/hyprspaces/waybar/current-binary
  • managed waybar shim(s) in user-writable PATH entries
  • backups in ~/.local/state/hyprspaces/waybar/

Development

Build:

cmake -S . -B build
cmake --build build

or:

make all

Tests:

ctest --test-dir build --output-on-failure

About

Multi-display workspace plugin for Hyprland

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors