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
This commit is contained in:
parent
65c54e12c2
commit
e8fe4ef673
4 changed files with 117 additions and 15 deletions
|
|
@ -26,7 +26,10 @@ Singleton {
|
||||||
readonly property int shown: 10
|
readonly property int shown: 10
|
||||||
readonly property string style: ""
|
readonly property string style: ""
|
||||||
readonly property bool occupiedBg: true
|
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: " "
|
readonly property string activeLabel: " "
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,16 +71,34 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on leading {
|
Behavior on leading {
|
||||||
|
enabled: BarConfig.workspaces.activeTrail
|
||||||
|
|
||||||
Anim {}
|
Anim {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on trailing {
|
Behavior on trailing {
|
||||||
|
enabled: BarConfig.workspaces.activeTrail
|
||||||
|
|
||||||
Anim {
|
Anim {
|
||||||
duration: Appearance.anim.durations.normal * 2
|
duration: Appearance.anim.durations.normal * 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on currentSize {
|
Behavior on currentSize {
|
||||||
|
enabled: BarConfig.workspaces.activeTrail
|
||||||
|
|
||||||
|
Anim {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on offset {
|
||||||
|
enabled: !BarConfig.workspaces.activeTrail
|
||||||
|
|
||||||
|
Anim {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on size {
|
||||||
|
enabled: !BarConfig.workspaces.activeTrail
|
||||||
|
|
||||||
Anim {}
|
Anim {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,14 @@
|
||||||
import "root:/widgets"
|
import "root:/widgets"
|
||||||
import "root:/services"
|
import "root:/services"
|
||||||
|
import "root:/utils"
|
||||||
import "root:/config"
|
import "root:/config"
|
||||||
|
import Quickshell
|
||||||
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
|
||||||
StyledText {
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
required property int index
|
required property int index
|
||||||
required property bool vertical
|
required property bool vertical
|
||||||
required property var occupied
|
required property var occupied
|
||||||
|
|
@ -12,15 +17,73 @@ StyledText {
|
||||||
readonly property bool isWorkspace: true // Flag for finding workspace children
|
readonly property bool isWorkspace: true // Flag for finding workspace children
|
||||||
|
|
||||||
readonly property int ws: groupOffset + index + 1
|
readonly property int ws: groupOffset + index + 1
|
||||||
readonly property string label: BarConfig.workspaces.label || ws
|
readonly property bool isOccupied: occupied[ws] ?? false
|
||||||
readonly property string activeLabel: BarConfig.workspaces.activeLabel || label
|
|
||||||
|
|
||||||
animate: true
|
Layout.preferredWidth: childrenRect.width + (isOccupied && !vertical ? Appearance.padding.normal : 0)
|
||||||
animateProp: "scale"
|
Layout.preferredHeight: childrenRect.height + (isOccupied && vertical ? Appearance.padding.normal : 0)
|
||||||
text: (Hyprland.activeWorkspace?.id ?? 1) === ws ? activeLabel : label
|
|
||||||
color: BarConfig.workspaces.occupiedBg || occupied[ws] ? Appearance.colours.text : Appearance.colours.subtext0
|
|
||||||
horizontalAlignment: StyledText.AlignHCenter
|
|
||||||
|
|
||||||
Layout.minimumWidth: vertical ? -1 : BarConfig.sizes.innerHeight
|
StyledText {
|
||||||
Layout.minimumHeight: vertical ? BarConfig.sizes.innerHeight : -1
|
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 {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on Layout.preferredHeight {
|
||||||
|
Anim {}
|
||||||
|
}
|
||||||
|
|
||||||
|
component Anim: NumberAnimation {
|
||||||
|
duration: Appearance.anim.durations.normal
|
||||||
|
easing.type: Easing.BezierSpline
|
||||||
|
easing.bezierCurve: Appearance.anim.curves.standard
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,13 @@ import QtQuick
|
||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property list<Client> clients: []
|
readonly property list<Client> clients: []
|
||||||
readonly property var workspaces: Hyprland.workspaces
|
readonly property var workspaces: Hyprland.workspaces
|
||||||
readonly property var monitors: Hyprland.monitors
|
readonly property var monitors: Hyprland.monitors
|
||||||
property Client activeClient: null
|
property Client activeClient: null
|
||||||
readonly property HyprlandWorkspace activeWorkspace: focusedMonitor?.activeWorkspace ?? null
|
readonly property HyprlandWorkspace activeWorkspace: focusedMonitor?.activeWorkspace ?? null
|
||||||
readonly property HyprlandMonitor focusedMonitor: Hyprland.monitors.values.find(m => m.lastIpcObject.focused) ?? null
|
readonly property HyprlandMonitor focusedMonitor: Hyprland.monitors.values.find(m => m.lastIpcObject.focused) ?? null
|
||||||
|
readonly property int activeWsId: activeWorkspace?.id ?? 1
|
||||||
|
|
||||||
function reload() {
|
function reload() {
|
||||||
Hyprland.refreshWorkspaces();
|
Hyprland.refreshWorkspaces();
|
||||||
|
|
@ -43,9 +44,25 @@ Singleton {
|
||||||
stdout: SplitParser {
|
stdout: SplitParser {
|
||||||
onRead: data => {
|
onRead: data => {
|
||||||
const clients = JSON.parse(data);
|
const clients = JSON.parse(data);
|
||||||
root.clients = clients.map(c => clientComp.createObject(root, {
|
const rClients = root.clients;
|
||||||
lastIpcObject: c
|
|
||||||
})).filter(c => c);
|
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 floating: lastIpcObject.floating
|
||||||
property bool fullscreen: lastIpcObject.fullscreen
|
property bool fullscreen: lastIpcObject.fullscreen
|
||||||
property int pid: lastIpcObject.pid
|
property int pid: lastIpcObject.pid
|
||||||
|
property int focusHistoryId: lastIpcObject.focusHistoryID
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue