Sweets
Configuration

Visual Effects

Live window and layer opacity, optimized or true scene blur, and standard client-controlled surface alpha.

The opacity, blur, blur_mode, and nested popups properties of sweets.window_rule({ ... }) apply compositor-side appearance to managed Wayland and XWayland windows. They use the same retained initial identity and ordered rule set as opening properties, but resolve live: a valid reload updates windows that are already open without rerunning placement or focus.

sweets.layer_rule({ ... }) exposes the same appearance fields for layer-shell roots, using exact namespace and current layer identity instead of window metadata.

sweets.window_rule({
  backend = "xdg",
  app_id = "foot",
  opacity = 0.88,
})

sweets.window_rule({
  backend = "xwayland",
  app_id = "XTerm",
  opacity = 0.92,
})

Matchers and appearance

Every appearance-only rule requires at least one matcher and one appearance property. A window rule may also combine these fields with opening properties.

FieldTypeMeaning
backendstringExactly "xdg" or "xwayland"
app_idstringXDG app ID, or X11 class for XWayland
titlestringInitial window title
dialogbooleanInitial dialog fact
transientbooleanInitial parent or transient-for fact
opacitynumberFinite whole-content opacity from 0.0 through 1.0
blurbooleanForce or suppress blur for the matching managed window
blur_modestringPer-window mode override: "optimized" or "scene"
popupstableDescendant XDG popup opacity, blur, and blur_mode

Matching strings are exact and case-sensitive. When several rules match, a later value replaces the earlier value for only the property it declares. Unmatched windows use opacity 1.0 and do not request blur. Installed rules run first and personal rules append afterward.

Opening-only, appearance-only, and combined declarations share one limit of 128 window rules and 32 KiB of retained matcher and opening-policy text.

Layer rules use an independent 128-rule and 32-KiB budget. Their opacity covers the layer root and ordinary subsurfaces, while independent XDG popups remain outside the multiplier. See Layer Rules for the live identity, ordering, and popup boundaries.

What becomes transparent

Opacity multiplies the managed root and all of its ordinary subsurfaces once. That means the complete application content—including text, images, and the application background—becomes translucent together.

The compositor border and independent role popups stay outside this multiplier. Use the nested popups table to give descendant XDG popup trees their own opacity and blur policy. Popup opacity does not multiply the root's opacity. A value of 0.0 makes the selected content invisible but does not unmap it: keyboard focus, pointer hit testing, popup grabs, and compositor operations continue normally.

Client background alpha and Sweets whole-content opacity multiply. A Foot background pixel at 0.70 client alpha with opacity = 0.75 produces effective alpha 0.525. Fully opaque text from the same Foot window becomes 0.75 alpha.

Sweets does not alter client buffers. An opaque application becomes uniformly translucent when window-rule opacity matches; an application such as Foot that already draws a transparent background keeps that internal alpha distinction.

Backdrop blur

Blur is a separate opt-in from transparency. Enable the renderer globally, then enable it for matching windows:

sweets.blur({
  enabled = true,
  mode = "optimized",
  strength = 8,
  noise = 0.02,
})

sweets.window_rule({
  app_id = "foot",
  blur = true,
})
Global fieldTypeMeaning
enabledbooleanMaster switch; default false
modestringBackdrop source: "optimized" or "scene"; default "optimized"
strengthintegerStable level from 1 through 15; default 8
noisenumberFinite premultiplied noise from 0.0 through 0.25; default 0.02

optimized prepares one shared blurred background per active output from its clear color plus background and bottom layer surfaces. It intentionally ignores ordinary windows and top/overlay content, so several blurred windows share one low-cost source. scene samples the framebuffer immediately below each blurred window. It therefore includes the wallpaper, bottom/background layers, and ordinary windows below, in the same stacking order shown on screen. It never samples the window that owns the effect or anything above it. Multiple overlapping blurred windows consequently build on one another in deterministic scene order. Sampling stops at the effect's physical bounds, so a neighboring window across a gap cannot bleed into its blurred edge.

Forced window blur follows the presented content geometry and its effective rounded corners. Forced layer blur follows the arranged layer-root geometry. A layer rule can set blur_ignore_alpha from 0.0 through 1.0 to suppress forced blur beneath client pixels at or below that alpha. The comparison uses client alpha before whole-root rule opacity. Omitting it preserves the complete arranged geometry. A matching window or layer rule can set blur = false to suppress an earlier matching rule. blur_mode overrides the global mode for only that owner. An application that already draws transparent pixels, such as Foot, remains merely transparent unless it requests blur or matching window-rule appearance properties explicitly enable blur.

Client-requested blur regions

