Skip to main content
Version: 2.1 (dev)

Shadows somewm-only

SomeWM provides built-in compositor-level shadows for windows and wiboxes. This replaces the need for external compositors like picom, which only work on X11.

Shadows are rendered using a smoothstep gradient falloff, displayed via the wlroots scene graph. They support full customization including color, blur radius, offset, and opacity.

What gets shadows?

This feature applies to clients (application windows) and drawins/wiboxes (containers like panels and popups). Individual widgets inside a wibox do not get separate shadows. For widget-level shadow effects, use Lua/Cairo drawing techniques.

Theme Variables​

Configure global shadow defaults in your theme.lua. Shadows are disabled by default and must be explicitly enabled.

Client Shadow Variables​

These control shadows for application windows (clients):

VariableTypeDefaultDescription
shadow_enabledbooleanfalseEnable shadows globally for clients
shadow_radiusinteger12Blur radius in pixels
shadow_offset_xinteger-15Horizontal offset (negative = left/behind window)
shadow_offset_yinteger-15Vertical offset (negative = up/behind window)
shadow_spreadinteger0Grow the shadow by this many pixels on every side before the blur
shadow_corner_radiusinteger0Round the shadow's corners by this many pixels
shadow_opacitynumber0.75Shadow opacity (0.0 = invisible, 1.0 = solid)
shadow_colorstring"#000000"Shadow color as "#RRGGBB" or "#RRGGBBAA" (alpha multiplies opacity)
note

shadow_clip from 2.0 is still accepted but has no effect since 2.1. The shadow is drawn at its offset and fades out on every side; sides fully covered by the window are simply not visible.

Drawin/Wibox Shadow Variables​

These control shadows for drawins and wiboxes (panels, popups, notifications). If not specified, they inherit from the client shadow settings.

VariableTypeDefaultDescription
shadow_drawin_enabledboolean(inherits from shadow_enabled)Enable shadows for drawins/wiboxes
shadow_drawin_radiusinteger(inherits from shadow_radius)Blur radius for drawins
shadow_drawin_offset_xinteger(inherits from shadow_offset_x)Horizontal offset for drawins
shadow_drawin_offset_yinteger(inherits from shadow_offset_y)Vertical offset for drawins
shadow_drawin_spreadinteger(inherits from shadow_spread)Spread for drawins
shadow_drawin_corner_radiusinteger(inherits from shadow_corner_radius)Corner radius for drawins
shadow_drawin_opacitynumber(inherits from shadow_opacity)Opacity for drawins
shadow_drawin_colorstring(inherits from shadow_color)Color for drawins

Theme Example​

-- In your theme.lua

-- Enable shadows for all windows
theme.shadow_enabled = true
theme.shadow_radius = 12
theme.shadow_offset_x = -15
theme.shadow_offset_y = -15
theme.shadow_opacity = 0.75
theme.shadow_color = "#000000"

-- Disable shadows for panels/wiboxes (optional)
theme.shadow_drawin_enabled = false

Client Properties​

client.shadow​

The shadow property controls shadows on individual clients.

Type: boolean or table

Access: Read/Write

When set to a boolean:

  • true - Enable shadow using theme defaults
  • false - Disable shadow for this client

When set to a table, you can override individual shadow parameters:

OptionTypeDescription
enabledbooleanEnable/disable shadow (default: true when table is provided)
radiusintegerBlur radius in pixels
offset_xintegerHorizontal offset
offset_yintegerVertical offset
spreadintegerGrow the shadow by this many pixels on every side before the blur
corner_radiusintegerRound the shadow's corners by this many pixels
opacitynumberShadow opacity (0.0-1.0)
colorstring or tableColor as "#RRGGBB"/"#RRGGBBAA" string or {r, g, b, a} table (values 0.0-1.0); alpha multiplies opacity

Examples:

-- Enable shadow with theme defaults
c.shadow = true

-- Disable shadow
c.shadow = false

-- Custom shadow configuration
c.shadow = {
radius = 8,
opacity = 0.5,
color = "#FF0000" -- Red shadow
}

-- Partial override (other values use theme defaults)
c.shadow = {
offset_x = -25,
offset_y = -25
}

-- Color as RGBA table
c.shadow = {
color = {0.5, 0.0, 0.5, 1.0} -- Purple
}

Reading Shadow Configuration​

When reading client.shadow, you receive:

  • false if shadows are disabled
  • A table with all current shadow settings if enabled
local s = c.shadow
if s then
print("Shadow enabled with radius:", s.radius)
print("Shadow color:", s.color)
else
print("Shadow disabled")
end

Drawin/Wibox Properties​

drawin.shadow​

The shadow property on drawins and wiboxes works identically to the client shadow property.

Type: boolean or table

Access: Read/Write

Examples:

-- Wibox with shadow
local mywibox = wibox {
width = 300,
height = 50,
visible = true,
shadow = true
}

-- Popup with custom shadow
local popup = awful.popup {
widget = mytextbox,
shadow = {
radius = 16,
opacity = 0.8
}
}

-- Notification-style glow effect
local notification_box = wibox {
width = 400,
height = 100,
shadow = {
color = "#3399FF",
radius = 20,
opacity = 0.6
}
}

Signals​

property::shadow​

Emitted when the shadow property changes on a client or drawin.

client.connect_signal("property::shadow", function(c)
if c.shadow then
print(c.name .. " now has shadows enabled")
end
end)

Using Rules​

shadow is settable from ruled.client like any client property:

ruled.client.append_rule {
rule = { class = "mpv" },
properties = { shadow = false } -- No shadows on video players
}

Runtime Control​

shadow is writable at runtime on any client or drawin, including over IPC:

somewm-client eval 'for _, c in ipairs(client.get()) do c.shadow = { radius = 24, opacity = 0.5 } end'

The Shadows guide has tested recipes (drop shadows, halos, glows, per-window rules) ready to copy.

Technical Notes​

  • The shadow is the window's frame grown by spread, moved by the offset, rounded by corner_radius, fading out over radius pixels on every side
  • It is rendered as a nine-patch (4 corner patches, 4 stretched edge strips, solid interior), so resizing never re-renders textures
  • Each shadow renders its own tiny gradient textures (a few KB total)
  • The falloff uses a smoothstep function that visually approximates Gaussian blur
  • Shadow nodes are placed below content in the wlroots scene graph

See Also​