1 Commits

11 changed files with 492 additions and 408 deletions
+12 -1
View File
@@ -22,6 +22,7 @@ Singleton {
property alias notifs: adapter.notifs property alias notifs: adapter.notifs
property alias osd: adapter.osd property alias osd: adapter.osd
property alias overview: adapter.overview property alias overview: adapter.overview
property alias plugins: adapter.plugins
property bool recentlySaved: false property bool recentlySaved: false
property alias screenshot: adapter.screenshot property alias screenshot: adapter.screenshot
property alias services: adapter.services property alias services: adapter.services
@@ -140,7 +141,8 @@ Singleton {
launcher: serializeLauncher(), launcher: serializeLauncher(),
colors: serializeColors(), colors: serializeColors(),
dock: serializeDock(), dock: serializeDock(),
screenshot: serializeScreenshot() screenshot: serializeScreenshot(),
plugins: serializePlugins()
}; };
} }
@@ -289,6 +291,13 @@ Singleton {
}; };
} }
function serializePlugins(): var {
return {
enabled: plugins.enabled,
entries: plugins.entries
};
}
function serializeScreenshot(): var { function serializeScreenshot(): var {
return { return {
enable_pp: screenshot.enable_pp, enable_pp: screenshot.enable_pp,
@@ -458,6 +467,8 @@ Singleton {
} }
property Overview overview: Overview { property Overview overview: Overview {
} }
property PluginConfig plugins: PluginConfig {
}
property Screenshot screenshot: Screenshot { property Screenshot screenshot: Screenshot {
} }
property Services services: Services { property Services services: Services {
+11
View File
@@ -0,0 +1,11 @@
import Quickshell.Io
JsonObject {
property bool enabled: false
property list<var> entries: [
{
id: "Plugin",
enabled: false
},
]
}
+18
View File
@@ -0,0 +1,18 @@
pragma Singleton
import Quickshell
import ZShell.Models
Singleton {
id: root
property alias plugins: plugins.entries
FileSystemModel {
id: plugins
nameFilters: ["*.qml"]
path: Quickshell.env("HOME") + "/.config/zshell"
recursive: false
}
}
+17
View File
@@ -0,0 +1,17 @@
import Quickshell
import QtQuick
import ZShell.Models
import qs.Config
Repeater {
model: FetchPlugins.plugins
LazyLoader {
required property FileSystemEntry modelData
activeAsync: Config.plugins.entries.some(p => {
return p.id === modelData.baseName && p.enabled;
})
source: modelData.path
}
}
-1
View File
@@ -6,7 +6,6 @@ import Quickshell
Singleton { Singleton {
property var extraOpts: ({}) property var extraOpts: ({})
readonly property list<var> fuzzyPrepped: useFuzzy ? list.map(e => { readonly property list<var> fuzzyPrepped: useFuzzy ? list.map(e => {
console.log(useFuzzy);
const obj = { const obj = {
_item: e _item: e
}; };
+6
View File
@@ -116,6 +116,12 @@ Item {
key: "updates" key: "updates"
name: "Updates" name: "Updates"
} }
ListElement {
icon: "extension"
key: "plugins"
name: "Extensions"
}
} }
CustomClippingRect { CustomClippingRect {
+18
View File
@@ -0,0 +1,18 @@
import qs.Modules.Settings.Controls
import qs.Config
SettingsPage {
SettingsSection {
sectionId: "Plugins"
SettingsHeader {
name: "Plugins"
}
SettingBarEntryList {
name: "Enable or disable plugins"
object: Config.plugins
setting: "entries"
}
}
}
+9
View File
@@ -79,6 +79,8 @@ Item {
stack.push(screenshot); stack.push(screenshot);
else if (currentCategory === "updates") else if (currentCategory === "updates")
stack.push(updates); stack.push(updates);
else if (currentCategory === "plugins")
stack.push(plugins);
} }
target: root target: root
@@ -245,4 +247,11 @@ Item {
Cat.SystemUpdates { Cat.SystemUpdates {
} }
} }
Component {
id: plugins
Cat.Plugins {
}
}
} }
+16 -25
View File
@@ -12,7 +12,8 @@ FileSystemEntry::FileSystemEntry(const QString& path, const QString& relativePat
, m_path(path) , m_path(path)
, m_relativePath(relativePath) , m_relativePath(relativePath)
, m_isImageInitialised(false) , m_isImageInitialised(false)
, m_mimeTypeInitialised(false) {} , m_mimeTypeInitialised(false) {
}
QString FileSystemEntry::path() const { QString FileSystemEntry::path() const {
return m_path; return m_path;
@@ -57,8 +58,8 @@ bool FileSystemEntry::isImage() const {
QString FileSystemEntry::mimeType() const { QString FileSystemEntry::mimeType() const {
if (!m_mimeTypeInitialised) { if (!m_mimeTypeInitialised) {
const QMimeDatabase db; static const QMimeDatabase s_db;
m_mimeType = db.mimeTypeForFile(m_path).name(); m_mimeType = s_db.mimeTypeForFile(m_path).name();
m_mimeTypeInitialised = true; m_mimeTypeInitialised = true;
} }
return m_mimeType; return m_mimeType;
@@ -219,7 +220,7 @@ void FileSystemModel::watchDirIfRecursive(const QString& path) {
if (m_recursive && m_watchChanges) { if (m_recursive && m_watchChanges) {
const auto currentDir = m_dir; const auto currentDir = m_dir;
const bool showHidden = m_showHidden; const bool showHidden = m_showHidden;
const auto future = QtConcurrent::run([showHidden, path]() { auto future = QtConcurrent::run([showHidden, path]() {
QDir::Filters filters = QDir::Dirs | QDir::NoDotAndDotDot; QDir::Filters filters = QDir::Dirs | QDir::NoDotAndDotDot;
if (showHidden) { if (showHidden) {
filters |= QDir::Hidden; filters |= QDir::Hidden;
@@ -232,16 +233,12 @@ void FileSystemModel::watchDirIfRecursive(const QString& path) {
} }
return dirs; return dirs;
}); });
const auto watcher = new QFutureWatcher<QStringList>(this); future.then(this, [currentDir, showHidden, this](const QStringList& paths) {
connect(watcher, &QFutureWatcher<QStringList>::finished, this, [currentDir, showHidden, watcher, this]() {
const auto paths = watcher->result();
if (currentDir == m_dir && showHidden == m_showHidden && !paths.isEmpty()) { if (currentDir == m_dir && showHidden == m_showHidden && !paths.isEmpty()) {
// Ignore if dir or showHidden has changed // Ignore if dir or showHidden has changed
m_watcher.addPaths(paths); m_watcher.addPaths(paths);
} }
watcher->deleteLater();
}); });
watcher->setFuture(future);
} }
} }
@@ -295,7 +292,7 @@ void FileSystemModel::updateEntriesForDir(const QString& dir) {
oldPaths << entry->path(); oldPaths << entry->path();
} }
const auto future = QtConcurrent::run([=](QPromise<QPair<QSet<QString>, QSet<QString>>>& promise) { auto future = QtConcurrent::run([=](QPromise<QPair<QSet<QString>, QSet<QString> > >& promise) {
const auto flags = recursive ? QDirIterator::Subdirectories : QDirIterator::NoIteratorFlags; const auto flags = recursive ? QDirIterator::Subdirectories : QDirIterator::NoIteratorFlags;
std::optional<QDirIterator> iter; std::optional<QDirIterator> iter;
@@ -353,7 +350,7 @@ void FileSystemModel::updateEntriesForDir(const QString& dir) {
newPaths.insert(path); newPaths.insert(path);
} }
if (promise.isCanceled() || newPaths == oldPaths) { if (promise.isCanceled()) {
return; return;
} }
@@ -365,23 +362,17 @@ void FileSystemModel::updateEntriesForDir(const QString& dir) {
} }
m_futures.insert(dir, future); m_futures.insert(dir, future);
const auto watcher = new QFutureWatcher<QPair<QSet<QString>, QSet<QString>>>(this); future
.then(this,
connect(watcher, &QFutureWatcher<QPair<QSet<QString>, QSet<QString>>>::finished, this, [dir, watcher, this]() { [dir, this](QPair<QSet<QString>, QSet<QString> > result) {
m_futures.remove(dir); m_futures.remove(dir);
if (!result.first.isEmpty() || !result.second.isEmpty()) {
if (!watcher->future().isResultReadyAt(0)) {
watcher->deleteLater();
return;
}
const auto result = watcher->result();
applyChanges(result.first, result.second); applyChanges(result.first, result.second);
}
watcher->deleteLater(); })
.onCanceled(this, [dir, this]() {
m_futures.remove(dir);
}); });
watcher->setFuture(future);
} }
void FileSystemModel::applyChanges(const QSet<QString>& removedPaths, const QSet<QString>& addedPaths) { void FileSystemModel::applyChanges(const QSet<QString>& removedPaths, const QSet<QString>& addedPaths) {
+90 -90
View File
@@ -13,136 +13,136 @@
namespace ZShell::models { namespace ZShell::models {
class FileSystemEntry : public QObject { class FileSystemEntry : public QObject {
Q_OBJECT Q_OBJECT
QML_ELEMENT QML_ELEMENT
QML_UNCREATABLE("FileSystemEntry instances can only be retrieved from a FileSystemModel") QML_UNCREATABLE("FileSystemEntry instances can only be retrieved from a FileSystemModel")
Q_PROPERTY(QString path READ path CONSTANT) Q_PROPERTY(QString path READ path CONSTANT)
Q_PROPERTY(QString relativePath READ relativePath NOTIFY relativePathChanged) Q_PROPERTY(QString relativePath READ relativePath NOTIFY relativePathChanged)
Q_PROPERTY(QString name READ name CONSTANT) Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(QString baseName READ baseName CONSTANT) Q_PROPERTY(QString baseName READ baseName CONSTANT)
Q_PROPERTY(QString parentDir READ parentDir CONSTANT) Q_PROPERTY(QString parentDir READ parentDir CONSTANT)
Q_PROPERTY(QString suffix READ suffix CONSTANT) Q_PROPERTY(QString suffix READ suffix CONSTANT)
Q_PROPERTY(qint64 size READ size CONSTANT) Q_PROPERTY(qint64 size READ size CONSTANT)
Q_PROPERTY(bool isDir READ isDir CONSTANT) Q_PROPERTY(bool isDir READ isDir CONSTANT)
Q_PROPERTY(bool isImage READ isImage CONSTANT) Q_PROPERTY(bool isImage READ isImage CONSTANT)
Q_PROPERTY(QString mimeType READ mimeType CONSTANT) Q_PROPERTY(QString mimeType READ mimeType CONSTANT)
public: public:
explicit FileSystemEntry(const QString& path, const QString& relativePath, QObject* parent = nullptr); explicit FileSystemEntry(const QString& path, const QString& relativePath, QObject* parent = nullptr);
[[nodiscard]] QString path() const; [[nodiscard]] QString path() const;
[[nodiscard]] QString relativePath() const; [[nodiscard]] QString relativePath() const;
[[nodiscard]] QString name() const; [[nodiscard]] QString name() const;
[[nodiscard]] QString baseName() const; [[nodiscard]] QString baseName() const;
[[nodiscard]] QString parentDir() const; [[nodiscard]] QString parentDir() const;
[[nodiscard]] QString suffix() const; [[nodiscard]] QString suffix() const;
[[nodiscard]] qint64 size() const; [[nodiscard]] qint64 size() const;
[[nodiscard]] bool isDir() const; [[nodiscard]] bool isDir() const;
[[nodiscard]] bool isImage() const; [[nodiscard]] bool isImage() const;
[[nodiscard]] QString mimeType() const; [[nodiscard]] QString mimeType() const;
void updateRelativePath(const QDir& dir); void updateRelativePath(const QDir& dir);
signals: signals:
void relativePathChanged(); void relativePathChanged();
private: private:
const QFileInfo m_fileInfo; const QFileInfo m_fileInfo;
const QString m_path; const QString m_path;
QString m_relativePath; QString m_relativePath;
mutable bool m_isImage; mutable bool m_isImage;
mutable bool m_isImageInitialised; mutable bool m_isImageInitialised;
mutable QString m_mimeType; mutable QString m_mimeType;
mutable bool m_mimeTypeInitialised; mutable bool m_mimeTypeInitialised;
}; };
class FileSystemModel : public QAbstractListModel { class FileSystemModel : public QAbstractListModel {
Q_OBJECT Q_OBJECT
QML_ELEMENT QML_ELEMENT
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged) Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged) Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged)
Q_PROPERTY(bool watchChanges READ watchChanges WRITE setWatchChanges NOTIFY watchChangesChanged) Q_PROPERTY(bool watchChanges READ watchChanges WRITE setWatchChanges NOTIFY watchChangesChanged)
Q_PROPERTY(bool showHidden READ showHidden WRITE setShowHidden NOTIFY showHiddenChanged) Q_PROPERTY(bool showHidden READ showHidden WRITE setShowHidden NOTIFY showHiddenChanged)
Q_PROPERTY(bool sortReverse READ sortReverse WRITE setSortReverse NOTIFY sortReverseChanged) Q_PROPERTY(bool sortReverse READ sortReverse WRITE setSortReverse NOTIFY sortReverseChanged)
Q_PROPERTY(Filter filter READ filter WRITE setFilter NOTIFY filterChanged) Q_PROPERTY(Filter filter READ filter WRITE setFilter NOTIFY filterChanged)
Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters NOTIFY nameFiltersChanged) Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters NOTIFY nameFiltersChanged)
Q_PROPERTY(QQmlListProperty<ZShell::models::FileSystemEntry> entries READ entries NOTIFY entriesChanged) Q_PROPERTY(QQmlListProperty<ZShell::models::FileSystemEntry> entries READ entries NOTIFY entriesChanged)
public: public:
enum Filter { enum Filter {
NoFilter, NoFilter,
Images, Images,
Files, Files,
Dirs Dirs
}; };
Q_ENUM(Filter) Q_ENUM(Filter)
explicit FileSystemModel(QObject* parent = nullptr); explicit FileSystemModel(QObject* parent = nullptr);
int rowCount(const QModelIndex& parent = QModelIndex()) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override; QHash<int, QByteArray> roleNames() const override;
[[nodiscard]] QString path() const; [[nodiscard]] QString path() const;
void setPath(const QString& path); void setPath(const QString& path);
[[nodiscard]] bool recursive() const; [[nodiscard]] bool recursive() const;
void setRecursive(bool recursive); void setRecursive(bool recursive);
[[nodiscard]] bool watchChanges() const; [[nodiscard]] bool watchChanges() const;
void setWatchChanges(bool watchChanges); void setWatchChanges(bool watchChanges);
[[nodiscard]] bool showHidden() const; [[nodiscard]] bool showHidden() const;
void setShowHidden(bool showHidden); void setShowHidden(bool showHidden);
[[nodiscard]] bool sortReverse() const; [[nodiscard]] bool sortReverse() const;
void setSortReverse(bool sortReverse); void setSortReverse(bool sortReverse);
[[nodiscard]] Filter filter() const; [[nodiscard]] Filter filter() const;
void setFilter(Filter filter); void setFilter(Filter filter);
[[nodiscard]] QStringList nameFilters() const; [[nodiscard]] QStringList nameFilters() const;
void setNameFilters(const QStringList& nameFilters); void setNameFilters(const QStringList& nameFilters);
[[nodiscard]] QQmlListProperty<FileSystemEntry> entries(); [[nodiscard]] QQmlListProperty<FileSystemEntry> entries();
signals: signals:
void pathChanged(); void pathChanged();
void recursiveChanged(); void recursiveChanged();
void watchChangesChanged(); void watchChangesChanged();
void showHiddenChanged(); void showHiddenChanged();
void sortReverseChanged(); void sortReverseChanged();
void filterChanged(); void filterChanged();
void nameFiltersChanged(); void nameFiltersChanged();
void entriesChanged(); void entriesChanged();
private: private:
QDir m_dir; QDir m_dir;
QFileSystemWatcher m_watcher; QFileSystemWatcher m_watcher;
QList<FileSystemEntry*> m_entries; QList<FileSystemEntry*> m_entries;
QHash<QString, QFuture<QPair<QSet<QString>, QSet<QString>>>> m_futures; QHash<QString, QFuture<QPair<QSet<QString>, QSet<QString> > > > m_futures;
QString m_path; QString m_path;
bool m_recursive; bool m_recursive;
bool m_watchChanges; bool m_watchChanges;
bool m_showHidden; bool m_showHidden;
bool m_sortReverse; bool m_sortReverse = false;
Filter m_filter; Filter m_filter;
QStringList m_nameFilters; QStringList m_nameFilters;
void watchDirIfRecursive(const QString& path); void watchDirIfRecursive(const QString& path);
void update(); void update();
void updateWatcher(); void updateWatcher();
void updateEntries(); void updateEntries();
void updateEntriesForDir(const QString& dir); void updateEntriesForDir(const QString& dir);
void applyChanges(const QSet<QString>& removedPaths, const QSet<QString>& addedPaths); void applyChanges(const QSet<QString>& removedPaths, const QSet<QString>& addedPaths);
[[nodiscard]] bool compareEntries(const FileSystemEntry* a, const FileSystemEntry* b) const; [[nodiscard]] bool compareEntries(const FileSystemEntry* a, const FileSystemEntry* b) const;
}; };
} // namespace ZShell::models } // namespace ZShell::models
+4
View File
@@ -6,6 +6,7 @@
//@ pragma Env QT_SCALE_FACTOR_ROUNDING_POLICY=Round //@ pragma Env QT_SCALE_FACTOR_ROUNDING_POLICY=Round
//@ pragma DropExpensiveFonts //@ pragma DropExpensiveFonts
import Quickshell import Quickshell
import qs.Extensions
import qs.Modules import qs.Modules
import qs.Modules.Wallpaper import qs.Modules.Wallpaper
import qs.Modules.Lock import qs.Modules.Lock
@@ -38,4 +39,7 @@ ShellRoot {
Polkit { Polkit {
} }
LoadExtensions {
}
} }