Add QtContext WinIdChange workaround
| | |
| | | + Fix `isFixedSize` code |
| | | + Support customized system button area on Mac |
| | | + Make Linux system move/resize more robust |
| | | + Fix unhandled WinIdChange when adding a QWebEngineView as sub-widget |
| | | + Fix unhandled WinIdChange when adding a QWebEngineView as sub-widget (Win32 and Qt fixed) |
| | | |
| | | ## Supported Platforms |
| | | |
| | |
| | | int main(int argc, char *argv[]) { |
| | | qputenv("QT_WIN_DEBUG_CONSOLE", "1"); |
| | | qputenv("QSG_INFO", "1"); |
| | | qputenv("QT_WIDGETS_HIGHDPI_DOWNSCALE", "1"); |
| | | #if 0 |
| | | qputenv("QT_WIDGETS_RHI", "1"); |
| | | qputenv("QSG_RHI_BACKEND", "d3d12"); |
| | |
| | | m_delegate.reset(delegate); |
| | | m_windowHandle = m_delegate->hostWindow(m_host); |
| | | if (m_windowHandle) { |
| | | m_windowHandleGuard = m_windowHandle; |
| | | winIdChanged(nullptr, false); |
| | | winIdChanged(nullptr); |
| | | } |
| | | } |
| | | |
| | |
| | | void AbstractWindowContext::notifyWinIdChange() { |
| | | auto oldWindow = m_windowHandle; |
| | | m_windowHandle = m_delegate->window(m_host); |
| | | winIdChanged(oldWindow, oldWindow && m_windowHandleGuard.isNull()); |
| | | if (oldWindow == m_windowHandle) |
| | | return; |
| | | winIdChanged(oldWindow); |
| | | } |
| | | |
| | | } |
| | |
| | | void notifyWinIdChange(); |
| | | |
| | | protected: |
| | | virtual void winIdChanged(QWindow *oldWindow, bool destroyed) = 0; |
| | | virtual void winIdChanged(QWindow *oldWindow) = 0; |
| | | |
| | | protected: |
| | | QObject *m_host{}; |
| | | std::unique_ptr<WindowItemDelegate> m_delegate; |
| | | QWindow *m_windowHandle{}; |
| | | QPointer<QWindow> m_windowHandleGuard; |
| | | |
| | | QSet<const QObject *> m_hitTestVisibleItems; |
| | | #ifdef Q_OS_MAC |
| | |
| | | AbstractWindowContext::virtual_hook(id, data); |
| | | } |
| | | |
| | | bool CocoaWindowContext::winIdChanged(QWindow *oldWindow) { |
| | | void CocoaWindowContext::winIdChanged(QWindow *oldWindow, bool destroyed) { |
| | | windowId = m_windowHandle->winId(); |
| | | ensureWindowProxy(windowId)->setSystemTitleBarVisible(false); |
| | | std::ignore = new CocoaWindowEventFilter(this, this); |
| | | cocoaWindowEventFilter = std::make_unique<CocoaWindowEventFilter>(this, this); |
| | | return true; |
| | | } |
| | | |
| | |
| | | |
| | | protected: |
| | | WId windowId = 0; |
| | | |
| | | std::unique_ptr<QObject> cocoaWindowEventFilter; |
| | | }; |
| | | |
| | | } |
| | |
| | | AbstractWindowContext::virtual_hook(id, data); |
| | | } |
| | | |
| | | bool QtWindowContext::winIdChanged() { |
| | | m_delegate->setWindowFlags(m_host, Qt::FramelessWindowHint); |
| | | std::ignore = new QtWindowEventFilter(this, this); |
| | | return true; |
| | | void QtWindowContext::winIdChanged(QWindow *oldWindow) { |
| | | Q_UNUSED(oldWindow) |
| | | m_delegate->setWindowFlags(m_host, |
| | | m_delegate->getWindowFlags(m_host) | Qt::FramelessWindowHint); |
| | | qtWindowEventFilter = std::make_unique<QtWindowEventFilter>(this); |
| | | } |
| | | |
| | | } |
| | |
| | | void virtual_hook(int id, void *data) override; |
| | | |
| | | protected: |
| | | bool winIdChanged() override; |
| | | void winIdChanged(QWindow *oldWindow) override; |
| | | |
| | | protected: |
| | | std::unique_ptr<QObject> qtWindowEventFilter; |
| | | }; |
| | | |
| | | } |
| | |
| | | g_wndProcHash->insert(hWnd, ctx); |
| | | } |
| | | |
| | | static inline void removeManagedWindow(HWND hWnd, bool restore) { |
| | | static inline void removeManagedWindow(HWND hWnd) { |
| | | // Remove window handle mapping |
| | | if (!g_wndProcHash->remove(hWnd)) |
| | | return; |
| | |
| | | if (g_wndProcHash->empty()) { |
| | | WindowsNativeEventFilter::uninstall(); |
| | | } |
| | | |
| | | // Restore window proc |
| | | if (restore) { |
| | | ::SetWindowLongPtrW(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(g_qtWindowProc)); |
| | | } |
| | | } |
| | | |
| | | Win32WindowContext::Win32WindowContext() : AbstractWindowContext() { |
| | |
| | | |
| | | Win32WindowContext::~Win32WindowContext() { |
| | | if (windowId) { |
| | | removeManagedWindow(reinterpret_cast<HWND>(windowId), false); |
| | | removeManagedWindow(reinterpret_cast<HWND>(windowId)); |
| | | } |
| | | } |
| | | |
| | |
| | | return getWindowFrameBorderThickness(reinterpret_cast<HWND>(windowId)); |
| | | } |
| | | |
| | | void Win32WindowContext::winIdChanged(QWindow *oldWindow, bool destroyed) { |
| | | void Win32WindowContext::winIdChanged(QWindow *oldWindow) { |
| | | if (oldWindow) { |
| | | removeManagedWindow(reinterpret_cast<HWND>(windowId), !destroyed); |
| | | removeManagedWindow(reinterpret_cast<HWND>(windowId)); |
| | | } |
| | | |
| | | if (!m_windowHandle) { |
| | |
| | | int borderThickness() const; |
| | | |
| | | protected: |
| | | void winIdChanged(QWindow *oldWindow, bool destroyed) override; |
| | | void winIdChanged(QWindow *oldWindow) override; |
| | | |
| | | public: |
| | | bool windowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result); |