Index: src/CMakeLists.txt =================================================================== --- src/CMakeLists.txt +++ src/CMakeLists.txt @@ -304,6 +304,22 @@ kf5_add_kdeinit_executable(dolphin ${dolphin_SRCS}) +if (APPLE) + # own plist template + set_target_properties (dolphin PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/MacOSXBundleInfo.plist.in) + # the MacOSX bundle display name property (CFBundleDisplayName) is not currently supported by cmake, + # so has to be set for all targets in this cmake file + set(MACOSX_BUNDLE_DISPLAY_NAME Okular5) + set_target_properties(dolphin PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Dolphin") + set_target_properties(dolphin PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Dolphin5") + set_target_properties(dolphin PROPERTIES MACOSX_BUNDLE_DISPLAY_NAME "Dolphin5") + set_target_properties(dolphin PROPERTIES MACOSX_BUNDLE_INFO_STRING "Dolphin, KDE's file manager focusing on usability") + set_target_properties(dolphin PROPERTIES MACOSX_BUNDLE_LONG_VERSION_STRING "Dolphin ${KDE_APPLICATIONS_VERSION}") + set_target_properties(dolphin PROPERTIES MACOSX_BUNDLE_SHORT_VERSION_STRING "${KDE_APPLICATIONS_VERSION_MAJOR}.${KDE_APPLICATIONS_VERSION_MINOR}") + set_target_properties(dolphin PROPERTIES MACOSX_BUNDLE_BUNDLE_VERSION "${KDE_APPLICATIONS_VERSION}") + set_target_properties(dolphin PROPERTIES MACOSX_BUNDLE_COPYRIGHT "2002-2020 The Dolphin Authors") +endif (APPLE) + target_link_libraries(kdeinit_dolphin PUBLIC dolphinprivate Index: src/MacOSXBundleInfo.plist.in =================================================================== --- /dev/null +++ src/MacOSXBundleInfo.plist.in @@ -0,0 +1,73 @@ + + + + + NSPrincipalClass + NSApplication + NSHighResolutionCapable + True + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${MACOSX_BUNDLE_EXECUTABLE_NAME} + CFBundleGetInfoString + ${MACOSX_BUNDLE_INFO_STRING} + CFBundleIconFile + ${MACOSX_BUNDLE_ICON_FILE} + CFBundleIdentifier + ${MACOSX_BUNDLE_GUI_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleLongVersionString + ${MACOSX_BUNDLE_LONG_VERSION_STRING} + CFBundleName + ${MACOSX_BUNDLE_BUNDLE_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + ${MACOSX_BUNDLE_SHORT_VERSION_STRING} + CFBundleSignature + ???? + CFBundleVersion + ${MACOSX_BUNDLE_BUNDLE_VERSION} + CSResourcesFileMapped + + LSRequiresCarbon + + NSHumanReadableCopyright + ${MACOSX_BUNDLE_COPYRIGHT} + CFBundleDocumentTypes + + + CFBundleTypeName + Folder + CFBundleTypeOSTypes + + fold + + CFBundleTypeRole + Editor + + + CFBundleTypeName + Volume + CFBundleTypeOSTypes + + disk + + CFBundleTypeRole + Editor + + + CFBundleTypeExtensions + + * + + CFBundleTypeName + NSStringPboardType + CFBundleTypeRole + Viewer + + + + Index: src/dolphinmainwindow.cpp =================================================================== --- src/dolphinmainwindow.cpp +++ src/dolphinmainwindow.cpp @@ -922,7 +922,11 @@ QUrl urlA = items.at(0).url(); QUrl urlB = items.at(1).url(); +#ifdef Q_OS_MACOS + QString command(QStringLiteral("open -a kompare --args -c \"")); +#else QString command(QStringLiteral("kompare -c \"")); +#endif command.append(urlA.toDisplayString(QUrl::PreferLocalFile)); command.append("\" \""); command.append(urlB.toDisplayString(QUrl::PreferLocalFile)); Index: src/dolphinpart.cpp =================================================================== --- src/dolphinpart.cpp +++ src/dolphinpart.cpp @@ -547,7 +547,11 @@ if (!(actions.isEmpty())) { actions.first()->trigger(); } else { +#ifdef Q_OS_MACOS + KIO::CommandLauncherJob *job = new KIO::CommandLauncherJob(QStringLiteral("open -a kfind --args"), {url().toString()}, this); +#else KIO::CommandLauncherJob *job = new KIO::CommandLauncherJob(QStringLiteral("kfind"), {url().toString()}, this); +#endif job->setDesktopName(QStringLiteral("org.kde.kfind")); job->setUiDelegate(new KDialogJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, widget())); job->start(); Index: src/dolphintabwidget.cpp =================================================================== --- src/dolphintabwidget.cpp +++ src/dolphintabwidget.cpp @@ -334,7 +334,7 @@ } args << QStringLiteral("--new-window"); - KIO::CommandLauncherJob *job = new KIO::CommandLauncherJob("dolphin", args, this); + KIO::CommandLauncherJob *job = new KIO::CommandLauncherJob(QCoreApplication::applicationFilePath(), args, this); job->setDesktopName(QStringLiteral("org.kde.dolphin")); job->start(); Index: src/global.cpp =================================================================== --- src/global.cpp +++ src/global.cpp @@ -53,7 +53,7 @@ void Dolphin::openNewWindow(const QList &urls, QWidget *window, const OpenNewWindowFlags &flags) { - QString command = QStringLiteral("dolphin --new-window"); + QString command = QStringLiteral("%1 --new-window").arg(QCoreApplication::applicationFilePath()); if (flags.testFlag(OpenNewWindowFlag::Select)) { command.append(QLatin1String(" --select")); Index: src/main.cpp =================================================================== --- src/main.cpp +++ src/main.cpp @@ -44,6 +44,52 @@ #endif #include +#ifdef Q_OS_MACOS +class OpenFileEventHandler : public QObject +{ + Q_OBJECT +public: + OpenFileEventHandler(QApplication *parent) + : QObject(parent) + { + parent->installEventFilter(this); + } + + bool eventFilter(QObject *obj, QEvent *event) override + { + if (event->type() == QEvent::FileOpen) { + QFileOpenEvent *openEvent = static_cast(event); + qCWarning(DolphinDebug) << "File open event:" << openEvent->url(); + urls.append(Dolphin::validateUris(QStringList(openEvent->file()))); + if (mainWindow && !urls.isEmpty()) { + if (GeneralSettings::openExternallyCalledFolderInNewTab()) { + const auto serviceName = QStringLiteral("org.kde.dolphin-%1").arg(QCoreApplication::applicationPid()); + if (!Dolphin::attachToExistingInstance(urls, false, false, serviceName)) { + qCWarning(DolphinDebug) << "Failed to open" << urls; + } + } else { + Dolphin::openNewWindow(urls, mainWindow); + } + urls.clear(); + } + return true; + } + return QObject::eventFilter(obj, event); + } + + QList popUrls() + { + const auto ret = urls; + urls.clear(); + return ret; + } + + DolphinMainWindow* mainWindow = nullptr; + QList urls; +}; + +#endif + extern "C" Q_DECL_EXPORT int kdemain(int argc, char **argv) { #ifndef Q_OS_WIN @@ -69,6 +115,10 @@ app.setWindowIcon(QIcon::fromTheme(QStringLiteral("system-file-manager"), app.windowIcon())); KCrash::initialize(); +#ifdef Q_OS_MACOS + // start processing Mac OS FileOpenEvents + const auto openEventHandler = new OpenFileEventHandler(&app); +#endif Kdelibs4ConfigMigrator migrate(QStringLiteral("dolphin")); migrate.setConfigFiles(QStringList() << QStringLiteral("dolphinrc")); @@ -144,16 +194,42 @@ KDBusService dolphinDBusService; DBusInterface interface; interface.setAsDaemon(); +#ifdef Q_OS_MACOS + // we probably shouldn't be accepting requests via Apple's LaunchServices + app.removeEventFilter(openEventHandler); +#endif return app.exec(); } +#ifdef Q_OS_MACOS + // Get the file open events that have been queued; a priori those are only + // for the documents or folders with which the user launched us. Any + // such events coming in from now until we set mainWindow will get lost. + QCoreApplication::sendPostedEvents(&app, QEvent::FileOpen); + QCoreApplication::processEvents(); + if (!openEventHandler->urls.isEmpty()) { + urls.append(openEventHandler->popUrls()); + } +#endif + if (!parser.isSet(QStringLiteral("new-window"))) { if (Dolphin::attachToExistingInstance(urls, openFiles, splitView)) { // Successfully attached to existing instance of Dolphin return 0; } } + // set up the D-Bus interface now, so we can activate normal file open event + // handling (on Mac) as soon as possible. + KDBusService dolphinDBusService; + DBusInterface interface; + + DolphinMainWindow* mainWindow = new DolphinMainWindow(); + +#ifdef Q_OS_MACOS + openEventHandler->mainWindow = mainWindow; +#endif + if (urls.isEmpty()) { // We need at least one URL to open Dolphin urls.append(Dolphin::homeUrl()); @@ -164,8 +240,6 @@ urls.append(urls.last()); } - DolphinMainWindow* mainWindow = new DolphinMainWindow(); - if (openFiles) { mainWindow->openFiles(urls, splitView); } else { @@ -183,8 +257,7 @@ } } - KDBusService dolphinDBusService; - DBusInterface interface; - return app.exec(); // krazy:exclude=crash; } + +#include "main.moc" Index: src/settings/services/servicemenuinstaller/CMakeLists.txt =================================================================== --- src/settings/services/servicemenuinstaller/CMakeLists.txt +++ src/settings/services/servicemenuinstaller/CMakeLists.txt @@ -1,7 +1,9 @@ +include(ECMMarkNonGuiExecutable) remove_definitions(-DTRANSLATION_DOMAIN=\"dolphin\") add_definitions(-DTRANSLATION_DOMAIN=\"dolphin_servicemenuinstaller\") add_executable(servicemenuinstaller servicemenuinstaller.cpp) +ecm_mark_nongui_executable(servicemenuinstaller) target_link_libraries(servicemenuinstaller PRIVATE Qt5::Core Qt5::Gui