show monitor-specific workspaces in bar, and change current-workspace highlight
This commit is contained in:
1 parent
feb0ce49fb
commit
34f4d976a2
3 files changed
+213
No files matched your search
@@ -0,0 +1,121 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
import qs.Commons
|
||||||
|
import qs.Ui
|
||||||
|
|
||||||
|
BarWidget {
|
||||||
|
id: root
|
||||||
|
moduleName: "joe.workspaces"
|
||||||
|
|
||||||
|
// The Hyprland monitor this bar surface lives on. One bar is built per
|
||||||
|
// screen, so each instance filters to its own monitor's workspaces.
|
||||||
|
readonly property var screen: root.QsWindow.window ? root.QsWindow.window.screen : null
|
||||||
|
readonly property var monitor: screen ? Hyprland.monitorFor(screen) : null
|
||||||
|
|
||||||
|
// Green from the current theme's colors.toml. The shell's Color singleton
|
||||||
|
// doesn't expose it, so read it here; `activeColor` in shell.json overrides.
|
||||||
|
property color themeGreen: "#9ece6a"
|
||||||
|
readonly property color activeColor: root.setting("activeColor", root.themeGreen)
|
||||||
|
|
||||||
|
FileView {
|
||||||
|
id: colorsFile
|
||||||
|
path: Color.currentThemePath + "/colors.toml"
|
||||||
|
printErrors: false
|
||||||
|
onLoaded: {
|
||||||
|
var match = text().match(/^\s*(?:green|color2)\s*=\s*["']?(#[0-9A-Fa-f]{6})/m)
|
||||||
|
if (match) root.themeGreen = match[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Theme switches push new colors into Color; re-read ours alongside.
|
||||||
|
Connections {
|
||||||
|
target: Color
|
||||||
|
function onAccentChanged() { colorsFile.reload() }
|
||||||
|
}
|
||||||
|
|
||||||
|
function workspaceById(id) {
|
||||||
|
var values = Hyprland.workspaces.values
|
||||||
|
for (var i = 0; i < values.length; i++) {
|
||||||
|
if (values[i].id === id) return values[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
function workspaceIds() {
|
||||||
|
var ids = []
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
ids.sort(function(left, right) { return left - right })
|
||||||
|
return ids
|
||||||
|
}
|
||||||
|
|
||||||
|
function focusWorkspace(id) {
|
||||||
|
if (!root.bar) return
|
||||||
|
root.bar.run("hyprctl dispatch " + Util.shellQuote("hl.dsp.focus({ workspace = \"" + id + "\" })"))
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property real trailingGap: root.vertical ? 0 : Style.spaceReal(1.5)
|
||||||
|
|
||||||
|
implicitWidth: grid.implicitWidth + trailingGap
|
||||||
|
implicitHeight: grid.implicitHeight
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
id: grid
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.rightMargin: root.trailingGap
|
||||||
|
columns: root.vertical ? 1 : Math.max(1, root.workspaceIds().length)
|
||||||
|
columnSpacing: root.vertical ? 0 : Style.space(1)
|
||||||
|
rowSpacing: root.vertical ? Style.space(2) : 0
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: root.workspaceIds()
|
||||||
|
|
||||||
|
WidgetButton {
|
||||||
|
required property int modelData
|
||||||
|
|
||||||
|
readonly property var workspace: root.workspaceById(modelData)
|
||||||
|
readonly property bool occupied: workspace !== null && workspace.toplevels.values.length > 0
|
||||||
|
// The workspace shown on this bar's monitor (each monitor has one).
|
||||||
|
readonly property bool focused: root.monitor !== null && root.monitor.activeWorkspace !== null
|
||||||
|
&& root.monitor.activeWorkspace.id === modelData
|
||||||
|
|
||||||
|
id: button
|
||||||
|
bar: root.bar
|
||||||
|
text: 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)
|
||||||
|
fixedHeight: root.barSize
|
||||||
|
onPressed: function() { root.focusWorkspace(modelData) }
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
textFormat: Text.PlainText
|
||||||
|
text: button.text
|
||||||
|
color: button.focused ? root.activeColor : button.foreground
|
||||||
|
font.family: button.fontFamily
|
||||||
|
font.pixelSize: button.fontSize
|
||||||
|
font.bold: button.focused
|
||||||
|
font.underline: button.focused
|
||||||
|
renderType: Text.NativeRendering
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"id": "joe.workspaces",
|
||||||
|
"name": "My Workspaces",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"author": "Omarchy",
|
||||||
|
"description": "Workspace number indicators",
|
||||||
|
"kinds": [
|
||||||
|
"bar-widget"
|
||||||
|
],
|
||||||
|
"entryPoints": {
|
||||||
|
"barWidget": "Workspaces.qml"
|
||||||
|
},
|
||||||
|
"barWidget": {
|
||||||
|
"displayName": "My Workspaces",
|
||||||
|
"description": "Workspace number indicators",
|
||||||
|
"category": "Compositor",
|
||||||
|
"allowMultiple": false
|
||||||
|
},
|
||||||
|
"omarchy": {
|
||||||
|
"clonedFrom": "omarchy.workspaces"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"idle": {
|
||||||
|
"screensaver": 150,
|
||||||
|
"lock": 300
|
||||||
|
},
|
||||||
|
"bar": {
|
||||||
|
"position": "top",
|
||||||
|
"transparent": false,
|
||||||
|
"centerAnchor": "omarchy.clock",
|
||||||
|
"layout": {
|
||||||
|
"left": [
|
||||||
|
{
|
||||||
|
"id": "omarchy.menu"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "joe.workspaces"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"center": [
|
||||||
|
{
|
||||||
|
"id": "omarchy.indicators"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "omarchy.clock",
|
||||||
|
"format": "dddd HH:mm",
|
||||||
|
"formatAlt": "d MMMM 'W'ww yyyy",
|
||||||
|
"verticalFormat": "HH\n—\nmm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "omarchy.keyboard-layout"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "omarchy.weather"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "omarchy.system-update"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"right": [
|
||||||
|
{
|
||||||
|
"id": "omarchy.tray"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "omarchy.tailscale"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "omarchy.agents"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "omarchy.bluetooth"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "omarchy.network"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "omarchy.audio"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "omarchy.monitor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "omarchy.power"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"plugins": []
|
||||||
|
}
|
||||||
Reference in new issue
Block a user