summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2011-05-23 13:46:18 +0200
committerSamuel Rødal <samuel.rodal@nokia.com>2011-05-23 13:46:18 +0200
commit1894da818656dd69a1309ecb7ce7ff816481ecfa (patch)
treebb58330182a9346f1e56e4a313ad665029861a17
parentc5d1f239426b4cf9b3ddc0f34fd1514504dfb985 (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.cpp23
-rw-r--r--src/gui/kernel/qwindow.h3
-rw-r--r--src/gui/kernel/qwindow_p.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp21
-rw-r--r--src/widgets/kernel/qwidget_qpa.cpp32
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);
+ }
}
}