Architecture
SomeWM uses a three-layer architecture inherited from AwesomeWM. Understanding this separation helps you know where to make changes and what's possible.
The Three Layers
┌─────────────────────────────────────┐
│ User Configuration │ ~/.config/somewm/rc.lua
│ (Customization) │ ~/.config/somewm/theme.lua
├─────────────────────────────────────┤
│ Lua Libraries │ awful.*, gears.*, wibox.*
│ (Default Behavior) │ naughty, beautiful, ruled
├─────────────────────────────────────┤
│ C Core │ Compositor, wlroots bindings
│ (Primitives) │ Wayland protocols
└─────────────────────────────────────┘
C Core (Primitives)
The C core is the compositor itself. It handles:
- Wayland protocols - communicating with applications
- wlroots integration - rendering, input, output management
- Core objects - clients, screens, tags, drawins (raw wibox)
- Input handling - keyboard and pointer event routing
- Lua bindings - exposing objects and functions to Lua
You don't modify the C core. It provides primitives that the Lua layers build upon.
What C provides to Lua:
client- window objects with properties likename,floating,geometryscreen- display objects withgeometry,workarea,tagstag- workspace objectsawesome- global functions likerestart(),quit(),emit_signal()root- root window functions for global keybindings
Lua Libraries (Default Behavior)
The Lua libraries provide sensible defaults and convenience functions. These are copied from AwesomeWM and live in SomeWM's installation directory.
| Library | Purpose |
|---|---|
awful.* | Window management, keybindings, layouts, spawning |
gears.* | Utilities: timers, shapes, filesystem, tables |
wibox.* | Widget system: primitives, containers, layouts |
beautiful | Theming system |
naughty | Notifications |
ruled | Rules for clients and notifications |
Don't modify these files directly. They're part of the SomeWM installation and will be overwritten on updates. Instead, override their behavior from your config.
User Configuration
Your configuration lives in ~/.config/somewm/ and consists of:
rc.lua- Main configuration: keybindings, tags, rules, layouttheme.lua- Colors, fonts, spacing, widget appearances
Your config uses the Lua libraries to customize behavior:
-- rc.lua uses awful.key from the Lua libraries
awful.keyboard.append_global_keybindings({
awful.key({ "Mod4" }, "Return", function()
awful.spawn("alacritty")
end),
})
How Layers Communicate
The layers talk to each other through three mechanisms:
Signals
Signals are events that flow from C to Lua (or between Lua objects). When something happens, a signal fires and your callbacks run.
-- C emits "manage" when a new window appears
client.connect_signal("manage", function(c)
-- Your Lua code reacts
c.border_width = 2
end)
-- Objects emit property change signals
client.connect_signal("property::floating", function(c)
if c.floating then
c.ontop = true
end
end)
Common signal patterns:
object.connect_signal("name", callback)- subscribe to eventsobject.emit_signal("name", ...)- send custom signalsproperty::Xsignals fire when property X changes
Properties
Properties are readable/writable attributes on objects. Setting a property from Lua tells C to make a change.
-- Read a property
local name = c.name
local is_floating = c.floating
-- Write a property (C applies the change)
c.floating = true
c.maximized = false
c.geometry = { x = 100, y = 100, width = 800, height = 600 }
Properties are the main way to control objects. When you write c.floating = true, Lua tells the C core to update the window state.
Methods
Methods are functions you call on objects to perform actions.
-- Client methods
c:kill() -- Close the window
c:move_to_tag(tag) -- Move to a tag
c:move_to_screen(s) -- Move to a screen
c:raise() -- Bring to front
-- Tag methods
t:view_only() -- Show only this tag
t:clients() -- Get clients on this tag
Startup Order
When SomeWM starts, things happen in this order:
- C core initializes - compositor starts, wlroots sets up displays
- Lua VM starts - embedded Lua interpreter begins
- Built-in libraries load - awful, gears, wibox become available
- rc.lua executes - your configuration runs top-to-bottom
beautiful.init()- theme loads (should be early in rc.lua)- Screen signals fire -
request::desktop_decorationfor each screen - Existing windows appear -
managesignal for any pre-existing clients - Event loop starts - compositor is now running
Your rc.lua runs once at startup (and again if you reload config). Code at the top level executes immediately; signal callbacks run later when events occur.
-- This runs immediately at startup
print("Config loading...")
-- This runs later, for each screen
screen.connect_signal("request::desktop_decoration", function(s)
-- Create wibar, tags, etc.
end)
-- This runs later, when windows appear
client.connect_signal("manage", function(c)
-- Configure new windows
end)
Where Things Live
When you want to change something, here's where to look:
| Want to change... | Look in... | Using... |
|---|---|---|
| Keybindings | rc.lua | awful.keyboard.append_global_keybindings |
| Colors and fonts | theme.lua | beautiful variables |
| Layouts | rc.lua | awful.layout.layouts table |
| Window rules | rc.lua | ruled.client.append_rule |
| Tags (workspaces) | rc.lua | awful.tag() |
| Wibar (panel) | rc.lua | awful.wibar{} inside screen signal |
| Notifications | rc.lua | naughty.config / ruled.notification |
| Input settings | rc.lua | awful.input properties |
Example: Tracing a Keybind
Here's how a keypress flows through the layers:
- C Core - wlroots receives keyboard event from Wayland
- C Core - Event matches a registered keybinding
- Lua callback - Your
awful.keycallback function runs - Lua libraries -
awful.spawn()forks a process - C Core - New window appears via Wayland
- Lua callback -
managesignal fires, you apply rules
-- You define this in rc.lua (User Configuration layer)
awful.key({ "Mod4" }, "Return", function()
-- This uses awful.spawn (Lua Libraries layer)
awful.spawn("alacritty")
-- C Core handles the actual process spawning
end)
See Also
- The Object Model - Understanding screens, tags, clients, widgets
- AwesomeWM Compatibility - How SomeWM maintains compatibility
- Basics - Put these concepts into practice