diff options
author | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2023-02-06 15:59:22 +0100 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2023-03-16 14:17:24 +0100 |
commit | 13951b44cd2cfa190f23c93ff210adf6e5a1d70b (patch) | |
tree | 82a919c4cd000e30267952880374093cd909024e /tests/auto/gui/kernel | |
parent | d243ab7d00e7f4f3461d349eb901cb5ceb0b29ef (diff) |
Add basic test for QWindow foreign windows
Only implemented on macOS and Windows for now.
Change-Id: Ib6330bc7024453d23675c1770367e8da6c4c9a34
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Diffstat (limited to 'tests/auto/gui/kernel')
-rw-r--r-- | tests/auto/gui/kernel/qwindow/CMakeLists.txt | 16 | ||||
-rw-r--r-- | tests/auto/gui/kernel/qwindow/tst_foreignwindow.cpp | 121 |
2 files changed, 137 insertions, 0 deletions
diff --git a/tests/auto/gui/kernel/qwindow/CMakeLists.txt b/tests/auto/gui/kernel/qwindow/CMakeLists.txt index ef054222c7..605761622f 100644 --- a/tests/auto/gui/kernel/qwindow/CMakeLists.txt +++ b/tests/auto/gui/kernel/qwindow/CMakeLists.txt @@ -14,6 +14,22 @@ qt_internal_add_test(tst_qwindow Qt::GuiPrivate ) +if(APPLE OR WIN32) + qt_internal_add_test(tst_foreignwindow + SOURCES + tst_foreignwindow.cpp + LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + ) + + if(APPLE) + target_compile_options(tst_foreignwindow PRIVATE -x objective-c++) + set_property(TARGET tst_foreignwindow PROPERTY PROPERTY MACOSX_BUNDLE TRUE) + endif() +endif() + ## Scopes: ##################################################################### diff --git a/tests/auto/gui/kernel/qwindow/tst_foreignwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_foreignwindow.cpp new file mode 100644 index 0000000000..256564f6bc --- /dev/null +++ b/tests/auto/gui/kernel/qwindow/tst_foreignwindow.cpp @@ -0,0 +1,121 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include <QTest> + +#include <QtCore/qloggingcategory.h> +#include <private/qguiapplication_p.h> +#include <qpa/qplatformintegration.h> + +#if defined(Q_OS_MACOS) +# include <AppKit/AppKit.h> +#elif defined(Q_OS_WIN) +# include <winuser.h> +#endif + +Q_LOGGING_CATEGORY(lcTests, "qt.gui.tests") + +class NativeWindow +{ + Q_DISABLE_COPY(NativeWindow) +public: + NativeWindow(); + ~NativeWindow(); + + operator WId() const { return reinterpret_cast<WId>(m_handle); } + +private: +#if defined(Q_OS_MACOS) + NSView *m_handle = nullptr; +#elif defined(Q_OS_WIN) + HWND m_handle = nullptr; +#endif +}; + +#if defined(Q_OS_MACOS) + +@interface View : NSView +@end + +@implementation View +- (instancetype)init +{ + if ((self = [super init])) { + qCDebug(lcTests) << "Initialized" << self; + } + return self; +} + +- (void)dealloc +{ + qCDebug(lcTests) << "Deallocating" << self; + [super dealloc]; +} +@end + +NativeWindow::NativeWindow() + : m_handle([View new]) +{ +} + +NativeWindow::~NativeWindow() +{ + [m_handle release]; +} + +#elif defined(Q_OS_WIN) + +NativeWindow::NativeWindow() +{ + static const LPCWSTR className = []{ + WNDCLASS wc = {}; + wc.lpfnWndProc = DefWindowProc; + wc.hInstance = GetModuleHandle(nullptr); + wc.lpszClassName = L"Native Window"; + RegisterClass(&wc); + return wc.lpszClassName; + }(); + m_handle = CreateWindowEx(0, className, nullptr, WS_POPUP, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + nullptr, nullptr, GetModuleHandle(nullptr), nullptr); +} + +NativeWindow::~NativeWindow() +{ + DestroyWindow(m_handle); +} + +#endif + +class tst_ForeignWindow: public QObject +{ + Q_OBJECT + +private slots: + void initTestCase() + { + auto *platformIntegration = QGuiApplicationPrivate::platformIntegration(); + if (!platformIntegration->hasCapability(QPlatformIntegration::ForeignWindows)) + QSKIP("This platform does not support foreign windows"); + } + + void fromWinId(); +}; + +void tst_ForeignWindow::fromWinId() +{ + NativeWindow nativeWindow; + QVERIFY(nativeWindow); + + std::unique_ptr<QWindow> foreignWindow(QWindow::fromWinId(nativeWindow)); + QVERIFY(foreignWindow); + QVERIFY(foreignWindow->flags().testFlag(Qt::ForeignWindow)); + QVERIFY(foreignWindow->handle()); + + // fromWinId does not take (exclusive) ownership of the native window, + // so deleting the foreign window should not be a problem/cause crashes. + foreignWindow.reset(); +} + +#include <tst_foreignwindow.moc> +QTEST_MAIN(tst_ForeignWindow) |