Fix system theme consistency

- In system mode, read palette from QGuiApplication::palette() rather
  than parsing kdeglobals (platform plugin already handles this)
- Don't call setPalette() in system mode — let Qt handle it
- Add isOverriding property for QML to check mode
- Use Fusion style by default for consistent palette respect
- Improved fallback logic in systemSchemePath() for dark/light detection
- Added /etc/xdg/kdeglobals as fallback for system-wide defaults
This commit is contained in:
Levi Neely 2026-10-01 09:15:31 +02:00
parent 5677be6236
commit 3d2edf1807
4 changed files with 59 additions and 9 deletions

View File

@ -13,7 +13,8 @@ ApplicationWindow {
font.family: theme.fontFamily || Qt.application.font.family
font.pointSize: theme.fontSize > 0 ? theme.fontSize : Qt.application.font.pointSize
// Apply theme palette to Qt Quick Controls
// Apply theme palette to Qt Quick Controls.
// theme.* colors return system palette when mode="system", override colors otherwise.
palette.active.window: theme.windowColor
palette.active.windowText: theme.windowTextColor
palette.active.base: theme.baseColor

View File

@ -55,6 +55,12 @@ static void dumpModel(const DocumentModel &m, const QModelIndex &parent, int dep
}
int main(int argc, char *argv[]) {
// Use Fusion style for consistent cross-platform look that respects palette
// This can be overridden with QT_QUICK_CONTROLS_STYLE env var
if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE")) {
qputenv("QT_QUICK_CONTROLS_STYLE", "Fusion");
}
QGuiApplication app(argc, argv);
app.setApplicationName("orkmode");
app.setOrganizationName("orkmode");

View File

@ -54,22 +54,34 @@ QStringList ThemeManager::availableSchemes() const
bool ThemeManager::isDark() const
{
QColor bg = m_palette.color(QPalette::Window);
// Use the stored palette (which reflects system or override)
QColor bg = m_palette.color(QPalette::Active, QPalette::Window);
// If palette not yet loaded, fall back to app palette
if (!bg.isValid())
bg = QGuiApplication::palette().color(QPalette::Window);
qreal luminance = 0.2126 * bg.redF() + 0.7152 * bg.greenF() + 0.0722 * bg.blueF();
return luminance < 0.5;
}
bool ThemeManager::isOverriding() const
{
return m_mode != "system";
}
void ThemeManager::applyPalette()
{
QString path;
if (m_mode == "system") {
path = systemSchemePath();
} else {
path = schemePath(m_mode);
// Don't override — let the platform theme (KDE, GNOME, etc.) handle it
// Just read the current system palette
m_palette = QGuiApplication::palette();
return;
}
// Mode is a specific scheme name
QString path = schemePath(m_mode);
if (path.isEmpty() || !QFile::exists(path)) {
// Fallback to application default palette
// Fallback: don't override
m_palette = QGuiApplication::palette();
return;
}
@ -297,10 +309,12 @@ QColor ThemeManager::parseColor(const QVariant &value) const
QString ThemeManager::systemSchemePath() const
{
// Try to read from kdeglobals
// Try to read from kdeglobals - KDE's config format
QString kdeglobals = QDir::homePath() + "/.config/kdeglobals";
if (QFile::exists(kdeglobals)) {
QSettings settings(kdeglobals, QSettings::IniFormat);
// KDE stores ColorScheme in [General] section
settings.beginGroup("General");
QString schemeName = settings.value("ColorScheme").toString();
settings.endGroup();
@ -312,7 +326,34 @@ QString ThemeManager::systemSchemePath() const
}
}
// Fallback to BreezeLight
// Also check kdedefaults for system-wide default
QString kdedefaults = "/etc/xdg/kdeglobals";
if (QFile::exists(kdedefaults)) {
QSettings settings(kdedefaults, QSettings::IniFormat);
settings.beginGroup("General");
QString schemeName = settings.value("ColorScheme").toString();
settings.endGroup();
if (!schemeName.isEmpty()) {
QString path = schemePath(schemeName);
if (QFile::exists(path))
return path;
}
}
// Last resort: check what Qt's platform plugin thinks
// by examining the application palette's window color
QPalette sysPal = QGuiApplication::palette();
QColor windowBg = sysPal.color(QPalette::Window);
qreal luminance = 0.2126 * windowBg.redF() + 0.7152 * windowBg.greenF() + 0.0722 * windowBg.blueF();
// If system palette is dark, try BreezeDark, else BreezeLight
if (luminance < 0.5) {
QString darkPath = schemePath("BreezeDark");
if (QFile::exists(darkPath))
return darkPath;
}
return schemePath("BreezeLight");
}

View File

@ -22,6 +22,7 @@ class ThemeManager : public QObject
Q_PROPERTY(QString mode READ mode WRITE setMode NOTIFY modeChanged)
Q_PROPERTY(QStringList availableSchemes READ availableSchemes CONSTANT)
Q_PROPERTY(bool isDark READ isDark NOTIFY paletteChanged)
Q_PROPERTY(bool isOverriding READ isOverriding NOTIFY paletteChanged)
// Palette colors for QML
Q_PROPERTY(QColor windowColor READ windowColor NOTIFY paletteChanged)
@ -71,6 +72,7 @@ public:
void setMode(const QString &mode);
QStringList availableSchemes() const;
bool isDark() const;
bool isOverriding() const;
// Palette colors
QColor windowColor() const;