added three new modules (Crypto.qml, Battery.qml, Network.qml), improved Stats.qml, improved Tray.qml, optimized code in general, added a polkit agent, configurations change (check configs)

This commit is contained in:
SomeElse
2026-05-14 04:56:33 +00:00
parent 046a36fbec
commit e3bfa6661f
31 changed files with 5857 additions and 353 deletions

728
bar/modules/Network.qml Normal file
View File

@@ -0,0 +1,728 @@
import QtQuick
import QtQuick.Layouts
import Quickshell
import Quickshell.Wayland
import Quickshell.Networking
import Quickshell.Services.Polkit
import "../../config" as Cfg
Rectangle {
id: root
property real panelRadius: Cfg.Config.radius / 2
property int borderWidth: Cfg.Config.panelBorderWidth
property bool isTop: true
property var targetScreen: null
property int barHeight: Cfg.Config.barHeight
property int barMargin: Cfg.Config.margin
readonly property var t: Cfg.Config.theme
readonly property var wifiDevice: {
for (const dev of (Networking.devices?.values ?? []))
if (dev.type === DeviceType.Wifi) return dev
return null
}
readonly property var wiredDevice: {
for (const dev of (Networking.devices?.values ?? []))
if (dev.type === DeviceType.Wired) return dev
return null
}
readonly property bool hasWifi: wifiDevice !== null
readonly property bool hasWired: wiredDevice !== null
readonly property bool wifiUp: hasWifi && wifiDevice.connected
readonly property bool wiredUp: hasWired && wiredDevice.connected
readonly property string connectivityLabel: {
switch (Networking.connectivity) {
case NetworkConnectivity.Portal: return "Captive Portal"
case NetworkConnectivity.Limited: return "Limited"
case NetworkConnectivity.None: return "No Internet"
default: return ""
}
}
readonly property string wifiModeLabel: {
if (!wifiUp || !wifiDevice) return ""
switch (wifiDevice.mode) {
case WifiDeviceMode.Infra: return "Infra"
case WifiDeviceMode.Ap: return "AP"
case WifiDeviceMode.Adhoc: return "Ad-Hoc"
case WifiDeviceMode.Mesh: return "Mesh"
default: return ""
}
}
readonly property var activeAP: {
for (const n of (wifiDevice?.networks?.values ?? []))
if (n.connected) return n
return null
}
readonly property string ssid: activeAP ? (activeAP.name || "") : ""
readonly property int strength: activeAP ? Math.round((activeAP.signalStrength || 0) * 100) : 0
readonly property string wifiIcon: {
if (!wifiUp) return "󰤭"
if (strength >= 80) return "󰤨"
if (strength >= 60) return "󰤥"
if (strength >= 40) return "󰤢"
if (strength >= 20) return "󰤟"
return "󰤯"
}
readonly property string displayIcon: hasWifi ? wifiIcon : ""
readonly property color iconColor: {
if (hasWifi) return wifiUp ? t.statusOk : t.statusErr
if (hasWired) return wiredUp ? t.statusOk : t.statusErr
return t.textDim
}
readonly property string chipLabel: {
if (hasWifi) return (wifiUp && ssid !== "") ? ssid : "Wi-Fi"
if (hasWired) return wiredUp ? "Ethernet" : "Offline"
return "No NIC"
}
property var pendingAP: null
property string pendingSSID: ""
property bool showPwdPrompt: false
property string enteredPwd: ""
function attemptConnect() {
if (!pendingAP) return
if (enteredPwd.length > 0)
pendingAP.connectWithPsk(enteredPwd)
else
pendingAP.connect()
pendingAP = null
pendingSSID = ""
enteredPwd = ""
showPwdPrompt = false
}
function cancelConnect() {
pendingAP = null
pendingSSID = ""
enteredPwd = ""
showPwdPrompt = false
}
implicitWidth: chipRow.implicitWidth + 24
height: Cfg.Config.moduleHeight
radius: panelRadius
color: chipHover.hovered ? t.netBgHover : t.netBg
border.color: chipHover.hovered ? t.netBorderHover : t.netBorder
border.width: borderWidth
Behavior on implicitWidth { NumberAnimation { duration: 250; easing.type: Easing.OutCubic } }
Behavior on color { ColorAnimation { duration: 150 } }
Behavior on border.color { ColorAnimation { duration: 150 } }
HoverHandler { id: chipHover; cursorShape: Qt.PointingHandCursor }
TapHandler { onTapped: netPopup.toggle() }
RowLayout {
id: chipRow
anchors.centerIn: parent
spacing: 6
Text {
text: root.displayIcon
color: root.iconColor
font.pixelSize: 16
Layout.alignment: Qt.AlignVCenter
SequentialAnimation on opacity {
running: root.hasWifi && root.wifiDevice
&& (root.wifiDevice.scannerEnabled || false)
loops: Animation.Infinite
NumberAnimation { to: 0.4; duration: 600; easing.type: Easing.InOutSine }
NumberAnimation { to: 1.0; duration: 600; easing.type: Easing.InOutSine }
}
opacity: 1.0
}
Text {
text: root.chipLabel
color: root.t.netText
font.pixelSize: 12
font.bold: true
verticalAlignment: Text.AlignVCenter
Layout.maximumWidth: 110
elide: Text.ElideRight
}
}
PanelWindow {
id: netPopup
screen: root.targetScreen
visible: false
color: "transparent"
property bool popupOpen: false
function open() {
root.cancelConnect()
hideTimer.stop()
visible = true
popupOpen = true
if (root.hasWifi && root.wifiDevice)
root.wifiDevice.scannerEnabled = true
}
function close() { popupOpen = false; hideTimer.restart() }
function toggle() { popupOpen ? close() : open() }
Timer {
id: hideTimer
interval: Cfg.Config.popupAnimDuration + 70
onTriggered: netPopup.visible = false
}
anchors { top: true; bottom: true; left: true; right: true }
WlrLayershell.layer: WlrLayer.Top
WlrLayershell.namespace: "main-shell-network"
WlrLayershell.exclusiveZone: -1
mask: netPopup.popupOpen ? null : _noInput
Region { id: _noInput }
TapHandler { onTapped: netPopup.close() }
Item {
id: popupClip
readonly property int cardW: 310
readonly property int screenPad: root.barMargin + 10
x: {
var cx = root.mapToItem(null, 0, 0).x + root.width / 2
var dx = cx - cardW / 2
return Math.max(screenPad, Math.min(dx, parent.width - cardW - screenPad))
}
width: cardW
anchors.top: root.isTop ? parent.top : undefined
anchors.bottom: root.isTop ? undefined : parent.bottom
anchors.topMargin: root.isTop ? (root.barHeight + 10) : 0
anchors.bottomMargin: root.isTop ? 0 : (root.barHeight + 10)
height: parent.height - root.barHeight - 10
clip: true
Rectangle {
id: card
width: parent.width
height: cardBody.implicitHeight + 24
anchors.top: root.isTop ? parent.top : undefined
anchors.bottom: root.isTop ? undefined : parent.bottom
transform: Translate {
y: netPopup.popupOpen ? 0 : (root.isTop ? -card.height : card.height)
Behavior on y {
NumberAnimation {
duration: Cfg.Config.popupAnimDuration
easing.type: Easing.OutExpo
}
enabled: netPopup.visible
}
}
opacity: netPopup.popupOpen ? 1.0 : 0.0
Behavior on opacity { NumberAnimation { duration: 200 } }
color: root.t.netPopupBg
radius: Cfg.Config.popupRadius
border.color: root.t.netPopupBorder
border.width: Cfg.Config.popupBorderWidth
layer.enabled: true
MouseArea { anchors.fill: parent; propagateComposedEvents: false }
ColumnLayout {
id: cardBody
anchors {
left: parent.left
right: parent.right
top: parent.top
margins: 16
topMargin: 18
}
spacing: 12
RowLayout {
Layout.fillWidth: true
spacing: 12
Text {
text: root.displayIcon
color: root.iconColor
font.pixelSize: 36
Layout.alignment: Qt.AlignVCenter
}
ColumnLayout {
spacing: 2
Layout.fillWidth: true
Text {
text: {
if (root.hasWifi)
return root.wifiUp
? (root.ssid !== "" ? root.ssid : "Connected")
: "Wi-Fi"
if (root.hasWired)
return root.wiredUp ? "Ethernet" : "Disconnected"
return "No Network"
}
color: root.t.netPopupHeader
font.pixelSize: 17
font.bold: true
elide: Text.ElideRight
Layout.fillWidth: true
}
Text {
text: {
if (root.hasWifi && root.wifiDevice) {
var st = root.wifiDevice.state
if (st === ConnectionState.Activating) return "Connecting..."
if (st === ConnectionState.Deactivating) return "Disconnecting..."
if (root.wifiUp && root.activeAP) {
var s = root.strength + "% signal"
if (root.wifiModeLabel !== "") s += " · " + root.wifiModeLabel
return s
}
if (st === ConnectionState.Deactivated)
return "Disconnected"
return "Not connected"
}
if (root.hasWired && root.wiredDevice)
return root.wiredDevice.name || "—"
return "No hardware found"
}
color: root.t.netPopupDim
font.pixelSize: 12
}
Text {
visible: root.connectivityLabel !== ""
text: root.connectivityLabel
color: root.t.statusErr
font.pixelSize: 11
}
}
Rectangle {
visible: root.hasWifi
width: 28; height: 28
radius: 8
color: scanHover.hovered ? root.t.netApHoverBg : "transparent"
border.color: root.t.netPopupBorder
border.width: 1
Behavior on color { ColorAnimation { duration: 120 } }
Text {
anchors.centerIn: parent
text: "\uf0450"
font.pixelSize: 15
color: scanHover.hovered ? root.t.accent : root.t.netPopupDim
RotationAnimator on rotation {
id: scanSpin; running: false
from: 0; to: 360; duration: 700; loops: 2
easing.type: Easing.InOutCubic
}
}
HoverHandler { id: scanHover; cursorShape: Qt.PointingHandCursor }
TapHandler {
onTapped: {
scanSpin.restart()
if (root.wifiDevice) root.wifiDevice.scannerEnabled = true
}
}
}
}
Rectangle { Layout.fillWidth: true; height: 1; color: root.t.netPopupSeparator }
ColumnLayout {
visible: root.hasWifi
Layout.fillWidth: true
spacing: 4
Text {
text: "AVAILABLE NETWORKS"
color: root.t.netPopupDim
font.pixelSize: 10
font.letterSpacing: 1.2
Layout.fillWidth: true
}
Text {
visible: root.hasWifi && root.wifiDevice
&& root.wifiDevice.networks.values.length === 0
text: (root.wifiDevice && (root.wifiDevice.scannerEnabled || false))
? "Scanning..." : "No networks found"
color: root.t.netPopupDim
font.pixelSize: 12
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: 4
}
Repeater {
model: (root.hasWifi && root.wifiDevice) ? root.wifiDevice.networks.values : []
delegate: Rectangle {
required property var modelData
Layout.fillWidth: true
height: 50
radius: 10
color: {
var active = modelData.connected || false
if (active) return root.t.netApActiveBg
if (apHover.hovered) return root.t.netApHoverBg
return "transparent"
}
border.color: (modelData.connected || false) ? root.t.accent : "transparent"
border.width: 1
Behavior on color { ColorAnimation { duration: 120 } }
Behavior on border.color { ColorAnimation { duration: 120 } }
HoverHandler { id: apHover; cursorShape: Qt.PointingHandCursor }
TapHandler {
onTapped: {
if (modelData.connected || false) return
if (modelData.security !== WifiSecurityType.None) {
root.pendingAP = modelData
root.pendingSSID = modelData.name || ""
root.enteredPwd = ""
root.showPwdPrompt = true
} else {
modelData.connect()
}
}
}
RowLayout {
anchors { fill: parent; leftMargin: 12; rightMargin: 12 }
spacing: 10
Text {
text: {
var s = Math.round((modelData.signalStrength || 0) * 100)
if (s >= 80) return "\uf0ec8"
if (s >= 60) return "\uf0ec5"
if (s >= 40) return "\uf0ec2"
if (s >= 20) return "\uf0ebf"
return "\uf0eef"
}
color: (modelData.connected || false)
? root.t.accent : root.t.netPopupDim
font.pixelSize: 18
Layout.alignment: Qt.AlignVCenter
}
ColumnLayout {
spacing: 2
Layout.fillWidth: true
Text {
text: modelData.name || "(hidden)"
color: (modelData.connected || false)
? root.t.netPopupHeader
: root.t.netPopupText
font.pixelSize: 13
font.bold: (modelData.connected || false)
elide: Text.ElideRight
Layout.fillWidth: true
}
Text {
text: {
if (modelData.stateChanging)
return modelData.state === ConnectionState.Activating
? "Connecting..." : "Disconnecting..."
var parts = []
if (modelData.known) parts.push("Saved")
if (modelData.security !== WifiSecurityType.None) parts.push("Secured")
else parts.push("Open")
parts.push(Math.round((modelData.signalStrength || 0) * 100) + "%")
return parts.join(" · ")
}
color: root.t.netPopupDim
font.pixelSize: 11
}
}
Text {
visible: (modelData.security !== WifiSecurityType.None) && !(modelData.connected || false)
text: "\uf033e"
color: root.t.netPopupDim
font.pixelSize: 13
Layout.alignment: Qt.AlignVCenter
}
Text {
visible: (modelData.connected || false)
text: "\uf012c"
color: root.t.statusOk
font.pixelSize: 15
Layout.alignment: Qt.AlignVCenter
}
}
}
}
Rectangle {
visible: root.wifiUp
Layout.fillWidth: true
Layout.topMargin: 4
height: 36; radius: 10
color: discoHover.hovered
? root.t.netDisconnectBg : "transparent"
border.color: root.t.netDisconnectBorder
border.width: 1
Behavior on color { ColorAnimation { duration: 120 } }
HoverHandler { id: discoHover; cursorShape: Qt.PointingHandCursor }
TapHandler {
onTapped: {
if (root.activeAP)
root.activeAP.disconnect()
}
}
Text {
anchors.centerIn: parent
text: "Disconnect"
color: root.t.statusErr
font.pixelSize: 12
font.bold: true
}
}
}
ColumnLayout {
visible: !root.hasWifi && root.hasWired
Layout.fillWidth: true
spacing: 10
Text {
text: "CONNECTION DETAILS"
color: root.t.netPopupDim
font.pixelSize: 10
font.letterSpacing: 1.2
Layout.fillWidth: true
}
Rectangle {
Layout.fillWidth: true
height: 38; radius: 10
color: root.wiredUp
? root.t.netWiredOkBg
: root.t.netWiredErrBg
border.color: root.wiredUp
? root.t.netWiredOkBorder
: root.t.netWiredErrBorder
border.width: 1
RowLayout {
anchors { fill: parent; leftMargin: 14; rightMargin: 14 }
spacing: 10
Text {
text: root.wiredUp ? "\uf0601" : "\uf0602"
color: root.wiredUp ? root.t.statusOk : root.t.statusErr
font.pixelSize: 18
Layout.alignment: Qt.AlignVCenter
}
Text {
text: root.wiredUp ? "Connected" : "Cable unplugged"
color: root.wiredUp ? root.t.statusOk : root.t.statusErr
font.pixelSize: 13
font.bold: true
Layout.fillWidth: true
}
}
}
ColumnLayout {
Layout.fillWidth: true
spacing: 6
Repeater {
model: [
{
label: "Interface",
value: (root.wiredDevice && root.wiredDevice.name)
? root.wiredDevice.name : "—"
},
{
label: "MAC",
value: (root.wiredDevice && root.wiredDevice.address)
? root.wiredDevice.address : "—"
},
{
label: "Link",
value: (root.wiredDevice)
? (root.wiredDevice.hasLink ? "Up" : "Down") : "—"
},
{
label: "Speed",
value: (root.wiredDevice && root.wiredUp &&
root.wiredDevice.linkSpeed > 0)
? (root.wiredDevice.linkSpeed + " Mbps") : "—"
}
]
delegate: RowLayout {
required property var modelData
Layout.fillWidth: true
Text {
text: modelData.label
color: root.t.netPopupDim
font.pixelSize: 12
Layout.fillWidth: true
}
Text {
text: modelData.value
color: root.t.netPopupText
font.pixelSize: 12
font.bold: true
font.family: "monospace"
}
}
}
}
}
Text {
visible: !root.hasWifi && !root.hasWired
text: "No network hardware detected."
color: root.t.netPopupDim
font.pixelSize: 12
horizontalAlignment: Text.AlignHCenter
Layout.fillWidth: true
Layout.topMargin: 4
}
ColumnLayout {
visible: root.showPwdPrompt
Layout.fillWidth: true
spacing: 8
Rectangle { Layout.fillWidth: true; height: 1; color: root.t.netPopupSeparator }
Text {
text: "Connect to \"" + root.pendingSSID + "\""
color: root.t.netPopupHeader
font.pixelSize: 13
font.bold: true
elide: Text.ElideRight
Layout.fillWidth: true
}
Rectangle {
Layout.fillWidth: true
height: 36; radius: 8
color: root.t.netFieldBg
border.color: pwdField.activeFocus ? root.t.accent : root.t.netPopupBorder
border.width: 1
Behavior on border.color { ColorAnimation { duration: 120 } }
RowLayout {
anchors { fill: parent; leftMargin: 12; rightMargin: 10 }
spacing: 6
TextInput {
id: pwdField
Layout.fillWidth: true
verticalAlignment: TextInput.AlignVCenter
echoMode: eyeToggle.showClear
? TextInput.Normal : TextInput.Password
color: root.t.netPopupText
font.pixelSize: 13
selectionColor: Qt.alpha(root.t.accent, 0.4)
clip: true
text: root.enteredPwd
onTextChanged: root.enteredPwd = text
Keys.onReturnPressed: root.attemptConnect()
Keys.onEscapePressed: root.cancelConnect()
onVisibleChanged: if (visible) forceActiveFocus()
Text {
anchors.fill: parent
verticalAlignment: Text.AlignVCenter
text: "Password"
color: root.t.netPopupDim
font.pixelSize: 13
visible: pwdField.text === "" && !pwdField.activeFocus
}
}
Text {
id: eyeToggle
property bool showClear: false
text: showClear ? "\uf0349" : "\uf0354"
color: eyeHover.hovered ? root.t.accent : root.t.netPopupDim
font.pixelSize: 15
Layout.alignment: Qt.AlignVCenter
HoverHandler { id: eyeHover; cursorShape: Qt.PointingHandCursor }
TapHandler { onTapped: eyeToggle.showClear = !eyeToggle.showClear }
}
}
}
RowLayout {
Layout.fillWidth: true
spacing: 8
Rectangle {
Layout.fillWidth: true
height: 34; radius: 8
color: cancelHover.hovered ? root.t.netCancelBgHover : "transparent"
border.color: root.t.netPopupBorder
border.width: 1
Behavior on color { ColorAnimation { duration: 120 } }
HoverHandler { id: cancelHover; cursorShape: Qt.PointingHandCursor }
TapHandler { onTapped: root.cancelConnect() }
Text {
anchors.centerIn: parent
text: "Cancel"
color: root.t.netPopupDim
font.pixelSize: 12
}
}
Rectangle {
Layout.fillWidth: true
height: 34; radius: 8
color: connHover.hovered ? root.t.accent : Qt.alpha(root.t.accent, 0.75)
Behavior on color { ColorAnimation { duration: 120 } }
HoverHandler { id: connHover; cursorShape: Qt.PointingHandCursor }
TapHandler { onTapped: root.attemptConnect() }
Text {
anchors.centerIn: parent
text: "Connect"
color: root.t.netConnectText
font.pixelSize: 12
font.bold: true
}
}
}
}
Item { height: 4 }
}
}
}
}
}