quickshell: fix workspace highlight drift and unstable sort

The sliding active indicator positioned itself via Repeater.itemAt(), which
returns null mid-rebuild; the fallback then stranded it at the top (looked
like workspace 1 was active while the font correctly showed another). Cells
are uniform, so compute the indicator's y arithmetically from the index
instead. Also make monitorWsData's sort deterministic: numbered workspaces
ascending, then named ones (e.g. joplin) alphabetically — parseInt alone
yields NaN and an unstable order for named workspaces.
This commit is contained in:
2026-06-01 14:26:20 +02:00
parent dd5d8a348d
commit 54e12efcae
+14 -4
View File
@@ -31,7 +31,16 @@ Item {
if (ws.monitor && ws.monitor.name === monitorName)
data.push({ id: ws.id, name: ws.name });
}
data.sort((a, b) => parseInt(a.name) - parseInt(b.name));
// Numbered workspaces first (ascending), then named ones (e.g. "joplin")
// alphabetically. parseInt-only sort is unstable for non-numeric names.
data.sort((a, b) => {
let na = parseInt(a.name), nb = parseInt(b.name);
let aNum = !isNaN(na), bNum = !isNaN(nb);
if (aNum && bNum) return na - nb;
if (aNum) return -1;
if (bNum) return 1;
return a.name.localeCompare(b.name);
});
return data;
}
@@ -85,10 +94,11 @@ Item {
}
return Math.max(0, Math.min(root.activeWsId - 1, root.wsCount - 1));
}
property var targetItem: wsRepeater.itemAt(targetIndex)
// Position arithmetically from the index — cells are uniform, so this
// avoids depending on Repeater.itemAt() (which returns null mid-rebuild
// and stranded the indicator at the top).
x: (container.width - width) / 2
y: targetItem ? targetItem.y + wsCol.y : container.padding
y: container.padding + targetIndex * (root.cellSize + wsCol.spacing)
width: root.cellSize
height: root.cellSize
radius: Shared.Theme.radiusSmall