diff options
author | Sergio Ahumada <sergio.ahumada@nokia.com> | 2012-04-17 10:38:24 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-04-17 10:38:24 +0200 |
commit | 16b53b2f0e3f8f64a59c465493a6209eb7f9ab47 (patch) | |
tree | bbb63401eb3c56c32ad9bd9be66bae8d3590de6b /src/gui/kernel/qguiapplication.cpp | |
parent | 2c13dc7482690756280cfefe8515eb809b069721 (diff) | |
parent | 9bd032355163d92cda5e7e59ecd21214b131f187 (diff) |
Merge "Merge remote-tracking branch 'origin/master' into api_changes" into refs/staging/api_changes
Diffstat (limited to 'src/gui/kernel/qguiapplication.cpp')
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 158 |
1 files changed, 157 insertions, 1 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index cb6f26b2c5..9ffc35a608 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -114,7 +114,6 @@ enum ApplicationResourceFlags static unsigned applicationResourceFlags = 0; QString *QGuiApplicationPrivate::platform_name = 0; -bool QGuiApplicationPrivate::app_do_modal = false; QPalette *QGuiApplicationPrivate::app_pal = 0; // default application palette @@ -381,6 +380,132 @@ QGuiApplicationPrivate::QGuiApplicationPrivate(int &argc, char **argv, int flags } /*! + Returns the most recently shown modal window. If no modal windows are + visible, this function returns zero. + + A modal window is a window which has its + \l{QWindow::windowModality}{windowModality} property set to Qt::WindowModal + or Qt::ApplicationModal. A modal window must be closed before the user can + continue with other parts of the program. + + Modal window are organized in a stack. This function returns the modal + window at the top of the stack. + + \sa Qt::WindowModality, QWindow::setWindowModality() +*/ +QWindow *QGuiApplication::modalWindow() +{ + if (QGuiApplicationPrivate::self->modalWindowList.isEmpty()) + return 0; + return QGuiApplicationPrivate::self->modalWindowList.first(); +} + +void QGuiApplicationPrivate::showModalWindow(QWindow *window) +{ + self->modalWindowList.prepend(window); + + 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); + } + } +} + +void QGuiApplicationPrivate::hideModalWindow(QWindow *window) +{ + self->modalWindowList.removeAll(window); + + QEvent e(QEvent::WindowUnblocked); + 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); + } + } +} + +/* + Returns true if \a window is blocked by a modal window. If \a + blockingWindow is non-zero, *blockingWindow will be set to the blocking + window (or to zero if \a window is not blocked). +*/ +bool QGuiApplicationPrivate::isWindowBlocked(QWindow *window, QWindow **blockingWindow) const +{ + QWindow *unused = 0; + if (!blockingWindow) + blockingWindow = &unused; + + if (modalWindowList.isEmpty()) { + *blockingWindow = 0; + return false; + } + + for (int i = 0; i < modalWindowList.count(); ++i) { + QWindow *modalWindow = modalWindowList.at(i); + + { + // check if the modal window is our window or a (transient) parent of our window + QWindow *w = window; + while (w) { + if (w == modalWindow) { + *blockingWindow = 0; + return false; + } + QWindow *p = w->parent(); + if (!p) + p = w->transientParent(); + w = p; + } + } + + Qt::WindowModality windowModality = modalWindow->windowModality(); + switch (windowModality) { + case Qt::ApplicationModal: + { + if (modalWindow != window) { + *blockingWindow = modalWindow; + return true; + } + break; + } + case Qt::WindowModal: + { + QWindow *w = window; + do { + QWindow *m = modalWindow; + do { + if (m == w) { + *blockingWindow = m; + return true; + } + QWindow *p = m->parent(); + if (!p) + p = m->transientParent(); + m = p; + } while (m); + QWindow *p = w->parent(); + if (!p) + p = w->transientParent(); + w = p; + } while (w); + break; + } + default: + Q_ASSERT_X(false, "QGuiApplication", "internal error, a modal widget cannot be modeless"); + break; + } + } + *blockingWindow = 0; + return false; +} + +/*! Returns the QWindow that receives events tied to focus, such as key events. */ @@ -1049,6 +1174,11 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo } if (window) { + if (window->d_func()->blockedByModalWindow) { + // a modal window is blocking this window, don't allow mouse events through + return; + } + QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers); ev.setTimestamp(e->timestamp); #ifndef QT_NO_CURSOR @@ -1111,6 +1241,11 @@ void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::Wh QWindow *window = e->window.data(); if (window) { + if (window->d_func()->blockedByModalWindow) { + // a modal window is blocking this window, don't allow wheel events through + return; + } + QWheelEvent ev(e->localPos, e->globalPos, e->pixelDelta, e->angleDelta, e->qt4Delta, e->qt4Orientation, buttons, e->modifiers); ev.setTimestamp(e->timestamp); QGuiApplication::sendSpontaneousEvent(window, &ev); @@ -1128,6 +1263,10 @@ void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyE window = QGuiApplication::activeWindow(); if (!window) return; + if (window->d_func()->blockedByModalWindow) { + // a modal window is blocking this window, don't allow key events through + return; + } QKeyEvent ev(e->keyType, e->key, e->modifiers, e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers, @@ -1140,6 +1279,10 @@ void QGuiApplicationPrivate::processEnterEvent(QWindowSystemInterfacePrivate::En { if (!e->enter) return; + if (e->enter.data()->d_func()->blockedByModalWindow) { + // a modal window is blocking this window, don't allow enter events through + return; + } QEvent event(QEvent::Enter); QCoreApplication::sendSpontaneousEvent(e->enter.data(), &event); @@ -1149,6 +1292,10 @@ void QGuiApplicationPrivate::processLeaveEvent(QWindowSystemInterfacePrivate::Le { if (!e->leave) return; + if (e->leave.data()->d_func()->blockedByModalWindow) { + // a modal window is blocking this window, don't allow leave events through + return; + } QEvent event(QEvent::Leave); QCoreApplication::sendSpontaneousEvent(e->leave.data(), &event); @@ -1263,6 +1410,10 @@ void QGuiApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::Cl { if (e->window.isNull()) return; + if (e->window.data()->d_func()->blockedByModalWindow) { + // a modal window is blocking this window, don't allow close events through + return; + } QCloseEvent event; QGuiApplication::sendSpontaneousEvent(e->window.data(), &event); @@ -1451,6 +1602,11 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To break; } + if (w->d_func()->blockedByModalWindow) { + // a modal window is blocking this window, don't allow touch events through + continue; + } + QTouchEvent touchEvent(eventType, e->device, e->modifiers, |