Dev

HyprSpace no macOS — O Tiling Window Manager que Chegou para Ficar

Guia completo do HyprSpace, um tiling window manager para macOS inspirado no Hyprland. Instalação, configuração, keybindings e dicas práticas.

O HyprSpace traz o dwindle layout do Hyprland para macOS. Sem SIP. Sem Xcode. TOML puro. Workspaces virtuais. E uma workspace bar que parece nativa.

Atualização (outubro de 2026): depois de este artigo ser escrito, o projeto mudou de nome para OmniWM e passou para github.com/OmniNull/OmniWM. Com a mudança: a licença passou de MIT para GPL-2.0; o requisito subiu para macOS 26+ em Apple Silicon; o tap barutsrb/tap foi retirado a favor de brew install --cask omniwm; o CLI mudou de hyprspace para omniwmctl; e o config passou para ~/.config/omniwm/settings.toml. O resto deste artigo documenta a versão antiga, como HyprSpace — os conceitos (dwindle layout, workspaces virtuais, TOML) mantêm-se, mas os comandos, caminhos e o nome do binário já não correspondem ao projeto atual. Para uma instalação de raiz, começa pelo repositório novo.

Sentes falta do Hyprland quando estás no macOS? Os tiling WMs para Mac existem (yabai, Amethyst, AeroSpace), mas nenhum tinha aquele feel do dwindle layout com a workspace bar à Hyprland. Até agora.

O HyprSpace é um fork pesado do AeroSpace com componentes do Barik. Foi escrito em Swift, funcionava no macOS 13.0+ (o OmniWM, a versão atual do projeto, exige macOS 26+), e não precisa de desativar o SIP. A workspace bar é bonita, integra-se no design do macOS, e responde ao rato.


O que é o HyprSpace

HyprSpace é um tiling window manager para macOS. Gestão de janelas por atalhos de teclado, dwindle layout (árvore binária), workspaces virtuais (5 por omissão), e suporte multi-monitor no estilo i3.

Diferente do yabai ou Amethyst, o HyprSpace não usa os Spaces nativos do macOS. Implementa os seus próprios workspaces virtuais. Isto significa que não estás limitado pelo comportamento errático do Mission Control.

A stack é Swift puro, com config em TOML. Cliente/servidor via UNIX socket (/tmp/barut.hyprspace-{user}.sock). A workspace bar é desenhada em SwiftUI e tem suporte total a rato.


Feature highlights
  • Dwindle layout — árvore binária, igual ao Hyprland
  • Workspace bar bonita — blends in com o macOS, não parece um hack
  • Virtual workspaces — sem depender dos Spaces do macOS
  • CLI first — hyprspace list-windows --all, hyprspace focus left, etc.
  • Man pages e shell completion — porque sim
  • Sem SIP disabled — usa só a Accessibility API
  • TOML config — dotfiles friendly, sem YAML

Instalação

Há três formas de instalar o HyprSpace.


1. Homebrew (assim que estiver publicado)
brew install --cask barutsrb/tap/hyprspace

2. Download do Release

Descarrega o HyprSpace-vX.X.X.zip da página de releases.

# Extrair e copiar
unzip HyprSpace-vX.X.X.zip
cp -r HyprSpace.app /Applications/
cp hyprspace /usr/local/bin/

# Remover quarantine (app não notarized)
xattr -d com.apple.quarantine /Applications/HyprSpace.app
xattr -d com.apple.quarantine /usr/local/bin/hyprspace

# Copiar config default
cp HyprSpace.app/Contents/Resources/default-config.toml ~/.hyprspace.toml

3. Build from Source

Foi esta a via que usei. Funciona bem, demora ~2 minutos.

git clone https://github.com/BarutSRB/HyprSpace.git
# ou o teu fork
git clone https://github.com/patroza/HyprSpace.git

cd HyprSpace

# Instalar dependências (ANTLR, complgen, swiftformat, swiftlint, xcodegen)
./script/install-dep.sh

# Build debug
./build-debug.sh

O build compila 765 ficheiros em ~133 segundos (Swift 6.1.2, CLI tools sem Xcode.app). Os binários ficam em .build/arm64-apple-macosx/debug/. Tens o CLI (hyprspace) e o app bundle (HyprSpaceApp).

Para correr:

./run-debug.sh

Na primeira execução, o macOS pede permissões de Acessibilidade. Vai a System Settings → Privacy & Security → Accessibility e ativa o HyprSpace.

Nota: O build debug usa o ficheiro ~/.hyprspace-debug.toml em vez de ~/.hyprspace.toml.


Primeiros passos

Assim que o HyprSpace está a correr, deves ver a workspace bar no topo do ecrã. São 5 workspaces numeradas, com destaque na ativa.

Começa por abrir um terminal: Alt + Enter abre o Ghostty (podes mudar no config).

Depois abre mais algumas janelas e experimenta:

  • Alt + H/J/K/L — navegação Vim entre janelas
  • Alt + Shift + H/J/K/L — move janela na direção
  • Alt + 1/2/3/4/5 — muda de workspace
  • Alt + Shift + 1/2/3/4/5 — manda janela para workspace

As janelas organizam-se automaticamente em dwindle layout. Cada nova janela divide o espaço disponível ao meio, alternando entre horizontal e vertical.


Keybindings Essenciais

Atalho Ação
Alt + Enter Abrir terminal (Ghostty)
Alt + H/J/K/L Foco left/down/up/right
Alt + Shift + H/J/K/L Mover janela left/down/up/right
Alt + 1-5 Switch workspace
Alt + Shift + 1-5 Mover janela para workspace
Alt + Tab Toggle workspace atual/anterior
Alt + Shift + Tab Mover workspace para próximo monitor
Alt + - / Alt + = Shrink / Grow janela
Alt + / Cycle split orientation
Alt + , Reset dwindle layout
Alt + Q Quit app focada
Alt + Shift + ; Service mode

