QWindow::fromWinId(): Return 0 when foreign window cannot be wrapped

Change window creation code in QWindow to not assert should
platform window creation fail for foreign windows.
Prototypically add check to the Windows QPA plugin.

[ChangeLog][Windows][Important Behavioral Changes] QWindow::fromWinId()
may return 0 when passing invalid window handles.

Task-number: QTBUG-41186
Change-Id: I936112607ec6e0838d36ac2a72aa88b869df5c23
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
bb10
Friedemann Kleint 2016-06-30 12:50:10 +02:00
parent 80c23042e4
commit f2ef587906
2 changed files with 13 additions and 3 deletions

View File

@ -402,7 +402,7 @@ void QWindowPrivate::create(bool recursive)
q->parent()->create();
platformWindow = QGuiApplicationPrivate::platformIntegration()->createPlatformWindow(q);
Q_ASSERT(platformWindow);
Q_ASSERT(platformWindow || q->type() == Qt::ForeignWindow);
if (!platformWindow) {
qWarning() << "Failed to create platform window for" << q << "with flags" << q->flags();
@ -2432,7 +2432,8 @@ QWindow *QWindowPrivate::topLevelWindow() const
This can be used, on platforms which support it, to embed a QWindow inside a
native window, or to embed a native window inside a QWindow.
If foreign windows are not supported, this function returns 0.
If foreign windows are not supported or embedding the native window
failed in the platform plugin, this function returns 0.
\note The resulting QWindow should not be used to manipulate the underlying
native window (besides re-parenting), or to observe state changes of the
@ -2453,6 +2454,10 @@ QWindow *QWindow::fromWinId(WId id)
window->setFlags(Qt::ForeignWindow);
window->setProperty("_q_foreignWinId", QVariant::fromValue(id));
window->create();
if (!window->handle()) {
delete window;
return nullptr;
}
return window;
}

View File

@ -311,7 +311,12 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons
}
if (window->type() == Qt::ForeignWindow) {
QWindowsForeignWindow *result = new QWindowsForeignWindow(window, reinterpret_cast<HWND>(window->winId()));
const HWND hwnd = reinterpret_cast<HWND>(window->winId());
if (!IsWindow(hwnd)) {
qWarning("Windows QPA: Invalid foreign window ID %p.");
return nullptr;
}
QWindowsForeignWindow *result = new QWindowsForeignWindow(window, hwnd);
const QRect obtainedGeometry = result->geometry();
QScreen *screen = Q_NULLPTR;
if (const QPlatformScreen *pScreen = result->screenForGeometry(obtainedGeometry))