Backport Qt 6 improvements to QGtkStyle for better Gtk/GNOME integration

Resolves: #2226797
This commit is contained in:
Jan Grulich 2023-08-21 10:50:06 +02:00
parent 829747ee2b
commit 6ad7f138fe
27 changed files with 6088 additions and 14 deletions

View File

@ -1,8 +1,17 @@
From dacd0c6b3466258d175e7119a8e4836171400820 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Wed, 26 Jul 2023 12:03:46 +0200
Subject: [PATCH 01/25] Use Wayland by default on GNOME
---
src/gui/kernel/qguiapplication.cpp | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index b8bfad4f16..676fdfad5e 100644
index b39b3b4e5e..a217719ea8 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -1376,14 +1376,7 @@ void QGuiApplicationPrivate::createPlatformIntegration()
@@ -1412,14 +1412,7 @@ void QGuiApplicationPrivate::createPlatformIntegration()
if (sessionType == QByteArrayLiteral("x11") && !platformName.contains(QByteArrayLiteral("xcb"))) {
platformName = QByteArrayLiteral("xcb");
} else if (sessionType == QByteArrayLiteral("wayland") && !platformName.contains(QByteArrayLiteral("wayland"))) {
@ -18,3 +27,6 @@ index b8bfad4f16..676fdfad5e 100644
}
}
#ifdef QT_QPA_DEFAULT_PLATFORM_NAME
--
2.41.0

View File

@ -0,0 +1,119 @@
From 488d73ca92deb669abc724c82dbd3206597107fd Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Wed, 26 Jul 2023 12:04:21 +0200
Subject: [PATCH 02/25] Add QPlatformTheme::Appearance for detecting light/dark
modes
And implement it on Windows and macOS.
---
src/gui/kernel/qplatformtheme.cpp | 5 +++++
src/gui/kernel/qplatformtheme.h | 8 ++++++++
src/plugins/platforms/cocoa/qcocoatheme.h | 1 +
src/plugins/platforms/cocoa/qcocoatheme.mm | 5 +++++
src/plugins/platforms/windows/qwindowstheme.cpp | 5 +++++
src/plugins/platforms/windows/qwindowstheme.h | 3 +++
6 files changed, 27 insertions(+)
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp
index 2325873245..662fef1426 100644
--- a/src/gui/kernel/qplatformtheme.cpp
+++ b/src/gui/kernel/qplatformtheme.cpp
@@ -399,6 +399,11 @@ QPlatformDialogHelper *QPlatformTheme::createPlatformDialogHelper(DialogType typ
return nullptr;
}
+QPlatformTheme::Appearance QPlatformTheme::appearance() const
+{
+ return Appearance::Unknown;
+}
+
const QPalette *QPlatformTheme::palette(Palette type) const
{
Q_D(const QPlatformTheme);
diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h
index 7e6c9d5740..c0dee4c581 100644
--- a/src/gui/kernel/qplatformtheme.h
+++ b/src/gui/kernel/qplatformtheme.h
@@ -131,6 +131,12 @@ public:
MessageDialog
};
+ enum class Appearance {
+ Unknown = 0x0000,
+ Light = 0x0001,
+ Dark = 0x0002
+ };
+
enum Palette {
SystemPalette,
ToolTipPalette,
@@ -320,6 +326,8 @@ public:
virtual QString standardButtonText(int button) const;
virtual QKeySequence standardButtonShortcut(int button) const;
+ virtual Appearance appearance() const;
+
static QVariant defaultThemeHint(ThemeHint hint);
static QString defaultStandardButtonText(int button);
static QString removeMnemonics(const QString &original);
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.h b/src/plugins/platforms/cocoa/qcocoatheme.h
index 50e56ef1bf..f719fd943b 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.h
+++ b/src/plugins/platforms/cocoa/qcocoatheme.h
@@ -73,6 +73,7 @@ public:
QIcon fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions options = {}) const override;
QVariant themeHint(ThemeHint hint) const override;
+ Appearance appearance() const override;
QString standardButtonText(int button) const override;
QKeySequence standardButtonShortcut(int button) const override;
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm
index d73b028afb..a79fa4e4b9 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.mm
+++ b/src/plugins/platforms/cocoa/qcocoatheme.mm
@@ -544,6 +544,11 @@ QVariant QCocoaTheme::themeHint(ThemeHint hint) const
return QPlatformTheme::themeHint(hint);
}
+QPlatformTheme::Appearance QCocoaTheme::appearance() const
+{
+ return qt_mac_applicationIsInDarkMode() ? Appearance::Dark : Appearance::Light;
+}
+
QString QCocoaTheme::standardButtonText(int button) const
{
return button == QPlatformDialogHelper::Discard ?
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index 25e083fd5c..510b8746da 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -520,6 +520,11 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const
return QPlatformTheme::themeHint(hint);
}
+QPlatformTheme::Appearance QWindowsTheme::appearance() const
+{
+ return QWindowsContext::isDarkMode() ? Appearance::Dark : Appearance::Light;
+}
+
void QWindowsTheme::clearPalettes()
{
qDeleteAll(m_palettes, m_palettes + NPalettes);
diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h
index af28f2878c..9d5fcc92fe 100644
--- a/src/plugins/platforms/windows/qwindowstheme.h
+++ b/src/plugins/platforms/windows/qwindowstheme.h
@@ -64,6 +64,9 @@ public:
QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const override;
#endif
QVariant themeHint(ThemeHint) const override;
+
+ Appearance appearance() const override;
+
const QPalette *palette(Palette type = SystemPalette) const override
{ return m_palettes[type]; }
const QFont *font(Font type = SystemFont) const override
--
2.41.0

View File

@ -0,0 +1,65 @@
From cf96f7cecf8d02722e303687c1f30361a4a55cd0 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Wed, 26 Jul 2023 12:06:29 +0200
Subject: [PATCH 03/25] Add enum class Qt::Appearance
It has been decided to add an appearance property in QStyleHints, which
will be propagated to classes that do not include QPlatformTheme.
Therefore an appearance enum class is added to the Qt namespace, thus
being available to all Qt classes.
---
src/corelib/global/qnamespace.h | 7 +++++++
src/corelib/global/qnamespace.qdoc | 11 +++++++++++
2 files changed, 18 insertions(+)
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index bf19b1627b..acf2c26368 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -123,6 +123,12 @@ public:
UNICODE_ACCEL = 0x00000000
};
+ enum class Appearance {
+ Unknown = 0x0000,
+ Light = 0x0001,
+ Dark = 0x0002
+ };
+
enum MouseButton {
NoButton = 0x00000000,
LeftButton = 0x00000001,
@@ -1820,6 +1826,7 @@ public:
QT_Q_ENUM(DayOfWeek)
QT_Q_ENUM(CursorShape)
QT_Q_ENUM(GlobalColor)
+ QT_Q_ENUM(Appearance)
QT_Q_ENUM(AspectRatioMode)
QT_Q_ENUM(TransformationMode)
QT_Q_FLAG(ImageConversionFlags)
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index dbb9469bba..70cf8290f5 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -841,6 +841,17 @@
\sa QDockWidget::setAllowedAreas, QDockWidget::isAreaAllowed
*/
+/*!
+ \enum Qt::Appearance
+
+ Represents the appearance of an application's theme,
+ defined by QGuiApplication::palette().
+
+ \value Unknown The appearance is unknown.
+ \value Light The background colors are lighter than the text color, i.e. the theme is light.
+ \value Dark The background colors are darker than the text color, i.e. the theme is dark.
+*/
+
/*!
\enum Qt::ImageConversionFlag
--
2.41.0

View File

@ -0,0 +1,89 @@
From 1d693df019b1ebf54980a015000b01ae947f82ee Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Wed, 26 Jul 2023 12:26:39 +0200
Subject: [PATCH 04/25] QGtk3Theme: implement appearance function to detect
dark themes
This allows Qt Quick Controls to detect if a dark theme is in use,
and if so, use a dark theme of the current style (if available).
---
.../platformthemes/gtk3/qgtk3theme.cpp | 42 +++++++++++++++++++
src/plugins/platformthemes/gtk3/qgtk3theme.h | 2 +
2 files changed, 44 insertions(+)
diff --git a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
index 93520344f8..a47720384c 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
@@ -41,6 +41,7 @@
#include "qgtk3dialoghelpers.h"
#include "qgtk3menu.h"
#include <QVariant>
+#include <QtCore/qregularexpression.h>
#undef signals
#include <gtk/gtk.h>
@@ -147,6 +148,47 @@ QString QGtk3Theme::gtkFontName() const
return QGnomeTheme::gtkFontName();
}
+QPlatformTheme::Appearance QGtk3Theme::appearance() const
+{
+ /*
+ https://docs.gtk.org/gtk3/running.html
+
+ It's possible to set a theme variant after the theme name when using GTK_THEME:
+
+ GTK_THEME=Adwaita:dark
+
+ Some themes also have "-dark" as part of their name.
+
+ We test this environment variable first because the documentation says
+ it's mainly used for easy debugging, so it should be possible to use it
+ to override any other settings.
+ */
+ QString themeName = qEnvironmentVariable("GTK_THEME");
+ const QRegularExpression darkRegex(QStringLiteral("[:-]dark"), QRegularExpression::CaseInsensitiveOption);
+ if (!themeName.isEmpty())
+ return darkRegex.match(themeName).hasMatch() ? Appearance::Dark : Appearance::Light;
+
+ /*
+ https://docs.gtk.org/gtk3/property.Settings.gtk-application-prefer-dark-theme.html
+
+ This setting controls which theme is used when the theme specified by
+ gtk-theme-name provides both light and dark variants. We can save a
+ regex check by testing this property first.
+ */
+ const auto preferDark = gtkSetting<bool>("gtk-application-prefer-dark-theme");
+ if (preferDark)
+ return Appearance::Dark;
+
+ /*
+ https://docs.gtk.org/gtk3/property.Settings.gtk-theme-name.html
+ */
+ themeName = gtkSetting("gtk-theme-name");
+ if (!themeName.isEmpty())
+ return darkRegex.match(themeName).hasMatch() ? Appearance::Dark : Appearance::Light;
+
+ return Appearance::Unknown;
+}
+
bool QGtk3Theme::usePlatformNativeDialog(DialogType type) const
{
switch (type) {
diff --git a/src/plugins/platformthemes/gtk3/qgtk3theme.h b/src/plugins/platformthemes/gtk3/qgtk3theme.h
index 54296d2ff1..5f439067af 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3theme.h
+++ b/src/plugins/platformthemes/gtk3/qgtk3theme.h
@@ -52,6 +52,8 @@ public:
virtual QVariant themeHint(ThemeHint hint) const override;
virtual QString gtkFontName() const override;
+ Appearance appearance() const override;
+
bool usePlatformNativeDialog(DialogType type) const override;
QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const override;
--
2.41.0

View File

@ -0,0 +1,128 @@
From 3d8874aaf5384818a51f158cd2880b7976c9a93a Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Wed, 26 Jul 2023 12:41:53 +0200
Subject: [PATCH 05/25] Account for dark system themes in qt_fusionPalette
On Ubuntu (Gnome), the Fusion style didn't account for when a dark
theme was set in the system's settings. Neither QGtk3Theme, nor
QGnomeTheme (which it derives from) provide a palette() implementation,
so they'd fall back to QPlatformTheme's. This default implementation
calls QPlatformThemePrivate::initializeSystemPalette(), which uses
qt_fusionPalette().
This patch accounts for QPlatformTheme::appearance() in
qt_fusionPalette(), adjusting the palette roles accordingly
to look correct when run under a dark theme.
This also fixes the same issue for the Fusion style in Qt Quick
Controls.
---
src/gui/kernel/qpalette.cpp | 36 -------------------------
src/gui/kernel/qplatformtheme.cpp | 44 ++++++++++++++++++++++++++++++-
2 files changed, 43 insertions(+), 37 deletions(-)
diff --git a/src/gui/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp
index a192b7aef4..0549f19699 100644
--- a/src/gui/kernel/qpalette.cpp
+++ b/src/gui/kernel/qpalette.cpp
@@ -1164,42 +1164,6 @@ void QPalette::setColorGroup(ColorGroup cg, const QBrush &foreground, const QBru
setBrush(cg, ToolTipText, toolTipText);
}
-Q_GUI_EXPORT QPalette qt_fusionPalette()
-{
- QColor backGround(239, 239, 239);
- QColor light = backGround.lighter(150);
- QColor mid(backGround.darker(130));
- QColor midLight = mid.lighter(110);
- QColor base = Qt::white;
- QColor disabledBase(backGround);
- QColor dark = backGround.darker(150);
- QColor darkDisabled = QColor(209, 209, 209).darker(110);
- QColor text = Qt::black;
- QColor hightlightedText = Qt::white;
- QColor disabledText = QColor(190, 190, 190);
- QColor button = backGround;
- QColor shadow = dark.darker(135);
- QColor disabledShadow = shadow.lighter(150);
-
- QPalette fusionPalette(Qt::black,backGround,light,dark,mid,text,base);
- fusionPalette.setBrush(QPalette::Midlight, midLight);
- fusionPalette.setBrush(QPalette::Button, button);
- fusionPalette.setBrush(QPalette::Shadow, shadow);
- fusionPalette.setBrush(QPalette::HighlightedText, hightlightedText);
-
- fusionPalette.setBrush(QPalette::Disabled, QPalette::Text, disabledText);
- fusionPalette.setBrush(QPalette::Disabled, QPalette::WindowText, disabledText);
- fusionPalette.setBrush(QPalette::Disabled, QPalette::ButtonText, disabledText);
- fusionPalette.setBrush(QPalette::Disabled, QPalette::Base, disabledBase);
- fusionPalette.setBrush(QPalette::Disabled, QPalette::Dark, darkDisabled);
- fusionPalette.setBrush(QPalette::Disabled, QPalette::Shadow, disabledShadow);
-
- fusionPalette.setBrush(QPalette::Active, QPalette::Highlight, QColor(48, 140, 198));
- fusionPalette.setBrush(QPalette::Inactive, QPalette::Highlight, QColor(48, 140, 198));
- fusionPalette.setBrush(QPalette::Disabled, QPalette::Highlight, QColor(145, 145, 145));
- return fusionPalette;
-}
-
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, const QPalette &p)
{
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp
index 662fef1426..62f569bbef 100644
--- a/src/gui/kernel/qplatformtheme.cpp
+++ b/src/gui/kernel/qplatformtheme.cpp
@@ -364,7 +364,49 @@ QPlatformThemePrivate::~QPlatformThemePrivate()
delete systemPalette;
}
-Q_GUI_EXPORT QPalette qt_fusionPalette();
+Q_GUI_EXPORT QPalette qt_fusionPalette()
+{
+ const bool darkAppearance = QGuiApplicationPrivate::platformTheme()->appearance()
+ == QPlatformTheme::Appearance::Dark;
+ const QColor windowText = darkAppearance ? QColor(240, 240, 240) : Qt::black;
+ const QColor backGround = darkAppearance ? QColor(50, 50, 50) : QColor(239, 239, 239);
+ const QColor light = backGround.lighter(150);
+ const QColor mid = (backGround.darker(130));
+ const QColor midLight = mid.lighter(110);
+ const QColor base = darkAppearance ? backGround.darker(140) : Qt::white;
+ const QColor disabledBase(backGround);
+ const QColor dark = backGround.darker(150);
+ const QColor darkDisabled = QColor(209, 209, 209).darker(110);
+ const QColor text = darkAppearance ? windowText : Qt::black;
+ const QColor hightlightedText = darkAppearance ? windowText : Qt::white;
+ const QColor disabledText = darkAppearance ? QColor(130, 130, 130) : QColor(190, 190, 190);
+ const QColor button = backGround;
+ const QColor shadow = dark.darker(135);
+ const QColor disabledShadow = shadow.lighter(150);
+ QColor placeholder = text;
+ placeholder.setAlpha(128);
+
+ QPalette fusionPalette(windowText, backGround, light, dark, mid, text, base);
+ fusionPalette.setBrush(QPalette::Midlight, midLight);
+ fusionPalette.setBrush(QPalette::Button, button);
+ fusionPalette.setBrush(QPalette::Shadow, shadow);
+ fusionPalette.setBrush(QPalette::HighlightedText, hightlightedText);
+
+ fusionPalette.setBrush(QPalette::Disabled, QPalette::Text, disabledText);
+ fusionPalette.setBrush(QPalette::Disabled, QPalette::WindowText, disabledText);
+ fusionPalette.setBrush(QPalette::Disabled, QPalette::ButtonText, disabledText);
+ fusionPalette.setBrush(QPalette::Disabled, QPalette::Base, disabledBase);
+ fusionPalette.setBrush(QPalette::Disabled, QPalette::Dark, darkDisabled);
+ fusionPalette.setBrush(QPalette::Disabled, QPalette::Shadow, disabledShadow);
+
+ fusionPalette.setBrush(QPalette::Active, QPalette::Highlight, QColor(48, 140, 198));
+ fusionPalette.setBrush(QPalette::Inactive, QPalette::Highlight, QColor(48, 140, 198));
+ fusionPalette.setBrush(QPalette::Disabled, QPalette::Highlight, QColor(145, 145, 145));
+
+ fusionPalette.setBrush(QPalette::PlaceholderText, placeholder);
+
+ return fusionPalette;
+}
void QPlatformThemePrivate::initializeSystemPalette()
{
--
2.41.0

View File

@ -0,0 +1,49 @@
From 84b0d114d98c58ecf00e20987321182e8e2ba4c1 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Wed, 26 Jul 2023 12:44:00 +0200
Subject: [PATCH 06/25] qt_fusionPalette: make links more legible on dark
backgrounds
QPalette's default for Link is Qt::blue, which is difficult to read
on dark backgrounds.
Use the same blue that is already used for Highlight, as it is
consistent and easy to read.
---
src/gui/kernel/qplatformtheme.cpp | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp
index 62f569bbef..14fdf94755 100644
--- a/src/gui/kernel/qplatformtheme.cpp
+++ b/src/gui/kernel/qplatformtheme.cpp
@@ -378,6 +378,7 @@ Q_GUI_EXPORT QPalette qt_fusionPalette()
const QColor dark = backGround.darker(150);
const QColor darkDisabled = QColor(209, 209, 209).darker(110);
const QColor text = darkAppearance ? windowText : Qt::black;
+ const QColor highlight = QColor(48, 140, 198);
const QColor hightlightedText = darkAppearance ? windowText : Qt::white;
const QColor disabledText = darkAppearance ? QColor(130, 130, 130) : QColor(190, 190, 190);
const QColor button = backGround;
@@ -399,12 +400,16 @@ Q_GUI_EXPORT QPalette qt_fusionPalette()
fusionPalette.setBrush(QPalette::Disabled, QPalette::Dark, darkDisabled);
fusionPalette.setBrush(QPalette::Disabled, QPalette::Shadow, disabledShadow);
- fusionPalette.setBrush(QPalette::Active, QPalette::Highlight, QColor(48, 140, 198));
- fusionPalette.setBrush(QPalette::Inactive, QPalette::Highlight, QColor(48, 140, 198));
+ fusionPalette.setBrush(QPalette::Active, QPalette::Highlight, highlight);
+ fusionPalette.setBrush(QPalette::Inactive, QPalette::Highlight, highlight);
fusionPalette.setBrush(QPalette::Disabled, QPalette::Highlight, QColor(145, 145, 145));
fusionPalette.setBrush(QPalette::PlaceholderText, placeholder);
+ // Use a more legible light blue on dark backgrounds than the default Qt::blue.
+ if (darkAppearance)
+ fusionPalette.setBrush(QPalette::Link, highlight);
+
return fusionPalette;
}
--
2.41.0

View File

@ -0,0 +1,29 @@
From dff40b9fed2b91244d6664342daf859b3aa0375f Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Wed, 26 Jul 2023 12:44:37 +0200
Subject: [PATCH 07/25] Add nullptr check for theme when initializing palette
---
src/gui/kernel/qplatformtheme.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp
index 14fdf94755..827829c4a5 100644
--- a/src/gui/kernel/qplatformtheme.cpp
+++ b/src/gui/kernel/qplatformtheme.cpp
@@ -366,8 +366,10 @@ QPlatformThemePrivate::~QPlatformThemePrivate()
Q_GUI_EXPORT QPalette qt_fusionPalette()
{
- const bool darkAppearance = QGuiApplicationPrivate::platformTheme()->appearance()
- == QPlatformTheme::Appearance::Dark;
+ auto theme = QGuiApplicationPrivate::platformTheme();
+ const bool darkAppearance = theme
+ ? theme->appearance() == QPlatformTheme::Appearance::Dark
+ : false;
const QColor windowText = darkAppearance ? QColor(240, 240, 240) : Qt::black;
const QColor backGround = darkAppearance ? QColor(50, 50, 50) : QColor(239, 239, 239);
const QColor light = backGround.lighter(150);
--
2.41.0

View File

@ -0,0 +1,202 @@
From 240ce954220d713968e608f2766144c7657bceed Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Wed, 26 Jul 2023 12:56:06 +0200
Subject: [PATCH 08/25] Replace QPlatformTheme::Appearance by Qt:Appearance
With the introduction of Qt:Appearance, its predecessor in
QPlatformTheme has become redundant.
This patch replaces all occurrences of QPlatformTheme::Appearance with
the new enum class.
---
src/gui/kernel/qplatformtheme.cpp | 6 +++---
src/gui/kernel/qplatformtheme.h | 8 +-------
src/plugins/platforms/cocoa/qcocoatheme.h | 2 +-
src/plugins/platforms/cocoa/qcocoatheme.mm | 4 ++--
src/plugins/platforms/windows/qwindowstheme.cpp | 4 ++--
src/plugins/platforms/windows/qwindowstheme.h | 2 +-
src/plugins/platformthemes/gtk3/qgtk3theme.cpp | 10 +++++-----
src/plugins/platformthemes/gtk3/qgtk3theme.h | 2 +-
src/plugins/styles/mac/qmacstyle_mac.mm | 2 +-
9 files changed, 17 insertions(+), 23 deletions(-)
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp
index 827829c4a5..6dd7d5c923 100644
--- a/src/gui/kernel/qplatformtheme.cpp
+++ b/src/gui/kernel/qplatformtheme.cpp
@@ -368,7 +368,7 @@ Q_GUI_EXPORT QPalette qt_fusionPalette()
{
auto theme = QGuiApplicationPrivate::platformTheme();
const bool darkAppearance = theme
- ? theme->appearance() == QPlatformTheme::Appearance::Dark
+ ? theme->appearance() == Qt::Appearance::Dark
: false;
const QColor windowText = darkAppearance ? QColor(240, 240, 240) : Qt::black;
const QColor backGround = darkAppearance ? QColor(50, 50, 50) : QColor(239, 239, 239);
@@ -448,9 +448,9 @@ QPlatformDialogHelper *QPlatformTheme::createPlatformDialogHelper(DialogType typ
return nullptr;
}
-QPlatformTheme::Appearance QPlatformTheme::appearance() const
+Qt::Appearance QPlatformTheme::appearance() const
{
- return Appearance::Unknown;
+ return Qt::Appearance::Unknown;
}
const QPalette *QPlatformTheme::palette(Palette type) const
diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h
index c0dee4c581..41213bf32b 100644
--- a/src/gui/kernel/qplatformtheme.h
+++ b/src/gui/kernel/qplatformtheme.h
@@ -131,12 +131,6 @@ public:
MessageDialog
};
- enum class Appearance {
- Unknown = 0x0000,
- Light = 0x0001,
- Dark = 0x0002
- };
-
enum Palette {
SystemPalette,
ToolTipPalette,
@@ -326,7 +320,7 @@ public:
virtual QString standardButtonText(int button) const;
virtual QKeySequence standardButtonShortcut(int button) const;
- virtual Appearance appearance() const;
+ virtual Qt::Appearance appearance() const;
static QVariant defaultThemeHint(ThemeHint hint);
static QString defaultStandardButtonText(int button);
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.h b/src/plugins/platforms/cocoa/qcocoatheme.h
index f719fd943b..78ff7cb51c 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.h
+++ b/src/plugins/platforms/cocoa/qcocoatheme.h
@@ -73,7 +73,7 @@ public:
QIcon fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions options = {}) const override;
QVariant themeHint(ThemeHint hint) const override;
- Appearance appearance() const override;
+ Qt::Appearance appearance() const override;
QString standardButtonText(int button) const override;
QKeySequence standardButtonShortcut(int button) const override;
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm
index a79fa4e4b9..cd2e7ef90a 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.mm
+++ b/src/plugins/platforms/cocoa/qcocoatheme.mm
@@ -544,9 +544,9 @@ QVariant QCocoaTheme::themeHint(ThemeHint hint) const
return QPlatformTheme::themeHint(hint);
}
-QPlatformTheme::Appearance QCocoaTheme::appearance() const
+Qt::Appearance QCocoaTheme::appearance() const
{
- return qt_mac_applicationIsInDarkMode() ? Appearance::Dark : Appearance::Light;
+ return qt_mac_applicationIsInDarkMode() ? Qt::Appearance::Dark : Qt::Appearance::Light;
}
QString QCocoaTheme::standardButtonText(int button) const
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index 510b8746da..5d006e6ba9 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -520,9 +520,9 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const
return QPlatformTheme::themeHint(hint);
}
-QPlatformTheme::Appearance QWindowsTheme::appearance() const
+Qt::Appearance QWindowsTheme::appearance() const
{
- return QWindowsContext::isDarkMode() ? Appearance::Dark : Appearance::Light;
+ return QWindowsContext::isDarkMode() ? Qt::Appearance::Dark : Qt::Appearance::Light;
}
void QWindowsTheme::clearPalettes()
diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h
index 9d5fcc92fe..ea72c96049 100644
--- a/src/plugins/platforms/windows/qwindowstheme.h
+++ b/src/plugins/platforms/windows/qwindowstheme.h
@@ -65,7 +65,7 @@ public:
#endif
QVariant themeHint(ThemeHint) const override;
- Appearance appearance() const override;
+ Qt::Appearance appearance() const override;
const QPalette *palette(Palette type = SystemPalette) const override
{ return m_palettes[type]; }
diff --git a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
index a47720384c..2a70d5f3dd 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
@@ -148,7 +148,7 @@ QString QGtk3Theme::gtkFontName() const
return QGnomeTheme::gtkFontName();
}
-QPlatformTheme::Appearance QGtk3Theme::appearance() const
+Qt::Appearance QGtk3Theme::appearance() const
{
/*
https://docs.gtk.org/gtk3/running.html
@@ -166,7 +166,7 @@ QPlatformTheme::Appearance QGtk3Theme::appearance() const
QString themeName = qEnvironmentVariable("GTK_THEME");
const QRegularExpression darkRegex(QStringLiteral("[:-]dark"), QRegularExpression::CaseInsensitiveOption);
if (!themeName.isEmpty())
- return darkRegex.match(themeName).hasMatch() ? Appearance::Dark : Appearance::Light;
+ return darkRegex.match(themeName).hasMatch() ? Qt::Appearance::Dark : Qt::Appearance::Light;
/*
https://docs.gtk.org/gtk3/property.Settings.gtk-application-prefer-dark-theme.html
@@ -177,16 +177,16 @@ QPlatformTheme::Appearance QGtk3Theme::appearance() const
*/
const auto preferDark = gtkSetting<bool>("gtk-application-prefer-dark-theme");
if (preferDark)
- return Appearance::Dark;
+ return Qt::Appearance::Dark;
/*
https://docs.gtk.org/gtk3/property.Settings.gtk-theme-name.html
*/
themeName = gtkSetting("gtk-theme-name");
if (!themeName.isEmpty())
- return darkRegex.match(themeName).hasMatch() ? Appearance::Dark : Appearance::Light;
+ return darkRegex.match(themeName).hasMatch() ? Qt::Appearance::Dark : Qt::Appearance::Light;
- return Appearance::Unknown;
+ return Qt::Appearance::Unknown;
}
bool QGtk3Theme::usePlatformNativeDialog(DialogType type) const
diff --git a/src/plugins/platformthemes/gtk3/qgtk3theme.h b/src/plugins/platformthemes/gtk3/qgtk3theme.h
index 5f439067af..89a3b98994 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3theme.h
+++ b/src/plugins/platformthemes/gtk3/qgtk3theme.h
@@ -52,7 +52,7 @@ public:
virtual QVariant themeHint(ThemeHint hint) const override;
virtual QString gtkFontName() const override;
- Appearance appearance() const override;
+ Qt::Appearance appearance() const override;
bool usePlatformNativeDialog(DialogType type) const override;
QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const override;
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index 4171e08286..fa748eb38a 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -303,7 +303,7 @@ static const qreal titleBarButtonSpacing = 8;
// active: window is active
// selected: tab is selected
// hovered: tab is hovered
-bool isDarkMode() { return qt_mac_applicationIsInDarkMode(); }
+bool isDarkMode() { return QGuiApplicationPrivate::platformTheme()->appearance() == Qt::Appearance::Dark; }
#if QT_CONFIG(tabbar)
static const QColor lightTabBarTabBackgroundActive(190, 190, 190);
--
2.41.0

