Mercurial > minori
view src/gui/theme.cc @ 351:c844f8bb87ce
gui/theme: add xsettings backend
this also adds newly-necessary endianness methods in core/endian.h
which just so happen to be constexpr as well
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Sun, 14 Jul 2024 23:23:56 -0400 |
parents | 91ac90a34003 |
children |
line wrap: on
line source
#include "core/config.h" #include "core/session.h" #include "gui/theme.h" #include <QApplication> #include <QDebug> #include <QFile> #include <QStyleFactory> #include <QTextStream> #include <QStyle> #include <QtGlobal> #ifdef MACOSX # include "sys/osx/dark_theme.h" #elif defined(WIN32) # include "sys/win32/dark_theme.h" #else # ifdef GLIB # include "sys/glib/dark_theme.h" # endif # ifdef HAVE_XCB # include "sys/x11/dark_theme.h" # endif #endif /* Weird quirks of this implementation: * 1. Dark mode stuff in Qt changes a lot and Qt 5 and Qt 6 are massively different * 2. Some widgets, i.e. QTabWidget, QTabBar, etc., just completely IGNORE the QPalette setting * on different platforms and the only way to fix it is by using Fusion * 3. Windows dark mode support in Qt 6.5 (with Fusion) is completely unavoidable */ namespace Theme { ThemeManager::ThemeManager(Theme theme) { this->theme = theme; } Theme ThemeManager::GetTheme() const { return theme; } bool ThemeManager::IsInDarkTheme() const { switch (theme) { case Theme::Default: #ifdef MACOSX if (osx::DarkThemeAvailable()) return osx::IsInDarkTheme(); #elif defined(WIN32) if (win32::DarkThemeAvailable()) return win32::IsInDarkTheme(); #else # ifdef HAVE_XCB if (x11::IsInDarkTheme()) return true; # endif # ifdef GLIB if (glib::IsInDarkTheme()) return true; # endif break; #endif default: break; } return (theme == Theme::Dark); } void ThemeManager::SetToDarkTheme() { /* macOS >= 10.14 has its own global dark theme, use it :) */ #ifdef MACOSX if (osx::DarkThemeAvailable()) osx::SetToDarkTheme(); else #elif defined(WIN32) if (win32::DarkThemeAvailable()) win32::SetTitleBarsToBlack(true); #endif SetStyleSheet(Theme::Dark); } void ThemeManager::SetToLightTheme() { #ifdef MACOSX if (osx::DarkThemeAvailable()) osx::SetToLightTheme(); else #elif defined(WIN32) if (win32::DarkThemeAvailable()) win32::SetTitleBarsToBlack(false); #endif SetStyleSheet(Theme::Light); } Theme ThemeManager::GetCurrentOSTheme() const { return IsInDarkTheme() ? Theme::Dark : Theme::Light; } /* this function is private, and should stay that way */ void ThemeManager::SetStyleSheet(Theme theme) { switch (theme) { case Theme::Dark: { const QColor darkGray(53, 53, 53); const QColor gray(128, 128, 128); const QColor black(25, 25, 25); const QColor blue(42, 130, 218); QPalette pal; pal.setColor(QPalette::Window, darkGray); pal.setColor(QPalette::WindowText, Qt::white); pal.setColor(QPalette::Base, black); pal.setColor(QPalette::AlternateBase, darkGray); pal.setColor(QPalette::ToolTipBase, blue); pal.setColor(QPalette::ToolTipText, Qt::white); pal.setColor(QPalette::Text, Qt::white); pal.setColor(QPalette::Button, darkGray); pal.setColor(QPalette::ButtonText, Qt::white); pal.setColor(QPalette::Link, blue); pal.setColor(QPalette::Highlight, blue); pal.setColor(QPalette::HighlightedText, Qt::black); pal.setColor(QPalette::Active, QPalette::Button, gray.darker()); pal.setColor(QPalette::Disabled, QPalette::ButtonText, gray); pal.setColor(QPalette::Disabled, QPalette::WindowText, gray); pal.setColor(QPalette::Disabled, QPalette::Text, gray); pal.setColor(QPalette::Disabled, QPalette::Light, darkGray); qApp->setPalette(pal); #ifdef WIN32 qApp->setStyleSheet([] { QFile f(":/dark.qss"); if (!f.exists()) return QStringLiteral(""); f.open(QFile::ReadOnly | QFile::Text); QTextStream ts(&f); return ts.readAll(); }()); #endif break; } default: /* this sucks */ QPalette pal(QApplication::style()->standardPalette()); #ifdef WIN32 /* fuck you Qt 6 */ pal.setColor(QPalette::Window, QColor(0xF0, 0xF0, 0xF0)); #endif qApp->setPalette(pal); qApp->setStyleSheet(""); break; } } void ThemeManager::SetTheme(Theme theme) { switch (theme) { case Theme::Light: SetToLightTheme(); break; case Theme::Dark: SetToDarkTheme(); break; case Theme::Default: if (GetCurrentOSTheme() == Theme::Light) SetToLightTheme(); else SetToDarkTheme(); break; } this->theme = theme; } void ThemeManager::RepaintCurrentTheme() { SetTheme(theme); } } // namespace Theme