per-group borders, workspace hover, battery notifications, richer network tooltip
This commit is contained in:
parent
b8ec39f2c9
commit
0eda2c71c9
7 changed files with 69 additions and 16 deletions
|
|
@ -40,6 +40,7 @@ PanelWindow {
|
||||||
spacing: M.Theme.barSpacing
|
spacing: M.Theme.barSpacing
|
||||||
|
|
||||||
M.BarGroup {
|
M.BarGroup {
|
||||||
|
borderColor: M.Theme.base0D
|
||||||
M.Clock { visible: M.Modules.clock }
|
M.Clock { visible: M.Modules.clock }
|
||||||
M.Notifications { visible: M.Modules.notifications }
|
M.Notifications { visible: M.Modules.notifications }
|
||||||
}
|
}
|
||||||
|
|
@ -53,12 +54,15 @@ PanelWindow {
|
||||||
spacing: M.Theme.barSpacing
|
spacing: M.Theme.barSpacing
|
||||||
|
|
||||||
M.BarGroup {
|
M.BarGroup {
|
||||||
|
borderColor: M.Theme.base0D
|
||||||
M.Workspaces { bar: bar; visible: M.Modules.workspaces }
|
M.Workspaces { bar: bar; visible: M.Modules.workspaces }
|
||||||
}
|
}
|
||||||
M.BarGroup {
|
M.BarGroup {
|
||||||
|
borderColor: M.Theme.base0D
|
||||||
M.Tray { bar: bar; visible: M.Modules.tray }
|
M.Tray { bar: bar; visible: M.Modules.tray }
|
||||||
}
|
}
|
||||||
M.BarGroup {
|
M.BarGroup {
|
||||||
|
borderColor: M.Theme.base0D
|
||||||
M.WindowTitle {
|
M.WindowTitle {
|
||||||
Layout.maximumWidth: 400
|
Layout.maximumWidth: 400
|
||||||
visible: M.Modules.windowTitle
|
visible: M.Modules.windowTitle
|
||||||
|
|
@ -78,18 +82,21 @@ PanelWindow {
|
||||||
|
|
||||||
// Media
|
// Media
|
||||||
M.BarGroup {
|
M.BarGroup {
|
||||||
|
borderColor: M.Theme.base0E
|
||||||
M.Mpris {}
|
M.Mpris {}
|
||||||
M.Volume { visible: M.Modules.volume }
|
M.Volume { visible: M.Modules.volume }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connectivity
|
// Connectivity
|
||||||
M.BarGroup {
|
M.BarGroup {
|
||||||
|
borderColor: M.Theme.base0D
|
||||||
M.Network { visible: M.Modules.network }
|
M.Network { visible: M.Modules.network }
|
||||||
M.Bluetooth {}
|
M.Bluetooth {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Controls
|
// Controls
|
||||||
M.BarGroup {
|
M.BarGroup {
|
||||||
|
borderColor: M.Theme.base0A
|
||||||
M.Backlight {}
|
M.Backlight {}
|
||||||
M.PowerProfile { visible: M.Modules.powerProfile }
|
M.PowerProfile { visible: M.Modules.powerProfile }
|
||||||
M.IdleInhibitor { visible: M.Modules.idleInhibitor }
|
M.IdleInhibitor { visible: M.Modules.idleInhibitor }
|
||||||
|
|
@ -97,6 +104,7 @@ PanelWindow {
|
||||||
|
|
||||||
// Stats
|
// Stats
|
||||||
M.BarGroup {
|
M.BarGroup {
|
||||||
|
borderColor: M.Theme.base08
|
||||||
M.Cpu { visible: M.Modules.cpu }
|
M.Cpu { visible: M.Modules.cpu }
|
||||||
M.Memory { visible: M.Modules.memory }
|
M.Memory { visible: M.Modules.memory }
|
||||||
M.Temperature { visible: M.Modules.temperature }
|
M.Temperature { visible: M.Modules.temperature }
|
||||||
|
|
@ -106,6 +114,7 @@ PanelWindow {
|
||||||
|
|
||||||
// Power
|
// Power
|
||||||
M.BarGroup {
|
M.BarGroup {
|
||||||
|
borderColor: M.Theme.base08
|
||||||
M.Battery {}
|
M.Battery {}
|
||||||
M.Power { bar: bar; visible: M.Modules.power }
|
M.Power { bar: bar; visible: M.Modules.power }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,10 @@ Rectangle {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
default property alias content: row.children
|
default property alias content: row.children
|
||||||
|
property color borderColor: M.Theme.base02
|
||||||
|
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
border.color: M.Theme.base02
|
border.color: borderColor
|
||||||
border.width: 1
|
border.width: 1
|
||||||
radius: M.Theme.radius
|
radius: M.Theme.radius
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
import Quickshell.Io
|
||||||
import Quickshell.Services.UPower
|
import Quickshell.Services.UPower
|
||||||
import "." as M
|
import "." as M
|
||||||
|
|
||||||
|
|
@ -21,6 +22,25 @@ M.BarSection {
|
||||||
|
|
||||||
Behavior on _stateColor { ColorAnimation { duration: 300 } }
|
Behavior on _stateColor { ColorAnimation { duration: 300 } }
|
||||||
|
|
||||||
|
property bool _warnSent: false
|
||||||
|
property bool _critSent: false
|
||||||
|
|
||||||
|
onChargingChanged: { _warnSent = false; _critSent = false; }
|
||||||
|
onPctChanged: {
|
||||||
|
if (charging) return;
|
||||||
|
if (pct < 15 && !_critSent) {
|
||||||
|
_critSent = true; _warnSent = true;
|
||||||
|
_notif.command = ["notify-send", "--urgency=critical", "--icon=battery-low", "--category=device", "Very Low Battery", "Connect to power now!"];
|
||||||
|
_notif.running = true;
|
||||||
|
} else if (pct < 25 && !_warnSent) {
|
||||||
|
_warnSent = true;
|
||||||
|
_notif.command = ["notify-send", "--icon=battery-caution", "--category=device", "Low Battery"];
|
||||||
|
_notif.running = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process { id: _notif }
|
||||||
|
|
||||||
M.BarIcon {
|
M.BarIcon {
|
||||||
icon: {
|
icon: {
|
||||||
if (root.charging)
|
if (root.charging)
|
||||||
|
|
|
||||||
|
|
@ -65,4 +65,5 @@ M.BarSection {
|
||||||
toggle.running = true;
|
toggle.running = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,33 +6,44 @@ M.BarSection {
|
||||||
id: root
|
id: root
|
||||||
spacing: M.Theme.moduleSpacing
|
spacing: M.Theme.moduleSpacing
|
||||||
tooltip: {
|
tooltip: {
|
||||||
if (root.state === "wifi")
|
const parts = [];
|
||||||
return "WiFi: " + root.essid + (root.ifname ? "\nInterface: " + root.ifname : "");
|
if (root.state === "wifi") {
|
||||||
if (root.state === "eth")
|
parts.push("WiFi: " + root.essid);
|
||||||
return "Ethernet: " + root.ifname;
|
if (root.signal) parts.push("Signal: " + root.signal + "%");
|
||||||
if (root.state === "linked")
|
} else if (root.state === "eth") {
|
||||||
return "Linked: " + root.ifname;
|
parts.push("Ethernet");
|
||||||
return "Disconnected";
|
} else if (root.state === "linked") {
|
||||||
|
parts.push("Linked");
|
||||||
|
} else {
|
||||||
|
return "Disconnected";
|
||||||
|
}
|
||||||
|
if (root.ipAddr) parts.push("IP: " + root.ipAddr);
|
||||||
|
if (root.ifname) parts.push("Interface: " + root.ifname);
|
||||||
|
return parts.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
property string ifname: ""
|
property string ifname: ""
|
||||||
property string essid: ""
|
property string essid: ""
|
||||||
property string state: "disconnected"
|
property string state: "disconnected"
|
||||||
|
property string ipAddr: ""
|
||||||
|
property string signal: ""
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: proc
|
id: proc
|
||||||
running: true
|
running: true
|
||||||
command: ["sh", "-c", "line=$(nmcli -t -f NAME,TYPE,DEVICE connection show --active 2>/dev/null | head -1); if [ -n \"$line\" ]; then echo \"$line\"; else dev=$(nmcli -t -f DEVICE,STATE device 2>/dev/null | grep ':connected' | grep -v ':unmanaged\\|:unavailable\\|:disconnected\\|:connecting' | head -1 | cut -d: -f1); if [ -n \"$dev\" ]; then echo \"linked:linked:$dev\"; fi; fi"]
|
command: ["sh", "-c", "line=$(nmcli -t -f NAME,TYPE,DEVICE connection show --active 2>/dev/null | head -1); if [ -z \"$line\" ]; then dev=$(nmcli -t -f DEVICE,STATE device 2>/dev/null | grep ':connected' | grep -v ':unmanaged\\|:unavailable\\|:disconnected\\|:connecting' | head -1 | cut -d: -f1); [ -n \"$dev\" ] && line=\"linked:linked:$dev\"; fi; [ -z \"$line\" ] && exit 0; echo \"$line\"; dev=$(echo \"$line\" | cut -d: -f3); ip=$(nmcli -t -f IP4.ADDRESS device show \"$dev\" 2>/dev/null | head -1 | cut -d: -f2); echo \"ip:${ip:-}\"; sig=$(nmcli -t -f GENERAL.SIGNAL device show \"$dev\" 2>/dev/null | head -1 | cut -d: -f2); echo \"sig:${sig:-}\""]
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
onStreamFinished: {
|
onStreamFinished: {
|
||||||
const line = text.trim();
|
const lines = text.trim().split("\n");
|
||||||
if (!line) {
|
if (!lines[0]) {
|
||||||
root.state = "disconnected";
|
root.state = "disconnected";
|
||||||
root.essid = "";
|
root.essid = "";
|
||||||
root.ifname = "";
|
root.ifname = "";
|
||||||
|
root.ipAddr = "";
|
||||||
|
root.signal = "";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const parts = line.split(":");
|
const parts = lines[0].split(":");
|
||||||
root.essid = parts[0] || "";
|
root.essid = parts[0] || "";
|
||||||
root.ifname = parts[2] || "";
|
root.ifname = parts[2] || "";
|
||||||
if ((parts[1] || "").includes("wireless"))
|
if ((parts[1] || "").includes("wireless"))
|
||||||
|
|
@ -41,6 +52,15 @@ M.BarSection {
|
||||||
root.state = "linked";
|
root.state = "linked";
|
||||||
else
|
else
|
||||||
root.state = "eth";
|
root.state = "eth";
|
||||||
|
// Parse extra info lines
|
||||||
|
root.ipAddr = "";
|
||||||
|
root.signal = "";
|
||||||
|
for (let i = 1; i < lines.length; i++) {
|
||||||
|
if (lines[i].startsWith("ip:"))
|
||||||
|
root.ipAddr = lines[i].slice(3);
|
||||||
|
else if (lines[i].startsWith("sig:"))
|
||||||
|
root.signal = lines[i].slice(4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -70,4 +90,5 @@ M.BarSection {
|
||||||
color: root.state === "disconnected" ? M.Theme.base08 : M.Theme.base0C
|
color: root.state === "disconnected" ? M.Theme.base08 : M.Theme.base0C
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,7 @@ M.PopupPanel {
|
||||||
property var _currentHandle: handle
|
property var _currentHandle: handle
|
||||||
property var _handleStack: []
|
property var _handleStack: []
|
||||||
|
|
||||||
QsMenuOpener {
|
property QsMenuOpener _opener: QsMenuOpener {
|
||||||
id: opener
|
|
||||||
menu: menuWindow._currentHandle
|
menu: menuWindow._currentHandle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,7 +51,7 @@ M.PopupPanel {
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: opener.children
|
model: menuWindow._opener.children
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
id: entryItem
|
id: entryItem
|
||||||
|
|
|
||||||
|
|
@ -69,9 +69,11 @@ Row {
|
||||||
required property var modelData
|
required property var modelData
|
||||||
|
|
||||||
readonly property bool active: modelData.id === root._activeId
|
readonly property bool active: modelData.id === root._activeId
|
||||||
|
property bool _hovered: false
|
||||||
|
|
||||||
HoverHandler {
|
HoverHandler {
|
||||||
onHoveredChanged: {
|
onHoveredChanged: {
|
||||||
|
pill._hovered = hovered;
|
||||||
const name = pill.modelData.name || ("Workspace " + pill.modelData.idx);
|
const name = pill.modelData.name || ("Workspace " + pill.modelData.idx);
|
||||||
if (hovered) {
|
if (hovered) {
|
||||||
M.FlyoutState.text = name;
|
M.FlyoutState.text = name;
|
||||||
|
|
@ -87,7 +89,7 @@ Row {
|
||||||
width: 20
|
width: 20
|
||||||
height: 20
|
height: 20
|
||||||
radius: M.Theme.radius
|
radius: M.Theme.radius
|
||||||
color: pill.active ? M.Theme.base0D : M.Theme.base02
|
color: pill.active ? M.Theme.base0D : (pill._hovered ? M.Theme.base03 : M.Theme.base02)
|
||||||
Behavior on color { ColorAnimation { duration: 150 } }
|
Behavior on color { ColorAnimation { duration: 150 } }
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue