summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/qapplication_s60.cpp67
-rw-r--r--src/gui/kernel/qgesturemanager.cpp7
-rw-r--r--src/gui/kernel/qt_s60_p.h1
-rw-r--r--src/gui/kernel/qwidget.cpp61
-rw-r--r--src/gui/kernel/qwidget_mac.mm18
-rw-r--r--src/gui/kernel/qwidget_p.h17
-rw-r--r--src/gui/kernel/qwidget_s60.cpp6
7 files changed, 117 insertions, 60 deletions
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index e64ebb1..670bf34 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -135,6 +135,38 @@ void QS60Data::setStatusPaneAndButtonGroupVisibility(bool statusPaneVisible, boo
}
#endif
+void QS60Data::controlVisibilityChanged(CCoeControl *control, bool visible)
+{
+ if (QWidgetPrivate::mapper && QWidgetPrivate::mapper->contains(control)) {
+ QWidget *const widget = QWidgetPrivate::mapper->value(control);
+ QWidget *const window = widget->window();
+ if (QTLWExtra *topData = qt_widget_private(window)->maybeTopData()) {
+ QWidgetBackingStoreTracker &backingStore = topData->backingStore;
+ if (visible) {
+ if (backingStore.data()) {
+ backingStore.registerWidget(widget);
+ } else {
+#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
+ S60->wsSession().SendEffectCommand(ETfxCmdRestoreLayer);
+#endif
+ backingStore.create(window);
+ backingStore.registerWidget(widget);
+ qt_widget_private(widget)->invalidateBuffer(widget->rect());
+ widget->repaint();
+ }
+ } else {
+#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
+ S60->wsSession().SendEffectCommand(ETfxCmdDeallocateLayer);
+#endif
+ backingStore.unregisterWidget(widget);
+ // In order to ensure that any resources used by the window surface
+ // are immediately freed, we flush the WSERV command buffer.
+ S60->wsSession().Flush();
+ }
+ }
+ }
+}
+
bool qt_nograb() // application no-grab option
{
#if defined(QT_DEBUG)
@@ -1475,6 +1507,8 @@ void qt_init(QApplicationPrivate * /* priv */, int)
S60->avkonComponentsSupportTransparency = (value==1) ? true : false;
}
}
+ delete repository;
+ repository = 0;
#endif
#ifdef QT_KEYPAD_NAVIGATION
@@ -1920,35 +1954,10 @@ int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent
if (callSymbianEventFilters(symbianEvent))
return 1;
const TWsVisibilityChangedEvent *visChangedEvent = event->VisibilityChanged();
- QWidget *w = QWidgetPrivate::mapper->value(control);
- QWidget *const window = w->window();
- if (!window->d_func()->maybeTopData())
- break;
- QRefCountedWidgetBackingStore &backingStore = window->d_func()->maybeTopData()->backingStore;
- if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible) {
-#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
- S60->wsSession().SendEffectCommand(ETfxCmdDeallocateLayer);
-#endif
- // 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) {
- if (backingStore.data()) {
- // Increment backing store reference count
- backingStore.ref();
- } else {
-#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
- S60->wsSession().SendEffectCommand(ETfxCmdRestoreLayer);
-#endif
- // Create backing store with an initial reference count of 1
- backingStore.create(window);
- backingStore.ref();
- w->d_func()->invalidateBuffer(w->rect());
- w->repaint();
- }
- }
+ if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible)
+ S60->controlVisibilityChanged(control, false);
+ else if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible)
+ S60->controlVisibilityChanged(control, true);
return 1;
}
break;
diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp
index fe9dd8a..e768a21 100644
--- a/src/gui/kernel/qgesturemanager.cpp
+++ b/src/gui/kernel/qgesturemanager.cpp
@@ -129,7 +129,12 @@ Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *r
void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type)
{
QList<QGestureRecognizer *> list = m_recognizers.values(type);
- m_recognizers.remove(type);
+ while (QGestureRecognizer *recognizer = m_recognizers.take(type)) {
+ if (!m_obsoleteGestures.contains(recognizer)) {
+ // inserting even an empty QSet will cause the recognizer to be deleted on destruction of the manager
+ m_obsoleteGestures.insert(recognizer, QSet<QGesture *>());
+ }
+ }
foreach (QGesture *g, m_gestureToRecognizer.keys()) {
QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g);
if (list.contains(recognizer)) {
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index a18ea07..ad6a99a 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -164,6 +164,7 @@ public:
static inline CEikButtonGroupContainer* buttonGroupContainer();
static void setStatusPaneAndButtonGroupVisibility(bool statusPaneVisible, bool buttonGroupVisible);
#endif
+ static void controlVisibilityChanged(CCoeControl *control, bool visible);
#ifdef Q_OS_SYMBIAN
TTrapHandler *s60InstalledTrapHandler;
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index aaa29a1..dad4848 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -162,47 +162,76 @@ static inline bool hasBackingStoreSupport()
extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp
extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp
+/*!
+ \internal
+ \class QWidgetBackingStoreTracker
+ \brief Class which allows tracking of which widgets are using a given backing store
-QRefCountedWidgetBackingStore::QRefCountedWidgetBackingStore()
+ QWidgetBackingStoreTracker is a thin wrapper around a QWidgetBackingStore pointer,
+ which maintains a list of the QWidgets which are currently using the backing
+ store. This list is modified via the registerWidget and unregisterWidget functions.
+ */
+
+QWidgetBackingStoreTracker::QWidgetBackingStoreTracker()
: m_ptr(0)
- , m_count(0)
{
}
-QRefCountedWidgetBackingStore::~QRefCountedWidgetBackingStore()
+QWidgetBackingStoreTracker::~QWidgetBackingStoreTracker()
{
delete m_ptr;
}
-void QRefCountedWidgetBackingStore::create(QWidget *widget)
+/*!
+ \internal
+ Destroy the contained QWidgetBackingStore, if not null, and clear the list of
+ widgets using the backing store, then create a new QWidgetBackingStore, providing
+ the QWidget.
+ */
+void QWidgetBackingStoreTracker::create(QWidget *widget)
{
destroy();
m_ptr = new QWidgetBackingStore(widget);
- m_count = 0;
}
-void QRefCountedWidgetBackingStore::destroy()
+/*!
+ \internal
+ Destroy the contained QWidgetBackingStore, if not null, and clear the list of
+ widgets using the backing store.
+ */
+void QWidgetBackingStoreTracker::destroy()
{
delete m_ptr;
m_ptr = 0;
- m_count = 0;
+ m_widgets.clear();
}
-void QRefCountedWidgetBackingStore::ref()
+/*!
+ \internal
+ Add the widget to the list of widgets currently using the backing store.
+ If the widget was already in the list, this function is a no-op.
+ */
+void QWidgetBackingStoreTracker::registerWidget(QWidget *w)
{
Q_ASSERT(m_ptr);
- ++m_count;
+ Q_ASSERT(w->internalWinId());
+ Q_ASSERT(qt_widget_private(w)->maybeBackingStore() == m_ptr);
+ m_widgets.insert(w);
}
-void QRefCountedWidgetBackingStore::deref()
+/*!
+ \internal
+ Remove the widget from the list of widgets currently using the backing store.
+ If the widget was in the list, and removing it causes the list to be empty,
+ the backing store is deleted.
+ If the widget was not in the list, this function is a no-op.
+ */
+void QWidgetBackingStoreTracker::unregisterWidget(QWidget *w)
{
- if (m_count) {
- Q_ASSERT(m_ptr);
- if (0 == --m_count) {
- delete m_ptr;
- m_ptr = 0;
- }
+ if (m_widgets.remove(w) && m_widgets.isEmpty()) {
+ delete m_ptr;
+ m_ptr = 0;
}
}
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index 8ae6a99..1979c84 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -2796,10 +2796,14 @@ void QWidgetPrivate::setSubWindowStacking(bool set)
if (QWidget *parent = q->parentWidget()) {
if (parent->testAttribute(Qt::WA_WState_Created)) {
- if (set)
- [qt_mac_window_for(parent) addChildWindow:qt_mac_window_for(q) ordered:NSWindowAbove];
- else
+ if (set) {
+ if (parent->isVisible()) {
+ NSWindow *childwin = qt_mac_window_for(q);
+ [qt_mac_window_for(parent) addChildWindow:childwin ordered:NSWindowAbove];
+ }
+ } else {
[qt_mac_window_for(parent) removeChildWindow:qt_mac_window_for(q)];
+ }
}
}
@@ -2807,10 +2811,12 @@ void QWidgetPrivate::setSubWindowStacking(bool set)
for (int i=0; i<widgets.size(); ++i) {
QWidget *child = widgets.at(i);
if (child->isWindow() && child->testAttribute(Qt::WA_WState_Created) && child->isVisibleTo(q)) {
- if (set)
- [qt_mac_window_for(q) addChildWindow:qt_mac_window_for(child) ordered:NSWindowAbove];
- else
+ if (set) {
+ NSWindow *childwin = qt_mac_window_for(child);
+ [qt_mac_window_for(q) addChildWindow:childwin ordered:NSWindowAbove];
+ } else {
[qt_mac_window_for(q) removeChildWindow:qt_mac_window_for(child)];
+ }
}
}
}
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index 587d7fb..4a79dc7 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -110,17 +110,18 @@ class QWidgetItemV2;
class QStyle;
-class Q_AUTOTEST_EXPORT QRefCountedWidgetBackingStore
+class Q_AUTOTEST_EXPORT QWidgetBackingStoreTracker
{
+
public:
- QRefCountedWidgetBackingStore();
- ~QRefCountedWidgetBackingStore();
+ QWidgetBackingStoreTracker();
+ ~QWidgetBackingStoreTracker();
void create(QWidget *tlw);
void destroy();
- void ref();
- void deref();
+ void registerWidget(QWidget *w);
+ void unregisterWidget(QWidget *w);
inline QWidgetBackingStore* data()
{
@@ -143,11 +144,11 @@ public:
}
private:
- Q_DISABLE_COPY(QRefCountedWidgetBackingStore)
+ Q_DISABLE_COPY(QWidgetBackingStoreTracker)
private:
QWidgetBackingStore* m_ptr;
- int m_count;
+ QSet<QWidget *> m_widgets;
};
struct QTLWExtra {
@@ -156,7 +157,7 @@ struct QTLWExtra {
// Regular pointers (keep them together to avoid gaps on 64 bits architectures).
QIcon *icon; // widget icon
QPixmap *iconPixmap;
- QRefCountedWidgetBackingStore backingStore;
+ QWidgetBackingStoreTracker backingStore;
QWindowSurface *windowSurface;
QPainter *sharedPainter;
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index 56349ad..319f330 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -684,6 +684,12 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
QSymbianControl *old_winid = static_cast<QSymbianControl *>(wasCreated ? data.winid : 0);
if ((q->windowType() == Qt::Desktop))
old_winid = 0;
+
+ // old_winid may not have received a 'not visible' visibility
+ // changed event before being destroyed; make sure that it is
+ // removed from the backing store's list of visible windows.
+ S60->controlVisibilityChanged(old_winid, false);
+
setWinId(0);
// hide and reparent our own window away. Otherwise we might get