Linux: handle dark system themes nicely
yuzu's default theme doesn't specify everything, which is fine for windows, but in linux anything unspecified is set to the users theme. Symptoms of this are that a linux user with a dark theme won't think to change the theme to a dark theme when first using yuzu Idea here is to try and support arbitrary themes on linux. preliminary work on a "default_dark" theme, used only as overlay for any themes that are measured to be dark mode. Other work done: FreeDesktop standard icon names: plus -> list-add delete refresh, we use view-refresh remove duplicated icons for qdarkstyle_midnight_blue referencing icon aliases in the qrc files is the way to go Note: Dynamic style changing doesn't appear to work with AppImage
This commit is contained in:
parent
b528c4f3af
commit
6af8034f3e
32 changed files with 819 additions and 35 deletions
|
@ -257,6 +257,18 @@ static QString PrettyProductName() {
|
|||
return QSysInfo::prettyProductName();
|
||||
}
|
||||
|
||||
bool GMainWindow::check_dark_mode() {
|
||||
#ifdef __linux__
|
||||
const QPalette test_palette(qApp->palette());
|
||||
const QColor text_color = test_palette.color(QPalette::Active, QPalette::Text);
|
||||
const QColor window_color = test_palette.color(QPalette::Active, QPalette::Window);
|
||||
return (text_color.value() > window_color.value());
|
||||
#else
|
||||
// TODO: Windows
|
||||
return false;
|
||||
#endif // __linux__
|
||||
}
|
||||
|
||||
GMainWindow::GMainWindow(bool has_broken_vulkan)
|
||||
: ui{std::make_unique<Ui::MainWindow>()}, system{std::make_unique<Core::System>()},
|
||||
input_subsystem{std::make_shared<InputCommon::InputSubsystem>()},
|
||||
|
@ -274,6 +286,13 @@ GMainWindow::GMainWindow(bool has_broken_vulkan)
|
|||
ui->setupUi(this);
|
||||
statusBar()->hide();
|
||||
|
||||
// Check dark mode before a theme is loaded
|
||||
os_dark_mode = check_dark_mode();
|
||||
startup_icon_theme = QIcon::themeName();
|
||||
// fallback can only be set once, colorful theme icons are okay on both light/dark
|
||||
QIcon::setFallbackThemeName(QStringLiteral("colorful"));
|
||||
QIcon::setFallbackSearchPaths(QStringList(QStringLiteral(":/icons")));
|
||||
|
||||
default_theme_paths = QIcon::themeSearchPaths();
|
||||
UpdateUITheme();
|
||||
|
||||
|
@ -3930,8 +3949,21 @@ void GMainWindow::filterBarSetChecked(bool state) {
|
|||
emit(OnToggleFilterBar());
|
||||
}
|
||||
|
||||
static void AdjustLinkColor() {
|
||||
QPalette new_pal(qApp->palette());
|
||||
if (UISettings::IsDarkTheme()) {
|
||||
new_pal.setColor(QPalette::Link, QColor(0, 190, 255, 255));
|
||||
} else {
|
||||
new_pal.setColor(QPalette::Link, QColor(0, 140, 200, 255));
|
||||
}
|
||||
if (qApp->palette().color(QPalette::Link) != new_pal.color(QPalette::Link)) {
|
||||
qApp->setPalette(new_pal);
|
||||
}
|
||||
}
|
||||
|
||||
void GMainWindow::UpdateUITheme() {
|
||||
const QString default_theme = QStringLiteral("default");
|
||||
const QString default_theme =
|
||||
QString::fromUtf8(UISettings::themes[static_cast<size_t>(Config::default_theme)].second);
|
||||
QString current_theme = UISettings::values.theme;
|
||||
QStringList theme_paths(default_theme_paths);
|
||||
|
||||
|
@ -3939,6 +3971,23 @@ void GMainWindow::UpdateUITheme() {
|
|||
current_theme = default_theme;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
QIcon::setThemeName(current_theme);
|
||||
AdjustLinkColor();
|
||||
#else
|
||||
if (current_theme == QStringLiteral("default") || current_theme == QStringLiteral("colorful")) {
|
||||
QIcon::setThemeName(current_theme == QStringLiteral("colorful") ? current_theme
|
||||
: startup_icon_theme);
|
||||
QIcon::setThemeSearchPaths(theme_paths);
|
||||
if (check_dark_mode()) {
|
||||
current_theme = QStringLiteral("default_dark");
|
||||
}
|
||||
} else {
|
||||
QIcon::setThemeName(current_theme);
|
||||
QIcon::setThemeSearchPaths(QStringList(QStringLiteral(":/icons")));
|
||||
AdjustLinkColor();
|
||||
}
|
||||
#endif
|
||||
if (current_theme != default_theme) {
|
||||
QString theme_uri{QStringLiteral(":%1/style.qss").arg(current_theme)};
|
||||
QFile f(theme_uri);
|
||||
|
@ -3961,17 +4010,6 @@ void GMainWindow::UpdateUITheme() {
|
|||
qApp->setStyleSheet({});
|
||||
setStyleSheet({});
|
||||
}
|
||||
|
||||
QPalette new_pal(qApp->palette());
|
||||
if (UISettings::IsDarkTheme()) {
|
||||
new_pal.setColor(QPalette::Link, QColor(0, 190, 255, 255));
|
||||
} else {
|
||||
new_pal.setColor(QPalette::Link, QColor(0, 140, 200, 255));
|
||||
}
|
||||
qApp->setPalette(new_pal);
|
||||
|
||||
QIcon::setThemeName(current_theme);
|
||||
QIcon::setThemeSearchPaths(theme_paths);
|
||||
}
|
||||
|
||||
void GMainWindow::LoadTranslation() {
|
||||
|
@ -4022,6 +4060,26 @@ void GMainWindow::SetDiscordEnabled([[maybe_unused]] bool state) {
|
|||
discord_rpc->Update();
|
||||
}
|
||||
|
||||
void GMainWindow::changeEvent(QEvent* event) {
|
||||
#ifdef __linux__
|
||||
// PaletteChange event appears to only reach so far into the GUI, explicitly asking to
|
||||
// UpdateUITheme is a decent work around
|
||||
if (event->type() == QEvent::PaletteChange) {
|
||||
const QPalette test_palette(qApp->palette());
|
||||
const QString current_theme = UISettings::values.theme;
|
||||
// Keeping eye on QPalette::Window to avoid looping. QPalette::Text might be useful too
|
||||
static QColor last_window_color;
|
||||
const QColor window_color = test_palette.color(QPalette::Active, QPalette::Window);
|
||||
if (last_window_color != window_color && (current_theme == QStringLiteral("default") ||
|
||||
current_theme == QStringLiteral("colorful"))) {
|
||||
UpdateUITheme();
|
||||
}
|
||||
last_window_color = window_color;
|
||||
}
|
||||
#endif // __linux__
|
||||
QWidget::changeEvent(event);
|
||||
}
|
||||
|
||||
#ifdef main
|
||||
#undef main
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue