diff options
author | Samuel Rødal <samuel.rodal@nokia.com> | 2011-05-23 13:46:18 +0200 |
---|---|---|
committer | Samuel Rødal <samuel.rodal@nokia.com> | 2011-05-23 13:46:18 +0200 |
commit | 1894da818656dd69a1309ecb7ce7ff816481ecfa (patch) | |
tree | bb58330182a9346f1e56e4a313ad665029861a17 | |
parent | c5d1f239426b4cf9b3ddc0f34fd1514504dfb985 (diff) |
Added QWindow::setTransientParent().
Make the transient parent relationship explicit instead of having it
encoded through the window flags.
-rw-r--r-- | src/gui/kernel/qwindow.cpp | 23 | ||||
-rw-r--r-- | src/gui/kernel/qwindow.h | 3 | ||||
-rw-r--r-- | src/gui/kernel/qwindow_p.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 21 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget_qpa.cpp | 32 |
5 files changed, 63 insertions, 18 deletions
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index b5bcc72d10..e53a205e88 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -105,7 +105,7 @@ void QWindow::create() QObject *object = childObjects.at(i); if(object->isWindowType()) { QWindow *window = static_cast<QWindow *>(object); - if (window->d_func()->platformWindow && !window->isTopLevel()) + if (window->d_func()->platformWindow) window->d_func()->platformWindow->setParent(d->platformWindow); } } @@ -138,7 +138,7 @@ void QWindow::setParent(QWindow *parent) QObject::setParent(parent); if (d->platformWindow) { - if (parent && parent->d_func()->platformWindow && !isTopLevel()) { + if (parent && parent->d_func()->platformWindow) { d->platformWindow->setParent(parent->d_func()->platformWindow); } else { d->platformWindow->setParent(0); @@ -149,12 +149,12 @@ void QWindow::setParent(QWindow *parent) } /*! - Returns whether the window is top level. + Returns whether the window is top level, i.e. has no parent window. */ bool QWindow::isTopLevel() const { Q_D(const QWindow); - return d->windowFlags & Qt::Window; + return d->parentWindow != 0; } bool QWindow::isModal() const @@ -293,6 +293,21 @@ void QWindow::setWindowState(Qt::WindowState state) d->windowState = state; } +/*! + Sets the transient parent, which is a hint to the window manager that this window is a dialog or pop-up on behalf of the given window. +*/ +void QWindow::setTransientParent(QWindow *parent) +{ + Q_D(QWindow); + d->transientParent = parent; +} + +QWindow *QWindow::transientParent() const +{ + Q_D(const QWindow); + return d->transientParent.data(); +} + QSize QWindow::minimumSize() const { Q_D(const QWindow); diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h index 998a48fb42..5b002a4791 100644 --- a/src/gui/kernel/qwindow.h +++ b/src/gui/kernel/qwindow.h @@ -119,6 +119,9 @@ public: Qt::WindowState windowState() const; void setWindowState(Qt::WindowState state); + void setTransientParent(QWindow *parent); + QWindow *transientParent() const; + QSize minimumSize() const; QSize maximumSize() const; QSize baseSize() const; diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h index f52dd559f1..aca26089ce 100644 --- a/src/gui/kernel/qwindow_p.h +++ b/src/gui/kernel/qwindow_p.h @@ -68,6 +68,7 @@ public: , surface(0) , windowState(Qt::WindowNoState) , maximumSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX) + , transientParent(0) { isWindow = true; } @@ -94,6 +95,7 @@ public: QSize sizeIncrement; Qt::WindowModality modality; + QPointer<QWindow> transientParent; }; diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 2a7594ee9b..0f1375d764 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -136,7 +136,7 @@ void QXcbWindow::create() QRect rect = window()->geometry(); xcb_window_t xcb_parent_id = m_screen->root(); - if (parent() && !window()->isTopLevel()) + if (parent()) xcb_parent_id = static_cast<QXcbWindow *>(parent())->xcb_window(); #if defined(XCB_USE_GLX) || defined(XCB_USE_EGL) @@ -322,14 +322,17 @@ void QXcbWindow::show() propagateSizeHints(); // update WM_TRANSIENT_FOR - if (isTransient(window()) && parent()) { - // ICCCM 4.1.2.6 - xcb_window_t parentWindow = static_cast<QXcbWindow *>(parent())->xcb_window(); - - // todo: set transient for group (wm_client_leader) if no parent, a la qwidget_x11.cpp - Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, - XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32, - 1, &parentWindow)); + if (window()->transientParent() && isTransient(window())) { + QXcbWindow *transientXcbParent = static_cast<QXcbWindow *>(window()->transientParent()->handle()); + if (transientXcbParent) { + // ICCCM 4.1.2.6 + xcb_window_t parentWindow = transientXcbParent->xcb_window(); + + // todo: set transient for group (wm_client_leader) if no parent, a la qwidget_x11.cpp + Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, + XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32, + 1, &parentWindow)); + } } // update _MOTIF_WM_HINTS diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp index 02487679bf..b4ed00d36d 100644 --- a/src/widgets/kernel/qwidget_qpa.cpp +++ b/src/widgets/kernel/qwidget_qpa.cpp @@ -65,8 +65,12 @@ void q_createNativeChildrenAndSetParent(QWindow *parentWindow, const QWidget *pa if (childWidget->testAttribute(Qt::WA_NativeWindow)) { if (!childWidget->windowHandle()) childWidget->winId(); - if (childWidget->windowHandle()) - childWidget->windowHandle()->setParent(parentWindow); + if (childWidget->windowHandle()) { + if (childWidget->isTopLevel()) + childWidget->windowHandle()->setTransientParent(parentWindow); + else + childWidget->windowHandle()->setParent(parentWindow); + } } else { q_createNativeChildrenAndSetParent(parentWindow,childWidget); } @@ -103,8 +107,15 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO } if (QWidget *nativeParent = q->nativeParentWidget()) { - if (nativeParent->windowHandle()) - win->setParent(nativeParent->windowHandle()); + if (nativeParent->windowHandle()) { + if (flags & Qt::Window) { + win->setTransientParent(nativeParent->windowHandle()); + win->setParent(0); + } else { + win->setTransientParent(0); + win->setParent(nativeParent->windowHandle()); + } + } } win->create(); @@ -185,7 +196,18 @@ void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f) q->windowHandle()->setWindowFlags(f); QWidget *parentWithWindow = newparent ? (newparent->windowHandle() ? newparent : newparent->nativeParentWidget()) : 0; - q->windowHandle()->setParent(parentWithWindow ? parentWithWindow->windowHandle() : 0); + if (parentWithWindow) { + if (f & Qt::Window) { + q->windowHandle()->setTransientParent(parentWithWindow->windowHandle()); + q->windowHandle()->setParent(0); + } else { + q->windowHandle()->setTransientParent(0); + q->windowHandle()->setParent(parentWithWindow->windowHandle()); + } + } else { + q->windowHandle()->setTransientParent(0); + q->windowHandle()->setParent(0); + } } } |