summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorOatmealDome <OatmealDome@users.noreply.github.com>2025-11-06 20:20:05 -0500
committerGitHub <noreply@github.com>2025-11-06 20:20:05 -0500
commit852b7d85b2eac31da239f4d6c0e0d5a7f2bb8a30 (patch)
tree70ce149873f1c97661fd00ed7216605026f97a99 /Source
parent2528feb98afdb921d830d128e91e34305b96e72c (diff)
parentcd16ec02bde44b303db738e0f2332ec713e299a4 (diff)
Merge pull request #14062 from Simonx22/macos-design-fixes
macOS: UI fixes for dark mode
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/DolphinQt/Config/SettingsWindow.cpp119
-rw-r--r--Source/Core/DolphinQt/Config/SettingsWindow.h11
2 files changed, 100 insertions, 30 deletions
diff --git a/Source/Core/DolphinQt/Config/SettingsWindow.cpp b/Source/Core/DolphinQt/Config/SettingsWindow.cpp
index 8efae30cee..04b1f2d021 100644
--- a/Source/Core/DolphinQt/Config/SettingsWindow.cpp
+++ b/Source/Core/DolphinQt/Config/SettingsWindow.cpp
@@ -3,9 +3,13 @@
#include "DolphinQt/Config/SettingsWindow.h"
+#include <QApplication>
+#include <QColor>
#include <QDialogButtonBox>
+#include <QEvent>
#include <QHBoxLayout>
#include <QListWidget>
+#include <QPalette>
#include <QStackedWidget>
#include <QTabWidget>
#include <QVBoxLayout>
@@ -17,6 +21,7 @@
#include "DolphinQt/MainWindow.h"
#include "DolphinQt/QtUtils/QtUtils.h"
#include "DolphinQt/QtUtils/WrapInScrollArea.h"
+#include "DolphinQt/Settings.h"
#include "DolphinQt/Settings/AdvancedPane.h"
#include "DolphinQt/Settings/AudioPane.h"
#include "DolphinQt/Settings/GameCubePane.h"
@@ -34,7 +39,7 @@ StackedSettingsWindow::StackedSettingsWindow(QWidget* parent) : QDialog{parent}
auto* const layout = new QHBoxLayout{this};
// Calculated value for the padding in our list items.
- const int list_item_padding = layout->contentsMargins().left() / 2;
+ m_list_item_padding = layout->contentsMargins().left() / 2;
// Eliminate padding around layouts.
layout->setContentsMargins(QMargins{});
@@ -46,33 +51,7 @@ StackedSettingsWindow::StackedSettingsWindow(QWidget* parent) : QDialog{parent}
m_navigation_list->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
m_navigation_list->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
- // FYI: "base" is the window color on Windows and "alternate-base" is very high contrast on macOS.
- const auto* const list_background =
-#if !defined(__APPLE__)
- "palette(alternate-base)";
-#else
- "palette(base)";
-#endif
-
- m_navigation_list->setStyleSheet(
- QString::fromUtf8(
- // Remove border around entire widget and adjust background color.
- "QListWidget { border: 0; background: %1; } "
- // Note: padding-left is broken unless border is set, which then breaks colors.
- // see: https://bugreports.qt.io/browse/QTBUG-122698
- "QListWidget::item { padding-top: %2px; padding-bottom: %2px; } "
- // Maintain selected item color when unfocused.
- "QListWidget::item:selected { background: palette(highlight); "
-#if !defined(__APPLE__)
- // Prevent text color change on focus loss.
- // This seems to breaks the nice white text on macOS.
- "color: palette(highlighted-text); "
-#endif
- "} "
- // Remove ugly dotted outline on selected row (Windows and GNOME).
- "* { outline: none; } ")
- .arg(QString::fromUtf8(list_background))
- .arg(list_item_padding));
+ UpdateNavigationListStyle();
layout->addWidget(m_navigation_list);
@@ -104,6 +83,90 @@ void StackedSettingsWindow::OnDoneCreatingPanes()
QtUtils::AdjustSizeWithinScreen(this);
}
+void StackedSettingsWindow::changeEvent(QEvent* event)
+{
+ QDialog::changeEvent(event);
+
+ const auto type = event->type();
+
+ const bool palette_changed = type == QEvent::PaletteChange;
+ const bool application_palette_changed = type == QEvent::ApplicationPaletteChange;
+ const bool style_changed = type == QEvent::StyleChange;
+ const bool theme_event = type == QEvent::ThemeChange;
+
+ const bool theme_changed = application_palette_changed || theme_event;
+
+ if (theme_changed && !m_handling_theme_change)
+ {
+ m_handling_theme_change = true;
+ Settings::Instance().ApplyStyle();
+ // Ensure the dialog and its children adopt the new system palette.
+ setPalette(qApp->palette());
+ Settings::Instance().TriggerThemeChanged();
+ m_handling_theme_change = false;
+ }
+
+ if (palette_changed || application_palette_changed || style_changed || theme_event)
+ UpdateNavigationListStyle();
+}
+
+void StackedSettingsWindow::UpdateNavigationListStyle()
+{
+ if (!m_navigation_list)
+ return;
+
+ // FYI: "base" is the window color on Windows and "alternate-base" is very high contrast on macOS.
+ const auto* const list_background =
+#if !defined(__APPLE__)
+ "palette(alternate-base)";
+#else
+ "palette(base)";
+#endif
+
+ m_navigation_list->setStyleSheet(
+ QString::fromUtf8(
+ // Remove border around entire widget and adjust background color.
+ "QListWidget { border: 0; background: %1; } "
+ // Note: padding-left is broken unless border is set, which then breaks colors.
+ // see: https://bugreports.qt.io/browse/QTBUG-122698
+ "QListWidget::item { padding-top: %2px; padding-bottom: %2px; } "
+ // Maintain selected item color when unfocused.
+ "QListWidget::item:selected { background: palette(highlight); "
+ // Prevent text color change on focus loss.
+ "color: palette(highlighted-text); "
+ "} "
+ // Remove ugly dotted outline on selected row (Windows and GNOME).
+ "* { outline: none; } ")
+ .arg(QString::fromUtf8(list_background))
+ .arg(m_list_item_padding));
+ QPalette list_palette = m_navigation_list->palette();
+ const QPalette app_palette = qApp->palette();
+
+ QColor highlight_color = app_palette.color(QPalette::Active, QPalette::Highlight);
+ QColor highlighted_text = app_palette.color(QPalette::Active, QPalette::HighlightedText);
+
+#if defined(__APPLE__)
+ const bool is_dark_theme = Settings::Instance().IsThemeDark();
+ // The default macOS accent is quite light in our list; darken it for readability in light mode.
+ if (!is_dark_theme)
+ {
+ highlight_color = highlight_color.darker(130);
+ highlighted_text = QColor(Qt::white);
+ }
+#endif
+
+ for (const QPalette::ColorGroup group : {QPalette::Active, QPalette::Inactive})
+ {
+ list_palette.setColor(group, QPalette::Base, app_palette.color(group, QPalette::Base));
+ list_palette.setColor(group, QPalette::AlternateBase,
+ app_palette.color(group, QPalette::AlternateBase));
+ list_palette.setColor(group, QPalette::Highlight, highlight_color);
+ list_palette.setColor(group, QPalette::HighlightedText, highlighted_text);
+ }
+
+ m_navigation_list->setPalette(list_palette);
+}
+
void StackedSettingsWindow::AddPane(QWidget* widget, const QString& name)
{
m_stacked_panes->addWidget(widget);
diff --git a/Source/Core/DolphinQt/Config/SettingsWindow.h b/Source/Core/DolphinQt/Config/SettingsWindow.h
index be8a85d103..3fd646e786 100644
--- a/Source/Core/DolphinQt/Config/SettingsWindow.h
+++ b/Source/Core/DolphinQt/Config/SettingsWindow.h
@@ -8,6 +8,7 @@
class QStackedWidget;
class QListWidget;
class MainWindow;
+class QEvent;
// A settings window with a QListWidget to switch between panes of a QStackedWidget.
class StackedSettingsWindow : public QDialog
@@ -27,9 +28,15 @@ protected:
// For derived classes to call after they create their settings panes.
void OnDoneCreatingPanes();
+ void changeEvent(QEvent* event) override;
+
private:
- QStackedWidget* m_stacked_panes;
- QListWidget* m_navigation_list;
+ void UpdateNavigationListStyle();
+
+ QStackedWidget* m_stacked_panes = nullptr;
+ QListWidget* m_navigation_list = nullptr;
+ int m_list_item_padding = 0;
+ bool m_handling_theme_change = false;
};
enum class SettingsWindowPaneIndex : int