Hyprland hl.* Lua API Source of Truth

Complete reference for the hl global table exposed by Hyprland's Lua configuration system. Config file: ~/.config/hypr/hyprland.lua (since Hyprland 0.55).

1 Configuration — hl.config()

hl.config({ settings })

Set Hyprland configuration values. The argument is a nested table mirroring the old hyprland.conf variable groups.

All config keys from general, decoration, input, gestures, group, binds, debug, misc, dwindle, master, scrolling, ecosystem, etc. are available.

-- Example
hl.config({
  general = {
    gaps_in        = 5,
    gaps_out       = 10,
    border_size    = 2,
    "col.active_border"   = "rgba(ffffffcc) rgba(111111cc) 45deg",
    "col.inactive_border" = "rgba(595959aa)",
    layout = "dwindle",
  },
  decoration = {
    rounding = 10, active_opacity = 1.0, inactive_opacity = 1.0,
    shadow = { enabled = true, range = 4, color = "rgba(1a1a1aee)" },
    blur   = { enabled = true, size = 3, passes = 1 },
  },
  input = { kb_layout = "us", follow_mouse = 1, touchpad = { natural_scroll = false } },
  misc  = { disable_autoreload = true, disable_hyprland_logo = true, vfr = true },
})
hl.get_config(key) → value

Read the current value of a config key. Returns nil + error_msg if the key is unknown.

2 Monitor Setup — hl.monitor()

hl.monitor({ fields })

Define or override a monitor configuration. The output field is required. Multiple calls are cumulative.

FieldTypeDescription
outputstringMonitor name, e.g. "DP-1", "eDP-1"
modestringResolution & refresh, e.g. "1920x1080@144", "preferred", "highres", "highrr"
positionstringLayout position, e.g. "0x0", "auto-right", "auto-left"
scalenumber/stringScale factor, e.g. 1.0, "auto"
transformint (0-7)Display transform (0=normal, 1=90°, 2=180°, 3=270°, 4-7=flipped variants)
mirrorstringOutput name to mirror, or empty string
bitdepthint8 or 10
cmstringColor management, e.g. "srgb" (default) or "passthrough"
vrrint (-1 to 3)Variable refresh rate: -1=unset, 0=off, 1=on, 2=always, 3=fullscreen
disabledbooltrue to disable this output
reserved / reserved_areatable{ top, bottom, left, right } in CSS gap format
iccstringPath to ICC color profile
sdr_eotfstringSDR electro-optical transfer function
sdrbrightnessfloatSDR brightness (default 1.0)
sdrsaturationfloatSDR saturation (default 1.0)
supports_wide_colorint (-1/0/1)Override wide color support detection
supports_hdrint (-1/0/1)Override HDR support detection
sdr_min_luminancefloatMin SDR luminance (default 0.2)
sdr_max_luminanceintMax SDR luminance (default 80)
min_luminancefloatMin luminance (default -1 = auto)
max_luminanceintMax luminance (default -1 = auto)
max_avg_luminanceintMax average luminance (default -1 = auto)

3 Window Rules — hl.window_rule()

hl.window_rule({ name?, enabled?, match?, ...effects }) → rule_handle

Define a window rule. Named rules can be updated by calling hl.window_rule() again with the same name. Returns a handle with :set_enabled(bool).

Match criteria (inside match = { ... })

KeyTypeDescription
classstringWindow class regex
titlestringWindow title regex
initialClassstringClass at creation time
initialTitlestringTitle at creation time
tagstringTag regex
pidnumberProcess ID
addressstringWindow address (hex)
xwaylandboolXWayland window
floatboolFloating state
fullscreenboolFullscreen state
pinboolPinned state
workspacestringWorkspace selector
monitorstringMonitor selector
groupedboolIn a group
swallowingboolSwallowing state

Static effects (as top-level fields)

