Compare commits
3
Commits
v0.4.0
..
cbb24a2c40
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cbb24a2c40 | ||
|
|
052e3a7800 | ||
|
|
439a14d29e |
+4
-4
@@ -126,7 +126,7 @@ MouseArea {
|
||||
CustomRect {
|
||||
id: item
|
||||
|
||||
readonly property bool active: modelData === root?.active
|
||||
readonly property bool active: modelData === root.active
|
||||
required property int index
|
||||
required property MenuItem modelData
|
||||
|
||||
@@ -163,19 +163,19 @@ MouseArea {
|
||||
MaterialIcon {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
color: item.active ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurfaceVariant
|
||||
text: item.modelData?.icon ?? ""
|
||||
text: item.modelData.icon
|
||||
}
|
||||
|
||||
CustomText {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
color: item.active ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurface
|
||||
text: item.modelData?.text ?? ""
|
||||
text: item.modelData.text
|
||||
}
|
||||
|
||||
Loader {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
active: item.modelData?.trailingIcon.length > 0
|
||||
active: item.modelData.trailingIcon.length > 0
|
||||
asynchronous: true
|
||||
visible: active
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
import QtQuick
|
||||
import ZShell.Config
|
||||
import qs.Components
|
||||
@@ -15,6 +16,9 @@ Scope {
|
||||
ExclusionZone {
|
||||
id: top
|
||||
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
anchors.left: true
|
||||
anchors.right: true
|
||||
anchors.top: true
|
||||
hasBar: root.geometry.barOnTop
|
||||
}
|
||||
|
||||
@@ -162,6 +162,19 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: unhideTimer
|
||||
|
||||
interval: Config.bar.revealDelay
|
||||
repeat: false
|
||||
running: false
|
||||
|
||||
onTriggered: {
|
||||
if (hoverHandler.hovered)
|
||||
root.bar.isHovered = true;
|
||||
}
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: hoverHandler
|
||||
|
||||
@@ -178,7 +191,7 @@ Item {
|
||||
root.popouts.hasCurrent = false;
|
||||
}
|
||||
|
||||
if (Config.bar.autoHide)
|
||||
if (Config.bar.autoHide || root.bar.fullscreen)
|
||||
root.bar.isHovered = false;
|
||||
}
|
||||
}
|
||||
@@ -200,6 +213,9 @@ Item {
|
||||
if (!root.visibilities.bar && Config.bar.autoHide && root.geometry.barContains(x, y, true))
|
||||
root.bar.isHovered = true;
|
||||
|
||||
if (root.bar.fullscreen && !root.bar.isHovered)
|
||||
unhideTimer.start();
|
||||
|
||||
if (root.panels.sidebar.offsetScale === 1) {
|
||||
const showOsd = root.inRightPanel(root.panels.osdWrapper, x, y);
|
||||
|
||||
@@ -302,6 +318,8 @@ Item {
|
||||
root.visibilities.sidebar = false;
|
||||
root.panels.popouts.hasCurrent = false;
|
||||
root.visibilities.launcher = false;
|
||||
} else {
|
||||
Config.save();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-2
@@ -51,7 +51,7 @@ CustomWindow {
|
||||
readonly property HyprlandMonitor monitor: Hypr.monitorFor(screen)
|
||||
property var root: Quickshell.shellDir
|
||||
readonly property real sdfBorderOffset: 2 * fsTransitionProg
|
||||
readonly property real shadowOpacity: 0.7 * (1 - fsTransitionProg)
|
||||
readonly property real shadowOpacity: 0.7 * (1 - (bar.isHovered ? 0 : fsTransitionProg))
|
||||
property color surfaceColor: Colors.tPalette.m3surface
|
||||
|
||||
WlrLayershell.exclusionMode: ExclusionMode.Ignore
|
||||
@@ -59,7 +59,7 @@ CustomWindow {
|
||||
WlrLayershell.layer: (fsTransitionProg > 0 && Config.general.showOverFullscreen) || (hasSpecialWorkspace && hasFullscreenOnNormalWs) ? WlrLayer.Overlay : WlrLayer.Top
|
||||
color: "transparent"
|
||||
contentItem.focus: true
|
||||
mask: visibilities.isDrawing ? null : (hasFullscreen ? emptyRegion : regions)
|
||||
mask: visibilities.isDrawing ? null : (hasFullscreen && !bar.isHovered ? emptyRegion : regions)
|
||||
name: "Bar"
|
||||
|
||||
Behavior on fsTransitionProg {
|
||||
@@ -118,6 +118,12 @@ CustomWindow {
|
||||
x: root.width - width
|
||||
y: panels.osdWrapper.y + bar.implicitHeight
|
||||
}
|
||||
|
||||
Region {
|
||||
height: geometry.horizontal ? 1 : root.screen.height
|
||||
width: geometry.horizontal ? root.screen.width : 1
|
||||
y: geometry.position === "bottom" ? root.screen.height - 1 : 0
|
||||
}
|
||||
}
|
||||
|
||||
Regions {
|
||||
|
||||
@@ -73,6 +73,7 @@ Singleton {
|
||||
|
||||
Config.dock.pinnedApps = pinnedApps;
|
||||
root.unpinnedOrder = visibleUnpinned.concat(root.unpinnedOrder.map(normalizeId).filter(id => !pinnedApps.includes(id) && !visibleUnpinned.includes(id)));
|
||||
Config.saveNoToast();
|
||||
}
|
||||
|
||||
function isPinned(appId) {
|
||||
|
||||
+10
-9
@@ -12,6 +12,7 @@ GridLayout {
|
||||
|
||||
required property bool fullscreen
|
||||
required property bool horizontal
|
||||
required property bool isHovered
|
||||
required property Wrapper popouts
|
||||
required property ClipWrapper popoutsWrapper
|
||||
required property ShellScreen screen
|
||||
@@ -92,7 +93,7 @@ GridLayout {
|
||||
delegate: EntryWrapper {
|
||||
HyprsunsetWidget {
|
||||
horizontal: root.horizontal
|
||||
visible: !root.fullscreen
|
||||
visible: !root.fullscreen || root.isHovered
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,7 +114,7 @@ GridLayout {
|
||||
Workspaces {
|
||||
horizontal: root.horizontal
|
||||
screen: root.screen
|
||||
visible: !root.fullscreen
|
||||
visible: !root.fullscreen || root.isHovered
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -126,7 +127,7 @@ GridLayout {
|
||||
horizontal: root.horizontal
|
||||
loader: root
|
||||
popouts: root.popouts
|
||||
visible: !root.fullscreen
|
||||
visible: !root.fullscreen || root.isHovered
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -148,7 +149,7 @@ GridLayout {
|
||||
Resources {
|
||||
horizontal: root.horizontal
|
||||
visibilities: root.visibilities
|
||||
visible: !root.fullscreen
|
||||
visible: !root.fullscreen || root.isHovered
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,7 +160,7 @@ GridLayout {
|
||||
delegate: EntryWrapper {
|
||||
UpdatesWidget {
|
||||
horizontal: root.horizontal
|
||||
visible: !root.fullscreen
|
||||
visible: !root.fullscreen || root.isHovered
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -172,7 +173,7 @@ GridLayout {
|
||||
horizontal: root.horizontal
|
||||
popouts: root.popouts
|
||||
visibilities: root.visibilities
|
||||
visible: !root.fullscreen
|
||||
visible: !root.fullscreen || root.isHovered
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,7 +187,7 @@ GridLayout {
|
||||
loader: root
|
||||
popouts: root.popouts
|
||||
visibilities: root.visibilities
|
||||
visible: !root.fullscreen
|
||||
visible: !root.fullscreen || root.isHovered
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -198,7 +199,7 @@ GridLayout {
|
||||
WindowTitle {
|
||||
bar: root
|
||||
horizontal: root.horizontal
|
||||
visible: !root.fullscreen
|
||||
visible: !root.fullscreen || root.isHovered
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,7 +219,7 @@ GridLayout {
|
||||
delegate: EntryWrapper {
|
||||
MediaWidget {
|
||||
horizontal: root.horizontal
|
||||
visible: !root.fullscreen
|
||||
visible: !root.fullscreen || root.isHovered
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ Item {
|
||||
required property ClipWrapper popoutsWrapper
|
||||
required property string position
|
||||
required property ShellScreen screen
|
||||
readonly property bool shouldBeVisible: !fullscreen && (!Config.bar.autoHide || visibilities.bar || isHovered)
|
||||
readonly property bool shouldBeVisible: (!fullscreen && (!Config.bar.autoHide || visibilities.bar)) || isHovered
|
||||
readonly property int vPadding: 6
|
||||
required property PersistentProperties visibilities
|
||||
|
||||
@@ -79,7 +79,9 @@ Item {
|
||||
|
||||
sourceComponent: Bar {
|
||||
fullscreen: root.fullscreen
|
||||
height: root.contentHeight
|
||||
horizontal: root.horizontal
|
||||
isHovered: root.isHovered
|
||||
popouts: root.popouts
|
||||
popoutsWrapper: root.popoutsWrapper
|
||||
screen: root.screen
|
||||
|
||||
@@ -82,6 +82,7 @@ Searcher {
|
||||
list.visibilities.launcher = false;
|
||||
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--scheme", variant]);
|
||||
Config.colors.schemeType = variant;
|
||||
Config.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ PageBase {
|
||||
|
||||
SelectRow {
|
||||
active: Config.bar.position === "top" ? menuItems[0] : Config.bar.position === "left" ? menuItems[1] : menuItems[2]
|
||||
last: true
|
||||
settingAnchor: "bar-position"
|
||||
subtext: qsTr("Change which edge the bar appears on")
|
||||
text: qsTr("Position")
|
||||
@@ -61,6 +60,28 @@ PageBase {
|
||||
onSelected: item => Config.bar.position = item.value
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.bar.fullscreenReveal
|
||||
settingAnchor: "bar-fullscreen-reveal"
|
||||
subtext: qsTr("Hover top edge to show bar in fullscreen")
|
||||
text: qsTr("Reveal on edge")
|
||||
|
||||
onToggled: Config.bar.fullscreenReveal = checked
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
from: 0
|
||||
last: true
|
||||
settingAnchor: "bar-reveal-delay"
|
||||
stepSize: 100
|
||||
subtext: qsTr("The delay before bar is revealed when cursor is at edge")
|
||||
text: qsTr("Reveal delay")
|
||||
to: 2000
|
||||
value: Config.bar.revealDelay
|
||||
|
||||
onMoved: v => Config.bar.revealDelay = v
|
||||
}
|
||||
|
||||
// Components
|
||||
SectionHeader {
|
||||
text: qsTr("Components")
|
||||
|
||||
@@ -70,7 +70,10 @@ PageBase {
|
||||
}
|
||||
]
|
||||
|
||||
onSelected: item => Config.screenshot.mode = item.value
|
||||
onSelected: item => {
|
||||
Config.screenshot.mode = item.value;
|
||||
Config.save();
|
||||
}
|
||||
}
|
||||
|
||||
SectionHeader {
|
||||
|
||||
@@ -104,6 +104,7 @@ PageBase {
|
||||
onApplySettings: (start, end) => {
|
||||
Config.general.color.scheduleDarkStart = start;
|
||||
Config.general.color.scheduleDarkEnd = end;
|
||||
Config.save();
|
||||
ModeScheduler.checkStartup();
|
||||
PopupManager.requestClose();
|
||||
}
|
||||
@@ -145,6 +146,7 @@ PageBase {
|
||||
onApplySettings: (start, end) => {
|
||||
Config.general.color.scheduleHyprsunsetStart = start;
|
||||
Config.general.color.scheduleHyprsunsetEnd = end;
|
||||
Config.save();
|
||||
Hyprsunset.checkStartup();
|
||||
PopupManager.requestClose();
|
||||
}
|
||||
|
||||
@@ -95,31 +95,15 @@ QString Config::filePath() const {
|
||||
|
||||
void Config::loadSync() {
|
||||
m_loading = true;
|
||||
|
||||
QFile f(filePath());
|
||||
QJsonObject before;
|
||||
|
||||
bool existed = false;
|
||||
|
||||
if (f.open(QIODevice::ReadOnly)) {
|
||||
const auto doc = QJsonDocument::fromJson(f.readAll());
|
||||
if (doc.isObject()) {
|
||||
before = doc.object();
|
||||
existed = true;
|
||||
} else {
|
||||
qInfo() << "Config: existing config at" << filePath()
|
||||
<< "is empty or not a valid JSON object - using defaults";
|
||||
}
|
||||
if (doc.isObject()) loadFromJson(QJsonValue(doc.object()));
|
||||
} else {
|
||||
qInfo() << "Config: no existing config at" << filePath()
|
||||
<< "- using defaults";
|
||||
}
|
||||
|
||||
loadFromJson(QJsonValue(before));
|
||||
m_loading = false;
|
||||
|
||||
const auto after = toJson().toObject();
|
||||
if (!existed || after != before) saveNow();
|
||||
}
|
||||
|
||||
void Config::updateWatch() {
|
||||
@@ -164,21 +148,27 @@ void Config::loadAsync() {
|
||||
|
||||
if (f.open(QIODevice::ReadOnly)) {
|
||||
const auto doc = QJsonDocument::fromJson(f.readAll());
|
||||
const bool valid = doc.isObject();
|
||||
const QJsonObject before = valid ? doc.object() : QJsonObject();
|
||||
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this, valid, before]() {
|
||||
loadFromJson(QJsonValue(before));
|
||||
m_loading = false;
|
||||
if (doc.isObject()) {
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this, doc]() {
|
||||
loadFromJson(QJsonValue(doc.object()));
|
||||
m_loading = false;
|
||||
|
||||
const auto after = toJson().toObject();
|
||||
if (!valid || after != before) saveNow();
|
||||
if (m_reloadPending) m_reloadTimer.start();
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
} else {
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this]() {
|
||||
m_loading = false;
|
||||
|
||||
if (m_reloadPending) m_reloadTimer.start();
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
if (m_reloadPending) m_reloadTimer.start();
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
} else {
|
||||
qInfo() << "Config: failed to reload from" << filePath()
|
||||
<< "- using in-memory values";
|
||||
|
||||
@@ -79,14 +79,13 @@ void ConfigList::loadFromJson(const QJsonValue& json) {
|
||||
if (!json.isArray()) {
|
||||
qCWarning(
|
||||
lcConfig,
|
||||
"Option '%s' must be a list, resetting to default",
|
||||
"Option '%s' must be a list, ignoring",
|
||||
qUtf8Printable(propertyPath()));
|
||||
|
||||
resetToDefaults();
|
||||
materializeDefaults();
|
||||
m_rejectedJson = json;
|
||||
return;
|
||||
}
|
||||
|
||||
m_rejectedJson = QJsonValue::Undefined;
|
||||
populate(json.toArray());
|
||||
m_loaded = true;
|
||||
}
|
||||
@@ -94,11 +93,12 @@ void ConfigList::loadFromJson(const QJsonValue& json) {
|
||||
QJsonValue ConfigList::toJson() const {
|
||||
if (m_loaded) return elementsToJson();
|
||||
|
||||
return QJsonValue::Undefined;
|
||||
return m_rejectedJson;
|
||||
}
|
||||
|
||||
void ConfigList::clearLoadedKeys() {
|
||||
m_loaded = false;
|
||||
m_rejectedJson = QJsonValue::Undefined;
|
||||
}
|
||||
|
||||
QStringList ConfigList::unknownKeys() const {
|
||||
@@ -113,15 +113,6 @@ QStringList ConfigList::unknownKeys() const {
|
||||
return keys;
|
||||
}
|
||||
|
||||
void ConfigList::materializeDefaults() {
|
||||
for (auto* const item : m_items)
|
||||
item->materializeDefaults();
|
||||
|
||||
if (m_global) return;
|
||||
|
||||
m_loaded = true;
|
||||
}
|
||||
|
||||
void ConfigList::resyncFromGlobal() {
|
||||
syncValuesFromGlobal();
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ class ConfigList : public ConfigNode {
|
||||
[[nodiscard]] QJsonValue toJson() const override;
|
||||
void clearLoadedKeys() override;
|
||||
[[nodiscard]] QStringList unknownKeys() const override;
|
||||
void materializeDefaults() override;
|
||||
void resyncFromGlobal() override;
|
||||
|
||||
signals:
|
||||
@@ -72,6 +71,7 @@ class ConfigList : public ConfigNode {
|
||||
QJsonArray m_defaults;
|
||||
QList<ConfigObject*> m_items;
|
||||
bool m_loaded = false;
|
||||
QJsonValue m_rejectedJson = QJsonValue::Undefined;
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -103,6 +103,7 @@ class ConfigList : public ConfigNode {
|
||||
} \
|
||||
};
|
||||
|
||||
|
||||
#define CONFIG_LIST(Type, name, ...) \
|
||||
Q_PROPERTY(ZShell::config::Type* name READ name CONSTANT) \
|
||||
\
|
||||
@@ -114,8 +115,6 @@ class ConfigList : public ConfigNode {
|
||||
private: \
|
||||
Type* m_##name = new Type(this __VA_OPT__(, __VA_ARGS__));
|
||||
|
||||
#define LIST_ENTRY(id, enabled) \
|
||||
vmap({{"id", QString::fromUtf8(#id)}, {"enabled", enabled}})
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
@@ -137,3 +136,6 @@ class ListEntry : public ConfigObject {
|
||||
CONFIG_LIST_TYPE(ListEntry, EntryList)
|
||||
|
||||
} // namespace ZShell::config
|
||||
|
||||
#define LIST_ENTRY(id, enabled) \
|
||||
vmap({{"id", QString::fromUtf8(#id)}, {"enabled", enabled}})
|
||||
|
||||
@@ -26,8 +26,6 @@ class ConfigNode : public QObject {
|
||||
[[nodiscard]] virtual QStringList unknownKeys() const = 0;
|
||||
[[nodiscard]] virtual QList<ConfigNode*> childNodes() const;
|
||||
|
||||
virtual void materializeDefaults() = 0;
|
||||
|
||||
void syncFromGlobal(ConfigNode* global);
|
||||
virtual void resyncFromGlobal() = 0;
|
||||
|
||||
|
||||
@@ -7,51 +7,6 @@
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
namespace {
|
||||
|
||||
bool isStringArray(const QJsonArray& arr) {
|
||||
for (const auto& v : arr) {
|
||||
if (!v.isString()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool jsonValueMatchesType(const QJsonValue& val, QMetaType type) {
|
||||
switch (val.type()) {
|
||||
case QJsonValue::Bool:
|
||||
return type.id() == QMetaType::Bool;
|
||||
|
||||
case QJsonValue::Double:
|
||||
switch (type.id()) {
|
||||
case QMetaType::Int:
|
||||
case QMetaType::UInt:
|
||||
case QMetaType::LongLong:
|
||||
case QMetaType::ULongLong:
|
||||
case QMetaType::Double:
|
||||
case QMetaType::Float:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
case QJsonValue::String:
|
||||
return type.id() == QMetaType::QString;
|
||||
|
||||
case QJsonValue::Array:
|
||||
if (type.id() == QMetaType::QStringList)
|
||||
return isStringArray(val.toArray());
|
||||
return type.id() == QMetaType::QVariantList;
|
||||
|
||||
case QJsonValue::Object:
|
||||
case QJsonValue::Null:
|
||||
case QJsonValue::Undefined:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ConfigObject::ConfigObject(QObject* parent) : ConfigNode(parent) {}
|
||||
|
||||
void ConfigObject::loadFromJson(const QJsonValue& json) {
|
||||
@@ -59,7 +14,6 @@ void ConfigObject::loadFromJson(const QJsonValue& json) {
|
||||
const auto* meta = metaObject();
|
||||
|
||||
QSet<QString> known;
|
||||
QSet<QString> invalid;
|
||||
|
||||
for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) {
|
||||
auto prop = meta->property(i);
|
||||
@@ -80,15 +34,6 @@ void ConfigObject::loadFromJson(const QJsonValue& json) {
|
||||
|
||||
if (!prop.isWritable()) continue;
|
||||
|
||||
if (!jsonValueMatchesType(jsonVal, prop.metaType())) {
|
||||
qWarning() << "Config: type mismatch for" << key << "in"
|
||||
<< meta->className() << "- expected"
|
||||
<< prop.metaType().name() << "got value" << jsonVal
|
||||
<< "- resetting to default";
|
||||
invalid.insert(key);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prop.metaType().id() == QMetaType::QStringList) {
|
||||
QStringList list;
|
||||
const auto jsonArr = jsonVal.toArray();
|
||||
@@ -111,12 +56,10 @@ void ConfigObject::loadFromJson(const QJsonValue& json) {
|
||||
|
||||
m_extras = {};
|
||||
for (auto it = obj.begin(); it != obj.end(); ++it) {
|
||||
if (!known.contains(it.key()) || invalid.contains(it.key())) {
|
||||
if (!known.contains(it.key())) {
|
||||
m_extras.insert(it.key(), it.value());
|
||||
}
|
||||
}
|
||||
|
||||
materializeDefaults();
|
||||
}
|
||||
|
||||
QJsonValue ConfigObject::toJson() const {
|
||||
@@ -161,6 +104,9 @@ QJsonValue ConfigObject::toJson() const {
|
||||
obj.insert(key, QJsonValue::fromVariant(value));
|
||||
}
|
||||
|
||||
for (auto it = m_extras.begin(); it != m_extras.end(); ++it)
|
||||
obj.insert(it.key(), it.value());
|
||||
|
||||
if (obj.isEmpty()) return QJsonValue::Undefined;
|
||||
|
||||
return obj;
|
||||
@@ -213,26 +159,6 @@ QList<ConfigNode*> ConfigObject::childNodes() const {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
void ConfigObject::materializeDefaults() {
|
||||
const auto* meta = metaObject();
|
||||
|
||||
for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) {
|
||||
const auto prop = meta->property(i);
|
||||
const auto key = QString::fromUtf8(prop.name());
|
||||
|
||||
if (auto* const node = prop.read(this).value<ConfigNode*>()) {
|
||||
node->materializeDefaults();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!prop.isWritable()) continue;
|
||||
|
||||
if (m_global) continue;
|
||||
|
||||
m_loadedKeys.insert(key);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigObject::syncValuesFromGlobal() {
|
||||
const auto* meta = metaObject();
|
||||
|
||||
|
||||
@@ -62,7 +62,6 @@ class ConfigObject : public ConfigNode {
|
||||
void clearLoadedKeys() override;
|
||||
[[nodiscard]] QStringList unknownKeys() const override;
|
||||
[[nodiscard]] QList<ConfigNode*> childNodes() const override;
|
||||
void materializeDefaults() override;
|
||||
void resyncFromGlobal() override;
|
||||
|
||||
[[nodiscard]] virtual QStringList identityKeys() const;
|
||||
|
||||
@@ -113,6 +113,7 @@ Singleton {
|
||||
function setMode(mode: string): void {
|
||||
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--mode", mode]);
|
||||
Config.general.color.mode = mode;
|
||||
Config.save();
|
||||
}
|
||||
|
||||
function swapRG(c: color): color {
|
||||
|
||||
Reference in New Issue
Block a user