Skip to content

Commit

Permalink
Merge pull request #5602 from nextcloud/bugfix/clean-up-systray-mac
Browse files Browse the repository at this point in the history
Clean up systray.mm (macOS)
  • Loading branch information
claucambra committed Jul 24, 2023
2 parents a727971 + 53cc438 commit 9727440
Showing 1 changed file with 74 additions and 74 deletions.
148 changes: 74 additions & 74 deletions src/gui/systray.mm
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,18 @@ void sendTalkReply(UNNotificationResponse *response, UNNotificationContent* cont
return;
}

UNTextInputNotificationResponse *textInputResponse = (UNTextInputNotificationResponse*)response;
UNTextInputNotificationResponse * const textInputResponse = (UNTextInputNotificationResponse*)response;

if (!textInputResponse) {
qCWarning(lcMacSystray()) << "Notification response was not a text input response."
<< "Can't send talk reply.";
return;
}

NSString *reply = textInputResponse.userText;
NSString *token = [content.userInfo objectForKey:@"token"];
NSString *account = [content.userInfo objectForKey:@"account"];
NSString *replyTo = [content.userInfo objectForKey:@"replyTo"];
NSString * const reply = textInputResponse.userText;
NSString * const token = [content.userInfo objectForKey:@"token"];
NSString * const account = [content.userInfo objectForKey:@"account"];
NSString * const replyTo = [content.userInfo objectForKey:@"replyTo"];

const auto qReply = QString::fromNSString(reply);
const auto qReplyTo = QString::fromNSString(replyTo);
Expand All @@ -58,7 +58,8 @@ void sendTalkReply(UNNotificationResponse *response, UNNotificationContent* cont
<< "Token:" << qToken
<< "Account:" << qAccount;

QPointer<OCC::TalkReply> talkReply = new OCC::TalkReply(accountState.data(), OCC::Systray::instance());
const auto talkReply = QSharedPointer<OCC::TalkReply>::create(
accountState.data(), OCC::Systray::instance());
talkReply->sendReplyMessage(qToken, qReply, qReplyTo);
}

Expand All @@ -83,12 +84,12 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center
}

- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler
{
qCDebug(lcMacSystray()) << "Received notification with category identifier:" << response.notification.request.content.categoryIdentifier
<< "and action identifier" << response.actionIdentifier;
UNNotificationContent* content = response.notification.request.content;
UNNotificationContent * const content = response.notification.request.content;
if ([content.categoryIdentifier isEqualToString:@"UPDATE"]) {

if ([response.actionIdentifier isEqualToString:@"DOWNLOAD_ACTION"] || [response.actionIdentifier isEqualToString:UNNotificationDefaultActionIdentifier]) {
Expand All @@ -112,13 +113,13 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center

double menuBarThickness()
{
const NSMenu *mainMenu = [[NSApplication sharedApplication] mainMenu];
NSMenu * const mainMenu = [[NSApplication sharedApplication] mainMenu];

if (mainMenu == nil) {
// Return this educated guess if something goes wrong.
// As of macOS 12.4 this will always return 22, even on notched Macbooks.
qCWarning(lcMacSystray) << "Got nil for main menu. Going with reasonable menu bar height guess.";
return [[NSStatusBar systemStatusBar] thickness];
return NSStatusBar.systemStatusBar.thickness;
}

return mainMenu.menuBarHeight;
Expand All @@ -127,85 +128,84 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center
// TODO: Get this to actually check for permissions
bool canOsXSendUserNotification()
{
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
UNUserNotificationCenter * const center = UNUserNotificationCenter.currentNotificationCenter;
return center != nil;
}

void registerNotificationCategories(const QString &localisedDownloadString) {
UNNotificationCategory* generalCategory = [UNNotificationCategory
categoryWithIdentifier:@"GENERAL"
actions:@[]
intentIdentifiers:@[]
options:UNNotificationCategoryOptionCustomDismissAction];
UNNotificationCategory * const generalCategory = [UNNotificationCategory
categoryWithIdentifier:@"GENERAL"
actions:@[]
intentIdentifiers:@[]
options:UNNotificationCategoryOptionCustomDismissAction];

// Create the custom actions for update notifications.
UNNotificationAction* downloadAction = [UNNotificationAction
actionWithIdentifier:@"DOWNLOAD_ACTION"
title:localisedDownloadString.toNSString()
options:UNNotificationActionOptionNone];
UNNotificationAction * const downloadAction = [UNNotificationAction
actionWithIdentifier:@"DOWNLOAD_ACTION"
title:localisedDownloadString.toNSString()
options:UNNotificationActionOptionNone];

// Create the category with the custom actions.
UNNotificationCategory* updateCategory = [UNNotificationCategory
categoryWithIdentifier:@"UPDATE"
actions:@[downloadAction]
intentIdentifiers:@[]
options:UNNotificationCategoryOptionNone];
UNNotificationCategory * const updateCategory = [UNNotificationCategory
categoryWithIdentifier:@"UPDATE"
actions:@[downloadAction]
intentIdentifiers:@[]
options:UNNotificationCategoryOptionNone];

// Create the custom action for talk notifications
UNTextInputNotificationAction* talkReplyAction = [UNTextInputNotificationAction
actionWithIdentifier:@"TALK_REPLY_ACTION"
title:QObject::tr("Reply").toNSString()
options:UNNotificationActionOptionNone
textInputButtonTitle:QObject::tr("Reply").toNSString()
textInputPlaceholder:QObject::tr("Send a Nextcloud Talk reply").toNSString()];

UNNotificationCategory* talkReplyCategory = [UNNotificationCategory
categoryWithIdentifier:@"TALK_MESSAGE"
actions:@[talkReplyAction]
intentIdentifiers:@[]
options:UNNotificationCategoryOptionNone];

[[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:[NSSet setWithObjects:generalCategory, updateCategory, talkReplyCategory, nil]];
UNTextInputNotificationAction * const talkReplyAction = [UNTextInputNotificationAction
actionWithIdentifier:@"TALK_REPLY_ACTION"
title:QObject::tr("Reply").toNSString()
options:UNNotificationActionOptionNone
textInputButtonTitle:QObject::tr("Reply").toNSString()
textInputPlaceholder:QObject::tr("Send a Nextcloud Talk reply").toNSString()];

UNNotificationCategory * const talkReplyCategory = [UNNotificationCategory
categoryWithIdentifier:@"TALK_MESSAGE"
actions:@[talkReplyAction]
intentIdentifiers:@[]
options:UNNotificationCategoryOptionNone];

[UNUserNotificationCenter.currentNotificationCenter setNotificationCategories:[NSSet setWithObjects:generalCategory, updateCategory, talkReplyCategory, nil]];
}

void checkNotificationAuth(MacNotificationAuthorizationOptions additionalAuthOption)
{
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
UNUserNotificationCenter * const center = UNUserNotificationCenter.currentNotificationCenter;
UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert + UNAuthorizationOptionSound;

if(additionalAuthOption == MacNotificationAuthorizationOptions::Provisional) {
authOptions += UNAuthorizationOptionProvisional;
}

[center requestAuthorizationWithOptions:(authOptions)
completionHandler:^(BOOL granted, NSError * _Nullable error) {
// Enable or disable features based on authorization.
if(granted) {
qCDebug(lcMacSystray) << "Authorization for notifications has been granted, can display notifications.";
} else {
qCDebug(lcMacSystray) << "Authorization for notifications not granted.";
if(error) {
QString errorDescription([error.localizedDescription UTF8String]);
qCDebug(lcMacSystray) << "Error from notification center: " << errorDescription;
}
[center requestAuthorizationWithOptions:(authOptions) completionHandler:^(BOOL granted, NSError * _Nullable error) {
// Enable or disable features based on authorization.
if (granted) {
qCDebug(lcMacSystray) << "Authorization for notifications has been granted, can display notifications.";
} else {
qCDebug(lcMacSystray) << "Authorization for notifications not granted.";
if (error) {
const auto errorDescription = QString::fromNSString(error.localizedDescription);
qCDebug(lcMacSystray) << "Error from notification center: " << errorDescription;
}
}
}];
}

void setUserNotificationCenterDelegate()
{
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
UNUserNotificationCenter * const center = UNUserNotificationCenter.currentNotificationCenter;

static dispatch_once_t once;
dispatch_once(&once, ^{
id delegate = [[NotificationCenterDelegate alloc] init];
[center setDelegate:delegate];
id delegate = [[NotificationCenterDelegate alloc] init];
[center setDelegate:delegate];
});
}

UNMutableNotificationContent* basicNotificationContent(const QString &title, const QString &message)
{
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
UNMutableNotificationContent * const content = [[UNMutableNotificationContent alloc] init];
content.title = title.toNSString();
content.body = message.toNSString();
content.sound = [UNNotificationSound defaultSound];
Expand All @@ -215,69 +215,69 @@ void setUserNotificationCenterDelegate()

void sendOsXUserNotification(const QString &title, const QString &message)
{
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
UNUserNotificationCenter * const center = UNUserNotificationCenter.currentNotificationCenter;
checkNotificationAuth();

UNMutableNotificationContent* content = basicNotificationContent(title, message);
UNMutableNotificationContent * const content = basicNotificationContent(title, message);
content.categoryIdentifier = @"GENERAL";

UNTimeIntervalNotificationTrigger* trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1 repeats: NO];
UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:@"NCUserNotification" content:content trigger:trigger];
UNTimeIntervalNotificationTrigger * const trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1 repeats:NO];
UNNotificationRequest * const request = [UNNotificationRequest requestWithIdentifier:@"NCUserNotification" content:content trigger:trigger];

[center addNotificationRequest:request withCompletionHandler:nil];
}

void sendOsXUpdateNotification(const QString &title, const QString &message, const QUrl &webUrl)
{
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
UNUserNotificationCenter * const center = UNUserNotificationCenter.currentNotificationCenter;
checkNotificationAuth();

UNMutableNotificationContent* content = basicNotificationContent(title, message);
UNMutableNotificationContent * const content = basicNotificationContent(title, message);
content.categoryIdentifier = @"UPDATE";
content.userInfo = [NSDictionary dictionaryWithObject:[webUrl.toNSURL() absoluteString] forKey:@"webUrl"];

UNTimeIntervalNotificationTrigger* trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1 repeats: NO];
UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:@"NCUpdateNotification" content:content trigger:trigger];
UNTimeIntervalNotificationTrigger * const trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1 repeats:NO];
UNNotificationRequest * const request = [UNNotificationRequest requestWithIdentifier:@"NCUpdateNotification" content:content trigger:trigger];

[center addNotificationRequest:request withCompletionHandler:nil];
}

void sendOsXTalkNotification(const QString &title, const QString &message, const QString &token, const QString &replyTo, const AccountStatePtr accountState)
{
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
UNUserNotificationCenter * const center = UNUserNotificationCenter.currentNotificationCenter;
checkNotificationAuth();

if (!accountState || !accountState->account()) {
sendOsXUserNotification(title, message);
return;
}

NSString *accountNS = accountState->account()->displayName().toNSString();
NSString *tokenNS = token.toNSString();
NSString *replyToNS = replyTo.toNSString();
NSString * const accountNS = accountState->account()->displayName().toNSString();
NSString * const tokenNS = token.toNSString();
NSString * const replyToNS = replyTo.toNSString();

UNMutableNotificationContent* content = basicNotificationContent(title, message);
UNMutableNotificationContent * const content = basicNotificationContent(title, message);
content.categoryIdentifier = @"TALK_MESSAGE";
content.userInfo = [NSDictionary dictionaryWithObjects:@[accountNS, tokenNS, replyToNS] forKeys:@[@"account", @"token", @"replyTo"]];

UNTimeIntervalNotificationTrigger* trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1 repeats: NO];
UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:@"NCTalkMessageNotification" content:content trigger:trigger];
UNTimeIntervalNotificationTrigger * const trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1 repeats:NO];
UNNotificationRequest * const request = [UNNotificationRequest requestWithIdentifier:@"NCTalkMessageNotification" content:content trigger:trigger];

[center addNotificationRequest:request withCompletionHandler:nil];
}

void setTrayWindowLevelAndVisibleOnAllSpaces(QWindow *window)
{
NSView *nativeView = (NSView *)window->winId();
NSWindow *nativeWindow = (NSWindow *)[nativeView window];
NSView * const nativeView = (NSView *)window->winId();
NSWindow * const nativeWindow = (NSWindow *)(nativeView.window);
[nativeWindow setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces | NSWindowCollectionBehaviorIgnoresCycle |
NSWindowCollectionBehaviorTransient];
[nativeWindow setLevel:NSMainMenuWindowLevel];
}

bool osXInDarkMode()
{
NSString *osxMode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
NSString * const osxMode = [NSUserDefaults.standardUserDefaults stringForKey:@"AppleInterfaceStyle"];
return [osxMode containsString:@"Dark"];
}

Expand Down

0 comments on commit 9727440

Please sign in to comment.