FieldTypeDescription
floatboolForce floating
tileboolForce tiling
fullscreenboolForce fullscreen
maximizeboolForce maximize
centerboolCenter on screen
contentstringContent type override
pseudoboolPseudo-tile
pinboolPin window
no_initial_focusboolDon't focus on open
fullscreen_statestringOverride fullscreen state string
movestringPosition expression e.g. "100 200" or "100 monitor_w-100"
sizestringSize expression e.g. "500x500" or "50% 50%"
monitorstringMove to monitor
workspacestringMove to workspace
groupstring"set", "unset", "toggle"
suppress_eventstringSuppress events (e.g. "maximize")
roundingint (0-20)Set rounding
border_sizeintSet border size
rounding_powerfloat (1-10)Rounding power
scroll_mousefloat (0.01-10)Mouse scroll speed multiplier
scroll_touchpadfloat (0.01-10)Touchpad scroll speed multiplier
scrolling_widthfloatScrolling layout window width
animationstringAnimation style name
idle_inhibitstring"none", "always", "focus", "fullscreen"
opacitystringOpacity override e.g. "0.9" or "0.9 0.8"
tagstringAssign a tag
max_sizestringMax size expression "WxH"
min_sizestringMin size expression "WxH"
border_colorstring/gradientBorder color/gradient override
persistent_sizeboolRemember size across state changes
allows_inputboolAllow input to window
dim_aroundboolDim area around window
decoratebool (default true)Show decorations
focus_on_activateboolFocus when activated
keep_aspect_ratioboolMaintain aspect ratio
nearest_neighborboolNearest-neighbor scaling
no_animboolDisable animations
no_blurboolDisable blur
no_close_forintNo close for N seconds
no_dimboolDisable dim
no_focusboolDon't focus automatically
no_follow_mouseboolDon't follow mouse focus
no_max_sizeboolIgnore max size hints
no_shadowboolDisable shadows
no_shortcuts_inhibitboolDon't allow shortcuts inhibit
opaqueboolForce opaque
force_rgbxboolForce RGBX format
sync_fullscreenboolSynchronize fullscreen states
immediateboolRender immediately (tearing)
xrayboolX-ray mode (pass-through blur)
render_unfocusedboolRender even when unfocused
no_screen_shareboolBlock screen sharing
no_vrrboolDisable VRR for this window
no_auto_hdrboolDisable auto HDR
stay_focusedboolKeep focus on this window
confine_pointerboolConfine pointer to window
tonemapstringTone mapping mode
-- Named rules can be toggled at runtime:
local rule = hl.window_rule({ name = "float-kitty", match = { class = "kitty" }, float = true })
-- rule:set_enabled(false)

4 Layer Rules — hl.layer_rule()

hl.layer_rule({ name?, enabled?, match?, ...effects }) → rule_handle

Define a layer surface rule. Match on namespace (regex) in the match table.

EffectTypeDescription
no_animboolDisable animation
blurboolEnable blur
blur_popupsboolBlur popups
ignore_alphafloat (0-1)Alpha threshold to ignore
dim_aroundboolDim around layer
xrayboolX-ray pass-through
animationstringAnimation style
orderintRender order override
above_lockint (0-2)Render above lock screen
no_screen_shareboolBlock screen sharing

5 Workspace Rules — hl.workspace_rule()

hl.workspace_rule({ workspace, monitor?, ...fields })

Assign workspace properties. The workspace field is a workspace selector string.

FieldTypeDescription
workspacestringWorkspace selector (e.g. "1", "name:code", "special")
monitorstringAssign workspace to monitor
defaultboolMark as default on its monitor
persistentboolKeep workspace alive when empty
gaps_inCSS gapInner gap override
gaps_outCSS gapOuter gap override
float_gapsCSS gapFloating window gap override
border_sizeintBorder size override
no_borderboolNo borders
no_roundingboolNo rounding
decorateboolShow decorations
no_shadowboolNo shadows
on_created_emptystringCommand to run when empty workspace is created
default_namestringDefault name for the workspace
layoutstringLayout plugin name ("dwindle", "master", etc.)
animationstringAnimation style override
layout_optstableLayout-specific options (string-keyed table of string/bool/number)
enabledboolEnable/disable the rule

6 Keybinds — hl.bind(), hl.unbind()

hl.bind(keys, dispatcher, opts?) → keybind_handle

Register a keybind. keys is a modifier-key string like "SUPER+SHIFT+Q". dispatcher is a closure from hl.dsp.* or a Lua function. Returns a handle with :set_enabled(bool).

Opt fieldTypeDescription
repeatingboolFire repeatedly while held
lockedboolWork when locked/inhibited
releaseboolFire on key release
clickboolFire on mouse click release
dragboolFire on mouse drag
non_consumingboolEvent passes through to window
auto_consumingboolAuto-consume key event
transparentboolTransparent to other binds
ignore_modsboolIgnore modifiers for matching
dont_inhibitboolDon't allow inhibition
long_pressboolFire on long press
submap_universalboolWork in all submaps
description / descstringHuman-readable description
devicetable{ inclusive = bool, list = { "dev1", "dev2" } }
hl.unbind(keys)

