From 76d46a2deedc69108cefce811e8dc6a65f9151e6 Mon Sep 17 00:00:00 2001 From: Jason Barron Date: Fri, 24 Apr 2009 16:13:56 +0200 Subject: Fix background painting. This is a reverted patch that has been rebased on to another branch and then caused conflicts so it might contain an error or two. Basically we need to store the background texture from the style into the palette so that it can be replaced by applications that don't want it. --- src/gui/kernel/qwidget.cpp | 12 +++++------- src/gui/styles/qs60style.cpp | 24 +----------------------- src/gui/styles/qs60style_symbian.cpp | 32 ++++++++++++++++++++------------ 3 files changed, 26 insertions(+), 42 deletions(-) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 7eaebbb..9015182 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -2038,19 +2038,17 @@ static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QPoin // Defined in qmacstyle_mac.cpp extern void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QPoint &offset, const QBrush &brush); qt_mac_fill_background(painter, rgn, offset, brush); +#elif defined(Q_WS_S60) + // Defined in qs60style_symbian.cpp + extern void qt_s60_fill_background(QPainter *painter, const QRegion &rgn, + const QPoint &offset, const QBrush &brush); + qt_s60_fill_background(painter, rgn, offset, brush); #else const QRegion translated = rgn.translated(offset); const QRect rect(translated.boundingRect()); painter->setClipRegion(translated); painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft()); #endif -#if defined(Q_WS_S60) && !defined(QT_NO_STYLE_S60) - } if (!brush.isOpaque()) { - // QS60Style knows it's background and does not store its texture in a palette - // Defined in qs60style.cpp - extern void qt_s60_fill_background(QPainter *painter, const QRegion &rgn, const QPoint &offset); - qt_s60_fill_background(painter, rgn, offset); -#endif } else { const QVector &rects = rgn.rects(); for (int i = 0; i < rects.size(); ++i) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 58dcb98..65ce104 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -485,7 +485,7 @@ void QS60StylePrivate::setThemePalette(QWidget *widget) const QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnHighlightColors, 2, 0)); // set these as transparent so that styled full screen theme background is visible widgetPalette.setColor(QPalette::AlternateBase, Qt::transparent); - widgetPalette.setColor(QPalette::Window, Qt::transparent); + widgetPalette.setColor(QPalette::Window, QS60StylePrivate::backgroundTexture()); widgetPalette.setColor(QPalette::Base, Qt::transparent); // set button and tooltipbase based on pixel colors QColor buttonColor = colorFromFrameGraphics(QS60StylePrivate::SF_ButtonNormal); @@ -530,17 +530,6 @@ void QS60Style::polish(QWidget *widget) Q_D(const QS60Style); QCommonStyle::polish(widget); - if (QAbstractScrollArea *scrollArea = qobject_cast(widget)){ - scrollArea->viewport()->setAutoFillBackground(false); - } - - if (false -#ifndef QT_NO_SCROLLBAR - || qobject_cast(widget) -#endif - ) { - widget->setAttribute(Qt::WA_OpaquePaintEvent, false); - } if (QS60StylePrivate::isSkinnableDialog(widget)) { widget->setAttribute(Qt::WA_StyledBackground); } else if (false @@ -565,17 +554,6 @@ void QS60Style::polish(QWidget *widget) void QS60Style::unpolish(QWidget *widget) { - if (QAbstractScrollArea *scrollArea = qobject_cast(widget)){ - scrollArea->viewport()->setAutoFillBackground(true); - } - - if (false -#ifndef QT_NO_SCROLLBAR - || qobject_cast(widget) -#endif - ) { - widget->setAttribute(Qt::WA_OpaquePaintEvent); - } if (QS60StylePrivate::isSkinnableDialog(widget)) { widget->setAttribute(Qt::WA_StyledBackground, false); } else if (false diff --git a/src/gui/styles/qs60style_symbian.cpp b/src/gui/styles/qs60style_symbian.cpp index a1e7800..083e3b9 100644 --- a/src/gui/styles/qs60style_symbian.cpp +++ b/src/gui/styles/qs60style_symbian.cpp @@ -372,21 +372,29 @@ bool QS60StylePrivate::isTouchSupported() return bool(AknLayoutUtils::PenEnabled()); } -void qt_s60_fill_background(QPainter *painter, const QRegion &rgn, const QPoint &offset) +void qt_s60_fill_background(QPainter *painter, const QRegion &rgn, const QPoint &offset, + const QBrush &brush) { const QPixmap backgroundTexture(QS60StylePrivate::backgroundTexture()); - const QPaintDevice *target = painter->device(); - if (target->devType() == QInternal::Widget) { - const QWidget *widget = static_cast(target); - const CCoeControl *control = widget->effectiveWinId(); - const TPoint globalPos = control ? control->PositionRelativeToScreen() : TPoint(0,0); - const QRegion translated = rgn.translated(offset); - const QVector &rects = translated.rects(); - for (int i = 0; i < rects.size(); ++i) { - const QRect rect(rects.at(i)); - painter->drawPixmap(rect.topLeft(), backgroundTexture, - rect.translated(globalPos.iX, globalPos.iY)); + if (backgroundTexture.cacheKey() == brush.texture().cacheKey()) { + const QPaintDevice *target = painter->device(); + if (target->devType() == QInternal::Widget) { + const QWidget *widget = static_cast(target); + CCoeControl *control = widget->effectiveWinId(); + TPoint globalPos = control ? control->PositionRelativeToScreen() : TPoint(0,0); + const QRegion translated = rgn.translated(offset); + const QVector &rects = translated.rects(); + for (int i = 0; i < rects.size(); ++i) { + const QRect rect(rects.at(i)); + painter->drawPixmap(rect.topLeft(), backgroundTexture, + rect.translated(globalPos.iX, globalPos.iY)); + } } + } else { + const QRegion translated = rgn.translated(offset); + const QRect rect(translated.boundingRect()); + painter->setClipRegion(translated); + painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft()); } } -- cgit v0.12 From 20a0448cfe6e683e8bc66d3bd62a0981067602f9 Mon Sep 17 00:00:00 2001 From: Jason Barron Date: Wed, 1 Apr 2009 15:43:57 +0200 Subject: We previously had some hacks in this function to avoid creating a backing store with the ARGB32 format (which is slower to draw on), but we actually want this in some cases so let's do this properly and move the hacks somewhere else. --- src/gui/kernel/qt_s60_p.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index 6261e4b..35755c3 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -227,12 +227,14 @@ static inline QImage::Format qt_TDisplayMode2Format(TDisplayMode mode) format = QImage::Format_RGB666; break; case EColor16MU: - case EColor16MA: format = QImage::Format_RGB32; break; + case EColor16MA: + format = QImage::Format_ARGB32; + break; #ifdef __S60_50__ case EColor16MAP: - format = QImage::Format_ARGB32; + format = QImage::Format_ARGB32_Premultiplied; break; #endif default: -- cgit v0.12 From c4e2008731cd7c9df922921c52294f84205fccb9 Mon Sep 17 00:00:00 2001 From: Jason Barron Date: Wed, 15 Apr 2009 14:12:20 +0200 Subject: Fixes: Add support for translucent windows in Symbian. Warning, this is completely untested! Details: This should (in theory) get translucent windows working but this hasn't been tested yet. The emulator environment seems to return only 16ColorMU display modes which implies the window is opague so Qt ignores the translucent flag. HW seems to create 16ColorMA windows, but it hasn't been tested there yet either (no time). --- src/gui/kernel/qapplication_s60.cpp | 4 +++- src/gui/kernel/qwidget.cpp | 6 ++++++ src/gui/kernel/qwidget.h | 1 + src/gui/kernel/qwidget_p.h | 4 ++++ src/gui/kernel/qwidget_s60.cpp | 34 ++++++++++++++++++++++++++++++++- src/gui/painting/qwindowsurface_s60.cpp | 11 ++++++++++- 6 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index c7bbcdb..e1155ad 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -540,7 +540,9 @@ void QSymbianControl::Draw(const TRect& r) const if (engine->type() == QPaintEngine::Raster) { QS60WindowSurface *s60Surface = static_cast(qwidget->windowSurface()); CFbsBitmap *bitmap = s60Surface->symbianBitmap(); - SystemGc().BitBlt(r.iTl, bitmap, r); + CWindowGc &gc = SystemGc(); + gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); + gc.BitBlt(r.iTl, bitmap, r); } else { surface->flush(qwidget, QRegion(qt_TRect2QRect(r)), QPoint()); } diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 9015182..f5deb96 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1991,6 +1991,9 @@ void QWidgetPrivate::setOpaque(bool opaque) #ifdef Q_WS_WIN winUpdateIsOpaque(); #endif +#ifdef Q_WS_S60 + s60UpdateIsOpaque(); +#endif } void QWidgetPrivate::updateIsTranslucent() @@ -2004,6 +2007,9 @@ void QWidgetPrivate::updateIsTranslucent() #ifdef Q_WS_WIN winUpdateIsOpaque(); #endif +#ifdef Q_WS_S60 + s60UpdateIsOpaque(); +#endif } /*! diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h index 8ecf758..2b584eb 100644 --- a/src/gui/kernel/qwidget.h +++ b/src/gui/kernel/qwidget.h @@ -746,6 +746,7 @@ private: #endif #ifdef Q_WS_S60 friend class QSymbianControl; + friend class QS60WindowSurface; #endif #ifdef Q_WS_X11 friend void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp); diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index ec64b6e..19f4b98 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -270,6 +270,10 @@ public: void applyMaxAndMinSizeConstraints(int &w, int &h); #endif +#ifdef Q_WS_S60 + void s60UpdateIsOpaque(); +#endif + void raise_sys(); void lower_sys(); void stackUnder_sys(QWidget *); diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index ec80a18..20325c2 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -202,8 +202,15 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO topExtra->rwindow->PointerFilter(EPointerFilterEnterExit | EPointerFilterMove | EPointerFilterDrag, 0); topExtra->rwindow->EnableVisibilityChangeEvents(); + + if (q->testAttribute(Qt::WA_TranslucentBackground)) { + RWindow *rwindow = static_cast(topExtra->rwindow); + TDisplayMode gotDM = (TDisplayMode)rwindow->SetRequiredDisplayMode(EColor16MA); + int erro = rwindow->SetTransparencyAlphaChannel(); + } } + id = (WId)control; setWinId(id); @@ -429,6 +436,29 @@ void QWidgetPrivate::setConstraints_sys() } + +void QWidgetPrivate::s60UpdateIsOpaque() +{ + Q_Q(QWidget); + + if (!q->testAttribute(Qt::WA_WState_Created) || !q->testAttribute(Qt::WA_TranslucentBackground)) + return; + + if ((data.window_flags & Qt::FramelessWindowHint) == 0) + return; + + if (!isOpaque) { + QTLWExtra *topExtra = topData(); + RWindow *rwindow = static_cast(topExtra->rwindow); + TDisplayMode gotDM = (TDisplayMode)rwindow->SetRequiredDisplayMode(EColor16MA); + int erro = rwindow->SetTransparencyAlphaChannel(); + } else { + QTLWExtra *topExtra = topData(); + RWindow *rwindow = static_cast(topExtra->rwindow); + rwindow->SetTransparentRegion(TRegionFix<1>()); + } +} + CFbsBitmap* qt_pixmapToNativeBitmapL(QPixmap pixmap, bool invert) { CFbsBitmap* fbsBitmap = new(ELeave)CFbsBitmap; @@ -576,7 +606,9 @@ void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r) */ void QWidgetPrivate::setWindowOpacity_sys(qreal level) { - + RWindow* rw = static_cast(topData()->rwindow); + if (rw) + rw->SetTransparencyFactor(TRgb::Gray256(255.0 * level)); } void QWidgetPrivate::updateFrameStrut() diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp index b262cb2..d0c3e1c 100644 --- a/src/gui/painting/qwindowsurface_s60.cpp +++ b/src/gui/painting/qwindowsurface_s60.cpp @@ -12,7 +12,7 @@ #include // for Q_WS_WIN define (non-PCH) #include -#include +#include #include "qwindowsurface_s60_p.h" #include "qt_s60_p.h" @@ -143,6 +143,15 @@ void QS60WindowSurface::lockBitmapHeap() // Get some values for QImage creation TDisplayMode mode = bitmap->DisplayMode(); + QWidget *win = QS60WindowSurfacePrivate::lockedSurface->window(); + RWindowBase *rwin = win->winId()->DrawableWindow(); + TDisplayMode rwMode = rwin->DisplayMode(); + + mode = rwMode; + + if (mode == EColor16MA + && qt_widget_private(QS60WindowSurfacePrivate::lockedSurface->window())->isOpaque) + mode = EColor16MU; QImage::Format format = qt_TDisplayMode2Format( mode ); TSize bitmapSize = bitmap->SizeInPixels(); int bytesPerLine = CFbsBitmap::ScanLineLength( bitmapSize.iWidth, mode); -- cgit v0.12 From 6143217a8594c40d693e4ffceb914bc927f43b05 Mon Sep 17 00:00:00 2001 From: Jason Barron Date: Fri, 24 Apr 2009 11:58:44 +0200 Subject: More work on translucent windows. One step closer to semi-transparent windows, but not there yet. This gets the transparent contents into the window, but the previous contents are not cleared so it keeps drawing the backing store on top of itself each time a Draw() is done. SetBackgroundColor() indicates to WSERV that our window is semi-transparent. We also make sure not to use 'EDrawModeWriteAlpha' when the widget is non-opaque since this actually changes the alpha channel on the frame buffer (not the window) so the gives undesired results. It's a faster draw mode though so we should use it where we can. --- src/gui/kernel/qapplication_s60.cpp | 3 ++- src/gui/kernel/qwidget_s60.cpp | 6 ++++-- src/gui/painting/qwindowsurface_s60.cpp | 17 ++++++++--------- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index e1155ad..06e47a7 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -541,7 +541,8 @@ void QSymbianControl::Draw(const TRect& r) const QS60WindowSurface *s60Surface = static_cast(qwidget->windowSurface()); CFbsBitmap *bitmap = s60Surface->symbianBitmap(); CWindowGc &gc = SystemGc(); - gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); + if (qwidget->d_func()->isOpaque) + gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); gc.BitBlt(r.iTl, bitmap, r); } else { surface->flush(qwidget, QRegion(qt_TRect2QRect(r)), QPoint()); diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 20325c2..f78b5be 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -206,7 +206,8 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO if (q->testAttribute(Qt::WA_TranslucentBackground)) { RWindow *rwindow = static_cast(topExtra->rwindow); TDisplayMode gotDM = (TDisplayMode)rwindow->SetRequiredDisplayMode(EColor16MA); - int erro = rwindow->SetTransparencyAlphaChannel(); + if (rwindow->SetTransparencyAlphaChannel() == KErrNone) + rwindow->SetBackgroundColor(~0); } } @@ -451,7 +452,8 @@ void QWidgetPrivate::s60UpdateIsOpaque() QTLWExtra *topExtra = topData(); RWindow *rwindow = static_cast(topExtra->rwindow); TDisplayMode gotDM = (TDisplayMode)rwindow->SetRequiredDisplayMode(EColor16MA); - int erro = rwindow->SetTransparencyAlphaChannel(); + if (rwindow->SetTransparencyAlphaChannel() == KErrNone) + rwindow->SetBackgroundColor(~0); } else { QTLWExtra *topExtra = topData(); RWindow *rwindow = static_cast(topExtra->rwindow); diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp index d0c3e1c..50278ce 100644 --- a/src/gui/painting/qwindowsurface_s60.cpp +++ b/src/gui/painting/qwindowsurface_s60.cpp @@ -35,12 +35,17 @@ QS60WindowSurface::QS60WindowSurface(QWidget* widget) d_ptr->bytes = 0; d_ptr->bitmap = 0; - TSize size(0, 0); TDisplayMode mode = S60->screenDevice()->DisplayMode(); + bool isOpaque = qt_widget_private(widget)->isOpaque; + if (mode == EColor16MA && isOpaque) + mode = EColor16MU; // Faster since 16MU -> 16MA is typically accelerated + else if (mode == EColor16MU && !isOpaque) + mode = EColor16MA; // Try for transparency anyway - // We create empty CFbsBitmap here -> it will be resized in setGeometry + + // We create empty CFbsBitmap here -> it will be resized in setGeometry d_ptr->bitmap = new (ELeave) CFbsBitmap; - User::LeaveIfError( d_ptr->bitmap->Create( size, mode ) ); + User::LeaveIfError( d_ptr->bitmap->Create(TSize(0, 0), mode ) ); updatePaintDeviceOnBitmap(); @@ -143,12 +148,6 @@ void QS60WindowSurface::lockBitmapHeap() // Get some values for QImage creation TDisplayMode mode = bitmap->DisplayMode(); - QWidget *win = QS60WindowSurfacePrivate::lockedSurface->window(); - RWindowBase *rwin = win->winId()->DrawableWindow(); - TDisplayMode rwMode = rwin->DisplayMode(); - - mode = rwMode; - if (mode == EColor16MA && qt_widget_private(QS60WindowSurfacePrivate::lockedSurface->window())->isOpaque) mode = EColor16MU; -- cgit v0.12 From 4e3ba194fe2404de380fbe544f87773edd66f7b9 Mon Sep 17 00:00:00 2001 From: Jason Barron Date: Fri, 24 Apr 2009 14:22:37 +0200 Subject: Get transparency working by clearing the window surface. This is duplicated code from the raster paint engine's beginPaint() function. For translucent windows the previous contents must be cleared from the backing store before the new content is painted. This class should probably be re-written as a subclass of the raster version. The reason we cannot use that implementation directly is because we cannot use QNativeImage because it doesn't provide anywhere we can do locking. --- src/gui/painting/qwindowsurface_s60.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp index 50278ce..85190c2 100644 --- a/src/gui/painting/qwindowsurface_s60.cpp +++ b/src/gui/painting/qwindowsurface_s60.cpp @@ -15,6 +15,7 @@ #include #include "qwindowsurface_s60_p.h" #include "qt_s60_p.h" +#include "private/qdrawhelper_p.h" QT_BEGIN_NAMESPACE @@ -61,7 +62,7 @@ QS60WindowSurface::~QS60WindowSurface() delete d_ptr; } -void QS60WindowSurface::beginPaint(const QRegion &) +void QS60WindowSurface::beginPaint(const QRegion &rgn) { if(!d_ptr->bitmap) return; @@ -69,6 +70,26 @@ void QS60WindowSurface::beginPaint(const QRegion &) Q_ASSERT(!QS60WindowSurfacePrivate::lockedSurface); QS60WindowSurfacePrivate::lockedSurface = this; lockBitmapHeap(); + + if (!qt_widget_private(window())->isOpaque) { + QRgb *data = reinterpret_cast(d_ptr->device.bits()); + const int row_stride = d_ptr->device.bytesPerLine() / 4; + + const QVector rects = rgn.rects(); + for (QVector::const_iterator it = rects.begin(); it != rects.end(); ++it) { + const int x_start = it->x(); + const int width = it->width(); + + const int y_start = it->y(); + const int height = it->height(); + + QRgb *row = data + row_stride * y_start; + for (int y = 0; y < height; ++y) { + qt_memfill(row + x_start, 0U, width); + row += row_stride; + } + } + } } void QS60WindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &) -- cgit v0.12 From 74d5d7a7d6e5433343eab38887064fc15a7c1250 Mon Sep 17 00:00:00 2001 From: Jason Barron Date: Mon, 27 Apr 2009 11:28:43 +0200 Subject: Fix compilation of tst_qwidget with some compilers. Some compilers such as the Metroworks compiler do not like it when the two pointers have different types so cast them to be the same. --- tests/auto/qwidget/tst_qwidget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index d493219..110a4e0 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -8790,8 +8790,8 @@ void tst_QWidget::toplevelLineEditFocus() #endif QTest::qWait(200); - QCOMPARE(QApplication::activeWindow(), &w); - QCOMPARE(QApplication::focusWidget(), &w); + QCOMPARE(QApplication::activeWindow(), (QWidget*)&w); + QCOMPARE(QApplication::focusWidget(), (QWidget*)&w); } QTEST_MAIN(tst_QWidget) -- cgit v0.12 From f546d1b79d64cfad35fc4b3e5cf5db7e513e1035 Mon Sep 17 00:00:00 2001 From: Jason Barron Date: Mon, 27 Apr 2009 12:38:05 +0200 Subject: Fix compilation of QS60Style after bad merge. The previous commit on this file broke compilation. It should have called setBrush() instead of setColor() to set the Window role of the palette to use a texture brush. --- src/gui/styles/qs60style.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 65ce104..d7ed1e5 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -485,7 +485,7 @@ void QS60StylePrivate::setThemePalette(QWidget *widget) const QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnHighlightColors, 2, 0)); // set these as transparent so that styled full screen theme background is visible widgetPalette.setColor(QPalette::AlternateBase, Qt::transparent); - widgetPalette.setColor(QPalette::Window, QS60StylePrivate::backgroundTexture()); + widgetPalette.setBrush(QPalette::Window, QS60StylePrivate::backgroundTexture()); widgetPalette.setColor(QPalette::Base, Qt::transparent); // set button and tooltipbase based on pixel colors QColor buttonColor = colorFromFrameGraphics(QS60StylePrivate::SF_ButtonNormal); -- cgit v0.12 From e28cefa64b02b61e305581abdbb0469b6e484c40 Mon Sep 17 00:00:00 2001 From: Jason Barron Date: Wed, 29 Apr 2009 10:43:45 +0200 Subject: Make QPixmap::grabWindow() work for top level windows. Its not enough to mask with Qt::Desktop because this enum value also includes Qt::Window so masking would give us a non-zero result thus causing the 'if' case to resolve to true which is not what we want. --- src/gui/image/qpixmap_s60.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp index 6246592..625988a 100644 --- a/src/gui/image/qpixmap_s60.cpp +++ b/src/gui/image/qpixmap_s60.cpp @@ -27,7 +27,7 @@ QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h ) // Find out if this is one of our windows. QSymbianControl *sControl; sControl = winId->MopGetObject(sControl); - if (sControl && sControl->widget()->windowType() & Qt::Desktop) { + if (sControl && sControl->widget()->windowType() == Qt::Desktop) { // Grabbing desktop widget srcSize = screenSize; } else { -- cgit v0.12 From b9088019b62abc288d704800ed7d45df942a3cd6 Mon Sep 17 00:00:00 2001 From: Jason Barron Date: Wed, 29 Apr 2009 11:22:02 +0200 Subject: Fixes crash when setting geometry on an obscured window. Since Qt on Symbian now destroys the backing store when it gets hidden or obscured we need to be careful not to use functions like moveRect() when we don't have a backing store since this function is really a backing store optimization and therefore assumes one exists. --- src/gui/kernel/qwidget_s60.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index f78b5be..a477a09 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -99,7 +99,7 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) // disable it for this particular widget. if (inTopLevelResize) tlwExtra->inTopLevelResize = false; - if (!isResize) + if (!isResize && maybeBackingStore()) moveRect(QRect(oldPos, oldSize), x - oldPos.x(), y - oldPos.y()); else invalidateBuffer_resizeHelper(oldPos, oldSize); -- cgit v0.12 From c714ecaf368c9285c2faffb4d1368f7fa79944dd Mon Sep 17 00:00:00 2001 From: Jason Barron Date: Wed, 29 Apr 2009 11:30:13 +0200 Subject: Undo implementation of setWindowOpacity_sys(). This function was implemented using API from Symbian that will be deprecated. It was never actually suitable anyway since this function cannot be called after the window has been shown and this needs to be a runtime decision for Qt. The solution is to use SetTransparencyAlphaChannel(), but that will come later. --- src/gui/kernel/qwidget_s60.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index a477a09..8fe88d8 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -606,11 +606,9 @@ void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r) TRANSPARENCY To a line in the wsini.ini file. */ -void QWidgetPrivate::setWindowOpacity_sys(qreal level) +void QWidgetPrivate::setWindowOpacity_sys(qreal) { - RWindow* rw = static_cast(topData()->rwindow); - if (rw) - rw->SetTransparencyFactor(TRgb::Gray256(255.0 * level)); + // ### TODO: Implement uniform window transparency } void QWidgetPrivate::updateFrameStrut() -- cgit v0.12 From 065cc545c985f31751edb1b80d577af8c964255f Mon Sep 17 00:00:00 2001 From: Jason Barron Date: Wed, 29 Apr 2009 15:41:47 +0200 Subject: Some code cleanups after review. Change these lines of code to either make it more consistent or more readable after review. --- src/gui/kernel/qwidget_s60.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 8fe88d8..f424e93 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -203,11 +203,11 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO | EPointerFilterMove | EPointerFilterDrag, 0); topExtra->rwindow->EnableVisibilityChangeEvents(); - if (q->testAttribute(Qt::WA_TranslucentBackground)) { + if (!isOpaque) { RWindow *rwindow = static_cast(topExtra->rwindow); TDisplayMode gotDM = (TDisplayMode)rwindow->SetRequiredDisplayMode(EColor16MA); if (rwindow->SetTransparencyAlphaChannel() == KErrNone) - rwindow->SetBackgroundColor(~0); + rwindow->SetBackgroundColor(TRgb(255, 255, 255, 0)); } } @@ -453,7 +453,7 @@ void QWidgetPrivate::s60UpdateIsOpaque() RWindow *rwindow = static_cast(topExtra->rwindow); TDisplayMode gotDM = (TDisplayMode)rwindow->SetRequiredDisplayMode(EColor16MA); if (rwindow->SetTransparencyAlphaChannel() == KErrNone) - rwindow->SetBackgroundColor(~0); + rwindow->SetBackgroundColor(TRgb(255, 255, 255, 0)); } else { QTLWExtra *topExtra = topData(); RWindow *rwindow = static_cast(topExtra->rwindow); -- cgit v0.12 From 9b091d474a0584ea5aa271d466833cfb24e9a5da Mon Sep 17 00:00:00 2001 From: Jason Barron Date: Thu, 30 Apr 2009 09:18:35 +0200 Subject: Small optimization when hiding windows. When a window is hidden, it will call releaseBuffer() on the backing store which in turn will resize the window surface to a null rect. In this case, there is no need to update the QImage with the data pointer since it will be updated on the subsequent beginPaint() when the image is resized to a valid size again. This also avoids doing unnecessary locking on the FBSERV heap which still involves a context switch on older versions of Symbian. --- src/gui/painting/qwindowsurface_s60.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp index 85190c2..2618ce2 100644 --- a/src/gui/painting/qwindowsurface_s60.cpp +++ b/src/gui/painting/qwindowsurface_s60.cpp @@ -144,12 +144,13 @@ void QS60WindowSurface::setGeometry(const QRect& rect) if (rect == geometry()) return; + QWindowSurface::setGeometry(rect); + TRect nativeRect(qt_QRect2TRect(rect)); User::LeaveIfError(d_ptr->bitmap->Resize(nativeRect.Size())); - updatePaintDeviceOnBitmap(); - - QWindowSurface::setGeometry(rect); + if (!rect.isNull()) + updatePaintDeviceOnBitmap(); } void QS60WindowSurface::lockBitmapHeap() -- cgit v0.12 From 4b1137345a0bbfedc348b020ad0ad6e5720eb6d1 Mon Sep 17 00:00:00 2001 From: Jason Barron Date: Thu, 30 Apr 2009 11:26:14 +0200 Subject: Avoid overwriting a user set palette. The polish(QWidget*) function is called the first time a widget is shown and therefore setting the widget's palette in this function will overwrite the user set palette if one is specified before show() is called. The solution is to break this into two parts, the first part sets the global palette in polish(QApplication*) and this is the part of the palette that is independent of widget. The second part involves adding the widget specific palettes using the QApplication:: setPalette() function that takes a classname and this is done in the polish(QWidget*) function. --- src/gui/styles/qs60style.cpp | 68 ++++++++++++++++++++++-------------- src/gui/styles/qs60style.h | 3 ++ src/gui/styles/qs60style_p.h | 2 +- src/gui/styles/qs60style_symbian.cpp | 10 +++--- 4 files changed, 50 insertions(+), 33 deletions(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index d7ed1e5..d197a92 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -462,7 +462,7 @@ int QS60StylePrivate::focusRectPenWidth() return pixelMetric(QS60Style::PM_DefaultFrameWidth); } -void QS60StylePrivate::setThemePalette(QWidget *widget) const +void QS60StylePrivate::setThemePalette(QApplication *app) const { QPalette widgetPalette = QPalette(Qt::white); @@ -498,31 +498,14 @@ void QS60StylePrivate::setThemePalette(QWidget *widget) const QColor toolTipColor = colorFromFrameGraphics(QS60StylePrivate::SF_ToolTip); widgetPalette.setColor(QPalette::ToolTipBase, toolTipColor ); - // widget specific colors - if (QSlider *slider = qobject_cast(widget)){ - widgetPalette.setColor(QPalette::All, QPalette::WindowText, - QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 8, 0)); - } else if (QPushButton *button = qobject_cast(widget)){ - widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, - QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0)); - widgetPalette.setColor(QPalette::Inactive, QPalette::ButtonText, - QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0)); - } else if (QHeaderView *table = qobject_cast(widget)){ - widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, - QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 23, 0)); - } else if (QMenuBar *menuBar = qobject_cast(widget)){ - widgetPalette.setColor(QPalette::All, QPalette::ButtonText, - QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 8, 0)); - } else if (QTabBar *tabBar = qobject_cast(widget)){ - widgetPalette.setColor(QPalette::Active, QPalette::WindowText, - QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 4, 0)); - } else if (QTableView *table = qobject_cast(widget)){ - widgetPalette.setColor(QPalette::All, QPalette::Text, - QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 22, 0)); - } + app->setPalette(widgetPalette); +} - if (widget) - widget->setPalette(widgetPalette); +void QS60Style::polish(QApplication *application) +{ + Q_D(const QS60Style); + originalPalette = application->palette(); + d->setThemePalette(application); } void QS60Style::polish(QWidget *widget) @@ -546,10 +529,41 @@ void QS60Style::polish(QWidget *widget) widget->setAttribute(Qt::WA_StyledBackground); } - if (widget){ - d->setThemePalette(widget); + QPalette widgetPalette = widget->palette(); + + // widget specific colors + if (QSlider *slider = qobject_cast(widget)){ + widgetPalette.setColor(QPalette::All, QPalette::WindowText, + QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 8, 0)); + QApplication::setPalette(widgetPalette, "QSlider"); + } else if (QPushButton *button = qobject_cast(widget)){ + widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, + QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0)); + widgetPalette.setColor(QPalette::Inactive, QPalette::ButtonText, + QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0)); + QApplication::setPalette(widgetPalette, "QPushButton"); + } else if (QHeaderView *table = qobject_cast(widget)){ + widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, + QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 23, 0)); + QApplication::setPalette(widgetPalette, "QHeaderView"); + } else if (QMenuBar *menuBar = qobject_cast(widget)){ + widgetPalette.setColor(QPalette::All, QPalette::ButtonText, + QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 8, 0)); + QApplication::setPalette(widgetPalette, "QMenuBar"); + } else if (QTabBar *tabBar = qobject_cast(widget)){ + widgetPalette.setColor(QPalette::Active, QPalette::WindowText, + QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 4, 0)); + QApplication::setPalette(widgetPalette, "QTabBar"); + } else if (QTableView *table = qobject_cast(widget)){ + widgetPalette.setColor(QPalette::All, QPalette::Text, + QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 22, 0)); + QApplication::setPalette(widgetPalette, "QTableView"); } +} +void QS60Style::unpolish(QApplication *application) +{ + application->setPalette(originalPalette); } void QS60Style::unpolish(QWidget *widget) diff --git a/src/gui/styles/qs60style.h b/src/gui/styles/qs60style.h index 253eb61..945e182 100644 --- a/src/gui/styles/qs60style.h +++ b/src/gui/styles/qs60style.h @@ -45,6 +45,8 @@ public: QRect subElementRect(SubElement element, const QStyleOption *opt, const QWidget *widget = 0) const; void polish(QWidget *widget); void unpolish(QWidget *widget); + void polish(QApplication *application); + void unpolish(QApplication *application); void setStyleProperty(const char *name, const QVariant &value); QVariant styleProperty(const char *name) const; @@ -69,6 +71,7 @@ protected slots: private: Q_DISABLE_COPY(QS60Style) friend class QStyleFactory; + QPalette originalPalette; }; #endif // QT_NO_STYLE_S60 diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index c11d89a..88f0864 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -307,7 +307,7 @@ public: static bool isTouchSupported(); // calculates average color based on button skin graphics (minus borders). QColor colorFromFrameGraphics(QS60StylePrivate::SkinFrameElements frame) const; - void setThemePalette(QWidget *widget) const; + void setThemePalette(QApplication *application) const; static int focusRectPenWidth(); diff --git a/src/gui/styles/qs60style_symbian.cpp b/src/gui/styles/qs60style_symbian.cpp index 083e3b9..426f8d9 100644 --- a/src/gui/styles/qs60style_symbian.cpp +++ b/src/gui/styles/qs60style_symbian.cpp @@ -969,18 +969,18 @@ void QS60Style::handleDynamicLayoutVariantSwitch() d->setActiveLayout(); #endif // QT_S60STYLE_LAYOUTDATA_SIMULATED d->refreshUI(); + d->setThemePalette(qApp); foreach (QWidget *widget, QApplication::allWidgets()) - d->setThemePalette(widget); + widget->ensurePolished(); } void QS60Style::handleSkinChange() { Q_D(QS60Style); d->clearCaches(); - foreach (QWidget *topLevelWidget, QApplication::allWidgets()){ - d->setThemePalette(topLevelWidget); - topLevelWidget->update(); - } + d->setThemePalette(qApp); + foreach (QWidget *topLevelWidget, QApplication::allWidgets()) + topLevelWidget->ensurePolished(); } QT_END_NAMESPACE -- cgit v0.12