Sweets
Configuration

Basic Configuration

Create, validate, and reload your Sweets Lua configuration

Sweets is configured in Lua. It loads the installed defaults first, then your personal file as an override.

Create a personal configuration

sweets --init-config

This creates ~/.config/sweets/sweets.lua with commented examples. It never overwrites an existing file, and it checks the result.

CommandResult
sweets --init-configCommented examples. Every default stays active.
sweets --init-config --fullA copy of every default to edit in place.
sweets --init-config PATHWrites to PATH instead.

A full copy overrides every setting it declares. Later changes to those defaults will not reach you. Delete the parts you do not change.

Put only the values you want to change in ~/.config/sweets/sweets.lua:

sweets.general({
    mod_key = "SUPER",
})

sweets.gaps({
    inner = 12,
    outer = 12,
    smart = true,
})

sweets.bind("MOD+D", "spawn", { "fuzzel" })

Do not edit the installed sweets.lua. Package upgrades and source installs replace it.

Load order

OrderFile
1PREFIX/share/sweets/sweets.lua — installed defaults
2~/.config/sweets/sweets.lua — yours, optional

PREFIX follows the binary. /usr/bin/sweets reads /usr/share/sweets/sweets.lua, /usr/local/bin/sweets reads /usr/local/share/sweets/sweets.lua. XDG_CONFIG_HOME is honored when set.

With neither file present, Sweets starts with built-in defaults and a small set of emergency bindings.

How the layers combine

Your file does not replace the installed one wholesale. Each API merges differently:

DeclarationMerge
Singleton sectionsYour fields override; omitted fields stay unchanged
Layout stylesOverlays fields for the same layout only
Key bindingsReplaces the same key; sweets.unbind removes it
Environment entriesReplaces the same variable name
Monitor and workspace rulesReplaces the rule for the same connector or number
Window and layer rulesInstalled rules run first, yours append
Input selectorsGlobal block overlays; selector rules append
Startup commandsBoth layers run, installed first
AnimationsYour fields overlay the installed timing

A singleton such as sweets.general, sweets.layout, or sweets.gaps may be declared once per layer. Declaring one twice in the same layer, includes counted, is an error.

Validate

sweets --check-config              # installed and personal together
sweets --check-config ./test.lua   # one file on its own

A successful check prints the resolved path and exits 0. Syntax errors, unknown fields, wrong types, duplicate declarations, and unsafe include paths exit nonzero with the failing source and message. Neither form opens a Wayland socket.

Reload

Sweets watches the installed file, your file, and every included file, and reloads on save. To reload manually, press MOD+Shift+R or run:

sweets msg reload

A reload is all or nothing. A rejected candidate leaves the last valid configuration active and shows the error on every monitor until you fix it.

Inspect the active path, generation, and latest error:

sweets msg config

Individual pages note when a valid reload affects only future actions or future windows.

The sweets table

The global sweets table is the only API available to your configuration.

CallConfigures
sweets.generalModifier, background, workspace mode, cross-monitor policy
sweets.xwaylandPrivate rootless XWayland startup
sweets.layoutLayout defaults, master position, insertion, cycling
sweets.layout_stylePer-layout appearance overrides
sweets.gaps, sweets.border, sweets.window, sweets.specialGaps, borders, corners, special-workspace appearance
sweets.notifyConfiguration-error bar appearance
sweets.keyboard, sweets.cursorXKB, repeat, Num Lock, cursor theme
sweets.pointerAutomatic pointer-follow behavior
sweets.inputGlobal and per-device libinput settings
sweets.gesture, sweets.gesturesTouchpad swipe actions and recognition policy
sweets.bind_switchLid and tablet-mode bindings
sweets.monitorMode, scale, transform, position, adaptive sync
sweets.workspaceWorkspace-to-monitor pins
sweets.window_ruleOpening behavior and appearance for matching windows
sweets.layer_ruleAppearance for matching layer-shell surfaces
sweets.blurGlobal backdrop-blur policy
sweets.shadowGlobal drop-shadow policy
sweets.animationsWindow and workspace transitions
sweets.curveNames a curve for reuse
sweets.envEnvironment for programs Sweets launches
sweets.exec_oncePrograms started once per session
sweets.bind, sweets.unbindKey bindings and sequences
sweets.includeAdditional Lua files

Unknown names and fields are rejected.

Strict globals

Reading an undeclared global rejects the configuration. This catches typos that Lua would otherwise turn into a silently absent field:

local enabled = true
sweets.pointer({ follow_focus = enabled })  -- valid

sweets.input({ natural_scroll = falsed })   -- error: unknown global `falsed`

Declare variables before reading them. An explicit nil still omits the entry as usual.

Sandbox

Lua functions, loops, tables, and the string, table, math, and utf8 libraries are available. Filesystem, process, and native-module access is not: io, os, package, require, debug, dofile, loadfile, load, pcall, xpcall, collectgarbage, and print are all removed.

Use sweets.include instead of require, and sweets.exec_once or a spawn binding to start programs. Commands are argument arrays and are never passed to a shell.

Each load is bounded:

LimitValue
Instructions5 million
Evaluation time250 ms
Memory16 MiB
Call depth128
Sources / include depth32 / 16
Per file / all files256 KiB / 512 KiB

Exceeding a limit rejects the configuration like any other error. Numbers must be finite; math.huge and 0/0 are rejected.

Next steps

On this page