Qt: Default to native/dynamic theme on Mac
This commit is contained in:
parent
27a0495c0e
commit
f8d5379f8e
|
@ -18,6 +18,7 @@
|
||||||
#include "debuggerwindow.h"
|
#include "debuggerwindow.h"
|
||||||
#include "displaywidget.h"
|
#include "displaywidget.h"
|
||||||
#include "frontend-common/game_list.h"
|
#include "frontend-common/game_list.h"
|
||||||
|
#include "frontend-common/platform_misc.h"
|
||||||
#include "gamelistsettingswidget.h"
|
#include "gamelistsettingswidget.h"
|
||||||
#include "gamelistwidget.h"
|
#include "gamelistwidget.h"
|
||||||
#include "gdbserver.h"
|
#include "gdbserver.h"
|
||||||
|
@ -62,7 +63,11 @@ static constexpr char DISC_IMAGE_FILTER[] = QT_TRANSLATE_NOOP(
|
||||||
"(*.ecm);;Media Descriptor Sidecar Images (*.mds);;PlayStation EBOOTs (*.pbp *.PBP);;PlayStation Executables (*.exe "
|
"(*.ecm);;Media Descriptor Sidecar Images (*.mds);;PlayStation EBOOTs (*.pbp *.PBP);;PlayStation Executables (*.exe "
|
||||||
"*.psexe *.ps-exe);;Portable Sound Format Files (*.psf *.minipsf);;Playlists (*.m3u)");
|
"*.psexe *.ps-exe);;Portable Sound Format Files (*.psf *.minipsf);;Playlists (*.m3u)");
|
||||||
|
|
||||||
static const char* DEFAULT_THEME_NAME = "darkfusion";
|
#ifdef __APPLE__
|
||||||
|
const char* DEFAULT_THEME_NAME = "";
|
||||||
|
#else
|
||||||
|
const char* DEFAULT_THEME_NAME = "darkfusion";
|
||||||
|
#endif
|
||||||
|
|
||||||
MainWindow* g_main_window = nullptr;
|
MainWindow* g_main_window = nullptr;
|
||||||
static QString s_unthemed_style_name;
|
static QString s_unthemed_style_name;
|
||||||
|
@ -116,6 +121,9 @@ MainWindow::~MainWindow()
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
unregisterForDeviceNotifications();
|
unregisterForDeviceNotifications();
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __APPLE__
|
||||||
|
FrontendCommon::RemoveThemeChangeHandler(this);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::updateApplicationTheme()
|
void MainWindow::updateApplicationTheme()
|
||||||
|
@ -149,6 +157,11 @@ void MainWindow::initialize()
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
registerForDeviceNotifications();
|
registerForDeviceNotifications();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
FrontendCommon::AddThemeChangeHandler(this,
|
||||||
|
[](void* ctx) { QtHost::RunOnUIThread([] { g_main_window->updateTheme(); }); });
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::reportError(const QString& title, const QString& message)
|
void MainWindow::reportError(const QString& title, const QString& message)
|
||||||
|
@ -2078,6 +2091,11 @@ void MainWindow::setTheme(const QString& theme)
|
||||||
{
|
{
|
||||||
Host::SetBaseStringSettingValue("UI", "Theme", theme.toUtf8().constData());
|
Host::SetBaseStringSettingValue("UI", "Theme", theme.toUtf8().constData());
|
||||||
Host::CommitBaseSettingChanges();
|
Host::CommitBaseSettingChanges();
|
||||||
|
updateTheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::updateTheme()
|
||||||
|
{
|
||||||
updateApplicationTheme();
|
updateApplicationTheme();
|
||||||
updateMenuSelectedTheme();
|
updateMenuSelectedTheme();
|
||||||
m_game_list_widget->reloadCommonImages();
|
m_game_list_widget->reloadCommonImages();
|
||||||
|
@ -2185,15 +2203,9 @@ void MainWindow::setStyleFromSettings()
|
||||||
|
|
||||||
void MainWindow::setIconThemeFromSettings()
|
void MainWindow::setIconThemeFromSettings()
|
||||||
{
|
{
|
||||||
const std::string theme(Host::GetBaseStringSettingValue("UI", "Theme", DEFAULT_THEME_NAME));
|
const QPalette palette(qApp->palette());
|
||||||
QString icon_theme;
|
const bool dark = palette.windowText().color().value() > palette.window().color().value();
|
||||||
|
QIcon::setThemeName(dark ? QStringLiteral("white") : QStringLiteral("black"));
|
||||||
if (theme == "qdarkstyle" || theme == "darkfusion" || theme == "darkfusionblue")
|
|
||||||
icon_theme = QStringLiteral("white");
|
|
||||||
else
|
|
||||||
icon_theme = QStringLiteral("black");
|
|
||||||
|
|
||||||
QIcon::setThemeName(icon_theme);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onSettingsResetToDefault()
|
void MainWindow::onSettingsResetToDefault()
|
||||||
|
|
|
@ -228,6 +228,7 @@ private:
|
||||||
void setGameListEntryCoverImage(const GameList::Entry* entry);
|
void setGameListEntryCoverImage(const GameList::Entry* entry);
|
||||||
void clearGameListEntryPlayTime(const GameList::Entry* entry);
|
void clearGameListEntryPlayTime(const GameList::Entry* entry);
|
||||||
void setTheme(const QString& theme);
|
void setTheme(const QString& theme);
|
||||||
|
void updateTheme();
|
||||||
void recreate();
|
void recreate();
|
||||||
|
|
||||||
void registerForDeviceNotifications();
|
void registerForDeviceNotifications();
|
||||||
|
|
|
@ -10,4 +10,11 @@ void ResumeScreensaver();
|
||||||
/// Abstracts platform-specific code for asynchronously playing a sound.
|
/// 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.
|
/// On Windows, this will use PlaySound(). On Linux, it will shell out to aplay. On MacOS, it uses NSSound.
|
||||||
bool PlaySoundAsync(const char* path);
|
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
|
} // namespace FrontendCommon
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
#include "common/string.h"
|
#include "common/string.h"
|
||||||
#include <IOKit/pwr_mgt/IOPMLib.h>
|
#include <IOKit/pwr_mgt/IOPMLib.h>
|
||||||
|
#include <Cocoa/Cocoa.h>
|
||||||
|
#include <QuartzCore/QuartzCore.h>
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
|
#include <vector>
|
||||||
Log_SetChannel(FrontendCommon);
|
Log_SetChannel(FrontendCommon);
|
||||||
|
|
||||||
#import <AppKit/AppKit.h>
|
#import <AppKit/AppKit.h>
|
||||||
|
@ -69,3 +72,61 @@ bool FrontendCommon::PlaySoundAsync(const char* path)
|
||||||
[nspath release];
|
[nspath release];
|
||||||
return result;
|
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];
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue