Skip to content
Expanding functionality

Expanding functionality

Note

Looking for the old hyprlang syntax? Check the 0.54 wiki pages. Since Hyprland 0.55, hyprlang is deprecated in favor of lua.

Lua utilities

Hyprland exposes a bunch of lua utilities for you to script your desktop with custom functionality and more.

Events

With hl.on, you can define callbacks on events. You can register as many as you want.

hl.on("window.active", function(w)
  hl.notification.create({ text = "Window focused: " .. w.title, timeout = 5000, icon = "ok" })
end)

or, if you’re working with events that have multiple parameters

hl.on("workspace.move_to_monitor", function(ws, m)
  hl.notification.create({
    text = "Workspace: " .. ws.name .. " moved to a monitor at x: " .. m.position.x,
    timeout = 4000,
    icon = "ok"
  })
end)

Event list:

EventDescriptionParameters
hyprland.startEmitted once on startNone
hyprland.shutdownEmitted once before Hyprland exitingNone
window.openEmitted when a window is fully initialized with window rules applied.Window
window.open_earlyEmitted when a window is created and mapped, but before window rules are applied.Window
window.closeEmitted when a window is closed. It may still be visible during its closing animation.Window
window.destroyEmitted when a window is removed from the compositor. For windows with a close animation, fires after the animation completes.Window
window.killEmitted when a window is forcefully killed via hyprctl kill.Window
window.activeEmitted when the active window changes.Window, int [0/1]
window.urgentEmitted when a window requests an urgent state.Window
window.titleEmitted when a window title changes.Window
window.classEmitted when a window class changes.Window
window.pinEmitted when a window is pinned or unpinned.Window
window.fullscreenEmitted when the fullscreen status of a window changes.Window
window.update_rulesEmitted when a window’s rules are re-evaluated, e.g. when its title or class changes.Window
window.move_to_workspaceEmitted when a window is moved to a different workspace.Window, Workspace
layer.openedEmitted when a layer surface is opened.LayerSurface
layer.closedEmitted when a layer surface is closed.LayerSurface
monitor.addedEmitted when a monitor is connected and ready.Monitor
monitor.removedEmitted when a monitor is disconnected and removed.Monitor
monitor.focusedEmitted when the active monitor changes.Monitor
monitor.layout_changedEmitted when the monitor arrangement changes. This occurs when a monitor is added or removed, a monitor’s resolution or refresh rate is changed, or the config is reloaded with different rules.None
workspace.activeEmitted when the active workspace on a monitor changes.Workspace
workspace.createdEmitted when a workspace is created.Workspace
workspace.removedEmitted when a workspace is removed.Workspace
workspace.move_to_monitorEmitted when a workspace is moved to a different monitor.Workspace, Monitor
config.reloadedEmitted when the config has been reloaded and applied.None
keybinds.submapEmitted when the active submap changes. An empty string means the default submap was restored.String: Submap Name
screenshare.stateEmitted when a screenshare session starts or stops.Bool: Active, Integer: Type, String: Name

Convenience functions

Hyprland exposes a bunch of convenience functions:

  • hl.get_active_window()
  • hl.get_windows()
  • hl.get_window(selector)
  • hl.get_urgent_window()
  • hl.get_workspaces()
  • hl.get_workspace(selector)
  • hl.get_active_workspace()
  • hl.get_active_special_workspace()
  • hl.get_monitors()
  • hl.get_monitor(selector)
  • hl.get_active_monitor()
  • hl.get_monitor_at({ x = num, y = num })
  • hl.get_monitor_at_cursor()
  • hl.get_cursor_pos()
  • hl.get_last_window()
  • hl.get_last_workspace()
  • hl.get_layers()
  • hl.get_workspace_windows(workspace_selector)
  • hl.get_current_submap()
  • hl.version()
  • hl.exec_cmd()

Timers

You can spawn and manage timers via hl.timer():

local demoTimer = hl.timer(function()
  print("hello from timer")
end, { timeout = 1000, type = "repeat" })

demoTimer:set_enabled(false)

hl.bind("SUPER + X", function()
  -- toggle the timer
  demoTimer:set_enabled(not demoTimer:is_enabled())
end)

Combining it all

You can expand functionality e.g. like so:

-- bind to toggle floating, unless the window is htop,
-- then only set floating

hl.bind("SUPER + X", function()
  local w = hl.get_active_window()
  if w ~= nil and w.title == "htop" do
    hl.dispatch(hl.dsp.window.float({ action = "set" }))
  else
    hl.dispatch(hl.dsp.window.float({ action = "toggle" }))
  end
end)

Sockets (IPC)

It’s recommended to use Lua. Lua will be faster, less buggy, have more APIs, and is more integrated.

However, if you want to use IPC instead, check the IPC page.

Last updated on