Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Split QPlatformWindow::isEmbedded into isAncestorOf to separate concerns
The function was doing two things, both checking window ancestry and
whether or the window was a direct child of non-Qt window. The former
has now been split of in a QPlatformWindow::isAncestorOf(), which
simplifies the code in e.g. QApplicationPrivate::isWindowBlocked().

Change-Id: I259a190e03ef8def23356005474eeeee74c9ae89
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
  • Loading branch information
torarnv committed Jan 5, 2017
1 parent c5282fc commit 2ac50ac
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 33 deletions.
27 changes: 21 additions & 6 deletions src/gui/kernel/qplatformwindow.cpp
Expand Up @@ -192,15 +192,30 @@ bool QPlatformWindow::isActive() const
}

/*!
Returns \c true if the window is a descendant of an embedded non-Qt window.
Example of an embedded non-Qt window is the parent window of an in-process QAxServer.
Returns \c true if the window is an ancestor of the given \a child.
If \a parentWindow is nonzero, only check if the window is embedded in the
specified \a parentWindow.
Platform overrides should iterate the native window hierarchy of the child,
to ensure that ancestary is reflected even with native windows in the window
hierarchy.
*/
bool QPlatformWindow::isEmbedded(const QPlatformWindow *parentWindow) const
bool QPlatformWindow::isAncestorOf(const QPlatformWindow *child) const
{
for (const QPlatformWindow *parent = child->parent(); parent; parent = child->parent()) {
if (parent == this)
return true;
}

return false;
}

/*!
Returns \c true if the window is a child of a non-Qt window.
A embedded window has no parent platform window as reflected
though parent(), but will have a native parent window.
*/
bool QPlatformWindow::isEmbedded() const
{
Q_UNUSED(parentWindow);
return false;
}

Expand Down
3 changes: 2 additions & 1 deletion src/gui/kernel/qplatformwindow.h
Expand Up @@ -102,7 +102,8 @@ class Q_GUI_EXPORT QPlatformWindow : public QPlatformSurface

virtual bool isExposed() const;
virtual bool isActive() const;
virtual bool isEmbedded(const QPlatformWindow *parentWindow = 0) const;
virtual bool isAncestorOf(const QPlatformWindow *child) const;
virtual bool isEmbedded() const;
virtual QPoint mapToGlobal(const QPoint &pos) const;
virtual QPoint mapFromGlobal(const QPoint &pos) const;

Expand Down
9 changes: 7 additions & 2 deletions src/gui/kernel/qwindow.cpp
Expand Up @@ -1300,8 +1300,13 @@ bool QWindow::isAncestorOf(const QWindow *child, AncestorMode mode) const
if (child->parent() == this || (mode == IncludeTransients && child->transientParent() == this))
return true;

if (child->parent(mode) && isAncestorOf(child->parent(mode), mode))
return true;
if (QWindow *parent = child->parent(mode)) {
if (isAncestorOf(parent, mode))
return true;
} else if (handle() && child->handle()) {
if (handle()->isAncestorOf(child->handle()))
return true;
}

return false;
}
Expand Down
16 changes: 6 additions & 10 deletions src/plugins/platforms/windows/qwindowswindow.cpp
Expand Up @@ -1243,18 +1243,14 @@ bool QWindowsWindow::isActive() const
return false;
}

bool QWindowsWindow::isEmbedded(const QPlatformWindow *parentWindow) const
bool QWindowsWindow::isAncestorOf(const QPlatformWindow *child) const
{
if (parentWindow) {
const QWindowsWindow *ww = static_cast<const QWindowsWindow *>(parentWindow);
const HWND hwnd = ww->handle();
if (!IsChild(hwnd, m_data.hwnd))
return false;
}

if (!m_data.embedded && parent())
return parent()->isEmbedded();
const QWindowsWindow *childWindow = static_cast<const QWindowsWindow *>(child);
return IsChild(m_data.hwnd, childWindow->handle());
}

bool QWindowsWindow::isEmbedded() const
{
return m_data.embedded;
}

Expand Down
3 changes: 2 additions & 1 deletion src/plugins/platforms/windows/qwindowswindow.h
Expand Up @@ -222,7 +222,8 @@ class QWindowsWindow : public QWindowsBaseWindow
bool isVisible() const;
bool isExposed() const override { return testFlag(Exposed); }
bool isActive() const override;
bool isEmbedded(const QPlatformWindow *parentWindow = 0) const override;
bool isAncestorOf(const QPlatformWindow *child) const override;
bool isEmbedded() const override;
QPoint mapToGlobal(const QPoint &pos) const override;
QPoint mapFromGlobal(const QPoint &pos) const override;

Expand Down
7 changes: 2 additions & 5 deletions src/plugins/platforms/xcb/qxcbwindow.cpp
Expand Up @@ -2154,12 +2154,9 @@ bool QXcbWindow::isExposed() const
return m_mapped;
}

bool QXcbWindow::isEmbedded(const QPlatformWindow *parentWindow) const
bool QXcbWindow::isEmbedded() const
{
if (!m_embedded)
return false;

return parentWindow ? (parentWindow == parent()) : true;
return m_embedded;
}

QPoint QXcbWindow::mapToGlobal(const QPoint &pos) const
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/platforms/xcb/qxcbwindow.h
Expand Up @@ -87,7 +87,7 @@ class Q_XCB_EXPORT QXcbWindow : public QXcbObject, public QXcbWindowEventListene
void setParent(const QPlatformWindow *window) override;

bool isExposed() const override;
bool isEmbedded(const QPlatformWindow *parentWindow = 0) const override;
bool isEmbedded() const override;
QPoint mapToGlobal(const QPoint &pos) const override;
QPoint mapFromGlobal(const QPoint &pos) const override;

Expand Down
7 changes: 0 additions & 7 deletions src/widgets/kernel/qapplication.cpp
Expand Up @@ -2462,13 +2462,6 @@ bool QApplicationPrivate::isWindowBlocked(QWindow *window, QWindow **blockingWin
return false;
}

// Embedded windows are not visible in normal parent-child chain,
// so check the native parent chain, too.
const QPlatformWindow *platWin = window->handle();
const QPlatformWindow *modalPlatWin = modalWindow->handle();
if (platWin && modalPlatWin && platWin->isEmbedded(modalPlatWin))
return false;

Qt::WindowModality windowModality = modalWindow->modality();
QWidgetWindow *modalWidgetWindow = qobject_cast<QWidgetWindow *>(modalWindow);
if (windowModality == Qt::NonModal) {
Expand Down

0 comments on commit 2ac50ac

Please sign in to comment.