Binding Modes
A named binding set that replaces the global one until you leave it
sweets.mode(name, function) declares a named binding set. The mode action
switches to it, and it replaces the global bindings until you leave.
sweets.mode("resize", function()
sweets.bind("Left", "resize_shrink")
sweets.bind("Right", "resize_grow")
sweets.bind("Escape", "mode", "default")
end)
sweets.bind("MOD+R", "mode", "resize")Press MOD+R, then bare arrow keys resize the focused window. Escape returns
to the normal bindings.
The default set
default is the name of your global bindings. It is reserved, so a mode cannot
be called default, and mode "default" always means "go back".
Modes do not nest. A mode's bindings may only name default, so you always
enter from the global set and leave back to it.
Every mode must have a way out
A mode declaring no binding back to default is rejected, and so is a mode
action naming a mode you never declared. Both keep your previous configuration.
Getting unstuck
Three things always return you to the global bindings, whatever the mode binds:
| Escape hatch | How |
|---|---|
| Reload | MOD+Shift+R, which every mode inherits |
| Locking the screen | The lock screen always uses the global bindings |
| From a terminal | sweets msg reset-binding-mode |
Every mode also inherits the built-in bindings,
so MOD+Shift+R and MOD+Shift+Q work from inside one. If you forget how to
leave a mode, MOD+Shift+slash lists that mode's bindings.
What a mode does not change
Only bindings change. Windows, focus, layouts, and the pointer behave exactly as they do normally. Pointer and scroll bindings work inside a mode too:
sweets.mode("resize", function()
sweets.bind("Escape", "mode", "default")
sweets.bind_scroll("ScrollUp", "resize_grow")
sweets.bind_scroll("ScrollDown", "resize_shrink")
end)A key held across a mode change still releases cleanly, and a half-typed key sequence is cancelled when the mode changes.
The indicator
sweets.mode_indicator styles the pill naming the active mode. It is shown on
every monitor and is separate from the error bar.
sweets.mode_indicator({
position = "top_center",
margin = 16,
background = "#1C1F26E6",
text = "#FFFFFF",
accent = "#7AA2F7",
font = "Monospace 10",
})| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Whether an active mode is announced on screen |
position | see below | top_center | Which edge the pill sits against |
margin | 0–512 | 12 | Logical pixels between the pill and that edge |
background | #RRGGBB[AA] | #1C1F26E6 | Pill background |
text | #RRGGBB[AA] | #FFFFFF | Mode name colour |
accent | #RRGGBB[AA] | #7AA2F7 | Stripe down the left edge |
font | Pango font string | Monospace 10 | Mode name font |
position is top_left, top_center, top_right, bottom_left,
bottom_center, or bottom_right. A top position sits below the error bar
when one is showing.
The pill draws above applications and panels, appears in screen captures, is hidden by the lock screen, and does not reserve work area. A long mode name is shortened rather than allowed to span the screen.
Setting enabled = false leaves you with no on-screen sign that a mode is
active. Keep a mode "default" binding you remember.
Limits
Up to 16 modes. A name is 1–32 characters, starts with a letter, and holds only
letters, digits, _, and -. Each mode may hold up to 256 bindings.
Reading the active mode
sweets msg status reports it, so a status bar can show it:
sweets msg statusThe binding_mode field is absent while the global bindings are active.