Prevent ending up in a state where focus is perpetually grabbed.
Mouse / enter / leave / key events etc are all blocked when a window has the blockedByModalWindow flag set. The problem appears if a QWindow is created and only later directly or indirectly parented to a modal window that's currently showing. Since the decision on whether a window should be blocked or not is based on its parent / transient parent chain, we need to reevaluate the blocked status each time the parent or transient parent of a window changes. Task-number: QTBUG-26112 Change-Id: Ida6b118b556fe26d17fa86335a0fe7baddc7eaf8 Reviewed-by: Lars Knoll <lars.knoll@nokia.com> Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
This commit is contained in:
parent
3c8eb40487
commit
7967cb4f48
@ -402,18 +402,30 @@ QWindow *QGuiApplication::modalWindow()
|
||||
return QGuiApplicationPrivate::self->modalWindowList.first();
|
||||
}
|
||||
|
||||
void QGuiApplicationPrivate::showModalWindow(QWindow *window)
|
||||
void QGuiApplicationPrivate::updateBlockedStatus(QWindow *window)
|
||||
{
|
||||
self->modalWindowList.prepend(window);
|
||||
bool shouldBeBlocked = false;
|
||||
if (window->windowType() != Qt::Tool && !self->modalWindowList.isEmpty())
|
||||
shouldBeBlocked = self->isWindowBlocked(window);
|
||||
|
||||
if (shouldBeBlocked != window->d_func()->blockedByModalWindow) {
|
||||
QEvent e(shouldBeBlocked ? QEvent::WindowBlocked : QEvent::WindowUnblocked);
|
||||
|
||||
window->d_func()->blockedByModalWindow = shouldBeBlocked;
|
||||
QGuiApplication::sendEvent(window, &e);
|
||||
}
|
||||
}
|
||||
|
||||
void QGuiApplicationPrivate::showModalWindow(QWindow *modal)
|
||||
{
|
||||
self->modalWindowList.prepend(modal);
|
||||
|
||||
QEvent e(QEvent::WindowBlocked);
|
||||
QWindowList windows = QGuiApplication::topLevelWindows();
|
||||
for (int i = 0; i < windows.count(); ++i) {
|
||||
QWindow *window = windows.at(i);
|
||||
if (!window->d_func()->blockedByModalWindow && window->windowType() != Qt::Tool && self->isWindowBlocked(window)) {
|
||||
window->d_func()->blockedByModalWindow = true;
|
||||
QGuiApplication::sendEvent(window, &e);
|
||||
}
|
||||
if (!window->d_func()->blockedByModalWindow)
|
||||
updateBlockedStatus(window);
|
||||
}
|
||||
}
|
||||
|
||||
@ -425,10 +437,8 @@ void QGuiApplicationPrivate::hideModalWindow(QWindow *window)
|
||||
QWindowList windows = QGuiApplication::topLevelWindows();
|
||||
for (int i = 0; i < windows.count(); ++i) {
|
||||
QWindow *window = windows.at(i);
|
||||
if (window->d_func()->blockedByModalWindow && window->windowType() != Qt::Tool && !self->isWindowBlocked(window)) {
|
||||
window->d_func()->blockedByModalWindow = false;
|
||||
QGuiApplication::sendEvent(window, &e);
|
||||
}
|
||||
if (window->d_func()->blockedByModalWindow)
|
||||
updateBlockedStatus(window);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,6 +168,7 @@ public:
|
||||
QWindowList modalWindowList;
|
||||
static void showModalWindow(QWindow *window);
|
||||
static void hideModalWindow(QWindow *window);
|
||||
static void updateBlockedStatus(QWindow *window);
|
||||
virtual bool isWindowBlocked(QWindow *window, QWindow **blockingWindow = 0) const;
|
||||
|
||||
static Qt::MouseButtons buttons;
|
||||
|
@ -360,6 +360,8 @@ void QWindow::setParent(QWindow *parent)
|
||||
}
|
||||
|
||||
d->parentWindow = parent;
|
||||
|
||||
QGuiApplicationPrivate::updateBlockedStatus(this);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -784,6 +786,8 @@ void QWindow::setTransientParent(QWindow *parent)
|
||||
{
|
||||
Q_D(QWindow);
|
||||
d->transientParent = parent;
|
||||
|
||||
QGuiApplicationPrivate::updateBlockedStatus(this);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
Loading…
x
Reference in New Issue
Block a user