View File

@ -0,0 +1,110 @@
From 168ca696f509e0437550cddb80ea61a5d9ee0f1b Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Wed, 26 Jul 2023 13:04:13 +0200
Subject: [PATCH 09/25] Rename QGuiApplicationPrivate::notifyThemeChanged to
handleThemeChanged
The work done by QGuiApplicationPrivate in response to a theme change
goes beyond notifying.
---
src/gui/kernel/qguiapplication.cpp | 26 +++++++++++++-------------
src/gui/kernel/qguiapplication_p.h | 2 +-
src/widgets/kernel/qapplication.cpp | 4 ++--
src/widgets/kernel/qapplication_p.h | 2 +-
4 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index a217719ea8..ddde913064 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -2563,13 +2563,25 @@ void QGuiApplicationPrivate::processSafeAreaMarginsChangedEvent(QWindowSystemInt
void QGuiApplicationPrivate::processThemeChanged(QWindowSystemInterfacePrivate::ThemeChangeEvent *tce)
{
if (self)
- self->notifyThemeChanged();
+ self->handleThemeChanged();
if (QWindow *window = tce->window.data()) {
QEvent e(QEvent::ThemeChange);
QGuiApplication::sendSpontaneousEvent(window, &e);
}
}
+void QGuiApplicationPrivate::handleThemeChanged()
+{
+ updatePalette();
+
+ if (!(applicationResourceFlags & ApplicationFontExplicitlySet)) {
+ const auto locker = qt_scoped_lock(applicationFontMutex);
+ clearFontUnlocked();
+ initFontUnlocked();
+ }
+ initThemeHints();
+}
+
void QGuiApplicationPrivate::processGeometryChangeEvent(QWindowSystemInterfacePrivate::GeometryChangeEvent *e)
{
if (e->window.isNull())
@@ -4249,18 +4261,6 @@ QPixmap QGuiApplicationPrivate::getPixmapCursor(Qt::CursorShape cshape)
return QPixmap();
}
-void QGuiApplicationPrivate::notifyThemeChanged()
-{
- updatePalette();
-
- if (!(applicationResourceFlags & ApplicationFontExplicitlySet)) {
- const auto locker = qt_scoped_lock(applicationFontMutex);
- clearFontUnlocked();
- initFontUnlocked();
- }
- initThemeHints();
-}
-
#if QT_CONFIG(draganddrop)
void QGuiApplicationPrivate::notifyDragStarted(const QDrag *drag)
{
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 261add1ba4..a13a797ec3 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -327,7 +327,7 @@ public:
static void updatePalette();
protected:
- virtual void notifyThemeChanged();
+ virtual void handleThemeChanged();
static bool setPalette(const QPalette &palette);
virtual QPalette basePalette() const;
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 1a0ac0cc3c..2d3ed99a83 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -4371,9 +4371,9 @@ void QApplicationPrivate::translateTouchCancel(QTouchDevice *device, ulong times
}
}
-void QApplicationPrivate::notifyThemeChanged()
+void QApplicationPrivate::handleThemeChanged()
{
- QGuiApplicationPrivate::notifyThemeChanged();
+ QGuiApplicationPrivate::handleThemeChanged();
qt_init_tooltip_palette();
}
diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h
index ab6d85aeb9..3a7214d01e 100644
--- a/src/widgets/kernel/qapplication_p.h
+++ b/src/widgets/kernel/qapplication_p.h
@@ -160,7 +160,7 @@ public:
static QStyle *app_style;
protected:
- void notifyThemeChanged() override;
+ void handleThemeChanged() override;
QPalette basePalette() const override;
void handlePaletteChanged(const char *className = nullptr) override;
--
2.41.0

View File

@ -0,0 +1,102 @@
From df8ef75321929d429c1f912453b63e85e98455c5 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Wed, 26 Jul 2023 13:30:15 +0200
Subject: [PATCH 10/25] Send ThemeChange event to all windows when system theme
changes
The QWSI event for theme change has an optional window parameter to
specify the window affected, but most platform react to global theme
changes, and end up passing nullptr into the event.
The reasonable thing to do in QGuiApplication in that case is send
a theme change event to every QWindow, so that they are all notified
about the situation.
This approach is what the Windows platform plugin was doing already,
but did so by iterating manually over the windows, resulting in multiple
calls to QGuiApplicationPrivate::handleThemeChanged -- one for each QWSI
event.
---
src/gui/kernel/qguiapplication.cpp | 9 +++++----
src/gui/kernel/qwindowsysteminterface.h | 2 +-
src/plugins/platforms/cocoa/qcocoatheme.mm | 2 +-
src/plugins/platforms/ios/qiosscreen.mm | 2 +-
src/plugins/platforms/windows/qwindowscontext.cpp | 3 +--
5 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index ddde913064..64e44406fb 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -2564,10 +2564,11 @@ void QGuiApplicationPrivate::processThemeChanged(QWindowSystemInterfacePrivate::
{
if (self)
self->handleThemeChanged();
- if (QWindow *window = tce->window.data()) {
- QEvent e(QEvent::ThemeChange);
- QGuiApplication::sendSpontaneousEvent(window, &e);
- }
+
+ QEvent themeChangeEvent(QEvent::ThemeChange);
+ const QWindowList windows = tce->window ? QWindowList{tce->window} : window_list;
+ for (auto *window : windows)
+ QGuiApplication::sendSpontaneousEvent(window, &themeChangeEvent);
}
void QGuiApplicationPrivate::handleThemeChanged()
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index 20baef12c1..5967c8f580 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -250,7 +250,7 @@ public:
static void handleScreenRefreshRateChange(QScreen *screen, qreal newRefreshRate);
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
- static void handleThemeChange(QWindow *window);
+ static void handleThemeChange(QWindow *window = nullptr);
static void handleFileOpenEvent(const QString& fileName);
static void handleFileOpenEvent(const QUrl &url);
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm
index cd2e7ef90a..269b580361 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.mm
+++ b/src/plugins/platforms/cocoa/qcocoatheme.mm
@@ -322,7 +322,7 @@ void QCocoaTheme::handleSystemThemeChange()
QFontCache::instance()->clear();
}
- QWindowSystemInterface::handleThemeChange<QWindowSystemInterface::SynchronousDelivery>(nullptr);
+ QWindowSystemInterface::handleThemeChange<QWindowSystemInterface::SynchronousDelivery>();
}
bool QCocoaTheme::usePlatformNativeDialog(DialogType dialogType) const
diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm
index a83d495043..6f0858a4a0 100644
--- a/src/plugins/platforms/ios/qiosscreen.mm
+++ b/src/plugins/platforms/ios/qiosscreen.mm
@@ -216,7 +216,7 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen)
if (self.screen == UIScreen.mainScreen) {
if (previousTraitCollection.userInterfaceStyle != self.traitCollection.userInterfaceStyle) {
QIOSTheme::initializeSystemPalette();
- QWindowSystemInterface::handleThemeChange<QWindowSystemInterface::SynchronousDelivery>(nullptr);
+ QWindowSystemInterface::handleThemeChange<QWindowSystemInterface::SynchronousDelivery>();
}
}
}
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index d5c3022080..cc9857673b 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -1237,8 +1237,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
}
if ((options & QWindowsIntegration::DarkModeStyle) != 0) {
QWindowsTheme::instance()->refresh();
- for (QWindowsWindow *w : d->m_windows)
- QWindowSystemInterface::handleThemeChange(w->window());
+ QWindowSystemInterface::handleThemeChange();
}
}
return d->m_screenManager.handleScreenChanges();
--
2.41.0

View File

@ -0,0 +1,261 @@
From dc53c50184021944e26a3986236f37a7868951ad Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Wed, 26 Jul 2023 13:38:50 +0200
Subject: [PATCH 11/25] Propagate appearance property from QPlatformTheme to
QStyleHints
Implement appearance property, getter and notifier in QStyleHints.
Update appearance property in QStyleHints when handling theme
change in QGuiApplicationPrivate.
---
.../5.15.10/QtGui/private/qstylehints_p.h | 1 +
src/gui/kernel/kernel.pri | 1 +
src/gui/kernel/qguiapplication.cpp | 16 ++++++
src/gui/kernel/qguiapplication_p.h | 2 +
src/gui/kernel/qstylehints.cpp | 51 +++++++++++-------
src/gui/kernel/qstylehints.h | 3 ++
src/gui/kernel/qstylehints_p.h | 53 +++++++++++++++++++
7 files changed, 108 insertions(+), 19 deletions(-)
create mode 100644 include/QtGui/5.15.10/QtGui/private/qstylehints_p.h
create mode 100644 src/gui/kernel/qstylehints_p.h
diff --git a/include/QtGui/5.15.10/QtGui/private/qstylehints_p.h b/include/QtGui/5.15.10/QtGui/private/qstylehints_p.h
new file mode 100644
index 0000000000..fa8b8505a6
--- /dev/null
+++ b/include/QtGui/5.15.10/QtGui/private/qstylehints_p.h
@@ -0,0 +1 @@
+#include "../../../../../src/gui/kernel/qstylehints_p.h"
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index 9c80f1e2cc..af9385b120 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -59,6 +59,7 @@ HEADERS += \
kernel/qscreen.h \
kernel/qscreen_p.h \
kernel/qstylehints.h \
+ kernel/qstylehints_p.h \
kernel/qtouchdevice.h \
kernel/qtouchdevice_p.h \
kernel/qplatformsharedgraphicscache.h \
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 64e44406fb..7c942dc233 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -74,6 +74,7 @@
#include <QtGui/qgenericpluginfactory.h>
#include <QtGui/qstylehints.h>
+#include <QtGui/private/qstylehints_p.h>
#include <QtGui/qinputmethod.h>
#include <QtGui/qpixmapcache.h>
#include <qpa/qplatforminputcontext.h>
@@ -2569,6 +2570,21 @@ void QGuiApplicationPrivate::processThemeChanged(QWindowSystemInterfacePrivate::
const QWindowList windows = tce->window ? QWindowList{tce->window} : window_list;
for (auto *window : windows)
QGuiApplication::sendSpontaneousEvent(window, &themeChangeEvent);
+
+ QStyleHintsPrivate::get(QGuiApplication::styleHints())->setAppearance(appearance());
+}
+
+/*!
+ \internal
+ \brief QGuiApplicationPrivate::appearance
+ \return the platform theme's appearance
+ or Qt::Appearance::Unknown if a platform theme cannot be established
+ Qt::Appearance.
+ */
+Qt::Appearance QGuiApplicationPrivate::appearance()
+{
+ return platformTheme() ? platformTheme()->appearance()
+ : Qt::Appearance::Unknown;
}
void QGuiApplicationPrivate::handleThemeChanged()
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index a13a797ec3..1e7f826c5b 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -343,6 +343,8 @@ private:
friend class QDragManager;
+ static Qt::Appearance appearance();
+
static QGuiApplicationPrivate *self;
static QTouchDevice *m_fakeTouchDevice;
static int m_fakeMouseSourcePointId;
diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp
index 288bdf1b3c..d4766227ef 100644
--- a/src/gui/kernel/qstylehints.cpp
+++ b/src/gui/kernel/qstylehints.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include <qstylehints.h>
+#include "qstylehints_p.h"
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformtheme.h>
#include <private/qguiapplication_p.h>
@@ -79,25 +80,6 @@ static inline QVariant themeableHint(QPlatformTheme::ThemeHint th)
return QPlatformTheme::defaultThemeHint(th);
}
-class QStyleHintsPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QStyleHints)
-public:
- int m_mouseDoubleClickInterval = -1;
- int m_mousePressAndHoldInterval = -1;
- int m_startDragDistance = -1;
- int m_startDragTime = -1;
- int m_keyboardInputInterval = -1;
- int m_cursorFlashTime = -1;
- int m_tabFocusBehavior = -1;
- int m_uiEffects = -1;
- int m_showShortcutsInContextMenus = -1;
- int m_wheelScrollLines = -1;
- int m_mouseQuickSelectionThreshold = -1;
- int m_mouseDoubleClickDistance = -1;
- int m_touchDoubleTapDistance = -1;
-};
-
/*!
\class QStyleHints
\since 5.0
@@ -176,6 +158,17 @@ int QStyleHints::touchDoubleTapDistance() const
themeableHint(QPlatformTheme::TouchDoubleTapDistance).toInt();
}
+/*!
+ \property QStyleHints::appearance
+ \brief the appearance of the platform theme
+ \sa Qt::Appearance
+ \since 6.5
+*/
+Qt::Appearance QStyleHints::appearance() const
+{
+ return d_func()->appearance();
+}
+
/*!
Sets the \a mousePressAndHoldInterval.
\internal
@@ -620,6 +613,26 @@ int QStyleHints::mouseQuickSelectionThreshold() const
return themeableHint(QPlatformTheme::MouseQuickSelectionThreshold, QPlatformIntegration::MouseQuickSelectionThreshold).toInt();
}
+/*!
+ \internal
+ QStyleHintsPrivate::setAppearance - set a new appearance.
+ Set \a appearance as the new appearance of the QStyleHints.
+ The appearanceChanged signal will be emitted if present and new appearance differ.
+ */
+void QStyleHintsPrivate::setAppearance(Qt::Appearance appearance)
+{
+ if (m_appearance != appearance) {
+ m_appearance = appearance;
+ emit q_func()->appearanceChanged(appearance);
+ }
+}
+
+QStyleHintsPrivate *QStyleHintsPrivate::get(QStyleHints *q)
+{
+ Q_ASSERT(q);
+ return q->d_func();
+}
+
QT_END_NAMESPACE
#include "moc_qstylehints.cpp"
diff --git a/src/gui/kernel/qstylehints.h b/src/gui/kernel/qstylehints.h
index 30d8fdc64d..3cd540b27a 100644
--- a/src/gui/kernel/qstylehints.h
+++ b/src/gui/kernel/qstylehints.h
@@ -76,6 +76,7 @@ class Q_GUI_EXPORT QStyleHints : public QObject
Q_PROPERTY(int mouseQuickSelectionThreshold READ mouseQuickSelectionThreshold WRITE setMouseQuickSelectionThreshold NOTIFY mouseQuickSelectionThresholdChanged FINAL)
Q_PROPERTY(int mouseDoubleClickDistance READ mouseDoubleClickDistance STORED false CONSTANT FINAL)
Q_PROPERTY(int touchDoubleTapDistance READ touchDoubleTapDistance STORED false CONSTANT FINAL)
+ Q_PROPERTY(Qt::Appearance appearance READ appearance NOTIFY appearanceChanged FINAL)
public:
void setMouseDoubleClickInterval(int mouseDoubleClickInterval);
@@ -112,6 +113,7 @@ public:
void setWheelScrollLines(int scrollLines);
void setMouseQuickSelectionThreshold(int threshold);
int mouseQuickSelectionThreshold() const;
+ Qt::Appearance appearance() const;
Q_SIGNALS:
void cursorFlashTimeChanged(int cursorFlashTime);
@@ -125,6 +127,7 @@ Q_SIGNALS:
void showShortcutsInContextMenusChanged(bool);
void wheelScrollLinesChanged(int scrollLines);
void mouseQuickSelectionThresholdChanged(int threshold);
+ void appearanceChanged(Qt::Appearance appearance);
private:
friend class QGuiApplication;
diff --git a/src/gui/kernel/qstylehints_p.h b/src/gui/kernel/qstylehints_p.h
new file mode 100644
index 0000000000..4a16fbef01
--- /dev/null
+++ b/src/gui/kernel/qstylehints_p.h
@@ -0,0 +1,53 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QSTYLEHINTS_P_H
+#define QSTYLEHINTS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qpa/qplatformintegration.h>
+#include <QPalette>
+#include <private/qguiapplication_p.h>
+#include "qstylehints.h"
+
+QT_BEGIN_NAMESPACE
+
+class QStyleHintsPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QStyleHints)
+public:
+ int m_mouseDoubleClickInterval = -1;
+ int m_mousePressAndHoldInterval = -1;
+ int m_startDragDistance = -1;
+ int m_startDragTime = -1;
+ int m_keyboardInputInterval = -1;
+ int m_cursorFlashTime = -1;
+ int m_tabFocusBehavior = -1;
+ int m_uiEffects = -1;
+ int m_showShortcutsInContextMenus = -1;
+ int m_wheelScrollLines = -1;
+ int m_mouseQuickSelectionThreshold = -1;
+ int m_mouseDoubleClickDistance = -1;
+ int m_touchDoubleTapDistance = -1;
+
+ Qt::Appearance appearance() const { return m_appearance; };
+ void setAppearance(Qt::Appearance appearance);
+ static QStyleHintsPrivate *get(QStyleHints *q);
+
+private:
+ Qt::Appearance m_appearance = Qt::Appearance::Unknown;
+};
+
+QT_END_NAMESPACE
+
+#endif
--
2.41.0

