summaryrefslogtreecommitdiffstats
path: root/tests/auto/gui/kernel
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2023-02-06 15:59:22 +0100
committerTor Arne Vestbø <tor.arne.vestbo@qt.io>2023-03-16 14:17:24 +0100
commit13951b44cd2cfa190f23c93ff210adf6e5a1d70b (patch)
tree82a919c4cd000e30267952880374093cd909024e /tests/auto/gui/kernel
parentd243ab7d00e7f4f3461d349eb901cb5ceb0b29ef (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.txt16
-rw-r--r--tests/auto/gui/kernel/qwindow/tst_foreignwindow.cpp121
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)