Sweets advertises ext_background_effect_manager_v1 version 1 with only its blur capability. A native Wayland client can attach one background-effect object to one of its surfaces and commit an exact blur region. Region add and subtract operations, disjoint pieces, and an explicitly empty region are preserved; destroying the source wl_region after the request is safe because the request copies it. A change becomes visible only with the associated wl_surface commit.

Requests work on ordinary managed XDG roots and subsurfaces, XDG popups, and layer-shell roots, subsurfaces, and popups that participate in the normal scene. Cursor surfaces, drag icons, input-method surfaces, unmanaged X11 surfaces, and secure lock surfaces do not receive backdrop effects. Sandboxed security-context clients do not see this global.

The global enabled switch still controls every effect. For a managed window, blur = false vetoes requests in its subtree. Otherwise a non-empty committed client region wins with its exact shape; blur = true supplies the rounded managed-window shape only when no non-empty client request is present. The window's blur_mode applies to both forms. A matching layer rule provides the same force, veto, and mode policy for its root and ordinary subsurfaces. Role popups remain independent and use their nested popup policy.

For popup trees, a non-empty client region also wins over forced geometry. popups.blur = false vetoes the request. The global master gates every form. Popup opacity affects client content, while the backdrop remains fully filtered. popups.corner_radius clips the backdrop effect to an explicitly configured popup shape; it does not clip the client's content or input region.

Disabling blur does not erase committed client requests, so re-enabling it on reload takes effect without client resubmission. Destroying the effect object queues removal for the next surface commit. Processing is bounded to 256 region operations and 256 resulting rectangles; a more complex request is ignored with one warning rather than disconnecting the client or creating unbounded render work.

Client-controlled surface opacity

Sweets advertises the standard staging alpha-modifier-v1 protocol as wp_alpha_modifier_v1 version 1. A Wayland client can attach a constant alpha multiplier to one of its own wl_surface objects and commit a new value without reattaching or damaging its buffer.

The protocol value is surface-local. Changing a root surface does not change an independent subsurface or popup; each surface that wants a multiplier owns its own protocol object. By contrast, matching Sweets window-rule opacity is deliberate whole-window policy and supplies its opacity to the complete managed root and ordinary subsurface tree. The final alpha is:

client pixel alpha × client surface multiplier × Sweets window/layer opacity

Every factor is applied once. Destroying the modifier object restores its unspecified/unit value on the next surface commit. Invalid duplicate objects or requests after surface destruction are protocol errors for only the offending client.

The protocol remains available to security-context clients because it can modify only surfaces owned by that client; it provides no observation or cross-client control.

Reload and capture behavior

On every valid configuration reload, Sweets resolves all current managed windows and layer roots from their typed identities, compares the effective old and new appearance, then installs each complete new rule snapshot atomically. An opacity change cannot configure, move, resize, focus, restack, dismiss a popup, disturb its grab, or rerun opening rules. Title and app-ID updates after opening do not continuously restyle the window. A committed layer-shell layer change does re-resolve layer rules because current layer is part of that protocol identity; namespace remains fixed.

The appearance survives workspace hiding, minimize and restore, unmap and remap, output moves, and XWayland surface association. A changed visible value damages the complete affected region once. Blur strength, noise, mode, and the master switch are live too. The same effective values schedule no frame, and static translucent or blurred windows do not create a continuous redraw source.

When a resize, layout, fullscreen, workspace, or output move is waiting for client buffers, opacity, blur, rounded masks, stacking, and geometry all remain on the same last complete presentation. A valid appearance or blur reload updates an open held window once at that held geometry without restarting the move. Popups keep their held parent coordinates and their own opacity.

Closing a tiled transparent or blurred window replaces its live tree with one renderer-owned snapshot of the last displayed client and border pixels. The desktop backdrop is not baked into that snapshot: Sweets retains the forced rounded blur or exact client-requested regions as separate elements immediately below it. Snapshot and effects are released together, and the live surface is never composed in the same slot, avoiding a darker double-opacity frame.

Output capture observes the same composed blur and transparency shown on screen. Isolated window capture retains the selected window's effective alpha but intentionally excludes wallpaper, neighboring windows, and backdrop blur.

Opacity below 1.0 or an active blur effect makes the output ineligible for direct primary-plane scanout because it must be composed with content behind it. These restrictions do not by themselves disable the hardware cursor plane. Removing the effects restores the existing primary-plane eligibility path when all other gates pass.

Invalid types, non-finite numbers, values outside 0.0..=1.0, unknown fields, or missing matchers/properties in either rule namespace reject the complete reload and retain the last valid appearance.

On this page