Sine Striker
2023-12-20 8209cdfb1d85a40cc770f854d773c3a10f5ab576
Add hot-switch to agent
10个文件已修改
98 ■■■■ 已修改文件
src/core/contexts/abstractwindowcontext.cpp 37 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/abstractwindowcontext_p.h 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/cocoawindowcontext.mm 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/cocoawindowcontext_p.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/qtwindowcontext.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/qtwindowcontext_p.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/win32windowcontext.cpp 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/win32windowcontext_p.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/windowagentbase.cpp 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/windowagentbase.h 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/abstractwindowcontext.cpp
@@ -18,10 +18,7 @@
        }
        m_host = host;
        m_delegate.reset(delegate);
        m_windowHandle = m_delegate->hostWindow(m_host);
        if (m_windowHandle) {
            winIdChanged(nullptr);
        }
        setEnabled(true);
    }
    void AbstractWindowContext::setWindowAttribute(const QString &key, const QVariant &var) {
@@ -193,11 +190,39 @@
    }
    void AbstractWindowContext::notifyWinIdChange() {
        if (!m_internalEnabled)
            return;
        auto oldWindow = m_windowHandle;
        m_windowHandle = m_delegate->window(m_host);
        if (oldWindow == m_windowHandle)
            return;
        winIdChanged(oldWindow);
        auto isDestroyed = oldWindow && m_windowHandleCache.isNull();
        m_windowHandle = m_delegate->window(m_host);
        m_windowHandleCache = m_windowHandle;
        winIdChanged(oldWindow, isDestroyed);
    }
    void AbstractWindowContext::setEnabled(bool enabled) {
        if (enabled == m_internalEnabled)
            return;
        m_internalEnabled = enabled;
        if (enabled) {
            m_windowHandle = m_delegate->window(m_host);
            m_windowHandleCache = m_windowHandle;
            if (m_windowHandle) {
                winIdChanged(nullptr, false);
            }
            return;
        }
        if (!m_windowHandle)
            return;
        auto oldWindow = m_windowHandle;
        m_windowHandle = nullptr;
        m_windowHandleCache.clear();
        winIdChanged(oldWindow, false);
    }
}
src/core/contexts/abstractwindowcontext_p.h
@@ -73,8 +73,11 @@
        void showSystemMenu(const QPoint &pos);
        void notifyWinIdChange();
        inline bool isEnabled() const;
        void setEnabled(bool enabled);
    protected:
        virtual void winIdChanged(QWindow *oldWindow) = 0;
        virtual void winIdChanged(QWindow *oldWindow, bool isDestroyed) = 0;
    protected:
        QObject *m_host{};
@@ -90,6 +93,10 @@
        std::array<QObject *, WindowAgentBase::NumSystemButton> m_systemButtons{};
        QVariantHash m_windowAttributes;
    private:
        bool m_internalEnabled = false;
        QPointer<QWindow> m_windowHandleCache;
    };
    inline QObject *AbstractWindowContext::host() const {
@@ -127,6 +134,10 @@
    }
#endif
    inline bool AbstractWindowContext::isEnabled() const {
        return m_internalEnabled;
    }
}
#endif // ABSTRACTWINDOWCONTEXT_P_H
src/core/contexts/cocoawindowcontext.mm
@@ -401,7 +401,7 @@
        AbstractWindowContext::virtual_hook(id, data);
    }
    void CocoaWindowContext::winIdChanged(QWindow *oldWindow) {
    void CocoaWindowContext::winIdChanged(QWindow *oldWindow, bool isDestroyed) {
        releaseWindowProxy(windowId);
        if (!m_windowHandle) {
            return;
src/core/contexts/cocoawindowcontext_p.h
@@ -24,7 +24,7 @@
        void virtual_hook(int id, void *data) override;
    protected:
        void winIdChanged(QWindow *oldWindow) override;
        void winIdChanged(QWindow *oldWindow, bool isDestroyed) override;
    protected:
        WId windowId = 0;
src/core/contexts/qtwindowcontext.cpp
@@ -247,7 +247,7 @@
        AbstractWindowContext::virtual_hook(id, data);
    }
    void QtWindowContext::winIdChanged(QWindow *oldWindow) {
    void QtWindowContext::winIdChanged(QWindow *oldWindow, bool isDestroyed) {
        Q_UNUSED(oldWindow)
        m_delegate->setWindowFlags(m_host,
                                   m_delegate->getWindowFlags(m_host) | Qt::FramelessWindowHint);
src/core/contexts/qtwindowcontext_p.h
@@ -24,7 +24,7 @@
        void virtual_hook(int id, void *data) override;
    protected:
        void winIdChanged(QWindow *oldWindow) override;
        void winIdChanged(QWindow *oldWindow, bool isDestroyed) override;
    protected:
        std::unique_ptr<QObject> qtWindowEventFilter;
src/core/contexts/win32windowcontext.cpp
@@ -845,6 +845,7 @@
        g_wndProcHash->insert(hWnd, ctx);
    }
    template <bool Destroyed = true>
    static inline void removeManagedWindow(HWND hWnd) {
        // Remove window handle mapping
        if (!g_wndProcHash->remove(hWnd))
@@ -853,6 +854,11 @@
        // Remove event filter if the all windows has been destroyed
        if (g_wndProcHash->empty()) {
            WindowsNativeEventFilter::uninstall();
        }
        // Restore window proc
        if constexpr (!Destroyed) {
            ::SetWindowLongPtrW(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(g_qtWindowProc));
        }
    }
@@ -964,9 +970,8 @@
                return;
            }
            default: {
            default:
                break;
            }
        }
        AbstractWindowContext::virtual_hook(id, data);
    }
