Improve startup speed and use single instance process

This commit is contained in:
reionwong 2021-09-26 19:23:54 +08:00
parent 8418faf167
commit 6d73bb234a
10 changed files with 304 additions and 90 deletions

View file

@ -18,8 +18,14 @@ find_package(KF5KIO)
find_package(KF5Solid) find_package(KF5Solid)
find_package(KF5WindowSystem) find_package(KF5WindowSystem)
qt5_add_dbus_adaptor(DBUS_SOURCES
com.cutefish.FileManager.xml
application.h Application)
add_executable(cutefish-filemanager add_executable(cutefish-filemanager
main.cpp main.cpp
application.cpp
window.cpp
model/foldermodel.cpp model/foldermodel.cpp
model/placesmodel.cpp model/placesmodel.cpp
model/placesitem.cpp model/placesitem.cpp
@ -56,6 +62,8 @@ add_executable(cutefish-filemanager
desktopiconprovider.cpp desktopiconprovider.cpp
qml.qrc qml.qrc
${DBUS_SOURCES}
) )
target_link_libraries(cutefish-filemanager target_link_libraries(cutefish-filemanager

143
application.cpp Normal file
View file

@ -0,0 +1,143 @@
/*
* Copyright (C) 2021 CutefishOS Team.
*
* Author: Reion Wong <reion@cutefishos.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "application.h"
#include "window.h"
#include "desktop/desktop.h"
#include "thumbnailer/thumbnailprovider.h"
#include "filemanageradaptor.h"
#include <QCommandLineParser>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QDBusConnection>
#include <QPixmapCache>
#include <QTranslator>
#include <QIcon>
#include <QDir>
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;
}

48
application.h Normal file
View file

@ -0,0 +1,48 @@
/*
* Copyright (C) 2021 CutefishOS Team.
*
* Author: Reion Wong <reion@cutefishos.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef APPLICATION_H
#define APPLICATION_H
#include <QApplication>
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

View file

@ -0,0 +1,9 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="com.cutefish.FileManager">
<method name="openFiles">
<arg type="as" direction="in"/>
</method>
<method name="emptyTrash"></method>
</interface>
</node>

View file

@ -17,15 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <QApplication> #include "application.h"
#include <QCommandLineParser>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QPixmapCache>
#include <QTranslator>
#include <QLocale>
#include "model/placesmodel.h" #include "model/placesmodel.h"
#include "model/foldermodel.h" #include "model/foldermodel.h"
#include "model/pathbarmodel.h" #include "model/pathbarmodel.h"
@ -39,31 +31,11 @@
#include "helper/fm.h" #include "helper/fm.h"
#include "helper/shortcut.h" #include "helper/shortcut.h"
#include "thumbnailer/thumbnailprovider.h"
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true); QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true);
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, 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. // Register QML Type.
const char *uri = "Cutefish.FileManager"; const char *uri = "Cutefish.FileManager";
qmlRegisterType<PlacesModel>(uri, 1, 0, "PlacesModel"); qmlRegisterType<PlacesModel>(uri, 1, 0, "PlacesModel");
@ -82,57 +54,6 @@ int main(int argc, char *argv[])
qmlRegisterAnonymousType<QAction>(uri, 1); qmlRegisterAnonymousType<QAction>(uri, 1);
#endif #endif
QCommandLineParser parser; Application app(argc, argv);
parser.setApplicationDescription(QStringLiteral("File Manager")); return app.run();
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();
} }

View file

@ -109,15 +109,15 @@ Item {
id: _background id: _background
anchors.fill: parent anchors.fill: parent
anchors.rightMargin: 1 anchors.rightMargin: 1
radius: FishUI.Theme.smallRadius radius: FishUI.Theme.mediumRadius
color: FishUI.Theme.secondBackgroundColor color: FishUI.Theme.secondBackgroundColor
Rectangle { Rectangle {
id: _topRightRect id: _topRightRect
anchors.right: parent.right anchors.right: parent.right
anchors.top: parent.top anchors.top: parent.top
height: FishUI.Theme.smallRadius height: FishUI.Theme.mediumRadius
width: FishUI.Theme.smallRadius width: FishUI.Theme.mediumRadius
color: FishUI.Theme.secondBackgroundColor color: FishUI.Theme.secondBackgroundColor
} }
@ -125,8 +125,8 @@ Item {
id: _bottomLeftRect id: _bottomLeftRect
anchors.left: parent.left anchors.left: parent.left
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
height: FishUI.Theme.smallRadius height: FishUI.Theme.mediumRadius
width: FishUI.Theme.smallRadius width: FishUI.Theme.mediumRadius
color: FishUI.Theme.secondBackgroundColor color: FishUI.Theme.secondBackgroundColor
} }
} }

View file

@ -56,7 +56,7 @@ ListView {
highlightResizeDuration : 0 highlightResizeDuration : 0
highlight: Rectangle { highlight: Rectangle {
radius: FishUI.Theme.smallRadius radius: FishUI.Theme.mediumRadius
color: FishUI.Theme.highlightColor color: FishUI.Theme.highlightColor
} }

View file

@ -34,8 +34,6 @@ QImage ThumbnailProvider::requestImage(const QString &id, QSize *size, const QSi
*size = requestedSize; *size = requestedSize;
QString f = id; QString f = id;
qDebug() << id << QFile::exists(f.replace("file://", ""));
QString thumbnail = ThumbnailCache::self()->requestThumbnail(id, requestedSize); QString thumbnail = ThumbnailCache::self()->requestThumbnail(id, requestedSize);
if (!thumbnail.isEmpty()) { if (!thumbnail.isEmpty()) {

49
window.cpp Normal file
View file

@ -0,0 +1,49 @@
/*
* Copyright (C) 2021 CutefishOS Team.
*
* Author: Reion Wong <reion@cutefishos.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "window.h"
#include <QEvent>
#include <QDebug>
#include <QQuickWindow>
Window::Window(QObject *parent)
: QQmlApplicationEngine(parent)
{
}
void Window::load(const QUrl &url)
{
QQmlApplicationEngine::load(url);
QQuickWindow *w = qobject_cast<QQuickWindow *>(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);
}

38
window.h Normal file
View file

@ -0,0 +1,38 @@
/*
* Copyright (C) 2021 CutefishOS Team.
*
* Author: Reion Wong <reion@cutefishos.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef WINDOW_H
#define WINDOW_H
#include <QQmlApplicationEngine>
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