diff --git a/dot_config/omarchy/plugins/private_joe.workspaces/Workspaces.qml b/dot_config/omarchy/plugins/private_joe.workspaces/Workspaces.qml index c46fadf..80a924d 100644 --- a/dot_config/omarchy/plugins/private_joe.workspaces/Workspaces.qml +++ b/dot_config/omarchy/plugins/private_joe.workspaces/Workspaces.qml @@ -45,24 +45,37 @@ BarWidget { return null } + // Hyprland gives named workspaces negative ids, as it does special + // (scratchpad) workspaces; only the latter have a "special:" name. + function isNamed(ws) { + return ws !== null && ws.id < 0 && String(ws.name).indexOf("special") !== 0 + } + + // Numbered workspaces 1-10 in order, then named ones alphabetically. function workspaceIds() { - var ids = [] + var numbered = [] + var named = [] var values = Hyprland.workspaces.values for (var i = 0; i < values.length; i++) { var ws = values[i] - if (ws.id <= 0 || ws.id > 10) continue if (root.monitor && ws.monitor !== root.monitor) continue - ids.push(ws.id) + if (ws.id > 0 && ws.id <= 10) numbered.push(ws.id) + else if (root.isNamed(ws)) named.push(ws) } - ids.sort(function(left, right) { return left - right }) - return ids + numbered.sort(function(left, right) { return left - right }) + named.sort(function(left, right) { return String(left.name).localeCompare(String(right.name)) }) + return numbered.concat(named.map(function(ws) { return ws.id })) } function focusWorkspace(id) { if (!root.bar) return - root.bar.run("hyprctl dispatch " + Util.shellQuote("hl.dsp.focus({ workspace = \"" + id + "\" })")) + var ws = root.workspaceById(id) + var target = root.isNamed(ws) + ? "name:" + String(ws.name).replace(/\\/g, "\\\\").replace(/"/g, "\\\"") + : String(id) + root.bar.run("hyprctl dispatch " + Util.shellQuote("hl.dsp.focus({ workspace = \"" + target + "\" })")) } readonly property real trailingGap: root.vertical ? 0 : Style.spaceReal(1.5) @@ -92,17 +105,22 @@ BarWidget { id: button bar: root.bar - text: modelData === 10 ? "0" : String(modelData) + readonly property bool named: root.isNamed(workspace) + + text: named ? String(workspace.name) : (modelData === 10 ? "0" : String(modelData)) // WidgetButton's own label can't be bolded, so draw our own instead. labelVisible: false opacity: occupied || focused ? 1 : 0.5 horizontalMargin: 6 verticalPadding: 6 - fixedWidth: root.vertical ? root.barSize : Style.space(20) + // Numbers get a fixed slot; names get as much room as they need. + fixedWidth: root.vertical ? root.barSize + : (named ? Math.max(Style.space(20), label.implicitWidth + Style.space(12)) : Style.space(20)) fixedHeight: root.barSize onPressed: function() { root.focusWorkspace(modelData) } Text { + id: label anchors.centerIn: parent textFormat: Text.PlainText text: button.text