@@ -979,8 +984,12 @@
        return getWindowFrameBorderThickness(reinterpret_cast<HWND>(windowId));
    }
    void Win32WindowContext::winIdChanged(QWindow *oldWindow) {
        removeManagedWindow(reinterpret_cast<HWND>(windowId));
    void Win32WindowContext::winIdChanged(QWindow *oldWindow, bool isDestroyed) {
        if (isDestroyed) {
            removeManagedWindow(reinterpret_cast<HWND>(windowId));
        } else {
            removeManagedWindow<false>(reinterpret_cast<HWND>(windowId));
        }
        if (!m_windowHandle) {
            return;
        }
@@ -1000,7 +1009,7 @@
#endif
        // Inform Qt we want and have set custom margins
        updateInternalWindowFrameMargins(hWnd, m_windowHandle);
        updateInternalWindowFrameMargins(hWnd, m_windowHandle); // TODO: Restore?
        // Add managed window
        addManagedWindow(hWnd, this);
@@ -1296,9 +1305,9 @@
                        // widget to be implicitly grabbed. After the menu is closed, Windows
                        // immediately sends WM_NCHITTEST, because the mouse is in the title bar
                        // draggable area, the result is HTCAPTION, so when the mouse is released,
                        // Windows sends WM_NCLBUTTONUP, which is a non-client area message, and it
                        // Windows sends WM_NCLBUTTONUP, which is a non-client message, and it
                        // will be ignored by Qt. As a consequence, QWidgetWindow can't receive a
                        // mouse release messages in the client area, so the grab remains, and other
                        // mouse release message in the client area, so the grab remains, and other
                        // widgets cannot receive mouse events.
                        // Since we didn't watch the menu window, we cannot capture any mouse
@@ -1609,7 +1618,7 @@
                        *result = (isTitleBar ? HTCAPTION : HTCLIENT);
                        return true;
                    }
                    // At this point, we know that the cursor is inside the client area
                    // At this point, we know that the cursor is inside the client area,
                    // so it has to be either the little border at the top of our custom
                    // title bar or the drag bar. Apparently, it must be the drag bar or
                    // the little border at the top which the user can use to move or
src/core/contexts/win32windowcontext_p.h
@@ -39,7 +39,7 @@
        int borderThickness() const;
    protected:
        void winIdChanged(QWindow *oldWindow) override;
        void winIdChanged(QWindow *oldWindow, bool isDestroyed) override;
    public:
        bool windowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result);
src/core/windowagentbase.cpp
@@ -60,6 +60,16 @@
        d->context->setWindowAttribute(key, var);
    }
    bool WindowAgentBase::isEnabled() const {
        Q_D(const WindowAgentBase);
        return d->context->isEnabled();
    }
    void WindowAgentBase::setEnabled(bool enabled) {
        Q_D(WindowAgentBase);
        d->context->setEnabled(enabled);
    }
    void WindowAgentBase::showSystemMenu(const QPoint &pos) {
        Q_D(WindowAgentBase);
        d->context->showSystemMenu(pos);
src/core/windowagentbase.h
@@ -31,6 +31,9 @@
        QVariant windowAttribute(const QString &key) const;
        void setWindowAttribute(const QString &key, const QVariant &var);
        bool isEnabled() const;
        void setEnabled(bool enabled);
    public Q_SLOTS:
        void showSystemMenu(const QPoint &pos);
        void centralize();