Skip to content

Commit b817da6

Browse files
committed
MapperProxyStyle: Workaround QTBUG-24279
Chaining proxy styles isn't really supported by Qt. Mapper can be caught by this if the system uses a proxy style like qt5ct. This change makes the "top-most" proxy style the direct proxy of all underlying styles, while keeping the top-down base style chain. Due to the generated child events, we can no longer try to update common_style on child events, but this isn't neccessary anyway unless really setting a new base style. For a qt5ct+fusion environment, this fixes: - segmented buttons - touch mode menu icon sizes - touch mode spin box hit tests.
1 parent 12d7a44 commit b817da6

File tree

2 files changed

+19
-15
lines changed

2 files changed

+19
-15
lines changed

src/gui/widgets/mapper_proxystyle.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include <QApplication>
2828
#include <QBrush>
2929
#include <QByteArray>
30-
#include <QChildEvent>
3130
#include <QColor>
3231
#include <QCommonStyle> // IWYU pragma: keep
3332
#include <QCoreApplication>
@@ -134,11 +133,26 @@ void MapperProxyStyle::onSettingsChanged()
134133
}
135134
}
136135

136+
void MapperProxyStyle::fixupProxyChain(QStyle* base_style)
137+
{
138+
// QTBUG-24279 QProxyStyle doesn't support proxies
139+
// This function makes this proxy style the direct proxy of all underlying
140+
// styles, while keeping the top-down base style chain.
141+
if (auto* base_proxy_style = qobject_cast<QProxyStyle*>(base_style))
142+
{
143+
fixupProxyChain(base_proxy_style->baseStyle());
144+
}
145+
auto* const old_base = baseStyle();
146+
old_base->setParent(nullptr); // Prevent deletion on setBaseStyle().
147+
setBaseStyle(base_style); // Set base_style's proxy and parent to this.
148+
old_base->setParent(this); // Restore healthy ownership.
149+
}
137150

138151
void MapperProxyStyle::polish(QApplication* application)
139152
{
140153
common_style = qobject_cast<QCommonStyle*>(baseStyle());
141154

155+
fixupProxyChain(baseStyle());
142156
QProxyStyle::polish(application);
143157
QApplication::setPalette(default_palette);
144158

@@ -207,13 +221,6 @@ void MapperProxyStyle::unpolish(QApplication* application)
207221
}
208222

209223

210-
void MapperProxyStyle::childEvent(QChildEvent* event)
211-
{
212-
if (event->added() || event->removed())
213-
common_style = qobject_cast<QCommonStyle*>(baseStyle());
214-
}
215-
216-
217224
void MapperProxyStyle::drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const
218225
{
219226
auto overridden_element = element;

src/gui/widgets/mapper_proxystyle.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@
2727
#include <QObject>
2828
#include <QPalette>
2929
#include <QPixmap>
30+
#include <QPointer>
3031
#include <QProxyStyle>
3132
#include <QRect>
3233
#include <QSize>
3334
#include <QString>
3435
#include <QStyle>
3536

3637
class QApplication;
37-
class QChildEvent;
3838
class QCommonStyle;
3939
class QPainter;
4040
class QStyleHintReturn;
@@ -101,11 +101,6 @@ Q_OBJECT
101101
void unpolish(QApplication* application) override;
102102

103103

104-
protected:
105-
void childEvent(QChildEvent* event) override;
106-
107-
108-
public:
109104
/**
110105
* Draws the given primitive element.
111106
*
@@ -198,7 +193,9 @@ Q_OBJECT
198193

199194
void onSettingsChanged();
200195

201-
QCommonStyle* common_style = nullptr;
196+
void fixupProxyChain(QStyle* proxy_style);
197+
198+
QPointer<QCommonStyle> common_style;
202199
QPalette default_palette;
203200
ToolBarMetrics toolbar = {};
204201
MenuMetrics menu = {};

0 commit comments

Comments
 (0)