118 lines
3.7 KiB
QML
118 lines
3.7 KiB
QML
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import "." as M
|
|
|
|
Row {
|
|
id: root
|
|
spacing: 4
|
|
|
|
required property var bar
|
|
|
|
property var _allWorkspaces: []
|
|
property int _activeId: -1
|
|
readonly property string _output: bar.screen?.name ?? ""
|
|
readonly property var _workspaces: _allWorkspaces.filter(w => w.output === root._output)
|
|
|
|
// Initial state
|
|
Process {
|
|
id: initProc
|
|
running: true
|
|
command: ["niri", "msg", "--json", "workspaces"]
|
|
stdout: StdioCollector {
|
|
onStreamFinished: {
|
|
try {
|
|
const ws = JSON.parse(text);
|
|
root._allWorkspaces = ws.sort((a, b) => a.idx - b.idx);
|
|
for (const w of ws) {
|
|
if (w.is_focused)
|
|
root._activeId = w.id;
|
|
}
|
|
} catch (e) {}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Live updates
|
|
Process {
|
|
id: eventStream
|
|
running: true
|
|
command: ["niri", "msg", "--json", "event-stream"]
|
|
stdout: SplitParser {
|
|
splitMarker: "\n"
|
|
onRead: line => {
|
|
try {
|
|
const ev = JSON.parse(line);
|
|
if (ev.WorkspacesChanged !== undefined) {
|
|
root._allWorkspaces = ev.WorkspacesChanged.workspaces.sort((a, b) => a.idx - b.idx);
|
|
} else if (ev.WorkspaceActivated !== undefined) {
|
|
if (ev.WorkspaceActivated.focused)
|
|
root._activeId = ev.WorkspaceActivated.id;
|
|
}
|
|
} catch (e) {}
|
|
}
|
|
}
|
|
}
|
|
|
|
Process {
|
|
id: switchProc
|
|
property int wsId: -1
|
|
command: ["niri", "msg", "action", "focus-workspace", String(wsId)]
|
|
}
|
|
|
|
Repeater {
|
|
model: root._workspaces
|
|
|
|
delegate: Rectangle {
|
|
id: pill
|
|
|
|
required property var modelData
|
|
|
|
readonly property bool active: modelData.id === root._activeId
|
|
property bool _hovered: false
|
|
|
|
HoverHandler {
|
|
onHoveredChanged: {
|
|
pill._hovered = hovered;
|
|
const name = pill.modelData.name || ("Workspace " + pill.modelData.idx);
|
|
if (hovered) {
|
|
M.FlyoutState.text = name;
|
|
M.FlyoutState.itemX = pill.mapToGlobal(pill.width / 2, 0).x - (QsWindow.window?.screen?.x ?? 0);
|
|
M.FlyoutState.screen = QsWindow.window?.screen ?? null;
|
|
M.FlyoutState.visible = true;
|
|
} else {
|
|
M.FlyoutState.visible = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
width: M.Theme.fontSize + 4
|
|
height: M.Theme.fontSize + 4
|
|
radius: width / 2
|
|
color: pill.active ? (root.parent?.accentColor ?? M.Theme.base0D) : (pill._hovered ? M.Theme.base03 : M.Theme.base02)
|
|
Behavior on color {
|
|
ColorAnimation {
|
|
duration: 150
|
|
}
|
|
}
|
|
|
|
Text {
|
|
anchors.centerIn: parent
|
|
text: pill.modelData.idx
|
|
color: pill.active ? M.Theme.base00 : M.Theme.base04
|
|
font.pixelSize: M.Theme.fontSize - 2
|
|
font.family: M.Theme.fontFamily
|
|
font.bold: pill.active
|
|
}
|
|
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
cursorShape: Qt.PointingHandCursor
|
|
onClicked: {
|
|
switchProc.wsId = pill.modelData.id;
|
|
switchProc.running = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|