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