summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGareth Stockwell <ext-gareth.stockwell@nokia.com>2011-08-31 14:52:25 (GMT)
committerGareth Stockwell <ext-gareth.stockwell@nokia.com>2011-09-27 09:06:10 (GMT)
commit24855ef3983fa5d87b3e3a06fe891a769e670ae5 (patch)
treedff8907bb32b5c078f88d0af315b109c4cab1e23
parente90cffc2c5f313cc813d0a21a1d9d0afe8d0ea7a (diff)
downloadQt-24855ef3983fa5d87b3e3a06fe891a769e670ae5.zip
Qt-24855ef3983fa5d87b3e3a06fe891a769e670ae5.tar.gz
Qt-24855ef3983fa5d87b3e3a06fe891a769e670ae5.tar.bz2
Always recreate backing store when TLW transparency changes
When using either the opengl or openvg graphics system on Symbian, if a TLW is made transparent, the widget switches to using raster rendering, because EGL surface transparency is currently not supported by the platform. This patch enables the reverse to occur: when the widget is subsequently made opaque, rendering switches back to using GL/VG. Task-number: QTBUG-21211 Reviewed-by: Jani Hautakangas Reviewed-by: Laszlo Agocs Reviewed-by: Sami Merila
-rw-r--r--src/gui/kernel/qwidget.cpp24
-rw-r--r--src/gui/kernel/qwidget_p.h1
-rw-r--r--src/gui/kernel/qwidget_s60.cpp58
-rw-r--r--tests/auto/qwidget/tst_qwidget.cpp45
4 files changed, 101 insertions, 27 deletions
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 8e8266c..bda0885 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -2238,10 +2238,16 @@ void QWidgetPrivate::updateIsOpaque()
#endif
#ifdef Q_WS_S60
- if (q->windowType() == Qt::Dialog && q->testAttribute(Qt::WA_TranslucentBackground)
- && S60->avkonComponentsSupportTransparency) {
- setOpaque(false);
- return;
+ if (q->testAttribute(Qt::WA_TranslucentBackground)) {
+ if (q->windowType() & Qt::Dialog || q->windowType() & Qt::Popup) {
+ if (S60->avkonComponentsSupportTransparency) {
+ setOpaque(false);
+ return;
+ }
+ } else {
+ setOpaque(false);
+ return;
+ }
}
#endif
@@ -2261,11 +2267,16 @@ void QWidgetPrivate::updateIsOpaque()
}
if (q->isWindow() && !q->testAttribute(Qt::WA_NoSystemBackground)) {
+#ifdef Q_WS_S60
+ setOpaque(true);
+ return;
+#else
const QBrush &windowBrush = q->palette().brush(QPalette::Window);
if (windowBrush.style() != Qt::NoBrush && windowBrush.isOpaque()) {
setOpaque(true);
return;
}
+#endif
}
setOpaque(false);
}
@@ -10845,11 +10856,14 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
}
break;
case Qt::WA_TranslucentBackground:
+#if defined(Q_OS_SYMBIAN)
+ setAttribute(Qt::WA_NoSystemBackground, on);
+#else
if (on) {
setAttribute(Qt::WA_NoSystemBackground);
d->updateIsTranslucent();
}
-
+#endif
break;
case Qt::WA_AcceptTouchEvents:
#if defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_OS_SYMBIAN)
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index e30497c..caa6454 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -228,6 +228,7 @@ struct QTLWExtra {
uint inExpose : 1; // Prevents drawing recursion
uint nativeWindowTransparencyEnabled : 1; // Tracks native window transparency
uint forcedToRaster : 1;
+ uint noSystemRotationDisabled : 1;
#endif
};
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index e80eced..e12dfa7 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -820,19 +820,12 @@ void QWidgetPrivate::setConstraints_sys()
void QWidgetPrivate::s60UpdateIsOpaque()
{
Q_Q(QWidget);
-
if (!q->testAttribute(Qt::WA_WState_Created))
return;
-
const bool writeAlpha = extraData()->nativePaintMode == QWExtra::BlitWriteAlpha;
- if (!q->testAttribute(Qt::WA_TranslucentBackground) && !writeAlpha)
- return;
const bool requireAlphaChannel = !isOpaque || writeAlpha;
-
createTLExtra();
-
RWindow *const window = static_cast<RWindow *>(q->effectiveWinId()->DrawableWindow());
-
#ifdef Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
if (QApplicationPrivate::instance()->useTranslucentEGLSurfaces
&& !extra->topextra->forcedToRaster) {
@@ -841,25 +834,47 @@ void QWidgetPrivate::s60UpdateIsOpaque()
return;
}
#endif
+ const bool recreateBackingStore = extra->topextra->backingStore.data() && (
+ QApplicationPrivate::graphics_system_name == QLatin1String("openvg") ||
+ QApplicationPrivate::graphics_system_name == QLatin1String("opengl")
+ );
if (requireAlphaChannel) {
- const TDisplayMode displayMode = static_cast<TDisplayMode>(window->SetRequiredDisplayMode(EColor16MA));
- if (window->SetTransparencyAlphaChannel() == KErrNone) {
+ window->SetRequiredDisplayMode(EColor16MA);
+ if (window->SetTransparencyAlphaChannel() == KErrNone)
window->SetBackgroundColor(TRgb(255, 255, 255, 0));
- extra->topextra->nativeWindowTransparencyEnabled = 1;
- if (extra->topextra->backingStore.data() && (
- QApplicationPrivate::graphics_system_name == QLatin1String("openvg")
- || QApplicationPrivate::graphics_system_name == QLatin1String("opengl"))) {
- // Semi-transparent EGL surfaces aren't supported. We need to
- // recreate backing store to get translucent surface (raster surface).
- extra->topextra->backingStore.create(q);
- extra->topextra->backingStore.registerWidget(q);
- // FixNativeOrientation() will not work without an EGL surface.
+ } else {
+ if (recreateBackingStore) {
+ // Clear the UI surface to ensure that the EGL surface content is visible
+ CWsScreenDevice *screenDevice = S60->screenDevice(q);
+ QScopedPointer<CWindowGc> gc(new CWindowGc(screenDevice));
+ const int err = gc->Construct();
+ if (!err) {
+ gc->Activate(*window);
+ window->BeginRedraw();
+ gc->SetDrawMode(CWindowGc::EDrawModeWriteAlpha);
+ gc->SetBrushColor(TRgb(0, 0, 0, 0));
+ gc->Clear(TRect(0, 0, q->width(), q->height()));
+ window->EndRedraw();
+ }
+ }
+ if (extra->topextra->nativeWindowTransparencyEnabled)
+ window->SetTransparentRegion(TRegionFix<1>());
+ }
+ extra->topextra->nativeWindowTransparencyEnabled = requireAlphaChannel;
+ if (recreateBackingStore) {
+ extra->topextra->backingStore.create(q);
+ extra->topextra->backingStore.registerWidget(q);
+ bool noSystemRotationDisabled = false;
+ if (requireAlphaChannel) {
+ if (q->testAttribute(Qt::WA_SymbianNoSystemRotation)) {
+ // FixNativeOrientation() will not work without an EGL surface
q->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
+ noSystemRotationDisabled = true;
}
+ } else {
+ q->setAttribute(Qt::WA_SymbianNoSystemRotation, extra->topextra->noSystemRotationDisabled);
}
- } else if (extra->topextra->nativeWindowTransparencyEnabled) {
- window->SetTransparentRegion(TRegionFix<1>());
- extra->topextra->nativeWindowTransparencyEnabled = 0;
+ extra->topextra->noSystemRotationDisabled = noSystemRotationDisabled;
}
}
@@ -1020,6 +1035,7 @@ void QWidgetPrivate::createTLSysExtra()
extra->topextra->inExpose = 0;
extra->topextra->nativeWindowTransparencyEnabled = 0;
extra->topextra->forcedToRaster = 0;
+ extra->topextra->noSystemRotationDisabled = 0;
}
void QWidgetPrivate::deleteTLSysExtra()
diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp
index 43dd077..2161f99 100644
--- a/tests/auto/qwidget/tst_qwidget.cpp
+++ b/tests/auto/qwidget/tst_qwidget.cpp
@@ -397,6 +397,9 @@ private slots:
void minimizedWindowModeTransitions();
void normalWindowModeTransitions();
void focusSwitchClosesPopupMenu();
+#if !defined(Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE)
+ void opacityChangeCausesBackingStoreRecreation();
+#endif
#endif
void focusProxyAndInputMethods();
@@ -10336,7 +10339,47 @@ void tst_QWidget::focusSwitchClosesPopupMenu()
mainWindow.activateWindow();
QVERIFY(!CEikonEnv::Static()->AppUiFactory()->MenuBar()->IsDisplayed());
}
-#endif
+
+#if !defined(Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE)
+class OpacityChangeWidget : public QWidget
+{
+public:
+ OpacityChangeWidget() : m_paintEngineType(QPaintEngine::MaxUser) { }
+ void paintEvent(QPaintEvent *)
+ {
+ QPainter painter(this);
+ m_paintEngineType = painter.paintEngine()->type();
+ }
+ QPaintEngine::Type paintEngineType() const { return m_paintEngineType; }
+private:
+ QPaintEngine::Type m_paintEngineType;
+};
+
+void tst_QWidget::opacityChangeCausesBackingStoreRecreation()
+{
+ OpacityChangeWidget w;
+ w.show();
+ QTest::qWaitForWindowShown(&w);
+ const QPaintEngine::Type type = w.paintEngineType();
+ if (QPaintEngine::OpenGL != type && QPaintEngine::OpenVG != type) {
+ QSKIP("Test case is only valid when using opengl or openvg graphics system", SkipAll);
+ } else {
+ if (QApplicationPrivate::instance()->useTranslucentEGLSurfaces) {
+ QSKIP("Test case is only valid when EGL surface transparency is not supported", SkipAll);
+ } else {
+ // Making window transparent should force switch to raster graphics system
+ w.setAttribute(Qt::WA_TranslucentBackground, true);
+ w.repaint();
+ QCOMPARE(w.paintEngineType(), QPaintEngine::Raster);
+ // Making window opaque should cause switch back to previous graphics system
+ w.setAttribute(Qt::WA_TranslucentBackground, false);
+ w.repaint();
+ QCOMPARE(w.paintEngineType(), type);
+ }
+ }
+}
+#endif // !Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
+#endif // Q_OS_SYMBIAN
class InputContextTester : public QInputContext
{