Remove a previously bound key. Pass "all" to clear all keybinds.

hl.define_submap(name, reset?, fn)

Define a submap. Inside fn, calls to hl.bind() are scoped to this submap. The optional reset string determines reset behavior.

-- Examples
hl.bind("SUPER+Q", hl.dsp.exec_cmd("kitty"))
hl.bind("SUPER+F", hl.dsp.window.float({ action = "toggle" }))
hl.bind("SUPER+SHIFT+left", hl.dsp.window.move({ direction = "left" }))
hl.bind("SUPER+left", hl.dsp.focus({ direction = "left" }))

-- With options
hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+"),
        { locked = true, repeating = true })

-- Submap example
hl.define_submap("resize", function()
  hl.bind("left",  hl.dsp.window.resize({ x = -10, y = 0 }))
  hl.bind("right", hl.dsp.window.resize({ x = 10, y = 0 }))
  hl.bind("Escape", hl.dsp.submap("default"))
end)
hl.bind("SUPER+R", hl.dsp.submap("resize"))

7 Dispatchers — hl.dsp.*

All hl.dsp.* functions return dispatcher closures — they do not execute the action directly. Pass the result to hl.bind() or hl.dispatch().

Top-level dispatchers

FunctionDescription
hl.dsp.exec_cmd(cmd)Spawn a shell command (applies window rules if available)
hl.dsp.exec_raw(cmd)Spawn a command without shell quoting
hl.dsp.exit()Exit the compositor
hl.dsp.submap(name)Switch to a named submap ("default" to reset)
hl.dsp.pass({ window })Pass keys through to a window
hl.dsp.send_shortcut({ mods, key, window? })Inject a keyboard shortcut to a window
hl.dsp.send_key_state({ mods, key, state, window? })Inject key state ("down"/"up"/"repeat")
hl.dsp.layout(msg)Send a layout message
hl.dsp.dpms({ action?, monitor? })Control DPMS ("toggle"/"on"/"off")
hl.dsp.event(msg)Send an internal event
hl.dsp.global(msg)Send a global shortcut
hl.dsp.force_renderer_reload()Force renderer GL reload
hl.dsp.force_idle(timeout)Force idle timeout in seconds
hl.dsp.focus({ ... })Multi-modal focus (see below)
hl.dsp.no_op()Do nothing (placeholder)

hl.dsp.focus() modes

ModeExample
Direction{ direction = "left"|"right"|"up"|"down" }
Monitor{ monitor = "DP-1"|"+"|"-"|"next"|"prev" }
Workspace{ workspace = "3"|"name:chat", on_current_monitor? }
Window{ window = "selector" } — by address, class, title, or regex
Urgent/last{ urgent_or_last = true }
Last{ last = true }

hl.dsp.window.*

FunctionDescription
hl.dsp.window.close({ window? })Close window
hl.dsp.window.kill({ window? })Force-kill window
hl.dsp.window.signal({ signal, window? })Send internal signal
hl.dsp.window.float({ action?, window? })Toggle/enable/disable float
hl.dsp.window.fullscreen({ mode?, action?, window? })Fullscreen (mode: "fullscreen"/"maximized", action: "toggle"/"set"/"unset")
hl.dsp.window.fullscreen_state({ internal, client, action?, window? })Explicit fullscreen state
hl.dsp.window.pseudo({ action?, window? })Pseudo-tile
hl.dsp.window.move({ ... })Multi-modal move (see below)
hl.dsp.window.swap({ ... })Swap windows (direction/target/next/prev)
hl.dsp.window.center({ window? })Center window on screen
hl.dsp.window.cycle_next({ next?, tiled?, floating?, window? })Cycle focus
hl.dsp.window.tag({ tag, window? })Tag window
hl.dsp.window.clear_tags({ window? })Clear all tags
hl.dsp.window.toggle_swallow()Toggle swallow
hl.dsp.window.pin({ action?, window? })Pin window
hl.dsp.window.bring_to_top()Raise window
hl.dsp.window.alter_zorder({ mode, window? })Change z-order ("top"/"bottom"/"up"/"down")
hl.dsp.window.set_prop({ prop, value, window? })Set arbitrary window property
hl.dsp.window.deny_from_group({ action? })Deny/allow from groups
hl.dsp.window.drag()Start mouse drag to move
hl.dsp.window.resize({ ... })Resize (by x/y or keep_aspect_ratio)

