fix(workspaces/hyprland): recover workspace mapping on monitor hotplug

fixes #3133
This commit is contained in:
bbedward
2026-08-21 10:17:26 -04:00
parent 589737e318
commit 90c5f65b0f
2 changed files with 25 additions and 7 deletions
@@ -253,6 +253,16 @@ Item {
return ws.id > 0 ? ws.id : "name:" + (ws.name ?? "");
}
// A hotplug can leave the workspace→monitor mapping stale so nothing matches this screen;
// show what the monitor itself reports rather than a fabricated workspace "1" (#3133)
function hyprlandMonitorWorkspaces(workspaces) {
const monitorWorkspaces = workspaces.filter(ws => ws.monitor?.name === root.screenName);
if (monitorWorkspaces.length > 0)
return monitorWorkspaces.sort(hyprlandWorkspaceOrder);
const active = Hyprland.monitors?.values?.find(m => m.name === root.screenName)?.activeWorkspace;
return active ? [active] : [];
}
function getHyprlandWorkspaces() {
const workspaces = Hyprland.workspaces?.values || [];
if (workspaces.length === 0) {
@@ -284,13 +294,7 @@ Item {
if (!root.screenName || SettingsData.workspaceFollowFocus) {
filtered = filtered.slice().sort(hyprlandWorkspaceOrder);
} else {
const monitorWorkspaces = filtered.filter(ws => ws.monitor?.name === root.screenName);
filtered = monitorWorkspaces.length > 0 ? monitorWorkspaces.sort(hyprlandWorkspaceOrder) : [
{
id: 1,
name: "1"
}
];
filtered = hyprlandMonitorWorkspaces(filtered);
}
if (!SettingsData.showOccupiedWorkspacesOnly) {
+14
View File
@@ -221,6 +221,10 @@ Singleton {
enabled: isHyprland
function onRawEvent(event) {
if (event.name === "monitoraddedv2" || event.name === "monitorremoved") {
root.refreshHyprlandMonitorLayout();
return;
}
if (event.name === "openwindow" || event.name === "closewindow" || event.name === "movewindow" || event.name === "movewindowv2" || event.name === "workspace" || event.name === "workspacev2" || event.name === "focusedmon" || event.name === "focusedmonv2" || event.name === "activewindow" || event.name === "activewindowv2" || event.name === "changefloatingmode" || event.name === "fullscreen" || event.name === "moveintogroup" || event.name === "moveoutofgroup" || event.name === "activespecial") {
try {
Hyprland.refreshToplevels();
@@ -690,9 +694,19 @@ Singleton {
target: Quickshell
function onScreensChanged() {
root._recomputeFrameBlocked();
root.refreshHyprlandMonitorLayout();
}
}
// Workspace moves can land before Hyprland announces the monitor and before the Wayland
// output reaches us, so re-read both models once the screen set settles (#3133)
function refreshHyprlandMonitorLayout() {
if (!isHyprland)
return;
Hyprland.refreshMonitors();
Hyprland.refreshWorkspaces();
}
function _screenForName(screenOrName) {
if (screenOrName && typeof screenOrName !== "string")
return screenOrName;