summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-06-03 10:32:45 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-06-03 10:32:45 (GMT)
commitda424a2e8a8570e24eac6272bb410a51381fcad7 (patch)
treee2a305281566a06ca6255caa286fb163a75c598b /src/gui/kernel
parent830bc78b90b800e72420186de301d2a9e17dac09 (diff)
parentc5b79062e134cb5dfbfb8b3a168798eb648f5509 (diff)
downloadQt-da424a2e8a8570e24eac6272bb410a51381fcad7.zip
Qt-da424a2e8a8570e24eac6272bb410a51381fcad7.tar.gz
Qt-da424a2e8a8570e24eac6272bb410a51381fcad7.tar.bz2
Merge branch '4.6' of scm.dev.nokia.troll.no:qt/qt-s60-public into 4.6-integration
* '4.6' of scm.dev.nokia.troll.no:qt/qt-s60-public: Fix QWS build failure Removed compiler warnings Window visibility changes update TLW backing store reference count Enable visibility change events on all Symbian native windows Added reference counting to QWidgetBackingStore Added tst_QWidget::destroyBackingStoreWhenHidden
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/qapplication_s60.cpp24
-rw-r--r--src/gui/kernel/qapplication_x11.cpp2
-rw-r--r--src/gui/kernel/qwidget.cpp57
-rw-r--r--src/gui/kernel/qwidget_p.h44
-rw-r--r--src/gui/kernel/qwidget_s60.cpp5
5 files changed, 110 insertions, 22 deletions
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index b1e0f63..78027b2 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -1703,19 +1703,27 @@ int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent
return 1;
const TWsVisibilityChangedEvent *visChangedEvent = event->VisibilityChanged();
QWidget *w = QWidgetPrivate::mapper->value(control);
- if (!w->d_func()->maybeTopData())
+ QWidget *const window = w->window();
+ if (!window->d_func()->maybeTopData())
break;
+ QRefCountedWidgetBackingStore &backingStore = window->d_func()->maybeTopData()->backingStore;
if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible) {
- delete w->d_func()->topData()->backingStore;
- w->d_func()->topData()->backingStore = 0;
+ // Decrement backing store reference count
+ backingStore.deref();
// In order to ensure that any resources used by the window surface
// are immediately freed, we flush the WSERV command buffer.
S60->wsSession().Flush();
- } else if ((visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible)
- && !w->d_func()->maybeBackingStore()) {
- w->d_func()->topData()->backingStore = new QWidgetBackingStore(w);
- w->d_func()->invalidateBuffer(w->rect());
- w->repaint();
+ } else if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible) {
+ if (backingStore.data()) {
+ // Increment backing store reference count
+ backingStore.ref();
+ } else {
+ // Create backing store with an initial reference count of 1
+ backingStore.create(window);
+ backingStore.ref();
+ w->d_func()->invalidateBuffer(w->rect());
+ w->repaint();
+ }
}
return 1;
}
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index 25a7750..304cd17 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -5245,7 +5245,7 @@ bool QETWidget::translateConfigEvent(const XEvent *event)
if (isVisible() && data->crect.size() != oldSize) {
Q_ASSERT(d->extra->topextra);
- QWidgetBackingStore *bs = d->extra->topextra->backingStore;
+ QWidgetBackingStore *bs = d->extra->topextra->backingStore.data();
const bool hasStaticContents = bs && bs->hasStaticContents();
// If we have a backing store with static contents, we have to disable the top-level
// resize optimization in order to get invalidated regions for resized widgets.
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index e180001..a9ea9ac 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -161,6 +161,51 @@ static inline bool hasBackingStoreSupport()
extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp
extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp
+
+QRefCountedWidgetBackingStore::QRefCountedWidgetBackingStore()
+ : m_ptr(0)
+ , m_count(0)
+{
+
+}
+
+QRefCountedWidgetBackingStore::~QRefCountedWidgetBackingStore()
+{
+ delete m_ptr;
+}
+
+void QRefCountedWidgetBackingStore::create(QWidget *widget)
+{
+ destroy();
+ m_ptr = new QWidgetBackingStore(widget);
+ m_count = 0;
+}
+
+void QRefCountedWidgetBackingStore::destroy()
+{
+ delete m_ptr;
+ m_ptr = 0;
+ m_count = 0;
+}
+
+void QRefCountedWidgetBackingStore::ref()
+{
+ Q_ASSERT(m_ptr);
+ ++m_count;
+}
+
+void QRefCountedWidgetBackingStore::deref()
+{
+ if (m_count) {
+ Q_ASSERT(m_ptr);
+ if (0 == --m_count) {
+ delete m_ptr;
+ m_ptr = 0;
+ }
+ }
+}
+
+
QWidgetPrivate::QWidgetPrivate(int version)
: QObjectPrivate(version)
, extra(0)
@@ -1324,11 +1369,9 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow)
// a real toplevel window needs a backing store
if (isWindow() && windowType() != Qt::Desktop) {
- delete d->topData()->backingStore;
- // QWidgetBackingStore will check this variable, hence it must be 0
- d->topData()->backingStore = 0;
+ d->topData()->backingStore.destroy();
if (hasBackingStoreSupport())
- d->topData()->backingStore = new QWidgetBackingStore(this);
+ d->topData()->backingStore.create(this);
}
d->setModal_sys();
@@ -1451,8 +1494,7 @@ QWidget::~QWidget()
// the backing store will delete its window surface, which may or may
// not have a reference to this widget that will be used later to
// notify the window it no longer has a surface.
- delete d->extra->topextra->backingStore;
- d->extra->topextra->backingStore = 0;
+ d->extra->topextra->backingStore.destroy();
}
#endif
if (QWidgetBackingStore *bs = d->maybeBackingStore()) {
@@ -1540,7 +1582,6 @@ void QWidgetPrivate::createTLExtra()
QTLWExtra* x = extra->topextra = new QTLWExtra;
x->icon = 0;
x->iconPixmap = 0;
- x->backingStore = 0;
x->windowSurface = 0;
x->sharedPainter = 0;
x->incw = x->inch = 0;
@@ -1619,7 +1660,7 @@ void QWidgetPrivate::deleteExtra()
#endif
if (extra->topextra) {
deleteTLSysExtra();
- delete extra->topextra->backingStore;
+ extra->topextra->backingStore.destroy();
delete extra->topextra->icon;
delete extra->topextra->iconPixmap;
#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER)
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index 555647c..9f7ad95 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -110,13 +110,53 @@ class QWidgetItemV2;
class QStyle;
+class Q_AUTOTEST_EXPORT QRefCountedWidgetBackingStore
+{
+public:
+ QRefCountedWidgetBackingStore();
+ ~QRefCountedWidgetBackingStore();
+
+ void create(QWidget *tlw);
+ void destroy();
+
+ void ref();
+ void deref();
+
+ inline QWidgetBackingStore* data()
+ {
+ return m_ptr;
+ }
+
+ inline QWidgetBackingStore* operator->()
+ {
+ return m_ptr;
+ }
+
+ inline QWidgetBackingStore& operator*()
+ {
+ return *m_ptr;
+ }
+
+ inline operator bool() const
+ {
+ return (0 != m_ptr);
+ }
+
+private:
+ Q_DISABLE_COPY(QRefCountedWidgetBackingStore)
+
+private:
+ QWidgetBackingStore* m_ptr;
+ int m_count;
+};
+
struct QTLWExtra {
// *************************** Cross-platform variables *****************************
// Regular pointers (keep them together to avoid gaps on 64 bits architectures).
QIcon *icon; // widget icon
QPixmap *iconPixmap;
- QWidgetBackingStore *backingStore;
+ QRefCountedWidgetBackingStore backingStore;
QWindowSurface *windowSurface;
QPainter *sharedPainter;
@@ -907,7 +947,7 @@ inline QWidgetBackingStore *QWidgetPrivate::maybeBackingStore() const
{
Q_Q(const QWidget);
QTLWExtra *x = q->window()->d_func()->maybeTopData();
- return x ? x->backingStore : 0;
+ return x ? x->backingStore.data() : 0;
}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index 438c2a3..86b858d 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -433,6 +433,7 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
// Request mouse move events.
drawableWindow->PointerFilter(EPointerFilterEnterExit
| EPointerFilterMove | EPointerFilterDrag, 0);
+ drawableWindow->EnableVisibilityChangeEvents();
if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) {
activateSymbianWindow(control.data());
@@ -908,14 +909,12 @@ void QWidgetPrivate::registerDropSite(bool /* on */)
void QWidgetPrivate::createTLSysExtra()
{
- extra->topextra->backingStore = 0;
extra->topextra->inExpose = 0;
}
void QWidgetPrivate::deleteTLSysExtra()
{
- delete extra->topextra->backingStore;
- extra->topextra->backingStore = 0;
+ extra->topextra->backingStore.destroy();
}
void QWidgetPrivate::createSysExtra()