Signals Reference
SomeWM is event-driven. The compositor and the AwesomeWM Lua libraries emit signals at lifecycle points; your rc.lua connects handlers to react. For the model behind signals (what they are, when C fires them, the request::* pattern, default handlers, ordering), see Signals (concepts).
This page is the lookup reference. Signals are grouped by the class or module that emits them.
Dispatch
The C-generated signals listed below are queued and drained at some_refresh(). Other C-generated signals and all Lua-emitted signals run synchronously. See Signals (concepts): Dispatch model for the model and the implications.
Currently queued:
- Property:
property::geometry,property::position,property::size,property::x,property::y,property::width,property::height,property::active - Focus:
focus,unfocus,client::focus,client::unfocus - Mouse:
mouse::enter,mouse::leave,mouse::move(coalesced per object) - Lifecycle:
list,swapped - Request:
request::activate,request::urgent - Systray:
request::secondary_activate,request::context_menu,request::scroll - Output:
property::enabled,property::scale,property::transform,property::mode,property::adaptive_sync,property::screen(screen attached), and the output classadded - Screen:
property::scale,property::geometry,property::workarea,primary_changed, and the screen classlistandproperty::_viewports - Layer shell:
property::layer,property::anchor,property::exclusive_zone,property::keyboard_interactive,property::margin - Globals:
xkb::map_changed,xkb::group_changed,idle::stop,dpms::on,spawn::timeout,spawn::completed,switch::toggle,screen::focus,client::map,client::unmap,client::property::geometry
The output and screen entries cover changes the compositor makes on its own: a monitor being
plugged or unplugged, or an external tool like wlr-randr or kanshi changing output state.
The equivalent changes made from Lua stay synchronous, so screen.fake_add, screen.fake_remove
and s:swap(...) still deliver list inline (s:swap delivers swapped inline too),
screen.primary = s still delivers primary_changed inline, and awesome.dpms_on() still
delivers dpms::on inline. property::workarea splits differently: the emitter driven by wibar
and client struts stays inline, so a wibar appearing notifies Lua immediately; only the
screen-geometry path queues, so it arrives after the property::geometry it follows.
property::geometry appears on both client and screen. The screen version carries the
previous geometry as a second argument; the client version carries none.
Everything else C emits, and every Lua-emitted signal, dispatches synchronously. The notable
synchronous survivors are request::manage and request::unmanage, screen added and
removed, output removed (and output property::screen when the screen is detached),
request::geometry, and the client scalar properties such as property::name
and property::fullscreen. request::focus_restore, scanning, scanned,
layer-surface lifecycle and keyboard requests, key and button callbacks,
grabber callbacks and D-Bus method handlers also run synchronously.
Two signals stay synchronous because a queued one would arrive too late to be useful.
idle::start is emitted just before your awesome.set_idle_timeout callback runs, so it has to
reach you first. logind::prepare_sleep is your window to lock the screen before the machine
suspends, and the event loop may stop before the next drain.
Signals queued against a screen or output that is then removed are dropped rather than
delivered, because a torn-down screen or output reports itself invalid. Reading any property
other than valid on one raises invalid object, and screen[s] returns nil for it.
State before a queued handler runs
The object may expose its new state before a queued handler updates a Lua cache. Immediately after a focus change, client.focus can name the new client while awful.client.focus.history.get and history.previous still reflect the previous focus event. Timer, IPC, D-Bus and keybinding callbacks can observe this interval. Code that needs the handler's result should defer that read until after the queue drains, for example with gears.timer.delayed_call.
The queue drains before refresh and the layout pass. XKB change signals also use the queue, so caches updated by their handlers may lag the keyboard state until that drain. Lua-emitted request::tag and request::select do not use this queue.
client signals
Emitted on the client class. Connect with client.connect_signal("name", handler) (no c argument: handlers receive whichever client the signal was emitted on).
Lifecycle
| Signal | Args | Notes |
|---|---|---|
request::manage | c, context, hints | A new client wants to be managed. Default handlers (in awful.permissions, ruled.client) tag it, place it, and apply rules. Connect after default handlers run if you want to read post-rule properties. context is "new" or "startup". |
request::unmanage | c, context, hints | The client is going away. Default handlers do final cleanup. context is "user", "reparented", or "destroyed". Don't access geometry or screen; they may already be invalid. |
scanning | none | Compositor is enumerating already-running clients before any are managed. ruled.client emits request::rules from here. |
scanned | none | Initial scan is complete. Fires before awesome.startup callbacks. |
Focus and stacking
| Signal | Args | Notes |
|---|---|---|
focus | c | Client gained focus. |
unfocus | c | Client lost focus. Fires before focus on the new client. |
raised | c | Client moved to top of its layer (see Client Stacking). |
lowered | c | Client moved to bottom of its layer. |
Properties
Each property::* fires after the property changes. Read the new value off the client.
| Signal | Notes |
|---|---|
property::name | Title changed. |
property::class | Class changed (rare; usually only at startup). |
property::geometry | Size or position changed. |
property::floating | Floating state toggled. |
property::fullscreen | Fullscreen toggled. |
property::ontop | Above-everything layer toggled. |
property::above | Above-normal layer toggled. |
property::below | Below-normal layer toggled. |
property::urgent | Urgency hint changed. Check c.urgent inside the handler; fires for both true and false. |
Requests
request::* signals ask handlers to do something. The default handler usually lives in awful.permissions and ships with sensible defaults; replace it by disconnect_signal plus your own connect_signal. See Replacing a default handler.
| Signal | Args | Notes |
|---|---|---|
request::activate | c, context, hints | Something asked for the client to become active (focused/raised). Default handler in awful.permissions.activate. |
request::titlebars | c, context, hints | Client should grow titlebars. Connect to draw them (or skip drawing to opt out). |
request::geometry | c, context, hints | Client (or another module) asked to be moved/resized. context says why ("maximized_horizontal", "fullscreen", etc.). |
request::tag | c, tag, hints | Client needs a tag (after creation, after losing its screen). Default handler: awful.permissions.tag. hints.reason can be "screen", "screen-removed", "rules". |
request::border | c, context, hints | Client wants its border restyled. Default handler: awful.permissions.update_border. context is one of "added", "active", "inactive", "floating", "urgent", "maximized", "fullscreen". |
request::urgent | c | Urgency hint set. Fires alongside property::urgent. |
request::default_keybindings | context (string) | Class signal emitted once at startup. Connect to register default keybindings via awful.keyboard.append_client_keybindings. |
request::default_mousebindings | context (string) | Class signal emitted once at startup. Connect to register default mousebindings via awful.mouse.append_client_mousebindings. |
screen signals
| Signal | Args | Notes |
|---|---|---|
added | s | New output connected. |
removed | s | Output disconnected. Tags on this screen will get request::screen next. |
request::desktop_decoration | s | Screen needs tags and wibars. Your handler creates them. See Tag Persistence. |
request::wallpaper | s | Screen wants its wallpaper drawn. The default handler builds it with awful.wallpaper. |
request::focus_restore | s | Something that had focus went away (client closed, layer surface dismissed, session unlocked, monitor disconnected). Default handler: awful.permissions.focus_restore, which activates the most recent visible client from focus history. If no handler focuses a client, C focuses the topmost client on the monitor. somewm-only |
property::geometry | s | Screen geometry changed (resolution or layout). |
property::workarea | s | Workarea (geometry minus struts) changed. Fires when wibars appear or resize. |
property::scale | s | Output scale changed. somewm-only |
property::outputs | s | Output metadata (model, make, refresh) changed. |
tag signals
Connect with tag.connect_signal("name", handler). Handlers receive the tag.
| Signal | Args | Notes |
|---|---|---|
request::screen | t, reason | Tag's screen was removed and it needs a new one. Default handler: awful.permissions.tag_screen. See Tag Persistence. |
request::default_layouts | context (string) | Class signal emitted once at startup. Connect to register layouts via awful.layout.append_default_layouts. |
property::selected | t | Tag was selected or deselected. |
property::activated | t | Tag was added to or removed from a screen. |
tagged | t, c | Client added to tag. |
untagged | t, c | Client removed from tag. |
ruled.client signals
Module-level signals on ruled.client. Connect with ruled.client.connect_signal(...).
| Signal | Args | Notes |
|---|---|---|
request::rules | none | Fires once on client.scanning, after all modules are loaded but before any client is managed. Append rules to ruled.client.rules here so every module gets a chance before client matching begins. See Defer startup with request::rules. |
ruled.notification signals
Module-level signals on ruled.notification.
| Signal | Args | Notes |
|---|---|---|
request::rules | none | Same shape as ruled.client request::rules. Append entries to ruled.notification.rules. |
naughty signals
| Signal | Args | Notes |
|---|---|---|
added | n | A notification was created. |
destroyed | n, reason | A notification was destroyed. reason matches naughty.notification_closed_reason.*. |
request::display | n | Naughty wants this notification rendered. Connect a handler that builds a notification widget. See Notifications. |
request::action_icon | a | An action wants its icon resolved. |
See the naughty reference for the full set.
Layer surface signals somewm-only
| Signal | Args | Notes |
|---|---|---|
request::manage | l, context, hints | A layer-shell surface appeared. |
request::unmanage | l, context, hints | A layer-shell surface is closing. |
request::keyboard | l, context, hints | Layer surface wants keyboard interactivity. |
property::has_keyboard_focus | l | Keyboard focus on the layer surface changed. |
See layer_surface reference for context.
Lock signals somewm-only
| Signal | Args | Notes |
|---|---|---|
lock::activate | source (string) | Session locked via awesome.lock(). source is always "user". |
lock::deactivate | none | Session unlocked. |
lock::auth_failed | none | Password authentication failed. |
Idle signals somewm-only
| Signal | Args | Notes |
|---|---|---|
idle::start | none | First idle timeout fired. |
idle::stop | none | Activity detected after being idle. |
property::idle_inhibited | none | Combined idle inhibition state changed. |
DPMS signals somewm-only
| Signal | Args | Notes |
|---|---|---|
dpms::off | none | At least one display entered sleep. |
dpms::on | none | At least one display woke up. |
See Lock, Idle, and DPMS reference.
awesome signals
Global signals on awesome.*. Connect with awesome.connect_signal(...).
| Signal | Args | Notes |
|---|---|---|
startup | none | SomeWM finished starting. Fires after client.scanned. Safe to assume all default handlers are connected. |
exit | restart (boolean) | SomeWM is shutting down. restart is true for a Lua hot reload in the same process. |
refresh | none | About to redraw. Avoid expensive work in this handler; it fires often. |
debug::error | msg | An uncaught Lua error occurred. Default handler logs to stderr. |
Example usage
-- React to new clients
client.connect_signal("request::manage", function(c, context, hints)
if c.floating then
awful.placement.centered(c)
end
end)
-- Add rules late, from a module
ruled.client.connect_signal("request::rules", function()
ruled.client.append_rule {
rule = { class = "Firefox" },
properties = { tag = screen.primary.tags[2] },
}
end)
-- Set default layouts at startup
tag.connect_signal("request::default_layouts", function()
awful.layout.append_default_layouts {
awful.layout.suit.tile,
awful.layout.suit.floating,
}
end)
See also
- Signals (concepts): what signals are, where they come from, and how
request::*plus default handlers work - Replacing a default handler
- React to client lifecycle
- Defer startup with
request::rules - AwesomeWM signals on
gears.object: the connect/emit/disconnect machinery