From b3dda7c5bfcc22ebbd443c667dad58112ecddb4b Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 27 Jan 2012 11:21:13 +0100 Subject: WindowsXP-Style: Draw on DC of backing store for widgets only. - Check the device type pof the painter passed in. - Introduce convenience functions for retrieving the DC for widgets that default to the top level. Change-Id: I18a8db02c8ffd7a249310a5ffaf3a530f0a3df40 Reviewed-by: Oliver Wolff --- src/widgets/styles/qwindowsvistastyle.cpp | 4 +-- src/widgets/styles/qwindowsxpstyle.cpp | 59 +++++++++++++++++-------------- src/widgets/styles/qwindowsxpstyle_p.h | 2 +- 3 files changed, 35 insertions(+), 30 deletions(-) diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index 252740cbab..09aec2f484 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -1010,12 +1010,12 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption QPainter startPainter(&startImage); stateId = PBS_DEFAULTED; XPThemeData theme(widget, &startPainter, name, partId, stateId, rect); - d->drawBackground(theme, true); // Do not draw on HDC of backing store. + d->drawBackground(theme); QPainter alternatePainter(&alternateImage); theme.stateId = PBS_DEFAULTED_ANIMATING; theme.painter = &alternatePainter; - d->drawBackground(theme, true); // Do not draw on HDC of backing store. + d->drawBackground(theme); pulse->setPrimaryImage(startImage); pulse->setAlternateImage(alternateImage); pulse->setStartTime(QTime::currentTime()); diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp index acc462ff72..3af297024c 100644 --- a/src/widgets/styles/qwindowsxpstyle.cpp +++ b/src/widgets/styles/qwindowsxpstyle.cpp @@ -136,7 +136,24 @@ static const int windowsRightBorder = 12; // right border on windows extern Q_WIDGETS_EXPORT HDC qt_win_display_dc(); extern QRegion qt_region_from_HRGN(HRGN rgn); +static inline QBackingStore *backingStoreForWidget(const QWidget *widget) +{ + if (QBackingStore *backingStore = widget->backingStore()) + return backingStore; + if (const QWidget *topLevel = widget->nativeParentWidget()) + if (QBackingStore *topLevelBackingStore = topLevel->backingStore()) + return topLevelBackingStore; + return 0; +} +static inline HDC hdcForWidgetBackingStore(const QWidget *widget) +{ + if (QBackingStore *backingStore = backingStoreForWidget(widget)) { + QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); + return static_cast(nativeInterface->nativeResourceForBackingStore(QByteArrayLiteral("getDC"), backingStore)); + } + return 0; +} // Theme data helper ------------------------------------------------------------------------------ /* \internal @@ -197,11 +214,8 @@ HRGN XPThemeData::mask(QWidget *widget) HRGN hrgn; HDC dc = 0; - if (widget) { - QBackingStore *backingStore = widget->backingStore(); - QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); - dc = static_cast(nativeInterface->nativeResourceForBackingStore("getDC", backingStore)); - } + if (widget) + dc = hdcForWidgetBackingStore(widget); RECT nativeRect = toRECT(rect); pGetThemeBackgroundRegion(handle(), dc, partId, stateId, &nativeRect, &hrgn); return hrgn; @@ -661,7 +675,7 @@ bool QWindowsXPStylePrivate::swapAlphaChannel(const QRect &rect, bool allPixels) - Theme part is flipped (mirrored horizontally) else use drawBackgroundDirectly(). */ -void QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData, bool forceFallback) +void QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData) { if (themeData.rect.isEmpty()) return; @@ -682,24 +696,18 @@ void QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData, bool forceFa translucentToplevel = win->testAttribute(Qt::WA_TranslucentBackground); } - HDC dc = 0; - if (themeData.widget) { - QBackingStore *backingStore = themeData.widget->backingStore(); - QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); - dc = static_cast(nativeInterface->nativeResourceForBackingStore("getDC", backingStore )); - } - - const bool useFallback = forceFallback || dc == 0 - || painter->opacity() != 1.0 - || themeData.rotate - || complexXForm - || themeData.mirrorVertically - || (themeData.mirrorHorizontally && pDrawThemeBackgroundEx == 0) - || translucentToplevel; - if (!useFallback) + // Draw on backing store DC only for real widgets. + const bool useFallback = !themeData.widget || painter->device()->devType() != QInternal::Widget + || painter->opacity() != 1.0 || themeData.rotate + || complexXForm || themeData.mirrorVertically + || (themeData.mirrorHorizontally && pDrawThemeBackgroundEx == 0) + || translucentToplevel; + const HDC dc = useFallback ? HDC(0) : hdcForWidgetBackingStore(themeData.widget); + if (dc && !useFallback) { drawBackgroundDirectly(themeData); - else + } else { drawBackgroundThruNativeBuffer(themeData); + } painter->restore(); } @@ -713,11 +721,8 @@ void QWindowsXPStylePrivate::drawBackgroundDirectly(XPThemeData &themeData) { QPainter *painter = themeData.painter; HDC dc = 0; - if (themeData.widget) { - QBackingStore *backingStore = themeData.widget->backingStore(); - QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); - dc = static_cast(nativeInterface->nativeResourceForBackingStore("getDC", backingStore)); - } + if (themeData.widget) + dc = hdcForWidgetBackingStore(themeData.widget); QPoint redirectionDelta(int(painter->deviceMatrix().dx()), int(painter->deviceMatrix().dy())); diff --git a/src/widgets/styles/qwindowsxpstyle_p.h b/src/widgets/styles/qwindowsxpstyle_p.h index d3bfff6a4b..15821c3e0a 100644 --- a/src/widgets/styles/qwindowsxpstyle_p.h +++ b/src/widgets/styles/qwindowsxpstyle_p.h @@ -314,7 +314,7 @@ public: QRegion region(XPThemeData &themeData); void setTransparency(QWidget *widget, XPThemeData &themeData); - void drawBackground(XPThemeData &themeData, bool forceFallback = false); + void drawBackground(XPThemeData &themeData); void drawBackgroundThruNativeBuffer(XPThemeData &themeData); void drawBackgroundDirectly(XPThemeData &themeData); -- cgit v1.2.3