Add QPlatformWindow::isForeignWindow()

Simplifies code at call sites and allows for refactoring how to decide
if a window is foreign or not at a later point.

Change-Id: Icc51a83bac187f4975535366b53b4990832b6c82
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Tor Arne Vestbø 2017-01-31 13:29:14 +01:00
parent ee8b61bcf5
commit a57f2128b1
12 changed files with 38 additions and 32 deletions

View File

@ -508,7 +508,7 @@ QPlatformScreen *QPlatformWindow::screenForGeometry(const QRect &newGeometry) co
// QRect::center can return a value outside the rectangle if it's empty. // QRect::center can return a value outside the rectangle if it's empty.
// Apply mapToGlobal() in case it is a foreign/embedded window. // Apply mapToGlobal() in case it is a foreign/embedded window.
QPoint center = newGeometry.isEmpty() ? newGeometry.topLeft() : newGeometry.center(); QPoint center = newGeometry.isEmpty() ? newGeometry.topLeft() : newGeometry.center();
if (window()->type() == Qt::ForeignWindow) if (isForeignWindow())
center = mapToGlobal(center - newGeometry.topLeft()); center = mapToGlobal(center - newGeometry.topLeft());
if (!parent() && currentScreen && !currentScreen->geometry().contains(center)) { if (!parent() && currentScreen && !currentScreen->geometry().contains(center)) {

View File

@ -104,6 +104,7 @@ public:
virtual bool isActive() const; virtual bool isActive() const;
virtual bool isAncestorOf(const QPlatformWindow *child) const; virtual bool isAncestorOf(const QPlatformWindow *child) const;
virtual bool isEmbedded() const; virtual bool isEmbedded() const;
virtual bool isForeignWindow() const { return window()->type() == Qt::ForeignWindow; };
virtual QPoint mapToGlobal(const QPoint &pos) const; virtual QPoint mapToGlobal(const QPoint &pos) const;
virtual QPoint mapFromGlobal(const QPoint &pos) const; virtual QPoint mapFromGlobal(const QPoint &pos) const;

View File

@ -2440,7 +2440,7 @@ QPoint QWindow::mapToGlobal(const QPoint &pos) const
Q_D(const QWindow); Q_D(const QWindow);
// QTBUG-43252, prefer platform implementation for foreign windows. // QTBUG-43252, prefer platform implementation for foreign windows.
if (d->platformWindow if (d->platformWindow
&& (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) { && (d->platformWindow->isForeignWindow() || d->platformWindow->isEmbedded())) {
return QHighDpi::fromNativeLocalPosition(d->platformWindow->mapToGlobal(QHighDpi::toNativeLocalPosition(pos, this)), this); return QHighDpi::fromNativeLocalPosition(d->platformWindow->mapToGlobal(QHighDpi::toNativeLocalPosition(pos, this)), this);
} }
return pos + d->globalPosition(); return pos + d->globalPosition();
@ -2460,7 +2460,7 @@ QPoint QWindow::mapFromGlobal(const QPoint &pos) const
Q_D(const QWindow); Q_D(const QWindow);
// QTBUG-43252, prefer platform implementation for foreign windows. // QTBUG-43252, prefer platform implementation for foreign windows.
if (d->platformWindow if (d->platformWindow
&& (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) { && (d->platformWindow->isForeignWindow() || d->platformWindow->isEmbedded())) {
return QHighDpi::fromNativeLocalPosition(d->platformWindow->mapFromGlobal(QHighDpi::toNativeLocalPosition(pos, this)), this); return QHighDpi::fromNativeLocalPosition(d->platformWindow->mapFromGlobal(QHighDpi::toNativeLocalPosition(pos, this)), this);
} }
return pos - d->globalPosition(); return pos - d->globalPosition();
@ -2471,11 +2471,13 @@ QPoint QWindowPrivate::globalPosition() const
Q_Q(const QWindow); Q_Q(const QWindow);
QPoint offset = q->position(); QPoint offset = q->position();
for (const QWindow *p = q->parent(); p; p = p->parent()) { for (const QWindow *p = q->parent(); p; p = p->parent()) {
if (p->type() != Qt::ForeignWindow) { QPlatformWindow *pw = p->handle();
offset += p->position(); if (pw && pw->isForeignWindow()) {
} else { // Use mapToGlobal() for foreign windows // Use mapToGlobal() for foreign windows
offset += p->mapToGlobal(QPoint(0, 0)); offset += p->mapToGlobal(QPoint(0, 0));
break; break;
} else {
offset += p->position();
} }
} }
return offset; return offset;

View File

@ -71,7 +71,7 @@ public:
void requestActivateWindow() override; void requestActivateWindow() override;
void updateStatusBarVisibility(); void updateStatusBarVisibility();
inline bool isRaster() const { inline bool isRaster() const {
if ((window()->flags() & Qt::ForeignWindow) == Qt::ForeignWindow) if (isForeignWindow())
return false; return false;
return window()->surfaceType() == QSurface::RasterSurface return window()->surfaceType() == QSurface::RasterSurface

View File

@ -151,7 +151,8 @@ Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions)
a no-op. a no-op.
For extra verbosity and clearer code, please consider checking For extra verbosity and clearer code, please consider checking
that window()->type() != Qt::ForeignWindow before using this cast. that the platform window is not a foreign window before using
this cast, via QPlatformWindow::isForeignWindow().
Do not use this method soley to check for foreign windows, as Do not use this method soley to check for foreign windows, as
that will make the code harder to read for people not working that will make the code harder to read for people not working

View File

@ -485,7 +485,7 @@ QCocoaWindow::~QCocoaWindow()
// Make sure to disconnect observer in all case if view is valid // Make sure to disconnect observer in all case if view is valid
// to avoid notifications received when deleting when using Qt::AA_NativeWindows attribute // to avoid notifications received when deleting when using Qt::AA_NativeWindows attribute
if (window()->type() != Qt::ForeignWindow) if (!isForeignWindow())
[[NSNotificationCenter defaultCenter] removeObserver:m_view]; [[NSNotificationCenter defaultCenter] removeObserver:m_view];
// While it is unlikely that this window will be in the popup stack // While it is unlikely that this window will be in the popup stack
@ -557,7 +557,7 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
QMacAutoReleasePool pool; QMacAutoReleasePool pool;
if (m_viewIsEmbedded) { if (m_viewIsEmbedded) {
if (window()->type() != Qt::ForeignWindow) { if (!isForeignWindow()) {
[m_view setFrame:NSMakeRect(0, 0, rect.width(), rect.height())]; [m_view setFrame:NSMakeRect(0, 0, rect.width(), rect.height())];
} else { } else {
QPlatformWindow::setGeometry(rect); QPlatformWindow::setGeometry(rect);
@ -581,7 +581,7 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
[m_view setFrame:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())]; [m_view setFrame:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())];
} }
if (window()->type() == Qt::ForeignWindow) if (isForeignWindow())
QPlatformWindow::setGeometry(rect); QPlatformWindow::setGeometry(rect);
// will call QPlatformWindow::setGeometry(rect) during resize confirmation (see qnsview.mm) // will call QPlatformWindow::setGeometry(rect) during resize confirmation (see qnsview.mm)
@ -1288,7 +1288,7 @@ void QCocoaWindow::windowDidEndLiveResize()
void QCocoaWindow::windowDidBecomeKey() void QCocoaWindow::windowDidBecomeKey()
{ {
if (window()->type() == Qt::ForeignWindow) if (isForeignWindow())
return; return;
if (m_windowUnderMouse) { if (m_windowUnderMouse) {
@ -1304,7 +1304,7 @@ void QCocoaWindow::windowDidBecomeKey()
void QCocoaWindow::windowDidResignKey() void QCocoaWindow::windowDidResignKey()
{ {
if (window()->type() == Qt::ForeignWindow) if (isForeignWindow())
return; return;
// Key window will be non-nil if another window became key, so do not // Key window will be non-nil if another window became key, so do not
@ -1885,7 +1885,7 @@ void QCocoaWindow::setWindowCursor(NSCursor *cursor)
return; return;
// Setting a cursor in a foregin view is not supported. // Setting a cursor in a foregin view is not supported.
if (window()->type() == Qt::ForeignWindow) if (isForeignWindow())
return; return;
[m_windowCursor release]; [m_windowCursor release];

View File

@ -66,7 +66,7 @@
- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame - (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame
{ {
Q_UNUSED(newFrame); Q_UNUSED(newFrame);
if (m_cocoaWindow && m_cocoaWindow->window()->type() != Qt::ForeignWindow) if (m_cocoaWindow && !m_cocoaWindow->isForeignWindow())
[qnsview_cast(m_cocoaWindow->view()) notifyWindowWillZoom:![window isZoomed]]; [qnsview_cast(m_cocoaWindow->view()) notifyWindowWillZoom:![window isZoomed]];
return YES; return YES;
} }

View File

@ -414,7 +414,7 @@ static bool isValidWheelReceiver(QWindow *candidate)
{ {
if (candidate) { if (candidate) {
const QWindow *toplevel = QWindowsWindow::topLevelOf(candidate); const QWindow *toplevel = QWindowsWindow::topLevelOf(candidate);
if (toplevel->type() == Qt::ForeignWindow) if (toplevel->handle() && toplevel->handle()->isForeignWindow())
return true; return true;
if (const QWindowsWindow *ww = QWindowsWindow::windowsWindowOf(toplevel)) if (const QWindowsWindow *ww = QWindowsWindow::windowsWindowOf(toplevel))
return !ww->testFlag(QWindowsWindow::BlockedByModal); return !ww->testFlag(QWindowsWindow::BlockedByModal);

View File

@ -1122,7 +1122,7 @@ void QWindowsWindow::updateDropSite(bool topLevel)
// if the parent window is a foreign window wrapped via QWindow::fromWinId, we need to enable the drop site // if the parent window is a foreign window wrapped via QWindow::fromWinId, we need to enable the drop site
// on the first child window // on the first child window
const QWindow *parent = window()->parent(); const QWindow *parent = window()->parent();
if (parent && (parent->type() == Qt::ForeignWindow)) if (parent && parent->handle() && parent->handle()->isForeignWindow())
parentIsEmbedded = true; parentIsEmbedded = true;
} }

View File

@ -385,15 +385,14 @@ QPoint QWindowsGeometryHint::mapFromGlobal(const QWindow *w, const QPoint &p)
inline QWindowsWindow *QWindowsWindow::windowsWindowOf(const QWindow *w) inline QWindowsWindow *QWindowsWindow::windowsWindowOf(const QWindow *w)
{ {
QWindowsWindow *result = Q_NULLPTR; if (!w || !w->handle())
if (w) { return nullptr;
const Qt::WindowType type = w->type();
if (type != Qt::Desktop && type != Qt::ForeignWindow) { const Qt::WindowType type = w->type();
if (QPlatformWindow *pw = w->handle()) if (type == Qt::Desktop || w->handle()->isForeignWindow())
result = static_cast<QWindowsWindow *>(pw); return nullptr;
}
} return static_cast<QWindowsWindow *>(w->handle());
return result;
} }
void *QWindowsWindow::userDataOf(HWND hwnd) void *QWindowsWindow::userDataOf(HWND hwnd)

View File

@ -397,7 +397,7 @@ void QXcbWindow::create()
xcb_window_t xcb_parent_id = platformScreen->root(); xcb_window_t xcb_parent_id = platformScreen->root();
if (parent()) { if (parent()) {
xcb_parent_id = static_cast<QXcbWindow *>(parent())->xcb_window(); xcb_parent_id = static_cast<QXcbWindow *>(parent())->xcb_window();
m_embedded = parent()->window()->type() == Qt::ForeignWindow; m_embedded = parent()->isForeignWindow();
QSurfaceFormat parentFormat = parent()->window()->requestedFormat(); QSurfaceFormat parentFormat = parent()->window()->requestedFormat();
if (window()->surfaceType() != QSurface::OpenGLSurface && parentFormat.hasAlpha()) { if (window()->surfaceType() != QSurface::OpenGLSurface && parentFormat.hasAlpha()) {
@ -1508,7 +1508,7 @@ void QXcbWindow::setParent(const QPlatformWindow *parent)
if (parent) { if (parent) {
const QXcbWindow *qXcbParent = static_cast<const QXcbWindow *>(parent); const QXcbWindow *qXcbParent = static_cast<const QXcbWindow *>(parent);
xcb_parent_id = qXcbParent->xcb_window(); xcb_parent_id = qXcbParent->xcb_window();
m_embedded = qXcbParent->window()->type() == Qt::ForeignWindow; m_embedded = qXcbParent->isForeignWindow();
} else { } else {
xcb_parent_id = xcbScreen()->root(); xcb_parent_id = xcbScreen()->root();
m_embedded = false; m_embedded = false;

View File

@ -2161,11 +2161,14 @@ QWidget *qt_tlw_for_window(QWindow *wnd)
// QTBUG-32177, wnd might be a QQuickView embedded via window container. // QTBUG-32177, wnd might be a QQuickView embedded via window container.
while (wnd && !wnd->isTopLevel()) { while (wnd && !wnd->isTopLevel()) {
QWindow *parent = wnd->parent(); QWindow *parent = wnd->parent();
// Don't end up in windows not belonging to this application if (!parent)
if (parent && parent->type() != Qt::ForeignWindow)
wnd = wnd->parent();
else
break; break;
// Don't end up in windows not belonging to this application
if (parent->handle() && parent->handle()->isForeignWindow())
break;
wnd = wnd->parent();
} }
if (wnd) { if (wnd) {
const auto tlws = qApp->topLevelWidgets(); const auto tlws = qApp->topLevelWidgets();