diff --git a/indicator/CMakeLists.txt b/indicator/CMakeLists.txt
index 6e86e3641..8f46e5143 100644
--- a/indicator/CMakeLists.txt
+++ b/indicator/CMakeLists.txt
@@ -13,7 +13,7 @@ ecm_add_app_icon(indicator_SRCS ICONS
if (WIN32)
list(APPEND indicator_SRCS indicatorhelper_win.cpp)
elseif (APPLE)
- list(APPEND indicator_SRCS indicatorhelper_mac.cpp)
+ list(APPEND indicator_SRCS indicatorhelper_mac.cpp serviceregister_mac.mm)
else ()
list(APPEND indicator_SRCS indicatorhelper.cpp)
endif()
@@ -26,6 +26,8 @@ if (WIN32)
endif()
if (APPLE)
+# Apple frameworks
+target_link_libraries(kdeconnect-indicator "-framework AppKit")
# Apple app package
set_target_properties(kdeconnect-indicator PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist)
set_target_properties(kdeconnect-indicator PROPERTIES
diff --git a/indicator/Info.plist b/indicator/Info.plist
index d734b263b..4a08059b4 100644
--- a/indicator/Info.plist
+++ b/indicator/Info.plist
@@ -34,5 +34,38 @@
1
NSHighResolutionCapable
True
+ NSServices
+
+
+ NSBackgroundColorName
+ background
+ NSIconName
+ NSActionTemplate
+ NSMenuItem
+
+ default
+ Send File via KDE Connect
+
+ NSMessage
+ sendViaKDEConnect
+ NSPortName
+ SendViaKDEConnect
+ NSRequiredContext
+
+ NSApplicationIdentifier
+ com.apple.finder
+
+ NSRequiredContext
+
+ NSTextContent
+ FilePath
+
+ NSSendTypes
+
+ NSFilenamesPboardType
+ public.plain-text
+
+
+
diff --git a/indicator/indicatorhelper_mac.cpp b/indicator/indicatorhelper_mac.cpp
index 5ad613df3..4e5fc3f19 100644
--- a/indicator/indicatorhelper_mac.cpp
+++ b/indicator/indicatorhelper_mac.cpp
@@ -32,9 +32,12 @@
#include "indicatorhelper.h"
+#include "serviceregister_mac.h"
IndicatorHelper::IndicatorHelper()
{
+ registerServices();
+
QIcon kdeconnectIcon = QIcon::fromTheme(QStringLiteral("kdeconnect"));
QPixmap splashPixmap(kdeconnectIcon.pixmap(256, 256));
diff --git a/indicator/serviceregister_mac.h b/indicator/serviceregister_mac.h
new file mode 100644
index 000000000..f02eb0fd6
--- /dev/null
+++ b/indicator/serviceregister_mac.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2020 Weixuan XIAO
+ *
+ * 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 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * 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 SERVICE_REGISTER_H
+#define SERVICE_REGISTER_H
+
+void registerServices();
+
+#endif
diff --git a/indicator/serviceregister_mac.mm b/indicator/serviceregister_mac.mm
new file mode 100644
index 000000000..04368fe21
--- /dev/null
+++ b/indicator/serviceregister_mac.mm
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2020 Weixuan XIAO
+ *
+ * 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 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * 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 .
+ */
+
+#import
+#import
+
+#include
+#include
+#include
+
+@interface KDEConnectSendFileService : NSObject
+- (void)sendViaKDEConnect:(NSPasteboard *)pboard userData:(NSString *)userData error:(NSString **)error;
+@end
+
+static KDEConnectSendFileService *sendFileService = nil;
+
+static void cleanup_service()
+{
+ if (sendFileService != nil)
+ [sendFileService release];
+
+ sendFileService = nil;
+}
+
+void registerServices() {
+ NSLog(@"Registering KDE Connect Send File Service");
+ KDEConnectSendFileService *sendFileService = [[KDEConnectSendFileService alloc] init];
+ qAddPostRoutine(cleanup_service); // Remove after quit
+
+ NSRegisterServicesProvider(sendFileService, @"SendViaKDEConnect");
+
+ NSLog(@"KDE Connect Send File Service registered");
+}
+
+@implementation KDEConnectSendFileService
+
+- (void)sendViaKDEConnect:(NSPasteboard *)pboard userData:(NSString *)userData error:(NSString **)error {
+ Q_UNUSED(userData);
+ Q_UNUSED(error);
+
+ NSAlert *alert = nil;
+ // NSPasteboardTypeFileURL is first introduced in macOS 13, avoid to use it now
+ NSArray *filePathArray = [pboard propertyListForType:NSFilenamesPboardType];
+ for (NSString *path in filePathArray) {
+ BOOL isDirectory = NO;
+ if ([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDirectory]) {
+ if (!isDirectory) {
+ if (QFile::exists(QCoreApplication::applicationDirPath() + QStringLiteral("/kdeconnect-handler"))) {
+ QProcess kdeconnect_handler;
+ kdeconnect_handler.setProgram(QCoreApplication::applicationDirPath() + QStringLiteral("/kdeconnect-handler"));
+ kdeconnect_handler.setArguments({QString::fromNSString(path)});
+ kdeconnect_handler.startDetached();
+ } else {
+ alert = [[NSAlert alloc] init];
+ [alert setInformativeText:@"Cannot find kdeconnect-handler"];
+ }
+ } else {
+ alert = [[NSAlert alloc] init];
+ [alert setInformativeText:@"Cannot share a directory"];
+ }
+ }
+ break; // Now we only support single file sharing
+ }
+
+ if ([filePathArray count] < 1) {
+ alert = [[NSAlert alloc] init];
+ [alert setInformativeText:@"Cannot share selected item"];
+ }
+
+ if (alert) {
+ [alert setMessageText:@"Share file failed"];
+ [alert addButtonWithTitle:@"OK"];
+ [alert setAlertStyle:NSAlertStyleCritical];
+ [alert runModal];
+ [alert release];
+ }
+}
+
+@end
\ No newline at end of file