plugin: rust-side modules + theme services with serde-typed config

This commit is contained in:
Damocles 2026-05-04 22:58:12 +02:00
parent a86e90e927
commit f34f3f2f4e
95 changed files with 2477 additions and 1011 deletions

View file

@ -4,6 +4,7 @@ import Quickshell
import Quickshell.Wayland
import "." as M
import "../services" as S
import NovaStats as NS
PanelWindow {
id: root
@ -43,9 +44,9 @@ PanelWindow {
Text {
text: Qt.formatDateTime(clock.date, "HH")
color: S.Theme.base0D
color: NS.ThemeService.base0D
font.pixelSize: 72
font.family: S.Theme.fontFamily
font.family: NS.ThemeService.fontFamily
font.bold: true
anchors.verticalCenter: parent.verticalCenter
}
@ -53,22 +54,22 @@ PanelWindow {
text: ":"
color: colon._colors[colon._colorIdx % colon._colors.length]
Behavior on color {
enabled: !S.Theme.reducedMotion
enabled: !S.ThemeUtil.reducedMotion
ColorAnimation {
duration: 500
}
}
font.pixelSize: 72
font.family: S.Theme.fontFamily
font.family: NS.ThemeService.fontFamily
font.bold: true
opacity: colon.opacity
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: Qt.formatDateTime(clock.date, "mm")
color: S.Theme.base0E
color: NS.ThemeService.base0E
font.pixelSize: 72
font.family: S.Theme.fontFamily
font.family: NS.ThemeService.fontFamily
font.bold: true
anchors.verticalCenter: parent.verticalCenter
}
@ -78,7 +79,7 @@ PanelWindow {
source: glowSource
anchors.fill: glowSource
shadowEnabled: true
shadowColor: S.Theme.base0D
shadowColor: NS.ThemeService.base0D
shadowBlur: 1.0
shadowVerticalOffset: 0
shadowHorizontalOffset: 0
@ -91,10 +92,10 @@ PanelWindow {
Text {
text: Qt.formatDateTime(clock.date, "HH")
color: S.Theme.base0D
color: NS.ThemeService.base0D
opacity: 0.85
font.pixelSize: 72
font.family: S.Theme.fontFamily
font.family: NS.ThemeService.fontFamily
font.bold: true
anchors.verticalCenter: parent.verticalCenter
}
@ -102,16 +103,16 @@ PanelWindow {
id: colon
text: ":"
font.pixelSize: 72
font.family: S.Theme.fontFamily
font.family: NS.ThemeService.fontFamily
font.bold: true
opacity: 0.85
anchors.verticalCenter: parent.verticalCenter
property int _colorIdx: 0
readonly property var _colors: [S.Theme.base08, S.Theme.base09, S.Theme.base0A, S.Theme.base0B, S.Theme.base0C, S.Theme.base0D, S.Theme.base0E, S.Theme.base05]
readonly property var _colors: [NS.ThemeService.base08, NS.ThemeService.base09, NS.ThemeService.base0A, NS.ThemeService.base0B, NS.ThemeService.base0C, NS.ThemeService.base0D, NS.ThemeService.base0E, NS.ThemeService.base05]
color: _colors[_colorIdx % _colors.length]
Behavior on color {
enabled: !S.Theme.reducedMotion
enabled: !S.ThemeUtil.reducedMotion
ColorAnimation {
duration: 500
}
@ -139,7 +140,7 @@ PanelWindow {
Connections {
target: clock
function onDateChanged() {
if (S.Theme.reducedMotion)
if (S.ThemeUtil.reducedMotion)
return;
colon._colorIdx++;
colonAnim.restart();
@ -148,10 +149,10 @@ PanelWindow {
}
Text {
text: Qt.formatDateTime(clock.date, "mm")
color: S.Theme.base0E
color: NS.ThemeService.base0E
opacity: 0.85
font.pixelSize: 72
font.family: S.Theme.fontFamily
font.family: NS.ThemeService.fontFamily
font.bold: true
anchors.verticalCenter: parent.verticalCenter
}
@ -163,16 +164,16 @@ PanelWindow {
id: dateText
anchors.horizontalCenter: parent.horizontalCenter
text: Qt.formatDateTime(clock.date, "dddd, dd MMMM yyyy")
color: S.Theme.base05
color: NS.ThemeService.base05
opacity: 0.5
font.pixelSize: 18
font.family: S.Theme.fontFamily
font.family: NS.ThemeService.fontFamily
font.letterSpacing: 4
layer.enabled: true
layer.effect: MultiEffect {
shadowEnabled: true
shadowColor: S.Theme.base0D
shadowColor: NS.ThemeService.base0D
shadowBlur: 0.4
shadowVerticalOffset: 0
shadowHorizontalOffset: 0
@ -187,7 +188,7 @@ PanelWindow {
Rectangle {
anchors.fill: parent
color: S.Theme.base02
color: NS.ThemeService.base02
radius: 1
opacity: 0.3
}
@ -196,7 +197,7 @@ PanelWindow {
height: parent.height
color: colon._colors[colon._colorIdx % colon._colors.length]
Behavior on color {
enabled: !S.Theme.reducedMotion
enabled: !S.ThemeUtil.reducedMotion
ColorAnimation {
duration: 500
}
@ -205,7 +206,7 @@ PanelWindow {
opacity: 0.6
Behavior on width {
enabled: !S.Theme.reducedMotion
enabled: !S.ThemeUtil.reducedMotion
NumberAnimation {
duration: 50
}

View file

@ -3,11 +3,12 @@ import Quickshell
import "." as M
import "../services" as S
import "../applets" as C
import NovaStats as NS
M.BarModule {
id: root
spacing: S.Theme.moduleSpacing
active: S.Modules.backlight.enable && S.BacklightService.available
spacing: NS.ThemeService.moduleSpacing
active: NS.ModulesService.backlightEnable && S.BacklightService.available
tooltip: "Brightness: " + percent + "%"
panelNamespace: "nova-backlight"
panelContentWidth: 200

View file

@ -4,6 +4,7 @@ import Quickshell
import Quickshell.Wayland
import "." as M
import "../services" as S
import NovaStats as NS
PanelWindow {
id: bar
@ -19,13 +20,13 @@ PanelWindow {
margins.right: S.DockState.reservedWidthAnimated
implicitHeight: S.Theme.barHeight
implicitHeight: NS.ThemeService.barHeight
exclusiveZone: implicitHeight
Rectangle {
anchors.fill: parent
color: S.Theme.base00
opacity: S.Theme.barOpacity
color: NS.ThemeService.base00
opacity: NS.ThemeService.barOpacity
}
Canvas {
@ -35,7 +36,7 @@ PanelWindow {
const ctx = getContext("2d");
const w = width;
const h = height;
const r = S.Theme.screenRadius;
const r = NS.ThemeService.screenRadius;
const lw = 3;
const hw = lw / 2;
@ -43,8 +44,8 @@ PanelWindow {
// Glow wash behind the border
const glowGrad = ctx.createLinearGradient(0, 0, w, 0);
glowGrad.addColorStop(0, S.Theme.base0C.toString());
glowGrad.addColorStop(1, S.Theme.base09.toString());
glowGrad.addColorStop(0, NS.ThemeService.base0C.toString());
glowGrad.addColorStop(1, NS.ThemeService.base09.toString());
ctx.globalAlpha = 0.25;
ctx.fillStyle = glowGrad;
ctx.fillRect(0, 0, w, h);
@ -61,8 +62,8 @@ PanelWindow {
// Horizontal gradient for the border
const grad = ctx.createLinearGradient(0, 0, w, 0);
grad.addColorStop(0, S.Theme.base0C.toString());
grad.addColorStop(1, S.Theme.base09.toString());
grad.addColorStop(0, NS.ThemeService.base0C.toString());
grad.addColorStop(1, NS.ThemeService.base09.toString());
ctx.strokeStyle = grad;
ctx.lineWidth = lw;
@ -97,16 +98,16 @@ PanelWindow {
Item {
anchors.fill: parent
anchors.topMargin: S.Theme.groupSpacing
anchors.leftMargin: S.Theme.groupSpacing
anchors.rightMargin: S.Theme.groupSpacing
anchors.topMargin: NS.ThemeService.groupSpacing
anchors.leftMargin: NS.ThemeService.groupSpacing
anchors.rightMargin: NS.ThemeService.groupSpacing
// ---- center (declared first so left/right can anchor to it) ----
RowLayout {
id: centerSection
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
spacing: S.Theme.groupSpacing
spacing: NS.ThemeService.groupSpacing
M.BarGroup {
M.PrivacyModule {}
@ -120,7 +121,7 @@ PanelWindow {
anchors.left: parent.left
anchors.right: centerSection.left
anchors.verticalCenter: parent.verticalCenter
spacing: S.Theme.groupSpacing
spacing: NS.ThemeService.groupSpacing
M.BarGroup {
id: workspacesGroup
@ -135,10 +136,10 @@ PanelWindow {
id: _windowTitleGroup
Layout.minimumWidth: 0
clip: true
visible: S.Modules.windowTitle.enable && S.NiriIpc.focusedTitle !== ""
visible: NS.ModulesService.windowTitleEnable && S.NiriIpc.focusedTitle !== ""
M.WindowTitleModule {
id: _windowTitle
readonly property real _maxWidth: Math.max(0, centerSection.x - _windowTitleGroup.x - 2 * S.Theme.groupPadding - S.Theme.groupSpacing)
readonly property real _maxWidth: Math.max(0, centerSection.x - _windowTitleGroup.x - 2 * NS.ThemeService.groupPadding - NS.ThemeService.groupSpacing)
width: Math.min(naturalWidth, _maxWidth)
}
}
@ -152,7 +153,7 @@ PanelWindow {
anchors.left: centerSection.right
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
spacing: S.Theme.groupSpacing
spacing: NS.ThemeService.groupSpacing
Item {
Layout.fillWidth: true

View file

@ -3,6 +3,7 @@ import QtQuick.Effects
import Quickshell
import "." as M
import "../services" as S
import NovaStats as NS
Item {
id: root
@ -18,14 +19,14 @@ Item {
const effectiveWidth = scr.width - (S.DockState.reservedWidthAnimated ?? 0);
return Math.max(0, Math.min(1, gx / (effectiveWidth > 0 ? effectiveWidth : scr.width)));
}
property color borderColor: Qt.rgba(S.Theme.base0C.r + (S.Theme.base09.r - S.Theme.base0C.r) * _posFrac, S.Theme.base0C.g + (S.Theme.base09.g - S.Theme.base0C.g) * _posFrac, S.Theme.base0C.b + (S.Theme.base09.b - S.Theme.base0C.b) * _posFrac, 1)
property color borderColor: Qt.rgba(NS.ThemeService.base0C.r + (NS.ThemeService.base09.r - NS.ThemeService.base0C.r) * _posFrac, NS.ThemeService.base0C.g + (NS.ThemeService.base09.g - NS.ThemeService.base0C.g) * _posFrac, NS.ThemeService.base0C.b + (NS.ThemeService.base09.b - NS.ThemeService.base0C.b) * _posFrac, 1)
property bool leftEdge: false
property bool rightEdge: false
readonly property real _tlr: leftEdge ? S.Theme.screenRadius : S.Theme.radius
readonly property real _trr: rightEdge ? S.Theme.screenRadius : S.Theme.radius
readonly property real _blr: S.Theme.radius
readonly property real _brr: S.Theme.radius
readonly property real _tlr: leftEdge ? NS.ThemeService.screenRadius : NS.ThemeService.radius
readonly property real _trr: rightEdge ? NS.ThemeService.screenRadius : NS.ThemeService.radius
readonly property real _blr: NS.ThemeService.radius
readonly property real _brr: NS.ThemeService.radius
// Check children's `active` instead of visibleChildren to avoid circular
// effectiveVisible dependency: if the BarGroup is invisible, children's
@ -41,9 +42,9 @@ Item {
}
implicitWidth: row.implicitWidth + _pad * 2
implicitHeight: S.Theme.barHeight - 3 - _pad
implicitHeight: NS.ThemeService.barHeight - 3 - _pad
readonly property int _pad: S.Theme.groupPadding
readonly property int _pad: NS.ThemeService.groupPadding
property bool _hovered: false
HoverHandler {
@ -57,7 +58,7 @@ Item {
topRightRadius: root._trr
bottomLeftRadius: root._blr
bottomRightRadius: root._brr
color: Qt.rgba(S.Theme.base01.r, S.Theme.base01.g, S.Theme.base01.b, 0.55)
color: Qt.rgba(NS.ThemeService.base01.r, NS.ThemeService.base01.g, NS.ThemeService.base01.b, 0.55)
}
// Frost sheen subtle white highlight, top-heavy
@ -137,7 +138,7 @@ Item {
property real _pulse: 0.08
SequentialAnimation on _pulse {
running: root._hovered && !S.Theme.reducedMotion
running: root._hovered && !S.ThemeUtil.reducedMotion
loops: Animation.Infinite
NumberAnimation {
to: 0.22
@ -156,7 +157,7 @@ Item {
id: row
property color accentColor: root.borderColor
anchors.centerIn: parent
spacing: S.Theme.moduleSpacing + 2
spacing: NS.ThemeService.moduleSpacing + 2
}
// Separator lines overlaid between visible row children

View file

@ -1,5 +1,6 @@
import QtQuick
import "../services" as S
import NovaStats as NS
// Icon element with crossfade animation on icon change.
// Pure visual component - tooltip handling lives in the parent BarModule.
@ -7,7 +8,7 @@ Text {
id: root
property string icon: ""
property string minIcon: ""
property color accentColor: parent?.accentColor ?? S.Theme.base05
property color accentColor: parent?.accentColor ?? NS.ThemeService.base05
property string _displayIcon: icon
property string _pendingIcon: ""
@ -42,8 +43,8 @@ Text {
width: minIcon ? Math.max(implicitWidth, _minIconMetrics.width) : implicitWidth
horizontalAlignment: minIcon ? Text.AlignHCenter : Text.AlignLeft
color: root.accentColor
font.pixelSize: S.Theme.fontSize + 1
font.family: S.Theme.iconFontFamily
font.pixelSize: NS.ThemeService.fontSize + 1
font.family: NS.ThemeService.iconFontFamily
verticalAlignment: Text.AlignVCenter
TextMetrics {

View file

@ -1,5 +1,6 @@
import QtQuick
import "../services" as S
import NovaStats as NS
// Label element with minimum-width support via minText.
// Pure visual component - tooltip handling lives in the parent BarModule.
@ -7,14 +8,14 @@ Text {
id: root
property string label: ""
property string minText: ""
property color accentColor: parent?.accentColor ?? S.Theme.base05
property color accentColor: parent?.accentColor ?? NS.ThemeService.base05
text: label
width: minText ? Math.max(implicitWidth, _minMetrics.width) : implicitWidth
horizontalAlignment: minText ? Text.AlignHCenter : Text.AlignLeft
color: root.accentColor
font.pixelSize: S.Theme.fontSize
font.family: S.Theme.fontFamily
font.pixelSize: NS.ThemeService.fontSize
font.family: NS.ThemeService.fontFamily
verticalAlignment: Text.AlignVCenter
TextMetrics {

View file

@ -2,6 +2,7 @@ import QtQuick
import Quickshell
import "." as M
import "../services" as S
import NovaStats as NS
// Unified base component for all bar modules.
// Provides: tooltip on hover, panel state management, OSD flash support.
@ -20,7 +21,7 @@ Row {
property string tooltip: ""
property bool _hovered: false
property color accentColor: parent?.accentColor ?? S.Theme.base05
property color accentColor: parent?.accentColor ?? NS.ThemeService.base05
property int cursorShape: Qt.PointingHandCursor
// Panel state

View file

@ -3,11 +3,12 @@ import Quickshell
import "." as M
import "../services" as S
import "../applets" as C
import NovaStats as NS
M.BarModule {
id: root
spacing: S.Theme.moduleSpacing
active: S.Modules.battery.enable && S.BatteryService.available
spacing: NS.ThemeService.moduleSpacing
active: NS.ModulesService.batteryEnable && S.BatteryService.available
tooltip: "Battery: " + Math.round(S.BatteryService.percent) + "%" + (S.BatteryService.charging ? " (charging)" : "")
panelNamespace: "nova-battery"
panelContentWidth: 240
@ -35,7 +36,7 @@ M.BarModule {
}
color: S.BatteryService.stateColor
opacity: root._blinkOpacity
font.pixelSize: S.Theme.fontSize + 2
font.pixelSize: NS.ThemeService.fontSize + 2
anchors.verticalCenter: parent.verticalCenter
}
M.BarLabel {

View file

@ -3,11 +3,12 @@ import Quickshell
import "." as M
import "../services" as S
import "../applets" as C
import NovaStats as NS
M.BarModule {
id: root
spacing: S.Theme.moduleSpacing
active: S.Modules.bluetooth.enable && S.BluetoothService.state !== "unavailable"
spacing: NS.ThemeService.moduleSpacing
active: NS.ModulesService.bluetoothEnable && S.BluetoothService.state !== "unavailable"
tooltip: {
if (S.BluetoothService.state === "connected")
return "Bluetooth: " + S.BluetoothService.device;
@ -33,7 +34,7 @@ M.BarModule {
M.BarIcon {
icon: "\uF294"
color: S.BluetoothService.state === "off" ? S.Theme.base04 : root.accentColor
color: S.BluetoothService.state === "off" ? NS.ThemeService.base04 : root.accentColor
anchors.verticalCenter: parent.verticalCenter
}
M.BarLabel {

View file

@ -3,11 +3,12 @@ import Quickshell
import "." as M
import "../services" as S
import "../applets" as C
import NovaStats as NS
M.BarModule {
id: root
active: S.Modules.clock.enable
spacing: S.Theme.moduleSpacing
active: NS.ModulesService.clockEnable
spacing: NS.ThemeService.moduleSpacing
tooltip: Qt.formatDateTime(clock.date, "dddd, dd. MMMM yyyy HH:mm:ss")
panelNamespace: "nova-clock"
panelContentWidth: 220
@ -25,7 +26,7 @@ M.BarModule {
}
M.BarLabel {
font.pixelSize: S.Theme.fontSize + 1
font.pixelSize: NS.ThemeService.fontSize + 1
label: Qt.formatDateTime(clock.date, "ddd, dd. MMM HH:mm")
minText: "Wed, 00. Sep 00:00"
anchors.verticalCenter: parent.verticalCenter

View file

@ -3,11 +3,12 @@ import Quickshell
import "." as M
import "../services" as S
import "../applets" as C
import NovaStats as NS
M.BarModule {
id: root
active: S.Modules.cpu.enable
spacing: Math.max(1, S.Theme.moduleSpacing - 2)
active: NS.ModulesService.cpuEnable
spacing: Math.max(1, NS.ThemeService.moduleSpacing - 2)
tooltip: "CPU: " + S.CpuService.usage + "% @ " + S.CpuService.freqGhz.toFixed(2) + " GHz"
panelNamespace: "nova-cpu"
panelContentWidth: 260

View file

@ -3,11 +3,12 @@ import Quickshell
import "." as M
import "../services" as S
import "../applets" as C
import NovaStats as NS
M.BarModule {
id: root
active: S.Modules.disk.enable
spacing: Math.max(1, S.Theme.moduleSpacing - 2)
active: NS.ModulesService.diskEnable
spacing: Math.max(1, NS.ThemeService.moduleSpacing - 2)
tooltip: "Disk: " + _rootPct + "% used"
panelNamespace: "nova-disk"
panelContentWidth: 260
@ -21,7 +22,7 @@ M.BarModule {
property var _mounts: S.SystemStats.diskMounts
property int _rootPct: S.SystemStats.diskRootPct
readonly property int _warnThreshold: S.Modules.disk.warnThreshold ?? 85
readonly property int _warnThreshold: NS.ModulesService.diskWarnThreshold ?? 85
readonly property bool _anyWarn: {
for (const m of _mounts)
if (m.pct >= _warnThreshold)
@ -31,13 +32,13 @@ M.BarModule {
M.BarIcon {
icon: "\uF0C9"
color: root._anyWarn ? S.Theme.base09 : root.accentColor
color: root._anyWarn ? NS.ThemeService.base09 : root.accentColor
anchors.verticalCenter: parent.verticalCenter
}
M.BarLabel {
label: root._rootPct + "%"
minText: "100%"
color: root._anyWarn ? S.Theme.base09 : root.accentColor
color: root._anyWarn ? NS.ThemeService.base09 : root.accentColor
anchors.verticalCenter: parent.verticalCenter
}
}

View file

@ -1,10 +1,11 @@
import QtQuick
import "." as M
import "../services" as S
import NovaStats as NS
M.BarModule {
id: root
active: S.Modules.dock.enable && S.DockState.mode !== "pinned"
active: NS.ModulesService.dockEnable && S.DockState.mode !== "pinned"
tooltip: S.DockState.open ? "Close dock" : "Open dock"
onTapped: S.DockState.toggle()

View file

@ -3,11 +3,12 @@ import Quickshell
import "." as M
import "../services" as S
import "../applets" as C
import NovaStats as NS
M.BarModule {
id: root
spacing: Math.max(1, S.Theme.moduleSpacing - 2)
active: S.Modules.gpu.enable && S.SystemStats.gpuAvailable
spacing: Math.max(1, NS.ThemeService.moduleSpacing - 2)
active: NS.ModulesService.gpuEnable && S.SystemStats.gpuAvailable
tooltip: "GPU: " + S.SystemStats.gpuUsage + "%"
panelNamespace: "nova-gpu"
panelContentWidth: 240

View file

@ -3,6 +3,7 @@ import Quickshell
import Quickshell.Wayland
import "." as M
import "../services" as S
import NovaStats as NS
// Bar panel - fullscreen transparent window so content can resize freely
// without triggering Wayland surface resizes.
@ -83,7 +84,7 @@ PanelWindow {
}
_winVisible = true;
hideAnim.stop();
if (S.Theme.reducedMotion) {
if (S.ThemeUtil.reducedMotion) {
panelContainer.opacity = 1;
panelContainer.y = 0;
} else {
@ -97,7 +98,7 @@ PanelWindow {
if (!_winVisible)
return;
showAnim.stop();
if (S.Theme.reducedMotion) {
if (S.ThemeUtil.reducedMotion) {
_winVisible = false;
dismissed();
} else {
@ -185,7 +186,7 @@ PanelWindow {
y: panelContainer.y
width: panelContainer.width
height: panelContainer.height
opacity: panelContainer.opacity * Math.max(S.Theme.barOpacity, 0.85)
opacity: panelContainer.opacity * Math.max(NS.ThemeService.barOpacity, 0.85)
accentColor: root.accentColor
}
@ -228,7 +229,7 @@ PanelWindow {
color: "transparent"
border.color: root.accentColor
border.width: 1
radius: S.Theme.radius
radius: NS.ThemeService.radius
opacity: panelContainer.opacity
}
}

View file

@ -2,10 +2,11 @@ import QtQuick
import Quickshell
import "." as M
import "../services" as S
import NovaStats as NS
M.BarModule {
id: root
active: S.Modules.idleInhibitor.enable
active: NS.ModulesService.idleInhibitorEnable
tooltip: {
const parts = ["Idle inhibition: " + (S.IdleInhibitService.active ? "active" : "inactive")];
if (S.IdleInhibitService.inhibitors)
@ -23,7 +24,7 @@ M.BarModule {
}
M.BarIcon {
color: S.IdleInhibitService.active ? S.Theme.base09 : root.accentColor
color: S.IdleInhibitService.active ? NS.ThemeService.base09 : root.accentColor
icon: S.IdleInhibitService.active ? "\uF06E" : "\uF070"
anchors.verticalCenter: parent.verticalCenter
}

View file

@ -5,10 +5,11 @@ import Quickshell
import "." as M
import "../services" as S
import "../applets" as C
import NovaStats as NS
M.BarModule {
id: root
active: S.Modules.machinectl.enable
active: NS.ModulesService.machinectlEnable
tooltip: {
const n = S.MachinectlService.machines.length;
return n === 0 ? "no containers" : n + " container" + (n === 1 ? "" : "s");
@ -30,7 +31,7 @@ M.BarModule {
}
}
readonly property color _stateColor: S.MachinectlService.anyUnhealthy ? S.Theme.base0A : root.accentColor
readonly property color _stateColor: S.MachinectlService.anyUnhealthy ? NS.ThemeService.base0A : root.accentColor
M.BarIcon {
icon: ""

View file

@ -3,11 +3,12 @@ import Quickshell
import "." as M
import "../services" as S
import "../applets" as C
import NovaStats as NS
M.BarModule {
id: root
active: S.Modules.memory.enable
spacing: Math.max(1, S.Theme.moduleSpacing - 2)
active: NS.ModulesService.memoryEnable
spacing: Math.max(1, NS.ThemeService.moduleSpacing - 2)
tooltip: "Memory: " + usedGb.toFixed(1) + " / " + totalGb.toFixed(1) + " GB"
panelNamespace: "nova-memory"
panelContentWidth: 240

View file

@ -5,11 +5,12 @@ import Quickshell.Services.Mpris
import "." as M
import "../services" as S
import "../applets" as C
import NovaStats as NS
M.BarModule {
id: root
spacing: S.Theme.moduleSpacing
active: S.Modules.mpris.enable && S.MprisService.player !== null
spacing: NS.ThemeService.moduleSpacing
active: NS.ModulesService.mprisEnable && S.MprisService.player !== null
tooltip: S.MprisService.player ? (S.MprisService.player.trackTitle || S.MprisService.player.identity || "Media") + (S.MprisService.playing ? " (playing)" : " (paused)") : "Media"
panelNamespace: "nova-mpris"
panelContentWidth: 280

View file

@ -3,11 +3,12 @@ import Quickshell
import "." as M
import "../services" as S
import "../applets" as C
import NovaStats as NS
M.BarModule {
id: root
active: S.Modules.network.enable
spacing: S.Theme.moduleSpacing
active: NS.ModulesService.networkEnable
spacing: NS.ThemeService.moduleSpacing
tooltip: {
if (state === "wifi")
return "Wi-Fi: " + S.NetworkService.essid;
@ -45,13 +46,13 @@ M.BarModule {
return "\uDB85\uDE16";
return "\uDB82\uDCFD";
}
color: root.state === "disconnected" ? S.Theme.base08 : root.accentColor
color: root.state === "disconnected" ? NS.ThemeService.base08 : root.accentColor
anchors.verticalCenter: parent.verticalCenter
}
M.BarLabel {
visible: root.state === "wifi"
label: S.NetworkService.essid
color: root.state === "disconnected" ? S.Theme.base08 : root.accentColor
color: root.state === "disconnected" ? NS.ThemeService.base08 : root.accentColor
anchors.verticalCenter: parent.verticalCenter
}
}

View file

@ -2,6 +2,7 @@ import QtQuick
import Quickshell.Services.Notifications
import "." as M
import "../services" as S
import NovaStats as NS
// Shared notification card: background, progress bar, urgency bar, icon, text, dismiss button.
// Does NOT include dismiss animation or dismiss logic emits dismissRequested() instead.
@ -14,7 +15,7 @@ Item {
property bool dismissOnAction: true
property int iconSize: 32
property int bodyMaxLines: 3
property color accentColor: S.Theme.base0D
property color accentColor: NS.ThemeService.base0D
signal dismissRequested
@ -36,9 +37,9 @@ Item {
// Background: base01, base02 on hover
Rectangle {
anchors.fill: parent
color: _hover.hovered ? S.Theme.base02 : S.Theme.base01
opacity: _hover.hovered ? 1.0 : Math.max(S.Theme.barOpacity, 0.9)
radius: S.Theme.radius
color: _hover.hovered ? NS.ThemeService.base02 : NS.ThemeService.base01
opacity: _hover.hovered ? 1.0 : Math.max(NS.ThemeService.barOpacity, 0.9)
radius: NS.ThemeService.radius
Behavior on color {
ColorAnimation {
@ -53,7 +54,7 @@ Item {
anchors.bottom: parent.bottom
anchors.left: parent.left
width: parent.width * Math.min(1, Math.max(0, (root.notif?.hints?.value ?? 0) / 100))
color: S.Theme.base03
color: NS.ThemeService.base03
radius: parent.radius
Behavior on width {
@ -73,7 +74,7 @@ Item {
radius: 1
color: {
const u = root.notif?.urgency ?? NotificationUrgency.Normal;
return u === NotificationUrgency.Critical ? S.Theme.base08 : u === NotificationUrgency.Low ? S.Theme.base04 : S.Theme.base0D;
return u === NotificationUrgency.Critical ? NS.ThemeService.base08 : u === NotificationUrgency.Low ? NS.ThemeService.base04 : NS.ThemeService.base0D;
}
}
@ -101,9 +102,9 @@ Item {
anchors.top: parent.top
anchors.topMargin: 8
text: "\uF00D"
color: _dismissHover.hovered ? S.Theme.base08 : S.Theme.base03
font.pixelSize: S.Theme.fontSize - 1
font.family: S.Theme.iconFontFamily
color: _dismissHover.hovered ? NS.ThemeService.base08 : NS.ThemeService.base03
font.pixelSize: NS.ThemeService.fontSize - 1
font.family: NS.ThemeService.iconFontFamily
opacity: _hover.hovered ? 1 : 0
HoverHandler {
@ -159,9 +160,9 @@ Item {
Text {
text: root.notif?.appName ?? "Notification"
color: S.Theme.base04
font.pixelSize: S.Theme.fontSize - 2
font.family: S.Theme.fontFamily
color: NS.ThemeService.base04
font.pixelSize: NS.ThemeService.fontSize - 2
font.family: NS.ThemeService.fontFamily
width: parent.width - _timeText.implicitWidth - 4
elide: Text.ElideRight
}
@ -169,9 +170,9 @@ Item {
Text {
id: _timeText
text: root.notif?.timeStr ?? ""
color: S.Theme.base03
font.pixelSize: S.Theme.fontSize - 2
font.family: S.Theme.fontFamily
color: NS.ThemeService.base03
font.pixelSize: NS.ThemeService.fontSize - 2
font.family: NS.ThemeService.fontFamily
}
}
@ -182,9 +183,9 @@ Item {
Text {
text: root.notif?.summary ?? ""
color: S.Theme.base05
font.pixelSize: S.Theme.fontSize
font.family: S.Theme.fontFamily
color: NS.ThemeService.base05
font.pixelSize: NS.ThemeService.fontSize
font.family: NS.ThemeService.fontFamily
font.bold: true
elide: Text.ElideRight
width: parent.width - _inlineTime.implicitWidth - 4
@ -193,9 +194,9 @@ Item {
Text {
id: _inlineTime
text: root.notif?.timeStr ?? ""
color: S.Theme.base03
font.pixelSize: S.Theme.fontSize - 2
font.family: S.Theme.fontFamily
color: NS.ThemeService.base03
font.pixelSize: NS.ThemeService.fontSize - 2
font.family: NS.ThemeService.fontFamily
anchors.verticalCenter: parent.verticalCenter
}
}
@ -204,9 +205,9 @@ Item {
visible: root.showAppName
width: parent.width
text: root.notif?.summary ?? ""
color: S.Theme.base05
font.pixelSize: S.Theme.fontSize
font.family: S.Theme.fontFamily
color: NS.ThemeService.base05
font.pixelSize: NS.ThemeService.fontSize
font.family: NS.ThemeService.fontFamily
font.bold: true
elide: Text.ElideRight
wrapMode: Text.WordWrap
@ -216,9 +217,9 @@ Item {
Text {
width: parent.width
text: root.notif?.body ?? ""
color: S.Theme.base04
font.pixelSize: S.Theme.fontSize - 1
font.family: S.Theme.fontFamily
color: NS.ThemeService.base04
font.pixelSize: NS.ThemeService.fontSize - 1
font.family: NS.ThemeService.fontFamily
elide: Text.ElideRight
wrapMode: Text.WordWrap
maximumLineCount: root.bodyMaxLines
@ -239,9 +240,9 @@ Item {
required property var modelData
width: _actText.implicitWidth + 12
height: _actText.implicitHeight + 6
radius: S.Theme.radius
color: _actHover.hovered ? S.Theme.base03 : "transparent"
border.color: S.Theme.base03
radius: NS.ThemeService.radius
color: _actHover.hovered ? NS.ThemeService.base03 : "transparent"
border.color: NS.ThemeService.base03
border.width: 1
Text {
@ -249,8 +250,8 @@ Item {
anchors.centerIn: parent
text: parent.modelData.text
color: root.accentColor
font.pixelSize: S.Theme.fontSize - 2
font.family: S.Theme.fontFamily
font.pixelSize: NS.ThemeService.fontSize - 2
font.family: NS.ThemeService.fontFamily
}
HoverHandler {

View file

@ -4,6 +4,7 @@ import Quickshell.Wayland
import Quickshell.Services.Notifications
import "." as M
import "../services" as S
import NovaStats as NS
PanelWindow {
id: root
@ -32,7 +33,7 @@ PanelWindow {
property var _knownIds: ({})
Repeater {
model: S.NotifService.popups.slice(0, S.Modules.notifications.maxPopups || 4)
model: S.NotifService.popups.slice(0, NS.ModulesService.notificationsMaxPopups || 4)
delegate: Item {
id: popupItem
@ -66,7 +67,7 @@ PanelWindow {
_heightScale = 1;
} else {
popupCol._knownIds[modelData.id] = true;
if (S.Theme.reducedMotion) {
if (S.ThemeUtil.reducedMotion) {
opacity = 1;
x = 0;
_heightScale = 1;
@ -86,7 +87,7 @@ PanelWindow {
}
Behavior on y {
enabled: popupItem._entered && !S.Theme.reducedMotion
enabled: popupItem._entered && !S.ThemeUtil.reducedMotion
NumberAnimation {
duration: 200
easing.type: Easing.OutCubic
@ -127,7 +128,7 @@ PanelWindow {
popupItem.modelData.beginDismiss();
_fullDismiss = !!full;
slideIn.stop();
if (S.Theme.reducedMotion) {
if (S.ThemeUtil.reducedMotion) {
full ? S.NotifService.dismiss(modelData.id) : S.NotifService.dismissPopup(modelData.id);
} else {
slideOut.start();

View file

@ -4,11 +4,12 @@ import Quickshell.Services.Notifications
import "." as M
import "../services" as S
import "../applets" as C
import NovaStats as NS
M.BarModule {
id: root
active: S.Modules.notifications.enable
spacing: S.Theme.moduleSpacing
active: NS.ModulesService.notificationsEnable
spacing: NS.ThemeService.moduleSpacing
tooltip: S.NotifService.count > 0 ? "Notifications: " + S.NotifService.count + (S.NotifService.dnd ? " (DND)" : "") : (S.NotifService.dnd ? "Do not disturb" : "No notifications")
panelNamespace: "nova-notifications"
panelContentWidth: 350
@ -28,13 +29,13 @@ M.BarModule {
return S.NotifService.count > 0 ? "\uDB80\uDCA0" : "\uDB82\uDE93";
return S.NotifService.count > 0 ? "\uDB84\uDD6B" : "\uDB80\uDC9C";
}
color: S.NotifService.dnd ? S.Theme.base04 : root.accentColor
color: S.NotifService.dnd ? NS.ThemeService.base04 : root.accentColor
anchors.verticalCenter: parent.verticalCenter
}
M.BarLabel {
id: countLabel
label: S.NotifService.count > 0 ? String(S.NotifService.count) + (root.hasUrgent ? "!" : "") : ""
color: root.hasUrgent ? S.Theme.base08 : root.accentColor
color: root.hasUrgent ? NS.ThemeService.base08 : root.accentColor
anchors.verticalCenter: parent.verticalCenter
transform: Scale {
@ -67,7 +68,7 @@ M.BarModule {
Connections {
target: S.NotifService
function onCountChanged() {
if (S.NotifService.count > 0 && !S.Theme.reducedMotion)
if (S.NotifService.count > 0 && !S.ThemeUtil.reducedMotion)
popAnim.start();
}
}

View file

@ -1,13 +1,14 @@
import QtQuick
import "." as M
import "../services" as S
import NovaStats as NS
Rectangle {
property color accentColor: S.Theme.base05
property color accentColor: NS.ThemeService.base05
color: S.Theme.base01
opacity: Math.max(S.Theme.barOpacity, 0.85)
radius: S.Theme.radius
color: NS.ThemeService.base01
opacity: Math.max(NS.ThemeService.barOpacity, 0.85)
radius: NS.ThemeService.radius
border.color: accentColor
border.width: 1
}

View file

@ -4,10 +4,11 @@ import Quickshell.Io
import "." as M
import "../services" as S
import "../applets" as C
import NovaStats as NS
M.BarModule {
id: root
active: S.Modules.power.enable
active: NS.ModulesService.powerEnable
tooltip: "Power menu"
panelNamespace: "nova-power"
panelContentWidth: 180

View file

@ -1,10 +1,11 @@
import QtQuick
import "." as M
import "../services" as S
import NovaStats as NS
M.BarModule {
id: root
active: S.Modules.powerProfile.enable
active: NS.ModulesService.powerProfileEnable
tooltip: "Power profile: " + (S.PowerProfileService.profile || "unknown")
onTapped: {
const cycle = ["performance", "balanced", "power-saver"];
@ -13,7 +14,7 @@ M.BarModule {
}
M.BarIcon {
color: S.PowerProfileService.profile === "performance" ? S.Theme.base09 : S.PowerProfileService.profile === "power-saver" ? S.Theme.base0B : root.accentColor
color: S.PowerProfileService.profile === "performance" ? NS.ThemeService.base09 : S.PowerProfileService.profile === "power-saver" ? NS.ThemeService.base0B : root.accentColor
icon: {
if (S.PowerProfileService.profile === "performance")
return "\uF0E7";

View file

@ -3,10 +3,11 @@ import QtQuick.Effects
import Quickshell.Services.Pipewire
import "." as M
import "../services" as S
import NovaStats as NS
M.BarModule {
id: root
spacing: S.Theme.moduleSpacing
spacing: NS.ThemeService.moduleSpacing
cursorShape: Qt.ArrowCursor
readonly property bool _videoCapture: {
@ -35,21 +36,21 @@ M.BarModule {
return false;
}
active: S.Modules.privacy.enable && (root._videoCapture || root._audioIn)
active: NS.ModulesService.privacyEnable && (root._videoCapture || root._audioIn)
// Screenshare indicator
Text {
visible: root._videoCapture
text: "\uF03D"
color: S.Theme.base08
font.pixelSize: S.Theme.fontSize + 2
font.family: S.Theme.iconFontFamily
color: NS.ThemeService.base08
font.pixelSize: NS.ThemeService.fontSize + 2
font.family: NS.ThemeService.iconFontFamily
anchors.verticalCenter: parent.verticalCenter
layer.enabled: true
layer.effect: MultiEffect {
shadowEnabled: true
shadowColor: S.Theme.base08
shadowColor: NS.ThemeService.base08
shadowBlur: 0.8
shadowVerticalOffset: 0
shadowHorizontalOffset: 0
@ -65,15 +66,15 @@ M.BarModule {
Text {
visible: root._audioIn
text: "\uF130"
color: S.Theme.base0B
font.pixelSize: S.Theme.fontSize + 2
font.family: S.Theme.iconFontFamily
color: NS.ThemeService.base0B
font.pixelSize: NS.ThemeService.fontSize + 2
font.family: NS.ThemeService.iconFontFamily
anchors.verticalCenter: parent.verticalCenter
layer.enabled: true
layer.effect: MultiEffect {
shadowEnabled: true
shadowColor: S.Theme.base0B
shadowColor: NS.ThemeService.base0B
shadowBlur: 0.8
shadowVerticalOffset: 0
shadowHorizontalOffset: 0

View file

@ -3,7 +3,7 @@ import "../services" as S
SequentialAnimation {
id: root
loops: S.Theme.reducedMotion ? 1 : Animation.Infinite
loops: S.ThemeUtil.reducedMotion ? 1 : Animation.Infinite
property real minOpacity: 0.4
property int halfDuration: 400

View file

@ -3,6 +3,7 @@ import Quickshell
import Quickshell.Wayland
import "." as M
import "../services" as S
import NovaStats as NS
// Draws rounded black corners at the edges of each screen.
// Disabled when screenRadius is 0.
@ -11,7 +12,7 @@ Item {
required property var screen
readonly property int _r: S.Theme.screenRadius
readonly property int _r: NS.ThemeService.screenRadius
component Corner: PanelWindow {
id: win

View file

@ -5,10 +5,11 @@ import Quickshell
import "." as M
import "../services" as S
import "../applets" as C
import NovaStats as NS
M.BarModule {
id: root
active: S.Modules.systemd.enable
active: NS.ModulesService.systemdEnable
tooltip: {
const sys = S.SystemdService.systemState;
const fc = S.SystemdService.totalFailedCount;
@ -40,8 +41,8 @@ M.BarModule {
if (st === "running")
return root.accentColor;
if (st === "degraded")
return S.Theme.base0A;
return S.Theme.base08;
return NS.ThemeService.base0A;
return NS.ThemeService.base08;
}
M.BarIcon {

View file

@ -3,11 +3,12 @@ import Quickshell
import "." as M
import "../services" as S
import "../applets" as C
import NovaStats as NS
M.BarModule {
id: root
active: S.Modules.temperature.enable
spacing: Math.max(1, S.Theme.moduleSpacing - 2)
active: NS.ModulesService.temperatureEnable
spacing: Math.max(1, NS.ThemeService.moduleSpacing - 2)
tooltip: "Temperature: " + _temp + "\u00B0C"
panelNamespace: "nova-temperature"
panelContentWidth: 220
@ -25,9 +26,9 @@ M.BarModule {
}
}
readonly property int _warm: S.Modules.temperature.warm || 80
readonly property int _hot: S.Modules.temperature.hot || 90
readonly property string _deviceFilter: S.Modules.temperature.device || ""
readonly property int _warm: NS.ModulesService.temperatureWarm || 80
readonly property int _hot: NS.ModulesService.temperatureHot || 90
readonly property string _deviceFilter: NS.ModulesService.temperatureDevice || ""
readonly property int _temp: {
if (_deviceFilter !== "") {
@ -38,7 +39,7 @@ M.BarModule {
return S.SystemStats.tempCelsius;
}
property color _stateColor: _temp > _hot ? S.Theme.base08 : _temp > _warm ? S.Theme.base0A : root.accentColor
property color _stateColor: _temp > _hot ? NS.ThemeService.base08 : _temp > _warm ? NS.ThemeService.base0A : root.accentColor
Behavior on _stateColor {
ColorAnimation {
duration: 300

View file

@ -3,6 +3,7 @@ import Quickshell
import Quickshell.Wayland
import "." as M
import "../services" as S
import NovaStats as NS
PanelWindow {
id: root
@ -17,7 +18,7 @@ PanelWindow {
if (_shown) {
_winVisible = true;
hideAnim.stop();
if (S.Theme.reducedMotion) {
if (S.ThemeUtil.reducedMotion) {
content.opacity = 1;
content.y = 0;
} else {
@ -25,7 +26,7 @@ PanelWindow {
}
} else {
showAnim.stop();
if (S.Theme.reducedMotion) {
if (S.ThemeUtil.reducedMotion) {
_winVisible = false;
} else {
hideAnim.start();
@ -43,8 +44,8 @@ PanelWindow {
margins.top: 0
margins.left: Math.max(0, Math.min(Math.round(M.TooltipState.itemX - implicitWidth / 2), screen.width - implicitWidth))
implicitWidth: label.implicitWidth + S.Theme.barPadding * 2
implicitHeight: label.implicitHeight + S.Theme.barPadding * 2
implicitWidth: label.implicitWidth + NS.ThemeService.barPadding * 2
implicitHeight: label.implicitHeight + NS.ThemeService.barPadding * 2
ParallelAnimation {
id: showAnim
@ -101,9 +102,9 @@ PanelWindow {
anchors.centerIn: parent
text: M.TooltipState.text.replace(/\n/g, "<br>")
textFormat: Text.RichText
color: S.Theme.base05
font.pixelSize: S.Theme.fontSize
font.family: S.Theme.fontFamily
color: NS.ThemeService.base05
font.pixelSize: NS.ThemeService.fontSize
font.family: NS.ThemeService.fontFamily
}
}
}

View file

@ -2,11 +2,12 @@ pragma Singleton
import QtQuick
import "." as M
import "../services" as S
import NovaStats as NS
QtObject {
property bool visible: false
property string text: ""
property real itemX: 0
property var screen: null
property color accentColor: S.Theme.base05
property color accentColor: NS.ThemeService.base05
}

View file

@ -2,6 +2,7 @@ import QtQuick
import Quickshell
import "." as M
import "../services" as S
import NovaStats as NS
M.HoverPanel {
id: menuWindow
@ -29,8 +30,8 @@ M.HoverPanel {
anchors.fill: parent
anchors.leftMargin: 4
anchors.rightMargin: 4
color: backArea.containsMouse ? S.Theme.base02 : "transparent"
radius: S.Theme.radius
color: backArea.containsMouse ? NS.ThemeService.base02 : "transparent"
radius: NS.ThemeService.radius
}
Text {
@ -38,9 +39,9 @@ M.HoverPanel {
anchors.left: parent.left
anchors.leftMargin: 12
text: "\u2039 Back"
color: S.Theme.base05
font.pixelSize: S.Theme.fontSize
font.family: S.Theme.fontFamily
color: NS.ThemeService.base05
font.pixelSize: NS.ThemeService.fontSize
font.family: NS.ThemeService.fontFamily
}
MouseArea {
@ -74,7 +75,7 @@ M.HoverPanel {
anchors.leftMargin: 8
anchors.rightMargin: 8
height: 1
color: S.Theme.base03
color: NS.ThemeService.base03
}
Rectangle {
@ -82,8 +83,8 @@ M.HoverPanel {
anchors.fill: parent
anchors.leftMargin: 4
anchors.rightMargin: 4
color: rowArea.containsMouse && entryItem.modelData.enabled ? S.Theme.base02 : "transparent"
radius: S.Theme.radius
color: rowArea.containsMouse && entryItem.modelData.enabled ? NS.ThemeService.base02 : "transparent"
radius: NS.ThemeService.radius
}
M.ThemedIcon {
@ -92,8 +93,8 @@ M.HoverPanel {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 12
width: S.Theme.fontSize
height: S.Theme.fontSize
width: NS.ThemeService.fontSize
height: NS.ThemeService.fontSize
source: entryItem.modelData.icon
tint: menuWindow.accentColor
fillMode: Image.PreserveAspectFit
@ -107,9 +108,9 @@ M.HoverPanel {
anchors.right: entryChevron.visible ? entryChevron.left : parent.right
anchors.rightMargin: entryChevron.visible ? 4 : 12
text: entryItem.modelData.text
color: entryItem.modelData.enabled ? S.Theme.base05 : S.Theme.base03
font.pixelSize: S.Theme.fontSize
font.family: S.Theme.fontFamily
color: entryItem.modelData.enabled ? NS.ThemeService.base05 : NS.ThemeService.base03
font.pixelSize: NS.ThemeService.fontSize
font.family: NS.ThemeService.fontFamily
elide: Text.ElideRight
}
@ -120,9 +121,9 @@ M.HoverPanel {
anchors.right: parent.right
anchors.rightMargin: 12
text: "\u203A"
color: entryItem.modelData.enabled ? S.Theme.base05 : S.Theme.base03
font.pixelSize: S.Theme.fontSize
font.family: S.Theme.fontFamily
color: entryItem.modelData.enabled ? NS.ThemeService.base05 : NS.ThemeService.base03
font.pixelSize: NS.ThemeService.fontSize
font.family: NS.ThemeService.fontFamily
}
MouseArea {

View file

@ -6,13 +6,14 @@ import Quickshell.Services.SystemTray
import "." as M
import "../services" as S
import NovaStats as NS
M.BarModule {
id: root
spacing: S.Theme.moduleSpacing + 2
spacing: NS.ThemeService.moduleSpacing + 2
cursorShape: Qt.ArrowCursor
active: S.Modules.tray.enable && _trayRepeater.count > 0
active: NS.ModulesService.trayEnable && _trayRepeater.count > 0
property var _activeMenu: null
@ -28,8 +29,8 @@ M.BarModule {
property bool _hovered: false
property real _pulseOpacity: 1
implicitWidth: S.Theme.fontSize + 4
implicitHeight: S.Theme.fontSize + 4
implicitWidth: NS.ThemeService.fontSize + 4
implicitHeight: NS.ThemeService.fontSize + 4
M.PulseAnimation on _pulseOpacity {
running: iconItem._needsAttention
@ -43,7 +44,7 @@ M.BarModule {
layer.enabled: iconItem._needsAttention || iconItem._hovered
layer.effect: MultiEffect {
shadowEnabled: true
shadowColor: iconItem._needsAttention ? S.Theme.base08 : S.Theme.base05
shadowColor: iconItem._needsAttention ? NS.ThemeService.base08 : NS.ThemeService.base05
shadowBlur: iconItem._needsAttention ? 0.8 : 0.5
shadowVerticalOffset: 0
shadowHorizontalOffset: 0
@ -52,7 +53,7 @@ M.BarModule {
M.ThemedIcon {
anchors.fill: parent
source: iconItem.modelData.icon
tint: iconItem._needsAttention ? S.Theme.base08 : root.accentColor
tint: iconItem._needsAttention ? NS.ThemeService.base08 : root.accentColor
}
}

View file

@ -3,11 +3,12 @@ import Quickshell
import "." as M
import "../services" as S
import "../applets" as C
import NovaStats as NS
M.BarModule {
id: root
active: S.Modules.volume.enable
spacing: S.Theme.moduleSpacing
active: NS.ModulesService.volumeEnable
spacing: NS.ThemeService.moduleSpacing
tooltip: "Volume: " + Math.round(volume * 100) + "%" + (muted ? " (muted)" : "")
panelNamespace: "nova-volume"
panelContentWidth: 220
@ -21,7 +22,7 @@ M.BarModule {
readonly property real volume: S.PipewireService.volume
readonly property bool muted: S.PipewireService.muted
readonly property string _volumeIcon: muted ? "\uF026" : (volume > 0.5 ? "\uF028" : (volume > 0 ? "\uF027" : "\uF026"))
readonly property color _volumeColor: muted ? S.Theme.base04 : root.accentColor
readonly property color _volumeColor: muted ? NS.ThemeService.base04 : root.accentColor
property bool _volumeInit: false
property bool _mutedInit: false

View file

@ -3,11 +3,12 @@ import Quickshell
import "." as M
import "../services" as S
import "../applets" as C
import NovaStats as NS
M.BarModule {
id: root
spacing: S.Theme.moduleSpacing
active: S.Modules.weather.enable && S.WeatherService.available
spacing: NS.ThemeService.moduleSpacing
active: NS.ModulesService.weatherEnable && S.WeatherService.available
tooltip: "Weather"
panelNamespace: "nova-weather"
panelContentWidth: 280

View file

@ -4,10 +4,11 @@ import Quickshell
import Quickshell.Widgets
import "." as M
import "../services" as S
import NovaStats as NS
M.BarModule {
id: root
spacing: S.Theme.moduleSpacing
spacing: NS.ThemeService.moduleSpacing
tooltip: S.NiriIpc.focusedAppId ? S.NiriIpc.focusedAppId + "\n" + S.NiriIpc.focusedTitle : S.NiriIpc.focusedTitle
cursorShape: Qt.ArrowCursor
@ -27,7 +28,7 @@ M.BarModule {
id: _icon
visible: root._iconSource !== ""
source: root._iconSource
implicitSize: S.Theme.fontSize + 2
implicitSize: NS.ThemeService.fontSize + 2
anchors.verticalCenter: parent.verticalCenter
layer.enabled: true
layer.effect: MultiEffect {

View file

@ -3,10 +3,11 @@ import Quickshell
import Quickshell.Io
import "." as M
import "../services" as S
import NovaStats as NS
M.BarModule {
id: root
active: S.Modules.workspaces.enable
active: NS.ModulesService.workspacesEnable
spacing: 4
cursorShape: Qt.ArrowCursor
@ -79,10 +80,10 @@ M.BarModule {
}
}
width: S.Theme.fontSize + 4
height: S.Theme.fontSize + 4
width: NS.ThemeService.fontSize + 4
height: NS.ThemeService.fontSize + 4
radius: width / 2
color: pill.active ? root.accentColor : (pill._hovered ? S.Theme.base03 : S.Theme.base02)
color: pill.active ? root.accentColor : (pill._hovered ? NS.ThemeService.base03 : NS.ThemeService.base02)
Behavior on color {
ColorAnimation {
duration: 150
@ -92,9 +93,9 @@ M.BarModule {
Text {
anchors.centerIn: parent
text: pill.modelData.idx
color: pill.active ? S.Theme.base00 : root.accentColor
font.pixelSize: S.Theme.fontSize - 2
font.family: S.Theme.fontFamily
color: pill.active ? NS.ThemeService.base00 : root.accentColor
font.pixelSize: NS.ThemeService.fontSize - 2
font.family: NS.ThemeService.fontFamily
font.bold: pill.active
}