feat(quickshell): support x11 bar sessions

This commit is contained in:
2026-09-27 09:33:47 -04:00
parent 3f6473ce17
commit 5c13c8c3e7
10 changed files with 133 additions and 24 deletions
+8 -13
View File
@@ -1,6 +1,5 @@
import QtQuick
import Quickshell
import Quickshell.Hyprland
import Quickshell.Services.Pipewire
import Quickshell.Services.UPower
@@ -11,6 +10,7 @@ PanelWindow {
property var source: Pipewire.defaultAudioSource
property var battery: UPower.displayDevice
property var hardware
property bool isWayland: Quickshell.env("XDG_SESSION_TYPE") === "wayland"
anchors {
top: true
@@ -42,34 +42,29 @@ PanelWindow {
id: leftModules
anchors {
left: parent.left
top: parent.top
bottom: parent.bottom
verticalCenter: parent.verticalCenter
}
height: Theme.blockHeight
spacing: Theme.moduleSpacing
Workspaces {
Loader {
height: parent.height
source: bar.isWayland ? "Workspaces.qml" : "I3Workspaces.qml"
}
}
Text {
Loader {
anchors.centerIn: parent
width: Math.max(0, Math.min(implicitWidth,
parent.width - leftModules.width - rightModules.width - Theme.blockHeight))
elide: Text.ElideRight
horizontalAlignment: Text.AlignHCenter
text: Hyprland.activeToplevel ? Hyprland.activeToplevel.title : ""
color: Theme.foreground
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSize
source: bar.isWayland ? "HyprlandTitle.qml" : "I3Title.qml"
}
Row {
id: rightModules
anchors {
right: parent.right
top: parent.top
bottom: parent.bottom
verticalCenter: parent.verticalCenter
rightMargin: Theme.moduleSpacing / 2
}
spacing: Theme.moduleSpacing
@@ -4,10 +4,10 @@ Block {
id: root
required property var battery
property int percentage: Math.round(battery.percentage * 100)
property int percentage: battery ? Math.round(battery.percentage * 100) : 0
signal detailsRequested(var anchorItem)
visible: battery.ready && battery.isLaptopBattery
visible: battery && battery.ready && battery.isLaptopBattery
interactive: true
blockColor: percentage <= 15 && UPower.onBattery
? Theme.urgent : UPower.onBattery ? Theme.foreground : Theme.secondary
@@ -0,0 +1,11 @@
import QtQuick
import Quickshell.Hyprland
Text {
elide: Text.ElideRight
horizontalAlignment: Text.AlignHCenter
text: Hyprland.activeToplevel ? Hyprland.activeToplevel.title : ""
color: Theme.foreground
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSize
}
@@ -0,0 +1,40 @@
import QtQuick
import Quickshell.I3
import Quickshell.Io
Text {
id: root
function focusedTitle(node) {
for (const child of (node.nodes || []).concat(node.floating_nodes || [])) {
const title = focusedTitle(child);
if (title)
return title;
}
return node.focused && node.type === "con" ? node.name || "" : "";
}
elide: Text.ElideRight
horizontalAlignment: Text.AlignHCenter
color: Theme.foreground
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSize
Connections {
target: I3
function onRawEvent(event) {
if ((event.type === "window" || event.type === "workspace") && !treeQuery.running)
treeQuery.running = true;
}
}
Process {
id: treeQuery
command: ["i3-msg", "-t", "get_tree"]
running: true
stdout: StdioCollector {
onStreamFinished: root.text = root.focusedTitle(JSON.parse(text))
}
}
}
@@ -0,0 +1,48 @@
import QtQuick
import Quickshell.I3
Row {
spacing: 0
Repeater {
model: I3.workspaces
Rectangle {
id: workspaceButton
required property var modelData
property bool active: modelData.active
visible: modelData.number > 0
width: visible ? Theme.blockHeight + 2 : 0
height: parent.height
color: modelData.urgent ? Theme.urgent
: active ? Theme.primary : "transparent"
Rectangle {
anchors {
left: parent.left
right: parent.right
bottom: parent.bottom
}
height: Theme.activeLineWidth
color: workspaceButton.active ? Theme.accent : "transparent"
}
Text {
anchors.centerIn: parent
text: modelData.number === 2 ? "\uf120"
: modelData.number === 13 ? "\uf001" : modelData.name
color: Theme.foreground
font.family: Theme.iconFontFamily
font.pixelSize: Theme.fontSize
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: workspaceButton.modelData.activate()
}
}
}
}
+1 -1
View File
@@ -18,7 +18,7 @@ Singleton {
readonly property string fontFamily: "SF Pro Display, Helvetica, Arial, sans-serif"
readonly property string iconFontFamily: "SF Pro Display, Font Awesome 6 Free"
readonly property int barHeight: 38
readonly property int barHeight: 32
readonly property int blockHeight: 32
readonly property int fontSize: 18
readonly property int fontTiny: 11
+2
View File
@@ -11,6 +11,8 @@ ShellRoot {
Bar {
required property var modelData
screen: modelData
visible: !Quickshell.env("QUICKSHELL_BAR_SCREEN")
|| modelData.name === Quickshell.env("QUICKSHELL_BAR_SCREEN")
hardware: hardwareService
}
}
@@ -3,7 +3,6 @@ Description=Quickshell desktop bar
Documentation=https://quickshell.org/
After=graphical-session.target
PartOf=graphical-session.target
ConditionEnvironment=WAYLAND_DISPLAY
[Service]
Type=simple