hl.dsp.window.move() modes

ModeExample
Direction{ direction = "left"|"right"|"up"|"down", group_aware? }
Position{ x = 100, y = 200, relative? = true }
Workspace{ workspace = "3"|"special:magic", follow? }
Monitor{ monitor = "DP-1"|"+"|"-", follow? }
Into group{ into_group = "left"|"right"|"up"|"down" }
Into/create group{ into_or_create_group = "left"|"right"|"up"|"down" }
Out of group{ out_of_group = true } or { out_of_group = "direction" }

hl.dsp.workspace.*

FunctionDescription
hl.dsp.workspace.rename({ workspace, name? })Rename workspace
hl.dsp.workspace.move({ workspace?, monitor })Move workspace (or current) to a monitor
hl.dsp.workspace.swap_monitors({ monitor1, monitor2 })Swap active workspaces between monitors
hl.dsp.workspace.change_id({ workspace, id })Change workspace ID
hl.dsp.workspace.toggle_special(name?)Toggle special (scratchpad) workspace

hl.dsp.group.*

FunctionDescription
hl.dsp.group.toggle({ window? })Toggle window group
hl.dsp.group.next({ window? })Next group member
hl.dsp.group.prev({ window? })Previous group member
hl.dsp.group.active({ index, window? })Set active tab by index
hl.dsp.group.move_window({ forward? })Move window within group
hl.dsp.group.lock({ action? })Lock/unlock all groups
hl.dsp.group.lock_active({ action? })Lock/unlock active group

hl.dsp.cursor.*

FunctionDescription
hl.dsp.cursor.move_to_corner({ corner=1-4, window? })Move cursor to window corner
hl.dsp.cursor.move({ x, y })Move cursor by offset

8 Query Functions — hl.get_*()

Windows

FunctionReturnsDescription
hl.get_windows({ filters? }){ HL.Window, ... }All windows matching filters: monitor, workspace, floating, mapped, class, title, tag. Defaults to mapped windows.
hl.get_window(selector)HL.Window | nilSingle window by address, title, class, regex, or object
hl.get_active_window()HL.Window | nilCurrently focused window
hl.get_urgent_window()HL.Window | nilWindow with urgent hint
hl.get_last_window()HL.Window | nilPreviously focused window
hl.get_workspace_windows(ws){ HL.Window, ... }All mapped windows on a workspace

Workspaces

FunctionReturnsDescription
hl.get_workspaces(){ HL.Workspace, ... }All non-inert workspaces
hl.get_workspace(selector)HL.Workspace | nilBy id, name, or object
hl.get_active_workspace(monitor?)HL.Workspace | nilActive workspace (on given or focused monitor)
hl.get_active_special_workspace(monitor?)HL.Workspace | nilActive special (scratchpad) workspace
hl.get_last_workspace(monitor?)HL.Workspace | nilPreviously active workspace

Monitors

FunctionReturnsDescription
hl.get_monitors(){ HL.Monitor, ... }All monitors
hl.get_monitor(selector)HL.Monitor | nilBy name, id, or object
hl.get_active_monitor()HL.MonitorFocused monitor
hl.get_monitor_at(x, y) or ({ x, y })HL.Monitor | nilMonitor at pixel coordinates
hl.get_monitor_at_cursor()HL.MonitorMonitor under cursor

Layers & misc

FunctionReturnsDescription
hl.get_layers({ filters? }){ HL.LayerSurface, ... }Filter by monitor, namespace
hl.get_cursor_pos(){ x, y }Current cursor coordinates
hl.get_current_submap()stringActive submap name
hl.version()stringHyprland version string
hl.get_loaded_plugins(){ {name,author,version,description}, ... }List of loaded plugins

9 Event System — hl.on(), hl.off()

hl.on(event_name, callback) → subscription

Subscribe to compositor events. Returns a subscription handle with methods :remove() and :is_active(). Pass to hl.off() to unsubscribe.

hl.off(subscription)

Unsubscribe from an event. Equivalent to subscription:remove().

Window events

