Qt: Default to native/dynamic theme on Mac

This commit is contained in:
Stenzek
2023-02-05 15:00:51 +10:00
parent 27a0495c0e
commit f8d5379f8e
4 changed files with 91 additions and 10 deletions

View File

@ -10,4 +10,11 @@ void ResumeScreensaver();
/// Abstracts platform-specific code for asynchronously playing a sound.
/// On Windows, this will use PlaySound(). On Linux, it will shell out to aplay. On MacOS, it uses NSSound.
bool PlaySoundAsync(const char* path);
#ifdef __APPLE__
/// Add a handler to be run when macOS changes between dark and light themes
void AddThemeChangeHandler(void* ctx, void(handler)(void* ctx));
/// Remove a handler previously added using AddThemeChangeHandler with the given context
void RemoveThemeChangeHandler(void* ctx);
#endif
} // namespace FrontendCommon

View File

@ -5,7 +5,10 @@
#include "common/log.h"
#include "common/string.h"
#include <IOKit/pwr_mgt/IOPMLib.h>
#include <Cocoa/Cocoa.h>
#include <QuartzCore/QuartzCore.h>
#include <cinttypes>
#include <vector>
Log_SetChannel(FrontendCommon);
#import <AppKit/AppKit.h>
@ -69,3 +72,61 @@ bool FrontendCommon::PlaySoundAsync(const char* path)
[nspath release];
return result;
}
// From https://github.com/PCSX2/pcsx2/blob/1b673d9dd0829a48f5f0b6604c1de2108e981399/common/CocoaTools.mm
@interface PCSX2KVOHelper : NSObject
- (void)addCallback:(void*)ctx run:(void(*)(void*))callback;
- (void)removeCallback:(void*)ctx;
@end
@implementation PCSX2KVOHelper
{
std::vector<std::pair<void*, void(*)(void*)>> _callbacks;
}
- (void)addCallback:(void*)ctx run:(void(*)(void*))callback
{
_callbacks.push_back(std::make_pair(ctx, callback));
}
- (void)removeCallback:(void*)ctx
{
auto new_end = std::remove_if(_callbacks.begin(), _callbacks.end(), [ctx](const auto& entry){
return ctx == entry.first;
});
_callbacks.erase(new_end, _callbacks.end());
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
for (const auto& callback : _callbacks)
callback.second(callback.first);
}
@end
static PCSX2KVOHelper* s_themeChangeHandler;
void FrontendCommon::AddThemeChangeHandler(void* ctx, void(handler)(void* ctx))
{
assert([NSThread isMainThread]);
if (!s_themeChangeHandler)
{
s_themeChangeHandler = [[PCSX2KVOHelper alloc] init];
NSApplication* app = [NSApplication sharedApplication];
[app addObserver:s_themeChangeHandler
forKeyPath:@"effectiveAppearance"
options:0
context:nil];
}
[s_themeChangeHandler addCallback:ctx run:handler];
}
void FrontendCommon::RemoveThemeChangeHandler(void* ctx)
{
assert([NSThread isMainThread]);
[s_themeChangeHandler removeCallback:ctx];
}