O modifier primário é o Alt (⌥), igual ao i3/Hyprland. Se usas Dvorak ou Colemak, há preset no config.


Service Mode

O service mode é um modo de comandos avançados. Entras com Alt + Shift + ;. A workspace bar muda para indicar que estás em service mode.

Tecla Ação
Esc Recarregar config + voltar ao main mode
R Reset/flatten workspace layout
F Toggle floating/tiling na janela focada
Backspace Fechar todas as janelas exceto a atual
Alt + Shift + H/J/K/L Join windows na direção
Up / Down Volume up / down
Shift + Down Mute

O Esc é o mais útil — recarrega o config sem precisar de reiniciar a app. Sempre que editares o ~/.hyprspace.toml, faz Alt + Shift + ; e depois Esc.


Configuração TOML

O ficheiro de config fica em ~/.hyprspace.toml (release) ou ~/.hyprspace-debug.toml (debug).

start-at-login = true
default-root-container-layout = 'dwindle'
default-root-container-orientation = 'auto'

after-startup-command = ['layout dwindle']

enable-normalization-flatten-containers = true
enable-normalization-opposite-orientation-for-nested-containers = true

on-focused-monitor-changed = ['move-mouse monitor-lazy-center']
automatically-unhide-macos-hidden-apps = false

[gaps]
inner.horizontal = 14
inner.vertical = 14
outer.top = 8
outer.bottom = 8
outer.left = 8
outer.right = 8

[key-mapping]
preset = 'qwerty'  # ou dvorak, colemak

Keybindings no config
[mode.main.binding]
alt-enter = 'exec-and-forget open -n -a "Ghostty"'
alt-q = 'exec-and-forget osascript -e "tell application \"System Events\" to keystroke \"q\" using command down"'

alt-h = 'focus left'
alt-j = 'focus down'
alt-k = 'focus up'
alt-l = 'focus right'

alt-shift-h = 'move left'
alt-shift-j = 'move down'
alt-shift-k = 'move up'
alt-shift-l = 'move right'

alt-1 = 'workspace 1'
alt-2 = 'workspace 2'
alt-3 = 'workspace 3'
alt-4 = 'workspace 4'
alt-5 = 'workspace 5'

alt-minus = 'resize smart -50'
alt-equal = 'resize smart +50'

alt-slash = 'layout dwindle horizontal vertical'
alt-comma = 'layout dwindle'

Service mode:

[mode.service.binding]
esc = ['reload-config', 'mode main']
r = ['flatten-workspace-tree', 'mode main']
f = ['layout floating tiling', 'mode main']
backspace = ['close-all-windows-but-current', 'mode main']
alt-shift-h = ['join-with left', 'mode main']
alt-shift-j = ['join-with down', 'mode main']
alt-shift-k = ['join-with up', 'mode main']
alt-shift-l = ['join-with right', 'mode main']
down = 'volume down'
up = 'volume up'
shift-down = ['volume set 0', 'mode main']

Chaves disponíveis: letras (a-z), números (0-9), f1-f20, especiais (minus, equal, period, comma, slash, semicolon, space, enter, esc, tab, arrows). Modifiers: cmd, alt, ctrl, shift.


CLI

# Recarregar config
hyprspace reload-config

# Listar janelas
hyprspace list-windows --all

# Debug info das janelas
hyprspace debug-windows

# Foco
hyprspace focus left
hyprspace focus down

# Workspace
hyprspace workspace 3

# Mover janela para workspace
hyprspace move-node-to-workspace 2

# Resize
hyprspace resize smart +50
hyprspace resize smart -50

# Layout
hyprspace layout dwindle horizontal

# Fechar tudo excepto actual
hyprspace close-all-windows-but-current

# Reset layout
hyprspace flatten-workspace-tree

hyprspace --help para a lista completa. Também há man page: man hyprspace.


Multi-monitor

Cada monitor pode ter os seus próprios workspaces.

Setup:

  1. Arranja os monitores em System Settings → Displays (sem overlap)
  2. Usa Alt + Shift + Tab para mover workspace para o próximo monitor
  3. O mouse segue o foco (configurável)

Forçar workspaces a monitores específicos:

[workspace-to-monitor-force-assignment]
1 = 'main'
2 = 'main'
3 = 'secondary'
4 = ['secondary', 1]
5 = ['secondary', 2]

Dicas e troubleshooting


Window dragging from anywhere
defaults write -g NSWindowShouldDragOnGesture -bool true

Depois é Ctrl + Cmd + arrastar.


Keybindings não funcionam

Verifica conflitos com outros atalhos do macOS ou apps.


Windows não fazem tiling
  • Alt + Shift + ; + Esc recarrega config
  • Alt + Shift + ; + R faz reset ao layout
  • hyprspace flatten-workspace-tree pela CLI

Permissões de Acessibilidade

System Settings → Privacy & Security → Accessibility. Para debug builds:

./script/reset-accessibility-permission-for-debug.sh

App não abre (quarantine)
xattr -d com.apple.quarantine /Applications/HyprSpace.app

Conclusão

O HyprSpace ainda está em desenvolvimento ativo (pré-1.0), mas já é estável para uso diário. A workspace bar é, de longe, a mais bonita que vi num tiling WM para macOS. O dwindle layout funciona bem, a config TOML é limpa, e o CLI é competente.

Se sentes falta do Hyprland no Mac, testa. O setup é rápido, o build from source é trivial, e o código é Swift aberto (GPL-2.0 na versão atual, OmniWM) se quiseres contribuir.


Recursos

Partilhar

Comentários 0

Ainda sem comentários — sê o primeiro.