You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
On niri, workspaces declared as persistent named workspaces (workspace "name" { open-on-output "…" }) never register as occupied in the bar's workspace switcher, even when they contain windows — they render identically to empty workspaces. The #2538 fix ("workspace: fix occupied color in niri", 09ca37c) is present in my build but does not cover this case.
The same root cause also makes showOccupiedWorkspacesOnly a no-op for these workspaces (empty named workspaces are never hidden).
Versions
DankMaterialShell:1.5.0+date=2026-07-08_bdfd565 (commit bdfd565, current stable HEAD)
"workspaceOccupiedColorMode": "custom",
"workspaceOccupiedCustomColor": "#47b5d8"// a distinct cyan
Steps to reproduce
Configure persistent named workspaces with open-on-output as above.
Set a distinct workspaceOccupiedColorMode / color.
Open a window on a non-active named workspace (e.g. a terminal on 02).
Expected
Workspace 02 shows the occupied color.
Actual
Workspace 02 shows the unfocused/empty color — isOccupied is false even though the workspace has a window. Every non-active workspace looks empty regardless of contents.
Evidence the data is present
niri msg -j windows shows the window's workspace_idmatches the workspace's id (e.g. window workspace_id: 2, workspace 02 has id: 2).
The FocusedApp widget correctly reads NiriService.windows[].workspace_id — the per-monitor focused-window title works — so NiriService.windowsis populated with workspace_id, and it matches NiriService.allWorkspaces[].id.
Stale reactive binding.isOccupied may not re-evaluate when windows change. NiriService.windows is populated asynchronously (IPC), so if the binding first evaluates before windows load, and the dependency on NiriService.windows isn't re-tracked (possibly through the ?. in NiriService.windows?.some(...)), isOccupied stays false. This would also explain why showOccupiedWorkspacesOnly acts as a no-op, and why the differently-structured FocusedApp reactive path works.
modelData?.id not resolving to the workspace id in the switcher delegate for named workspaces.
The isOccupied and is_urgent checks (WorkspaceSwitcher.qml:1529) both depend on this match, so occupied and urgent coloring are affected. I haven't verified either hypothesis — happy to test a patch and report back.
Summary
On niri, workspaces declared as persistent named workspaces (
workspace "name" { open-on-output "…" }) never register as occupied in the bar's workspace switcher, even when they contain windows — they render identically to empty workspaces. The #2538 fix ("workspace: fix occupied color in niri",09ca37c) is present in my build but does not cover this case.The same root cause also makes
showOccupiedWorkspacesOnlya no-op for these workspaces (empty named workspaces are never hidden).Versions
1.5.0+date=2026-07-08_bdfd565(commitbdfd565, currentstableHEAD)v25.08(commit01be0e65f4eb91a9cd624ac0b76aaeab765c7294)0.3.0(tag-v0.3.0, Nixpkgs)26.05.20260611.a037402, installed viadms.homeModules(flake)niri config (persistent named workspaces pinned per output)
DMS settings used to diagnose
Steps to reproduce
open-on-outputas above.workspaceOccupiedColorMode/ color.02).Expected
Workspace
02shows the occupied color.Actual
Workspace
02shows the unfocused/empty color —isOccupiedis false even though the workspace has a window. Every non-active workspace looks empty regardless of contents.Evidence the data is present
niri msg -j windowsshows the window'sworkspace_idmatches the workspace'sid(e.g. windowworkspace_id: 2, workspace02hasid: 2).NiriService.windows[].workspace_id— the per-monitor focused-window title works — soNiriService.windowsis populated withworkspace_id, and it matchesNiriService.allWorkspaces[].id.WorkspaceSwitcher.qmlisOccupied(the occupied workspace color not working. #2538-fixed version):Hypotheses (unverified — for maintainer to check)
Two candidate causes, either or both:
isOccupiedmay not re-evaluate when windows change.NiriService.windowsis populated asynchronously (IPC), so if the binding first evaluates before windows load, and the dependency onNiriService.windowsisn't re-tracked (possibly through the?.inNiriService.windows?.some(...)),isOccupiedstaysfalse. This would also explain whyshowOccupiedWorkspacesOnlyacts as a no-op, and why the differently-structuredFocusedAppreactive path works.modelData?.idnot resolving to the workspace id in the switcher delegate for named workspaces.The
isOccupiedandis_urgentchecks (WorkspaceSwitcher.qml:1529) both depend on this match, so occupied and urgent coloring are affected. I haven't verified either hypothesis — happy to test a patch and report back.Possibly related
open-on-output/ named workspaces on multiple outputs on startup)