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
@@ -931,7 +931,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(KShell::quoteArgs(QCoreApplication::applicationFilePath()), args, this);
job->setDesktopName(QStringLiteral("org.kde.dolphin"));
job->start();
Index: src/global.cpp
===================================================================
--- src/global.cpp
+++ src/global.cpp
@@ -27,6 +27,7 @@
#include
#include
#include
+#include
#include
#include
@@ -53,7 +54,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(KShell::quoteArg(QCoreApplication::applicationFilePath()));
if (flags.testFlag(OpenNewWindowFlag::Select)) {
command.append(QLatin1String(" --select"));
Index: src/main.cpp
===================================================================
--- src/main.cpp
+++ src/main.cpp
@@ -45,6 +45,59 @@
#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);
+ qCDebug(DolphinDebug) << "File open event:" << openEvent->url();
+ m_urls.append(Dolphin::validateUris(QStringList(openEvent->file())));
+ if (m_mainWindow && !m_urls.isEmpty()) {
+ if (GeneralSettings::openExternallyCalledFolderInNewTab()) {
+ const auto serviceName = QStringLiteral("org.kde.dolphin-%1").arg(QCoreApplication::applicationPid());
+ if (!Dolphin::attachToExistingInstance(m_urls, false, false, serviceName)) {
+ qCWarning(DolphinDebug) << "Failed to open" << m_urls;
+ }
+ } else {
+ Dolphin::openNewWindow(m_urls, m_mainWindow);
+ }
+ m_urls.clear();
+ }
+ return true;
+ }
+ return QObject::eventFilter(obj, event);
+ }
+
+ QList popUrls()
+ {
+ const auto ret = m_urls;
+ m_urls.clear();
+ return ret;
+ }
+
+
+ void setMainWindow(DolphinMainWindow *w)
+ {
+ m_mainWindow = w;
+ }
+
+private:
+ DolphinMainWindow* m_mainWindow = nullptr;
+ QList m_urls;
+};
+
+#endif
+
extern "C" Q_DECL_EXPORT int kdemain(int argc, char **argv)
{
#ifndef Q_OS_WIN
@@ -70,6 +123,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"));
@@ -140,24 +197,45 @@
const bool openFiles = parser.isSet(QStringLiteral("select"));
const QStringList args = parser.positionalArguments();
QList urls = Dolphin::validateUris(args);
- // We later mutate urls, so we need to store if it was empty originally
- const bool startedWithURLs = !urls.isEmpty();
-
if (parser.isSet(QStringLiteral("daemon"))) {
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. This has to
+ // be done in "jit" fashion so we don't drop any events. Any such events \
+ // coming in from now until we call setMainWindow will get lost.
+ // Since D11382 we also need to get the startup urls before setting startedWithURLs.
+ QCoreApplication::sendPostedEvents(&app, QEvent::FileOpen);
+ QCoreApplication::processEvents();
+ urls.append(openEventHandler->popUrls());
+#endif
+ // We later mutate urls, so we need to store if it was empty originally
+ const bool startedWithURLs = !urls.isEmpty();
+
if (!parser.isSet(QStringLiteral("new-window"))) {
if (Dolphin::attachToExistingInstance(urls, openFiles, splitView)) {
// Successfully attached to existing instance of Dolphin
return 0;
}
}
+ // Open the main window now, so we can activate normal file open event
+ // handling (on Mac) as soon as possible.
+ DolphinMainWindow* mainWindow = new DolphinMainWindow();
+#ifdef Q_OS_MACOS
+ openEventHandler->setMainWindow(mainWindow);
+#endif
+
if (!startedWithURLs) {
// We need at least one URL to open Dolphin
urls.append(Dolphin::homeUrl());
@@ -168,8 +246,6 @@
urls.append(urls.last());
}
- DolphinMainWindow* mainWindow = new DolphinMainWindow();
-
if (openFiles) {
mainWindow->openFiles(urls, splitView);
} else {
@@ -205,3 +281,5 @@
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