diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -297,11 +297,12 @@ kf5_add_kdeinit_executable(dolphin ${dolphin_SRCS}) - +find_package(KF5WindowSystem) target_link_libraries(kdeinit_dolphin PRIVATE dolphinstatic dolphinprivate KF5::Crash + KF5::WindowSystem ) include(DbusInterfaceMacros) diff --git a/src/dbusinterface.cpp b/src/dbusinterface.cpp --- a/src/dbusinterface.cpp +++ b/src/dbusinterface.cpp @@ -41,7 +41,7 @@ if (urls.isEmpty()) { return; } - Dolphin::openNewWindow(urls); + Dolphin::openNewWindow(urls, nullptr, Dolphin::OpenNewWindowFlag::NoForce); } void DBusInterface::ShowItems(const QStringList& uriList, const QString& startUpId) @@ -51,7 +51,8 @@ if (urls.isEmpty()) { return; } - Dolphin::openNewWindow(urls, nullptr, Dolphin::OpenNewWindowFlag::Select); + const auto flags = Dolphin::OpenNewWindowFlags(Dolphin::OpenNewWindowFlag::Select) | Dolphin::OpenNewWindowFlag::NoForce; + Dolphin::openNewWindow(urls, nullptr, flags); } void DBusInterface::ShowItemProperties(const QStringList& uriList, const QString& startUpId) diff --git a/src/global.h b/src/global.h --- a/src/global.h +++ b/src/global.h @@ -25,15 +25,18 @@ namespace Dolphin { QList validateUris(const QStringList& uriList); + QList validateUris(const QStringList& uriList, const QString& currentDir); /** * Returns the home url which is defined in General Settings */ QUrl homeUrl(); enum class OpenNewWindowFlag { None = 0, - Select = 1<<1 + Select = 1<<1, // --select + Split = 1<<2, // --split + NoForce = 1<<3 // Don't specify --new-window which is implicit with other options }; Q_DECLARE_FLAGS(OpenNewWindowFlags, OpenNewWindowFlag) diff --git a/src/global.cpp b/src/global.cpp --- a/src/global.cpp +++ b/src/global.cpp @@ -27,9 +27,8 @@ #include #include -QList Dolphin::validateUris(const QStringList& uriList) +QList Dolphin::validateUris(const QStringList& uriList, const QString& currentDir) { - const QString currentDir = QDir::currentPath(); QList urls; foreach (const QString& str, uriList) { const QUrl url = QUrl::fromUserInput(str, currentDir, QUrl::AssumeLocalFile); @@ -42,6 +41,12 @@ return urls; } +QList Dolphin::validateUris(const QStringList& uriList) +{ + const QString currentDir = QDir::currentPath(); + return validateUris(uriList, currentDir); +} + QUrl Dolphin::homeUrl() { return QUrl::fromUserInput(GeneralSettings::homeUrl(), QString(), QUrl::AssumeLocalFile); @@ -55,6 +60,14 @@ command.append(QLatin1String(" --select")); } + if (flags.testFlag(OpenNewWindowFlag::Split)) { + command.append(QLatin1String(" --split")); + } + + if (!flags.testFlag(OpenNewWindowFlag::NoForce)) { + command.append(QLatin1String(" --new-window")); + } + if (!urls.isEmpty()) { command.append(QLatin1String(" %U")); } diff --git a/src/main.cpp b/src/main.cpp --- a/src/main.cpp +++ b/src/main.cpp @@ -31,15 +31,55 @@ #include #include #include +#include +#include #include #include +#include #ifndef Q_OS_WIN #include #endif #include +void handleCommandLine(DolphinMainWindow* mainWindow, const QCommandLineParser& parser, const QString& workingDirectory) +{ + QList urls = Dolphin::validateUris(parser.positionalArguments(), workingDirectory); + + if (urls.isEmpty()) { + // We need at least one URL to open Dolphin + urls.append(Dolphin::homeUrl()); + } + + const bool splitView = parser.isSet(QStringLiteral("split")) || GeneralSettings::splitView(); + if (splitView && urls.size() < 2) { + // Split view does only make sense if we have at least 2 URLs + urls.append(urls.last()); + } + + if (mainWindow) { + if (parser.isSet(QStringLiteral("select"))) { + mainWindow->openFiles(urls, splitView); + } else { + mainWindow->openDirectories(urls, splitView); + } + + mainWindow->show(); + } else { // daemon mode + Dolphin::OpenNewWindowFlags flags = Dolphin::OpenNewWindowFlag::NoForce; + if (splitView) { + flags |= Dolphin::OpenNewWindowFlag::Split; + } + if (parser.isSet(QStringLiteral("select"))) { + flags |= Dolphin::OpenNewWindowFlag::Select; + } + + Dolphin::openNewWindow(urls, nullptr, flags); + } +} + + extern "C" Q_DECL_EXPORT int kdemain(int argc, char **argv) { #ifndef Q_OS_WIN @@ -112,49 +152,52 @@ KAboutData::setApplicationData(aboutData); - KDBusService dolphinDBusService; - DBusInterface interface; - QCommandLineParser parser; aboutData.setupCommandLine(&parser); // command line options parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("select"), i18nc("@info:shell", "The files and folders passed as arguments " "will be selected."))); parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("split"), i18nc("@info:shell", "Dolphin will get started with a split view."))); parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("daemon"), i18nc("@info:shell", "Start Dolphin Daemon (only required for DBus Interface)"))); + parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("new-window"), i18nc("@info:shell", "Open as a new window even if dolphin is configured to use a unique windows."))); parser.addPositionalArgument(QStringLiteral("+[Url]"), i18nc("@info:shell", "Document to open")); parser.process(app); aboutData.processCommandLine(&parser); - if (parser.isSet(QStringLiteral("daemon"))) { - return app.exec(); - } - - const QStringList args = parser.positionalArguments(); - QList urls = Dolphin::validateUris(args); - - if (urls.isEmpty()) { - // We need at least one URL to open Dolphin - urls.append(Dolphin::homeUrl()); + auto startupMode = KDBusService::Multiple; + if (GeneralSettings::uniqueWindow() + && !parser.isSet(QStringLiteral("new-window")) + && !parser.isSet(QStringLiteral("daemon"))) { + startupMode = KDBusService::Unique; } + KDBusService dolphinDBusService(startupMode); - const bool splitView = parser.isSet(QStringLiteral("split")) || GeneralSettings::splitView(); - if (splitView && urls.size() < 2) { - // Split view does only make sense if we have at least 2 URLs - urls.append(urls.last()); - } + DBusInterface interface; - DolphinMainWindow* mainWindow = new DolphinMainWindow(); + // Don't create the main window if started in daemon mode + // But, declare it beforehand so we can reference it in the activateRequested slot + DolphinMainWindow* mainWindow = nullptr; + + QObject::connect(&dolphinDBusService, &KDBusService::activateRequested, + [&](const QStringList& arguments, const QString &workingDirectory) { + parser.parse(arguments); + handleCommandLine(mainWindow, parser, workingDirectory); + // If not a daemon + if (mainWindow) { + // Terminate startup notification and activate the mainwindow: + KStartupInfo::setNewStartupId(mainWindow, KStartupInfo::startupId()); + KWindowSystem::forceActiveWindow(mainWindow->winId()); + } + }); - if (parser.isSet(QStringLiteral("select"))) { - mainWindow->openFiles(urls, splitView); - } else { - mainWindow->openDirectories(urls, splitView); + if (parser.isSet(QStringLiteral("daemon"))) { + return app.exec(); } - mainWindow->show(); + mainWindow = new DolphinMainWindow(); + handleCommandLine(mainWindow, parser, QDir::currentPath()); if (app.isSessionRestored()) { const QString className = KXmlGuiWindow::classNameOfToplevel(1); diff --git a/src/settings/dolphin_generalsettings.kcfg b/src/settings/dolphin_generalsettings.kcfg --- a/src/settings/dolphin_generalsettings.kcfg +++ b/src/settings/dolphin_generalsettings.kcfg @@ -62,6 +62,10 @@ true + + + false + true diff --git a/src/settings/startup/startupsettingspage.h b/src/settings/startup/startupsettingspage.h --- a/src/settings/startup/startupsettingspage.h +++ b/src/settings/startup/startupsettingspage.h @@ -64,6 +64,7 @@ QCheckBox* m_showFullPath; QCheckBox* m_filterBar; QCheckBox* m_showFullPathInTitlebar; + QCheckBox* m_uniqueWindow; }; #endif diff --git a/src/settings/startup/startupsettingspage.cpp b/src/settings/startup/startupsettingspage.cpp --- a/src/settings/startup/startupsettingspage.cpp +++ b/src/settings/startup/startupsettingspage.cpp @@ -43,7 +43,8 @@ m_editableUrl(nullptr), m_showFullPath(nullptr), m_filterBar(nullptr), - m_showFullPathInTitlebar(nullptr) + m_showFullPathInTitlebar(nullptr), + m_uniqueWindow(nullptr) { QFormLayout* topLayout = new QFormLayout(this); @@ -100,7 +101,8 @@ topLayout->addRow(QString(), m_filterBar); m_showFullPathInTitlebar = new QCheckBox(i18nc("@option:check Startup Settings", "Show full path in title bar")); topLayout->addRow(QString(), m_showFullPathInTitlebar); - + m_uniqueWindow = new QCheckBox(i18nc("@option:check Startup Settings", "Keep only one window open")); + topLayout->addRow(QString(), m_uniqueWindow); loadSettings(); @@ -110,6 +112,7 @@ connect(m_showFullPath, &QCheckBox::toggled, this, &StartupSettingsPage::slotSettingsChanged); connect(m_filterBar, &QCheckBox::toggled, this, &StartupSettingsPage::slotSettingsChanged); connect(m_showFullPathInTitlebar, &QCheckBox::toggled, this, &StartupSettingsPage::slotSettingsChanged); + connect(m_uniqueWindow, &QCheckBox::toggled, this, &StartupSettingsPage::slotSettingsChanged); } StartupSettingsPage::~StartupSettingsPage() @@ -133,6 +136,7 @@ settings->setShowFullPath(m_showFullPath->isChecked()); settings->setFilterBar(m_filterBar->isChecked()); settings->setShowFullPathInTitlebar(m_showFullPathInTitlebar->isChecked()); + settings->setUniqueWindow(m_uniqueWindow->isChecked()); settings->save(); } @@ -183,4 +187,5 @@ m_showFullPath->setChecked(GeneralSettings::showFullPath()); m_filterBar->setChecked(GeneralSettings::filterBar()); m_showFullPathInTitlebar->setChecked(GeneralSettings::showFullPathInTitlebar()); + m_uniqueWindow->setChecked(GeneralSettings::uniqueWindow()); }