summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gui/kernel/qplatformwindow.cpp2
-rw-r--r--src/gui/kernel/qwindow.cpp46
-rw-r--r--src/widgets/accessible/qaccessiblewidgetfactory.cpp9
3 files changed, 46 insertions, 11 deletions
diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp
index aea029b7f5..fd3ce40342 100644
--- a/src/gui/kernel/qplatformwindow.cpp
+++ b/src/gui/kernel/qplatformwindow.cpp
@@ -62,6 +62,8 @@ QPlatformWindow::QPlatformWindow(QWindow *window)
*/
QPlatformWindow::~QPlatformWindow()
{
+ // We don't flush window system events here, as the event will be
+ // delivered with a platform window that is half-way destroyed.
}
/*!
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 21734f1619..11ae3aa5c7 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -1648,15 +1648,6 @@ void QWindow::destroy()
}
}
- if (QGuiApplicationPrivate::focus_window == this)
- QGuiApplicationPrivate::focus_window = parent();
- if (QGuiApplicationPrivate::currentMouseWindow == this)
- QGuiApplicationPrivate::currentMouseWindow = parent();
- if (QGuiApplicationPrivate::currentMousePressWindow == this)
- QGuiApplicationPrivate::currentMousePressWindow = parent();
- if (QGuiApplicationPrivate::tabletPressTarget == this)
- QGuiApplicationPrivate::tabletPressTarget = parent();
-
bool wasVisible = isVisible();
d->visibilityOnDestroy = wasVisible && d->platformWindow;
@@ -1665,11 +1656,44 @@ void QWindow::destroy()
QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed);
QGuiApplication::sendEvent(this, &e);
- delete d->platformWindow;
+ QPlatformWindow *platformWindow = d->platformWindow;
+ d->platformWindow = 0;
+
+ // We flush before deleting the platform window so that any pending activation
+ // events for the window will be delivered.
+ QWindowSystemInterface::flushWindowSystemEvents();
+
+ delete platformWindow;
+
+ // Then we flush again so that if the platform plugin sent any deactivation
+ // events as a result of being destroyed, we can pick that up by looking at
+ // QGuiApplicationPrivate::focus_window, which will be up to date.
+ QWindowSystemInterface::flushWindowSystemEvents();
+
d->resizeEventPending = true;
d->receivedExpose = false;
d->exposed = false;
- d->platformWindow = 0;
+
+ // Ensure Qt doesn't refer to a destroyed QWindow if the platform plugin
+ // didn't reset the window activation or other states as part of setVisible
+ // or its destruction. We make a best guess of transferring to the parent
+ // window, as this is what most window managers will do. We go through the
+ // QWindowSystemInterface so that the proper signals and events are sent
+ // as a result of the reset.
+ if (QGuiApplicationPrivate::focus_window == this)
+ QWindowSystemInterface::handleWindowActivated(parent());
+ if (QGuiApplicationPrivate::currentMouseWindow == this)
+ QWindowSystemInterface::handleEnterLeaveEvent(parent(), this);
+
+ // FIXME: Handle these two though QPA like the others. Unfortunately both
+ // processMouseEvent and processTabletEvent in QGuiApplication have conditions
+ // that make sending the event though QPA not feasable right now.
+ if (QGuiApplicationPrivate::currentMousePressWindow == this)
+ QGuiApplicationPrivate::currentMousePressWindow = parent();
+ if (QGuiApplicationPrivate::tabletPressTarget == this)
+ QGuiApplicationPrivate::tabletPressTarget = parent();
+
+ QWindowSystemInterface::flushWindowSystemEvents();
if (wasVisible)
d->maybeQuitOnLastWindowClosed();
diff --git a/src/widgets/accessible/qaccessiblewidgetfactory.cpp b/src/widgets/accessible/qaccessiblewidgetfactory.cpp
index 4fa7c89482..00e21da34d 100644
--- a/src/widgets/accessible/qaccessiblewidgetfactory.cpp
+++ b/src/widgets/accessible/qaccessiblewidgetfactory.cpp
@@ -43,6 +43,7 @@
#include <qtreeview.h>
#include <qvariant.h>
#include <qaccessible.h>
+#include <private/qwidget_p.h>
#ifndef QT_NO_ACCESSIBILITY
@@ -53,7 +54,15 @@ QAccessibleInterface *qAccessibleFactory(const QString &classname, QObject *obje
QAccessibleInterface *iface = 0;
if (!object || !object->isWidgetType())
return iface;
+
+ // QWidget emits destroyed() from its destructor instead of letting the QObject
+ // destructor do it, which means the QWidget is unregistered from the accessibillity
+ // cache. But QWidget destruction also emits enter and leave events, which may end
+ // up here, so we have to ensure that we don't fill the cache with an entry of
+ // a widget that is going away.
QWidget *widget = static_cast<QWidget*>(object);
+ if (QWidgetPrivate::get(widget)->data.in_destructor)
+ return iface;
if (false) {
#ifndef QT_NO_LINEEDIT