Skip to content

Commit 0bcd321

Browse files
committed
docs 📚 (opencode): HAD-61 archive hypr-monitor-binds change
1 parent c0bb62b commit 0bcd321

5 files changed

Lines changed: 126 additions & 0 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
schema: spec-driven
2+
created: 2026-06-12
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
## Context
2+
3+
Hyprland bindings are organized in `configs/binds/` as modular sub-modules (`window.lua`, `layout.lua`, `apps.lua`, `workspace.lua`), loaded by `configs/binds.lua` orchestrator. The codebase follows a `register(mainMod)` pattern where `mainMod = "SUPER"` is passed to each module.
4+
5+
No existing module covers monitor-level operations. The user needs two plain-ALT bindings (no SUPER prefix) for moving windows between monitors and maximizing.
6+
7+
## Goals / Non-Goals
8+
9+
**Goals:**
10+
- Add `configs/binds/monitor.lua` with two keybindings as module-level constant definitions
11+
- Load via existing orchestrator with one `require()` line
12+
- Follow existing sub-module conventions (return `M` table with `register()` function)
13+
- Keep binding logic minimal — YAGNI
14+
15+
**Non-Goals:**
16+
- No changes to Hyprland `.conf` files, monitor configuration, or DMS IPC
17+
- No multi-monitor workspace management (focus/move workspace to monitor)
18+
- No profile system or conditional monitor detection
19+
20+
## Decisions
21+
22+
| Decision | Choice | Rationale |
23+
|----------|--------|-----------|
24+
| **Modifier keys as constants** | Define `MOD_ALT` constant at module top, use it in bind definitions | User requirement: "key configs as constants, no inline strings"; matches pattern of `mainMod` elsewhere |
25+
| **Plain ALT (no SUPER)** | `hl.bind("ALT + O", ...)` without `mainMod` prefix | User explicitly wants ALT+O and ALT+M; multimedia keys already use this no-prefix pattern in `window.lua` |
26+
| **Monitor move dispatch** | `hl.dsp.window.move({ monitor = "+1" })` | Hyprland `monitor = "+1"` moves to the next monitor in the list, cycling forward (1→2→3→1). For 2 monitors this behaves as a toggle; for 3+ it cycles through all connected monitors |
27+
| **Maximize dispatch** | `hl.dsp.window.fullscreen({ mode = "maximize" })` | Fills workspace area while keeping bar visible (`maximized` hides decorations) |
28+
| **Sub-module location** | `configs/binds/monitor.lua` | Consistent with existing modular split; loaded after `window` in orchestrator |
29+
| **No custom dispatcher** | Use `hl.dsp.*` directly | The Hyprland Lua API already provides these; no need for custom helper functions (YAGNI) |
30+
31+
## Risks / Trade-offs
32+
33+
- **[Key collision]** ALT+O/M might conflict with application-level shortcuts → Low risk since Hyprland captures at compositor level before apps see the event
34+
- **[Single monitor systems]** `monitor = "+1"` on single-monitor is a no-op (no crash, no error) → Graceful no-op by design
35+
- **[Maximize mode mismatch]** If `fullscreen({ mode = "maximize" })` doesn't behave as expected, fallback is `fullscreen({ mode = "maximized" })` → Easy tweak, single constant change at module top
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
## Why
2+
3+
Hyprland currently lacks dedicated keybindings for window-to-monitor movement and window maximize. The user needs quick keyboard shortcuts to move the active window between monitors (ALT+O) and maximize it (ALT+M) without reaching for the mouse or relying on workspace-based workflows.
4+
5+
## What Changes
6+
7+
- Add new `configs/binds/monitor.lua` sub-module with two keybindings:
8+
- **ALT + O**: Toggle active window between monitors (cycles forward with 3+ monitors)
9+
- **ALT + M**: Maximize active window (fill workspace area, keep bar visible)
10+
- Define all modifier keys as module-level constants (no inline strings)
11+
- Load via `configs/binds.lua` orchestrator in existing require chain
12+
- No changes to existing binds, no config files, no DMS IPC
13+
14+
## Capabilities
15+
16+
### New Capabilities
17+
- `monitor-binds`: Two keybindings for monitor-level window management — move to other monitor and maximize
18+
19+
### Modified Capabilities
20+
*(none — this is purely additive, no existing capability changes)*
21+
22+
## Impact
23+
24+
- **New file**: `configs/binds/monitor.lua` (~30 lines)
25+
- **Modified file**: `configs/binds.lua` — add one `require("configs.binds.monitor").register(mainMod)` line
26+
- **Zero impact** on existing bindings, workspaces, DMS IPC, or Hyprland config
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
## ADDED Requirements
2+
3+
### Requirement: Toggle window between monitors
4+
The system SHALL bind ALT+O to toggle the active window between monitors. If the window is on monitor 1, it moves to monitor 2. If pressed again, it moves back to monitor 1.
5+
6+
#### Scenario: Toggle from primary to secondary
7+
- **WHEN** user presses ALT+O with an active window on the primary monitor
8+
- **THEN** the window moves to the secondary monitor
9+
10+
#### Scenario: Toggle back to primary
11+
- **WHEN** user presses ALT+O again with the window now on the secondary monitor
12+
- **THEN** the window moves back to the primary monitor
13+
14+
#### Scenario: Cycle forward with 3+ monitors
15+
- **WHEN** user presses ALT+O on a system with three or more monitors
16+
- **THEN** the window moves forward to the next monitor in the list (1→2→3→1)
17+
18+
#### Scenario: No-op on single monitor
19+
- **WHEN** user presses ALT+O on a system with only one monitor connected
20+
- **THEN** no change occurs (graceful no-op, no error)
21+
22+
### Requirement: Maximize active window
23+
The system SHALL bind ALT+M to maximize the active window, filling the workspace area while keeping the bar/panel visible.
24+
25+
#### Scenario: Maximize tiled window
26+
- **WHEN** user presses ALT+M on a tiled window
27+
- **THEN** the window expands to fill the workspace (excluding panel/bar area)
28+
29+
#### Scenario: Maximize floating window
30+
- **WHEN** user presses ALT+M on a floating window
31+
- **THEN** the window snaps to fill the workspace (excluding panel/bar area)
32+
33+
#### Scenario: Toggle maximize off
34+
- **WHEN** user presses ALT+M on an already-maximized window
35+
- **THEN** the window returns to its previous size and position
36+
37+
### Requirement: Key constants
38+
All modifier keys SHALL be defined as module-level constants at the top of the file, not inlined in bind registration calls.
39+
40+
#### Scenario: Constants precede usage
41+
- **WHEN** reading the monitor.lua module
42+
- **THEN** all modifier key strings are defined as local constants before any `hl.bind()` call
43+
44+
### Requirement: Integration with orchestrator
45+
The module SHALL export a `register(mainMod)` function following the existing sub-module convention, loaded by `configs/binds.lua`.
46+
47+
#### Scenario: Module loaded on startup
48+
- **WHEN** Hyprland starts with `require("configs.binds").register(mainMod)` in the load chain
49+
- **THEN** the ALT+O and ALT+M bindings are active
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
## 1. Create monitor.lua sub-module
2+
3+
- [x] 1.1 Create `configs/binds/monitor.lua` with ALT and SUPER constants at module top
4+
- [x] 1.2 Add ALT+O bind using `hl.dsp.window.move({ monitor = "+1" })` (toggle/cycle between monitors)
5+
- [x] 1.3 Add ALT+M bind using `hl.dsp.window.fullscreen({ mode = "maximize" })`
6+
7+
## 2. Register in orchestrator
8+
9+
- [x] 2.1 Add `require("configs.binds.monitor").register(mainMod)` to `configs/binds.lua`
10+
11+
## 3. Verify
12+
13+
- [x] 3.1 Run `task validate` for pre-commit hooks
14+
- [x] 3.2 Verify Lua syntax with `luac -p` or `stylua --check`

0 commit comments

Comments
 (0)