added quickshell config
This commit is contained in:
13
dotfiles/.config/quickshell/modules/bar/ActiveWindow.qml
Normal file
13
dotfiles/.config/quickshell/modules/bar/ActiveWindow.qml
Normal file
@@ -0,0 +1,13 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Hyprland
|
||||
import "../../config"
|
||||
|
||||
Text {
|
||||
Layout.maximumWidth: 320
|
||||
elide: Text.ElideRight
|
||||
font.family: Appearance.fontFamily
|
||||
font.pixelSize: Appearance.fontSizeSmall
|
||||
color: Colors.muted
|
||||
text: Hyprland.activeToplevel ? Hyprland.activeToplevel.title : ""
|
||||
}
|
||||
55
dotfiles/.config/quickshell/modules/bar/Bar.qml
Normal file
55
dotfiles/.config/quickshell/modules/bar/Bar.qml
Normal file
@@ -0,0 +1,55 @@
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import "../../config"
|
||||
|
||||
PanelWindow {
|
||||
id: bar
|
||||
|
||||
anchors {
|
||||
top: true
|
||||
left: true
|
||||
right: true
|
||||
}
|
||||
implicitHeight: Appearance.barHeight
|
||||
exclusiveZone: implicitHeight
|
||||
color: "transparent"
|
||||
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
WlrLayershell.namespace: "quickshell:bar"
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Colors.background
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
leftMargin: Appearance.spacing
|
||||
}
|
||||
spacing: Appearance.spacing
|
||||
Workspaces { screen: bar.screen }
|
||||
ActiveWindow {}
|
||||
}
|
||||
|
||||
Clock {
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors {
|
||||
right: parent.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
rightMargin: Appearance.spacing
|
||||
}
|
||||
spacing: Appearance.spacing
|
||||
Tray {}
|
||||
NetworkIndicator {}
|
||||
BluetoothIndicator {}
|
||||
Volume {}
|
||||
PowerButton {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import QtQuick
|
||||
import Quickshell.Bluetooth
|
||||
import "../../config"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
implicitWidth: label.implicitWidth + 4
|
||||
implicitHeight: Appearance.barHeight
|
||||
|
||||
readonly property var adapter: Bluetooth.defaultAdapter
|
||||
readonly property bool anyConnected: {
|
||||
if (!adapter) return false
|
||||
const devices = adapter.devices.values
|
||||
for (let i = 0; i < devices.length; i++) {
|
||||
if (devices[i].connected) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
Text {
|
||||
id: label
|
||||
anchors.centerIn: parent
|
||||
font.family: Appearance.iconFontFamily
|
||||
font.variableAxes: Appearance.iconFontAxes
|
||||
font.pixelSize: 16
|
||||
color: (root.adapter && root.adapter.enabled) ? Colors.foreground : Colors.muted
|
||||
text: {
|
||||
if (!root.adapter || !root.adapter.enabled) return "bluetooth_disabled"
|
||||
return root.anyConnected ? "bluetooth_connected" : "bluetooth"
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: if (root.adapter) root.adapter.enabled = !root.adapter.enabled
|
||||
}
|
||||
}
|
||||
18
dotfiles/.config/quickshell/modules/bar/Clock.qml
Normal file
18
dotfiles/.config/quickshell/modules/bar/Clock.qml
Normal file
@@ -0,0 +1,18 @@
|
||||
import QtQuick
|
||||
import "../../config"
|
||||
|
||||
Text {
|
||||
id: root
|
||||
font.family: Appearance.fontFamily
|
||||
font.pixelSize: Appearance.fontSize
|
||||
font.bold: true
|
||||
color: Colors.foreground
|
||||
text: Qt.formatDateTime(new Date(), "ddd d MMM hh:mm")
|
||||
|
||||
Timer {
|
||||
interval: 1000
|
||||
running: true
|
||||
repeat: true
|
||||
onTriggered: root.text = Qt.formatDateTime(new Date(), "ddd d MMM hh:mm")
|
||||
}
|
||||
}
|
||||
35
dotfiles/.config/quickshell/modules/bar/NetworkIndicator.qml
Normal file
35
dotfiles/.config/quickshell/modules/bar/NetworkIndicator.qml
Normal file
@@ -0,0 +1,35 @@
|
||||
import QtQuick
|
||||
import Quickshell.Networking
|
||||
import "../../config"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
implicitWidth: label.implicitWidth + 4
|
||||
implicitHeight: Appearance.barHeight
|
||||
|
||||
readonly property var connectedDevice: {
|
||||
const devices = Networking.devices.values
|
||||
for (let i = 0; i < devices.length; i++) {
|
||||
if (devices[i].connected)
|
||||
return devices[i]
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
Text {
|
||||
id: label
|
||||
anchors.centerIn: parent
|
||||
font.family: Appearance.iconFontFamily
|
||||
font.variableAxes: Appearance.iconFontAxes
|
||||
font.pixelSize: 16
|
||||
color: root.connectedDevice ? Colors.foreground : Colors.muted
|
||||
text: {
|
||||
if (!root.connectedDevice)
|
||||
return "wifi_off"
|
||||
return root.connectedDevice.type === DeviceType.Wired ? "settings_ethernet" : "wifi"
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(follow-up): wire this up to a network panel (SSID list, connect/forget)
|
||||
// once the control center lands.
|
||||
}
|
||||
114
dotfiles/.config/quickshell/modules/bar/PowerButton.qml
Normal file
114
dotfiles/.config/quickshell/modules/bar/PowerButton.qml
Normal file
@@ -0,0 +1,114 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import "../../config"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
implicitWidth: label.implicitWidth + 4
|
||||
implicitHeight: Appearance.barHeight
|
||||
|
||||
Text {
|
||||
id: label
|
||||
anchors.centerIn: parent
|
||||
font.family: Appearance.iconFontFamily
|
||||
font.variableAxes: Appearance.iconFontAxes
|
||||
font.pixelSize: 16
|
||||
color: Colors.foreground
|
||||
text: "power_settings_new"
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: menu.visible = !menu.visible
|
||||
}
|
||||
|
||||
Process { id: proc }
|
||||
|
||||
PopupWindow {
|
||||
id: menu
|
||||
visible: false
|
||||
color: "transparent"
|
||||
implicitWidth: 170
|
||||
implicitHeight: list.model.length * 32 + (list.model.length - 1) * 2 + 16
|
||||
|
||||
anchor {
|
||||
item: root
|
||||
edges: Edges.Bottom | Edges.Right
|
||||
gravity: Edges.Bottom | Edges.Left
|
||||
margins.top: 4
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: Appearance.radius
|
||||
color: Colors.surface
|
||||
border.color: Colors.muted
|
||||
border.width: 1
|
||||
|
||||
Column {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 8
|
||||
spacing: 2
|
||||
|
||||
Repeater {
|
||||
id: list
|
||||
model: [
|
||||
// "iconSize" is optional — omit it to use the 15px default below.
|
||||
// Material Symbols glyphs aren't all the same visual weight at a
|
||||
// given size (a padlock silhouette reads bulkier than a thin arrow),
|
||||
// so nudge individual icons here to balance them by eye.
|
||||
{ label: "Lock", icon: "lock", iconSize: 13, cmd: ["hyprlock"] },
|
||||
{ label: "Log out", icon: "logout", cmd: ["hyprctl", "dispatch", "exit"] },
|
||||
{ label: "Reboot", icon: "restart_alt", cmd: ["systemctl", "reboot"] },
|
||||
{ label: "Shut down", icon: "power_settings_new", cmd: ["systemctl", "poweroff"] }
|
||||
]
|
||||
|
||||
delegate: Rectangle {
|
||||
id: entry
|
||||
required property var modelData
|
||||
width: parent ? parent.width : 0
|
||||
height: 32
|
||||
radius: Appearance.radiusSmall
|
||||
color: entryMouse.containsMouse ? Colors.primary : "transparent"
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 8
|
||||
spacing: 8
|
||||
Text {
|
||||
Layout.preferredWidth: 20
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: entry.modelData.icon
|
||||
font.family: Appearance.iconFontFamily
|
||||
font.variableAxes: Appearance.iconFontAxes
|
||||
font.pixelSize: entry.modelData.iconSize || 15
|
||||
color: entryMouse.containsMouse ? Colors.primaryText : Colors.foreground
|
||||
}
|
||||
Text {
|
||||
text: entry.modelData.label
|
||||
font.family: Appearance.fontFamily
|
||||
font.pixelSize: Appearance.fontSize
|
||||
color: entryMouse.containsMouse ? Colors.primaryText : Colors.foreground
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: entryMouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
proc.command = entry.modelData.cmd
|
||||
proc.running = true
|
||||
menu.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
32
dotfiles/.config/quickshell/modules/bar/Tray.qml
Normal file
32
dotfiles/.config/quickshell/modules/bar/Tray.qml
Normal file
@@ -0,0 +1,32 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Services.SystemTray
|
||||
import Quickshell.Widgets
|
||||
import "../../config"
|
||||
|
||||
RowLayout {
|
||||
spacing: Appearance.spacing * 0.6
|
||||
|
||||
Repeater {
|
||||
model: SystemTray.items
|
||||
|
||||
delegate: IconImage {
|
||||
id: trayIcon
|
||||
required property var modelData
|
||||
implicitWidth: 16
|
||||
implicitHeight: 16
|
||||
source: modelData.icon
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onClicked: (mouse) => {
|
||||
if (mouse.button === Qt.LeftButton)
|
||||
trayIcon.modelData.activate()
|
||||
else
|
||||
trayIcon.modelData.secondaryActivate()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
43
dotfiles/.config/quickshell/modules/bar/Volume.qml
Normal file
43
dotfiles/.config/quickshell/modules/bar/Volume.qml
Normal file
@@ -0,0 +1,43 @@
|
||||
import QtQuick
|
||||
import Quickshell.Services.Pipewire
|
||||
import "../../config"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
implicitWidth: label.implicitWidth + 4
|
||||
implicitHeight: Appearance.barHeight
|
||||
|
||||
readonly property var sink: Pipewire.defaultAudioSink
|
||||
readonly property real vol: (sink && sink.audio) ? sink.audio.volume : 0
|
||||
readonly property bool muted: (sink && sink.audio) ? sink.audio.muted : false
|
||||
|
||||
PwObjectTracker { objects: root.sink ? [root.sink] : [] }
|
||||
|
||||
Text {
|
||||
id: label
|
||||
anchors.centerIn: parent
|
||||
font.family: Appearance.iconFontFamily
|
||||
font.variableAxes: Appearance.iconFontAxes
|
||||
font.pixelSize: 16
|
||||
color: Colors.foreground
|
||||
text: {
|
||||
if (root.muted || root.vol <= 0) return "volume_off"
|
||||
if (root.vol < 0.5) return "volume_down"
|
||||
return "volume_up"
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onClicked: if (root.sink && root.sink.audio) root.sink.audio.muted = !root.sink.audio.muted
|
||||
|
||||
onWheel: (wheel) => {
|
||||
if (!root.sink || !root.sink.audio) return
|
||||
const step = 0.05
|
||||
const delta = wheel.angleDelta.y > 0 ? step : -step
|
||||
root.sink.audio.volume = Math.max(0, Math.min(1, root.sink.audio.volume + delta))
|
||||
}
|
||||
}
|
||||
}
|
||||
44
dotfiles/.config/quickshell/modules/bar/Workspaces.qml
Normal file
44
dotfiles/.config/quickshell/modules/bar/Workspaces.qml
Normal file
@@ -0,0 +1,44 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Hyprland
|
||||
import "../../config"
|
||||
|
||||
RowLayout {
|
||||
id: root
|
||||
property var screen
|
||||
|
||||
spacing: 4
|
||||
|
||||
Repeater {
|
||||
model: Hyprland.workspaces
|
||||
|
||||
delegate: Rectangle {
|
||||
id: pill
|
||||
required property var modelData
|
||||
visible: modelData.monitor && root.screen && modelData.monitor.name === root.screen.name
|
||||
|
||||
implicitWidth: 26
|
||||
implicitHeight: 22
|
||||
radius: Appearance.radiusSmall
|
||||
color: modelData.urgent ? Colors.urgent
|
||||
: modelData.active ? Colors.primary
|
||||
: "transparent"
|
||||
|
||||
Behavior on color { ColorAnimation { duration: Appearance.animationDuration } }
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: modelData.name
|
||||
font.family: Appearance.fontFamily
|
||||
font.pixelSize: Appearance.fontSizeSmall
|
||||
color: modelData.active ? Colors.primaryText : Colors.foreground
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: Hyprland.dispatch("workspace " + modelData.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user