From 1f3a8277010852ec17bcb9817f177ee944746c62 Mon Sep 17 00:00:00 2001 From: Ryan Hughes Date: Tue, 19 May 2026 19:18:56 -0400 Subject: [PATCH] consolidate logic --- shell/Ui/BarWidget.qml | 17 +++++++ shell/Ui/KeyboardPanel.qml | 11 +++++ shell/Ui/PanelController.qml | 49 +++++++++++++++++++ shell/Ui/qmldir | 2 + shell/plugins/bar/widgets/activeWindow.qml | 7 ++- shell/plugins/bar/widgets/audioPanel.qml | 37 ++++---------- shell/plugins/bar/widgets/bluetoothPanel.qml | 30 ++++-------- shell/plugins/bar/widgets/calendar.qml | 6 +-- shell/plugins/bar/widgets/idleInhibitor.qml | 6 +-- shell/plugins/bar/widgets/keyboardLayout.qml | 6 +-- shell/plugins/bar/widgets/lockKeys.qml | 7 ++- shell/plugins/bar/widgets/media.qml | 6 +-- shell/plugins/bar/widgets/microphone.qml | 6 +-- shell/plugins/bar/widgets/monitorPanel.qml | 30 ++++++------ shell/plugins/bar/widgets/networkPanel.qml | 35 +++++-------- .../bar/widgets/notificationCenter.qml | 6 +-- shell/plugins/bar/widgets/powerPanel.qml | 26 ++++------ shell/plugins/bar/widgets/spacer.qml | 7 ++- shell/plugins/bar/widgets/systemStats.qml | 6 +-- shell/plugins/bar/widgets/weather.qml | 6 +-- 20 files changed, 158 insertions(+), 148 deletions(-) create mode 100644 shell/Ui/BarWidget.qml create mode 100644 shell/Ui/PanelController.qml diff --git a/shell/Ui/BarWidget.qml b/shell/Ui/BarWidget.qml new file mode 100644 index 00000000..1cf3e256 --- /dev/null +++ b/shell/Ui/BarWidget.qml @@ -0,0 +1,17 @@ +import QtQuick + +// Base item every bar widget extends. Codifies the three properties the +// bar host injects into each widget slot: +// bar - the host Bar instance (foreground/background/run/etc). +// moduleName - widget's canonical id, used by the host registry to look +// up settings and to disambiguate inline IPC routes. +// settings - per-widget overrides read from shell.json's layout entry. +// +// Widgets are free to add their own properties, signals, and child items. +Item { + id: root + + property QtObject bar: null + property string moduleName: "" + property var settings: ({}) +} diff --git a/shell/Ui/KeyboardPanel.qml b/shell/Ui/KeyboardPanel.qml index 21404b77..684666c7 100644 --- a/shell/Ui/KeyboardPanel.qml +++ b/shell/Ui/KeyboardPanel.qml @@ -45,6 +45,14 @@ PanelWindow { property bool open: false property int gap: Style.gapsOut // distance between bar edge and panel + // Item that should take keyboard focus once the panel maps. Typically a + // PanelKeyCatcher inside the panel content. Layer-shell grants focus to + // the surface at map time, but Qt still needs an active-focus target + // inside the surface for Keys.onPressed handlers to fire. Schedule the + // focus through Qt.callLater so it runs after the surface is fully + // mapped and child items have completed layout. + property Item focusTarget: null + default property alias contentItem: contentHolder.children readonly property var coordinatorKey: owner || root @@ -187,6 +195,9 @@ PanelWindow { // Coordinate on `open`, not `visible`. `visible` lags into the fade-out // animation, which made ownership transfer to a sibling popup race. onOpenChanged: { + if (open && focusTarget) Qt.callLater(function() { + if (root.open && root.focusTarget) root.focusTarget.forceActiveFocus() + }) if (!bar) return if (open) bar.requestPopout(coordinatorKey) else if (bar.activePopout === coordinatorKey) bar.releasePopout(coordinatorKey) diff --git a/shell/Ui/PanelController.qml b/shell/Ui/PanelController.qml new file mode 100644 index 00000000..408183a4 --- /dev/null +++ b/shell/Ui/PanelController.qml @@ -0,0 +1,49 @@ +import QtQuick +import Quickshell +import Quickshell.Io + +// Owns the open/close lifecycle for a bar panel widget. Wraps the +// repetitive popupOpen + closePopout + toggle/show/hide IpcHandler triplet +// so each panel just declares one of these and binds its WidgetButton + +// KeyboardPanel to the exposed `open` property. +// +// Usage: +// PanelController { id: ctrl; ipcTarget: "audioPanel" } +// +// WidgetButton { onPressed: ctrl.toggle() } +// KeyboardPanel { open: ctrl.open; owner: ctrl; focusTarget: keyCatcher } +// +// The bar popout coordinator uses `owner` as a registry key, so each +// PanelController instance doubles as that key. KeyboardPanel calls +// `owner.closePopout()` when another panel grabs the slot. +// +// Set `manageIpc: false` when the panel needs to declare its own IpcHandler +// for additional methods on the same target (monitorPanel adds brightness + +// state). Quickshell only honors one IpcHandler per target, so the panel's +// handler must then also delegate toggle/show/hide to this controller. +QtObject { + id: root + + // IPC target name. The bar pairs this with the bar widget's filename so a + // Hyprland keybind (`omarchy-shell toggle`) summons the panel. + property string ipcTarget: "" + property bool manageIpc: true + + property bool open: false + + function toggle() { open = !open } + function show() { if (!open) open = true } + function hide() { open = false } + function closePopout() { open = false } + + property IpcHandler _ipc: manageIpc ? ipcComponent.createObject(root) : null + + property Component ipcComponent: Component { + IpcHandler { + target: root.ipcTarget + function toggle(): void { root.toggle() } + function show(): void { root.show() } + function hide(): void { root.hide() } + } + } +} diff --git a/shell/Ui/qmldir b/shell/Ui/qmldir index 66afd990..7a10590e 100644 --- a/shell/Ui/qmldir +++ b/shell/Ui/qmldir @@ -1,5 +1,6 @@ module qs.Ui +BarWidget 1.0 BarWidget.qml Button 1.0 Button.qml ButtonGroup 1.0 ButtonGroup.qml CursorSurface 1.0 CursorSurface.qml @@ -7,6 +8,7 @@ Dropdown 1.0 Dropdown.qml KeyboardPanel 1.0 KeyboardPanel.qml NumberField 1.0 NumberField.qml PanelActionButton 1.0 PanelActionButton.qml +PanelController 1.0 PanelController.qml PanelKeyCatcher 1.0 PanelKeyCatcher.qml PanelSectionHeader 1.0 PanelSectionHeader.qml PanelSeparator 1.0 PanelSeparator.qml diff --git a/shell/plugins/bar/widgets/activeWindow.qml b/shell/plugins/bar/widgets/activeWindow.qml index c0963ad5..8f9d0137 100644 --- a/shell/plugins/bar/widgets/activeWindow.qml +++ b/shell/plugins/bar/widgets/activeWindow.qml @@ -2,13 +2,12 @@ import QtQuick import Quickshell import Quickshell.Wayland import qs.Commons +import qs.Ui -Item { +BarWidget { id: root + moduleName: "activeWindow" - property QtObject bar: null - property string moduleName: "activeWindow" - property var settings: ({}) function setting(name, fallback) { var value = settings ? settings[name] : undefined diff --git a/shell/plugins/bar/widgets/audioPanel.qml b/shell/plugins/bar/widgets/audioPanel.qml index 1b16caa9..c7cf38d8 100644 --- a/shell/plugins/bar/widgets/audioPanel.qml +++ b/shell/plugins/bar/widgets/audioPanel.qml @@ -6,16 +6,14 @@ import Quickshell.Services.Pipewire import qs.Ui import qs.Commons -Item { +BarWidget { id: root + moduleName: "audioPanel" - property QtObject bar: null - property string moduleName: "audioPanel" - property var settings: ({}) - property bool popupOpen: false - - function closePopout() { popupOpen = false } + PanelController { id: ctrl; ipcTarget: "audioPanel" } + readonly property bool popupOpen: ctrl.open + function closePopout() { ctrl.hide() } readonly property var sink: Pipewire.defaultAudioSink readonly property var source: Pipewire.defaultAudioSource @@ -219,10 +217,7 @@ Item { focusSection = "output" selectedIndex = -1 // first keyboard cursor reveal starts on the output slider cursorActive = false - Qt.callLater(function() { - resetScroll() - if (keyCatcher) keyCatcher.forceActiveFocus() - }) + Qt.callLater(resetScroll) } } @@ -460,19 +455,6 @@ for block in re.split(r"(?m)^Sink #", sys.stdin.read())[1:]: onTriggered: if (!sinkAvailabilityProc.running) sinkAvailabilityProc.running = true } - // Lets a Hyprland keybind summon the panel without a click. Mirrors the - // networkPanel IpcHandler pattern; KeyboardPanel grants Exclusive focus - // at map-time so j/k/h/l work the moment the panel appears. - IpcHandler { - target: "audioPanel" - function toggle(): void { - if (root.popupOpen) root.closePopout() - else root.popupOpen = true - } - function show(): void { if (!root.popupOpen) root.popupOpen = true } - function hide(): void { root.closePopout() } - } - WidgetButton { id: button anchors.fill: parent @@ -481,7 +463,7 @@ for block in re.split(r"(?m)^Sink #", sys.stdin.read())[1:]: fontSize: Style.font.body onPressed: function(b) { if (b === Qt.RightButton) root.toggleOutputMute() - else root.popupOpen = !root.popupOpen + else ctrl.toggle() } onWheelMoved: function(delta) { @@ -493,9 +475,10 @@ for block in re.split(r"(?m)^Sink #", sys.stdin.read())[1:]: KeyboardPanel { id: panel anchorItem: button - owner: root + owner: ctrl bar: root.bar - open: root.popupOpen + open: ctrl.open + focusTarget: keyCatcher contentWidth: panel.fittedContentWidth(Style.space(370)) contentHeight: panel.fittedContentHeight(panelColumn.implicitHeight, Style.space(560)) diff --git a/shell/plugins/bar/widgets/bluetoothPanel.qml b/shell/plugins/bar/widgets/bluetoothPanel.qml index cbff342a..f114ae54 100644 --- a/shell/plugins/bar/widgets/bluetoothPanel.qml +++ b/shell/plugins/bar/widgets/bluetoothPanel.qml @@ -6,14 +6,13 @@ import Quickshell.Bluetooth import qs.Ui import qs.Commons -Item { +BarWidget { id: root + moduleName: "bluetoothPanel" - property QtObject bar: null - property string moduleName: "bluetoothPanel" - property var settings: ({}) - property bool popupOpen: false + PanelController { id: ctrl; ipcTarget: "bluetoothPanel" } + readonly property bool popupOpen: ctrl.open // Address -> true while we are waiting for a click-initiated pair to land // so we can chain trust + connect at root scope. Doing this in the row's @@ -21,7 +20,7 @@ Item { // moment `paired` flips, before the row's handler reliably fires. property var pendingPairAddresses: ({}) - function closePopout() { popupOpen = false } + function closePopout() { ctrl.hide() } readonly property var adapter: Bluetooth.defaultAdapter readonly property var devices: Bluetooth.devices ? Bluetooth.devices.values : [] @@ -226,7 +225,6 @@ Item { if (knownDevices.length > 0) { focusSection = "known"; selectedIndex = 0 } else { focusSection = "header"; selectedIndex = 1 } cursorActive = false - Qt.callLater(function() { if (keyCatcher) keyCatcher.forceActiveFocus() }) } } @@ -335,17 +333,6 @@ Item { } } - // Lets a Hyprland keybind summon the panel without a click. - IpcHandler { - target: "bluetoothPanel" - function toggle(): void { - if (root.popupOpen) root.closePopout() - else root.popupOpen = true - } - function show(): void { if (!root.popupOpen) root.popupOpen = true } - function hide(): void { root.closePopout() } - } - WidgetButton { id: button anchors.fill: parent @@ -354,16 +341,17 @@ Item { onPressed: function(b) { if (b === Qt.RightButton && root.adapter) root.adapter.enabled = !root.adapter.enabled else if (b === Qt.MiddleButton) root.bar.run("omarchy-launch-bluetooth") - else root.popupOpen = !root.popupOpen + else ctrl.toggle() } } KeyboardPanel { id: panel anchorItem: button - owner: root + owner: ctrl bar: root.bar - open: root.popupOpen + open: ctrl.open + focusTarget: keyCatcher contentWidth: panel.fittedContentWidth(Style.space(320)) contentHeight: panel.fittedContentHeight(column.implicitHeight) diff --git a/shell/plugins/bar/widgets/calendar.qml b/shell/plugins/bar/widgets/calendar.qml index a069e812..c3282daf 100644 --- a/shell/plugins/bar/widgets/calendar.qml +++ b/shell/plugins/bar/widgets/calendar.qml @@ -4,12 +4,10 @@ import Quickshell import qs.Ui import qs.Commons -Item { +BarWidget { id: root + moduleName: "calendar" - property QtObject bar: null - property string moduleName: "calendar" - property var settings: ({}) property date now: new Date() property date viewMonth: new Date() diff --git a/shell/plugins/bar/widgets/idleInhibitor.qml b/shell/plugins/bar/widgets/idleInhibitor.qml index 8017bcab..558d9e2c 100644 --- a/shell/plugins/bar/widgets/idleInhibitor.qml +++ b/shell/plugins/bar/widgets/idleInhibitor.qml @@ -3,12 +3,10 @@ import Quickshell import Quickshell.Io import qs.Ui -Item { +BarWidget { id: root + moduleName: "idleInhibitor" - property QtObject bar: null - property string moduleName: "idleInhibitor" - property var settings: ({}) property bool active: false diff --git a/shell/plugins/bar/widgets/keyboardLayout.qml b/shell/plugins/bar/widgets/keyboardLayout.qml index 1ab15bc7..f2ff8a56 100644 --- a/shell/plugins/bar/widgets/keyboardLayout.qml +++ b/shell/plugins/bar/widgets/keyboardLayout.qml @@ -5,12 +5,10 @@ import Quickshell.Io import qs.Ui import qs.Commons -Item { +BarWidget { id: root + moduleName: "keyboardLayout" - property QtObject bar: null - property string moduleName: "keyboardLayout" - property var settings: ({}) property string layoutLabel: "" property string layoutFull: "" diff --git a/shell/plugins/bar/widgets/lockKeys.qml b/shell/plugins/bar/widgets/lockKeys.qml index 87b5f648..3704ff4d 100644 --- a/shell/plugins/bar/widgets/lockKeys.qml +++ b/shell/plugins/bar/widgets/lockKeys.qml @@ -2,13 +2,12 @@ import QtQuick import Quickshell import Quickshell.Io import qs.Commons +import qs.Ui -Item { +BarWidget { id: root + moduleName: "lockKeys" - property QtObject bar: null - property string moduleName: "lockKeys" - property var settings: ({}) property bool capsOn: false property bool numOn: false diff --git a/shell/plugins/bar/widgets/media.qml b/shell/plugins/bar/widgets/media.qml index 655be058..b0ec1b9f 100644 --- a/shell/plugins/bar/widgets/media.qml +++ b/shell/plugins/bar/widgets/media.qml @@ -4,12 +4,10 @@ import Quickshell.Services.Mpris import qs.Ui import qs.Commons -Item { +BarWidget { id: root + moduleName: "media" - property QtObject bar: null - property string moduleName: "media" - property var settings: ({}) function setting(name, fallback) { var value = settings ? settings[name] : undefined diff --git a/shell/plugins/bar/widgets/microphone.qml b/shell/plugins/bar/widgets/microphone.qml index ae22e617..c137f3be 100644 --- a/shell/plugins/bar/widgets/microphone.qml +++ b/shell/plugins/bar/widgets/microphone.qml @@ -3,12 +3,10 @@ import Quickshell import Quickshell.Services.Pipewire import qs.Ui -Item { +BarWidget { id: root + moduleName: "microphone" - property QtObject bar: null - property string moduleName: "microphone" - property var settings: ({}) readonly property var source: Pipewire.defaultAudioSource readonly property bool muted: source && source.audio ? source.audio.muted : true diff --git a/shell/plugins/bar/widgets/monitorPanel.qml b/shell/plugins/bar/widgets/monitorPanel.qml index 13ba8ff5..d8d85e54 100644 --- a/shell/plugins/bar/widgets/monitorPanel.qml +++ b/shell/plugins/bar/widgets/monitorPanel.qml @@ -5,14 +5,15 @@ import Quickshell.Io import qs.Ui import qs.Commons -Item { +BarWidget { id: root + moduleName: "monitorPanel" - property QtObject bar: null - property string moduleName: "monitorPanel" - property var settings: ({}) - property bool popupOpen: false + // manageIpc: false so this panel can own the single IpcHandler the target + // permits — needed for the brightness + state methods below. + PanelController { id: ctrl; ipcTarget: "monitorPanel"; manageIpc: false } + readonly property bool popupOpen: ctrl.open property int brightnessPercent: 0 property int pendingBrightnessPercent: 0 property bool brightnessSetQueued: false @@ -169,7 +170,7 @@ Item { flick.contentY = bottom + margin - flick.height } - function closePopout() { popupOpen = false } + function closePopout() { ctrl.hide() } IpcHandler { target: "monitorPanel" @@ -190,12 +191,9 @@ Item { }) } - function toggle(): void { - if (root.popupOpen) root.closePopout() - else root.popupOpen = true - } - function show(): void { if (!root.popupOpen) root.popupOpen = true } - function hide(): void { root.closePopout() } + function toggle(): void { ctrl.toggle() } + function show(): void { ctrl.show() } + function hide(): void { ctrl.hide() } } function refresh() { @@ -273,7 +271,6 @@ Item { selectedIndex = 0 } cursorActive = false - Qt.callLater(function() { if (keyCatcher) keyCatcher.forceActiveFocus() }) } } @@ -346,7 +343,7 @@ Item { bar: root.bar text: root.displays.length > 1 ? "󰍺" : "󰍹" fontSize: Style.font.subtitle - onPressed: function(b) { root.popupOpen = !root.popupOpen } + onPressed: function(b) { ctrl.toggle() } onWheelMoved: function(delta) { if (root.brightnessAvailable) root.setBrightness(root.brightnessPercent + (delta > 0 ? 5 : -5)) } @@ -355,9 +352,10 @@ Item { KeyboardPanel { id: panel anchorItem: button - owner: root + owner: ctrl bar: root.bar - open: root.popupOpen + open: ctrl.open + focusTarget: keyCatcher contentWidth: panel.fittedContentWidth(Style.space(320)) contentHeight: panel.fittedContentHeight(panelColumn.implicitHeight, Style.space(560)) diff --git a/shell/plugins/bar/widgets/networkPanel.qml b/shell/plugins/bar/widgets/networkPanel.qml index 882b7ef0..e6f3228a 100644 --- a/shell/plugins/bar/widgets/networkPanel.qml +++ b/shell/plugins/bar/widgets/networkPanel.qml @@ -5,17 +5,16 @@ import Quickshell.Io import qs.Ui import qs.Commons -Item { +BarWidget { id: root + moduleName: "networkPanel" - property QtObject bar: null - property string moduleName: "networkPanel" - property var settings: ({}) - property bool popupOpen: false + PanelController { id: ctrl; ipcTarget: "networkPanel" } + readonly property bool popupOpen: ctrl.open // Centralized close so callers can't forget to drop the passphrase prompt. function closePopout() { - popupOpen = false + ctrl.hide() passwordSsid = "" } @@ -108,12 +107,13 @@ Item { var idx = dnsProviders.indexOf(dnsProvider) dnsIndex = idx >= 0 ? idx : 0 cursorActive = false - Qt.callLater(function() { if (keyCatcher) keyCatcher.forceActiveFocus() }) } } // When the passphrase prompt closes (Esc / Cancel / success) restore // focus to the keyCatcher so j/k/Enter resume working without a click. + // The KeyboardPanel's focusTarget covers initial popup-open; this handles + // the inline-editor case where focus was handed off to a child. onPasswordSsidChanged: { if (passwordSsid === "" && popupOpen) { Qt.callLater(function() { if (keyCatcher) keyCatcher.forceActiveFocus() }) @@ -478,18 +478,6 @@ iwctl known-networks ${quotedSsid} forget Component.onCompleted: refresh() - // Lets a Hyprland keybind summon the panel without needing to click the - // bar icon. Paired with the SUPER+CTRL+W binding in utilities.lua. - IpcHandler { - target: "networkPanel" - function toggle(): void { - if (root.popupOpen) root.closePopout() - else root.popupOpen = true - } - function show(): void { if (!root.popupOpen) root.popupOpen = true } - function hide(): void { root.closePopout() } - } - // Pulls everything we want about the active route's interface in one shot. Process { id: detailsProc @@ -643,8 +631,8 @@ fi rightExtraMargin: 2 onPressed: function(b) { - if (root.popupOpen) root.closePopout() - else { root.popupOpen = true; root.refresh() } + if (ctrl.open) root.closePopout() + else { ctrl.show(); root.refresh() } } } @@ -657,9 +645,10 @@ fi KeyboardPanel { id: panel anchorItem: button - owner: root + owner: ctrl bar: root.bar - open: root.popupOpen + open: ctrl.open + focusTarget: keyCatcher contentWidth: panel.fittedContentWidth(Style.space(340)) contentHeight: panel.fittedContentHeight(column.implicitHeight) diff --git a/shell/plugins/bar/widgets/notificationCenter.qml b/shell/plugins/bar/widgets/notificationCenter.qml index 7dc75c4f..c21bc40a 100644 --- a/shell/plugins/bar/widgets/notificationCenter.qml +++ b/shell/plugins/bar/widgets/notificationCenter.qml @@ -4,12 +4,10 @@ import Quickshell import qs.Commons import qs.Ui -Item { +BarWidget { id: root + moduleName: "notificationCenter" - property QtObject bar: null - property string moduleName: "notificationCenter" - property var settings: ({}) property bool popupOpen: false function closePopout() { popupOpen = false } diff --git a/shell/plugins/bar/widgets/powerPanel.qml b/shell/plugins/bar/widgets/powerPanel.qml index e2530950..a5667dad 100644 --- a/shell/plugins/bar/widgets/powerPanel.qml +++ b/shell/plugins/bar/widgets/powerPanel.qml @@ -5,14 +5,13 @@ import Quickshell.Services.UPower import qs.Commons import qs.Ui -Item { +BarWidget { id: root + moduleName: "powerPanel" - property QtObject bar: null - property string moduleName: "powerPanel" - property var settings: ({}) - property bool popupOpen: false + PanelController { id: ctrl; ipcTarget: "powerPanel" } + readonly property bool popupOpen: ctrl.open property var batteryInfo: ({}) property var systemInfo: ({}) property var profiles: [] @@ -20,7 +19,7 @@ Item { property int profileIndex: 0 property bool cursorActive: false - function closePopout() { popupOpen = false } + function closePopout() { ctrl.hide() } function selectProfileByDelta(delta) { if (profiles.length === 0) { profileIndex = 0; return } @@ -114,7 +113,6 @@ Item { var idx = profiles.indexOf(activeProfile) profileIndex = idx >= 0 ? idx : 0 cursorActive = false - Qt.callLater(function() { if (keyCatcher) keyCatcher.forceActiveFocus() }) } } @@ -123,13 +121,6 @@ Item { implicitWidth: button.implicitWidth implicitHeight: button.implicitHeight - IpcHandler { - target: "powerPanel" - function toggle(): void { root.popupOpen = !root.popupOpen } - function show(): void { root.popupOpen = true } - function hide(): void { root.closePopout() } - } - Process { id: batteryProc command: ["bash", "-lc", ` @@ -173,15 +164,16 @@ printf 'time\t%s\n' "$($OMARCHY_PATH/bin/omarchy-battery-remaining-time 2>/dev/n rightExtraMargin: 2 active: UPower.displayDevice && UPower.displayDevice.percentage <= 0.2 && UPower.onBattery tooltipText: "" - onPressed: function(b) { root.popupOpen = !root.popupOpen } + onPressed: function(b) { ctrl.toggle() } } KeyboardPanel { id: panel anchorItem: button - owner: root + owner: ctrl bar: root.bar - open: root.popupOpen + open: ctrl.open + focusTarget: keyCatcher contentWidth: panel.fittedContentWidth(Style.space(340)) contentHeight: panel.fittedContentHeight(column.implicitHeight) diff --git a/shell/plugins/bar/widgets/spacer.qml b/shell/plugins/bar/widgets/spacer.qml index 78a428ab..744a1856 100644 --- a/shell/plugins/bar/widgets/spacer.qml +++ b/shell/plugins/bar/widgets/spacer.qml @@ -1,11 +1,10 @@ import QtQuick +import qs.Ui -Item { +BarWidget { id: root + moduleName: "spacer" - property QtObject bar: null - property string moduleName: "spacer" - property var settings: ({}) readonly property bool vertical: bar ? bar.vertical : false readonly property int span: settings && settings.size !== undefined ? Number(settings.size) : 12 diff --git a/shell/plugins/bar/widgets/systemStats.qml b/shell/plugins/bar/widgets/systemStats.qml index c23024fc..2939b83b 100644 --- a/shell/plugins/bar/widgets/systemStats.qml +++ b/shell/plugins/bar/widgets/systemStats.qml @@ -4,12 +4,10 @@ import Quickshell.Io import qs.Ui import qs.Commons -Item { +BarWidget { id: root + moduleName: "systemStats" - property QtObject bar: null - property string moduleName: "systemStats" - property var settings: ({}) property real cpuPercent: 0 property real memPercent: 0 diff --git a/shell/plugins/bar/widgets/weather.qml b/shell/plugins/bar/widgets/weather.qml index 8e2cde40..2b5284cf 100644 --- a/shell/plugins/bar/widgets/weather.qml +++ b/shell/plugins/bar/widgets/weather.qml @@ -4,12 +4,10 @@ import Quickshell.Io import qs.Commons import qs.Ui -Item { +BarWidget { id: root + moduleName: "weather" - property QtObject bar: null - property string moduleName: "weather" - property var settings: ({}) property bool popupOpen: false function closePopout() { popupOpen = false }