Input Devices
Keyboard, cursor, and hardware-switch configuration.
These blocks configure keyboards and the pointer cursor image. Sweets can also run explicit commands for native hardware-switch transitions.
sweets.keyboard{ ... }
Keyboard settings apply to physical keyboards and re-apply on reload.
sweets.keyboard({
numlock = true,
repeat_rate = 25,
repeat_delay = 600,
layout = "us,lv",
variant = ",apostrophe",
options = "grp:alt_shift_toggle,caps:escape",
model = "pc105",
rules = "evdev",
})| Key | Type | Default | Description |
|---|---|---|---|
numlock | bool | true | Lock the numpad on at startup |
repeat_rate | int | 25 | Held-key repeats per second (0–1000); 0 disables repeat |
repeat_delay | int | 600 | Milliseconds before repeat begins (0–10000) |
layout | string | XKB default | XKB layout, or comma-separated such as us,lv |
variant | string | XKB default | XKB variant; empty entry for no variant, e.g. ,apostrophe |
options | string | XKB default | Comma-separated XKB options; "" clears them |
model | string | XKB default | XKB model, normally pc105 |
rules | string | XKB default | XKB rules file, normally evdev |
Sweets locks Num Lock on for each keyboard as it connects. Set numlock = false
to leave it off.
To make backspace clear faster, raise repeat_rate and lower repeat_delay —
for example repeat_rate = 50 and repeat_delay = 250.
layout, variant, options, model, and rules use standard XKB names.
Omit a field to keep the system default, normally from XKB_DEFAULT_*. Sweets
verifies the keymap compiles before accepting a reload, so an invalid layout
keeps the active config. Virtual keyboards keep the keymap from their client.
sweets.cursor{ ... }
Controls the pointer image size and xcursor theme.
sweets.cursor({
size = 24,
-- theme = "Adwaita",
})| Key | Type | Default | Description |
|---|---|---|---|
size | integer | 24 | Cursor size in logical pixels (1–256) |
theme | string | backend | Installed xcursor theme name |
Changes apply on hot reload. An unknown theme falls back to whatever the xcursor library resolves.
How client cursors follow
size and theme set the compositor-drawn cursor. They reach client cursors
two ways.
cursor-shape-v1 (preferred). Modern clients — Zed, recent GTK and Qt, SDL3
— ask for a named shape, and Sweets draws it from the configured theme at the
right size and per-output scale. These always match, including on fractionally
scaled outputs, and update live on reload.
XCURSOR_SIZE / XCURSOR_THEME (fallback). Clients that draw their own
xcursor read these env vars. Sweets exports them so spawned programs inherit a
matching cursor. They are read at startup, so only newly launched programs pick
up a change.
Some GTK/Electron/Firefox builds take the theme from GSettings via the desktop portal. If an app ignores both mechanisms above, set the same values there:
gsettings set org.gnome.desktop.interface cursor-theme 'breeze_cursors'
gsettings set org.gnome.desktop.interface cursor-size 24Sweets does not write GSettings itself, to avoid mutating global desktop
state. Clients drawing their own xcursor on a fractionally scaled output may
not multiply XCURSOR_SIZE by the scale, so their cursor can look small.
cursor-shape-v1 avoids this.
sweets.bind_switch(selector, "spawn", command)
Hardware switch events do nothing by default. Bind a direct argv command to a native libinput state transition:
sweets.bind_switch("lid:closed", "spawn", { "veila", "lock" })
sweets.bind_switch("lid:open", "spawn", { "notify-send", "Lid opened" })
sweets.bind_switch("tablet_mode:on", "spawn", { "wvkbd-mobintl" })
sweets.bind_switch("tablet_mode:off", "spawn", { "pkill", "wvkbd-mobintl" })| Selector | Trigger |
|---|---|
lid:closed / lid:open | Laptop lid closes or opens |
tablet_mode:on / tablet_mode:off | Convertible/tablet-mode switch changes |
Only the spawn action is accepted, and its command uses the same bounded,
no-shell argv format as a key binding. Multiple bindings may match one event
and launch independently in declaration order. Commands remain available while
the session is locked so an explicit lid-open or suspend policy still works;
the binding API itself exposes no compositor window action. The spawned program
is an explicit, trusted user policy choice.
Initial device state is recorded without running a command, and duplicate
reports are coalesced. A valid reload affects later transitions without
replaying the current state. sweets msg inputs reports observed switch types
and their on or off states. The nested backend has no physical switch
events.
Sweets does not lock, suspend, or alter output power automatically. Prefer one locker or policy command when locking must be securely established before display power changes. The current Smithay/libinput boundary exposes lid and tablet-mode events; keypad-slide bindings are not advertised.
Touchscreens and tablet tools
Touchscreen and tablet tool or pad routing are not currently implemented.