changes to config plugin, reduce file amount + code, fix greeter

This commit is contained in:
2026-08-13 15:41:16 +02:00
parent 9d2f78eb5e
commit b2e092d0be
145 changed files with 2531 additions and 6949 deletions
-40
View File
@@ -1,40 +0,0 @@
#include "Appearance.hpp"
Anim::Anim(QObject *parent) : ConfigSection(parent) {
m_mediaGifSpeedAdjustment = 300;
m_sessionGifSpeed = 0.7;
wireSignals();
}
Deform::Deform(QObject *parent) : ConfigSection(parent) {
m_scale = 1;
wireSignals();
}
FontFamily::FontFamily(QObject *parent) : ConfigSection(parent) {
m_clock = QStringLiteral("Rubik");
m_material = QStringLiteral("Material Symbols Rounded");
m_mono = QStringLiteral("SegoeUI Variable");
m_sans = QStringLiteral("SegoeUI Variable");
wireSignals();
}
Font::Font(QObject *parent) : ConfigSection(parent) {
m_family = new FontFamily(this);
wireSignals();
}
Transparency::Transparency(QObject *parent) : ConfigSection(parent) {
m_base = 0.75;
m_enabled = true;
m_layers = 0.4;
wireSignals();
}
Appearance::Appearance(QObject *parent) : ConfigSection(parent) {
m_anim = new Anim(this);
m_deform = new Deform(this);
m_font = new Font(this);
m_transparency = new Transparency(this);
wireSignals();
}
-78
View File
@@ -1,78 +0,0 @@
#pragma once
#include "ConfigSection.hpp"
#include <qqmlregistration.h>
// NOTE: multiple classes per file is fine - moc processes every Q_OBJECT
// class it finds in a header, regardless of how many. Config.appearance.anim
// works purely through object composition (Appearance owns an Anim*), which
// has nothing to do with how the files are split.
class Anim : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(int, mediaGifSpeedAdjustment, MediaGifSpeedAdjustment)
CFG_PROPERTY(qreal, sessionGifSpeed, SessionGifSpeed)
public:
explicit Anim(QObject *parent = nullptr);
};
class Deform : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(qreal, scale, Scale)
public:
explicit Deform(QObject *parent = nullptr);
};
class FontFamily : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(QString, clock, Clock)
CFG_PROPERTY(QString, material, Material)
CFG_PROPERTY(QString, mono, Mono)
CFG_PROPERTY(QString, sans, Sans)
public:
explicit FontFamily(QObject *parent = nullptr);
};
class Font : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_SECTION(FontFamily, family, Family)
public:
explicit Font(QObject *parent = nullptr);
};
class Transparency : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(qreal, base, Base)
CFG_PROPERTY(bool, enabled, Enabled)
CFG_PROPERTY(qreal, layers, Layers)
public:
explicit Transparency(QObject *parent = nullptr);
};
class Appearance : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_SECTION(Anim, anim, Anim)
CFG_SECTION(Deform, deform, Deform)
CFG_SECTION(Font, font, Font)
CFG_SECTION(Transparency, transparency, Transparency)
public:
explicit Appearance(QObject *parent = nullptr);
};
-7
View File
@@ -1,7 +0,0 @@
#include "Background.hpp"
Background::Background(QObject *parent) : ConfigSection(parent) {
m_enabled = true;
m_wallFadeDuration = 300;
wireSignals();
}
-14
View File
@@ -1,14 +0,0 @@
#pragma once
#include "ConfigSection.hpp"
#include <qqmlregistration.h>
class Background : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(bool, enabled, Enabled)
CFG_PROPERTY(int, wallFadeDuration, WallFadeDuration)
public:
explicit Background(QObject *parent = nullptr);
};
-63
View File
@@ -1,63 +0,0 @@
#include "Bar.hpp"
namespace {
QVariantMap entry(bool enabled, const char *id) {
QVariantMap m;
m["enabled"] = enabled;
m["id"] = QString::fromLatin1(id);
return m;
}
}
Popouts::Popouts(QObject *parent) : ConfigSection(parent) {
m_statusIcons = true;
m_tray = true;
wireSignals();
}
Tray::Tray(QObject *parent) : ConfigSection(parent) {
m_recolorIcons = false;
m_showOnHover = true;
m_statusIcons = {
entry(true, "audio"),
entry(true, "microphone"),
entry(true, "bluetooth"),
entry(false, "network"),
entry(false, "wifi"),
entry(true, "power"),
};
m_trayIconSize = 24;
wireSignals();
}
Bar::Bar(QObject *parent) : ConfigSection(parent) {
m_autoHide = false;
m_border = 4;
m_entries = {
entry(true, "workspaces"),
entry(true, "audio"),
entry(true, "media"),
entry(true, "resources"),
entry(true, "updates"),
entry(false, "dash"),
entry(true, "spacer"),
entry(true, "activeWindow"),
entry(true, "spacer"),
entry(true, "hyprsunset"),
entry(true, "tray"),
entry(true, "statusIcons"),
entry(false, "network"),
entry(true, "upower"),
entry(true, "clock"),
entry(true, "notifBell"),
};
m_fullscreenReveal = true;
m_height = 24;
m_hideWhenNotif = true;
m_popouts = new Popouts(this);
m_revealDelay = 100;
m_rounding = 14;
m_smoothing = 32;
m_tray = new Tray(this);
wireSignals();
}
-52
View File
@@ -1,52 +0,0 @@
#pragma once
#include "ConfigSection.hpp"
#include <qqmlregistration.h>
#include <QVariantList>
class Popouts : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(bool, statusIcons, StatusIcons)
CFG_PROPERTY(bool, tray, Tray)
public:
explicit Popouts(QObject *parent = nullptr);
};
class Tray : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(bool, recolorIcons, RecolorIcons)
CFG_PROPERTY(bool, showOnHover, ShowOnHover)
// Array of { enabled, id } objects. QML can't mutate array elements in
// place - assign the whole list back to change it, e.g.
// Config.bar.tray.statusIcons = updatedList
CFG_PROPERTY(QVariantList, statusIcons, StatusIcons)
CFG_PROPERTY(int, trayIconSize, TrayIconSize)
public:
explicit Tray(QObject *parent = nullptr);
};
class Bar : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(bool, autoHide, AutoHide)
CFG_PROPERTY(int, border, Border)
// Array of { enabled, id } objects, in display order.
CFG_PROPERTY(QVariantList, entries, Entries)
CFG_PROPERTY(bool, fullscreenReveal, FullscreenReveal)
CFG_PROPERTY(int, height, Height)
CFG_PROPERTY(bool, hideWhenNotif, HideWhenNotif)
CFG_SECTION(Popouts, popouts, Popouts)
CFG_PROPERTY(int, revealDelay, RevealDelay)
CFG_PROPERTY(int, rounding, Rounding)
CFG_PROPERTY(int, smoothing, Smoothing)
CFG_SECTION(Tray, tray, Tray)
public:
explicit Bar(QObject *parent = nullptr);
};
+21 -20
View File
@@ -1,24 +1,25 @@
qml_module(ZShell-config
URI ZShell.Config
SOURCES
ConfigSection.hpp ConfigSection.cpp
Config.hpp Config.cpp
Tokens.hpp Tokens.cpp
Appearance.hpp Appearance.cpp
Background.hpp Background.cpp
Bar.hpp Bar.cpp
Clipboard.hpp Clipboard.cpp
Colors.hpp Colors.cpp
Dashboard.hpp Dashboard.cpp
Dock.hpp Dock.cpp
General.hpp General.cpp
Launcher.hpp Launcher.cpp
Lock.hpp Lock.cpp
Notifs.hpp Notifs.cpp
Osd.hpp Osd.cpp
Overview.hpp Overview.cpp
Screenshot.hpp Screenshot.cpp
Services.hpp Services.cpp
Sidebar.hpp Sidebar.cpp
Utilities.hpp Utilities.cpp
confignode.hpp confignode.cpp
configobject.hpp configobject.cpp
configlist.hpp configlist.cpp
config.hpp config.cpp
tokens.hpp
appearance.hpp
background.hpp
bar.hpp
clipboard.hpp
colors.hpp
dashboard.hpp
dock.hpp
general.hpp
launcher.hpp
lock.hpp
notifs.hpp
osd.hpp
screenshot.hpp
services.hpp
sidebar.hpp
utilities.hpp
)
-16
View File
@@ -1,16 +0,0 @@
#include "Clipboard.hpp"
ClipboardSizes::ClipboardSizes(QObject *parent) : ConfigSection(parent) {
m_itemHeight = 60;
m_minPreviewWidth = 200;
m_previewWidth = 800;
m_width = 500;
wireSignals();
}
Clipboard::Clipboard(QObject *parent) : ConfigSection(parent) {
m_enabled = true;
m_maxEntriesShown = 10;
m_sizes = new ClipboardSizes(this);
wireSignals();
}
-28
View File
@@ -1,28 +0,0 @@
#pragma once
#include "ConfigSection.hpp"
#include <qqmlregistration.h>
class ClipboardSizes : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(int, itemHeight, ItemHeight)
CFG_PROPERTY(int, minPreviewWidth, MinPreviewWidth)
CFG_PROPERTY(int, previewWidth, PreviewWidth)
CFG_PROPERTY(int, width, Width)
public:
explicit ClipboardSizes(QObject *parent = nullptr);
};
class Clipboard : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(bool, enabled, Enabled)
CFG_PROPERTY(int, maxEntriesShown, MaxEntriesShown)
CFG_SECTION(ClipboardSizes, sizes, Sizes)
public:
explicit Clipboard(QObject *parent = nullptr);
};
-14
View File
@@ -1,14 +0,0 @@
#include "Colors.hpp"
Presets::Presets(QObject *parent) : ConfigSection(parent) {
m_accent = QString();
m_name = QStringLiteral("Catppuccin");
m_variant = QStringLiteral("latte");
wireSignals();
}
Colors::Colors(QObject *parent) : ConfigSection(parent) {
m_presets = new Presets(this);
m_schemeType = QStringLiteral("fidelity");
wireSignals();
}
-26
View File
@@ -1,26 +0,0 @@
#pragma once
#include "ConfigSection.hpp"
#include <qqmlregistration.h>
class Presets : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(QString, accent, Accent)
CFG_PROPERTY(QString, name, Name)
CFG_PROPERTY(QString, variant, Variant)
public:
explicit Presets(QObject *parent = nullptr);
};
class Colors : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_SECTION(Presets, presets, Presets)
CFG_PROPERTY(QString, schemeType, SchemeType)
public:
explicit Colors(QObject *parent = nullptr);
};
-86
View File
@@ -1,86 +0,0 @@
#pragma once
#include "ConfigSection.hpp"
#include <qqmlregistration.h>
#include <QTimer>
#include <QtConcurrent/QtConcurrent>
#include <QFuture>
#include "Appearance.hpp"
#include "Background.hpp"
#include "Bar.hpp"
#include "Clipboard.hpp"
#include "Colors.hpp"
#include "Dashboard.hpp"
#include "Dock.hpp"
#include "General.hpp"
#include "Launcher.hpp"
#include "Lock.hpp"
#include "Notifs.hpp"
#include "Osd.hpp"
#include "Overview.hpp"
#include "Screenshot.hpp"
#include "Services.hpp"
#include "Sidebar.hpp"
#include "Utilities.hpp"
class QQmlEngine;
class QJSEngine;
// The central hub. Exposed to QML as a singleton, so `Config.appearance.
// anim.sessionGifSpeed` just works from anywhere without an import context
// juggle. Every top-level JSON key is a CFG_SECTION child object; the
// generic load()/save() logic lives entirely in ConfigSection, this class
// only adds: the file path, the debounced/atomic write, and the QML
// singleton factory.
class Config : public ConfigSection {
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
CFG_SECTION(Appearance, appearance, Appearance)
CFG_SECTION(Background, background, Background)
CFG_SECTION(Bar, bar, Bar)
CFG_SECTION(Clipboard, clipboard, Clipboard)
CFG_SECTION(Colors, colors, Colors)
CFG_SECTION(Dashboard, dashboard, Dashboard)
CFG_SECTION(Dock, dock, Dock)
CFG_SECTION(General, general, General)
CFG_SECTION(Launcher, launcher, Launcher)
CFG_SECTION(Lock, lock, Lock)
CFG_SECTION(Notifs, notifs, Notifs)
CFG_SECTION(Osd, osd, Osd)
CFG_SECTION(Overview, overview, Overview)
CFG_SECTION(Screenshot, screenshot, Screenshot)
CFG_SECTION(Services, services, Services)
CFG_SECTION(Sidebar, sidebar, Sidebar)
CFG_SECTION(Utilities, utilities, Utilities)
public:
explicit Config(QObject* parent = nullptr);
static Config* create(QQmlEngine*, QJSEngine*);
// Reload from disk, discarding any unsaved in-memory changes.
// Synchronous for first load on startup, async for subsequent reloads.
Q_INVOKABLE void load();
// Force an immediate synchronous write, bypassing the debounce timer.
// Call this from your shell's shutdown handler so nothing gets lost.
Q_INVOKABLE void saveNow();
// Reload from disk asynchronously (for file change notifications).
Q_INVOKABLE void reloadAsync();
private Q_SLOTS:
void scheduleSave();
void flushAsync();
private:
QString filePath() const;
void writeAtomically(const QByteArray& data);
void loadSync();
void loadAsync();
QTimer m_saveTimer;
bool m_loading = false;
bool m_firstLoadDone = false;
QFuture<void> m_loadFuture;
};
-87
View File
@@ -1,87 +0,0 @@
#include "ConfigSection.hpp"
#include <QMetaType>
#include <QVariant>
namespace {
// Property index to start scanning from - skips QObject's own "objectName"
// property, which we never want in the JSON.
int firstOwnProperty() {
return QObject::staticMetaObject.propertyCount();
}
}
ConfigSection::ConfigSection(QObject *parent) : QObject(parent) {}
void ConfigSection::wireSignals() {
if (m_wired) return;
m_wired = true;
const QMetaObject *mo = metaObject();
const int slotIdx = mo->indexOfSlot("onPropertyChanged()");
Q_ASSERT(slotIdx != -1);
const QMetaMethod slot = mo->method(slotIdx);
const int start = firstOwnProperty();
for (int i = start; i < mo->propertyCount(); ++i) {
const QMetaProperty prop = mo->property(i);
if (prop.metaType().flags().testFlag(QMetaType::PointerToQObject)) {
if (auto *child = qobject_cast<ConfigSection *>(prop.read(this).value<QObject *>())) {
// Child sections bubble their changes straight up as our
// own changed() - no need to also react to our own notify.
connect(child, &ConfigSection::changed, this, &ConfigSection::changed);
continue;
}
}
if (prop.hasNotifySignal())
connect(this, prop.notifySignal(), this, slot);
}
}
void ConfigSection::onPropertyChanged() {
Q_EMIT changed();
}
void ConfigSection::fromJson(const QJsonObject &obj) {
const QMetaObject *mo = metaObject();
const int start = firstOwnProperty();
for (int i = start; i < mo->propertyCount(); ++i) {
const QMetaProperty prop = mo->property(i);
const QLatin1String name(prop.name());
if (!obj.contains(name)) continue;
if (prop.metaType().flags().testFlag(QMetaType::PointerToQObject)) {
if (auto *child = qobject_cast<ConfigSection *>(prop.read(this).value<QObject *>())) {
child->fromJson(obj.value(name).toObject());
continue;
}
}
if (prop.isWritable())
prop.write(this, obj.value(name).toVariant());
}
}
QJsonObject ConfigSection::toJson() const {
QJsonObject obj;
const QMetaObject *mo = metaObject();
const int start = firstOwnProperty();
for (int i = start; i < mo->propertyCount(); ++i) {
const QMetaProperty prop = mo->property(i);
if (prop.metaType().flags().testFlag(QMetaType::PointerToQObject)) {
if (auto *child = qobject_cast<ConfigSection *>(prop.read(this).value<QObject *>())) {
obj.insert(QLatin1String(prop.name()), child->toJson());
continue;
}
}
obj.insert(QLatin1String(prop.name()), QJsonValue::fromVariant(prop.read(this)));
}
return obj;
}
-82
View File
@@ -1,82 +0,0 @@
#pragma once
#include <QObject>
#include <QJsonObject>
#include <QJsonValue>
#include <QMetaProperty>
#include <QMetaMethod>
// ---------------------------------------------------------------------------
// CFG_PROPERTY / CFG_SECTION
//
// These generate exactly the boilerplate you'd write by hand for a
// Q_PROPERTY with a backing member, getter, setter and NOTIFY signal - just
// in one line instead of ~8. Because everything they generate is a normal
// compiled getter/setter, there is *zero* extra runtime cost vs hand-written
// code: reading Config.appearance.anim.sessionGifSpeed from QML calls a
// plain inline getter. Reflection (QMetaObject) is only walked at load time,
// save time, and once at construction time to wire change signals - never
// on the read/write path itself.
//
// CFG_PROPERTY(type, name, Name)
// - type: C++ type (bool, int, qreal, QString, QVariantList, ...)
// - name: property name as it must appear in the JSON file (camelCase,
// or whatever the JSON actually uses - it MUST match exactly)
// - Name: same name, capitalized, used to build setName()/NameChanged()
//
// CFG_SECTION(Type, name, Name)
// - Declares a child ConfigSection* property (e.g. Anim inside Appearance)
// - The pointer itself is CONSTANT (never reassigned); the object it
// points to is what actually changes.
// ---------------------------------------------------------------------------
#define CFG_PROPERTY(type, name, Name) \
Q_PROPERTY(type name READ name WRITE set##Name NOTIFY Name##Changed) \
public: \
type name() const { return m_##name; } \
void set##Name(const type &value) { \
if (m_##name == value) return; \
m_##name = value; \
Q_EMIT Name##Changed(); \
} \
Q_SIGNALS: \
void Name##Changed(); \
private: \
type m_##name{};
#define CFG_SECTION(Type, name, Name) \
public: \
Q_PROPERTY(Type *name READ name CONSTANT) \
Type *name() const { return m_##name; } \
private: \
Type *m_##name = nullptr;
class ConfigSection : public QObject {
Q_OBJECT
public:
explicit ConfigSection(QObject *parent = nullptr);
// Populate this section (and all child sections) from JSON. Unknown
// keys in obj are ignored; missing keys keep their current value.
void fromJson(const QJsonObject &obj);
// Serialize this section (and all child sections) to JSON.
QJsonObject toJson() const;
Q_SIGNALS:
// Emitted whenever any property in this section, or any nested section,
// changes. Config listens on the root section to know a save is needed,
// without every leaf class needing to know about Config.
void changed();
protected:
// Call once, at the end of every subclass constructor, after all child
// ConfigSection* members have been constructed (new'd with `this` as
// parent). Sets up the reflection-based signal forwarding.
void wireSignals();
private Q_SLOTS:
void onPropertyChanged();
private:
bool m_wired = false;
};
-39
View File
@@ -1,39 +0,0 @@
#include "Dashboard.hpp"
Performance::Performance(QObject *parent) : ConfigSection(parent) {
m_enabled = true;
m_showBattery = false;
m_showCpu = true;
m_showGpu = true;
m_showMemory = true;
m_showNetwork = true;
m_showStorage = true;
m_showVram = true;
wireSignals();
}
DashboardSizes::DashboardSizes(QObject *parent) : ConfigSection(parent) {
m_dateTimeWidth = 110;
m_infoIconSize = 25;
m_infoWidth = 200;
m_mediaCoverArtSize = 150;
m_mediaProgressSweep = 180;
m_mediaProgressThickness = 8;
m_mediaVisualizerSize = 200;
m_mediaWidth = 200;
m_resourceProgessThickness = 10;
m_resourceSize = 200;
m_tabIndicatorHeight = 3;
m_tabIndicatorSpacing = 5;
m_weatherWidth = 250;
wireSignals();
}
Dashboard::Dashboard(QObject *parent) : ConfigSection(parent) {
m_enabled = true;
m_mediaUpdateInterval = 2000;
m_performance = new Performance(this);
m_resourceUpdateInterval = 1000;
m_sizes = new DashboardSizes(this);
wireSignals();
}
-56
View File
@@ -1,56 +0,0 @@
#pragma once
#include "ConfigSection.hpp"
#include <qqmlregistration.h>
class Performance : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(bool, enabled, Enabled)
CFG_PROPERTY(bool, showBattery, ShowBattery)
CFG_PROPERTY(bool, showCpu, ShowCpu)
CFG_PROPERTY(bool, showGpu, ShowGpu)
CFG_PROPERTY(bool, showMemory, ShowMemory)
CFG_PROPERTY(bool, showNetwork, ShowNetwork)
CFG_PROPERTY(bool, showStorage, ShowStorage)
CFG_PROPERTY(bool, showVram, ShowVram)
public:
explicit Performance(QObject *parent = nullptr);
};
class DashboardSizes : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(int, dateTimeWidth, DateTimeWidth)
CFG_PROPERTY(int, infoIconSize, InfoIconSize)
CFG_PROPERTY(int, infoWidth, InfoWidth)
CFG_PROPERTY(int, mediaCoverArtSize, MediaCoverArtSize)
CFG_PROPERTY(int, mediaProgressSweep, MediaProgressSweep)
CFG_PROPERTY(int, mediaProgressThickness, MediaProgressThickness)
CFG_PROPERTY(int, mediaVisualizerSize, MediaVisualizerSize)
CFG_PROPERTY(int, mediaWidth, MediaWidth)
CFG_PROPERTY(int, resourceProgessThickness, ResourceProgessThickness)
CFG_PROPERTY(int, resourceSize, ResourceSize)
CFG_PROPERTY(int, tabIndicatorHeight, TabIndicatorHeight)
CFG_PROPERTY(int, tabIndicatorSpacing, TabIndicatorSpacing)
CFG_PROPERTY(int, weatherWidth, WeatherWidth)
public:
explicit DashboardSizes(QObject *parent = nullptr);
};
class Dashboard : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(bool, enabled, Enabled)
CFG_PROPERTY(int, mediaUpdateInterval, MediaUpdateInterval)
CFG_SECTION(Performance, performance, Performance)
CFG_PROPERTY(int, resourceUpdateInterval, ResourceUpdateInterval)
CFG_SECTION(DashboardSizes, sizes, Sizes)
public:
explicit Dashboard(QObject *parent = nullptr);
};
-15
View File
@@ -1,15 +0,0 @@
#include "Dock.hpp"
Dock::Dock(QObject *parent) : ConfigSection(parent) {
m_enable = false;
m_height = 80;
m_hoverToReveal = false;
m_ignoredAppRegexes = {};
m_pinnedApps = {
QStringLiteral("com.ayugram.desktop"),
QStringLiteral("com.obsproject.studio"),
QStringLiteral("librewolf"),
};
m_pinnedOnStartup = false;
wireSignals();
}
-19
View File
@@ -1,19 +0,0 @@
#pragma once
#include "ConfigSection.hpp"
#include <qqmlregistration.h>
#include <QVariantList>
class Dock : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(bool, enable, Enable)
CFG_PROPERTY(int, height, Height)
CFG_PROPERTY(bool, hoverToReveal, HoverToReveal)
CFG_PROPERTY(QVariantList, ignoredAppRegexes, IgnoredAppRegexes)
CFG_PROPERTY(QVariantList, pinnedApps, PinnedApps)
CFG_PROPERTY(bool, pinnedOnStartup, PinnedOnStartup)
public:
explicit Dock(QObject *parent = nullptr);
};
-77
View File
@@ -1,77 +0,0 @@
#include "General.hpp"
namespace {
QVariantList strList(std::initializer_list<const char *> items) {
QVariantList list;
for (auto *item : items) list << QString::fromLatin1(item);
return list;
}
QVariantMap threshold(const char *icon, const char *message, const char *name, int perc) {
QVariantMap m;
m["icon"] = QString::fromLatin1(icon);
m["message"] = QString::fromLatin1(message);
m["name"] = QString::fromLatin1(name);
m["perc"] = perc;
return m;
}
}
Apps::Apps(QObject *parent) : ConfigSection(parent) {
m_archiver = strList({"ark"});
m_audio = strList({"pavucontrol"});
m_document = strList({"libreoffice"});
m_editor = strList({"kate"});
m_explorer = strList({"dolphin"});
m_image = strList({"imv"});
m_playback = strList({"vlc"});
m_terminal = strList({"wezterm"});
wireSignals();
}
Battery::Battery(QObject *parent) : ConfigSection(parent) {
m_critPerc = 5;
m_popupThresholds = {
threshold("battery_android_frame_2", "Battery low", "Low battery", 20),
threshold("battery_android_frame_2", "Battery lower", "Low battery", 15),
threshold("battery_android_frame_2", "Battery lowest", "Low battery", 10),
};
wireSignals();
}
ColorSettings::ColorSettings(QObject *parent) : ConfigSection(parent) {
m_hyprsunsetTemp = 2600;
m_mode = QStringLiteral("dark");
m_neovimColors = false;
m_scheduleDark = false;
m_scheduleDarkEnd = 600;
m_scheduleDarkStart = 1140;
m_scheduleHyprsunset = true;
m_scheduleHyprsunsetEnd = 570;
m_scheduleHyprsunsetStart = 1200;
m_schemeGeneration = true;
m_smart = false;
wireSignals();
}
Idle::Idle(QObject *parent) : ConfigSection(parent) {
QVariantMap lock;
lock["idleAction"] = QStringLiteral("lock");
lock["name"] = QStringLiteral("Lock");
lock["timeout"] = 180;
m_timeouts = { lock };
wireSignals();
}
General::General(QObject *parent) : ConfigSection(parent) {
m_apps = new Apps(this);
m_battery = new Battery(this);
m_color = new ColorSettings(this);
m_dateFormat = QStringLiteral("ddd d MMM - hh:mm:ss");
m_desktopIcons = true;
m_idle = new Idle(this);
m_logo = QString();
m_showOverFullscreen = true;
m_wallpaperPath = QStringLiteral("/mnt/IronWolf/SDImages/SWWW_Wals/");
wireSignals();
}
-82
View File
@@ -1,82 +0,0 @@
#pragma once
#include "ConfigSection.hpp"
#include <qqmlregistration.h>
#include <QVariantList>
class Apps : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(QVariantList, archiver, Archiver)
CFG_PROPERTY(QVariantList, audio, Audio)
CFG_PROPERTY(QVariantList, document, Document)
CFG_PROPERTY(QVariantList, editor, Editor)
CFG_PROPERTY(QVariantList, explorer, Explorer)
CFG_PROPERTY(QVariantList, image, Image)
CFG_PROPERTY(QVariantList, playback, Playback)
CFG_PROPERTY(QVariantList, terminal, Terminal)
public:
explicit Apps(QObject *parent = nullptr);
};
class Battery : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(int, critPerc, CritPerc)
// Array of { icon, message, name, perc } objects.
CFG_PROPERTY(QVariantList, popupThresholds, PopupThresholds)
public:
explicit Battery(QObject *parent = nullptr);
};
class ColorSettings : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(int, hyprsunsetTemp, HyprsunsetTemp)
CFG_PROPERTY(QString, mode, Mode)
CFG_PROPERTY(bool, neovimColors, NeovimColors)
CFG_PROPERTY(bool, scheduleDark, ScheduleDark)
CFG_PROPERTY(int, scheduleDarkEnd, ScheduleDarkEnd)
CFG_PROPERTY(int, scheduleDarkStart, ScheduleDarkStart)
CFG_PROPERTY(bool, scheduleHyprsunset, ScheduleHyprsunset)
CFG_PROPERTY(int, scheduleHyprsunsetEnd, ScheduleHyprsunsetEnd)
CFG_PROPERTY(int, scheduleHyprsunsetStart, ScheduleHyprsunsetStart)
CFG_PROPERTY(bool, schemeGeneration, SchemeGeneration)
CFG_PROPERTY(bool, smart, Smart)
public:
explicit ColorSettings(QObject *parent = nullptr);
};
class Idle : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
// Array of { idleAction, name, timeout } objects.
CFG_PROPERTY(QVariantList, timeouts, Timeouts)
public:
explicit Idle(QObject *parent = nullptr);
};
class General : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_SECTION(Apps, apps, Apps)
CFG_SECTION(Battery, battery, Battery)
CFG_SECTION(ColorSettings, color, Color)
CFG_PROPERTY(QString, dateFormat, DateFormat)
CFG_PROPERTY(bool, desktopIcons, DesktopIcons)
CFG_SECTION(Idle, idle, Idle)
CFG_PROPERTY(QString, logo, Logo)
CFG_PROPERTY(bool, showOverFullscreen, ShowOverFullscreen)
CFG_PROPERTY(QString, wallpaperPath, WallpaperPath)
public:
explicit General(QObject *parent = nullptr);
};
-71
View File
@@ -1,71 +0,0 @@
#include "Launcher.hpp"
namespace {
QVariantList strList(std::initializer_list<const char *> items) {
QVariantList list;
for (auto *item : items) list << QString::fromLatin1(item);
return list;
}
QVariantMap action(QVariantList command, bool dangerous, const char *description,
bool enabled, const char *icon, const char *name) {
QVariantMap m;
m["command"] = std::move(command);
m["dangerous"] = dangerous;
m["description"] = QString::fromLatin1(description);
m["enabled"] = enabled;
m["icon"] = QString::fromLatin1(icon);
m["name"] = QString::fromLatin1(name);
return m;
}
}
LauncherSizes::LauncherSizes(QObject *parent) : ConfigSection(parent) {
m_itemHeight = 50;
m_itemWidth = 600;
m_wallpaperHeight = 200;
m_wallpaperWidth = 280;
wireSignals();
}
UseFuzzy::UseFuzzy(QObject *parent) : ConfigSection(parent) {
m_actions = true;
m_apps = true;
m_schemes = true;
m_variants = true;
m_wallpapers = true;
wireSignals();
}
Launcher::Launcher(QObject *parent) : ConfigSection(parent) {
m_actionPrefix = QStringLiteral("<");
m_actions = {
action(strList({"autocomplete", "calc"}), false, "Do simple math equations", true, "calculate", "Calculator"),
action(strList({"setMode", "light"}), false, "Change to light mode", true, "light_mode", "Light"),
action(strList({"setMode", "dark"}), false, "Change to dark mode", true, "dark_mode", "Dark"),
action(strList({"autocomplete", "wallpaper"}), false, "Change the current wallpaper", true, "image", "Wallpaper"),
action(strList({"autocomplete", "variant"}), false, "Change the current scheme variant", true, "colors", "Variant"),
action(strList({"systemctl", "poweroff"}), true, "Shutdown the system", true, "power_settings_new", "Shutdown"),
action(strList({"systemctl", "reboot"}), true, "Reboot the system", true, "cached", "Reboot"),
action(strList({"loginctl", "terminate-user", ""}), true, "Log out of the current session", true, "logout", "Logout"),
action(strList({"loginctl", "lock-session"}), false, "Lock the current session", true, "lock", "Lock"),
action(strList({"systemctl", "suspend-then-hibernate"}), false, "Suspend then hibernate", true, "bedtime", "Sleep"),
};
m_dragThreshold = 150;
m_enableDangerousActions = true;
m_enabled = true;
m_favoriteApps = strList({"Balatro", "Slay the Spire 2", "com.obsproject.Studio"});
m_hiddenApps = strList({
"zellij", "vim", "jshell-java-openjdk", "jconsole-java-openjdk",
"jshell-java21-openjdk", "jconsole-java21-openjdk", "jshell-java17-openjdk",
"jconsole-java17-openjdk", "org.neovim.nvim", "avahi-discover", "bvnc",
"bssh", "nm-connection-editor",
});
m_maxAppsShown = 18;
m_maxWallpapers = 7;
m_sizes = new LauncherSizes(this);
m_specialPrefix = QStringLiteral("@");
m_useFuzzy = new UseFuzzy(this);
m_uwsm = true;
wireSignals();
}
-55
View File
@@ -1,55 +0,0 @@
#pragma once
#include "ConfigSection.hpp"
#include <qqmlregistration.h>
#include <QVariantList>
class LauncherSizes : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(int, itemHeight, ItemHeight)
CFG_PROPERTY(int, itemWidth, ItemWidth)
CFG_PROPERTY(int, wallpaperHeight, WallpaperHeight)
CFG_PROPERTY(int, wallpaperWidth, WallpaperWidth)
public:
explicit LauncherSizes(QObject *parent = nullptr);
};
class UseFuzzy : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(bool, actions, Actions)
CFG_PROPERTY(bool, apps, Apps)
CFG_PROPERTY(bool, schemes, Schemes)
CFG_PROPERTY(bool, variants, Variants)
CFG_PROPERTY(bool, wallpapers, Wallpapers)
public:
explicit UseFuzzy(QObject *parent = nullptr);
};
class Launcher : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(QString, actionPrefix, ActionPrefix)
// Array of action-definition objects (command, dangerous, description,
// enabled, icon, name).
CFG_PROPERTY(QVariantList, actions, Actions)
CFG_PROPERTY(int, dragThreshold, DragThreshold)
CFG_PROPERTY(bool, enableDangerousActions, EnableDangerousActions)
CFG_PROPERTY(bool, enabled, Enabled)
CFG_PROPERTY(QVariantList, favoriteApps, FavoriteApps)
CFG_PROPERTY(QVariantList, hiddenApps, HiddenApps)
CFG_PROPERTY(int, maxAppsShown, MaxAppsShown)
CFG_PROPERTY(int, maxWallpapers, MaxWallpapers)
CFG_SECTION(LauncherSizes, sizes, Sizes)
CFG_PROPERTY(QString, specialPrefix, SpecialPrefix)
CFG_SECTION(UseFuzzy, useFuzzy, UseFuzzy)
CFG_PROPERTY(bool, uwsm, Uwsm)
public:
explicit Launcher(QObject *parent = nullptr);
};
-19
View File
@@ -1,19 +0,0 @@
#include "Lock.hpp"
LockSizes::LockSizes(QObject *parent) : ConfigSection(parent) {
m_centerWidth = 600;
m_heightMult = 0.7;
m_ratio = 1.78;
wireSignals();
}
Lock::Lock(QObject *parent) : ConfigSection(parent) {
m_blurAmount = 10;
m_enableFprint = true;
m_maxFprintTries = 3;
m_recolorLogo = false;
m_showNotifContent = true;
m_showNotifIcon = true;
m_sizes = new LockSizes(this);
wireSignals();
}
-31
View File
@@ -1,31 +0,0 @@
#pragma once
#include "ConfigSection.hpp"
#include <qqmlregistration.h>
class LockSizes : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(int, centerWidth, CenterWidth)
CFG_PROPERTY(qreal, heightMult, HeightMult)
CFG_PROPERTY(qreal, ratio, Ratio)
public:
explicit LockSizes(QObject *parent = nullptr);
};
class Lock : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(int, blurAmount, BlurAmount)
CFG_PROPERTY(bool, enableFprint, EnableFprint)
CFG_PROPERTY(int, maxFprintTries, MaxFprintTries)
CFG_PROPERTY(bool, recolorLogo, RecolorLogo)
CFG_PROPERTY(bool, showNotifContent, ShowNotifContent)
CFG_PROPERTY(bool, showNotifIcon, ShowNotifIcon)
CFG_SECTION(LockSizes, sizes, Sizes)
public:
explicit Lock(QObject *parent = nullptr);
};
-22
View File
@@ -1,22 +0,0 @@
#include "Notifs.hpp"
NotifsSizes::NotifsSizes(QObject *parent) : ConfigSection(parent) {
m_badge = 20;
m_image = 41;
m_width = 400;
wireSignals();
}
Notifs::Notifs(QObject *parent) : ConfigSection(parent) {
m_actionOnClick = false;
m_appNotifCooldown = 0;
m_clearThreshold = 0.3;
m_defaultExpireTimeout = 5000;
m_expandThreshold = 20;
m_expire = true;
m_groupPreviewNum = 5;
m_openExpanded = false;
m_showInFullscreen = false;
m_sizes = new NotifsSizes(this);
wireSignals();
}
-34
View File
@@ -1,34 +0,0 @@
#pragma once
#include "ConfigSection.hpp"
#include <qqmlregistration.h>
class NotifsSizes : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(int, badge, Badge)
CFG_PROPERTY(int, image, Image)
CFG_PROPERTY(int, width, Width)
public:
explicit NotifsSizes(QObject *parent = nullptr);
};
class Notifs : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(bool, actionOnClick, ActionOnClick)
CFG_PROPERTY(int, appNotifCooldown, AppNotifCooldown)
CFG_PROPERTY(qreal, clearThreshold, ClearThreshold)
CFG_PROPERTY(int, defaultExpireTimeout, DefaultExpireTimeout)
CFG_PROPERTY(int, expandThreshold, ExpandThreshold)
CFG_PROPERTY(bool, expire, Expire)
CFG_PROPERTY(int, groupPreviewNum, GroupPreviewNum)
CFG_PROPERTY(bool, openExpanded, OpenExpanded)
CFG_PROPERTY(bool, showInFullscreen, ShowInFullscreen)
CFG_SECTION(NotifsSizes, sizes, Sizes)
public:
explicit Notifs(QObject *parent = nullptr);
};
-17
View File
@@ -1,17 +0,0 @@
#include "Osd.hpp"
OsdSizes::OsdSizes(QObject *parent) : ConfigSection(parent) {
m_sliderHeight = 150;
m_sliderWidth = 30;
wireSignals();
}
Osd::Osd(QObject *parent) : ConfigSection(parent) {
m_allMonBrightness = true;
m_enableBrightness = true;
m_enableMicrophone = true;
m_enabled = true;
m_hideDelay = 3000;
m_sizes = new OsdSizes(this);
wireSignals();
}
-29
View File
@@ -1,29 +0,0 @@
#pragma once
#include "ConfigSection.hpp"
#include <qqmlregistration.h>
class OsdSizes : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(int, sliderHeight, SliderHeight)
CFG_PROPERTY(int, sliderWidth, SliderWidth)
public:
explicit OsdSizes(QObject *parent = nullptr);
};
class Osd : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(bool, allMonBrightness, AllMonBrightness)
CFG_PROPERTY(bool, enableBrightness, EnableBrightness)
CFG_PROPERTY(bool, enableMicrophone, EnableMicrophone)
CFG_PROPERTY(bool, enabled, Enabled)
CFG_PROPERTY(int, hideDelay, HideDelay)
CFG_SECTION(OsdSizes, sizes, Sizes)
public:
explicit Osd(QObject *parent = nullptr);
};
-9
View File
@@ -1,9 +0,0 @@
#include "Overview.hpp"
Overview::Overview(QObject *parent) : ConfigSection(parent) {
m_columns = 5;
m_enable = false;
m_rows = 2;
m_scale = 0.16;
wireSignals();
}
-16
View File
@@ -1,16 +0,0 @@
#pragma once
#include "ConfigSection.hpp"
#include <qqmlregistration.h>
class Overview : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(int, columns, Columns)
CFG_PROPERTY(bool, enable, Enable)
CFG_PROPERTY(int, rows, Rows)
CFG_PROPERTY(qreal, scale, Scale)
public:
explicit Overview(QObject *parent = nullptr);
};
-15
View File
@@ -1,15 +0,0 @@
#include "Screenshot.hpp"
Screenshot::Screenshot(QObject *parent) : ConfigSection(parent) {
m_enable_pp = false;
m_mode = QStringLiteral("manual");
m_radius = 49;
m_rounding = false;
m_saveOnCopy = false;
m_shadow = true;
m_shadow_blur = 0;
m_shadow_color = { 0, 0, 0, 160 };
m_shadow_offset_x = 30;
m_shadow_offset_y = 50;
wireSignals();
}
-26
View File
@@ -1,26 +0,0 @@
#pragma once
#include "ConfigSection.hpp"
#include <qqmlregistration.h>
#include <QVariantList>
class Screenshot : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
// Property names below must match the JSON keys exactly (the JSON here
// uses snake_case for these particular keys, so we do too).
CFG_PROPERTY(bool, enable_pp, EnablePp)
CFG_PROPERTY(QString, mode, Mode)
CFG_PROPERTY(int, radius, Radius)
CFG_PROPERTY(bool, rounding, Rounding)
CFG_PROPERTY(bool, saveOnCopy, SaveOnCopy)
CFG_PROPERTY(bool, shadow, Shadow)
CFG_PROPERTY(int, shadow_blur, ShadowBlur)
// [r, g, b, a]
CFG_PROPERTY(QVariantList, shadow_color, ShadowColor)
CFG_PROPERTY(int, shadow_offset_x, ShadowOffsetX)
CFG_PROPERTY(int, shadow_offset_y, ShadowOffsetY)
public:
explicit Screenshot(QObject *parent = nullptr);
};
-23
View File
@@ -1,23 +0,0 @@
#include "Services.hpp"
Services::Services(QObject *parent) : ConfigSection(parent) {
m_audioIncrement = 0.1;
m_brightnessIncrement = 0.1;
m_ddcutilService = true;
m_defaultPlayer = QStringLiteral("Spotify");
m_gpuType = QStringLiteral("NVIDIA");
m_maxVolume = 1;
m_minBrightness = 0.01;
QVariantMap alias;
alias["from"] = QStringLiteral("com.github.th_ch.youtube_music");
alias["to"] = QStringLiteral("YT Music");
m_playerAliases = { alias };
m_updates = true;
m_useFahrenheit = false;
m_useTwelveHourClock = false;
m_visualizerBars = 50;
m_weatherLocation = QString();
wireSignals();
}
-27
View File
@@ -1,27 +0,0 @@
#pragma once
#include "ConfigSection.hpp"
#include <qqmlregistration.h>
#include <QVariantList>
class Services : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(qreal, audioIncrement, AudioIncrement)
CFG_PROPERTY(qreal, brightnessIncrement, BrightnessIncrement)
CFG_PROPERTY(bool, ddcutilService, DdcutilService)
CFG_PROPERTY(QString, defaultPlayer, DefaultPlayer)
CFG_PROPERTY(QString, gpuType, GpuType)
CFG_PROPERTY(qreal, maxVolume, MaxVolume)
CFG_PROPERTY(qreal, minBrightness, MinBrightness)
// Array of { from, to } objects.
CFG_PROPERTY(QVariantList, playerAliases, PlayerAliases)
CFG_PROPERTY(bool, updates, Updates)
CFG_PROPERTY(bool, useFahrenheit, UseFahrenheit)
CFG_PROPERTY(bool, useTwelveHourClock, UseTwelveHourClock)
CFG_PROPERTY(int, visualizerBars, VisualizerBars)
CFG_PROPERTY(QString, weatherLocation, WeatherLocation)
public:
explicit Services(QObject *parent = nullptr);
};
-13
View File
@@ -1,13 +0,0 @@
#include "Sidebar.hpp"
SidebarSizes::SidebarSizes(QObject *parent) : ConfigSection(parent) {
m_width = 520;
wireSignals();
}
Sidebar::Sidebar(QObject *parent) : ConfigSection(parent) {
m_dragThreshold = 30;
m_enabled = true;
m_sizes = new SidebarSizes(this);
wireSignals();
}
-25
View File
@@ -1,25 +0,0 @@
#pragma once
#include "ConfigSection.hpp"
#include <qqmlregistration.h>
class SidebarSizes : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(int, width, Width)
public:
explicit SidebarSizes(QObject *parent = nullptr);
};
class Sidebar : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(int, dragThreshold, DragThreshold)
CFG_PROPERTY(bool, enabled, Enabled)
CFG_SECTION(SidebarSizes, sizes, Sizes)
public:
explicit Sidebar(QObject *parent = nullptr);
};
-109
View File
@@ -1,109 +0,0 @@
#include "Tokens.hpp"
TokensRounding::TokensRounding(QObject* parent) : QObject(parent) {
m_extraSmall = 4;
m_full = 1000;
m_large = 24;
m_medium = 16;
m_normal = 18;
m_scale = 1;
m_small = 12;
m_smallest = 8;
}
TokensPadding::TokensPadding(QObject* parent) : QObject(parent) {
m_extraLarge = 28;
m_extraLargeIncreased = 32;
m_extraSmall = 4;
m_large = 16;
m_largeIncreased = 20;
m_larger = 12;
m_normal = 8;
m_scale = 1;
m_small = 5;
m_smaller = 7;
m_smallest = 2;
}
TokensSpacing::TokensSpacing(QObject* parent) : QObject(parent) {
m_extraSmall = 4;
m_large = 20;
m_larger = 16;
m_normal = 12;
m_scale = 1;
m_small = 8;
m_smaller = 10;
}
TokensFontSize::TokensFontSize(QObject* parent) : QObject(parent) {
m_extraLarge = 28;
m_large = 18;
m_larger = 16;
m_medium = 14;
m_normal = 13;
m_scale = 1;
m_small = 11;
m_smaller = 12;
}
TokensFont::TokensFont(QObject* parent) : QObject(parent) {
m_size = new TokensFontSize(this);
}
TokensAnimCurves::TokensAnimCurves(QObject* parent) : QObject(parent) {
m_emphasized = {
0.05,
0,
2.0 / 15.0,
0.06,
1.0 / 6.0,
0.4,
5.0 / 24.0,
0.82,
0.25,
1,
1,
1};
m_emphasizedAccel = {0.3, 0, 0.8, 0.15, 1, 1};
m_emphasizedDecel = {0.05, 0.7, 0.1, 1, 1, 1};
m_expressiveDefaultEffects = {0.34, 0.8, 0.34, 1, 1, 1};
m_expressiveDefaultSpatial = {0.38, 1.21, 0.22, 1, 1, 1};
m_expressiveEffects = {0.34, 0.8, 0.34, 1, 1, 1};
m_expressiveFastEffects = {0.31, 0.94, 0.34, 1, 1, 1};
m_expressiveFastSpatial = {0.42, 1.67, 0.21, 0.9, 1, 1};
m_expressiveSlowEffects = {0.34, 0.88, 0.34, 1, 1, 1};
m_expressiveSlowSpatial = {0.39, 1.29, 0.35, 0.98, 1, 1};
m_standard = {0.2, 0, 0, 1, 1, 1};
m_standardAccel = {0.3, 0, 1, 1, 1, 1};
m_standardDecel = {0, 0, 0, 1, 1, 1};
}
TokensAnimDurations::TokensAnimDurations(QObject* parent) : QObject(parent) {
m_expressiveDefaultSpatial = 500;
m_expressiveEffects = 200;
m_expressiveFastEffects = 150;
m_expressiveFastSpatial = 350;
m_expressiveSlowEffects = 300;
m_extraLarge = 1000;
m_large = 600;
m_normal = 400;
m_scale = 1;
m_small = 200;
}
TokensAnim::TokensAnim(QObject* parent) : QObject(parent) {
m_curves = new TokensAnimCurves(this);
m_durations = new TokensAnimDurations(this);
}
Tokens::Tokens(QObject* parent) : QObject(parent) {
m_rounding = new TokensRounding(this);
m_padding = new TokensPadding(this);
m_spacing = new TokensSpacing(this);
m_font = new TokensFont(this);
m_anim = new TokensAnim(this);
}
Tokens* Tokens::create(QQmlEngine*, QJSEngine*) {
return new Tokens();
}
-348
View File
@@ -1,348 +0,0 @@
#pragma once
#include <QObject>
#include <qqmlregistration.h>
#include <QQmlEngine>
#include <QJSEngine>
class TokensRounding : public QObject {
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
QML_UNCREATABLE("Instantiated internally by Tokens")
Q_PROPERTY(qreal extraSmall READ extraSmall CONSTANT)
Q_PROPERTY(qreal full READ full CONSTANT)
Q_PROPERTY(qreal large READ large CONSTANT)
Q_PROPERTY(qreal medium READ medium CONSTANT)
Q_PROPERTY(qreal normal READ normal CONSTANT)
Q_PROPERTY(qreal scale READ scale CONSTANT)
Q_PROPERTY(qreal small READ small CONSTANT)
Q_PROPERTY(qreal smallest READ smallest CONSTANT)
public:
explicit TokensRounding(QObject* parent = nullptr);
qreal extraSmall() const { return m_extraSmall; }
qreal full() const { return m_full; }
qreal large() const { return m_large; }
qreal medium() const { return m_medium; }
qreal normal() const { return m_normal; }
qreal scale() const { return m_scale; }
qreal small() const { return m_small; }
qreal smallest() const { return m_smallest; }
private:
qreal m_extraSmall;
qreal m_full;
qreal m_large;
qreal m_medium;
qreal m_normal;
qreal m_scale;
qreal m_small;
qreal m_smallest;
};
class TokensPadding : public QObject {
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
QML_UNCREATABLE("Instantiated internally by Tokens")
Q_PROPERTY(qreal extraLarge READ extraLarge CONSTANT)
Q_PROPERTY(qreal extraLargeIncreased READ extraLargeIncreased CONSTANT)
Q_PROPERTY(qreal extraSmall READ extraSmall CONSTANT)
Q_PROPERTY(qreal large READ large CONSTANT)
Q_PROPERTY(qreal largeIncreased READ largeIncreased CONSTANT)
Q_PROPERTY(qreal larger READ larger CONSTANT)
Q_PROPERTY(qreal normal READ normal CONSTANT)
Q_PROPERTY(qreal scale READ scale CONSTANT)
Q_PROPERTY(qreal small READ small CONSTANT)
Q_PROPERTY(qreal smaller READ smaller CONSTANT)
Q_PROPERTY(qreal smallest READ smallest CONSTANT)
public:
explicit TokensPadding(QObject* parent = nullptr);
qreal extraLarge() const { return m_extraLarge; }
qreal extraLargeIncreased() const { return m_extraLargeIncreased; }
qreal extraSmall() const { return m_extraSmall; }
qreal large() const { return m_large; }
qreal largeIncreased() const { return m_largeIncreased; }
qreal larger() const { return m_larger; }
qreal normal() const { return m_normal; }
qreal scale() const { return m_scale; }
qreal small() const { return m_small; }
qreal smaller() const { return m_smaller; }
qreal smallest() const { return m_smallest; }
private:
qreal m_extraLarge;
qreal m_extraLargeIncreased;
qreal m_extraSmall;
qreal m_large;
qreal m_largeIncreased;
qreal m_larger;
qreal m_normal;
qreal m_scale;
qreal m_small;
qreal m_smaller;
qreal m_smallest;
};
class TokensSpacing : public QObject {
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
QML_UNCREATABLE("Instantiated internally by Tokens")
Q_PROPERTY(qreal extraSmall READ extraSmall CONSTANT)
Q_PROPERTY(qreal large READ large CONSTANT)
Q_PROPERTY(qreal larger READ larger CONSTANT)
Q_PROPERTY(qreal normal READ normal CONSTANT)
Q_PROPERTY(qreal scale READ scale CONSTANT)
Q_PROPERTY(qreal small READ small CONSTANT)
Q_PROPERTY(qreal smaller READ smaller CONSTANT)
public:
explicit TokensSpacing(QObject* parent = nullptr);
qreal extraSmall() const { return m_extraSmall; }
qreal large() const { return m_large; }
qreal larger() const { return m_larger; }
qreal normal() const { return m_normal; }
qreal scale() const { return m_scale; }
qreal small() const { return m_small; }
qreal smaller() const { return m_smaller; }
private:
qreal m_extraSmall;
qreal m_large;
qreal m_larger;
qreal m_normal;
qreal m_scale;
qreal m_small;
qreal m_smaller;
};
class TokensFontSize : public QObject {
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
QML_UNCREATABLE("Instantiated internally by Tokens")
Q_PROPERTY(qreal extraLarge READ extraLarge CONSTANT)
Q_PROPERTY(qreal large READ large CONSTANT)
Q_PROPERTY(qreal larger READ larger CONSTANT)
Q_PROPERTY(qreal medium READ medium CONSTANT)
Q_PROPERTY(qreal normal READ normal CONSTANT)
Q_PROPERTY(qreal scale READ scale CONSTANT)
Q_PROPERTY(qreal small READ small CONSTANT)
Q_PROPERTY(qreal smaller READ smaller CONSTANT)
public:
explicit TokensFontSize(QObject* parent = nullptr);
qreal extraLarge() const { return m_extraLarge; }
qreal large() const { return m_large; }
qreal larger() const { return m_larger; }
qreal medium() const { return m_medium; }
qreal normal() const { return m_normal; }
qreal scale() const { return m_scale; }
qreal small() const { return m_small; }
qreal smaller() const { return m_smaller; }
private:
qreal m_extraLarge;
qreal m_large;
qreal m_larger;
qreal m_medium;
qreal m_normal;
qreal m_scale;
qreal m_small;
qreal m_smaller;
};
class TokensFont : public QObject {
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
QML_UNCREATABLE("Instantiated internally by Tokens")
Q_PROPERTY(TokensFontSize* size READ size CONSTANT)
public:
explicit TokensFont(QObject* parent = nullptr);
TokensFontSize* size() const { return m_size; }
private:
TokensFontSize* m_size = nullptr;
};
class TokensAnimCurves : public QObject {
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
QML_UNCREATABLE("Instantiated internally by Tokens")
Q_PROPERTY(QVariantList emphasized READ emphasized CONSTANT)
Q_PROPERTY(QVariantList emphasizedAccel READ emphasizedAccel CONSTANT)
Q_PROPERTY(QVariantList emphasizedDecel READ emphasizedDecel CONSTANT)
Q_PROPERTY(
QVariantList expressiveDefaultEffects READ expressiveDefaultEffects
CONSTANT)
Q_PROPERTY(
QVariantList expressiveDefaultSpatial READ expressiveDefaultSpatial
CONSTANT)
Q_PROPERTY(QVariantList expressiveEffects READ expressiveEffects CONSTANT)
Q_PROPERTY(
QVariantList expressiveFastEffects READ expressiveFastEffects CONSTANT)
Q_PROPERTY(
QVariantList expressiveFastSpatial READ expressiveFastSpatial CONSTANT)
Q_PROPERTY(
QVariantList expressiveSlowEffects READ expressiveSlowEffects CONSTANT)
Q_PROPERTY(
QVariantList expressiveSlowSpatial READ expressiveSlowSpatial CONSTANT)
Q_PROPERTY(QVariantList standard READ standard CONSTANT)
Q_PROPERTY(QVariantList standardAccel READ standardAccel CONSTANT)
Q_PROPERTY(QVariantList standardDecel READ standardDecel CONSTANT)
public:
explicit TokensAnimCurves(QObject* parent = nullptr);
QVariantList emphasized() const { return m_emphasized; }
QVariantList emphasizedAccel() const { return m_emphasizedAccel; }
QVariantList emphasizedDecel() const { return m_emphasizedDecel; }
QVariantList expressiveDefaultEffects() const {
return m_expressiveDefaultEffects;
}
QVariantList expressiveDefaultSpatial() const {
return m_expressiveDefaultSpatial;
}
QVariantList expressiveEffects() const { return m_expressiveEffects; }
QVariantList expressiveFastEffects() const {
return m_expressiveFastEffects;
}
QVariantList expressiveFastSpatial() const {
return m_expressiveFastSpatial;
}
QVariantList expressiveSlowEffects() const {
return m_expressiveSlowEffects;
}
QVariantList expressiveSlowSpatial() const {
return m_expressiveSlowSpatial;
}
QVariantList standard() const { return m_standard; }
QVariantList standardAccel() const { return m_standardAccel; }
QVariantList standardDecel() const { return m_standardDecel; }
private:
QVariantList m_emphasized;
QVariantList m_emphasizedAccel;
QVariantList m_emphasizedDecel;
QVariantList m_expressiveDefaultEffects;
QVariantList m_expressiveDefaultSpatial;
QVariantList m_expressiveEffects;
QVariantList m_expressiveFastEffects;
QVariantList m_expressiveFastSpatial;
QVariantList m_expressiveSlowEffects;
QVariantList m_expressiveSlowSpatial;
QVariantList m_standard;
QVariantList m_standardAccel;
QVariantList m_standardDecel;
};
class TokensAnimDurations : public QObject {
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
QML_UNCREATABLE("Instantiated internally by Tokens")
Q_PROPERTY(
int expressiveDefaultSpatial READ expressiveDefaultSpatial CONSTANT)
Q_PROPERTY(int expressiveEffects READ expressiveEffects CONSTANT)
Q_PROPERTY(int expressiveFastEffects READ expressiveFastEffects CONSTANT)
Q_PROPERTY(int expressiveFastSpatial READ expressiveFastSpatial CONSTANT)
Q_PROPERTY(int expressiveSlowEffects READ expressiveSlowEffects CONSTANT)
Q_PROPERTY(int extraLarge READ extraLarge CONSTANT)
Q_PROPERTY(int large READ large CONSTANT)
Q_PROPERTY(int normal READ normal CONSTANT)
Q_PROPERTY(qreal scale READ scale CONSTANT)
Q_PROPERTY(int small READ small CONSTANT)
public:
explicit TokensAnimDurations(QObject* parent = nullptr);
int expressiveDefaultSpatial() const { return m_expressiveDefaultSpatial; }
int expressiveEffects() const { return m_expressiveEffects; }
int expressiveFastEffects() const { return m_expressiveFastEffects; }
int expressiveFastSpatial() const { return m_expressiveFastSpatial; }
int expressiveSlowEffects() const { return m_expressiveSlowEffects; }
int extraLarge() const { return m_extraLarge; }
int large() const { return m_large; }
int normal() const { return m_normal; }
qreal scale() const { return m_scale; }
int small() const { return m_small; }
private:
int m_expressiveDefaultSpatial;
int m_expressiveEffects;
int m_expressiveFastEffects;
int m_expressiveFastSpatial;
int m_expressiveSlowEffects;
int m_extraLarge;
int m_large;
int m_normal;
qreal m_scale;
int m_small;
};
class TokensAnim : public QObject {
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
QML_UNCREATABLE("Instantiated internally by Tokens")
Q_PROPERTY(TokensAnimCurves* curves READ curves CONSTANT)
Q_PROPERTY(TokensAnimDurations* durations READ durations CONSTANT)
public:
explicit TokensAnim(QObject* parent = nullptr);
TokensAnimCurves* curves() const { return m_curves; }
TokensAnimDurations* durations() const { return m_durations; }
private:
TokensAnimCurves* m_curves = nullptr;
TokensAnimDurations* m_durations = nullptr;
};
class Tokens : public QObject {
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
Q_PROPERTY(TokensRounding* rounding READ rounding CONSTANT)
Q_PROPERTY(TokensPadding* padding READ padding CONSTANT)
Q_PROPERTY(TokensSpacing* spacing READ spacing CONSTANT)
Q_PROPERTY(TokensFont* font READ font CONSTANT)
Q_PROPERTY(TokensAnim* anim READ anim CONSTANT)
public:
explicit Tokens(QObject* parent = nullptr);
static Tokens* create(QQmlEngine*, QJSEngine*);
TokensRounding* rounding() const { return m_rounding; }
TokensPadding* padding() const { return m_padding; }
TokensSpacing* spacing() const { return m_spacing; }
TokensFont* font() const { return m_font; }
TokensAnim* anim() const { return m_anim; }
private:
TokensRounding* m_rounding = nullptr;
TokensPadding* m_padding = nullptr;
TokensSpacing* m_spacing = nullptr;
TokensFont* m_font = nullptr;
TokensAnim* m_anim = nullptr;
};
-38
View File
@@ -1,38 +0,0 @@
#include "Utilities.hpp"
UtilitiesSizes::UtilitiesSizes(QObject *parent) : ConfigSection(parent) {
m_toastWidth = 430;
m_width = 430;
wireSignals();
}
Toasts::Toasts(QObject *parent) : ConfigSection(parent) {
m_audioInputChanged = true;
m_audioOutputChanged = true;
m_capsLockChanged = true;
m_chargingChanged = true;
m_configLoaded = true;
m_dndChanged = true;
m_gameModeChanged = true;
m_kbLayoutChanged = true;
m_kbLimit = true;
m_nowPlaying = false;
m_numLockChanged = true;
m_vpnChanged = true;
wireSignals();
}
Vpn::Vpn(QObject *parent) : ConfigSection(parent) {
m_enabled = false;
m_provider = { QStringLiteral("netbird") };
wireSignals();
}
Utilities::Utilities(QObject *parent) : ConfigSection(parent) {
m_enabled = true;
m_maxToasts = 4;
m_sizes = new UtilitiesSizes(this);
m_toasts = new Toasts(this);
m_vpn = new Vpn(this);
wireSignals();
}
-61
View File
@@ -1,61 +0,0 @@
#pragma once
#include "ConfigSection.hpp"
#include <qqmlregistration.h>
#include <QVariantList>
class UtilitiesSizes : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(int, toastWidth, ToastWidth)
CFG_PROPERTY(int, width, Width)
public:
explicit UtilitiesSizes(QObject *parent = nullptr);
};
class Toasts : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(bool, audioInputChanged, AudioInputChanged)
CFG_PROPERTY(bool, audioOutputChanged, AudioOutputChanged)
CFG_PROPERTY(bool, capsLockChanged, CapsLockChanged)
CFG_PROPERTY(bool, chargingChanged, ChargingChanged)
CFG_PROPERTY(bool, configLoaded, ConfigLoaded)
CFG_PROPERTY(bool, dndChanged, DndChanged)
CFG_PROPERTY(bool, gameModeChanged, GameModeChanged)
CFG_PROPERTY(bool, kbLayoutChanged, KbLayoutChanged)
CFG_PROPERTY(bool, kbLimit, KbLimit)
CFG_PROPERTY(bool, nowPlaying, NowPlaying)
CFG_PROPERTY(bool, numLockChanged, NumLockChanged)
CFG_PROPERTY(bool, vpnChanged, VpnChanged)
public:
explicit Toasts(QObject *parent = nullptr);
};
class Vpn : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(bool, enabled, Enabled)
CFG_PROPERTY(QVariantList, provider, Provider)
public:
explicit Vpn(QObject *parent = nullptr);
};
class Utilities : public ConfigSection {
Q_OBJECT
QML_UNCREATABLE("Instantiated internally by Config")
CFG_PROPERTY(bool, enabled, Enabled)
CFG_PROPERTY(int, maxToasts, MaxToasts)
CFG_SECTION(UtilitiesSizes, sizes, Sizes)
CFG_SECTION(Toasts, toasts, Toasts)
CFG_SECTION(Vpn, vpn, Vpn)
public:
explicit Utilities(QObject *parent = nullptr);
};
+83
View File
@@ -0,0 +1,83 @@
#pragma once
#include "configobject.hpp"
#include <qqmlregistration.h>
namespace ZShell::config {
class Anim : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(int, mediaGifSpeedAdjustment, 300)
CFG_PROPERTY(qreal, sessionGifSpeed, 0.7)
public:
explicit Anim(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class Deform : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(qreal, scale, 1)
public:
explicit Deform(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class FontFamily : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(QString, clock, QStringLiteral("Rubik"))
CFG_PROPERTY(QString, material, QStringLiteral("Material Symbols Rounded"))
CFG_PROPERTY(QString, mono, QStringLiteral("CaskaydiaCove NF"))
CFG_PROPERTY(QString, sans, QStringLiteral("Segoe UI Variable Text"))
public:
explicit FontFamily(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class Font : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CONFIG_SUBOBJECT(FontFamily, family)
public:
explicit Font(QObject* parent = nullptr)
: ConfigObject(parent), m_family(new FontFamily(this)) {}
};
class Transparency : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(qreal, base, 0.85)
CFG_PROPERTY(bool, enabled, false)
CFG_PROPERTY(qreal, layers, 0.4)
public:
explicit Transparency(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class Appearance : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CONFIG_SUBOBJECT(Anim, anim)
CONFIG_SUBOBJECT(Deform, deform)
CONFIG_SUBOBJECT(Font, font)
CONFIG_SUBOBJECT(Transparency, transparency)
public:
explicit Appearance(QObject* parent = nullptr)
: ConfigObject(parent)
, m_anim(new Anim(this))
, m_deform(new Deform(this))
, m_font(new Font(this))
, m_transparency(new Transparency(this)) {}
};
} // namespace ZShell::config
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include "configobject.hpp"
#include <qqmlintegration.h>
namespace ZShell::config {
class Background : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(bool, enabled, true)
CFG_PROPERTY(int, wallFadeDuration, 300)
public:
explicit Background(QObject* parent = nullptr) : ConfigObject(parent) {}
};
} // namespace ZShell::config
+94
View File
@@ -0,0 +1,94 @@
#pragma once
#include "configlist.hpp"
#include "configobject.hpp"
#include <qqmlregistration.h>
namespace ZShell::config {
class BarEntry : public ListEntry {
Q_OBJECT
QML_ANONYMOUS
public:
explicit BarEntry(QObject* parent = nullptr) : ListEntry(parent) {}
};
class Popouts : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(bool, statusIcons, true)
CFG_PROPERTY(bool, tray, true)
public:
explicit Popouts(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class Tray : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(bool, recolorIcons, false)
CFG_PROPERTY(bool, showOnHover, true)
CFG_PROPERTY(int, trayIconSize, 24)
CONFIG_LIST(
EntryList,
statusIcons,
{
LIST_ENTRY(audio, true),
LIST_ENTRY(microphone, true),
LIST_ENTRY(bluetooth, false),
LIST_ENTRY(network, false),
LIST_ENTRY(wifi, false),
LIST_ENTRY(power, true),
})
public:
explicit Tray(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class Bar : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(bool, autoHide, false)
CFG_PROPERTY(int, border, 4)
CFG_PROPERTY(bool, fullscreenReveal, true)
CFG_PROPERTY(int, height, 24)
CFG_PROPERTY(bool, hideWhenNotif, true)
CONFIG_SUBOBJECT(Popouts, popouts)
CFG_PROPERTY(int, revealDelay, 100)
CFG_PROPERTY(int, rounding, 14)
CFG_PROPERTY(int, smoothing, 32)
CONFIG_SUBOBJECT(Tray, tray)
CONFIG_LIST(
EntryList,
entries,
{
LIST_ENTRY(workspaces, true),
LIST_ENTRY(audio, true),
LIST_ENTRY(media, true),
LIST_ENTRY(resources, true),
LIST_ENTRY(updates, true),
LIST_ENTRY(dash, false),
LIST_ENTRY(spacer, true),
LIST_ENTRY(activeWindow, true),
LIST_ENTRY(spacer, true),
LIST_ENTRY(hyprsunset, true),
LIST_ENTRY(tray, true),
LIST_ENTRY(statusIcons, true),
LIST_ENTRY(network, false),
LIST_ENTRY(upower, true),
LIST_ENTRY(clock, true),
LIST_ENTRY(notifBell, true),
})
public:
explicit Bar(QObject* parent = nullptr)
: ConfigObject(parent)
, m_popouts(new Popouts(this))
, m_tray(new Tray(this)) {}
};
} // namespace ZShell::config
+33
View File
@@ -0,0 +1,33 @@
#pragma once
#include "configobject.hpp"
#include <qqmlintegration.h>
namespace ZShell::config {
class ClipboardSizes : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(int, itemHeight, 60)
CFG_PROPERTY(int, minPreviewWidth, 200)
CFG_PROPERTY(int, previewWidth, 800)
CFG_PROPERTY(int, width, 500)
public:
explicit ClipboardSizes(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class Clipboard : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(bool, enabled, true)
CFG_PROPERTY(int, maxEntriesShown, 10)
CONFIG_SUBOBJECT(ClipboardSizes, sizes)
public:
explicit Clipboard(QObject* parent = nullptr)
: ConfigObject(parent), m_sizes(new ClipboardSizes(this)) {}
};
} // namespace ZShell::config
+31
View File
@@ -0,0 +1,31 @@
#pragma once
#include "configobject.hpp"
#include <qqmlintegration.h>
namespace ZShell::config {
class Presets : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(QString, accent, QString())
CFG_PROPERTY(QString, name, QStringLiteral("Catppuccin"))
CFG_PROPERTY(QString, variant, QStringLiteral("latte"))
public:
explicit Presets(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class Colors : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CONFIG_SUBOBJECT(Presets, presets)
CFG_PROPERTY(QString, schemeType, QStringLiteral("fidelity"))
public:
explicit Colors(QObject* parent = nullptr)
: ConfigObject(parent), m_presets(new Presets(this)) {}
};
} // namespace ZShell::config
@@ -1,4 +1,21 @@
#include "Config.hpp"
#include "config.hpp"
#include "appearance.hpp"
#include "background.hpp"
#include "bar.hpp"
#include "clipboard.hpp"
#include "colors.hpp"
#include "dashboard.hpp"
#include "dock.hpp"
#include "general.hpp"
#include "launcher.hpp"
#include "lock.hpp"
#include "notifs.hpp"
#include "osd.hpp"
#include "screenshot.hpp"
#include "services.hpp"
#include "sidebar.hpp"
#include "utilities.hpp"
#include <QFile>
#include <QSaveFile>
@@ -8,31 +25,30 @@
#include <QDebug>
#include <QFutureWatcher>
Config::Config(QObject* parent) : ConfigSection(parent) {
m_appearance = new Appearance(this);
m_background = new Background(this);
m_bar = new Bar(this);
m_clipboard = new Clipboard(this);
m_colors = new Colors(this);
m_dashboard = new Dashboard(this);
m_dock = new Dock(this);
m_general = new General(this);
m_launcher = new Launcher(this);
m_lock = new Lock(this);
m_notifs = new Notifs(this);
m_osd = new Osd(this);
m_overview = new Overview(this);
m_screenshot = new Screenshot(this);
m_services = new Services(this);
m_sidebar = new Sidebar(this);
m_utilities = new Utilities(this);
wireSignals(); // forwards every child's changed() up to our own changed()
namespace ZShell::config {
connect(this, &ConfigSection::changed, this, &Config::scheduleSave);
Config::Config(QObject* parent)
: ConfigObject(parent)
, m_appearance(new Appearance(this))
, m_background(new Background(this))
, m_bar(new Bar(this))
, m_clipboard(new Clipboard(this))
, m_colors(new Colors(this))
, m_dashboard(new Dashboard(this))
, m_dock(new Dock(this))
, m_general(new General(this))
, m_launcher(new Launcher(this))
, m_lock(new Lock(this))
, m_notifs(new Notifs(this))
, m_osd(new Osd(this))
, m_screenshot(new Screenshot(this))
, m_services(new Services(this))
, m_sidebar(new Sidebar(this))
, m_utilities(new Utilities(this)) {
connect(this, &ConfigObject::propertiesChanged, this, &Config::scheduleSave);
m_saveTimer.setSingleShot(true);
m_saveTimer.setInterval(
300); // debounce: coalesce rapid-fire edits (e.g. dragging a slider)
m_saveTimer.setInterval(300);
connect(&m_saveTimer, &QTimer::timeout, this, &Config::flushAsync);
loadSync();
@@ -40,7 +56,6 @@ Config::Config(QObject* parent) : ConfigSection(parent) {
}
Config* Config::create(QQmlEngine*, QJSEngine*) {
// The QML engine takes ownership of singletons created this way.
return new Config();
}
@@ -53,12 +68,11 @@ QString Config::filePath() const {
}
void Config::loadSync() {
m_loading =
true; // suppress scheduleSave() while properties are set from disk
m_loading = true;
QFile f(filePath());
if (f.open(QIODevice::ReadOnly)) {
const auto doc = QJsonDocument::fromJson(f.readAll());
if (doc.isObject()) fromJson(doc.object());
if (doc.isObject()) loadFromJson(QJsonValue(doc.object()));
} else {
qInfo() << "Config: no existing config at" << filePath()
<< "- using defaults";
@@ -73,21 +87,24 @@ void Config::loadAsync() {
if (f.open(QIODevice::ReadOnly)) {
const auto doc = QJsonDocument::fromJson(f.readAll());
if (doc.isObject()) {
QMetaObject::invokeMethod(this, [this, doc]() {
fromJson(doc.object());
m_loading = false;
}, Qt::QueuedConnection);
QMetaObject::invokeMethod(
this,
[this, doc]() {
loadFromJson(QJsonValue(doc.object()));
m_loading = false;
},
Qt::QueuedConnection);
} else {
QMetaObject::invokeMethod(this, [this]() {
m_loading = false;
}, Qt::QueuedConnection);
QMetaObject::invokeMethod(
this,
[this]() { m_loading = false; },
Qt::QueuedConnection);
}
} else {
qInfo() << "Config: failed to reload from" << filePath()
<< "- using in-memory values";
QMetaObject::invokeMethod(this, [this]() {
m_loading = false;
}, Qt::QueuedConnection);
QMetaObject::invokeMethod(
this, [this]() { m_loading = false; }, Qt::QueuedConnection);
}
});
m_loadFuture = future;
@@ -107,12 +124,13 @@ void Config::reloadAsync() {
void Config::scheduleSave() {
if (m_loading) return;
m_saveTimer.start(); // restarts the window if it's already running
m_saveTimer.start();
}
void Config::flushAsync() {
auto future = QtConcurrent::run([this]() {
const QByteArray data = QJsonDocument(toJson()).toJson(QJsonDocument::Indented);
const QByteArray data =
QJsonDocument(toJson().toObject()).toJson(QJsonDocument::Indented);
writeAtomically(data);
});
}
@@ -123,9 +141,6 @@ void Config::saveNow() {
}
void Config::writeAtomically(const QByteArray& data) {
// QSaveFile writes to a temp file next to the target and atomically
// renames it into place on commit() - a crash or power loss mid-write
// can never leave config.json half-written.
QSaveFile f(filePath());
if (!f.open(QIODevice::WriteOnly)) {
qWarning() << "Config: failed to open for atomic write:"
@@ -135,3 +150,5 @@ void Config::writeAtomically(const QByteArray& data) {
f.write(data);
if (!f.commit()) qWarning() << "Config: commit failed:" << f.errorString();
}
}; // namespace ZShell::config
+95
View File
@@ -0,0 +1,95 @@
#pragma once
#include "configobject.hpp"
#include <qqmlregistration.h>
#include <QTimer>
#include <QtConcurrent/QtConcurrent>
#include <QFuture>
#include <qtmetamacros.h>
class QQmlEngine;
class QJSEngine;
namespace ZShell::config {
class Appearance;
class Background;
class Bar;
class Clipboard;
class Colors;
class Dashboard;
class Dock;
class General;
class Launcher;
class Lock;
class Notifs;
class Osd;
class Screenshot;
class Services;
class Sidebar;
class Utilities;
class Config : public ConfigObject {
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
Q_MOC_INCLUDE("appearance.hpp")
Q_MOC_INCLUDE("background.hpp")
Q_MOC_INCLUDE("bar.hpp")
Q_MOC_INCLUDE("clipboard.hpp")
Q_MOC_INCLUDE("colors.hpp")
Q_MOC_INCLUDE("dashboard.hpp")
Q_MOC_INCLUDE("dock.hpp")
Q_MOC_INCLUDE("general.hpp")
Q_MOC_INCLUDE("launcher.hpp")
Q_MOC_INCLUDE("lock.hpp")
Q_MOC_INCLUDE("notifs.hpp")
Q_MOC_INCLUDE("osd.hpp")
Q_MOC_INCLUDE("screenshot.hpp")
Q_MOC_INCLUDE("services.hpp")
Q_MOC_INCLUDE("sidebar.hpp")
Q_MOC_INCLUDE("utilities.hpp")
CONFIG_SUBOBJECT(Appearance, appearance)
CONFIG_SUBOBJECT(Background, background)
CONFIG_SUBOBJECT(Bar, bar)
CONFIG_SUBOBJECT(Clipboard, clipboard)
CONFIG_SUBOBJECT(Colors, colors)
CONFIG_SUBOBJECT(Dashboard, dashboard)
CONFIG_SUBOBJECT(Dock, dock)
CONFIG_SUBOBJECT(General, general)
CONFIG_SUBOBJECT(Launcher, launcher)
CONFIG_SUBOBJECT(Lock, lock)
CONFIG_SUBOBJECT(Notifs, notifs)
CONFIG_SUBOBJECT(Osd, osd)
CONFIG_SUBOBJECT(Screenshot, screenshot)
CONFIG_SUBOBJECT(Services, services)
CONFIG_SUBOBJECT(Sidebar, sidebar)
CONFIG_SUBOBJECT(Utilities, utilities)
public:
explicit Config(QObject* parent = nullptr);
static Config* create(QQmlEngine*, QJSEngine*);
Q_INVOKABLE void load();
Q_INVOKABLE void saveNow();
Q_INVOKABLE void reloadAsync();
private Q_SLOTS:
void scheduleSave();
void flushAsync();
private:
QString filePath() const;
void writeAtomically(const QByteArray& data);
void loadSync();
void loadAsync();
QTimer m_saveTimer;
bool m_loading = false;
bool m_firstLoadDone = false;
QFuture<void> m_loadFuture;
};
} // namespace ZShell::config
+305
View File
@@ -0,0 +1,305 @@
#include "configlist.hpp"
#include <QJsonObject>
#include <QMetaObject>
#include <QQmlEngine>
#include <QString>
namespace ZShell::config {
ConfigList::ConfigList(QObject* parent, const QVariantList& defaults)
: ConfigNode(parent), m_defaults(QJsonArray::fromVariantList(defaults)) {}
int ConfigList::count() const {
return static_cast<int>(m_items.size());
}
QVariantList ConfigList::values() const {
QVariantList vals;
vals.reserve(m_items.size());
for (auto* const item : m_items)
vals.append(QVariant::fromValue(item));
return vals;
}
ConfigObject* ConfigList::itemAt(int index) const {
if (index < 0 || index >= m_items.size()) return nullptr;
return m_items.at(index);
}
const QList<ConfigObject*>& ConfigList::items() const {
return m_items;
}
void ConfigList::remove(int index) {
if (index < 0 || index >= m_items.size()) {
qCWarning(lcConfig)
<< metaObject()->className() << "cannot remove index" << index
<< "of" << count();
return;
}
destroyItem(m_items.takeAt(index));
m_loaded = true;
emit countChanged();
emit valuesChanged();
notifyChanged();
}
void ConfigList::move(int from, int to) {
if (from < 0 || from >= m_items.size() || to < 0 || to >= m_items.size()) {
qCWarning(lcConfig) << metaObject()->className() << "cannot move"
<< from << "to" << to << "of" << count();
return;
}
if (from == to) return;
m_items.move(from, to);
m_loaded = true;
emit valuesChanged();
notifyChanged();
}
void ConfigList::clear() {
if (m_items.isEmpty()) return;
destroyItems();
m_loaded = true;
emit countChanged();
emit valuesChanged();
notifyChanged();
}
void ConfigList::loadFromJson(const QJsonValue& json) {
if (!json.isArray()) {
qCWarning(
lcConfig,
"Option '%s' must be a list, ignoring",
qUtf8Printable(propertyPath()));
m_rejectedJson = json;
return;
}
m_rejectedJson = QJsonValue::Undefined;
populate(json.toArray());
m_loaded = true;
}
QJsonValue ConfigList::toJson() const {
if (m_loaded) return elementsToJson();
return m_rejectedJson;
}
void ConfigList::clearLoadedKeys() {
m_loaded = false;
m_rejectedJson = QJsonValue::Undefined;
}
QStringList ConfigList::unknownKeys() const {
QStringList keys;
for (int i = 0; i < m_items.size(); ++i) {
const auto childKeys = m_items.at(i)->unknownKeys();
for (const auto& childKey : childKeys)
keys.append(joinPath(QString("[%1]").arg(i), childKey));
}
return keys;
}
void ConfigList::resyncFromGlobal() {
syncValuesFromGlobal();
}
ConfigObject* ConfigList::insertItem(const QVariantMap& props, int index) {
const auto pos = index < 0 || index > m_items.size() ? m_items.size()
: index;
appendItem(QJsonObject::fromVariantMap(props));
m_items.move(m_items.size() - 1, pos);
auto* const item = m_items.at(pos);
const auto unknown = item->unknownKeys();
for (const auto& key : unknown)
qCWarning(lcConfig) << "Unknown option" << key << "for"
<< item->metaObject()->className();
m_loaded = true;
emit countChanged();
emit valuesChanged();
notifyChanged();
return item;
}
QJsonArray ConfigList::elementsToJson() const {
QJsonArray arr;
for (auto* const item : m_items)
arr.append(item->toJson().toObject());
return arr;
}
void ConfigList::resetToDefaults() {
loadFromJsonQuietly(m_defaults);
m_loaded = false;
}
void ConfigList::syncValuesFromGlobal() {
if (m_loaded) return;
if (auto* const global = qobject_cast<ConfigList*>(m_global))
populate(global->elementsToJson());
}
void ConfigList::onGlobalPropertiesChanged(const QMap<QString, QVariant>&) {
syncValuesFromGlobal();
}
QString ConfigList::childPath(const ConfigNode* child) const {
for (int i = 0; i < m_items.size(); ++i)
if (m_items.at(i) == child) return QString("[%1]").arg(i);
return {};
}
void ConfigList::populate(const QJsonArray& arr) {
const auto current = elementsToJson();
if (current == arr) return;
const auto old = m_items;
QList<bool> reused(old.size(), false);
m_items.clear();
m_items.reserve(arr.size());
for (int i = 0; i < arr.size(); ++i) {
auto match =
i < old.size() && !reused.at(i) && current.at(i) == arr.at(i) ? i
: -1;
for (int j = 0; match < 0 && j < old.size(); ++j)
if (!reused.at(j) && current.at(j) == arr.at(i)) match = j;
auto update = false;
for (int j = 0; match < 0 && j < old.size(); ++j) {
if (!reused.at(j) &&
sameElement(old.at(j), current.at(j), arr.at(i))) {
match = j;
update = true;
}
}
if (match < 0) {
appendItem(arr.at(i));
continue;
}
reused[match] = true;
if (update) old.at(match)->loadFromJsonQuietly(arr.at(i));
m_items.append(old.at(match));
}
for (int i = 0; i < old.size(); ++i)
if (!reused.at(i)) destroyItem(old.at(i));
if (m_items.size() != old.size()) emit countChanged();
emit valuesChanged();
notifyChanged();
}
bool ConfigList::sameElement(
const ConfigObject* item,
const QJsonValue& current,
const QJsonValue& json) {
const auto keys = item->identityKeys();
if (keys.isEmpty()) return false;
const auto currentObj = current.toObject();
const auto newObj = json.toObject();
if (currentObj.keys() != newObj.keys()) return false;
for (const auto& key : keys)
if (!newObj.contains(key) || currentObj.value(key) != newObj.value(key))
return false;
return true;
}
void ConfigList::appendItem(const QJsonValue& json) {
auto* const item = createItem();
QQmlEngine::setObjectOwnership(item, QQmlEngine::CppOwnership);
if (m_items.isEmpty()) rejectGlobalOnlyElement(item);
item->loadFromJsonQuietly(json);
connectItem(item);
m_items.append(item);
}
void ConfigList::rejectGlobalOnlyElement(const ConfigObject* item) const {
const auto keys = item->globalOnlyKeys();
if (keys.isEmpty()) return;
qCCritical(
lcConfig,
"%s declares global-only options (%s) which do not work inside a list, "
"use CONFIG_GLOBAL_LIST on %s instead",
item->metaObject()->className(),
qUtf8Printable(keys.join(", ")),
metaObject()->className());
}
void ConfigList::connectItem(ConfigNode* node) {
connect(
node, &ConfigNode::propertiesChanged, this, &ConfigList::onItemChanged);
const auto children = node->childNodes();
for (auto* const child : children)
connectItem(child);
}
void ConfigList::disconnectItem(ConfigNode* node) {
node->disconnect(this);
const auto children = node->childNodes();
for (auto* const child : children)
disconnectItem(child);
}
void ConfigList::destroyItems() {
for (auto* const item : std::as_const(m_items))
destroyItem(item);
m_items.clear();
}
void ConfigList::destroyItem(ConfigObject* item) {
disconnectItem(item);
item->deleteLater();
}
void ConfigList::onItemChanged() {
m_loaded = true;
notifyChanged();
}
void ConfigList::notifyChanged() {
notifyPropertyChanged("values", count());
}
} // namespace ZShell::config
+141
View File
@@ -0,0 +1,141 @@
#pragma once
#include "configobject.hpp"
#include <QJsonArray>
#include <QJsonObject>
#include <QQmlEngine>
#include <QVariantList>
namespace ZShell::config {
class ConfigList : public ConfigNode {
Q_OBJECT
QML_ANONYMOUS
Q_PROPERTY(int count READ count NOTIFY countChanged)
Q_PROPERTY(QVariantList values READ values NOTIFY valuesChanged)
public:
explicit ConfigList(
QObject* parent = nullptr, const QVariantList& defaults = {});
[[nodiscard]] int count() const;
[[nodiscard]] QVariantList values() const;
[[nodiscard]] ConfigObject* itemAt(int index) const;
[[nodiscard]] const QList<ConfigObject*>& items() const;
Q_INVOKABLE void remove(int index);
Q_INVOKABLE void move(int from, int to);
Q_INVOKABLE void clear();
void loadFromJson(const QJsonValue& json) override;
[[nodiscard]] QJsonValue toJson() const override;
void clearLoadedKeys() override;
[[nodiscard]] QStringList unknownKeys() const override;
void resyncFromGlobal() override;
signals:
void countChanged();
void valuesChanged();
protected:
virtual ConfigObject* createItem() = 0;
void resetToDefaults();
ConfigObject* insertItem(const QVariantMap& props, int index = -1);
[[nodiscard]] QJsonArray elementsToJson() const;
void syncValuesFromGlobal() override;
void onGlobalPropertiesChanged(
const QMap<QString, QVariant>& changed) override;
[[nodiscard]] QString childPath(const ConfigNode* child) const override;
private:
void populate(const QJsonArray& arr);
static bool sameElement(
const ConfigObject* item,
const QJsonValue& current,
const QJsonValue& json);
void appendItem(const QJsonValue& json);
void destroyItems();
void destroyItem(ConfigObject* item);
void rejectGlobalOnlyElement(const ConfigObject* item) const;
void connectItem(ConfigNode* node);
void disconnectItem(ConfigNode* node);
void onItemChanged();
void notifyChanged();
QJsonArray m_defaults;
QList<ConfigObject*> m_items;
bool m_loaded = false;
QJsonValue m_rejectedJson = QJsonValue::Undefined;
};
} // namespace ZShell::config
#define CONFIG_LIST_TYPE(Element, Name) \
class Name : public ZShell::config::ConfigList { \
Q_OBJECT \
QML_ANONYMOUS \
\
public: \
explicit Name( \
QObject* parent = nullptr, const QVariantList& defaults = {}) \
: ZShell::config::ConfigList(parent, defaults) { \
resetToDefaults(); \
} \
\
Q_INVOKABLE ZShell::config::Element* at(int index) const { \
return static_cast<ZShell::config::Element*>(itemAt(index)); \
} \
Q_INVOKABLE ZShell::config::Element* insert( \
const QVariantMap& props, int index = -1) { \
return static_cast<ZShell::config::Element*>( \
insertItem(props, index)); \
} \
\
protected: \
[[nodiscard]] ZShell::config::ConfigObject* createItem() override { \
return new ZShell::config::Element(this); \
} \
};
#define CONFIG_LIST(Type, name, ...) \
Q_PROPERTY(ZShell::config::Type* name READ name CONSTANT) \
\
public: \
[[nodiscard]] Type* name() const { \
return m_##name; \
} \
\
private: \
Type* m_##name = new Type(this __VA_OPT__(, __VA_ARGS__));
namespace ZShell::config {
class ListEntry : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(QString, id)
CFG_PROPERTY(bool, enabled, true)
public:
explicit ListEntry(QObject* parent = nullptr) : ConfigObject(parent) {}
[[nodiscard]] QStringList identityKeys() const override {
return {QStringLiteral("id")};
}
};
CONFIG_LIST_TYPE(ListEntry, EntryList)
} // namespace ZShell::config
#define LIST_ENTRY(id, enabled) \
vmap({{"id", QString::fromUtf8(#id)}, {"enabled", enabled}})
+89
View File
@@ -0,0 +1,89 @@
#include "confignode.hpp"
#include <qjsonvalue.h>
#include <qloggingcategory.h>
#include <qmetaobject.h>
#include <qstring.h>
namespace ZShell::config {
Q_LOGGING_CATEGORY(lcConfig, "zshell.config")
ConfigNode::ConfigNode(QObject* parent) : QObject(parent) {
m_batchTimer = new QTimer(this);
m_batchTimer->setSingleShot(true);
m_batchTimer->setInterval(0);
connect(
m_batchTimer, &QTimer::timeout, this, &ConfigNode::emitBatchedChanges);
}
void ConfigNode::loadFromJsonQuietly(const QJsonValue& json) {
setNotifySuppressed(true);
loadFromJson(json);
setNotifySuppressed(false);
}
void ConfigNode::setNotifySuppressed(bool suppressed) {
m_suppressNotify = suppressed;
const auto children = childNodes();
for (auto* const child : children)
child->setNotifySuppressed(suppressed);
}
QList<ConfigNode*> ConfigNode::childNodes() const {
return {};
}
void ConfigNode::syncFromGlobal(ConfigNode* global) {
m_global = global;
resyncFromGlobal();
}
bool ConfigNode::isOverlay() const {
return m_global != nullptr && this != m_global;
}
QString ConfigNode::propertyPath(const QString& name) const {
if (name.isEmpty()) return objectName();
QObject* const parentObj = parent();
if (parentObj) {
if (auto* parentNode = qobject_cast<ConfigNode*>(parentObj)) {
const auto childName = parentNode->childPath(this);
if (!childName.isEmpty()) {
return joinPath(parentNode->propertyPath(childName), name);
}
}
}
return name;
}
int ConfigNode::basePropertyOffset() {
return QObject::staticMetaObject.propertyCount();
}
void ConfigNode::notifyPropertyChanged(
const QString& name, const QVariant& value) {
if (m_suppressNotify) return;
m_pendingChanges[name] = value;
if (m_batchTimer && !m_batchTimer->isActive()) m_batchTimer->start();
}
QString ConfigNode::joinPath(const QString& parent, const QString& child) {
// List elements are addressed as parent[i], everything else as parent.child
if (child.startsWith(QLatin1Char('['))) return parent + child;
return parent + QLatin1Char('.') + child;
}
void ConfigNode::emitBatchedChanges() {
if (m_pendingChanges.isEmpty()) return;
QMap<QString, QVariant> changes = m_pendingChanges;
m_pendingChanges.clear();
emit propertiesChanged(changes);
}
} // namespace ZShell::config
+63
View File
@@ -0,0 +1,63 @@
#pragma once
#include <QJsonValue>
#include <QLoggingCategory>
#include <QMap>
#include <QObject>
#include <QStringList>
#include <QTimer>
#include <QVariant>
namespace ZShell::config {
Q_DECLARE_LOGGING_CATEGORY(lcConfig)
class ConfigNode : public QObject {
Q_OBJECT
public:
explicit ConfigNode(QObject* parent = nullptr);
virtual void loadFromJson(const QJsonValue& json) = 0;
void loadFromJsonQuietly(const QJsonValue& json);
[[nodiscard]] virtual QJsonValue toJson() const = 0;
virtual void clearLoadedKeys() = 0;
[[nodiscard]] virtual QStringList unknownKeys() const = 0;
[[nodiscard]] virtual QList<ConfigNode*> childNodes() const;
void syncFromGlobal(ConfigNode* global);
virtual void resyncFromGlobal() = 0;
[[nodiscard]] bool isOverlay() const;
[[nodiscard]] QString propertyPath(const QString& name = {}) const;
[[nodiscard]] static int basePropertyOffset();
signals:
void propertiesChanged(const QMap<QString, QVariant>& changed);
protected:
virtual void syncValuesFromGlobal() = 0;
virtual void onGlobalPropertiesChanged(
const QMap<QString, QVariant>& changed) = 0;
[[nodiscard]] virtual QString childPath(const ConfigNode* child) const = 0;
void notifyPropertyChanged(const QString& name, const QVariant& value);
[[nodiscard]] static QString joinPath(
const QString& parent, const QString& child);
ConfigNode* m_global = nullptr;
private:
void setNotifySuppressed(bool suppressed);
void emitBatchedChanges();
QMap<QString, QVariant> m_pendingChanges;
QTimer* m_batchTimer = nullptr;
bool m_suppressNotify = false;
};
} // namespace ZShell::config
+270
View File
@@ -0,0 +1,270 @@
#include "configobject.hpp"
#include <QJsonArray>
#include <QMetaObject>
#include <QStringList>
#include <QVariant>
namespace ZShell::config {
ConfigObject::ConfigObject(QObject* parent) : ConfigNode(parent) {}
void ConfigObject::loadFromJson(const QJsonValue& json) {
const auto obj = json.toObject();
const auto* meta = metaObject();
QSet<QString> known;
for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) {
auto prop = meta->property(i);
const auto key = QString::fromUtf8(prop.name());
known.insert(key);
if (!obj.contains(key)) continue;
const auto jsonVal = obj.value(key);
if (prop.metaType().flags().testFlag(QMetaType::PointerToQObject)) {
if (auto* const node = prop.read(this).value<ConfigNode*>()) {
node->loadFromJson(jsonVal);
continue;
}
}
if (!prop.isWritable()) continue;
if (prop.metaType().id() == QMetaType::QStringList) {
QStringList list;
const auto jsonArr = jsonVal.toArray();
for (const auto& v : jsonArr)
list.append(v.toString());
prop.write(this, QVariant::fromValue(list));
m_loadedKeys.insert(key);
continue;
}
if (prop.metaType().id() == QMetaType::QVariantList) {
prop.write(this, jsonVal.toVariant());
m_loadedKeys.insert(key);
continue;
}
prop.write(this, jsonVal.toVariant());
m_loadedKeys.insert(key);
}
m_extras = {};
for (auto it = obj.begin(); it != obj.end(); ++it) {
if (!known.contains(it.key())) {
m_extras.insert(it.key(), it.value());
}
}
}
QJsonValue ConfigObject::toJson() const {
QJsonObject obj;
const auto* meta = metaObject();
for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) {
const auto prop = meta->property(i);
if (!prop.isReadable()) continue;
const auto key = QString::fromUtf8(prop.name());
const auto value = prop.read(this);
if (prop.metaType().flags().testFlag(QMetaType::PointerToQObject)) {
if (auto* const node = value.value<ConfigNode*>()) {
const auto childJson = node->toJson();
if (!childJson.isUndefined()) obj.insert(key, childJson);
continue;
}
}
if (!m_loadedKeys.contains(key)) continue;
if (!prop.isWritable()) continue;
if (prop.metaType().id() == QMetaType::QStringList) {
QJsonArray arr;
const auto strList = value.toStringList();
for (const auto& s : strList)
arr.append(s);
obj.insert(key, arr);
continue;
}
if (prop.metaType().id() == QMetaType::QVariantList) {
obj.insert(key, QJsonArray::fromVariantList(value.toList()));
continue;
}
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;
}
void ConfigObject::clearLoadedKeys() {
m_loadedKeys.clear();
m_extras = {};
const auto* meta = metaObject();
for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) {
auto prop = meta->property(i);
if (auto* const node = prop.read(this).value<ConfigNode*>())
node->clearLoadedKeys();
}
}
QStringList ConfigObject::identityKeys() const {
return {};
}
QStringList ConfigObject::unknownKeys() const {
auto keys = m_extras.keys();
const auto* meta = metaObject();
for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) {
const auto prop = meta->property(i);
auto* const node = prop.read(this).value<ConfigNode*>();
if (!node) continue;
const auto childKeys = node->unknownKeys();
for (const auto& childKey : childKeys)
keys.append(joinPath(QString::fromUtf8(prop.name()), childKey));
}
return keys;
}
QList<ConfigNode*> ConfigObject::childNodes() const {
QList<ConfigNode*> nodes;
const auto* meta = metaObject();
for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) {
const auto prop = meta->property(i);
if (auto* const node = prop.read(this).value<ConfigNode*>())
nodes.append(node);
}
return nodes;
}
void ConfigObject::syncValuesFromGlobal() {
const auto* meta = metaObject();
for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) {
auto prop = meta->property(i);
const auto key = QString::fromUtf8(prop.name());
if (auto* const node = prop.read(this).value<ConfigNode*>()) {
if (auto* const globalNode =
prop.read(m_global).value<ConfigNode*>())
node->syncFromGlobal(globalNode);
continue;
}
if (!prop.isWritable()) continue;
if (!m_loadedKeys.contains(key)) {
auto val = prop.read(m_global);
prop.write(this, val);
m_loadedKeys.remove(key);
}
}
}
void ConfigObject::resyncFromGlobal() {
if (!m_global) return;
const auto* meta = metaObject();
for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) {
auto prop = meta->property(i);
const auto key = QString::fromUtf8(prop.name());
if (auto* const node = prop.read(this).value<ConfigNode*>()) {
node->resyncFromGlobal();
continue;
}
if (!prop.isWritable()) continue;
if (!m_loadedKeys.contains(key)) {
prop.write(this, prop.read(m_global));
m_loadedKeys.remove(key);
}
}
}
bool ConfigObject::isPropertyLoaded(const QString& name) const {
return m_loadedKeys.contains(name);
}
bool ConfigObject::isGlobalOnly(const QString& name) const {
return m_globalOnlyKeys.contains(name);
}
QStringList ConfigObject::globalOnlyKeys() const {
return {m_globalOnlyKeys.begin(), m_globalOnlyKeys.end()};
}
void ConfigObject::resetOption(const QString& name) {
m_loadedKeys.remove(name);
const int idx = metaObject()->indexOfProperty(name.toUtf8().constData());
if (idx < 0) return;
const auto prop = metaObject()->property(idx);
if (auto* const node = prop.read(this).value<ConfigNode*>()) {
node->clearLoadedKeys();
node->resyncFromGlobal();
return;
}
if (m_global && prop.isWritable()) prop.write(this, prop.read(m_global));
}
void ConfigObject::onGlobalPropertiesChanged(
const QMap<QString, QVariant>& changed) {
for (auto it = changed.begin(); it != changed.end(); ++it) {
if (m_loadedKeys.contains(it.key()) || isGlobalOnly(it.key())) continue;
int idx = metaObject()->indexOfProperty(it.key().toUtf8().constData());
if (idx >= 0) {
metaObject()->property(idx).write(this, it.value());
m_loadedKeys.remove(it.key());
}
}
}
QString ConfigObject::childPath(const ConfigNode* child) const {
const auto* meta = metaObject();
for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) {
const auto prop = meta->property(i);
if (prop.read(this).value<ConfigNode*>() == child)
return QString::fromUtf8(prop.name());
}
return {};
}
void ConfigObject::markPropertyLoaded(const QString& name) {
m_loadedKeys.insert(name);
}
void ConfigObject::markGlobalOnly(const QString& name) {
m_globalOnlyKeys.insert(name);
}
} // namespace ZShell::config
+100
View File
@@ -0,0 +1,100 @@
#pragma once
#include "confignode.hpp"
#include <QJsonObject>
#include <QMetaProperty>
#include <QMetaType>
#include <QObject>
#include <QSet>
#include <QStringList>
#include <QVariant>
#include <QVariantList>
namespace ZShell::config {
inline QVariantMap vmap(
std::initializer_list<std::pair<QString, QVariant>> entries) {
QVariantMap map;
for (const auto& [key, value] : entries)
map.insert(key, value);
return map;
}
#define CFG_PROPERTY(Type, name, ...) \
Q_PROPERTY(Type name READ name WRITE set_##name NOTIFY name##Changed) \
public: \
[[nodiscard]] Type name() const { \
return m_##name; \
} \
void set_##name(const Type& value) { \
if (ConfigObject::updateMember(m_##name, value)) { \
markPropertyLoaded(QStringLiteral(#name)); \
Q_EMIT name##Changed(); \
notifyPropertyChanged( \
QStringLiteral(#name), QVariant::fromValue(m_##name)); \
} \
} \
Q_SIGNAL void name##Changed(); \
\
private: \
Type m_##name __VA_OPT__(= __VA_ARGS__);
#define CONFIG_SUBOBJECT(Type, name) \
Q_PROPERTY(ZShell::config::Type* name READ name CONSTANT) \
\
public: \
[[nodiscard]] Type* name() const { \
return m_##name; \
} \
\
private: \
Type* m_##name = nullptr;
class ConfigObject : public ConfigNode {
Q_OBJECT
public:
explicit ConfigObject(QObject* parent = nullptr);
void loadFromJson(const QJsonValue& json) override;
[[nodiscard]] QJsonValue toJson() const override;
void clearLoadedKeys() override;
[[nodiscard]] QStringList unknownKeys() const override;
[[nodiscard]] QList<ConfigNode*> childNodes() const override;
void resyncFromGlobal() override;
[[nodiscard]] virtual QStringList identityKeys() const;
[[nodiscard]] bool isPropertyLoaded(const QString& name) const;
[[nodiscard]] bool isGlobalOnly(const QString& name) const;
[[nodiscard]] QStringList globalOnlyKeys() const;
Q_INVOKABLE void resetOption(const QString& name);
template <typename T> static bool updateMember(T& member, const T& value) {
if constexpr (std::is_floating_point_v<T>) {
if (qFuzzyCompare(member + 1.0, value + 1.0)) return false;
} else {
if (member == value) return false;
}
member = value;
return true;
}
protected:
void syncValuesFromGlobal() override;
void onGlobalPropertiesChanged(
const QMap<QString, QVariant>& changed) override;
[[nodiscard]] QString childPath(const ConfigNode* child) const override;
void markPropertyLoaded(const QString& name);
void markGlobalOnly(const QString& name);
private:
QSet<QString> m_loadedKeys;
QSet<QString> m_globalOnlyKeys;
QJsonObject m_extras;
};
} // namespace ZShell::config
+63
View File
@@ -0,0 +1,63 @@
#pragma once
#include "configobject.hpp"
#include <qqmlintegration.h>
namespace ZShell::config {
class Performance : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(bool, enabled, true)
CFG_PROPERTY(bool, showBattery, false)
CFG_PROPERTY(bool, showCpu, true)
CFG_PROPERTY(bool, showGpu, true)
CFG_PROPERTY(bool, showMemory, true)
CFG_PROPERTY(bool, showNetwork, true)
CFG_PROPERTY(bool, showStorage, true)
CFG_PROPERTY(bool, showVram, true)
public:
explicit Performance(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class DashboardSizes : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(int, dateTimeWidth, 110)
CFG_PROPERTY(int, infoIconSize, 25)
CFG_PROPERTY(int, infoWidth, 200)
CFG_PROPERTY(int, mediaCoverArtSize, 150)
CFG_PROPERTY(int, mediaProgressSweep, 180)
CFG_PROPERTY(int, mediaProgressThickness, 8)
CFG_PROPERTY(int, mediaVisualizerSize, 200)
CFG_PROPERTY(int, mediaWidth, 200)
CFG_PROPERTY(int, resourceProgessThickness, 10)
CFG_PROPERTY(int, resourceSize, 200)
CFG_PROPERTY(int, tabIndicatorHeight, 3)
CFG_PROPERTY(int, tabIndicatorSpacing, 5)
CFG_PROPERTY(int, weatherWidth, 250)
public:
explicit DashboardSizes(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class Dashboard : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(bool, enabled, true)
CFG_PROPERTY(int, mediaUpdateInterval, 2000)
CONFIG_SUBOBJECT(Performance, performance)
CFG_PROPERTY(int, resourceUpdateInterval, 1000)
CONFIG_SUBOBJECT(DashboardSizes, sizes)
public:
explicit Dashboard(QObject* parent = nullptr)
: ConfigObject(parent)
, m_performance(new Performance(this))
, m_sizes(new DashboardSizes(this)) {}
};
} // namespace ZShell::config
+29
View File
@@ -0,0 +1,29 @@
#pragma once
#include "configobject.hpp"
#include <QStringList>
#include <qqmlintegration.h>
namespace ZShell::config {
class Dock : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(bool, enable, false)
CFG_PROPERTY(int, height, 80)
CFG_PROPERTY(bool, hoverToReveal, false)
CFG_PROPERTY(QStringList, ignoredAppRegexes, {})
CFG_PROPERTY(
QStringList,
pinnedApps,
(QStringList{
QStringLiteral("com.ayugram.desktop"),
QStringLiteral("com.obsproject.studio"),
QStringLiteral("librewolf")}))
CFG_PROPERTY(bool, pinnedOnStartup, false)
public:
explicit Dock(QObject* parent = nullptr) : ConfigObject(parent) {}
};
} // namespace ZShell::config
+158
View File
@@ -0,0 +1,158 @@
#pragma once
#include "configlist.hpp"
#include "configobject.hpp"
#include <QStringList>
namespace ZShell::config {
class BatteryThresholdEntry : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(QString, icon)
CFG_PROPERTY(QString, message)
CFG_PROPERTY(QString, name)
CFG_PROPERTY(int, perc)
public:
explicit BatteryThresholdEntry(QObject* parent = nullptr)
: ConfigObject(parent) {}
[[nodiscard]] QStringList identityKeys() const override {
return {QStringLiteral("perc")};
}
};
CONFIG_LIST_TYPE(BatteryThresholdEntry, BatteryThresholdList)
class IdleTimeoutEntry : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(QString, idleAction)
CFG_PROPERTY(QString, name)
CFG_PROPERTY(int, timeout)
public:
explicit IdleTimeoutEntry(QObject* parent = nullptr)
: ConfigObject(parent) {}
[[nodiscard]] QStringList identityKeys() const override {
return {QStringLiteral("name")};
}
};
CONFIG_LIST_TYPE(IdleTimeoutEntry, IdleTimeoutList)
class Apps : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(QStringList, archiver, {QStringLiteral("ark")})
CFG_PROPERTY(QStringList, audio, {QStringLiteral("pavucontrol")})
CFG_PROPERTY(QStringList, document, {QStringLiteral("libreoffice")})
CFG_PROPERTY(QStringList, editor, {QStringLiteral("kate")})
CFG_PROPERTY(QStringList, explorer, {QStringLiteral("dolphin")})
CFG_PROPERTY(QStringList, image, {QStringLiteral("imv")})
CFG_PROPERTY(QStringList, playback, {QStringLiteral("vlc")})
CFG_PROPERTY(QStringList, terminal, {QStringLiteral("wezterm")})
public:
explicit Apps(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class Battery : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(int, critPerc, 5)
CONFIG_LIST(
BatteryThresholdList,
popupThresholds,
{
vmap(
{{"icon", "battery_android_frame_2"},
{"message", "Battery low"},
{"name", "Low battery"},
{"perc", 20}}),
vmap(
{{"icon", "battery_android_frame_2"},
{"message", "Battery lower"},
{"name", "Low battery"},
{"perc", 15}}),
vmap(
{{"icon", "battery_android_frame_2"},
{"message", "Battery lowest"},
{"name", "Low battery"},
{"perc", 10}}),
})
public:
explicit Battery(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class ColorSettings : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(int, hyprsunsetTemp, 2600)
CFG_PROPERTY(QString, mode, QStringLiteral("dark"))
CFG_PROPERTY(bool, neovimColors, false)
CFG_PROPERTY(bool, scheduleDark, false)
CFG_PROPERTY(int, scheduleDarkEnd, 600)
CFG_PROPERTY(int, scheduleDarkStart, 1140)
CFG_PROPERTY(bool, scheduleHyprsunset, true)
CFG_PROPERTY(int, scheduleHyprsunsetEnd, 570)
CFG_PROPERTY(int, scheduleHyprsunsetStart, 1200)
CFG_PROPERTY(bool, schemeGeneration, true)
CFG_PROPERTY(bool, smart, false)
public:
explicit ColorSettings(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class Idle : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CONFIG_LIST(
IdleTimeoutList,
timeouts,
{
vmap(
{{"idleAction", QStringLiteral("lock")},
{"name", QStringLiteral("Lock")},
{"timeout", 180}}),
})
public:
explicit Idle(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class General : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CONFIG_SUBOBJECT(Apps, apps)
CONFIG_SUBOBJECT(Battery, battery)
CONFIG_SUBOBJECT(ColorSettings, color)
CFG_PROPERTY(QString, dateFormat, QStringLiteral("ddd d MMM - hh:mm:ss"))
CFG_PROPERTY(bool, desktopIcons, true)
CONFIG_SUBOBJECT(Idle, idle)
CFG_PROPERTY(QString, logo, QString())
CFG_PROPERTY(bool, showOverFullscreen, true)
CFG_PROPERTY(
QString,
wallpaperPath,
QStringLiteral("/mnt/IronWolf/SDImages/SWWW_Wals/"))
public:
explicit General(QObject* parent = nullptr)
: ConfigObject(parent)
, m_apps(new Apps(this))
, m_battery(new Battery(this))
, m_color(new ColorSettings(this))
, m_idle(new Idle(this)) {}
};
} // namespace ZShell::config
+177
View File
@@ -0,0 +1,177 @@
#pragma once
#include "configlist.hpp"
#include "configobject.hpp"
#include <QStringList>
namespace ZShell::config {
class LauncherActionEntry : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(QVariantList, command)
CFG_PROPERTY(bool, dangerous, false)
CFG_PROPERTY(QString, description)
CFG_PROPERTY(bool, enabled, true)
CFG_PROPERTY(QString, icon)
CFG_PROPERTY(QString, name)
public:
explicit LauncherActionEntry(QObject* parent = nullptr)
: ConfigObject(parent) {}
[[nodiscard]] QStringList identityKeys() const override {
return {QStringLiteral("name")};
}
};
CONFIG_LIST_TYPE(LauncherActionEntry, LauncherActionList)
class LauncherSizes : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(int, itemHeight, 50)
CFG_PROPERTY(int, itemWidth, 600)
CFG_PROPERTY(int, wallpaperHeight, 200)
CFG_PROPERTY(int, wallpaperWidth, 280)
public:
explicit LauncherSizes(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class UseFuzzy : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(bool, actions, true)
CFG_PROPERTY(bool, apps, true)
CFG_PROPERTY(bool, schemes, true)
CFG_PROPERTY(bool, variants, true)
CFG_PROPERTY(bool, wallpapers, true)
public:
explicit UseFuzzy(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class Launcher : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(QString, actionPrefix, QStringLiteral("<"))
CONFIG_LIST(
LauncherActionList,
actions,
{
vmap(
{{"command", QVariantList{"autocomplete", "calc"}},
{"dangerous", false},
{"description", "Do simple math equations"},
{"enabled", true},
{"icon", "calculate"},
{"name", "Calculator"}}),
vmap(
{{"command", QVariantList{"setMode", "light"}},
{"dangerous", false},
{"description", "Change to light mode"},
{"enabled", true},
{"icon", "light_mode"},
{"name", "Light"}}),
vmap(
{{"command", QVariantList{"setMode", "dark"}},
{"dangerous", false},
{"description", "Change to dark mode"},
{"enabled", true},
{"icon", "dark_mode"},
{"name", "Dark"}}),
vmap(
{{"command", QVariantList{"autocomplete", "wallpaper"}},
{"dangerous", false},
{"description", "Change the current wallpaper"},
{"enabled", true},
{"icon", "image"},
{"name", "Wallpaper"}}),
vmap(
{{"command", QVariantList{"autocomplete", "variant"}},
{"dangerous", false},
{"description", "Change the current scheme variant"},
{"enabled", true},
{"icon", "colors"},
{"name", "Variant"}}),
vmap(
{{"command", QVariantList{"systemctl", "poweroff"}},
{"dangerous", true},
{"description", "Shutdown the system"},
{"enabled", true},
{"icon", "power_settings_new"},
{"name", "Shutdown"}}),
vmap(
{{"command", QVariantList{"systemctl", "reboot"}},
{"dangerous", true},
{"description", "Reboot the system"},
{"enabled", true},
{"icon", "cached"},
{"name", "Reboot"}}),
vmap(
{{"command", QVariantList{"loginctl", "terminate-user", ""}},
{"dangerous", true},
{"description", "Log out of the current session"},
{"enabled", true},
{"icon", "logout"},
{"name", "Logout"}}),
vmap(
{{"command", QVariantList{"loginctl", "lock-session"}},
{"dangerous", false},
{"description", "Lock the current session"},
{"enabled", true},
{"icon", "lock"},
{"name", "Lock"}}),
vmap(
{{"command",
QVariantList{"systemctl", "suspend-then-hibernate"}},
{"dangerous", false},
{"description", "Suspend then hibernate"},
{"enabled", true},
{"icon", "bedtime"},
{"name", "Sleep"}}),
})
CFG_PROPERTY(int, dragThreshold, 150)
CFG_PROPERTY(bool, enableDangerousActions, true)
CFG_PROPERTY(bool, enabled, true)
CFG_PROPERTY(
QStringList,
favoriteApps,
{QStringLiteral("Balatro"),
QStringLiteral("Slay the Spire 2"),
QStringLiteral("com.obsproject.Studio")})
CFG_PROPERTY(
QStringList,
hiddenApps,
{QStringLiteral("zellij"),
QStringLiteral("vim"),
QStringLiteral("jshell-java-openjdk"),
QStringLiteral("jconsole-java-openjdk"),
QStringLiteral("jshell-java21-openjdk"),
QStringLiteral("jconsole-java21-openjdk"),
QStringLiteral("jshell-java17-openjdk"),
QStringLiteral("jconsole-java17-openjdk"),
QStringLiteral("org.neovim.nvim"),
QStringLiteral("avahi-discover"),
QStringLiteral("bvnc"),
QStringLiteral("bssh"),
QStringLiteral("nm-connection-editor")})
CFG_PROPERTY(int, maxAppsShown, 18)
CFG_PROPERTY(int, maxWallpapers, 7)
CONFIG_SUBOBJECT(LauncherSizes, sizes)
CFG_PROPERTY(QString, specialPrefix, QStringLiteral("@"))
CONFIG_SUBOBJECT(UseFuzzy, useFuzzy)
CFG_PROPERTY(bool, uwsm, true)
public:
explicit Launcher(QObject* parent = nullptr)
: ConfigObject(parent)
, m_sizes(new LauncherSizes(this))
, m_useFuzzy(new UseFuzzy(this)) {}
};
} // namespace ZShell::config
+36
View File
@@ -0,0 +1,36 @@
#pragma once
#include "configobject.hpp"
#include <qqmlintegration.h>
namespace ZShell::config {
class LockSizes : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(int, centerWidth, 600)
CFG_PROPERTY(qreal, heightMult, 0.7)
CFG_PROPERTY(qreal, ratio, 1.78)
public:
explicit LockSizes(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class Lock : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(int, blurAmount, 10)
CFG_PROPERTY(bool, enableFprint, true)
CFG_PROPERTY(int, maxFprintTries, 3)
CFG_PROPERTY(bool, recolorLogo, false)
CFG_PROPERTY(bool, showNotifContent, true)
CFG_PROPERTY(bool, showNotifIcon, true)
CONFIG_SUBOBJECT(LockSizes, sizes)
public:
explicit Lock(QObject* parent = nullptr)
: ConfigObject(parent), m_sizes(new LockSizes(this)) {}
};
} // namespace ZShell::config
+39
View File
@@ -0,0 +1,39 @@
#pragma once
#include "configobject.hpp"
#include <qqmlintegration.h>
namespace ZShell::config {
class NotifsSizes : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(int, badge, 20)
CFG_PROPERTY(int, image, 41)
CFG_PROPERTY(int, width, 400)
public:
explicit NotifsSizes(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class Notifs : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(bool, actionOnClick, false)
CFG_PROPERTY(int, appNotifCooldown, 0)
CFG_PROPERTY(qreal, clearThreshold, 0.3)
CFG_PROPERTY(int, defaultExpireTimeout, 5000)
CFG_PROPERTY(int, expandThreshold, 20)
CFG_PROPERTY(bool, expire, true)
CFG_PROPERTY(int, groupPreviewNum, 5)
CFG_PROPERTY(bool, openExpanded, false)
CFG_PROPERTY(bool, showInFullscreen, false)
CONFIG_SUBOBJECT(NotifsSizes, sizes)
public:
explicit Notifs(QObject* parent = nullptr)
: ConfigObject(parent), m_sizes(new NotifsSizes(this)) {}
};
} // namespace ZShell::config
+34
View File
@@ -0,0 +1,34 @@
#pragma once
#include "configobject.hpp"
#include <qqmlintegration.h>
namespace ZShell::config {
class OsdSizes : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(int, sliderHeight, 150)
CFG_PROPERTY(int, sliderWidth, 30)
public:
explicit OsdSizes(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class Osd : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(bool, allMonBrightness, true)
CFG_PROPERTY(bool, enableBrightness, true)
CFG_PROPERTY(bool, enableMicrophone, true)
CFG_PROPERTY(bool, enabled, true)
CFG_PROPERTY(int, hideDelay, 3000)
CONFIG_SUBOBJECT(OsdSizes, sizes)
public:
explicit Osd(QObject* parent = nullptr)
: ConfigObject(parent), m_sizes(new OsdSizes(this)) {}
};
} // namespace ZShell::config
+27
View File
@@ -0,0 +1,27 @@
#pragma once
#include "configobject.hpp"
#include <QVariantList>
#include <qqmlintegration.h>
namespace ZShell::config {
class Screenshot : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(bool, enable_pp, false)
CFG_PROPERTY(QString, mode, QStringLiteral("manual"))
CFG_PROPERTY(int, radius, 49)
CFG_PROPERTY(bool, rounding, false)
CFG_PROPERTY(bool, saveOnCopy, false)
CFG_PROPERTY(bool, shadow, true)
CFG_PROPERTY(int, shadow_blur, 0)
CFG_PROPERTY(QVariantList, shadow_color, (QVariantList{0, 0, 0, 160}))
CFG_PROPERTY(int, shadow_offset_x, 30)
CFG_PROPERTY(int, shadow_offset_y, 50)
public:
explicit Screenshot(QObject* parent = nullptr) : ConfigObject(parent) {}
};
} // namespace ZShell::config
+54
View File
@@ -0,0 +1,54 @@
#pragma once
#include "configlist.hpp"
#include "configobject.hpp"
namespace ZShell::config {
class PlayerAliasEntry : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(QString, from)
CFG_PROPERTY(QString, to)
public:
explicit PlayerAliasEntry(QObject* parent = nullptr)
: ConfigObject(parent) {}
[[nodiscard]] QStringList identityKeys() const override {
return {QStringLiteral("from")};
}
};
CONFIG_LIST_TYPE(PlayerAliasEntry, PlayerAliasList)
class Services : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(qreal, audioIncrement, 0.1)
CFG_PROPERTY(qreal, brightnessIncrement, 0.1)
CFG_PROPERTY(bool, ddcutilService, true)
CFG_PROPERTY(QString, defaultPlayer, QStringLiteral("Spotify"))
CFG_PROPERTY(QString, gpuType, QStringLiteral("NVIDIA"))
CFG_PROPERTY(qreal, maxVolume, 1)
CFG_PROPERTY(qreal, minBrightness, 0.01)
CONFIG_LIST(
PlayerAliasList,
playerAliases,
{
vmap(
{{"from", QStringLiteral("com.github.th_ch.youtube_music")},
{"to", QStringLiteral("YT Music")}}),
})
CFG_PROPERTY(bool, updates, true)
CFG_PROPERTY(bool, useFahrenheit, false)
CFG_PROPERTY(bool, useTwelveHourClock, false)
CFG_PROPERTY(int, visualizerBars, 50)
CFG_PROPERTY(QString, weatherLocation, QString())
public:
explicit Services(QObject* parent = nullptr) : ConfigObject(parent) {}
};
} // namespace ZShell::config
+30
View File
@@ -0,0 +1,30 @@
#pragma once
#include "configobject.hpp"
#include <qqmlintegration.h>
namespace ZShell::config {
class SidebarSizes : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(int, width, 520)
public:
explicit SidebarSizes(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class Sidebar : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(int, dragThreshold, 30)
CFG_PROPERTY(bool, enabled, true)
CONFIG_SUBOBJECT(SidebarSizes, sizes)
public:
explicit Sidebar(QObject* parent = nullptr)
: ConfigObject(parent), m_sizes(new SidebarSizes(this)) {}
};
} // namespace ZShell::config
+221
View File
@@ -0,0 +1,221 @@
#pragma once
#include "configobject.hpp"
#include <QVariantList>
#include <qqmlengine.h>
#include <qqmlregistration.h>
namespace ZShell::config {
class AppearanceRounding : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(qreal, extraSmall, 4)
CFG_PROPERTY(qreal, full, 1000)
CFG_PROPERTY(qreal, large, 24)
CFG_PROPERTY(qreal, medium, 16)
CFG_PROPERTY(qreal, normal, 18)
CFG_PROPERTY(qreal, scale, 1)
CFG_PROPERTY(qreal, small, 12)
CFG_PROPERTY(qreal, smallest, 8)
public:
explicit AppearanceRounding(QObject* parent = nullptr)
: ConfigObject(parent) {}
};
class AppearancePadding : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(qreal, extraLarge, 28)
CFG_PROPERTY(qreal, extraLargeIncreased, 32)
CFG_PROPERTY(qreal, extraSmall, 4)
CFG_PROPERTY(qreal, large, 16)
CFG_PROPERTY(qreal, largeIncreased, 20)
CFG_PROPERTY(qreal, larger, 12)
CFG_PROPERTY(qreal, normal, 8)
CFG_PROPERTY(qreal, scale, 1)
CFG_PROPERTY(qreal, small, 5)
CFG_PROPERTY(qreal, smaller, 7)
CFG_PROPERTY(qreal, smallest, 2)
public:
explicit AppearancePadding(QObject* parent = nullptr)
: ConfigObject(parent) {}
};
class AppearanceSpacing : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(qreal, extraSmall, 4)
CFG_PROPERTY(qreal, large, 20)
CFG_PROPERTY(qreal, larger, 16)
CFG_PROPERTY(qreal, normal, 12)
CFG_PROPERTY(qreal, scale, 1)
CFG_PROPERTY(qreal, small, 8)
CFG_PROPERTY(qreal, smaller, 10)
public:
explicit AppearanceSpacing(QObject* parent = nullptr)
: ConfigObject(parent) {}
};
class FontSizeTokens : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(qreal, extraLarge, 28)
CFG_PROPERTY(qreal, large, 18)
CFG_PROPERTY(qreal, larger, 16)
CFG_PROPERTY(qreal, medium, 14)
CFG_PROPERTY(qreal, normal, 13)
CFG_PROPERTY(qreal, scale, 1)
CFG_PROPERTY(qreal, small, 11)
CFG_PROPERTY(qreal, smaller, 12)
public:
explicit FontSizeTokens(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class FontTokens : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CONFIG_SUBOBJECT(FontSizeTokens, size)
public:
explicit FontTokens(QObject* parent = nullptr)
: ConfigObject(parent), m_size(new FontSizeTokens(this)) {}
};
class AnimCurves : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(
QVariantList,
emphasized,
QVariantList{
0.05,
0,
2.0 / 15.0,
0.06,
1.0 / 6.0,
0.4,
5.0 / 24.0,
0.82,
0.25,
1,
1,
1})
CFG_PROPERTY(
QVariantList, emphasizedAccel, QVariantList{0.3, 0, 0.8, 0.15, 1, 1})
CFG_PROPERTY(
QVariantList, emphasizedDecel, QVariantList{0.05, 0.7, 0.1, 1, 1, 1})
CFG_PROPERTY(
QVariantList,
expressiveDefaultEffects,
QVariantList{0.34, 0.8, 0.34, 1, 1, 1})
CFG_PROPERTY(
QVariantList,
expressiveDefaultSpatial,
QVariantList{0.38, 1.21, 0.22, 1, 1, 1})
CFG_PROPERTY(
QVariantList, expressiveEffects, QVariantList{0.34, 0.8, 0.34, 1, 1, 1})
CFG_PROPERTY(
QVariantList,
expressiveFastEffects,
QVariantList{0.31, 0.94, 0.34, 1, 1, 1})
CFG_PROPERTY(
QVariantList,
expressiveFastSpatial,
QVariantList{0.42, 1.67, 0.21, 0.9, 1, 1})
CFG_PROPERTY(
QVariantList,
expressiveSlowEffects,
QVariantList{0.34, 0.88, 0.34, 1, 1, 1})
CFG_PROPERTY(
QVariantList,
expressiveSlowSpatial,
QVariantList{0.39, 1.29, 0.35, 0.98, 1, 1})
CFG_PROPERTY(QVariantList, standard, QVariantList{0.2, 0, 0, 1, 1, 1})
CFG_PROPERTY(QVariantList, standardAccel, QVariantList{0.3, 0, 1, 1, 1, 1})
CFG_PROPERTY(QVariantList, standardDecel, QVariantList{0, 0, 0, 1, 1, 1})
public:
explicit AnimCurves(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class AnimDurations : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(int, expressiveDefaultSpatial, 500)
CFG_PROPERTY(int, expressiveEffects, 200)
CFG_PROPERTY(int, expressiveFastEffects, 150)
CFG_PROPERTY(int, expressiveFastSpatial, 350)
CFG_PROPERTY(int, expressiveSlowEffects, 300)
CFG_PROPERTY(int, extraLarge, 1000)
CFG_PROPERTY(int, large, 600)
CFG_PROPERTY(int, normal, 400)
CFG_PROPERTY(qreal, scale, 1)
CFG_PROPERTY(int, small, 200)
public:
explicit AnimDurations(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class AnimTokens : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CONFIG_SUBOBJECT(AnimCurves, curves)
CONFIG_SUBOBJECT(AnimDurations, durations)
public:
explicit AnimTokens(QObject* parent = nullptr)
: ConfigObject(parent)
, m_curves(new AnimCurves(this))
, m_durations(new AnimDurations(this)) {}
};
class Tokens : public ConfigObject {
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
CONFIG_SUBOBJECT(AppearanceRounding, rounding)
CONFIG_SUBOBJECT(AppearancePadding, padding)
CONFIG_SUBOBJECT(AppearanceSpacing, spacing)
CONFIG_SUBOBJECT(FontTokens, font)
CONFIG_SUBOBJECT(AnimTokens, anim)
public:
explicit Tokens(QObject* parent = nullptr)
: ConfigObject(parent)
, m_rounding(new AppearanceRounding(this))
, m_padding(new AppearancePadding(this))
, m_spacing(new AppearanceSpacing(this))
, m_font(new FontTokens(this))
, m_anim(new AnimTokens(this)) {}
static Tokens* create(QQmlEngine*, QJSEngine*) { return new Tokens(); }
};
} // namespace ZShell::config
+70
View File
@@ -0,0 +1,70 @@
#pragma once
#include "configobject.hpp"
#include <QVariantList>
#include <QStringList>
#include <qqmlintegration.h>
namespace ZShell::config {
class UtilitiesSizes : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(int, toastWidth, 430)
CFG_PROPERTY(int, width, 430)
public:
explicit UtilitiesSizes(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class Toasts : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(bool, audioInputChanged, true)
CFG_PROPERTY(bool, audioOutputChanged, true)
CFG_PROPERTY(bool, capsLockChanged, true)
CFG_PROPERTY(bool, chargingChanged, true)
CFG_PROPERTY(bool, configLoaded, true)
CFG_PROPERTY(bool, dndChanged, true)
CFG_PROPERTY(bool, gameModeChanged, true)
CFG_PROPERTY(bool, kbLayoutChanged, true)
CFG_PROPERTY(bool, kbLimit, true)
CFG_PROPERTY(bool, nowPlaying, false)
CFG_PROPERTY(bool, numLockChanged, true)
CFG_PROPERTY(bool, vpnChanged, true)
public:
explicit Toasts(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class Vpn : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(bool, enabled, false)
CFG_PROPERTY(QStringList, provider, (QStringList{QStringLiteral("netbird")}))
public:
explicit Vpn(QObject* parent = nullptr) : ConfigObject(parent) {}
};
class Utilities : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
CFG_PROPERTY(bool, enabled, true)
CFG_PROPERTY(int, maxToasts, 4)
CONFIG_SUBOBJECT(UtilitiesSizes, sizes)
CONFIG_SUBOBJECT(Toasts, toasts)
CONFIG_SUBOBJECT(Vpn, vpn)
public:
explicit Utilities(QObject* parent = nullptr)
: ConfigObject(parent)
, m_sizes(new UtilitiesSizes(this))
, m_toasts(new Toasts(this))
, m_vpn(new Vpn(this)) {}
};
} // namespace ZShell::config