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 coordinatesSize Values
{ size = "800x600" } -- Exact size
{ size = "50%" } -- 50% of screen
{ size = "1280 720" } -- Whitespace-separatedDynamic 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" })