How to focus main monitor & main workspace on startup

Hyprland version
Hyprland 0.55.4 built from branch unknown at commit a0136d8c04687bb36eb8a28eb9d1ff92aea99704 dirty (unknown).
Date: 2026-06-11
Tag: v0.55.4, commits: 0

Libraries:
Hyprgraphics: built against 0.5.1, system has unknown
Hyprutils: built against 0.13.1, system has unknown
Hyprcursor: built against 0.1.13, system has unknown
Hyprlang: built against 0.6.8, system has unknown
Aquamarine: built against 0.12.1, system has unknown

Version ABI string: a0136d8c04687bb36eb8a28eb9d1ff92aea99704_aq_0.12_hu_0.13_hg_0.5_hc_0.1_hlg_0.6
flags set:
nix

how to focus main monitor & main workspace on startup

I have 2 monitors: a secondary monitor with workspace 0 and my primary monitor with workspaces 1 to 9:

for i = 1, 9 do
    hl.workspace_rule({ workspace = i, monitor = monitor_first })
end
hl.workspace_rule({ workspace = 4, monitor = monitor_first, default = true })
hl.workspace_rule({ workspace = 0, monitor = monitor_second })

On startup I would like to focus my primary monitor with workspace 4 but unfortunately it always focuses workspace 0 with the secondary monitor.

I tried using hl.disp.focus on the hyprland.start event but it doesn’t work. Maybe hyprland.start is triggered too early? But I don’t know which other event would work. I also tried monitor.added or workspace.created but neither worked.

hl.on("hyprland.start", function ()
  hl.dsp.focus({ workspace = 4 }) -- focus on main monitor with main workspace
end)

I know the default workspace keyword exists but it only binds a workspace to a monitor and doesn’t define a global default workspace. A default monitor doesn’t seem to exist at all. What would be the correct way to have hyprland focus the correct workspace upon startup?

I tried this; can’t get it to work, either. If I run:

hyprctl dispatch 'hl.dsp.focus({ workspace = 4 })'

from the terminal, it switches as expected. Maybe we’re not adding the dispatcher in the correct block.

You almost had it.
As per the Dispatchers page on the wiki:

Dispatchers return tables that describe an action you want to make. They do not invoke any action immediately, and their contents are not guaranteed to be stable at all. Their purpose is to be fed into hl.bind() or hl.dispatch().

You forgot to actually dispatch your dispatcher :stuck_out_tongue:

Correct syntax is:

hl.on("hyprland.start", function ()
  hl.dispatch(hl.dsp.focus({ workspace = 4 })) -- focus on main monitor with main workspace
end)