From 0092b41a058ae47f8d1caaa66ba84d618efa136d Mon Sep 17 00:00:00 2001 From: zach Date: Fri, 14 Aug 2026 22:15:11 +0200 Subject: [PATCH] fix config file writing + positioning issues --- Modules/Bar/BarLoader.qml | 2 +- Modules/Clock.qml | 2 +- Modules/HyprsunsetWidget.qml | 6 +++--- Modules/MediaWidget.qml | 21 ++++++++++++++++----- Modules/NotifBell.qml | 6 +++--- Modules/Resource.qml | 4 ++-- Modules/Resources.qml | 4 ++-- Modules/Settings/Pages/Panels/BarPanel.qml | 9 +++------ Modules/SysTray/StatusIcons.qml | 2 +- Modules/SysTray/TrayIcons.qml | 2 +- Modules/SysTray/Widgets/AudioWidget.qml | 2 +- Modules/SysTray/Widgets/MicWidget.qml | 2 +- Modules/SysTray/Widgets/UPowerWidget.qml | 2 +- Modules/Updates/UpdatesWidget.qml | 7 ++++--- Modules/Workspaces.qml | 2 +- Plugins/ZShell/Config/bar.hpp | 3 ++- Plugins/ZShell/Config/config.cpp | 11 +++++++++++ Plugins/ZShell/Config/config.hpp | 1 + Plugins/ZShell/Config/tokens.hpp | 16 +++++++++++++++- 19 files changed, 70 insertions(+), 34 deletions(-) diff --git a/Modules/Bar/BarLoader.qml b/Modules/Bar/BarLoader.qml index a19ea4a..ff7f0a2 100644 --- a/Modules/Bar/BarLoader.qml +++ b/Modules/Bar/BarLoader.qml @@ -14,7 +14,7 @@ Item { id: root readonly property int clampedExtent: Math.max(Config.bar.border, extent) - readonly property int contentThickness: Math.max(Config.bar.height, 30) + padding * 2 + readonly property int contentThickness: Math.max(Config.bar.height, Tokens.bar.innerSize) + padding * 2 readonly property int exclusiveZone: Config.bar.autoHide ? Config.bar.border : contentThickness property real extent: fullscreen ? 0 : Config.bar.border required property bool fullscreen diff --git a/Modules/Clock.qml b/Modules/Clock.qml index 6c63af5..0626ed9 100644 --- a/Modules/Clock.qml +++ b/Modules/Clock.qml @@ -13,7 +13,7 @@ CustomRect { required property bool horizontal required property GridLayout loader required property Wrapper popouts - readonly property real shortSize: Config.bar.height + readonly property real shortSize: Math.max(Config.bar.height, Tokens.bar.innerSize) readonly property real size: timeText.contentWidth + (horizontal ? Tokens.padding.normal : Tokens.padding.larger) * 2 required property PersistentProperties visibilities diff --git a/Modules/HyprsunsetWidget.qml b/Modules/HyprsunsetWidget.qml index 19b89ba..34d1426 100644 --- a/Modules/HyprsunsetWidget.qml +++ b/Modules/HyprsunsetWidget.qml @@ -11,8 +11,8 @@ CustomRect { property bool tempEnabled: Hyprsunset.enabled color: root.tempEnabled ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer - implicitHeight: horizontal ? Config.bar.height : width - implicitWidth: horizontal ? height : Config.bar.height + implicitHeight: horizontal ? Math.max(Config.bar.height, Tokens.bar.innerSize) : width + implicitWidth: horizontal ? height : Math.max(Config.bar.height, Tokens.bar.innerSize) radius: Tokens.rounding.full StateLayer { @@ -27,7 +27,7 @@ CustomRect { animate: true color: root.tempEnabled ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface fill: root.tempEnabled ? 1 : 0 - font.pointSize: root.horizontal ? Tokens.font.size.larger : Tokens.font.size.large + font.pointSize: Tokens.font.size.larger text: root.tempEnabled ? "lightbulb" : "light_off" Behavior on fill { diff --git a/Modules/MediaWidget.qml b/Modules/MediaWidget.qml index 87d26e4..15e9679 100644 --- a/Modules/MediaWidget.qml +++ b/Modules/MediaWidget.qml @@ -14,11 +14,19 @@ CustomRect { readonly property int textWidth: Math.min(metrics.width, 200) color: Colors.tPalette.m3surfaceContainer - implicitHeight: horizontal ? Config.bar.height : layout.implicitHeight + Tokens.padding.normal * 2 - implicitWidth: horizontal ? layout.implicitWidth + Tokens.padding.normal * 2 : Config.bar.height + implicitHeight: horizontal ? Math.max(Config.bar.height, Tokens.bar.innerSize) : layout.implicitHeight + Tokens.padding.normal * 2 + implicitWidth: horizontal ? layout.implicitWidth + Tokens.padding.normal * 2 : Math.max(Config.bar.height, Tokens.bar.innerSize) radius: Tokens.rounding.full + Behavior on implicitHeight { + enabled: !root.horizontal + + Anim { + } + } Behavior on implicitWidth { + enabled: root.horizontal + Anim { } } @@ -33,7 +41,11 @@ CustomRect { GridLayout { id: layout - anchors.centerIn: parent + anchors.bottomMargin: root.horizontal ? 0 : Tokens.padding.normal + anchors.fill: parent + anchors.leftMargin: root.horizontal ? Tokens.padding.normal : 0 + anchors.rightMargin: root.horizontal ? Tokens.padding.normal : 0 + anchors.topMargin: root.horizontal ? 0 : Tokens.padding.normal columns: root.horizontal ? -1 : 1 Behavior on implicitWidth { @@ -53,15 +65,14 @@ CustomRect { id: mediatext Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter - Layout.preferredHeight: root.horizontal ? root.height : root.textWidth animate: true color: Players.active?.isPlaying ? Colors.palette.m3primary : Colors.palette.m3onSurface font.pointSize: Tokens.font.size.normal horizontalAlignment: Text.AlignHCenter + implicitWidth: root.textWidth marqueeEnabled: false pauseMs: 4000 text: root.currentMedia - width: root.textWidth transform: [ Translate { diff --git a/Modules/NotifBell.qml b/Modules/NotifBell.qml index f1a1315..0567d89 100644 --- a/Modules/NotifBell.qml +++ b/Modules/NotifBell.qml @@ -13,8 +13,8 @@ CustomRect { required property PersistentProperties visibilities color: visibilities.sidebar ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer - implicitHeight: horizontal ? Config.bar.height : width - implicitWidth: horizontal ? height : Config.bar.height + implicitHeight: horizontal ? Math.max(Config.bar.height, Tokens.bar.innerSize) : width + implicitWidth: horizontal ? height : Math.max(Config.bar.height, Tokens.bar.innerSize) radius: Tokens.rounding.full MaterialIcon { @@ -23,7 +23,7 @@ CustomRect { anchors.centerIn: parent color: root.visibilities.sidebar ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface fill: root.visibilities.sidebar ? 1 : 0 - font.pointSize: root.horizontal ? Tokens.font.size.larger : Tokens.font.size.large + font.pointSize: Tokens.font.size.larger text: NotifServer.list.length ? "\uf4fe" : "\ue7f4" Behavior on color { diff --git a/Modules/Resource.qml b/Modules/Resource.qml index 9b15b8c..0608268 100644 --- a/Modules/Resource.qml +++ b/Modules/Resource.qml @@ -49,7 +49,7 @@ GridLayout { } CustomClippingRect { - Layout.preferredHeight: root.horizontal ? icon.implicitHeight : 4 + Layout.preferredHeight: root.horizontal ? icon.implicitHeight - Tokens.padding.small : 4 Layout.preferredWidth: root.horizontal ? 4 : icon.implicitWidth color: Colors.layer(Colors.palette.m3surfaceContainerHigh, 2) radius: Tokens.rounding.full @@ -63,7 +63,7 @@ GridLayout { anchors.top: root.horizontal ? undefined : parent.top color: root.mainColor implicitHeight: root.horizontal ? Math.ceil(root.percentage * parent.height) : 0 - implicitWidth: root.horizontal ? 0 : Math.ceil(root.percentage * parent.height) + implicitWidth: root.horizontal ? 0 : Math.ceil(root.percentage * parent.width) // Behavior on implicitHeight { // Anim { diff --git a/Modules/Resources.qml b/Modules/Resources.qml index 65f881a..123636e 100644 --- a/Modules/Resources.qml +++ b/Modules/Resources.qml @@ -17,8 +17,8 @@ CustomRect { clip: true color: visibilities.resources ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer - implicitHeight: horizontal ? Math.max(Config.bar.height, 24) : gridLayout.implicitHeight + Tokens.padding.normal * 2 - implicitWidth: horizontal ? gridLayout.implicitWidth + Tokens.padding.larger * 2 : Config.bar.height + implicitHeight: horizontal ? Math.max(Config.bar.height, Tokens.bar.innerSize) : gridLayout.implicitHeight + Tokens.padding.normal * 2 + implicitWidth: horizontal ? gridLayout.implicitWidth + Tokens.padding.larger * 2 : Math.max(Config.bar.height, Tokens.bar.innerSize) radius: Tokens.rounding.full StateLayer { diff --git a/Modules/Settings/Pages/Panels/BarPanel.qml b/Modules/Settings/Pages/Panels/BarPanel.qml index 090c79c..31e613a 100644 --- a/Modules/Settings/Pages/Panels/BarPanel.qml +++ b/Modules/Settings/Pages/Panels/BarPanel.qml @@ -37,8 +37,8 @@ PageBase { active: Config.bar.position === "top" ? menuItems[0] : Config.bar.position === "left" ? menuItems[1] : menuItems[2] last: true settingAnchor: "bar-position" - subtext: qsTr("Automatic or manual effect values") - text: qsTr("Effects mode") + subtext: qsTr("Change which edge the bar appears on") + text: qsTr("Position") menuItems: [ MenuItem { @@ -58,10 +58,7 @@ PageBase { } ] - onSelected: item => { - Config.bar.position = item.value; - Config.save(); - } + onSelected: item => Config.bar.position = item.value } // Components diff --git a/Modules/SysTray/StatusIcons.qml b/Modules/SysTray/StatusIcons.qml index ab41b6b..2fa363a 100644 --- a/Modules/SysTray/StatusIcons.qml +++ b/Modules/SysTray/StatusIcons.qml @@ -30,7 +30,7 @@ CustomClippingRect { return i; return -1; } - readonly property real shortSize: Config.bar.height + readonly property real shortSize: Math.max(Config.bar.height, Tokens.bar.innerSize) readonly property real size: horizontal ? grid.implicitWidth + Tokens.padding.small * 2 : grid.implicitHeight + Tokens.padding.small * 2 readonly property int spacing: Tokens.spacing.normal / 2 diff --git a/Modules/SysTray/TrayIcons.qml b/Modules/SysTray/TrayIcons.qml index bb1ffaf..c9eb96f 100644 --- a/Modules/SysTray/TrayIcons.qml +++ b/Modules/SysTray/TrayIcons.qml @@ -17,7 +17,7 @@ CustomClippingRect { required property GridLayout loader readonly property int padding: Tokens.padding.small required property Wrapper popouts - readonly property real shortSize: Config.bar.height + readonly property real shortSize: Math.max(Config.bar.height, Tokens.bar.innerSize) readonly property real size: horizontal ? sysGrid.implicitWidth + Tokens.padding.small : sysGrid.implicitHeight + Tokens.padding.small bottomLeftRadius: horizontal ? Tokens.rounding.full : Tokens.rounding.smallest / 2 diff --git a/Modules/SysTray/Widgets/AudioWidget.qml b/Modules/SysTray/Widgets/AudioWidget.qml index 8e5f8f2..93c4752 100644 --- a/Modules/SysTray/Widgets/AudioWidget.qml +++ b/Modules/SysTray/Widgets/AudioWidget.qml @@ -13,7 +13,7 @@ MaterialIcon { animate: true color: Audio.muted ? Colors.palette.m3error : Colors.palette.m3onSurface fill: 1 - font.pointSize: horizontal ? Tokens.font.size.larger : Tokens.font.size.large + font.pointSize: Tokens.font.size.larger text: Audio.muted ? "volume_off" : "volume_up" Behavior on Layout.maximumWidth { diff --git a/Modules/SysTray/Widgets/MicWidget.qml b/Modules/SysTray/Widgets/MicWidget.qml index 59725b1..8f58616 100644 --- a/Modules/SysTray/Widgets/MicWidget.qml +++ b/Modules/SysTray/Widgets/MicWidget.qml @@ -13,7 +13,7 @@ MaterialIcon { animate: true color: (Audio.sourceMuted ?? false) ? Colors.palette.m3error : Colors.palette.m3onSurface fill: 1 - font.pointSize: horizontal ? Tokens.font.size.larger : Tokens.font.size.large + font.pointSize: Tokens.font.size.larger text: Audio.sourceMuted ? "mic_off" : "mic" Behavior on Layout.maximumWidth { diff --git a/Modules/SysTray/Widgets/UPowerWidget.qml b/Modules/SysTray/Widgets/UPowerWidget.qml index ca38488..380b912 100644 --- a/Modules/SysTray/Widgets/UPowerWidget.qml +++ b/Modules/SysTray/Widgets/UPowerWidget.qml @@ -125,7 +125,7 @@ Item { Layout.alignment: Qt.AlignVCenter animate: true fill: 1 - font.pointSize: root.horizontal ? Tokens.font.size.larger : Tokens.font.size.large + font.pointSize: Tokens.font.size.larger text: { if (PowerProfiles.profile === PowerProfile.PowerSaver) return "energy_savings_leaf"; diff --git a/Modules/Updates/UpdatesWidget.qml b/Modules/Updates/UpdatesWidget.qml index 385b755..3babcae 100644 --- a/Modules/Updates/UpdatesWidget.qml +++ b/Modules/Updates/UpdatesWidget.qml @@ -14,8 +14,8 @@ CustomRect { property color textColor: Colors.palette.m3onSurface color: Colors.tPalette.m3surfaceContainer - implicitHeight: horizontal ? Config.bar.height : content.implicitHeight + Tokens.spacing.small * 2 - implicitWidth: horizontal ? content.implicitWidth + Tokens.spacing.small * 2 : Config.bar.height + implicitHeight: horizontal ? Math.max(Config.bar.height, Tokens.bar.innerSize) : content.implicitHeight + Tokens.spacing.small + implicitWidth: horizontal ? content.implicitWidth + Tokens.spacing.small * 2 : Math.max(Config.bar.height, Tokens.bar.innerSize) radius: Tokens.rounding.full GridLayout { @@ -24,6 +24,7 @@ CustomRect { anchors.centerIn: parent columnSpacing: Tokens.spacing.small columns: root.horizontal ? -1 : 1 + rowSpacing: -Tokens.spacing.extraSmall / 2 MaterialIcon { Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter @@ -34,7 +35,7 @@ CustomRect { CustomText { Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter color: root.textColor - font.pointSize: root.horizontal ? Tokens.font.size.normal : Tokens.font.size.larger + font.pointSize: Tokens.font.size.normal text: root.countUpdates } } diff --git a/Modules/Workspaces.qml b/Modules/Workspaces.qml index 01ebeb5..fa7e297 100644 --- a/Modules/Workspaces.qml +++ b/Modules/Workspaces.qml @@ -17,7 +17,7 @@ Item { required property bool horizontal readonly property HyprlandMonitor monitor: Hyprland.monitorFor(root.screen) required property ShellScreen screen - readonly property real shortSize: Math.max(Config.bar.height, 24) + readonly property real shortSize: Math.max(Config.bar.height, Tokens.bar.innerSize) readonly property real size: (workspaceButtonWidth * workspacesShown) + activeWorkspaceMargin * 2 property int workspaceButtonWidth: (horizontal ? bgRect.implicitHeight : bgRect.implicitWidth) - root.activeWorkspaceMargin * 2 property int workspaceIndexInGroup: (effectiveActiveWorkspaceId - 1) % root.workspacesShown diff --git a/Plugins/ZShell/Config/bar.hpp b/Plugins/ZShell/Config/bar.hpp index 9edd18c..4a0c8ae 100644 --- a/Plugins/ZShell/Config/bar.hpp +++ b/Plugins/ZShell/Config/bar.hpp @@ -3,6 +3,7 @@ #include "configlist.hpp" #include "configobject.hpp" #include +#include #include namespace ZShell::config { @@ -62,7 +63,7 @@ class Bar : public ConfigObject { CFG_PROPERTY(int, revealDelay, 100) CFG_PROPERTY(int, rounding, 14) CFG_PROPERTY(int, smoothing, 32) - CFG_PROPERTY(QString, position, "top") + CFG_PROPERTY(QString, position, QStringLiteral("top")) CONFIG_SUBOBJECT(Tray, tray) CONFIG_LIST( EntryList, diff --git a/Plugins/ZShell/Config/config.cpp b/Plugins/ZShell/Config/config.cpp index c0fcc9d..ea2c307 100644 --- a/Plugins/ZShell/Config/config.cpp +++ b/Plugins/ZShell/Config/config.cpp @@ -61,6 +61,8 @@ Config::Config(QObject* parent) m_reloadTimer.setInterval(50); connect(&m_reloadTimer, &QTimer::timeout, this, &Config::reloadAsync); + connectAutoSave(this); + connect( &m_watcher, &QFileSystemWatcher::directoryChanged, @@ -232,6 +234,15 @@ void Config::saveNow() { flushAsync(); } +void Config::connectAutoSave(ConfigNode* node) { + connect(node, &ConfigNode::propertiesChanged, this, [this] { + scheduleSave(); + }); + + for (auto* child : node->childNodes()) + connectAutoSave(child); +} + bool Config::writeAtomically(const QByteArray& data) { QSaveFile f(filePath()); diff --git a/Plugins/ZShell/Config/config.hpp b/Plugins/ZShell/Config/config.hpp index 1a201f3..e1881c5 100644 --- a/Plugins/ZShell/Config/config.hpp +++ b/Plugins/ZShell/Config/config.hpp @@ -90,6 +90,7 @@ class Config : public ConfigObject { void updateWatch(); void loadSync(); void loadAsync(); + void connectAutoSave(ConfigNode* node); QTimer m_saveTimer; QTimer m_reloadTimer; diff --git a/Plugins/ZShell/Config/tokens.hpp b/Plugins/ZShell/Config/tokens.hpp index 79056c1..7c83e47 100644 --- a/Plugins/ZShell/Config/tokens.hpp +++ b/Plugins/ZShell/Config/tokens.hpp @@ -3,7 +3,9 @@ #include "configobject.hpp" #include +#include #include +#include #include namespace ZShell::config { @@ -195,6 +197,16 @@ class AnimTokens : public ConfigObject { , m_durations(new AnimDurations(this)) {} }; +class BarTokens : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(int, innerSize, 28) + + public: + explicit BarTokens(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + class Tokens : public ConfigObject { Q_OBJECT QML_ELEMENT @@ -205,6 +217,7 @@ class Tokens : public ConfigObject { CONFIG_SUBOBJECT(AppearanceSpacing, spacing) CONFIG_SUBOBJECT(FontTokens, font) CONFIG_SUBOBJECT(AnimTokens, anim) + CONFIG_SUBOBJECT(BarTokens, bar) public: explicit Tokens(QObject* parent = nullptr) @@ -213,7 +226,8 @@ class Tokens : public ConfigObject { , m_padding(new AppearancePadding(this)) , m_spacing(new AppearanceSpacing(this)) , m_font(new FontTokens(this)) - , m_anim(new AnimTokens(this)) {} + , m_anim(new AnimTokens(this)) + , m_bar(new BarTokens(this)) {} static Tokens* create(QQmlEngine*, QJSEngine*) { return new Tokens(); } };