Skip to main content

client

A client is one application window. The client global is the class: it carries the class-level signal bus, the focus field, and the history helpers, while each mapped window is an instance you read, write, and call methods on.

client.on("map", function(c)
if c.app_id == "mpv" then
c.floating = true
c.ontop = true
end
end)

kiln.key { mods = { "mod" }, key = "q", press = kiln.focused(function(c)
c:close()
end) }

Properties

Computed properties

These are backed by getters and setters, not plain storage.

PropertyTypeDefaultDescription
tagtag or nilnilSugar for c.tags[1]. Read returns the first tag; write means c.tags = {t} (nil writes {}).
tagslist of tags{}The membership write. Assigning diffs old against new, updates each tag's clients list, emits tagged/untagged per tag, then property::tags. Read/write.
screenscreen or nilderivedThe first tag's screen. Derived on every read, never stored. Read only.
parentclient or nilderivedThe client object for transient_for (a dialog's parent), else nil. Read only.

Protocol-seeded properties

Written by the compositor when the window maps or its metadata changes. Read them freely; most are facts, not knobs.

PropertyTypeDefaultDescription
handlenumberseededThe C-side identity. Key for core.client.* and core.surface.
x, y, width, heightnumberseededGeometry facts. Updated on map and on every size commit.
app_idstringseededWayland app id.
titlestringseededWindow title.
class, instancestringX11 onlyThe X11 WM_CLASS pair.
pidnumberX11 onlyProcess id, when the client reports one.
transient_fornumber or nilseededParent handle for dialogs. Prefer c.parent for the object.
window_typelist of stringsX11 only_NET_WM_WINDOW_TYPE atoms, in client order.
rolestring or nilseededX11 window role.
iconstring or nilseededIcon name or path.
override_redirectbooleanX11 OR onlyTrue for override-redirect windows (menus, tooltips). No rules, no titlebar or border, no focus-on-open.
wants_focusbooleanX11 OR onlyWhether an override-redirect window takes focus, per the ICCCM answer.
mappedbooleantrue on mapLiveness. Maintained by the map/unmap handlers.

Policy properties

Written by the standard library, rules, or your config. All read/write, all emit property::<name>.

PropertyTypeDefaultDescription
floatingbooleanfalseOut of the tiled order; the layout declares the client as a float.
floattableseeded on mapThe floating box {x, y, width, height}. Replace the whole table; one write is one property::float.
fullscreenbooleanfalseThe write is the whole verb: a listener mirrors the protocol hint and redraws.
maximizedbooleanfalseSame shape as fullscreen.
minimizedbooleanfalseThe client stops being declared: not drawn, not hit, not focusable. Focus moves to the successor.
ontopbooleanfalseBand choice; read by the layout at declare time.
urgentbooleanfalseDrawn by the border. Set by requests, cleared by c:focus().
titlebarbooleanfalseWhether the titlebar row is declared.
stickybooleanfalseVisible on every tag of its screen.
no_focusbooleanfalseSet by a rule's focus = false; activation policy reads it.
bandstringunsetExplicit z-band override for the client's float ("below", "above", ...). Unset, the band derives from state: fullscreen while focused, above when ontop, else normal. See Nodes, floats, and bands.
note

There is no property allowlist. Any key you write on a client stores and emits property::<key> exactly like the built-in ones, so you can hang your own state off a client and listen for changes to it.

Which property writes redraw

Writes to floating, float, ontop, urgent, titlebar, sticky, title, app_id, and icon mark the client's screen dirty and redraw (so do fullscreen, maximized, and minimized, through their own listeners). Geometry writes do not: width and height are written on every size commit, and a redraw there would pin the screen at panel rate. A write outside the list still changes state and emits its signal, but draws nothing until the next frame; call kiln.dirty() if you need one now.

Methods

MethodDescription
c:raise()Move to the tail of every tag's client list, the top of the stack.
c:lower()Move to the head, the bottom of the stack.
c:swap(other)Exchange positions with other in every shared tag. For tiled clients this is "promote to master".
c:focus()The canonical focus: activates, clears urgent, sets screen.focused, emits focus.
c:close()Polite close (the xdg close request).
c:kill()Force kill. See the warning below.
c:toggle_fullscreen()Sugar for c.fullscreen = not c.fullscreen.
c:toggle_maximized()Sugar for c.maximized = not c.maximized.
c:toggle_minimized()Sugar for c.minimized = not c.minimized.
c:grab_move()Interactive move. Needs a held button, so call it from a button handler.
c:grab_resize(edges)Interactive resize from a compass edge ("n", "se", ...).
c:grab_resize_nearest()Interactive resize from the corner nearest the press.
c:move_to(target)Move to screen target's selected tag. Focus follows.
warning

c:kill() is the impolite path: SIGKILL for a Wayland client, xcb_kill_client for an X11 one. If you are coming from AwesomeWM, note that awesome's c:kill() is the polite close; in kiln the polite close is c:close().

Class functions and fields

MethodDescription
client.all()Deduplicated list of every client on every screen.
client.focusPlain field: the focused client or nil. Set by c:focus() and by unmap policy.
client.history()Read-only copy of the most-recently-used focus list, most recent first.
client.history.previous()The most recent mapped, non-minimized client that is not focused (the mod+Tab target).
client.on(name, fn) / client.off(name, fn)Class-level signals: catch a signal on every client.

Signals

SignalPayloadEmitted when
mapnoneA window maps. Properties are already seeded when this fires.
unmapnoneA window unmaps.
destroynoneA window is destroyed.
focusnoneThe client gains focus through c:focus().
taggedthe tagThe client joins a tag.
untaggedthe tagThe client leaves a tag.
property::tagsthe new listThe tag membership changed.
property::<any>new valueAny property write that changed the value.
mouse::enternoneThe pointer enters the client.
request::activate{valid, app_id}The client asks to be raised; valid means a seat-backed activation token.
request::configure{x, y, width, height}An X11 client asks to place or size itself.
request::urgentbooleanICCCM urgency changed.
request::fullscreenbooleanThe client asks for (or arrives in) fullscreen.
request::maximizebooleanSame, for maximized.
request::minimizebooleanSame, for minimized.
request::decoration_modemodeThe client states its preferred decoration mode.
request::closenoneA foreign toplevel (a taskbar) asks to close this client.

Two stock listeners ride the focus signal: one promotes the client in the focus history, one raises floating, fullscreen, and maximized clients (tiled clients are deliberately not raised, since their list position is their cell). Every request::* signal routes to the matching kiln.defaults.* policy, and each is replaceable wholesale; see defaults.

See also