From 6d73bb234aa45ed8bb32b36836f59f550940f468 Mon Sep 17 00:00:00 2001 From: reionwong Date: Sun, 26 Sep 2021 19:23:54 +0800 Subject: [PATCH] Improve startup speed and use single instance process --- CMakeLists.txt | 8 ++ application.cpp | 143 ++++++++++++++++++++++++++++++ application.h | 48 ++++++++++ com.cutefish.FileManager.xml | 9 ++ main.cpp | 85 +----------------- qml/FolderPage.qml | 10 +-- qml/SideBar.qml | 2 +- thumbnailer/thumbnailprovider.cpp | 2 - window.cpp | 49 ++++++++++ window.h | 38 ++++++++ 10 files changed, 304 insertions(+), 90 deletions(-) create mode 100644 application.cpp create mode 100644 application.h create mode 100644 com.cutefish.FileManager.xml create mode 100644 window.cpp create mode 100644 window.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9208244..7a28e9a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,8 +18,14 @@ find_package(KF5KIO) find_package(KF5Solid) find_package(KF5WindowSystem) +qt5_add_dbus_adaptor(DBUS_SOURCES + com.cutefish.FileManager.xml + application.h Application) + add_executable(cutefish-filemanager main.cpp + application.cpp + window.cpp model/foldermodel.cpp model/placesmodel.cpp model/placesitem.cpp @@ -56,6 +62,8 @@ add_executable(cutefish-filemanager desktopiconprovider.cpp qml.qrc + + ${DBUS_SOURCES} ) target_link_libraries(cutefish-filemanager diff --git a/application.cpp b/application.cpp new file mode 100644 index 0000000..c9936e6 --- /dev/null +++ b/application.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2021 CutefishOS Team. + * + * Author: Reion Wong + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "application.h" +#include "window.h" +#include "desktop/desktop.h" +#include "thumbnailer/thumbnailprovider.h" +#include "filemanageradaptor.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +Application::Application(int& argc, char** argv) + : QApplication(argc, argv) + , m_instance(false) +{ + if (QDBusConnection::sessionBus().registerService("com.cutefish.FileManager")) { + setOrganizationName("cutefishos"); + setWindowIcon(QIcon::fromTheme("file-manager")); + + new FileManagerAdaptor(this); + QDBusConnection::sessionBus().registerObject("/FileManager", this); + + // Translations + QLocale locale; + QString qmFilePath = QString("%1/%2.qm").arg("/usr/share/cutefish-filemanager/translations/").arg(locale.name()); + if (QFile::exists(qmFilePath)) { + QTranslator *translator = new QTranslator(this); + if (translator->load(qmFilePath)) { + installTranslator(translator); + } else { + translator->deleteLater(); + } + } + + m_instance = true; + } +} + +int Application::run() +{ + if (!parseCommandLineArgs()) + return 0; + + return QApplication::exec(); +} + +void Application::openFiles(const QStringList &paths) +{ + for (const QString &path : paths) { + openWindow(path); + } +} + +void Application::emptyTrash() +{ + Window *w = new Window; + w->load(QUrl("qrc:/qml/Dialogs/EmptyTrashDialog.qml")); +} + +void Application::openWindow(const QString &path) +{ + Window *w = new Window; + w->rootContext()->setContextProperty("arg", path); + w->addImageProvider("thumbnailer", new ThumbnailProvider()); + w->load(QUrl("qrc:/qml/main.qml")); +} + +bool Application::parseCommandLineArgs() +{ + QCommandLineParser parser; + parser.setApplicationDescription(QStringLiteral("File Manager")); + parser.addHelpOption(); + + parser.addPositionalArgument("files", "Files", "[FILE1, FILE2,...]"); + + QCommandLineOption desktopOption(QStringList() << "d" << "desktop" << "Desktop Mode"); + parser.addOption(desktopOption); + + QCommandLineOption emptyTrashOption(QStringList() << "e" << "empty-trash" << "Empty Trash"); + parser.addOption(emptyTrashOption); + + parser.process(arguments()); + + if (m_instance) { + QPixmapCache::setCacheLimit(2048); + + if (parser.isSet(desktopOption)) { + Desktop desktop; + } else { + QStringList paths = parser.positionalArguments(); + + if (paths.isEmpty()) { + paths.append(QDir::currentPath()); + } + + openFiles(paths); + } + } else { + QDBusInterface iface("com.cutefish.FileManager", + "/FileManager", + "com.cutefish.FileManager", + QDBusConnection::sessionBus(), this); + + if (parser.isSet(emptyTrashOption)) { + // Empty Dialog + iface.call("emptyTrash"); + } else { + QStringList paths = parser.positionalArguments(); + + if (paths.isEmpty()) { + paths.append(QDir::currentPath()); + } + + iface.call("openFiles", paths); + } + } + + return m_instance; +} diff --git a/application.h b/application.h new file mode 100644 index 0000000..ff2edf5 --- /dev/null +++ b/application.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2021 CutefishOS Team. + * + * Author: Reion Wong + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef APPLICATION_H +#define APPLICATION_H + +#include + +class Application : public QApplication +{ + Q_OBJECT + +public: + explicit Application(int& argc, char** argv); + + int run(); + + // DBus + void openFiles(const QStringList &paths); + void emptyTrash(); + +private: + void openWindow(const QString &path); + +private: + bool parseCommandLineArgs(); + +private: + bool m_instance; +}; + +#endif // APPLICATION_H diff --git a/com.cutefish.FileManager.xml b/com.cutefish.FileManager.xml new file mode 100644 index 0000000..58366a4 --- /dev/null +++ b/com.cutefish.FileManager.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/main.cpp b/main.cpp index 5d97dea..0be9f1a 100644 --- a/main.cpp +++ b/main.cpp @@ -17,15 +17,7 @@ * along with this program. If not, see . */ -#include -#include -#include -#include - -#include -#include -#include - +#include "application.h" #include "model/placesmodel.h" #include "model/foldermodel.h" #include "model/pathbarmodel.h" @@ -39,31 +31,11 @@ #include "helper/fm.h" #include "helper/shortcut.h" -#include "thumbnailer/thumbnailprovider.h" - int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true); - QApplication app(argc, argv); - app.setOrganizationName("cutefishos"); - app.setWindowIcon(QIcon::fromTheme("file-manager")); - - QPixmapCache::setCacheLimit(1024 * 10); - - // Translations - QLocale locale; - QString qmFilePath = QString("%1/%2.qm").arg("/usr/share/cutefish-filemanager/translations/").arg(locale.name()); - if (QFile::exists(qmFilePath)) { - QTranslator *translator = new QTranslator(app.instance()); - if (translator->load(qmFilePath)) { - app.installTranslator(translator); - } else { - translator->deleteLater(); - } - } - // Register QML Type. const char *uri = "Cutefish.FileManager"; qmlRegisterType(uri, 1, 0, "PlacesModel"); @@ -82,57 +54,6 @@ int main(int argc, char *argv[]) qmlRegisterAnonymousType(uri, 1); #endif - QCommandLineParser parser; - parser.setApplicationDescription(QStringLiteral("File Manager")); - parser.addHelpOption(); - - parser.addPositionalArgument("files", "Files", "[FILE1, FILE2,...]"); - - QCommandLineOption desktopOption(QStringList() << "d" << "desktop" << "Desktop Mode"); - parser.addOption(desktopOption); - - QCommandLineOption emptyTrashOption(QStringList() << "e" << "empty-trash" << "Empty Trash"); - parser.addOption(emptyTrashOption); - - parser.process(app); - - if (parser.isSet(desktopOption)) { - app.setApplicationName("cutefish-desktop"); - Desktop desktop; - return app.exec(); - } else if (parser.isSet(emptyTrashOption)) { - // Empty Dialog - QQmlApplicationEngine engine; - const QUrl url(QStringLiteral("qrc:/qml/Dialogs/EmptyTrashDialog.qml")); - engine.load(url); - return app.exec(); - } - - QQmlApplicationEngine engine; - const QUrl url(QStringLiteral("qrc:/qml/main.qml")); - QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, - &app, [url](QObject *obj, const QUrl &objUrl) { - if (!obj && url == objUrl) - QCoreApplication::exit(-1); - }, Qt::QueuedConnection); - - // Handle urls - if (!parser.positionalArguments().isEmpty()) { - QStringList arguments = parser.positionalArguments(); - QUrl url(arguments.first()); - if (!url.isValid()) - url = QUrl::fromLocalFile(arguments.first()); - - if (url.isValid()) - engine.rootContext()->setContextProperty("arg", arguments.first()); - else - engine.rootContext()->setContextProperty("arg", ""); - } else { - engine.rootContext()->setContextProperty("arg", ""); - } - - engine.load(url); - engine.addImageProvider("thumbnailer", new ThumbnailProvider()); - - return app.exec(); + Application app(argc, argv); + return app.run(); } diff --git a/qml/FolderPage.qml b/qml/FolderPage.qml index 7a81225..11e214f 100644 --- a/qml/FolderPage.qml +++ b/qml/FolderPage.qml @@ -109,15 +109,15 @@ Item { id: _background anchors.fill: parent anchors.rightMargin: 1 - radius: FishUI.Theme.smallRadius + radius: FishUI.Theme.mediumRadius color: FishUI.Theme.secondBackgroundColor Rectangle { id: _topRightRect anchors.right: parent.right anchors.top: parent.top - height: FishUI.Theme.smallRadius - width: FishUI.Theme.smallRadius + height: FishUI.Theme.mediumRadius + width: FishUI.Theme.mediumRadius color: FishUI.Theme.secondBackgroundColor } @@ -125,8 +125,8 @@ Item { id: _bottomLeftRect anchors.left: parent.left anchors.bottom: parent.bottom - height: FishUI.Theme.smallRadius - width: FishUI.Theme.smallRadius + height: FishUI.Theme.mediumRadius + width: FishUI.Theme.mediumRadius color: FishUI.Theme.secondBackgroundColor } } diff --git a/qml/SideBar.qml b/qml/SideBar.qml index d45e89e..d47419b 100644 --- a/qml/SideBar.qml +++ b/qml/SideBar.qml @@ -56,7 +56,7 @@ ListView { highlightResizeDuration : 0 highlight: Rectangle { - radius: FishUI.Theme.smallRadius + radius: FishUI.Theme.mediumRadius color: FishUI.Theme.highlightColor } diff --git a/thumbnailer/thumbnailprovider.cpp b/thumbnailer/thumbnailprovider.cpp index c76bcce..6f48b46 100644 --- a/thumbnailer/thumbnailprovider.cpp +++ b/thumbnailer/thumbnailprovider.cpp @@ -34,8 +34,6 @@ QImage ThumbnailProvider::requestImage(const QString &id, QSize *size, const QSi *size = requestedSize; QString f = id; - qDebug() << id << QFile::exists(f.replace("file://", "")); - QString thumbnail = ThumbnailCache::self()->requestThumbnail(id, requestedSize); if (!thumbnail.isEmpty()) { diff --git a/window.cpp b/window.cpp new file mode 100644 index 0000000..13747ec --- /dev/null +++ b/window.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2021 CutefishOS Team. + * + * Author: Reion Wong + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "window.h" +#include +#include +#include + +Window::Window(QObject *parent) + : QQmlApplicationEngine(parent) +{ +} + +void Window::load(const QUrl &url) +{ + QQmlApplicationEngine::load(url); + + QQuickWindow *w = qobject_cast(rootObjects().first()); + + if (w) + w->installEventFilter(this); +} + +bool Window::eventFilter(QObject *obj, QEvent *e) +{ + if (e->type() == QEvent::Close) { + clearComponentCache(); + deleteLater(); + e->accept(); + } + + return QObject::eventFilter(obj, e); +} diff --git a/window.h b/window.h new file mode 100644 index 0000000..e4c30de --- /dev/null +++ b/window.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2021 CutefishOS Team. + * + * Author: Reion Wong + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +class Window : public QQmlApplicationEngine +{ + Q_OBJECT + +public: + explicit Window(QObject *parent = nullptr); + + void load(const QUrl &url); + +protected: + bool eventFilter(QObject *o, QEvent *e); +}; + +#endif // WINDOW_H