View File

@ -0,0 +1,78 @@
From 8c9d7b5f33707803b67c737afa18c80e5a4cf229 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Wed, 26 Jul 2023 13:43:29 +0200
Subject: [PATCH 12/25] Sync and assert StandardPixmap enums in QPlatformTheme
and QStyle
Add missing enum values in QPlatformTheme::standardPixmap to sync with
QStyle::standardPixmap changes from:
785d2b9d0728bbbc0d2a92b7d4186a3114d54128
aa5a595a98f1af4a514485268a18e6cb9cfec783
Add enum values NStandardPixmap at the bottom of both enums as well
as an assertion in QStyle constructor that these values are identical.
Add omitvalue for NStandardPixmap in QStyle (QPlatformTheme enum is
not documented).
---
src/gui/kernel/qplatformtheme.h | 9 +++++++++
src/widgets/styles/qstyle.cpp | 4 ++++
src/widgets/styles/qstyle.h | 1 +
3 files changed, 14 insertions(+)
diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h
index 41213bf32b..210bd40afa 100644
--- a/src/gui/kernel/qplatformtheme.h
+++ b/src/gui/kernel/qplatformtheme.h
@@ -256,6 +256,15 @@ public:
MediaVolume,
MediaVolumeMuted,
LineEditClearButton,
+ DialogYesToAllButton,
+ DialogNoToAllButton,
+ DialogSaveAllButton,
+ DialogAbortButton,
+ DialogRetryButton,
+ DialogIgnoreButton,
+ RestoreDefaultsButton,
+ NStandardPixmap, // assertion value for sync with QStyle::StandardPixmap
+
// do not add any values below/greater than this
CustomBase = 0xf0000000
};
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index 669f158b7b..18d21a843d 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -412,6 +412,9 @@ QStyle::QStyle(QStylePrivate &dd)
{
Q_D(QStyle);
d->proxyStyle = this;
+ Q_STATIC_ASSERT_X(int(StandardPixmap::NStandardPixmap) ==
+ int(QPlatformTheme::StandardPixmap::NStandardPixmap),
+ "StandardPixmap in QPlatformTheme and QStyle out of sync");
}
/*!
@@ -2117,6 +2120,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
This enum value was added in Qt 5.14.
\value SP_RestoreDefaultsButton Icon for a standard RestoreDefaults button in a QDialogButtonBox.
This enum value was added in Qt 5.14.
+ \omitvalue NStandardPixmap
\value SP_CustomBase Base value for custom standard pixmaps;
custom values must be greater than this value.
diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h
index 5be1b4b290..9d98f76152 100644
--- a/src/widgets/styles/qstyle.h
+++ b/src/widgets/styles/qstyle.h
@@ -845,6 +845,7 @@ public:
SP_DialogRetryButton,
SP_DialogIgnoreButton,
SP_RestoreDefaultsButton,
+ NStandardPixmap, // assertion value for sync with QPlatformTheme::StandardPixmap
// do not add any values below/greater than this
SP_CustomBase = 0xf0000000
};
--
2.41.0

View File

@ -0,0 +1,50 @@
From 544c063ad74bfcc5c8e9f7d6c2f4e7b6301df497 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Wed, 26 Jul 2023 15:38:13 +0200
Subject: [PATCH 13/25] QGtk3Theme: subscribe to theme hint changes
---
.../platformthemes/gtk3/qgtk3theme.cpp | 20 +++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
index 2a70d5f3dd..0e940ae690 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
@@ -40,6 +40,7 @@
#include "qgtk3theme.h"
#include "qgtk3dialoghelpers.h"
#include "qgtk3menu.h"
+#include "qpa/qwindowsysteminterface.h"
#include <QVariant>
#include <QtCore/qregularexpression.h>
@@ -101,6 +102,25 @@ QGtk3Theme::QGtk3Theme()
/* Use our custom log handler. */
g_log_set_handler("Gtk", G_LOG_LEVEL_MESSAGE, gtkMessageHandler, nullptr);
+
+#define SETTING_CONNECT(setting) g_signal_connect(settings, "notify::" setting, G_CALLBACK(notifyThemeChanged), nullptr)
+ auto notifyThemeChanged = [] {
+ QWindowSystemInterface::handleThemeChange(nullptr);
+ };
+
+ GtkSettings *settings = gtk_settings_get_default();
+ SETTING_CONNECT("gtk-cursor-blink-time");
+ SETTING_CONNECT("gtk-double-click-distance");
+ SETTING_CONNECT("gtk-double-click-time");
+ SETTING_CONNECT("gtk-long-press-time");
+ SETTING_CONNECT("gtk-entry-password-hint-timeout");
+ SETTING_CONNECT("gtk-dnd-drag-threshold");
+ SETTING_CONNECT("gtk-icon-theme-name");
+ SETTING_CONNECT("gtk-fallback-icon-theme");
+ SETTING_CONNECT("gtk-font-name");
+ SETTING_CONNECT("gtk-application-prefer-dark-theme");
+ SETTING_CONNECT("gtk-theme-name");
+#undef SETTING_CONNECT
}
static inline QVariant gtkGetLongPressTime()
--
2.41.0

View File

@ -0,0 +1,54 @@
From ff4c01410f56001c59ed9628d7365a44019ce85c Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Wed, 26 Jul 2023 15:38:38 +0200
Subject: [PATCH 14/25] Gtk3Theme: set XCURSOR_SIZE and XCURSOR_THEME for
wayland sessions
GNOME doesn't set these for Wayland session and without those env
variables set users might experience broken cursor with Qt apps
as QWayland reads them to setup QWaylandInputDevice.
There is no cursor protocol available on Wayland yet, see also
https://gitlab.freedesktop.org/wayland/wayland-protocols/-/issues/58
Qt Wayland QPA plugin still tries to load from those two envs.
---
src/plugins/platformthemes/gtk3/qgtk3theme.cpp | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
index 0e940ae690..8688fe205e 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
@@ -41,6 +41,7 @@
#include "qgtk3dialoghelpers.h"
#include "qgtk3menu.h"
#include "qpa/qwindowsysteminterface.h"
+#include <QGuiApplication>
#include <QVariant>
#include <QtCore/qregularexpression.h>
@@ -121,6 +122,20 @@ QGtk3Theme::QGtk3Theme()
SETTING_CONNECT("gtk-application-prefer-dark-theme");
SETTING_CONNECT("gtk-theme-name");
#undef SETTING_CONNECT
+
+ /* Set XCURSOR_SIZE and XCURSOR_THEME for Wayland sessions */
+ if (QGuiApplication::platformName().startsWith("wayland")) {
+ if (qEnvironmentVariableIsEmpty("XCURSOR_SIZE")) {
+ const int cursorSize = gtkSetting<gint>("gtk-cursor-theme-size");
+ if (cursorSize > 0)
+ qputenv("XCURSOR_SIZE", QString::number(cursorSize).toUtf8());
+ }
+ if (qEnvironmentVariableIsEmpty("XCURSOR_THEME")) {
+ const QString cursorTheme = gtkSetting("gtk-cursor-theme-name");
+ if (!cursorTheme.isEmpty())
+ qputenv("XCURSOR_THEME", cursorTheme.toUtf8());
+ }
+ }
}
static inline QVariant gtkGetLongPressTime()
--
2.41.0

View File

