External monitors: Ideal setup

Hyprland version
Hyprland 0.55.3 built from branch v0.55.3 at commit fe5fe79a29ac3adaf3e75560b2f4b7a6d58b31c9 clean ([gha] Nix: update inputs).
Date: Sun Jun 7 10:35:01 2026
Tag: v0.55.3, commits: 7366

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

Version ABI string: fe5fe79a29ac3adaf3e75560b2f4b7a6d58b31c9_aq_0.12_hu_0.13_hg_0.5_hc_0.1_hlg_0.6
no flags were set

Describe your issue / feature…

I don’t understand how workspaces work with external monitors. I have an awkward setup and I would like to know how it’s done properly for my use case.

(Config is below)

Acknowledgement

This is a user-error. I just don’t know how and I’m looking for answers.

Use case

I have a desktop and a laptop that both use the same config. My desktop correctly assumes the config for DP-1 while my laptop uses eDP-1. DP-3 on the other hand is for external monitors I plug in whenever I am presenting something to an audience on a large screen.

The problem

In DP-3 config, I uncomment mirror and change the laptops (eDP-1) built in display’s resolution and scale manually. I do this because I find the behavior for external monitors confusing.

I don’t know on which workspace the external monitor decides to be on and so I blindly switch between workspaces and open a window to see where it happens. When I do find the correct workspace and move the window I want to share to said workspace, then it works but another problem comes up:

When I use SUPER+SHIFT+[1-10] to move a window to a different workspace, then it behaves differently when doing so from the workspace with an external monitor. If the only window on the external workspace is moved that way, the workspace that is moved to becomes the external workspace.

As a result I would have to awkwardly spawn a window in the external workspace first before moving it out, bringing the new window in and closing the temporary window.

Ideal scenario

The external monitor is binded to a predictable workspace (like workspace 1) and does not budge like in the aforementioned case of moving windows. Bonus points if I do not need to change config in real time to make things happen and only need to plug the monitor cable in.

hyprland.lua:

--- MONITORS ----

hl.monitor({
    output   = "DP-1",
    mode     = "2560x1440@144",
    position = "0x0",
    scale    = "1",
})

hl.monitor({
    output   = "eDP-1",
    mode     = "2256x1504@60",
    -- mode     = "3840x2160@60",
    position = "0x0",
    scale    = "1.33",
    -- scale    = "2",
})

hl.monitor({
    output   = "DP-3",
    mode     = "3840x2160@60",
    position = "2256x0",
    scale    = "1.33",
    -- mirror = "eDP-1"
})

I am suffering for a long time by the same unpredicted workspace behaviour when switching monitors.
I did bring it up in another thread but there was no response.

It is a frustration, no doubt.
hyprland does not remember which workspaces/windows are open when switching to another monitor.
My case is pretty close to yours, a desktop with DP-1 and a TV on HDMI.

I did not feel reporting it as a bug before getting some good advice in here.
Maybe one of the devs can look into it or give us a solid approach.

https://wiki.hypr.land/Configuring/Basics/Workspace-Rules/#rules

Workspace rules do support monitor binding, have a look at examples given in the doc and tinker around to figure out if its works

@ny572233

Thank you, I am aware of these.
This is not what I am talking about.

In my case, if I enable one monitor and disable the other, workspaces are messed up.
Some are hidden and not to be retrieved.

What I am looking for is:
Boot with one monitor enabled/the other disabled.
Open any workspaces/windows I need.
Then,
Enable the second monitor and disable the first.
I expect/hope that any active workspaces and windows would be properly shown on the second monitor. It’s not happening.

Thanks anyway.