EventCallback arguments
"window.open"HL.Window
"window.open_early"HL.Window
"window.close"HL.Window
"window.destroy"HL.Window
"window.kill"HL.Window
"window.active"HL.Window, int focusReason
"window.urgent"HL.Window
"window.title"HL.Window
"window.class"HL.Window
"window.pin"HL.Window
"window.fullscreen"HL.Window
"window.update_rules"HL.Window
"window.move_to_workspace"HL.Window, HL.Workspace

Layer events

EventCallback arguments
"layer.opened"HL.LayerSurface
"layer.closed"HL.LayerSurface

Workspace events

EventCallback arguments
"workspace.active"HL.Workspace
"workspace.special_active"HL.Workspace, HL.Monitor
"workspace.created"HL.Workspace
"workspace.removed"HL.Workspace
"workspace.move_to_monitor"HL.Workspace, HL.Monitor

Monitor events

EventCallback arguments
"monitor.added"HL.Monitor
"monitor.removed"HL.Monitor
"monitor.focused"HL.Monitor
"monitor.layout_changed"(none)

Config events

EventCallback arguments
"config.reloaded"(none)
"config.props_refreshed"bool (was scheduled?)

Input & misc events

EventCallback arguments
"keybinds.submap"string submapName
"screenshare.state"bool state, int type, string name
"hyprland.start"(none)
"hyprland.shutdown"(none)
"input.keyboard.key"int keycode, int timeMs, int state
hl.on("window.open", function(win)
  hl.print("Window opened:", win.class, win.title)
end)

10 Utility Functions

hl.print(...)

Log one or more values to the Hyprland log.

hl.exec_cmd(cmd, rule_table?)

Execute a shell command immediately (not as a dispatcher). Accepts an optional rule table for window rule effects.

hl.env(name, value, dbus?)

Set an environment variable. If dbus is true, also update via D-Bus activation environment.

hl.dispatch(dispatcher_closure)

