deskflow/src/lib/gui/OSXHelpers.mm
sithlord48 1085df54ed refactor: Reuse compliance
build files and documentation: MIT
  images / sources: GPL-2.0-only
  breeze icons: LGPL-2.0-only
  Microsoft MSM file, vc redist license
2025-01-27 17:05:47 -05:00

109 lines
4 KiB
Text

/*
* Deskflow -- mouse and keyboard sharing utility
* SPDX-FileCopyrightText: (C) 2015 Symless Ltd.
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
*/
#import "OSXHelpers.h"
#import <Cocoa/Cocoa.h>
#import <CoreData/CoreData.h>
#import <Foundation/Foundation.h>
#import <UserNotifications/UNNotification.h>
#import <UserNotifications/UNNotificationContent.h>
#import <UserNotifications/UNNotificationTrigger.h>
#import <UserNotifications/UNUserNotificationCenter.h>
#import <QtGlobal>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
void requestOSXNotificationPermission()
{
#if OSX_DEPLOYMENT_TARGET >= 1014
if (isOSXDevelopmentBuild()) {
qWarning("Not requesting notification permission in dev build");
return;
}
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound)
completionHandler:^(BOOL granted, NSError *_Nullable error) {
if (error != nil) {
qWarning(
"Notification permission request error: %s",
[[NSString stringWithFormat:@"%@", error] UTF8String]
);
}
}];
#endif
}
bool isOSXDevelopmentBuild()
{
std::string bundleURL = [[[NSBundle mainBundle] bundleURL].absoluteString UTF8String];
return (bundleURL.find("Applications/Deskflow.app") == std::string::npos);
}
bool showOSXNotification(const QString &title, const QString &body)
{
#if OSX_DEPLOYMENT_TARGET >= 1014
// accessing notification center on unsigned build causes an immidiate
// application shutodown (in this case, server) and cannot be caught
// to avoid issues with it need to first check if this is a dev build
if (isOSXDevelopmentBuild()) {
qWarning("Not showing notification in dev build");
return false;
}
requestOSXNotificationPermission();
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = title.toNSString();
content.body = body.toNSString();
// Create the request object.
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"SecureInput"
content:content
trigger:nil];
[center
addNotificationRequest:request
withCompletionHandler:^(NSError *_Nullable error) {
if (error != nil) {
qWarning("Notification display request error: %s", [[NSString stringWithFormat:@"%@", error] UTF8String]);
}
}];
#else
NSUserNotification *notification = [[NSUserNotification alloc] init];
notification.title = title.toNSString();
notification.informativeText = body.toNSString();
notification.soundName = NSUserNotificationDefaultSoundName; // Will play a default sound
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
[notification autorelease];
#endif
return true;
}
bool isOSXInterfaceStyleDark()
{
// Implementation from http://stackoverflow.com/a/26472651
NSDictionary *dict = [[NSUserDefaults standardUserDefaults] persistentDomainForName:NSGlobalDomain];
id style = [dict objectForKey:@"AppleInterfaceStyle"];
return (style && [style isKindOfClass:[NSString class]] && NSOrderedSame == [style caseInsensitiveCompare:@"dark"]);
}
void forceAppActive()
{
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
[[NSApplication sharedApplication] setActivationPolicy:NSApplicationActivationPolicyRegular];
}
void macOSNativeHide()
{
[NSApp hide:nil];
[[NSApplication sharedApplication] setActivationPolicy:NSApplicationActivationPolicyAccessory];
}