| 1 |
# Mouse |
| 2 |
|
| 3 |
tarmac supports several mouse-driven interactions alongside its keyboard focus. |
| 4 |
|
| 5 |
## Click to focus |
| 6 |
|
| 7 |
Clicking any window focuses it. This works for both tiled and floating windows and is always enabled. |
| 8 |
|
| 9 |
tarmac intercepts mouse events via a CGEventTap in listen-only mode (it observes clicks without consuming them). When a left-click is detected, tarmac determines which window is under the cursor and focuses it. |
| 10 |
|
| 11 |
## Focus follows mouse |
| 12 |
|
| 13 |
When enabled, hovering the cursor over a window focuses it automatically — no click required. |
| 14 |
|
| 15 |
```lua |
| 16 |
gar.set("focus_follows_mouse", "true") -- enabled (default) |
| 17 |
gar.set("focus_follows_mouse", "false") -- disabled |
| 18 |
``` |
| 19 |
|
| 20 |
### Cooldown |
| 21 |
|
| 22 |
Focus-follows-mouse has a 500ms cooldown to prevent rapid refocusing. After a focus change, the mouse must hover over a different window for 500ms before another automatic focus change triggers. This prevents: |
| 23 |
|
| 24 |
- Accidental focus changes when moving the mouse across windows |
| 25 |
- Focus thrashing during drag operations |
| 26 |
- Rapid cycling when the cursor crosses a window boundary |
| 27 |
|
| 28 |
## Mouse follows focus |
| 29 |
|
| 30 |
When enabled, the cursor warps to the center of a newly focused window whenever focus changes via keyboard (e.g., `focus left`). |
| 31 |
|
| 32 |
```lua |
| 33 |
gar.set("mouse_follows_focus", "true") -- enabled (default) |
| 34 |
gar.set("mouse_follows_focus", "false") -- disabled |
| 35 |
``` |
| 36 |
|
| 37 |
This only triggers on keyboard-driven focus changes, not on mouse clicks. |
| 38 |
|
| 39 |
## Drag operations |
| 40 |
|
| 41 |
### Move floating windows |
| 42 |
|
| 43 |
Hold **Command** and **left-click drag** on a floating window to move it. |
| 44 |
|
| 45 |
### Resize floating windows |
| 46 |
|
| 47 |
Hold **Command** and **right-click drag** on a floating window to resize it. |
| 48 |
|
| 49 |
These use the macOS Command key directly (not the `mod_key` setting). They're implemented via the same CGEventTap that handles click-to-focus. |
| 50 |
|
| 51 |
> Note: drag operations only work on floating windows. Tiled windows cannot be dragged — use swap/resize keybinds instead. |
| 52 |
|
| 53 |
<img |
| 54 |
src="/cmd-drag.png" |
| 55 |
alt="tarmac Cmd+drag — repositioning a floating window on macOS" |
| 56 |
className="rounded-lg border border-surface-200 dark:border-surface-700 my-6 w-full" |
| 57 |
loading="lazy" |
| 58 |
/> |
| 59 |
|
| 60 |
## Mouse event tap |
| 61 |
|
| 62 |
tarmac uses a `CGEventTap` with `kCGEventTapOptionListenOnly` to observe mouse events system-wide. This means: |
| 63 |
|
| 64 |
- Mouse events are not consumed — they still reach the target application |
| 65 |
- No modifier keys are swallowed |
| 66 |
- The event tap is passive and has minimal performance impact |
| 67 |
|
| 68 |
The tap listens for: |
| 69 |
- Left mouse down (click-to-focus) |
| 70 |
- Left mouse drag with Command (move floating) |
| 71 |
- Right mouse drag with Command (resize floating) |
| 72 |
- Mouse moved (focus-follows-mouse) |
| 73 |
|