@ -0,0 +1,29 @@
From fc0d325fee69cc3fa5f415b1e83592376adeb061 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Wed, 26 Jul 2023 15:39:31 +0200
Subject: [PATCH 15/25] Gtk3: fix stack smashing on mismatch between bool and
gboolean
Glib is written in C and predates C99 (though not really, glib 2.0 was
released in 2002), so it defines gboolean as int, a 4-byte type. C++'s
bool is a 1-byte type, so this caused a buffer overflow.
---
src/plugins/platformthemes/gtk3/qgtk3theme.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
index 8688fe205e..c01947e402 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
@@ -210,7 +210,7 @@ Qt::Appearance QGtk3Theme::appearance() const
gtk-theme-name provides both light and dark variants. We can save a
regex check by testing this property first.
*/
- const auto preferDark = gtkSetting<bool>("gtk-application-prefer-dark-theme");
+ const auto preferDark = gtkSetting<gboolean>("gtk-application-prefer-dark-theme");
if (preferDark)
return Qt::Appearance::Dark;
--
2.41.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,27 @@
From 01ae45ce9cca19e96875eda74bf6b9168f90e464 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Thu, 27 Jul 2023 12:35:44 +0200
Subject: [PATCH 17/25] GTK3 theme: simplify code
There's no need to first convert to QString and then convert back to
QByteArray.
---
src/plugins/platformthemes/gtk3/qgtk3theme.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
index 5d9fc24d71..fcd466f768 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
@@ -128,7 +128,7 @@ QGtk3Theme::QGtk3Theme()
if (qEnvironmentVariableIsEmpty("XCURSOR_SIZE")) {
const int cursorSize = gtkSetting<gint>("gtk-cursor-theme-size");
if (cursorSize > 0)
- qputenv("XCURSOR_SIZE", QString::number(cursorSize).toUtf8());
+ qputenv("XCURSOR_SIZE", QByteArray::number(cursorSize));
}
if (qEnvironmentVariableIsEmpty("XCURSOR_THEME")) {
const QString cursorTheme = gtkSetting("gtk-cursor-theme-name");
--
2.41.0

View File

@ -0,0 +1,48 @@
From f44986a54facefafeed851a7db902867f701208b Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Thu, 27 Jul 2023 12:36:14 +0200
Subject: [PATCH 18/25] Fix checkbox and radiobutton background in QGtk3Theme
The background color for radio buttons and checkboxes was not
correctly read from the current GTK3 theme in light mode.
This has lead to identical colors for indicators and background of
radio buttons and checkboxes for certain GTK themes (e.g. Breeze).
This patch sets the GTK default foreground color to the base color of
palettes for checkboxes and radio buttons.
---
src/plugins/platformthemes/gtk3/qgtk3storage.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/plugins/platformthemes/gtk3/qgtk3storage.cpp b/src/plugins/platformthemes/gtk3/qgtk3storage.cpp
index 55c7c8eff8..1a9f88f6df 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3storage.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3storage.cpp
@@ -377,7 +377,6 @@ void QGtk3Storage::createMapping()
ADD(Normal, Button);
ADD(Normal, Base);
ADD(Inactive, Base);
- ADD(Normal, Window); // redundant
ADD(Inactive, Window);
LIGHTER(Normal, Window, 125);
ADD(Normal, Light);
@@ -391,7 +390,6 @@ void QGtk3Storage::createMapping()
LIGHTER(Normal, WindowText, 50);
ADD(Disabled, Text);
ADD(Disabled, WindowText);
- //ADD(Normal, ButtonText);
ADD(Inactive, ButtonText);
GTK(button, Text, NORMAL);
ADD(Disabled, ButtonText);
@@ -427,6 +425,8 @@ void QGtk3Storage::createMapping()
// Checkbox and Radio Button
GTK(button, Text, ACTIVE);
ADD(Normal, Base, Dark);
+ GTK(Default, Background, NORMAL);
+ ADD(All, Base);
GTK(button, Text, NORMAL);
ADD(Normal, Base, Light);
SAVE(CheckBoxPalette);
--
2.41.0

View File

@ -0,0 +1,108 @@
From e35349100e0f8fc21643c0fa514af5f6f8950097 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Thu, 27 Jul 2023 12:38:53 +0200
Subject: [PATCH 19/25] Cleanup QGtk3Theme
1. Remove unused include.
2. Replace unnecessary null checks with asserts.
3. Remove dead code after the cleanup.
---
.../platformthemes/gtk3/qgtk3theme.cpp | 55 ++++---------------
1 file changed, 10 insertions(+), 45 deletions(-)
diff --git a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
index fcd466f768..d3383097fc 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
@@ -43,7 +43,6 @@
#include "qpa/qwindowsysteminterface.h"
#include <QGuiApplication>
#include <QVariant>
-#include <QtCore/qregularexpression.h>
#undef signals
#include <gtk/gtk.h>
@@ -187,46 +186,8 @@ QString QGtk3Theme::gtkFontName() const
Qt::Appearance QGtk3Theme::appearance() const
{
- if (m_storage)
- return m_storage->appearance();
- /*
- https://docs.gtk.org/gtk3/running.html
-
- It's possible to set a theme variant after the theme name when using GTK_THEME:
-
- GTK_THEME=Adwaita:dark
-
- Some themes also have "-dark" as part of their name.
-
- We test this environment variable first because the documentation says
- it's mainly used for easy debugging, so it should be possible to use it
- to override any other settings.
- */
- QString themeName = qEnvironmentVariable("GTK_THEME");
- if (!themeName.isEmpty())
- return themeName.contains("dark", Qt::CaseInsensitive)
- ? Qt::Appearance::Dark : Qt::Appearance::Light;
-
- /*
- https://docs.gtk.org/gtk3/property.Settings.gtk-application-prefer-dark-theme.html
-
- This setting controls which theme is used when the theme specified by
- gtk-theme-name provides both light and dark variants. We can save a
- regex check by testing this property first.
- */
- const auto preferDark = gtkSetting<gboolean>("gtk-application-prefer-dark-theme");
- if (preferDark)
- return Qt::Appearance::Dark;
-
- /*
- https://docs.gtk.org/gtk3/property.Settings.gtk-theme-name.html
- */
- themeName = gtkSetting("gtk-theme-name");
- if (!themeName.isEmpty())
- return themeName.contains("dark", Qt::CaseInsensitive)
- ? Qt::Appearance::Dark : Qt::Appearance::Light;
-
- return Qt::Appearance::Unknown;
+ Q_ASSERT(m_storage);
+ return m_storage->appearance();
}
bool QGtk3Theme::usePlatformNativeDialog(DialogType type) const
@@ -284,23 +245,27 @@ bool QGtk3Theme::useNativeFileDialog()
const QPalette *QGtk3Theme::palette(Palette type) const
{
- return m_storage ? m_storage->palette(type) : QPlatformTheme::palette(type);
+ Q_ASSERT(m_storage);
+ return m_storage->palette(type);
}
QPixmap QGtk3Theme::standardPixmap(StandardPixmap sp, const QSizeF &size) const
{
- return m_storage ? m_storage->standardPixmap(sp, size) : QPlatformTheme::standardPixmap(sp, size);
+ Q_ASSERT(m_storage);
+ return m_storage->standardPixmap(sp, size);
}
const QFont *QGtk3Theme::font(Font type) const
{
- return m_storage ? m_storage->font(type) : QGnomeTheme::font(type);
+ Q_ASSERT(m_storage);
+ return m_storage->font(type);
}
QIcon QGtk3Theme::fileIcon(const QFileInfo &fileInfo,
QPlatformTheme::IconOptions iconOptions) const
{
- return m_storage ? m_storage->fileIcon(fileInfo) : QGnomeTheme::fileIcon(fileInfo, iconOptions);
+ Q_ASSERT(m_storage);
+ return m_storage->fileIcon(fileInfo);
}
QT_END_NAMESPACE
--
2.41.0

View File

@ -0,0 +1,85 @@
From 45a629fb6495c2469c89e1bf797ee84214e7e661 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Thu, 27 Jul 2023 12:40:32 +0200
Subject: [PATCH 20/25] Detect appearance by colors unless GTK theme name
contains "dark"
QGtk3Theme detects the appearance property by theme name: If the name
contains the keyword "dark", the theme is considered to be dark and
otherwise light.
This detection logic fails, when the GTK theme is dark without
containing the "dark" keyword, e.g. the dark theme "Adapta-Nokto".
While QGtk3Theme imports the right colors in that case, it wrongly
identifies a light theme.
This patch adapts the detection logic: If the theme name contains the
"dark" keyword, it is considered a dark theme without further checks.
If it doesn't, the current GTK3 theme's default background and
foreground colors will be read. If the foreground is lighter than the
background, the theme is considered dark. If the background is lighter
than the foreground, the theme is considered light. If both colors are
identical, the appearance will be Qt::Appearance::Unknown.
---
.../platformthemes/gtk3/qgtk3interface.cpp | 16 ++++++++++++++++
.../platformthemes/gtk3/qgtk3interface_p.h | 3 +++
src/plugins/platformthemes/gtk3/qgtk3storage.cpp | 2 +-
3 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/src/plugins/platformthemes/gtk3/qgtk3interface.cpp b/src/plugins/platformthemes/gtk3/qgtk3interface.cpp
index d932b250a5..e2444197da 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3interface.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3interface.cpp
@@ -400,6 +400,22 @@ const QString QGtk3Interface::themeName() const
return QLatin1String(theme_name);
}
+Qt::Appearance QGtk3Interface::appearanceByColors() const
+{
+ const QColor background = color(widget(QGtkWidget::gtk_Default),
+ QGtkColorSource::Background,
+ GTK_STATE_FLAG_ACTIVE);
+ const QColor foreground = color(widget(QGtkWidget::gtk_Default),
+ QGtkColorSource::Foreground,
+ GTK_STATE_FLAG_ACTIVE);
+
+ if (foreground.lightness() > background.lightness())
+ return Qt::Appearance::Dark;
+ if (foreground.lightness() < background.lightness())
+ return Qt::Appearance::Light;
+ return Qt::Appearance::Unknown;
+}
+
inline constexpr QGtk3Interface::QGtkWidget QGtk3Interface::toWidgetType(QPlatformTheme::Font type)
{
switch (type) {
diff --git a/src/plugins/platformthemes/gtk3/qgtk3interface_p.h b/src/plugins/platformthemes/gtk3/qgtk3interface_p.h
index 8997a64e76..e04025923d 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3interface_p.h
+++ b/src/plugins/platformthemes/gtk3/qgtk3interface_p.h
@@ -97,6 +97,9 @@ public:
// Return current GTK theme name
const QString themeName() const;
+ // Derive appearance from default colors
+ Qt::Appearance appearanceByColors() const;
+
// Convert GTK state to/from string
static int toGtkState(const QString &state);
static const QLatin1String fromGtkState(GtkStateFlags state);
diff --git a/src/plugins/platformthemes/gtk3/qgtk3storage.cpp b/src/plugins/platformthemes/gtk3/qgtk3storage.cpp
index 1a9f88f6df..c206b4d3b5 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3storage.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3storage.cpp
@@ -222,7 +222,7 @@ void QGtk3Storage::populateMap()
// Derive appearance from theme name
m_appearance = newThemeName.contains("dark", Qt::CaseInsensitive)
- ? Qt::Appearance::Dark : Qt::Appearance::Light;
+ ? Qt::Appearance::Dark : m_interface->appearanceByColors();
if (m_themeName.isEmpty()) {
qCDebug(lcQGtk3Interface) << "GTK theme initialized:" << newThemeName << m_appearance;
--
2.41.0

View File

@ -0,0 +1,120 @@
From 3491415f1e2f60cae47273af4810db1bfda81394 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Thu, 27 Jul 2023 12:41:06 +0200
Subject: [PATCH 21/25] Change parsing log output in QGtk3Json from qCDebug to
qCInfo
When a palette mapping is imported from a Json file, parsing errors are
logged with qCDebug. This prevents errors from being logged in release
builds.
This patch replaces qCDebug with qCInfo for Json parsing to make errors
visible when the logging category qt.qpa.gtk is activated.
---
src/plugins/platformthemes/gtk3/qgtk3json.cpp | 23 +++++++++----------
1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/src/plugins/platformthemes/gtk3/qgtk3json.cpp b/src/plugins/platformthemes/gtk3/qgtk3json.cpp
index f4d5b50ec5..9db1ea3d20 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3json.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3json.cpp
@@ -331,7 +331,7 @@ bool QGtk3Json::load(QGtk3Storage::PaletteMap &map, const QJsonDocument &doc)
{
#define GETSTR(obj, key)\
if (!obj.contains(key)) {\
- qCDebug(lcQGtk3Interface) << key << "missing for palette" << paletteName\
+ qCInfo(lcQGtk3Interface) << key << "missing for palette" << paletteName\
<< ", Brush" << colorRoleName;\
return false;\
}\
@@ -339,7 +339,7 @@ bool QGtk3Json::load(QGtk3Storage::PaletteMap &map, const QJsonDocument &doc)
#define GETINT(obj, key, var) GETSTR(obj, key);\
if (!obj[key].isDouble()) {\
- qCDebug(lcQGtk3Interface) << key << "type mismatch" << value\
+ qCInfo(lcQGtk3Interface) << key << "type mismatch" << value\
<< "is not an integer!"\
<< "(Palette" << paletteName << "), Brush" << colorRoleName;\
return false;\
@@ -349,7 +349,7 @@ bool QGtk3Json::load(QGtk3Storage::PaletteMap &map, const QJsonDocument &doc)
map.clear();
const QJsonObject top(doc.object());
if (doc.isEmpty() || top.isEmpty() || !top.contains(cePalettes)) {
- qCDebug(lcQGtk3Interface) << "Document does not contain Palettes.";
+ qCInfo(lcQGtk3Interface) << "Document does not contain Palettes.";
return false;
}
@@ -358,13 +358,12 @@ bool QGtk3Json::load(QGtk3Storage::PaletteMap &map, const QJsonDocument &doc)
bool ok;
const QPlatformTheme::Palette paletteType = toPalette(paletteName);
if (paletteType == QPlatformTheme::NPalettes) {
- qCDebug(lcQGtk3Interface) << "Invalid Palette name:" << paletteName;
- return false;
+ qCInfo(lcQGtk3Interface) << "Invalid Palette name:" << paletteName;
}
const QJsonObject &paletteObject = top[cePalettes][paletteName].toObject();
const QStringList &brushList = paletteObject.keys();
if (brushList.isEmpty()) {
- qCDebug(lcQGtk3Interface) << "Palette" << paletteName << "does not contain brushes";
+ qCInfo(lcQGtk3Interface) << "Palette" << paletteName << "does not contain brushes";
return false;
}
@@ -374,7 +373,7 @@ bool QGtk3Json::load(QGtk3Storage::PaletteMap &map, const QJsonDocument &doc)
const int intVal = QMetaEnum::fromType<QPalette::ColorRole>().keyToValue(colorRoleName
.toLatin1().constData(), &ok);
if (!ok) {
- qCDebug(lcQGtk3Interface) << "Palette" << paletteName
+ qCInfo(lcQGtk3Interface) << "Palette" << paletteName
<< "contains invalid color role" << colorRoleName;
return false;
}
@@ -383,7 +382,7 @@ bool QGtk3Json::load(QGtk3Storage::PaletteMap &map, const QJsonDocument &doc)
for (int brushIndex = 0; brushIndex < brushArray.size(); ++brushIndex) {
const QJsonObject brushObject = brushArray.at(brushIndex).toObject();
if (brushObject.isEmpty()) {
- qCDebug(lcQGtk3Interface) << "Brush specification missing at for palette"
+ qCInfo(lcQGtk3Interface) << "Brush specification missing at for palette"
<< paletteName << ", Brush" << colorRoleName;
return false;
}
@@ -399,7 +398,7 @@ bool QGtk3Json::load(QGtk3Storage::PaletteMap &map, const QJsonDocument &doc)
QGtk3Storage::Source s;
if (!brushObject.contains(ceData) || !brushObject[ceData].isObject()) {
- qCDebug(lcQGtk3Interface) << "Source specification missing for palette" << paletteName
+ qCInfo(lcQGtk3Interface) << "Source specification missing for palette" << paletteName
<< "Brush" << colorRoleName;
return false;
}
@@ -421,7 +420,7 @@ bool QGtk3Json::load(QGtk3Storage::PaletteMap &map, const QJsonDocument &doc)
case QGtk3Storage::SourceType::Fixed: {
if (!sourceObject.contains(ceBrush)) {
- qCDebug(lcQGtk3Interface) << "Fixed brush specification missing for palette" << paletteName
+ qCInfo(lcQGtk3Interface) << "Fixed brush specification missing for palette" << paletteName
<< "Brush" << colorRoleName;
return false;
}
@@ -431,7 +430,7 @@ bool QGtk3Json::load(QGtk3Storage::PaletteMap &map, const QJsonDocument &doc)
GETSTR(fixedSource, ceColor);
const QColor color(value);
if (!color.isValid()) {
- qCDebug(lcQGtk3Interface) << "Color" << value << "can't be parsed for:" << paletteName
+ qCInfo(lcQGtk3Interface) << "Color" << value << "can't be parsed for:" << paletteName
<< "Brush" << colorRoleName;
return false;
}
@@ -459,7 +458,7 @@ bool QGtk3Json::load(QGtk3Storage::PaletteMap &map, const QJsonDocument &doc)
break;
case QGtk3Storage::SourceType::Invalid:
- qCDebug(lcQGtk3Interface) << "Invalid source type for palette" << paletteName
+ qInfo(lcQGtk3Interface) << "Invalid source type for palette" << paletteName
<< "Brush." << colorRoleName;
return false;
}
--
2.41.0

View File

@ -0,0 +1,400 @@
From e22d4e2a63976fe6f88266d8f2bde002b12b0744 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Thu, 27 Jul 2023 12:42:04 +0200
Subject: [PATCH 22/25] Document QGtk3Interface
Add internal documentation to header and implementation of
QGtk3Interface
---
.../platformthemes/gtk3/qgtk3interface.cpp | 161 ++++++++++++++++--
.../platformthemes/gtk3/qgtk3interface_p.h | 43 ++++-
2 files changed, 183 insertions(+), 21 deletions(-)
diff --git a/src/plugins/platformthemes/gtk3/qgtk3interface.cpp b/src/plugins/platformthemes/gtk3/qgtk3interface.cpp
index e2444197da..0fab1220b4 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3interface.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3interface.cpp
@@ -65,6 +65,14 @@ QGtk3Interface::~QGtk3Interface()
gtk_widget_destroy(v.second);
}
+/*!
+ \internal
+ \brief Converts a string into the GtkStateFlags enum.
+
+ Converts a string formatted GTK color \param state into an enum value.
+ Returns an integer corresponding to GtkStateFlags.
+ Returns -1 if \param state does not correspond to a valid enum key.
+ */
int QGtk3Interface::toGtkState(const QString &state)
{
#define CASE(x) \
@@ -92,6 +100,10 @@ int QGtk3Interface::toGtkState(const QString &state)
#undef CASE
}
+/*!
+ \internal
+ \brief Returns \param state converted into a string.
+ */
const QLatin1String QGtk3Interface::fromGtkState(GtkStateFlags state)
{
#define CASE(x) case GTK_STATE_FLAG_ ##x: return QLatin1String(#x)
@@ -103,9 +115,12 @@ const QLatin1String QGtk3Interface::fromGtkState(GtkStateFlags state)
#undef CONVERT
}
+/*!
+ \internal
+ \brief Populates the internal map used to find a GTK color's source and fallback generic color.
+ */
void QGtk3Interface::initColorMap()
{
- // Populate map with default values
#define SAVE(src, state, prop, def)\
{ColorKey({QGtkColorSource::src, GTK_STATE_FLAG_ ##state}), ColorValue({#prop, QGtkColorDefault::def})}
@@ -132,8 +147,17 @@ void QGtk3Interface::initColorMap()
qCDebug(lcQGtk3Interface) << "Color map populated from defaults.";
}
-// Return an image rather than an icon or a pixmap:
-// Image can be cached and re-scaled to different sizes if requested multiple times
+/*!
+ \internal
+ \brief Returns a QImage corresponding to \param standardPixmap.
+
+ A QImage (not a QPixmap) is returned so it can be cached and re-scaled in case the pixmap is
+ requested multiple times with different resolutions.
+
+ \note Rather than defaulting to a QImage(), all QPlatformTheme::StandardPixmap enum values have
+ been mentioned explicitly.
+ That way they can be covered more easily in case additional icons are provided by GTK.
+ */
QImage QGtk3Interface::standardPixmap(QPlatformTheme::StandardPixmap standardPixmap) const
{
switch (standardPixmap) {
@@ -235,6 +259,10 @@ QImage QGtk3Interface::standardPixmap(QPlatformTheme::StandardPixmap standardPix
Q_UNREACHABLE();
}
+/*!
+ \internal
+ \brief Returns a QImage for a given GTK \param iconName.
+ */
QImage QGtk3Interface::qt_gtk_get_icon(const char* iconName) const
{
GtkIconSet* iconSet = gtk_icon_factory_lookup_default (iconName);
@@ -242,14 +270,23 @@ QImage QGtk3Interface::qt_gtk_get_icon(const char* iconName) const
return qt_convert_gdk_pixbuf(icon);
}
+/*!
+ \internal
+ \brief Returns a QImage converted from the GDK pixel buffer \param buf.
+
+ The ability to convert GdkPixbuf to QImage relies on the following assumptions:
+ \list
+ \li QImage uses uchar as a data container (unasserted)
+ \li the types guint8 and uchar are identical (statically asserted)
+ \li GDK pixel buffer uses 8 bits per sample (assumed at runtime)
+ \li GDK pixel buffer has 4 channels (assumed at runtime)
+ \endlist
+ */
QImage QGtk3Interface::qt_convert_gdk_pixbuf(GdkPixbuf *buf) const
{
if (!buf)
return QImage();
- // Ability to convert GdkPixbuf to QImage relies on the assumptions, that
- // - QImage uses uchar as a data container
- // - the types guint8 and uchar are identical
const guint8 *gdata = gdk_pixbuf_read_pixels(buf);
static_assert(std::is_same<decltype(gdata), const uchar *>::value,
"guint8 has diverted from uchar. Code needs fixing.");
@@ -264,6 +301,13 @@ QImage QGtk3Interface::qt_convert_gdk_pixbuf(GdkPixbuf *buf) const
return converted.copy(); // detatch to survive lifetime of buf
}
+/*!
+ \internal
+ \brief Instantiate a new GTK widget.
+
+ Returns a pointer to a new GTK widget of \param type, allocated on the heap.
+ Returns nullptr of gtk_Default has is passed.
+ */
GtkWidget *QGtk3Interface::qt_new_gtkWidget(QGtkWidget type) const
{
#define CASE(Type)\
@@ -298,6 +342,14 @@ GtkWidget *QGtk3Interface::qt_new_gtkWidget(QGtkWidget type) const
Q_UNREACHABLE();
}
+/*!
+ \internal
+ \brief Read a GTK widget's color from a generic color getter.
+
+ This method returns a generic color of \param con, a given GTK style context.
+ The requested color is defined by \param def and the GTK color-state \param state.
+ The return type is GDK color in RGBA format.
+ */
GdkRGBA QGtk3Interface::genericColor(GtkStyleContext *con, GtkStateFlags state, QGtkColorDefault def) const
{
GdkRGBA color;
@@ -316,9 +368,16 @@ GdkRGBA QGtk3Interface::genericColor(GtkStyleContext *con, GtkStateFlags state,
#undef CASE
}
-// Deliver a QColor from a GTK widget, a source type and a GTK widget state
-// Fall back to the generic color getter of source/state if the property name does not exist
-// Fall back to a hard coded generic color getter of source/state are not mapped
+/*!
+ \internal
+ \brief Read a GTK widget's color from a property.
+
+ Returns a color of GTK-widget \param widget, defined by \param source and \param state.
+ The return type is GDK color in RGBA format.
+
+ \note If no corresponding property can be found for \param source, the method falls back to a
+ suitable generic color.
+ */
QColor QGtk3Interface::color(GtkWidget *widget, QGtkColorSource source, GtkStateFlags state) const
{
GdkRGBA col;
@@ -355,7 +414,15 @@ QColor QGtk3Interface::color(GtkWidget *widget, QGtkColorSource source, GtkState
#undef CASE
}
-// Deliver a widget pointer
+/*!
+ \internal
+ \brief Get pointer to a GTK widget by \param type.
+
+ Returns the pointer to a GTK widget, specified by \param type.
+ GTK widgets are cached, so that only one instance of each type is created.
+ \note
+ The method returns nullptr for the enum value gtk_Default.
+ */
GtkWidget *QGtk3Interface::widget(QGtkWidget type) const
{
if (type == QGtkWidget::gtk_Default)
@@ -371,7 +438,14 @@ GtkWidget *QGtk3Interface::widget(QGtkWidget type) const
return w;
}
-// Return widget syle context or default style
+/*!
+ \internal
+ \brief Access a GTK widget's style context.
+
+ Returns the pointer to the style context of GTK widget \param w.
+
+ \note If \param w is nullptr, the GTK default style context (entry style) is returned.
+ */
GtkStyleContext *QGtk3Interface::context(GtkWidget *w) const
{
if (w)
@@ -380,15 +454,28 @@ GtkStyleContext *QGtk3Interface::context(GtkWidget *w) const
return gtk_widget_get_style_context(widget(QGtkWidget::gtk_entry));
}
-// FIXME
-// Brush assets (e.g. 9-patches) can't be accessed by the GTK API.
-// => brush height and width from GTK will be ignored for the time being,
-// because it is unknown if they relate to a plain brush or an image brush.
+/*!
+ \internal
+ \brief Create a QBrush from a GTK widget.
+
+ Returns a QBrush corresponding to GTK widget type \param wtype, \param source and \param state.
+
+ Brush height and width is ignored in GTK3, because brush assets (e.g. 9-patches)
+ can't be accessed by the GTK3 API. It's therefore unknown, if the brush relates only to colors,
+ or to a pixmap based style.
+
+ */
QBrush QGtk3Interface::brush(QGtkWidget wtype, QGtkColorSource source, GtkStateFlags state) const
{
+ // FIXME: When a color's pixmap can be accessed via the GTK API,
+ // read it and set it in the brush.
return QBrush(color(widget(wtype), source, state));
}
+/*!
+ \internal
+ \brief Returns the name of the current GTK theme.
+ */
const QString QGtk3Interface::themeName() const
{
gchar *theme_name;
@@ -400,6 +487,15 @@ const QString QGtk3Interface::themeName() const
return QLatin1String(theme_name);
}
+/*!
+ \internal
+ \brief Determine appearance by colors.
+
+ Returns the appearance of the current GTK theme, heuristically determined by the
+ lightness difference between default background and foreground colors.
+
+ \note Returns Unknown in the unlikely case that both colors have the same lightness.
+ */
Qt::Appearance QGtk3Interface::appearanceByColors() const
{
const QColor background = color(widget(QGtkWidget::gtk_Default),
@@ -416,6 +512,12 @@ Qt::Appearance QGtk3Interface::appearanceByColors() const
return Qt::Appearance::Unknown;
}
+/*!
+ \internal
+ \brief Map font type to GTK widget type.
+
+ Returns the GTK widget type corresponding to the given QPlatformTheme::Font \param type.
+ */
inline constexpr QGtk3Interface::QGtkWidget QGtk3Interface::toWidgetType(QPlatformTheme::Font type)
{
switch (type) {
@@ -451,6 +553,10 @@ inline constexpr QGtk3Interface::QGtkWidget QGtk3Interface::toWidgetType(QPlatfo
Q_UNREACHABLE();
}
+/*!
+ \internal
+ \brief Convert pango \param style to QFont::Style.
+ */
inline constexpr QFont::Style QGtk3Interface::toFontStyle(PangoStyle style)
{
switch (style) {
@@ -462,6 +568,13 @@ inline constexpr QFont::Style QGtk3Interface::toFontStyle(PangoStyle style)
Q_UNREACHABLE();
}
+/*!
+ \internal
+ \brief Convert pango font \param weight to an int, representing font weight in Qt.
+
+ Compatibility of PangoWeight is statically asserted.
+ The minimum (1) and maximum (1000) weight in Qt is respeced.
+ */
inline constexpr int QGtk3Interface::toFontWeight(PangoWeight weight)
{
// GTK PangoWeight can be directly converted to QFont::Weight
@@ -494,6 +607,17 @@ inline constexpr QFont::Weight QGtk3Interface::toQFontWeight(int weight)
return QFont::Black;
}
+/*!
+ \internal
+ \brief Return a GTK styled font.
+
+ Returns the QFont corresponding to \param type by reading the corresponding
+ GTK widget type's font.
+
+ \note GTK allows to specify a non fixed font as the system's fixed font.
+ If a fixed font is requested, the method fixes the pitch and falls back to monospace,
+ unless a suitable fixed pitch font is found.
+ */
QFont QGtk3Interface::font(QPlatformTheme::Font type) const
{
GtkStyleContext *con = context(widget(toWidgetType(type)));
@@ -517,9 +641,6 @@ QFont QGtk3Interface::font(QPlatformTheme::Font type) const
font.setPointSizeF(static_cast<float>(pango_font_description_get_size(gtkFont)/PANGO_SCALE));
font.setStyle(toFontStyle(pango_font_description_get_style(gtkFont)));
- // fix pixel pitch if fixed font is requested
- // NOTE: GTK allows to specify a non fixed font as the system's fixed font.
- // => the returned font may still not be a fixed font.
if (type == QPlatformTheme::FixedFont) {
font.setFixedPitch(true);
if (!QFontInfo(font).fixedPitch()) {
@@ -532,6 +653,10 @@ QFont QGtk3Interface::font(QPlatformTheme::Font type) const
return font;
}
+/*!
+ \internal
+ \brief Returns a GTK styled file icon for \param fileInfo.
+ */
QIcon QGtk3Interface::fileIcon(const QFileInfo &fileInfo) const
{
GFile *file = g_file_new_for_path(fileInfo.absoluteFilePath().toLatin1().constData());
diff --git a/src/plugins/platformthemes/gtk3/qgtk3interface_p.h b/src/plugins/platformthemes/gtk3/qgtk3interface_p.h
index e04025923d..42643e72ef 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3interface_p.h
+++ b/src/plugins/platformthemes/gtk3/qgtk3interface_p.h
@@ -36,6 +36,18 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcQGtk3Interface);
class QGtk3Storage;
+
+/*!
+ \internal
+ \brief The QGtk3Interface class centralizes communication with the GTK3 library.
+
+ By encapsulating all GTK version specific syntax and conversions, it makes Qt's GTK theme
+ independent from GTK versions.
+
+ \note
+ Including GTK3 headers requires #undef signals, which disables Qt signal/slot handling.
+ */
+
class QGtk3Interface
{
Q_GADGET
@@ -43,7 +55,13 @@ public:
QGtk3Interface(QGtk3Storage *);
~QGtk3Interface();
- // Enum representing GTK widget types
+ /*!
+ * \internal
+ \enum QGtk3Interface::QGtkWidget
+ \brief Represents GTK widget types used to obtain color information.
+
+ \note The enum value gtk_Default refers to the GTK default style, rather than to a specific widget.
+ */
enum class QGtkWidget {
gtk_menu_bar,
gtk_menu,
@@ -68,7 +86,15 @@ public:
};
Q_ENUM(QGtkWidget)
- // Enum representing color sources of a GTK theme
+ /*!
+ \internal
+ \enum QGtk3Interface::QGtkColorSource
+ \brief The QGtkColorSource enum represents the source of a color within a GTK widgets style context.
+
+ If the current GTK theme provides such a color for a given widget, the color can be read
+ from the style context by passing the enum's key as a property name to the GTK method
+ gtk_style_context_lookup_color. The method will return false, if no color has been found.
+ */
enum class QGtkColorSource {
Foreground,
Background,
@@ -78,7 +104,18 @@ public:
};
Q_ENUM(QGtkColorSource)
- // Enum for default color getter
+ /*!
+ \internal
+ \enum QGtk3Interface::QGtkColorDefault
+ \brief The QGtkColorDefault enum represents generic GTK colors.
+
+ The GTK3 methods gtk_style_context_get_color, gtk_style_context_get_background_color, and
+ gtk_style_context_get_foreground_color always return the respective colors with a widget's
+ style context. Unless set as a property by the current GTK theme, GTK's default colors will
+ be returned.
+ These generic default colors, represented by the GtkColorDefault enum, are used as a
+ back, if a specific color property is requested but not defined in the current GTK theme.
+ */
enum class QGtkColorDefault {
Foreground,
Background,
--
2.41.0

View File

@ -0,0 +1,366 @@
From 4d4cb6a17e5890ef1ee7ac0398d7b5ecdf77d48f Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Thu, 27 Jul 2023 12:42:49 +0200
Subject: [PATCH 23/25] Document QGtk3Storage
Add internal documentation to header and implementation of
QGtk3Storage
---
.../platformthemes/gtk3/qgtk3storage.cpp | 231 +++++++++++++++---
.../platformthemes/gtk3/qgtk3storage_p.h | 1 +
2 files changed, 193 insertions(+), 39 deletions(-)
diff --git a/src/plugins/platformthemes/gtk3/qgtk3storage.cpp b/src/plugins/platformthemes/gtk3/qgtk3storage.cpp
index c206b4d3b5..0f53d526b8 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3storage.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3storage.cpp
@@ -24,7 +24,26 @@ QGtk3Storage::QGtk3Storage()
populateMap();
}
-// Set a brush from a source and resolve recursions
+/*!
+ \internal
+ \enum QGtk3Storage::SourceType
+ \brief This enum represents the type of a color source.
+
+ \value Gtk Color is read from a GTK widget
+ \value Fixed A fixed brush is specified
+ \value Modified The color is a modification of another color (fixed or read from GTK)
+ \omitvalue Invalid
+ */
+
+/*!
+ \internal
+ \brief Find a brush from a source.
+
+ Returns a QBrush from a given \param source and a \param map of available brushes
+ to search from.
+
+ A null QBrush is returned, if no brush corresponding to the source has been found.
+ */
QBrush QGtk3Storage::brush(const Source &source, const BrushMap &map) const
{
switch (source.sourceType) {
@@ -64,7 +83,14 @@ QBrush QGtk3Storage::brush(const Source &source, const BrushMap &map) const
Q_UNREACHABLE();
}
-// Find source for a recursion and take dark/light/unknown into consideration
+/*!
+ \internal
+ \brief Recurse to find a source brush for modification.
+
+ Returns the source specified by the target brush \param b in the \param map of brushes.
+ Takes dark/light/unknown into consideration.
+ Returns an empty brush if no suitable one can be found.
+ */
QGtk3Storage::Source QGtk3Storage::brush(const TargetBrush &b, const BrushMap &map) const
{
#define FIND(brush) if (map.contains(brush))\
@@ -88,7 +114,16 @@ QGtk3Storage::Source QGtk3Storage::brush(const TargetBrush &b, const BrushMap &m
#undef FIND
}
-// Create a simple standard palette
+/*!
+ \internal
+ \brief Returns a simple, hard coded base palette.
+
+ Create a hard coded palette with default colors as a fallback for any color that can't be
+ obtained from GTK.
+
+ \note This palette will be used as a default baseline for the system palette, which then
+ will be used as a default baseline for any other palette type.
+ */
QPalette QGtk3Storage::standardPalette()
{
QColor backgroundColor(0xd4, 0xd0, 0xc8);
@@ -105,7 +140,13 @@ QPalette QGtk3Storage::standardPalette()
return palette;
}
-// Deliver a palette styled according to the current GTK Theme
+/*!
+ \internal
+ \brief Return a GTK styled QPalette.
+
+ Returns the pointer to a (cached) QPalette for \param type, with its brushes
+ populated according to the current GTK theme.
+ */
const QPalette *QGtk3Storage::palette(QPlatformTheme::Palette type) const
{
if (type >= QPlatformTheme::NPalettes)
@@ -160,6 +201,12 @@ const QPalette *QGtk3Storage::palette(QPlatformTheme::Palette type) const
return &m_paletteCache[type].value();
}
+/*!
+ \internal
+ \brief Return a GTK styled font.
+
+ Returns a QFont of \param type, styled according to the current GTK theme.
+*/
const QFont *QGtk3Storage::font(QPlatformTheme::Font type) const
{
if (m_fontCache[type].has_value())
@@ -169,6 +216,13 @@ const QFont *QGtk3Storage::font(QPlatformTheme::Font type) const
return &m_fontCache[type].value();
}
+/*!
+ \internal
+ \brief Return a GTK styled standard pixmap if available.
+
+ Returns a pixmap specified by \param standardPixmap and \param size.
+ Returns an empty pixmap if GTK doesn't support the requested one.
+ */
QPixmap QGtk3Storage::standardPixmap(QPlatformTheme::StandardPixmap standardPixmap,
const QSizeF &size) const
{
@@ -186,11 +240,19 @@ QPixmap QGtk3Storage::standardPixmap(QPlatformTheme::StandardPixmap standardPixm
return QPixmap::fromImage(image.scaled(size.toSize()));
}
+/*!
+ \internal
+ \brief Returns a GTK styled file icon corresponding to \param fileInfo.
+ */
QIcon QGtk3Storage::fileIcon(const QFileInfo &fileInfo) const
{
return m_interface ? m_interface->fileIcon(fileInfo) : QIcon();
}
+/*!
+ \internal
+ \brief Clears all caches.
+ */
void QGtk3Storage::clear()
{
m_appearance = Qt::Appearance::Unknown;
@@ -202,6 +264,13 @@ void QGtk3Storage::clear()
cache.reset();
}
+/*!
+ \internal
+ \brief Handles a theme change at runtime.
+
+ Clear all caches, re-populate with current GTK theme and notify the window system interface.
+ This method is a callback for the theme change signal sent from GTK.
+ */
void QGtk3Storage::handleThemeChange()
{
clear();
@@ -209,6 +278,54 @@ void QGtk3Storage::handleThemeChange()
QWindowSystemInterface::handleThemeChange();
}
+/*!
+ \internal
+ \brief Populates a map with information about how to locate colors in GTK.
+
+ This method creates a data structure to locate color information for each brush of a QPalette
+ within GTK. The structure can hold mapping information for each QPlatformTheme::Palette
+ enum value. If no specific mapping is stored for an enum value, the system palette is returned
+ instead of a specific one. If no mapping is stored for the system palette, it will fall back to
+ QGtk3Storage::standardPalette.
+
+ The method will populate the data structure with a standard mapping, covering the following
+ palette types:
+ \list
+ \li QPlatformTheme::SystemPalette
+ \li QPlatformTheme::CheckBoxPalette
+ \li QPlatformTheme::RadioButtonPalette
+ \li QPlatformTheme::ComboBoxPalette
+ \li QPlatformTheme::GroupBoxPalette
+ \li QPlatformTheme::MenuPalette
+ \li QPlatformTheme::TextLineEditPalette
+ \endlist
+
+ The method will check the environment variable {{QT_GUI_GTK_JSON_SAVE}}. If it points to a
+ valid path with write access, it will write the standard mapping into a Json file.
+ That Json file can be modified and/or extended.
+ The Json syntax is
+ - "QGtk3Palettes" (top level value)
+ - QPlatformTheme::Palette
+ - QPalette::ColorRole
+ - Qt::Appearance
+ - Qt::ColorGroup
+ - Source data
+ - Source Type
+ - [source data]
+
+ If the environment variable {{QT_GUI_GTK_JSON_HARDCODED}} contains the keyword \c true,
+ all sources are converted to fixed sources. In that case, they contain the hard coded HexRGBA
+ values read from GTK.
+
+ The method will also check the environment variable {{QT_GUI_GTK_JSON}}. If it points to a valid
+ Json file with read access, it will be parsed instead of creating a standard mapping.
+ Parsing errors will be printed out with qCInfo if the logging category {{qt.qpa.gtk}} is activated.
+ In case of a parsing error, the method will fall back to creating a standard mapping.
+
+ \note
+ If a Json file contains only fixed brushes (e.g. exported with {{QT_GUI_GTK_JSON_HARDCODED=true}}),
+ no colors will be imported from GTK.
+ */
void QGtk3Storage::populateMap()
{
static QString m_themeName;
@@ -248,6 +365,15 @@ void QGtk3Storage::populateMap()
qWarning() << "File" << jsonOutput << "could not be saved.\n";
}
+/*!
+ \internal
+ \brief Return a palette map for saving.
+
+ This method returns the existing palette map, if the environment variable
+ {{QT_GUI_GTK_JSON_HARDCODED}} is not set or does not contain the keyword \c true.
+ If it contains the keyword \c true, it returns a palette map with all brush
+ sources converted to fixed sources.
+ */
const QGtk3Storage::PaletteMap QGtk3Storage::savePalettes() const
{
const QString hard = qEnvironmentVariable("QT_GUI_GTK_JSON_HARDCODED");
@@ -282,21 +408,50 @@ const QGtk3Storage::PaletteMap QGtk3Storage::savePalettes() const
return map;
}
+/*!
+ \internal
+ \brief Saves current palette mapping to a \param filename with Json format \param f.
+
+ Saves the current palette mapping into a QJson file,
+ taking {{QT_GUI_GTK_JSON_HARDCODED}} into consideration.
+ Returns \c true if saving was successful and \c false otherwise.
+ */
bool QGtk3Storage::save(const QString &filename, QJsonDocument::JsonFormat f) const
{
return QGtk3Json::save(savePalettes(), filename, f);
}
+/*!
+ \internal
+ \brief Returns a QJsonDocument with current palette mapping.
+
+ Saves the current palette mapping into a QJsonDocument,
+ taking {{QT_GUI_GTK_JSON_HARDCODED}} into consideration.
+ Returns \c true if saving was successful and \c false otherwise.
+ */
QJsonDocument QGtk3Storage::save() const
{
return QGtk3Json::save(savePalettes());
}
+/*!
+ \internal
+ \brief Loads palette mapping from Json file \param filename.
+
+ Returns \c true if the file was successfully parsed and \c false otherwise.
+ */
bool QGtk3Storage::load(const QString &filename)
{
return QGtk3Json::load(m_palettes, filename);
}
+/*!
+ \internal
+ \brief Creates a standard palette mapping.
+
+ The method creates a hard coded standard mapping, used if no external Json file
+ containing a valid mapping has been specified in the environment variable {{QT_GUI_GTK_JSON}}.
+ */
void QGtk3Storage::createMapping()
{
// Hard code standard mapping
@@ -332,41 +487,39 @@ void QGtk3Storage::createMapping()
#define CLEAR map.clear()
/*
- * Macro ussage:
- *
- * 1. Define a source
- *
- * GTK(QGtkWidget, QGtkColorSource, GTK_STATE_FLAG)
- * Fetch the color from a GtkWidget, related to a source and a state.
- *
- * LIGHTER(ColorGroup, ColorROle, lighter)
- * Use a color of the same QPalette related to ColorGroup and ColorRole.
- * Make the color lighter (if lighter >100) or darker (if lighter < 100)
- *
- * MODIFY(ColorGroup, ColorRole, red, green, blue)
- * Use a color of the same QPalette related to ColorGroup and ColorRole.
- * Modify it by adding red, green, blue.
- *
- * FIX(const QBrush &)
- * Use a fixed brush without querying GTK
- *
- * 2. Define the target
- *
- * Use ADD(ColorGroup, ColorRole) to use the defined source for the
- * color group / role in the current palette.
- *
- * Use ADD(ColorGroup, ColorRole, Appearance) to use the defined source
- * only for a specific appearance
- *
- * 3. Save mapping
- * Save the defined mappings for a specific palette.
- * If a mapping entry does not cover all color groups and roles of a palette,
- * the system palette will be used for the remaining values.
- * If the system palette does not have all combination of color groups and roles,
- * the remaining ones will be populated by a hard coded fusion-style like palette.
- *
- * 4. Clear mapping
- * Use CLEAR to clear the mapping and begin a new one.
+ Macro usage:
+
+ 1. Define a source
+ GTK(QGtkWidget, QGtkColorSource, GTK_STATE_FLAG)
+ Fetch the color from a GtkWidget, related to a source and a state.
+
+ LIGHTER(ColorGroup, ColorROle, lighter)
+ Use a color of the same QPalette related to ColorGroup and ColorRole.
+ Make the color lighter (if lighter >100) or darker (if lighter < 100)
+
+ MODIFY(ColorGroup, ColorRole, red, green, blue)
+ Use a color of the same QPalette related to ColorGroup and ColorRole.
+ Modify it by adding red, green, blue.
+
+ FIX(const QBrush &)
+ Use a fixed brush without querying GTK
+
+ 2. Define the target
+ Use ADD(ColorGroup, ColorRole) to use the defined source for the
+ color group / role in the current palette.
+
+ Use ADD(ColorGroup, ColorRole, Appearance) to use the defined source
+ only for a specific appearance
+
+ 3. Save mapping
+ Save the defined mappings for a specific palette.
+ If a mapping entry does not cover all color groups and roles of a palette,
+ the system palette will be used for the remaining values.
+ If the system palette does not have all combination of color groups and roles,
+ the remaining ones will be populated by a hard coded fusion-style like palette.
+
+ 4. Clear mapping
+ Use CLEAR to clear the mapping and begin a new one.
*/
diff --git a/src/plugins/platformthemes/gtk3/qgtk3storage_p.h b/src/plugins/platformthemes/gtk3/qgtk3storage_p.h
index 57f6aeea96..af628d49ff 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3storage_p.h
+++ b/src/plugins/platformthemes/gtk3/qgtk3storage_p.h
@@ -33,6 +33,7 @@ class QGtk3Storage
public:
QGtk3Storage();
+ // Enum documented in cpp file. Please keep it in line with updates made here.
enum class SourceType {
Gtk,
Fixed,
--
2.41.0

View File

@ -0,0 +1,84 @@
From 5ad394475f26725d854a0c4c733ffcde8f3bbf15 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Thu, 27 Jul 2023 12:44:11 +0200
Subject: [PATCH 24/25] QGtk3Theme: Improve fixed font delivery
The gtk_fixed widget was used as a reference to obtain a fixed font
and HeaderViewFont.
This is a mistake, because the gtk_fixed widget is a container for
other widgets with fixed geometries and no layouting.
This patch makes the default style being used for a fixed font and, as
a drive-by, the combo box as a reference for a header view font.
A monospace based css provider as explicitly added to the style
context, in case a fixed font is requested. The provider is removed
afterwards.
---
.../platformthemes/gtk3/qgtk3interface.cpp | 24 +++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/src/plugins/platformthemes/gtk3/qgtk3interface.cpp b/src/plugins/platformthemes/gtk3/qgtk3interface.cpp
index 0fab1220b4..21abea81cf 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3interface.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3interface.cpp
@@ -18,6 +18,7 @@
#include <QtCore/QMetaEnum>
#include <QtCore/QSettings>
#include <QtCore/QFileInfo>
+#include <QtCore/QScopeGuard>
#include <QtGui/QFontDatabase>
#include <QtGui/QIcon>
@@ -538,13 +539,13 @@ inline constexpr QGtk3Interface::QGtkWidget QGtk3Interface::toWidgetType(QPlatfo
case QPlatformTheme::ToolButtonFont: return QGtkWidget::gtk_button;
case QPlatformTheme::ItemViewFont: return QGtkWidget::gtk_entry;
case QPlatformTheme::ListViewFont: return QGtkWidget::gtk_tree_view;
- case QPlatformTheme::HeaderViewFont: return QGtkWidget::gtk_fixed;
+ case QPlatformTheme::HeaderViewFont: return QGtkWidget::gtk_combo_box;
case QPlatformTheme::ListBoxFont: return QGtkWidget::gtk_Default;
case QPlatformTheme::ComboMenuItemFont: return QGtkWidget::gtk_combo_box;
case QPlatformTheme::ComboLineEditFont: return QGtkWidget::gtk_combo_box_text;
case QPlatformTheme::SmallFont: return QGtkWidget::gtk_Default;
case QPlatformTheme::MiniFont: return QGtkWidget::gtk_Default;
- case QPlatformTheme::FixedFont: return QGtkWidget::gtk_fixed;
+ case QPlatformTheme::FixedFont: return QGtkWidget::gtk_Default;
case QPlatformTheme::GroupBoxTitleFont: return QGtkWidget::gtk_Default;
case QPlatformTheme::TabButtonFont: return QGtkWidget::gtk_button;
case QPlatformTheme::EditorFont: return QGtkWidget::gtk_entry;
@@ -624,6 +625,24 @@ QFont QGtk3Interface::font(QPlatformTheme::Font type) const
if (!con)
return QFont();
+ // explicitly add provider for fixed font
+ GtkCssProvider *cssProvider = nullptr;
+ if (type == QPlatformTheme::FixedFont) {
+ cssProvider = gtk_css_provider_new();
+ const char *fontSpec = "{font-family: monospace;}";
+ gtk_css_provider_load_from_data(cssProvider, fontSpec, -1, NULL);
+ gtk_style_context_add_provider(con, GTK_STYLE_PROVIDER(cssProvider),
+ GTK_STYLE_PROVIDER_PRIORITY_USER);
+ }
+
+ // remove monospace provider from style context and unref it
+ QScopeGuard guard([&](){
+ if (cssProvider) {
+ gtk_style_context_remove_provider(con, GTK_STYLE_PROVIDER(cssProvider));
+ g_object_unref(cssProvider);
+ }
+ });
+
const PangoFontDescription *gtkFont = gtk_style_context_get_font(con, GTK_STATE_FLAG_NORMAL);
if (!gtkFont)
return QFont();
@@ -650,6 +669,7 @@ QFont QGtk3Interface::font(QPlatformTheme::Font type) const
font.setFamily("monospace");
}
}
+
return font;
}
--
2.41.0

View File

@ -0,0 +1,56 @@
From 7b52f959ccc772b399fb32c9a4eabe37dc572db6 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Thu, 27 Jul 2023 12:44:31 +0200
Subject: [PATCH 25/25] QGtk3Theme: Do not default Active WindowText to button
foreground
QGtk3Theme uses the GTK button foreground as a default for the
WindowText color role. When a GTK3 theme has no specific color for the
entry text, this can lead to text on certain assets looking darker
and thus disabled.
This discontinues usage of the button foreground for the window text.
Finding the WindowText color role in QPlatformTheme::SystemPalette now
follows the following logic:
(1) GTK normal entry text is used if specified. This is the preferred
option, copying GTK behavior.
(2) If (1) is not specified, the GTK default text color is used, making
WindowText equal to Text.
(3) If neither (1), nor (2) are specified, the WindowText color role is
taken from qt_fusionPalette, where it is also equal to Text.
The SystemPalette is used as a default template for all other control
or widget speicific palettes. The rules above therefor apply to all
screen assets (unless they use a JSON file to specify a their
individual WindowText).
[ChangeLog][QGtk3Theme][SystemPalette][WindowText] Default to GTK
Entry Text / Normal Text / qt_fusionPalette
---
src/plugins/platformthemes/gtk3/qgtk3storage.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/platformthemes/gtk3/qgtk3storage.cpp b/src/plugins/platformthemes/gtk3/qgtk3storage.cpp
index 0f53d526b8..df7f7c77b8 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3storage.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3storage.cpp
@@ -538,7 +538,6 @@ void QGtk3Storage::createMapping()
LIGHTER(Normal, Window, 80);
ADD(Normal, Dark);
GTK(button, Foreground, ACTIVE);
- ADD(Normal, WindowText);
ADD(Inactive, WindowText);
LIGHTER(Normal, WindowText, 50);
ADD(Disabled, Text);
@@ -562,6 +561,7 @@ void QGtk3Storage::createMapping()
ADD(Disabled, HighlightedText);
GTK(Default, Text, NORMAL);
ADD(Normal, Text);
+ ADD(Normal, WindowText);
ADD(Inactive, Text);
ADD(Normal, HighlightedText);
LIGHTER(Normal, Base, 93);
--
2.41.0

View File

@ -57,7 +57,7 @@
Name: qt5-qtbase
Summary: Qt5 - QtBase components
Version: 5.15.10
Release: 5%{?dist}
Release: 6%{?dist}
# See LGPL_EXCEPTIONS.txt, for exception details
License: LGPL-3.0-only OR GPL-3.0-only WITH Qt-GPL-exception-1.0
@ -125,11 +125,6 @@ Patch64: qt5-qtbase-5.12.1-firebird-4.0.0.patch
# fix for new mariadb
Patch65: qtbase-opensource-src-5.9.0-mysql.patch
# https://fedoraproject.org/wiki/Changes/Qt_Wayland_By_Default_On_Gnome
# https://bugzilla.redhat.com/show_bug.cgi?id=1732129
Patch80: qtbase-use-wayland-on-gnome.patch
# gcc-11
Patch90: %{name}-gcc11.patch
@ -152,7 +147,42 @@ Patch103: qtbase-QTBUG-112136.patch
Patch104: qtbase-QTBUG-103393.patch
# upstream security fixes
Patch150: CVE-2023-37369-qtbase-5.15.diff
Patch110: CVE-2023-37369-qtbase-5.15.diff
## Qt 6 backports for better Gtk/GNOME integration
# https://fedoraproject.org/wiki/Changes/Qt_Wayland_By_Default_On_Gnome
# https://bugzilla.redhat.com/show_bug.cgi?id=1732129
Patch150: 0001-Use-Wayland-by-default-on-GNOME.patch
# https://fedoraproject.org/wiki/Changes/NoCustomQtThemingForWorkstation
# https://bugzilla.redhat.com/show_bug.cgi?id=2226797
Patch151: 0002-Add-QPlatformTheme-Appearance-for-detecting-light-da.patch
Patch152: 0003-Add-enum-class-Qt-Appearance.patch
Patch153: 0004-QGtk3Theme-implement-appearance-function-to-detect-d.patch
Patch154: 0005-Account-for-dark-system-themes-in-qt_fusionPalette.patch
Patch155: 0006-qt_fusionPalette-make-links-more-legible-on-dark-bac.patch
Patch156: 0007-Add-nullptr-check-for-theme-when-initializing-palett.patch
Patch157: 0008-Replace-QPlatformTheme-Appearance-by-Qt-Appearance.patch
Patch158: 0009-Rename-QGuiApplicationPrivate-notifyThemeChanged-to-.patch
Patch159: 0010-Send-ThemeChange-event-to-all-windows-when-system-th.patch
Patch160: 0011-Propagate-appearance-property-from-QPlatformTheme-to.patch
Patch161: 0012-Sync-and-assert-StandardPixmap-enums-in-QPlatformThe.patch
Patch162: 0013-QGtk3Theme-subscribe-to-theme-hint-changes.patch
Patch163: 0014-Gtk3Theme-set-XCURSOR_SIZE-and-XCURSOR_THEME-for-way.patch
Patch164: 0015-Gtk3-fix-stack-smashing-on-mismatch-between-bool-and.patch
Patch165: 0016-Re-implement-palette-standardPixmap-file-icons-fonts.patch
Patch166: 0017-GTK3-theme-simplify-code.patch
Patch167: 0018-Fix-checkbox-and-radiobutton-background-in-QGtk3Them.patch
Patch168: 0019-Cleanup-QGtk3Theme.patch
Patch169: 0020-Detect-appearance-by-colors-unless-GTK-theme-name-co.patch
Patch170: 0021-Change-parsing-log-output-in-QGtk3Json-from-qCDebug-.patch
Patch171: 0022-Document-QGtk3Interface.patch
Patch172: 0023-Document-QGtk3Storage.patch
Patch173: 0024-QGtk3Theme-Improve-fixed-font-delivery.patch
Patch174: 0025-QGtk3Theme-Do-not-default-Active-WindowText-to-butto.patch
# Latest QGnomePlatform needs to be specified to be used
Patch200: qtbase-use-qgnomeplatform-as-default-platform-theme-on-gnome.patch
# Do not check any files in %%{_qt5_plugindir}/platformthemes/ for requires.
# Those themes are there for platform integration. If the required libraries are
@ -422,10 +452,6 @@ Qt5 libraries used for drawing widgets and OpenGL items.
%patch -P65 -p1 -b .mysql
%endif
%if 0%{?fedora} > 30 || 0%{?rhel} > 8
%patch -P80 -p1 -b .use-wayland-on-gnome.patch
%endif
%patch -P90 -p1 -b .gcc11
## upstream patches
@ -434,7 +460,43 @@ Qt5 libraries used for drawing widgets and OpenGL items.
%patch -P102 -p1
%patch -P103 -p1
%patch -P104 -p1
%patch -P150 -p1
%patch -P110 -p1
## Qt 6 backports
%if 0%{?fedora} > 30 || 0%{?rhel} > 8
%patch -P150 -p1 -b .use-wayland-on-gnome.patch
%endif
%if 0%{?fedora} > 38 || 0%{?rhel} > 9
%patch -P151 -p1
%patch -P152 -p1
%patch -P153 -p1
%patch -P154 -p1
%patch -P155 -p1
%patch -P156 -p1
%patch -P157 -p1
%patch -P158 -p1
%patch -P159 -p1
%patch -P160 -p1
%patch -P161 -p1
%patch -P162 -p1
%patch -P163 -p1
%patch -P164 -p1
%patch -P165 -p1
%patch -P166 -p1
%patch -P167 -p1
%patch -P168 -p1
%patch -P169 -p1
%patch -P170 -p1
%patch -P171 -p1
%patch -P172 -p1
%patch -P173 -p1
%patch -P174 -p1
%endif
%if 0%{?fedora} < 39
# Use QGnomePlatform by default
%patch -P200 -p1
%endif
# move some bundled libs to ensure they're not accidentally used
pushd src/3rdparty
@ -1114,6 +1176,11 @@ fi
%changelog
* Mon Aug 21 2023 Jan Grulich <jgrulich@redhat.com> - 5.15.10-6
- Backport Qt 6 improvements to QGtkStyle for better Gtk/GNOME integration
- Use QGnomePlatform by default on F38 and older
Resolves: #2226797
* Wed Aug 16 2023 Than Ngo <than@redhat.com> - 5.15.10-5
- Fixed bz#2232359, CVE-2023-37369 qtbase: buffer overflow in QXmlStreamReader

View File

@ -0,0 +1,13 @@
diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
index 6e01af052c..fc67477ba9 100644
--- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
@@ -868,6 +868,8 @@ QStringList QGenericUnixTheme::themeNames()
result.push_back(QLatin1String(QKdeTheme::name));
#endif
} else if (gtkBasedEnvironments.contains(desktopName)) {
+ // prefer the QGnomePlatform theme
+ result.push_back(QStringLiteral("qgnomeplatform"));
// prefer the GTK3 theme implementation with native dialogs etc.
result.push_back(QStringLiteral("gtk3"));
// fallback to the generic Gnome theme if loading the GTK3 theme fails