diff options
| author | 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> | 2025-04-30 13:49:05 +1000 |
|---|---|---|
| committer | 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> | 2025-04-30 13:49:05 +1000 |
| commit | e8fe4ef673ebb3bc89f192ad5dba0b6d54149f34 (patch) | |
| tree | e82697134093d7b025c3257a3c6aa49abce483b7 | |
| parent | bar: custom workspace labels (diff) | |
| download | caelestia-shell-e8fe4ef673ebb3bc89f192ad5dba0b6d54149f34.tar.gz caelestia-shell-e8fe4ef673ebb3bc89f192ad5dba0b6d54149f34.tar.bz2 caelestia-shell-e8fe4ef673ebb3bc89f192ad5dba0b6d54149f34.zip | |
feat: bar workspaces show windows
Better hyprland clients (update existing instead of resetting every time)
Option for ws trail
Custom label for occupied ws as well
| -rw-r--r-- | config/BarConfig.qml | 5 | ||||
| -rw-r--r-- | modules/bar/components/workspaces/ActiveIndicator.qml | 18 | ||||
| -rw-r--r-- | modules/bar/components/workspaces/Workspace.qml | 83 | ||||
| -rw-r--r-- | services/Hyprland.qml | 26 |
4 files changed, 117 insertions, 15 deletions
diff --git a/config/BarConfig.qml b/config/BarConfig.qml index fe0dab3..e5c0711 100644 --- a/config/BarConfig.qml +++ b/config/BarConfig.qml @@ -26,7 +26,10 @@ Singleton { readonly property int shown: 10 readonly property string style: "" readonly property bool occupiedBg: true - readonly property string label: " " + readonly property bool showWindows: true + readonly property bool activeTrail: !showWindows // Doesn't work well with variable sized workspaces + readonly property string label: " " + readonly property string occupiedLabel: " " readonly property string activeLabel: " " } diff --git a/modules/bar/components/workspaces/ActiveIndicator.qml b/modules/bar/components/workspaces/ActiveIndicator.qml index 027b575..f8b0deb 100644 --- a/modules/bar/components/workspaces/ActiveIndicator.qml +++ b/modules/bar/components/workspaces/ActiveIndicator.qml @@ -71,16 +71,34 @@ Rectangle { } Behavior on leading { + enabled: BarConfig.workspaces.activeTrail + Anim {} } Behavior on trailing { + enabled: BarConfig.workspaces.activeTrail + Anim { duration: Appearance.anim.durations.normal * 2 } } Behavior on currentSize { + enabled: BarConfig.workspaces.activeTrail + + Anim {} + } + + Behavior on offset { + enabled: !BarConfig.workspaces.activeTrail + + Anim {} + } + + Behavior on size { + enabled: !BarConfig.workspaces.activeTrail + Anim {} } diff --git a/modules/bar/components/workspaces/Workspace.qml b/modules/bar/components/workspaces/Workspace.qml index a6e2b43..c5d7475 100644 --- a/modules/bar/components/workspaces/Workspace.qml +++ b/modules/bar/components/workspaces/Workspace.qml @@ -1,9 +1,14 @@ import "root:/widgets" import "root:/services" +import "root:/utils" import "root:/config" +import Quickshell +import QtQuick import QtQuick.Layouts -StyledText { +Item { + id: root + required property int index required property bool vertical required property var occupied @@ -12,15 +17,73 @@ StyledText { readonly property bool isWorkspace: true // Flag for finding workspace children readonly property int ws: groupOffset + index + 1 - readonly property string label: BarConfig.workspaces.label || ws - readonly property string activeLabel: BarConfig.workspaces.activeLabel || label + readonly property bool isOccupied: occupied[ws] ?? false + + Layout.preferredWidth: childrenRect.width + (isOccupied && !vertical ? Appearance.padding.normal : 0) + Layout.preferredHeight: childrenRect.height + (isOccupied && vertical ? Appearance.padding.normal : 0) + + StyledText { + id: indicator + + readonly property string label: BarConfig.workspaces.label || root.ws + readonly property string occupiedLabel: BarConfig.workspaces.occupiedLabel || label + readonly property string activeLabel: BarConfig.workspaces.activeLabel || (root.isOccupied ? occupiedLabel : label) + + animate: true + animateProp: "scale" + text: Hyprland.activeWsId === root.ws ? activeLabel : root.isOccupied ? occupiedLabel : label + color: BarConfig.workspaces.occupiedBg || root.isOccupied ? Appearance.colours.text : Appearance.colours.subtext0 + horizontalAlignment: StyledText.AlignHCenter + verticalAlignment: StyledText.AlignVCenter + + width: BarConfig.sizes.innerHeight + height: BarConfig.sizes.innerHeight + } + + Grid { + flow: root.vertical ? GridLayout.TopToBottom : GridLayout.LeftToRight + rows: root.vertical ? -1 : 1 + columns: root.vertical ? 1 : -1 + spacing: Appearance.padding.small + + anchors.left: vertical ? undefined : indicator.right + anchors.top: vertical ? indicator.bottom : undefined + anchors.verticalCenter: vertical ? undefined : indicator.verticalCenter + anchors.horizontalCenter: vertical ? indicator.horizontalCenter : undefined + + add: Transition { + Anim { + properties: "scale" + from: 0 + to: 1 + duration: Appearance.anim.durations.small + } + } + + Repeater { + model: ScriptModel { + values: Hyprland.clients.filter(c => c.workspace.id === root.ws) + } + + MaterialIcon { + required property Hyprland.Client modelData + + text: Icons.getAppCategoryIcon(modelData.wmClass, "terminal") + } + } + } + + Behavior on Layout.preferredWidth { + Anim {} + } - animate: true - animateProp: "scale" - text: (Hyprland.activeWorkspace?.id ?? 1) === ws ? activeLabel : label - color: BarConfig.workspaces.occupiedBg || occupied[ws] ? Appearance.colours.text : Appearance.colours.subtext0 - horizontalAlignment: StyledText.AlignHCenter + Behavior on Layout.preferredHeight { + Anim {} + } - Layout.minimumWidth: vertical ? -1 : BarConfig.sizes.innerHeight - Layout.minimumHeight: vertical ? BarConfig.sizes.innerHeight : -1 + component Anim: NumberAnimation { + duration: Appearance.anim.durations.normal + easing.type: Easing.BezierSpline + easing.bezierCurve: Appearance.anim.curves.standard + } } diff --git a/services/Hyprland.qml b/services/Hyprland.qml index 336be73..f47c0cb 100644 --- a/services/Hyprland.qml +++ b/services/Hyprland.qml @@ -8,12 +8,13 @@ import QtQuick Singleton { id: root - property list<Client> clients: [] + readonly property list<Client> clients: [] readonly property var workspaces: Hyprland.workspaces readonly property var monitors: Hyprland.monitors property Client activeClient: null readonly property HyprlandWorkspace activeWorkspace: focusedMonitor?.activeWorkspace ?? null readonly property HyprlandMonitor focusedMonitor: Hyprland.monitors.values.find(m => m.lastIpcObject.focused) ?? null + readonly property int activeWsId: activeWorkspace?.id ?? 1 function reload() { Hyprland.refreshWorkspaces(); @@ -43,9 +44,25 @@ Singleton { stdout: SplitParser { onRead: data => { const clients = JSON.parse(data); - root.clients = clients.map(c => clientComp.createObject(root, { - lastIpcObject: c - })).filter(c => c); + const rClients = root.clients; + + const len = rClients.length; + for (let i = 0; i < len; i++) { + const client = rClients[i]; + if (!clients.find(c => c.address === client.address)) + rClients.splice(i, 1); + } + + for (const client of clients) { + const match = rClients.find(c => c.address === client.address); + if (match) { + match.lastIpcObject = client; + } else { + rClients.push(clientComp.createObject(root, { + lastIpcObject: client + })); + } + } } } } @@ -78,6 +95,7 @@ Singleton { property bool floating: lastIpcObject.floating property bool fullscreen: lastIpcObject.fullscreen property int pid: lastIpcObject.pid + property int focusHistoryId: lastIpcObject.focusHistoryID } Component { |