Migrate away from deprecated API on MacOS
Some checks failed
CI - File health / Check (push) Has been cancelled
CI - macOS / Build (push) Has been cancelled
CI - Python / Check (push) Has been cancelled
CI - Ubuntu / Build (push) Has been cancelled
CI - WebUI / Check (push) Has been cancelled
CI - Windows / Build (push) Has been cancelled

Currently `NSUserNotifications API` is used on MacOS to display notifications. However this is marked as deprecated and should be replaced with `UserNotifications.frameworks API`. With the new API it is required to ask for permission before notifications can be send. The program will ask for permission to send notifications on the start.

Related: #15630.
PR #23019.
This commit is contained in:
Ryu481 2025-08-01 12:25:56 +02:00 committed by GitHub
commit ae8a6689dc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 36 additions and 7 deletions

View file

@ -296,7 +296,10 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
programupdater.h programupdater.h
programupdater.cpp programupdater.cpp
) )
target_link_libraries(qbt_gui PRIVATE objc) target_link_libraries(qbt_gui PRIVATE
objc
"-framework UserNotifications"
)
endif() endif()
if (CMAKE_SYSTEM_NAME STREQUAL "Windows") if (CMAKE_SYSTEM_NAME STREQUAL "Windows")

View file

@ -80,6 +80,7 @@ DesktopIntegration::DesktopIntegration(QObject *parent)
{ {
#ifdef Q_OS_MACOS #ifdef Q_OS_MACOS
desktopIntegrationInstance = this; desktopIntegrationInstance = this;
MacUtils::askForNotificationPermission();
MacUtils::overrideDockClickHandler(handleDockClicked); MacUtils::overrideDockClickHandler(handleDockClicked);
m_menu->setAsDockMenu(); m_menu->setAsDockMenu();
#else #else

View file

@ -40,6 +40,7 @@ namespace MacUtils
{ {
QPixmap pixmapForExtension(const QString &ext, const QSize &size); QPixmap pixmapForExtension(const QString &ext, const QSize &size);
void overrideDockClickHandler(bool (*dockClickHandler)(id, SEL, ...)); void overrideDockClickHandler(bool (*dockClickHandler)(id, SEL, ...));
void askForNotificationPermission();
void displayNotification(const QString &title, const QString &message); void displayNotification(const QString &title, const QString &message);
void openFiles(const PathList &pathList); void openFiles(const PathList &pathList);

View file

@ -29,13 +29,17 @@
#include "macutilities.h" #include "macutilities.h"
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h> #import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
#import <UserNotifications/UserNotifications.h>
#include <objc/message.h> #include <objc/message.h>
#include <QCoreApplication>
#include <QPixmap> #include <QPixmap>
#include <QSize> #include <QSize>
#include <QString> #include <QString>
#include "base/logger.h"
#include "base/path.h" #include "base/path.h"
QImage qt_mac_toQImage(CGImageRef image); QImage qt_mac_toQImage(CGImageRef image);
@ -85,16 +89,36 @@ namespace MacUtils
} }
} }
void askForNotificationPermission()
{
@autoreleasepool
{
[UNUserNotificationCenter.currentNotificationCenter requestAuthorizationWithOptions:
(UNAuthorizationOptionAlert + UNAuthorizationOptionSound)
completionHandler:^([[maybe_unused]] BOOL granted, NSError * _Nullable error)
{
if (error)
{
LogMsg(QCoreApplication::translate("MacUtils", "Permission for notifications not granted. Error: \"%1\"").arg
(QString::fromNSString(error.localizedDescription)), Log::WARNING);
}
}];
}
}
void displayNotification(const QString &title, const QString &message) void displayNotification(const QString &title, const QString &message)
{ {
@autoreleasepool @autoreleasepool
{ {
NSUserNotification *notification = [[NSUserNotification alloc] init]; UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
notification.title = title.toNSString(); content.title = title.toNSString();
notification.informativeText = message.toNSString(); content.body = message.toNSString();
notification.soundName = NSUserNotificationDefaultSoundName; content.sound = [UNNotificationSound defaultSound];
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; [[NSUUID UUID] UUIDString] content:content
trigger:nil];
[UNUserNotificationCenter.currentNotificationCenter
addNotificationRequest:request withCompletionHandler:nil];
} }
} }