Skip to content

Window Rules

Window rules let you control how windows open — auto-float, move to workspace, resize, and more.

Basic Syntax

samwm.windowrule(
    { class = "Firefox" },       -- Match criteria
    { float = "true" }          -- Actions to apply
)

Match Criteria

Criterion Example Description
class { class = "Firefox" } Match by app class (WM_CLASS)
title { title = "Picture-in-Picture" } Match by window title
instance { instance = "gnome-calculator" } Match by instance name

Available Actions

Action Example Description
float { float = "true" } Make window floating
tile { tile = "true" } Force tiling (undo float)
fullscreen { fullscreen = "true" } Make window fullscreen
workspace { workspace = "2" } Move to workspace
size { size = "800x600" } Set window size
position { position = "center" } Set window position
opacity { opacity = "0.8" } Set window opacity
border { border = "false" } Hide window border

Examples

Float a Window

-- Float calculator
samwm.windowrule(
    { class = "gnome-calculator" },
    { float = "true" }
)

Move to Workspace

-- Open music in workspace 9
samwm.windowrule(
    { class = "Spotify" },
    { workspace = "9" }
)

Float and Center

-- Float and center dialogs
samwm.windowrule(
    { title = "Open Files" },
    { float = "true", position = "center" }
)

Set Size

-- Open terminal at specific size
samwm.windowrule(
    { class = "alacritty" },
    { size = "1280x720" }
)

Multiple Rules

Rules apply in order — later rules override earlier ones.

-- All browsers float
samwm.windowrule(
    { class = "Firefox" },
    { float = "true" }
)

-- Exception: Firefox DevTools tile
samwm.windowrule(
    { class = "Firefox", title = "Developer Tools" },
    { float = "false", tile = "true" }
)

Regex Matching

Match using patterns instead of exact strings:

-- Match anything starting with "Picture-in-Picture"
samwm.windowrule(
    { title = "~^Picture-in-Picture" },
    { float = "true" }
)
Prefix Meaning
~^ Regex: starts with
~$ Regex: ends with
~* Regex: contains
~= Case-insensitive match

Examples

-- Float all notification popups
samwm.windowrule(
    { title = "~*notification" },
    { float = "true" }
)

-- Tile any Picture-in-Picture window
samwm.windowrule(
    { title = "~^Picture-in-Picture" },
    { float = "false" }
)

Multiple Criteria

Combine criteria with AND logic — all must match:

-- Match Firefox with specific title
samwm.windowrule(
    { class = "Firefox", title = "~*Settings" },
    { float = "true" }
)

Action Stacking

Apply multiple actions in one rule:

-- Move to workspace 2, float, and set size
samwm.windowrule(
    { class = "Gimp" },
    {
        workspace = "2",
        float = "true",
        size = "1600x900",
        position = "center"
    }
)

Special Values

Position Values

{ position = "center" }      -- Center of screen
{ position = "cursor" }       -- At cursor position
{ position = "5,5" }         -- Pixel coordinates

Size Values

{ size = "800x600" }         -- Exact size
{ size = "50%" }             -- 50% of screen
{ size = "1280 720" }        -- Whitespace-separated

Dynamic Rules

Create rules programmatically:

-- Add rule from Lua
samwm.add_windowrule(
    { class = "my-app" },
    { float = "true" }
)

-- Remove rule
samwm.remove_windowrule({ class = "my-app" })

On-Demand Rules

Apply rules when windows open using event hooks:

samwm.on("window_open", function(window)
    if window.class == "mpv" then
        samwm.set_window_rule(window, { float = "true" })
    end
end)

Priority

Rules are checked in order. More specific rules should come after general ones:

-- General: all Firefox float
samwm.windowrule({ class = "Firefox" }, { float = "true" })

-- Specific: devtools tile
samwm.windowrule({ class = "Firefox", title = "~*Developer Tools" }, { float = "false" })