summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2011-05-16 17:28:56 +0200
committerSamuel Rødal <samuel.rodal@nokia.com>2011-05-16 17:28:56 +0200
commit10a3b10726d2f46b2a284ecb7533bb9226f8c7c8 (patch)
treeee180a5d21a15d0b26b1bb14c10ca1890b675192
parent25f70314e0e2aa5cb913aba108d2e9c16117004a (diff)
Re-implement transient window support in XCB backend.
If a QWindow has a parent but is top-level the corresponding QPlatformWindow should not be re-parented but instead be made transient for the parent window if possible.
-rw-r--r--src/gui/kernel/qplatformwindow_qpa.cpp11
-rw-r--r--src/gui/kernel/qplatformwindow_qpa.h2
-rw-r--r--src/gui/kernel/qwindow.cpp16
-rw-r--r--src/gui/kernel/qwindow.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp48
-rw-r--r--src/widgets/kernel/qwidget_qpa.cpp8
6 files changed, 50 insertions, 36 deletions
diff --git a/src/gui/kernel/qplatformwindow_qpa.cpp b/src/gui/kernel/qplatformwindow_qpa.cpp
index afbff2ad5d..f6a1260d9d 100644
--- a/src/gui/kernel/qplatformwindow_qpa.cpp
+++ b/src/gui/kernel/qplatformwindow_qpa.cpp
@@ -70,7 +70,7 @@ QPlatformWindow::~QPlatformWindow()
}
/*!
- Returnes the window which belongs to the QPlatformWindow
+ Returns the window which belongs to the QPlatformWindow
*/
QWindow *QPlatformWindow::window() const
{
@@ -79,6 +79,15 @@ QWindow *QPlatformWindow::window() const
}
/*!
+ Returns the parent platform window (or 0 if orphan).
+*/
+QPlatformWindow *QPlatformWindow::parent() const
+{
+ Q_D(const QPlatformWindow);
+ return d->window->parent() ? d->window->parent()->handle() : 0;
+}
+
+/*!
This function is called by Qt whenever a window is moved or the window is resized. The resize
can happen programatically(from ie. user application) or by the window manager. This means that
there is no need to call this function specifically from the window manager callback, instead
diff --git a/src/gui/kernel/qplatformwindow_qpa.h b/src/gui/kernel/qplatformwindow_qpa.h
index de3174bde9..6bfdc5bc75 100644
--- a/src/gui/kernel/qplatformwindow_qpa.h
+++ b/src/gui/kernel/qplatformwindow_qpa.h
@@ -66,6 +66,8 @@ public:
virtual ~QPlatformWindow();
QWindow *window() const;
+ QPlatformWindow *parent() const;
+
virtual void setGeometry(const QRect &rect);
virtual QRect geometry() const;
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 5d4fd763b8..3b01a0d352 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -97,7 +97,7 @@ void QWindow::create()
QObject *object = childObjects.at(i);
if(object->isWindowType()) {
QWindow *window = static_cast<QWindow *>(object);
- if (window->d_func()->platformWindow)
+ if (window->d_func()->platformWindow && !window->isTopLevel())
window->d_func()->platformWindow->setParent(d->platformWindow);
}
}
@@ -133,9 +133,9 @@ void QWindow::setParent(QWindow *parent)
QObject::setParent(parent);
if (d->platformWindow) {
- if (parent && parent->d_func()->platformWindow) {
+ if (parent && parent->d_func()->platformWindow && !isTopLevel()) {
d->platformWindow->setParent(parent->d_func()->platformWindow);
- } else if (!parent) {
+ } else {
d->platformWindow->setParent(0);
}
}
@@ -144,12 +144,12 @@ void QWindow::setParent(QWindow *parent)
}
/*!
- Returns whether the window is top level, i.e. parent-less.
+ Returns whether the window is top level.
*/
bool QWindow::isTopLevel() const
{
Q_D(const QWindow);
- return d->parentWindow == 0;
+ return d->windowFlags & Qt::Window;
}
void QWindow::setWindowFormat(const QWindowFormat &format)
@@ -196,6 +196,12 @@ Qt::WindowFlags QWindow::windowFlags() const
return d->windowFlags;
}
+Qt::WindowType QWindow::windowType() const
+{
+ Q_D(const QWindow);
+ return static_cast<Qt::WindowType>(int(d->windowFlags & Qt::WindowType_Mask));
+}
+
void QWindow::setWindowTitle(const QString &title)
{
Q_D(QWindow);
diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h
index e0a1871ea1..22dbf48538 100644
--- a/src/gui/kernel/qwindow.h
+++ b/src/gui/kernel/qwindow.h
@@ -107,6 +107,7 @@ public:
void setWindowFlags(Qt::WindowFlags flags);
Qt::WindowFlags windowFlags() const;
+ Qt::WindowType windowType() const;
QString windowTitle() const;
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 709efb2bc6..7942e46c1d 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -73,20 +73,17 @@
#include "../eglconvenience/qxlibeglintegration.h"
#endif
-#if 0
// Returns true if we should set WM_TRANSIENT_FOR on \a w
-static inline bool isTransient(const QWidget *w)
+static inline bool isTransient(const QWindow *w)
{
- return ((w->windowType() == Qt::Dialog
- || w->windowType() == Qt::Sheet
- || w->windowType() == Qt::Tool
- || w->windowType() == Qt::SplashScreen
- || w->windowType() == Qt::ToolTip
- || w->windowType() == Qt::Drawer
- || w->windowType() == Qt::Popup)
- && !w->testAttribute(Qt::WA_X11BypassTransientForHint));
+ return w->windowType() == Qt::Dialog
+ || w->windowType() == Qt::Sheet
+ || w->windowType() == Qt::Tool
+ || w->windowType() == Qt::SplashScreen
+ || w->windowType() == Qt::ToolTip
+ || w->windowType() == Qt::Drawer
+ || w->windowType() == Qt::Popup;
}
-#endif
QXcbWindow::QXcbWindow(QWindow *window)
: QPlatformWindow(window)
@@ -119,8 +116,8 @@ QXcbWindow::QXcbWindow(QWindow *window)
QRect rect = window->geometry();
xcb_window_t xcb_parent_id = m_screen->root();
- if (window->parent() && window->parent()->handle())
- xcb_parent_id = static_cast<QXcbWindow *>(window->parent()->handle())->xcb_window();
+ if (parent() && !window->isTopLevel())
+ xcb_parent_id = static_cast<QXcbWindow *>(parent())->xcb_window();
#if defined(XCB_USE_GLX) || defined(XCB_USE_EGL)
if (window->surfaceType() == QWindow::OpenGLSurface
@@ -217,18 +214,6 @@ QXcbWindow::QXcbWindow(QWindow *window)
&m_syncCounter));
}
-#if 0
- if (tlw && isTransient(tlw) && tlw->parentWidget()) {
- // ICCCM 4.1.2.6
- QWidget *p = tlw->parentWidget()->window();
- xcb_window_t parentWindow = p->winId();
- 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));
-
- }
-#endif
-
// set the PID to let the WM kill the application if unresponsive
long pid = getpid();
Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
@@ -278,7 +263,19 @@ void QXcbWindow::show()
xcb_set_wm_hints(xcb_connection(), m_window, &hints);
+ // update WM_NORMAL_HINTS
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));
+ }
}
Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window));
@@ -598,6 +595,7 @@ void QXcbWindow::lower()
void QXcbWindow::propagateSizeHints()
{
+ // update WM_NORMAL_HINTS
xcb_size_hints_t hints;
QRect rect = geometry();
diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp
index 533cc0a47c..e6a55968f9 100644
--- a/src/widgets/kernel/qwidget_qpa.cpp
+++ b/src/widgets/kernel/qwidget_qpa.cpp
@@ -93,11 +93,9 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
QWindow *win = topData()->window;
- if (!q->isWindow()) {
- if (QWidget *nativeParent = q->nativeParentWidget()) {
- if (nativeParent->windowHandle())
- win->setParent(nativeParent->windowHandle());
- }
+ if (QWidget *nativeParent = q->nativeParentWidget()) {
+ if (nativeParent->windowHandle())
+ win->setParent(nativeParent->windowHandle());
}
win->setWindowFlags(data.window_flags);