Compare commits

...

4 commits

Author SHA1 Message Date
Damocles
186c9a3aa2 move stuff into components 2026-04-12 01:00:05 +02:00
Damocles
14292e6683 move stuff into components 2026-04-12 00:56:17 +02:00
Damocles
6370732e4e add tooltips 2026-04-12 00:49:58 +02:00
Damocles
7ca7e1e952 add scrool or click actions 2026-04-12 00:46:38 +02:00
20 changed files with 147 additions and 49 deletions

View file

@ -2,13 +2,26 @@ import QtQuick
import Quickshell.Io
import "." as M
Row {
M.BarSection {
id: root
spacing: 4
visible: percent > 0
tooltip: "Brightness: " + root.percent + "%"
property int percent: 0
Process {
id: adjProc
property string cmd: ""
command: ["sh", "-c", cmd]
onRunningChanged: if (!running && cmd !== "") current.reload()
}
function adjust(delta) {
adjProc.cmd = delta > 0 ? "light -A 5" : "light -U 5";
adjProc.running = true;
}
FileView {
id: current
path: "/sys/class/backlight/intel_backlight/brightness"
@ -36,4 +49,8 @@ Row {
font.family: M.Theme.fontFamily
anchors.verticalCenter: parent.verticalCenter
}
WheelHandler {
onWheel: event => root.adjust(event.angleDelta.y)
}
}

View file

@ -1,12 +1,20 @@
import QtQuick
import QtQuick.Controls
import "." as M
Text {
property string icon: ""
property string tooltip: ""
text: icon
color: M.Theme.base05
font.pixelSize: M.Theme.fontSize + 1
font.family: M.Theme.iconFontFamily
verticalAlignment: Text.AlignVCenter
HoverHandler { id: _hover }
ToolTip {
visible: _hover.hovered && parent.tooltip !== ""
text: parent.tooltip
}
}

View file

@ -1,12 +1,20 @@
import QtQuick
import QtQuick.Controls
import "." as M
Text {
property string label: ""
property string tooltip: ""
text: label
color: M.Theme.base05
font.pixelSize: M.Theme.fontSize
font.family: M.Theme.fontFamily
verticalAlignment: Text.AlignVCenter
HoverHandler { id: _hover }
ToolTip {
visible: _hover.hovered && parent.tooltip !== ""
text: parent.tooltip
}
}

12
modules/BarSection.qml Normal file
View file

@ -0,0 +1,12 @@
import QtQuick
import QtQuick.Controls
Row {
property string tooltip: ""
HoverHandler { id: _hover }
ToolTip {
visible: _hover.hovered && parent.tooltip !== ""
text: parent.tooltip
}
}

View file

@ -2,10 +2,17 @@ import QtQuick
import Quickshell.Services.UPower
import "." as M
Row {
M.BarSection {
id: root
spacing: 4
visible: UPower.displayDevice?.isLaptopBattery ?? false
tooltip: {
const state = root.charging ? "Charging" : "Discharging";
const t = root.charging ? root.dev?.timeToFull : root.dev?.timeToEmpty;
const mins = t ? Math.round(t / 60) : 0;
const timeStr = mins > 0 ? "\n" + Math.floor(mins / 60) + "h " + (mins % 60) + "m " + (root.charging ? "until full" : "remaining") : "";
return state + " \u2014 " + Math.round(root.pct) + "%" + timeStr;
}
readonly property var dev: UPower.displayDevice
readonly property real pct: (dev?.percentage ?? 0) * 100

View file

@ -2,9 +2,10 @@ import QtQuick
import Quickshell.Io
import "." as M
Row {
M.BarSection {
id: root
spacing: 4
tooltip: root.status === "connected" ? "Bluetooth: " + root.device : "Bluetooth: on"
property string status: "off"
property string device: ""

View file

@ -2,15 +2,13 @@ import QtQuick
import Quickshell
import "." as M
Text {
M.BarLabel {
SystemClock {
id: clock
precision: SystemClock.Minutes
precision: SystemClock.Seconds
}
text: Qt.formatDateTime(clock.date, "ddd, dd. MMM HH:mm")
color: M.Theme.base05
font.pixelSize: M.Theme.fontSize + 1
font.family: M.Theme.fontFamily
verticalAlignment: Text.AlignVCenter
label: Qt.formatDateTime(clock.date, "ddd, dd. MMM HH:mm")
tooltip: Qt.formatDateTime(clock.date, "dddd, dd. MMMM yyyy\nHH:mm:ss")
}

View file

@ -2,13 +2,13 @@ import QtQuick
import Quickshell.Io
import "." as M
Row {
M.BarSection {
id: root
spacing: 2
tooltip: "CPU: " + root.usage + "%\n" + root.freqGhz.toFixed(2) + " GHz"
property int usage: 0
property real freqGhz: 0
property var _prev: null
FileView {
@ -25,10 +25,7 @@ Row {
if (dTotal > 0)
root.usage = Math.round((1 - dIdle / dTotal) * 100);
}
root._prev = {
idle,
total
};
root._prev = { idle, total };
}
}
FileView {
@ -36,8 +33,7 @@ Row {
path: "/proc/cpuinfo"
onLoaded: {
const lines = text().split("\n").filter(l => l.startsWith("cpu MHz"));
if (lines.length === 0)
return;
if (lines.length === 0) return;
const sum = lines.reduce((a, l) => a + parseFloat(l.split(":")[1]), 0);
root.freqGhz = sum / lines.length / 1000;
}
@ -46,10 +42,7 @@ Row {
interval: 1000
running: true
repeat: true
onTriggered: {
stat.reload();
cpuinfo.reload();
}
onTriggered: { stat.reload(); cpuinfo.reload(); }
}
M.BarIcon {

View file

@ -2,9 +2,10 @@ import QtQuick
import Quickshell.Io
import "." as M
Row {
M.BarSection {
id: root
spacing: 2
tooltip: root.freePct + "% free of " + root.totalTb.toFixed(1) + " TB"
property int freePct: 0
property real totalTb: 0

View file

@ -4,6 +4,7 @@ import "." as M
M.BarIcon {
id: root
tooltip: "Idle inhibition: " + (root.active ? "active" : "inactive")
property bool active: false

View file

@ -2,9 +2,10 @@ import QtQuick
import Quickshell.Io
import "." as M
Row {
M.BarSection {
id: root
spacing: 2
tooltip: "Memory: " + root.percent + "% used"
property int percent: 0
@ -15,8 +16,7 @@ Row {
const m = {};
text().split("\n").forEach(l => {
const [k, v] = l.split(":");
if (v)
m[k.trim()] = parseInt(v.trim());
if (v) m[k.trim()] = parseInt(v.trim());
});
const total = m.MemTotal;
const avail = m.MemAvailable;

View file

@ -2,10 +2,19 @@ import QtQuick
import Quickshell.Services.Mpris
import "." as M
Row {
M.BarSection {
id: root
spacing: 4
visible: player !== null
tooltip: {
const p = root.player;
if (!p) return "";
const parts = [];
if (p.trackTitle) parts.push(p.trackTitle);
if (p.trackArtists?.length) parts.push(p.trackArtists.join(", "));
if (p.trackAlbum) parts.push(p.trackAlbum);
return parts.join("\n") || p.identity;
}
readonly property MprisPlayer player: Mpris.players.values[0] ?? null
readonly property bool playing: player?.playbackState === MprisPlaybackState.Playing

View file

@ -2,9 +2,15 @@ import QtQuick
import Quickshell.Io
import "." as M
Row {
M.BarSection {
id: root
spacing: 4
tooltip: {
if (root.state === "wifi") return "WiFi: " + root.essid + (root.ifname ? "\nInterface: " + root.ifname : "");
if (root.state === "eth") return "Ethernet: " + root.ifname;
if (root.state === "linked") return "Linked: " + root.ifname;
return "Disconnected";
}
property string ifname: ""
property string essid: ""
@ -44,12 +50,9 @@ Row {
M.BarIcon {
icon: {
if (root.state === "wifi")
return "\uF1EB";
if (root.state === "eth")
return "\uDB80\uDE00";
if (root.state === "linked")
return "\uDB85\uDE16";
if (root.state === "wifi") return "\uF1EB";
if (root.state === "eth") return "\uDB80\uDE00";
if (root.state === "linked") return "\uDB85\uDE16";
return "\uDB82\uDCFD";
}
anchors.verticalCenter: parent.verticalCenter

View file

@ -2,9 +2,15 @@ import QtQuick
import Quickshell.Io
import "." as M
Row {
M.BarSection {
id: root
spacing: 4
tooltip: {
const parts = [root.count + " notification" + (root.count !== 1 ? "s" : "")];
if (root.dnd) parts.push("Do not disturb");
if (root.inhibited) parts.push("Inhibited");
return parts.join("\n");
}
property int count: 0
property bool dnd: false
@ -55,7 +61,5 @@ Row {
clicker.running = true;
}
}
Process {
id: clicker
}
Process { id: clicker }
}

View file

@ -4,6 +4,7 @@ import "." as M
M.BarIcon {
id: root
tooltip: "Power profile: " + (root.profile || "unknown")
property string profile: ""
@ -28,4 +29,20 @@ M.BarIcon {
repeat: true
onTriggered: proc.running = true
}
Process {
id: setter
property string next: ""
command: ["powerprofilesctl", "set", next]
onRunningChanged: if (!running && next !== "") proc.running = true
}
TapHandler {
onTapped: {
const cycle = ["performance", "balanced", "power-saver"];
const idx = cycle.indexOf(root.profile);
setter.next = cycle[(idx + 1) % cycle.length];
setter.running = true;
}
}
}

View file

@ -2,9 +2,10 @@ import QtQuick
import Quickshell.Io
import "." as M
Row {
M.BarSection {
id: root
spacing: 2
tooltip: "Temperature: " + root.celsius + "\u00B0C"
property int celsius: 0
@ -26,7 +27,7 @@ Row {
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: root.celsius + "°C"
text: root.celsius + "\u00B0C"
color: root.celsius > 80 ? M.Theme.base08 : M.Theme.base05
font.pixelSize: M.Theme.fontSize
font.family: M.Theme.fontFamily

View file

@ -2,9 +2,12 @@ import QtQuick
import Quickshell.Services.Pipewire
import "." as M
Row {
M.BarSection {
id: root
spacing: 4
tooltip: (root.sink?.description ?? root.sink?.name ?? "Unknown sink") +
"\nVolume: " + Math.round(root.volume * 100) + "%" +
(root.muted ? "\nMuted" : "")
PwObjectTracker {
objects: [Pipewire.defaultAudioSink]
@ -26,4 +29,11 @@ Row {
TapHandler {
onTapped: if (root.sink?.audio) root.sink.audio.muted = !root.sink.audio.muted
}
WheelHandler {
onWheel: event => {
if (!root.sink?.audio) return;
root.sink.audio.volume = Math.max(0, root.sink.audio.volume + (event.angleDelta.y > 0 ? 0.05 : -0.05));
}
}
}

View file

@ -2,10 +2,12 @@ import QtQuick
import Quickshell.Io
import "." as M
Text {
M.BarSection {
id: root
spacing: 4
tooltip: root.weatherTooltip
property string label: ""
property string weatherTooltip: ""
Process {
id: proc
@ -15,9 +17,11 @@ Text {
onStreamFinished: {
try {
const data = JSON.parse(text);
root.label = data.text ?? "";
label.text = data.text ?? "";
root.weatherTooltip = data.tooltip ?? "";
} catch (e) {
root.label = "";
label.text = "";
root.weatherTooltip = "";
}
}
}
@ -29,9 +33,11 @@ Text {
onTriggered: proc.running = true
}
text: root.label
Text {
id: label
color: M.Theme.base05
font.pixelSize: M.Theme.fontSize
font.family: M.Theme.iconFontFamily
verticalAlignment: Text.AlignVCenter
anchors.verticalCenter: parent.verticalCenter
}
}

View file

@ -4,6 +4,7 @@ import "." as M
M.BarIcon {
icon: "\uF011"
tooltip: "Open logout menu"
Process {
id: proc

View file

@ -1,6 +1,7 @@
module modules
singleton Theme 1.0 Theme.qml
Bar 1.0 Bar.qml
BarSection 1.0 BarSection.qml
Workspaces 1.0 Workspaces.qml
WindowTitle 1.0 WindowTitle.qml
Clock 1.0 Clock.qml