Execute a dispatcher closure immediately (same as calling a bound key's action).

hl.load_plugin(path)

Register a plugin to be loaded. Path is the absolute path to .so file.

hl.clear_crashed_lockscreen()

Clear a crashed lockscreen session.

hl.exec_scheduled_prop_refresh_immediately()

Execute any pending scheduled property refresh immediately.

hl.is_key_down(keycode_or_keysym) → bool

Check if a key is currently pressed. Accepts a keycode (int) or keysym (string).

hl.env("XCURSOR_SIZE", "24")
hl.exec_cmd("waybar")
hl.dispatch(hl.dsp.window.close())

11 Notifications — hl.notification.*

hl.notification.create({ text, duration, icon?, color?, font_size? }) → notification_handle
FieldTypeDescription
textstringNotification message
duration / timeout / timenumber (ms)Display duration (required)
iconstring or intIcon: "warning", "info", "error", "ok", "hint", "confused", "question", "none", or numeric
colorstring or intBackground color (hex string, rgba, or numeric)
font_sizenumberFont size (default 13)
hl.notification.get() → { HL.Notification, ... }

Get list of current notifications.

HL.Notification methods

The object returned by hl.notification.create() and hl.notification.get() has the following methods:

MethodDescription
pause()Pause the notification (keeps it visible indefinitely)
resume()Resume the notification timer
set_paused(bool)Set paused state
is_paused() → boolCheck if paused
set_text(text)Set notification text
set_timeout(ms)Set display timeout in ms
set_color(color)Set background color (string or number)
set_icon(icon)Set icon (name or number)
set_font_size(size)Set font size
dismiss()Dismiss the notification immediately
get_text() → stringGet notification text
get_timeout() → numberGet timeout in ms
get_color() → intGet color as hex integer
get_icon() → intGet icon ID
get_font_size() → numberGet font size
get_elapsed() → numberGet elapsed time since last change (ms)
get_elapsed_since_creation() → numberGet elapsed time since creation (ms)
is_alive() → boolCheck if notification still exists

12 Timers — hl.timer()

hl.timer(callback, { timeout, type }) → timer_handle
FieldTypeDescription
callbackfunctionFunction to call when timer fires
timeoutnumber (ms)Interval/delay in milliseconds
typestring"repeat" or "oneshot"
local t = hl.timer(function() hl.print("tick") end, { timeout = 1000, type = "repeat" })
-- t:cancel() to stop

13 Animations & Curves — hl.curve(), hl.animation()

hl.curve(name, definition)

Define a named animation curve (bezier or spring).

TypeDefinition table
bezier{ type = "bezier", points = { {x1,y1}, {x2,y2} } }
spring{ type = "spring", mass = number, stiffness = number, dampening = number }
hl.animation({ leaf, enabled, speed, bezier? / spring?, style? })

Configure an animation leaf. Known leaves: "global", "border", "windows", "windowsIn", "windowsOut", "fade", "fadeIn", "fadeOut", "layers", "layersIn", "layersOut", "workspaces", etc.

hl.curve("myBezier", { type = "bezier", points = { {0.23, 1}, {0.32, 1} } })
hl.animation({ leaf = "windows", enabled = true, speed = 4.79, spring = "easy" })

14 Devices — hl.device()

hl.device({ name, ...fields })

Configure per-device input settings. The name field is the device name (from hyprctl devices).

FieldTypeDescription
namestringDevice name (required)
enabledboolEnable/disable device
sensitivityfloat (-1 to 1)Pointer sensitivity
accel_profilestring"adaptive" or "flat"
natural_scrollboolNatural scrolling
tap_to_clickboolTap to click
tap_and_dragboolTap and drag
drag_lockint (0-2)Drag lock behavior
left_handedboolLeft-handed mode
scroll_methodstring"on_button_down", "edge", "two_finger", "no_scroll"
scroll_buttonint (0-300)Scroll button
scroll_button_lockboolLock scroll button
scroll_factorfloat (0-100)Scroll speed multiplier
clickfinger_behaviorboolClickfinger behavior
middle_button_emulationboolMiddle button emulation
tap_button_mapstring"lrm" or "lmr"
disable_while_typingboolDisable touchpad while typing
numlock_by_defaultboolNumLock on by default
resolve_binds_by_symboolResolve binds by keysym
kb_layoutstringKeyboard layout
kb_variantstringKeyboard variant
kb_optionsstringKeyboard options
kb_rulesstringKeyboard rules
kb_modelstringKeyboard model
kb_filestringCustom keymap file path
repeat_rateint (0-200)Key repeat rate
repeat_delayint (0-2000)Key repeat delay (ms)
rotationint (0-359)Tablet rotation
transformintTablet transform
outputstringTablet output mapping
region_positionvec2Tablet region position
region_sizevec2Tablet region size
relative_inputboolRelative input mode
flip_x / flip_yboolFlip tablet axis
tagsstringDevice tags
keybindsboolEnable keybinds on this device
share_statesint (0-2)LED state sharing
scroll_pointsstringScroll point configuration
absolute_region_positionboolUse absolute region position for tablet
active_area_positionvec2Tablet active area position
active_area_sizevec2Tablet active area size
drag_3fgint (0-2)Three-finger drag behavior
release_pressed_on_closeboolRelease pressed keys when virtual keyboard closes

15 Permissions — hl.permission()

hl.permission(binary, type, mode)
hl.permission({ binary, type, mode })

Set a permission rule for a binary. Accepts positional args or a table with binary, type, mode fields. Requires hl.config({ ecosystem = { enforce_permissions = true } }) to be active.

FieldValues
binaryRegex path to binary, e.g. "/usr/bin/grim", "/usr/(bin|libexec)/xdg-desktop-portal-hyprland"
type"screencopy", "cursorpos", "plugin", "keyboard"
mode"allow", "deny", "ask"

Permissions are only applied on first launch. Changes require a restart.

16 Gestures — hl.gesture()

hl.gesture({ fingers, direction, action, ... })
FieldTypeDescription
fingersint (2-9)Number of fingers
directionstring"horizontal", "vertical", "left", "right", "up", "down", "any"
actionstring or function"workspace", "resize", "move", "special", "close", "float", "fullscreen", "cursor_zoom" / "cursorZoom", "scroll_move", "unset", or a Lua function
modsstringModifier combination like "SUPER"
scalefloat (0.1-10)Delta scale (default 1.0)
disable_inhibitboolDisable inhibit for this gesture
zoom_levelstringZoom level for cursor_zoom action
workspace_namestringWorkspace name for special action
modestringMode for float / fullscreen / cursor_zoom actions

17 Plugins — hl.plugin.load()

hl.plugin.load(path)

Register a plugin to load. The path is an absolute path to the .so file.

18 Custom Layouts — hl.layout.*

hl.layout.register(name, methods)

Register a custom tiling layout. The methods table must implement layout lifecycle callbacks.

Required methodSignature
onWindowAddedfunction(window)
onWindowRemovedfunction(window)
onWindowSwappedfunction(w1, w2)
onWindowMovedfunction(window, fromWorkspace)
requestResizefunction(window, edge, delta)
requestMovefunction(window, x, y)
calculateWindowSizefunction(window)
recalculatefunction()
resizeActiveWindowfunction(delta, edge)
hl.layout.list() → { string, ... }

List registered layout names.

hl.layout.get(name) → layout

Get a registered layout by name.

19 Object Types

HL.Window

PropertyTypeDescription
addressstringMemory address ("0x...")
mappedboolIs mapped
hiddenboolIs hidden
visibleboolIs visible
accepts_inputboolAccepts keyboard input
at{ x, y }Position on screen
size{ x, y }Width and height
workspaceHL.WorkspaceWorkspace containing the window
floatingboolIs floating
monitorHL.MonitorMonitor the window is on
classstringWindow class
titlestringWindow title
initial_classstringClass at creation
initial_titlestringTitle at creation
pidintProcess ID
xwaylandboolIs XWayland window
pinnedboolIs pinned to workspace
fullscreenintInternal fullscreen mode (0/1/2)
fullscreen_clientintClient fullscreen mode (0/1/2)
over_fullscreenboolCreated over fullscreen
groupHL.GroupGroup object if in a group
tags{ string, ... }List of tags
swallowingHL.WindowSwallowed window
focus_history_idintPosition in focus history
inhibiting_idleboolIs inhibiting idle
xdg_tagstringXDG tag
xdg_descriptionstringXDG description
content_typestringContent type
stable_idintStable window ID
activeboolIs focused
layout{ name, is_master?, perc_master?, perc_size?, ... }Layout-specific data

HL.Workspace

PropertyTypeDescription
idintWorkspace ID
namestringWorkspace name
monitorHL.MonitorMonitor the workspace is on
windowsintNumber of windows
visibleboolIs visible
specialboolIs special (scratchpad) workspace
activeboolIs active on its monitor
has_urgentboolHas urgent window
fullscreen_modeintFullscreen mode
has_fullscreenboolHas fullscreen window
is_persistentboolIs persistent workspace
is_emptyboolHas no windows
config_namestringConfig-specified name
tiled_layoutstringActive tiled layout name
last_windowHL.WindowLast focused window
fullscreen_windowHL.WindowFullscreen window (if any)
groupsintNumber of groups
get_windows(){ HL.Window, ... }Get all windows on this workspace
get_groups(){ HL.Group, ... }Get all groups on this workspace

HL.Monitor

PropertyTypeDescription
idintMonitor ID
namestringMonitor name (e.g. "DP-1")
descriptionstringShort description
serialstringSerial number
widthintPixel width
heightintPixel height
physical_widthintPhysical width (mm)
physical_heightintPhysical height (mm)
refresh_ratenumberRefresh rate (Hz)
xintPosition X
yintPosition Y
position{ x, y }Position as table
size{ width, height }Size as table
scalenumberScale factor
transformintTransform (0-7)
active_workspaceHL.WorkspaceActive workspace
active_special_workspaceHL.WorkspaceActive special workspace (or nil)
dpms_statusboolDPMS state
vrr_activeboolVRR active
is_mirrorboolIs mirroring another output
mirrors{ HL.Monitor, ... }Mirroring outputs
available_modes{ {width,height,refresh_rate,preferred}, ... }Available video modes
focusedboolIs focused
cmstringColor management mode
reserved{ top, right, bottom, left }Reserved area (for bars)
set_workspace({ workspace })Switch to a workspace on this monitor
set_special_workspace({ workspace? })Toggle special workspace

HL.LayerSurface

PropertyTypeDescription
addressstringMemory address
xintPosition X
yintPosition Y
wintWidth
hintHeight
namespacestringLayer namespace
pidintProcess ID
monitorHL.MonitorMonitor
mappedboolIs mapped
layerintLayer index
interactivityintInteractivity level
above_fullscreenboolRenders above fullscreen windows

HL.Group

PropertyTypeDescription
lockedboolGroup is locked (can't add/remove members)
deniedboolGroup is denied (members can't be focused)
sizeintNumber of members
current_indexintIndex of the active member (1-based)
currentHL.WindowCurrently focused member window
members{ HL.Window, ... }All member windows