My personal "Window Manager", based on Hammerspoon.
I dislike clicking and try to minimize clicks in common actions. To that end, I:
- use a trackpad (tap is better than click, but wait there's more)
- turn on three-finger drag
- use the awesome AutoRaise
To complement the above I wrote Win-Mouse and Win-Kbd.
Win-Mouse allows you to move windows by simply moving the mouse while holding down certain modifiers. No clicks or right-clicks are involved, no mouse buttons need to be held down, and there's no need to grab window corners or title-bars. Just hover anywhere over a window, and while holding down Ctrl
+Cmd
simply move the mouse.
The same can is done for resizing windows, with Ctrl
+Option
instead of Ctrl
+Cmd
.
(The keys are configurable, but the defaults are such because I find it convenient to switch between moving and resizing windows with just a tiny movement of my left thumb.)
While moving or resizing, window edges snap to screen edges, the screen's vertical and horizontal centers, and the edges of other windows.
(Win-Mouse is one reason why my iTerm2 windows have no title bar and the thinnest possible border. Not only does this look cleaner, it also saves desktop real-estate.)
win_mouse.mp4
Win-Kbd is the keyboard-only counterpart to Win-Mouse, operating on the focused window instead of the window under the mouse pointer.
Holding down Ctrl
+Cmd
and using the arrow keys moves the focused window along a 16x8 grid, while doing the same with Ctrl
+Option
instead resizes.
win_kbd.mp4
With a little from hidutils
, my CapsLock key is now a new modifier key which I call Hyper
.
Some variations define Hyper as pressing all four modifiers (Shift
, Ctrl
, Option
and Cmd
) together, but in my version Hyper is a unique new key in its own right (well, almost). One could a Hyper
-Shift
-k
hotkey (but read the note below).
Actually, my CapsLock key acts in two distinct ways:
- pressed by itself, without any other key, CapsLock acts as Esc. This is great because it's on the home row and large, of which Esc is neither.
- pressed together with other keys (but read the note below), CapsLock acts as
Hyper
+those-keys.
I use Hyper
for launching applications and performing systems tasks. E.g.:
Hyper
+b
launches a new Chrome window ("Browser")Hyper
+l
activate the screensaver ("Lock")
Note: as a modifier, Hyper
currently only supports a single non-modifier key together with it. This restriction will be lifted in the future.
hyper.mp4
Dark Background lets you decrease and increase the desktop wallpaper brightness. When the room is not well lit this can reduce glare and eye strain. (When in focus mode, I dim the wallpaper to the point where it is completely black, removing any visual distractions.)
The default keys are Ctrl
+Cmd
+-
/ Ctrl
+Cmd
+=
to decrease / increase the brightness.
Brightness is preserved across restarts.
dark_bg.mp4
Press Ctrl
+Cmd
+m
(for "Mouse") to draw a red circle around the mouse pointer for 3 seconds.
It's the same idea as "wiggling your mouse to make the mouse pointer large" in OxX, but much less annoying.
find_mouse_pointer.mp4
When activated, mouse clicks provide visual feedback in the form a circle around the mouse pointer; the circle remains visible as long as the mouse button remains pressed, and collapses into the mouse pointer when the mouse button is released. The circle is yellow for a left click and purple for a right click.
viz_mouse_clicks.mp4
a-la the excellent Key-Castr, but with:
- Support for (my) Hyper key
- Support for modifiers-only chords (e.g.
Cmd
-Ctrl
) - Easier (?) to tweak visualization
- Support for "linger time" for chords
Note: the functionality and visuals are basic, as this was written for recording the screencasts in this README. It can look nicer, and maybe one day it will.
The bread-and-butter dev-mode assistant: when files in ~/.hammerspoon
change, this will tell Hammerspoon to reload its init.lua
.
Click the Fenstr menubar widget for a list of plugins and the ability to enable/disable each. You can also launch the Settings and Hotkeys dialogs (see below).
The menubar widget itself is a plugin, and as such can be disabled.
Pressing Hyper
-,
shows the Settings dialog, where you can enable/disable individual plugins and set plugin configurations.
![settings_dialog](https://private-user-images.githubusercontent.com/1918551/385785484-3b9f92ff-c1dc-4636-8692-46da77fa6e15.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzM3OTgxNzIsIm5iZiI6MTczMzc5Nzg3MiwicGF0aCI6Ii8xOTE4NTUxLzM4NTc4NTQ4NC0zYjlmOTJmZi1jMWRjLTQ2MzYtODY5Mi00NmRhNzdmYTZlMTUucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MTIxMCUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDEyMTBUMDIzMTEyWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9MTEzMWViMjE0YmMzZDBlNWQ5ZTNlM2Q2NDQ2NTdlNjk0NjExOWZiYTAzNzkzOTM5MzZmMTY0ZDM0OGM1MWEyYyZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.yD2gDgqS4KY9_dIs0IfPFRoPiqQWkbPxbivXokio7X4)
Pressing Hyper
-.
shows the Hotkeys dialog, where you can record the hotkey combination for actions provided by the different plugins. A hotkey is a combination of zero or more modifiers and a single non-modifier key. (but see the note under "Hyper" regarding using it with other modifiers.)
An action with no bound hotkey shows as an empty slot with a dashed border.
Clicking a slot turns it red and start the recording. Clicking again cancels the recording.
![hotkeys_dialog](https://private-user-images.githubusercontent.com/1918551/385785584-e78c631f-8e5a-4044-9d18-e92e183113d3.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzM3OTgxNzIsIm5iZiI6MTczMzc5Nzg3MiwicGF0aCI6Ii8xOTE4NTUxLzM4NTc4NTU4NC1lNzhjNjMxZi04ZTVhLTQwNDQtOWQxOC1lOTJlMTgzMTEzZDMucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MTIxMCUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDEyMTBUMDIzMTEyWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9NzYzNzI2NjFjZWEwMjA5ODg0ZGM3NjFlMWE2OGU4YjEyZmQyMzQ5Y2UxNzc0ZTExOTUyOWFjZDllNTYxZTNlNiZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.dnWZZOTSxCybRuv9NOPbHr39kwWWdmFZBz78quPWvpU)
Simply:
git clone git@github.com:nitzan-shaked/fenstr.git ~/.hammerspoon
Feel free to open issues and submit PRs of any kind. Nothing too formal here.
The codebase uses the Lua Language Server, which I have installed as a VSCode extension; as such, rudimentary static type hints for the parts of Hammerspoon I use, the way I use them, live under types/
.
Under experimental/
you can find stuff I'm working on, which may one day graduate and become first-class features. Currently there are Live Preview (see experimental/live_preview.md
), some Tiling Window-Manager code, and a menubar widget for controlling the output volume.
Feel free to ignore both types/
and experimental/
.
My setup uses one monitor so the codebase is not well-tested on multi-monitor setups. Let me know.