Remove use of some deprecated code and cleanup other macOS code

This commit is contained in:
Jonas Kvinge
2019-08-06 20:31:54 +02:00
parent 20766c1feb
commit 4a934c9dab
11 changed files with 147 additions and 93 deletions

View File

@@ -68,19 +68,23 @@
#include <QtDebug>
QDebug operator<<(QDebug dbg, NSObject* object) {
QString ns_format = [[NSString stringWithFormat:@"%@", object] UTF8String];
QString ns_format = [ [NSString stringWithFormat:@"%@", object] UTF8String];
dbg.nospace() << ns_format;
return dbg.space();
}
// Capture global media keys on Mac (Cocoa only!)
// See: http://www.rogueamoeba.com/utm/2007/09/29/apple-keyboard-media-key-event-handling/
@interface MacApplication : NSApplication {
PlatformInterface* application_handler_;
AppDelegate* delegate_;
// shortcut_handler_ only used to temporarily save it AppDelegate does all the heavy-shortcut-lifting
GlobalShortcutBackendMacOS* shortcut_handler_;
}
- (GlobalShortcutBackendMacOS*)shortcut_handler;
@@ -91,52 +95,36 @@ QDebug operator<<(QDebug dbg, NSObject* object) {
@end
#ifdef HAVE_BREAKPAD
static bool BreakpadCallback(int, int, mach_port_t, void*) { return true; }
static BreakpadRef InitBreakpad() {
ScopedNSAutoreleasePool pool;
BreakpadRef breakpad = nil;
NSDictionary* plist = [[NSBundle mainBundle] infoDictionary];
if (plist) {
breakpad = BreakpadCreate(plist);
BreakpadSetFilterCallback(breakpad, &BreakpadCallback, nullptr);
}
[pool release];
return breakpad;
}
#endif // HAVE_BREAKPAD
@implementation AppDelegate
- (id)init {
if ((self = [super init])) {
application_handler_ = nil;
shortcut_handler_ = nil;
dock_menu_ = nil;
}
return self;
}
- (id)initWithHandler:(PlatformInterface*)handler {
application_handler_ = handler;
#ifdef HAVE_BREAKPAD
breakpad_ = InitBreakpad();
#endif
// Register defaults for the whitelist of apps that want to use media keys
[[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys:
[SPMediaKeyTap defaultMediaKeyUserBundleIdentifiers], kMediaKeyUsingBundleIdentifiersDefaultsKey,
nil]];
[ [NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys:[SPMediaKeyTap defaultMediaKeyUserBundleIdentifiers], kMediaKeyUsingBundleIdentifiersDefaultsKey, nil] ];
return self;
}
- (BOOL) applicationShouldHandleReopen: (NSApplication*)app hasVisibleWindows:(BOOL)flag {
if (application_handler_) {
application_handler_->Activate();
}
return YES;
}
- (void)setDockMenu:(NSMenu*)menu {
@@ -156,21 +144,19 @@ static BreakpadRef InitBreakpad() {
}
- (void)applicationDidFinishLaunching:(NSNotification*)aNotification {
key_tap_ = [[SPMediaKeyTap alloc] initWithDelegate:self];
if ([SPMediaKeyTap usesGlobalMediaKeyTap] &&
![[NSProcessInfo processInfo]
isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){
.majorVersion = 10,
.minorVersion = 12,
.patchVersion = 0}]) {
key_tap_ = [ [SPMediaKeyTap alloc] initWithDelegate:self];
if ([SPMediaKeyTap usesGlobalMediaKeyTap] && ![ [NSProcessInfo processInfo]isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){.majorVersion = 10, .minorVersion = 12, .patchVersion = 0}]) {
[key_tap_ startWatchingMediaKeys];
}
else {
qLog(Warning) << "Media key monitoring disabled";
}
}
- (BOOL)application:(NSApplication*)app openFile:(NSString*)filename {
qLog(Debug) << "Wants to open:" << [filename UTF8String];
if (application_handler_->LoadUrl(QString::fromUtf8([filename UTF8String]))) {
@@ -178,16 +164,20 @@ static BreakpadRef InitBreakpad() {
}
return NO;
}
- (void)application:(NSApplication*)app openFiles:(NSArray*)filenames {
qLog(Debug) << "Wants to open:" << filenames;
[filenames enumerateObjectsUsingBlock:^(id object, NSUInteger idx, BOOL* stop) {
[self application:app openFile:(NSString*)object];
}];
[self application:app openFile:(NSString*)object];
}];
}
- (void) mediaKeyTap: (SPMediaKeyTap*)keyTap receivedMediaKeyEvent:(NSEvent*)event {
NSAssert([event type] == NSSystemDefined && [event subtype] == SPSystemDefinedEventMediaKeys, @"Unexpected NSEvent in mediaKeyTap:receivedMediaKeyEvent:");
int key_code = (([event data1] & 0xFFFF0000) >> 16);
@@ -202,12 +192,10 @@ static BreakpadRef InitBreakpad() {
if (key_is_released) {
shortcut_handler_->MacMediaKeyPressed(key_code);
}
}
- (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication*) sender {
#ifdef HAVE_BREAKPAD
BreakpadRelease(breakpad_);
#endif
return NSTerminateNow;
}
@@ -242,17 +230,19 @@ static BreakpadRef InitBreakpad() {
}
- (void)SetApplicationHandler:(PlatformInterface*)handler {
delegate_ = [[AppDelegate alloc] initWithHandler:handler];
delegate_ = [ [AppDelegate alloc] initWithHandler:handler];
// App-shortcut-handler set before delegate is set.
// this makes sure the delegate's shortcut_handler is set
[delegate_ setShortcutHandler:shortcut_handler_];
[self setDelegate:delegate_];
[[NSUserNotificationCenter defaultUserNotificationCenter]
setDelegate:delegate_];
[ [NSUserNotificationCenter defaultUserNotificationCenter]setDelegate:delegate_];
}
- (void)sendEvent:(NSEvent*)event {
// If event tap is not installed, handle events that reach the app instead
BOOL shouldHandleMediaKeyEventLocally = ![SPMediaKeyTap usesGlobalMediaKeyTap];
@@ -261,6 +251,7 @@ static BreakpadRef InitBreakpad() {
}
[super sendEvent:event];
}
@end
@@ -268,13 +259,15 @@ static BreakpadRef InitBreakpad() {
namespace mac {
void MacMain() {
ScopedNSAutoreleasePool pool;
// Creates and sets the magic global variable so QApplication will find it.
[MacApplication sharedApplication];
#ifdef HAVE_SPARKLE
// Creates and sets the magic global variable for Sparkle.
[[SUUpdater sharedUpdater] setDelegate:NSApp];
[ [SUUpdater sharedUpdater] setDelegate:NSApp];
#endif
}
void SetShortcutHandler(GlobalShortcutBackendMacOS* handler) {
@@ -287,52 +280,61 @@ void SetApplicationHandler(PlatformInterface* handler) {
void CheckForUpdates() {
#ifdef HAVE_SPARKLE
[[SUUpdater sharedUpdater] checkForUpdates:NSApp];
[ [SUUpdater sharedUpdater] checkForUpdates:NSApp];
#endif
}
QString GetBundlePath() {
ScopedCFTypeRef<CFURLRef> app_url(CFBundleCopyBundleURL(CFBundleGetMainBundle()));
ScopedCFTypeRef<CFStringRef> mac_path(CFURLCopyFileSystemPath(app_url.get(), kCFURLPOSIXPathStyle));
const char* path = CFStringGetCStringPtr(mac_path.get(), CFStringGetSystemEncoding());
QString bundle_path = QString::fromUtf8(path);
return bundle_path;
}
QString GetResourcesPath() {
QString bundle_path = GetBundlePath();
return bundle_path + "/Contents/Resources";
}
QString GetApplicationSupportPath() {
ScopedNSAutoreleasePool pool;
NSArray* paths = NSSearchPathForDirectoriesInDomains(
NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
QString ret;
if ([paths count] > 0) {
NSString* user_path = [paths objectAtIndex:0];
ret = QString::fromUtf8([user_path UTF8String]);
} else {
}
else {
ret = "~/Library/Application Support";
}
return ret;
}
QString GetMusicDirectory() {
ScopedNSAutoreleasePool pool;
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSMusicDirectory,
NSUserDomainMask, YES);
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSMusicDirectory, NSUserDomainMask, YES);
QString ret;
if ([paths count] > 0) {
NSString* user_path = [paths objectAtIndex:0];
ret = QString::fromUtf8([user_path UTF8String]);
} else {
}
else {
ret = "~/Music";
}
return ret;
}
static int MapFunctionKey(int keycode) {
switch (keycode) {
// Function keys
case NSInsertFunctionKey: return Qt::Key_Insert;
@@ -392,6 +394,7 @@ static int MapFunctionKey(int keycode) {
}
QKeySequence KeySequenceFromNSEvent(NSEvent* event) {
NSString* str = [event charactersIgnoringModifiers];
NSString* upper = [str uppercaseString];
const char* chars = [upper UTF8String];
@@ -409,7 +412,8 @@ QKeySequence KeySequenceFromNSEvent(NSEvent* event) {
if (key == 0) {
if (c >= 0x20 && c <= 0x7e) { // ASCII from space to ~
key = c;
} else {
}
else {
key = MapFunctionKey([event keyCode]);
if (key == 0) {
return QKeySequence();
@@ -431,11 +435,14 @@ QKeySequence KeySequenceFromNSEvent(NSEvent* event) {
}
return QKeySequence(key);
}
void DumpDictionary(CFDictionaryRef dict) {
NSDictionary* d = (NSDictionary*)dict;
NSLog(@"%@", d);
}
// NSWindowCollectionBehaviorFullScreenPrimary
@@ -446,11 +453,14 @@ void EnableFullScreen(const QWidget& main_window) {
NSView* view = reinterpret_cast<NSView*>(main_window.winId());
NSWindow* window = [view window];
[window setCollectionBehavior:kFullScreenPrimary];
}
float GetDevicePixelRatio(QWidget* widget) {
NSView* view = reinterpret_cast<NSView*>(widget->winId());
return [[view window] backingScaleFactor];
return [ [view window] backingScaleFactor];
}
} // namespace mac

View File

@@ -37,3 +37,7 @@ QKeySequence KeySequenceFromNSEvent(NSEvent* event);
void DumpDictionary(CFDictionaryRef dict);
float GetDevicePixelRatio(QWidget *widget);
}
namespace Utilities {
qint32 GetMacOsVersion();
}

36
src/core/mac_utilities.mm Normal file
View File

@@ -0,0 +1,36 @@
/*
* Strawberry Music Player
* Copyright 2019, Jonas Kvinge <jonas@jkvinge.net>
*
* Strawberry 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 3 of the License, or
* (at your option) any later version.
*
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "config.h"
#include <QtGlobal>
#import <Foundation/Foundation.h>
#import <Foundation/NSProcessInfo.h>
namespace Utilities {
qint32 GetMacOsVersion() {
NSOperatingSystemVersion version = [ [NSProcessInfo processInfo] operatingSystemVersion];
return version.minorVersion;
}
} // namespace Utilities

View File

@@ -25,6 +25,7 @@
#include <QtDebug>
#include "core/utilities.h"
#include "core/mac_utilities.h"
// kIOPMAssertionTypePreventUserIdleDisplaySleep from Lion.
#define kLionDisplayAssertion CFSTR("PreventUserIdleDisplaySleep")

View File

@@ -329,14 +329,6 @@ QString ColorToRgba(const QColor &c) {
}
#ifdef Q_OS_MACOS
qint32 GetMacOsVersion() {
SInt32 minor_version;
Gestalt(gestaltSystemVersionMinor, &minor_version);
return minor_version;
}
// Better than openUrl(dirname(path)) - also highlights file at path
void RevealFileInFinder(QString const &path) {
QProcess::execute("/usr/bin/open", QStringList() << "-R" << path);

View File

@@ -125,9 +125,6 @@ void SetEnv(const char *key, const QString &value);
void IncreaseFDLimit();
void CheckPortable();
// Returns the minor version of OS X (ie. 6 for Snow Leopard, 7 for Lion).
qint32 GetMacOsVersion();
// Borrowed from schedutils
enum IoPriority {
IOPRIO_CLASS_NONE = 0,