Zhao Yuhang
2023-12-15 dddf96c011723a12b11acc2980c10eb370961021
add qt impl
11个文件已修改
277 ■■■■ 已修改文件
src/core/contexts/abstractwindowcontext_p.h 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/cocoawindowcontext.mm 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/qtwindowcontext.cpp 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/qtwindowcontext_p.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/windowitemdelegate.cpp 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/windowitemdelegate_p.h 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/quick/quickitemdelegate.cpp 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/quick/quickitemdelegate_p.h 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/widgets/widgetitemdelegate.cpp 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/widgets/widgetitemdelegate_p.h 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/widgets/widgetwindowagent_cocoa.cpp 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/abstractwindowcontext_p.h
@@ -25,6 +25,7 @@
        inline QObject *host() const;
        inline QWindow *window() const;
        inline WindowItemDelegate *delegate() const;
        inline bool isHitTestVisible(const QObject *obj) const;
        bool setHitTestVisible(const QObject *obj, bool visible);
@@ -79,6 +80,10 @@
        return m_windowHandle;
    }
    inline WindowItemDelegate *AbstractWindowContext::delegate() const {
        return m_delegate.get();
    }
    inline bool AbstractWindowContext::isHitTestVisible(const QObject *obj) const {
        return m_hitTestVisibleItems.contains(obj);
    }
src/core/contexts/cocoawindowcontext.mm
@@ -238,11 +238,9 @@
        return it.value();
    }
    CocoaWindowContext::CocoaWindowContext() {
    }
    CocoaWindowContext::CocoaWindowContext() : AbstractWindowContext() {}
    CocoaWindowContext::~CocoaWindowContext() {
    }
    CocoaWindowContext::~CocoaWindowContext() = default;
    QString CocoaWindowContext::key() const {
        return QStringLiteral("cocoa");
@@ -255,10 +253,7 @@
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
        m_windowHandle->setProperty("_q_mac_wantsLayer", 1);
#endif
        WId winId = m_windowHandle->winId();
        ensureWindowProxy(winId)->setSystemTitleBarVisible(false);
        // Cache window ID
        windowId = winId;
        ensureWindowProxy(m_windowHandle->winId())->setSystemTitleBarVisible(false);
        return true;
    }
src/core/contexts/qtwindowcontext.cpp
@@ -2,7 +2,7 @@
namespace QWK {
    static constexpr const int kDefaultResizeBorderThickness = 8;
    static constexpr const quint8 kDefaultResizeBorderThickness = 8;
    static Qt::CursorShape calculateCursorShape(const QWindow *window, const QPoint &pos) {
#ifdef Q_OS_MACOS
@@ -40,6 +40,149 @@
#endif
    }
    static inline Qt::Edges calculateWindowEdges(const QWindow *window, const QPoint &pos)
    {
#ifdef Q_OS_MACOS
        Q_UNUSED(window);
        Q_UNUSED(pos);
        return {};
#else
        Q_ASSERT(window);
        if (!window) {
            return {};
        }
        if (window->visibility() != QWindow::Windowed) {
            return {};
        }
        Qt::Edges edges = {};
        const int x = pos.x();
        const int y = pos.y();
        if (x < kDefaultResizeBorderThickness) {
            edges |= Qt::LeftEdge;
        }
        if (x >= (window->width() - kDefaultResizeBorderThickness)) {
            edges |= Qt::RightEdge;
        }
        if (y < kDefaultResizeBorderThickness) {
            edges |= Qt::TopEdge;
        }
        if (y >= (window->height() - kDefaultResizeBorderThickness)) {
            edges |= Qt::BottomEdge;
        }
        return edges;
#endif
    }
    class WindowEventFilter : public QObject {
        Q_OBJECT
    public:
        explicit WindowEventFilter(AbstractWindowContext *context, QObject *parent = nullptr);
        ~WindowEventFilter() override;
    protected:
        bool eventFilter(QObject *object, QEvent *event) override;
    private:
        AbstractWindowContext *m_context;
        bool m_leftButtonPressed;
        bool m_cursorShapeChanged;
    };
    WindowEventFilter::WindowEventFilter(AbstractWindowContext *context, QObject *parent) : QObject(parent), m_context(context), m_leftButtonPressed(false), m_cursorShapeChanged(false) {}
    WindowEventFilter::~WindowEventFilter() = default;
    bool WindowEventFilter::eventFilter(QObject *object, QEvent *event) {
        const auto type = event->type();
        if (type < QEvent::MouseButtonPress || type > QEvent::MouseMove) {
            return false;
        }
        QObject *host = m_context->host();
        QWindow *window = m_context->window();
        WindowItemDelegate *delegate = m_context->delegate();
        const bool fixedSize = delegate->isHostSizeFixed(host);
        const auto mouseEvent = static_cast<const QMouseEvent *>(event);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
        const QPoint scenePos = mouseEvent->scenePosition().toPoint();
        const QPoint globalPos = mouseEvent->globalPosition().toPoint();
#else
        const QPoint scenePos = mouseEvent->windowPos().toPoint();
        const QPoint globalPos = mouseEvent->screenPos().toPoint();
#endif
        const bool inTitleBar = m_context->isInTitleBarDraggableArea(scenePos);
        switch (type) {
            case QEvent::MouseButtonPress: {
                if (mouseEvent->button() == Qt::LeftButton) {
                    m_leftButtonPressed = true;
                    if (!fixedSize) {
                        const Qt::Edges edges = calculateWindowEdges(window, scenePos);
                        if (edges != Qt::Edges{}) {
                            window->startSystemResize(edges);
                            event->accept();
                            return true;
                        }
                    }
                    if (inTitleBar) {
                        event->accept();
                        return true;
                    }
                }
                break;
            }
            case QEvent::MouseButtonRelease: {
                if (mouseEvent->button() == Qt::LeftButton) {
                    m_leftButtonPressed = false;
                    if (inTitleBar) {
                        event->accept();
                        return true;
                    }
                }
                break;
            }
            case QEvent::MouseMove: {
                if (!fixedSize) {
                    const Qt::CursorShape shape = calculateCursorShape(window, scenePos);
                    if (shape == Qt::ArrowCursor) {
                        if (m_cursorShapeChanged) {
                            delegate->restoreCursorShape(host);
                            m_cursorShapeChanged = false;
                        }
                    } else {
                        delegate->setCursorShape(host, shape);
                        m_cursorShapeChanged = true;
                    }
                }
                if (m_leftButtonPressed && inTitleBar) {
                    window->startSystemMove();
                    event->accept();
                    return true;
                }
                break;
            }
            case QEvent::MouseButtonDblClick: {
                if (mouseEvent->button() == Qt::LeftButton && inTitleBar && !fixedSize) {
                    const Qt::WindowStates windowState = delegate->getWindowState(host);
                    if (!(windowState & Qt::WindowFullScreen)) {
                        if (windowState & Qt::WindowMaximized) {
                            delegate->setWindowState(host, windowState & ~Qt::WindowMaximized);
                        } else {
                            delegate->setWindowState(host, windowState | Qt::WindowMaximized);
                        }
                        event->accept();
                        return true;
                    }
                }
                break;
            }
            default: {
                Q_UNREACHABLE();
                return false;
            }
        }
        return false;
    }
    QtWindowContext::QtWindowContext() : AbstractWindowContext() {
    }
@@ -53,7 +196,11 @@
    }
    bool QtWindowContext::setupHost() {
        m_delegate->setWindowFlags(m_host, Qt::FramelessWindowHint);
        m_windowHandle->installEventFilter(new WindowEventFilter(this, m_windowHandle));
        return true;
    }
}
}
#include "qtwindowcontext.moc"
src/core/contexts/qtwindowcontext_p.h
@@ -9,7 +9,7 @@
        Q_OBJECT
    public:
        QtWindowContext();
        ~QtWindowContext();
        ~QtWindowContext() override;
        QString key() const override;
        void virtual_hook(int id, void *data) override;
src/core/windowitemdelegate.cpp
@@ -6,6 +6,8 @@
    WindowItemDelegate::~WindowItemDelegate() = default;
    void WindowItemDelegate::resetQtGrabbedControl() const {}
    void WindowItemDelegate::resetQtGrabbedControl(QObject *host) const {
        Q_UNUSED(host);
    }
}
src/core/windowitemdelegate_p.h
@@ -16,18 +16,24 @@
    public:
        // Item property query
        virtual QWindow *window(QObject *obj) const = 0;
        virtual QWindow *window(const QObject *obj) const = 0;
        virtual bool isEnabled(const QObject *obj) const = 0;
        virtual bool isVisible(const QObject *obj) const = 0;
        virtual QRect mapGeometryToScene(const QObject *obj) const = 0;
        // Host property query
        virtual QWindow *hostWindow(QObject *host) const = 0;
        virtual QWindow *hostWindow(const QObject *host) const = 0;
        virtual bool isHostSizeFixed(const QObject *host) const = 0;
        virtual bool isWindowActive(const QObject *host) const = 0;
        virtual Qt::WindowStates getWindowState(const QObject *host) const = 0;
        virtual Qt::WindowFlags getWindowFlags(const QObject *host) const = 0;
        // Callbacks
        virtual void resetQtGrabbedControl() const;
        virtual void resetQtGrabbedControl(QObject *host) const;
        virtual void setWindowState(QObject *host, const Qt::WindowStates &state) const = 0;
        virtual void setCursorShape(QObject *host, const Qt::CursorShape shape) const = 0;
        virtual void restoreCursorShape(QObject *host) const = 0;
        virtual void setWindowFlags(QObject *host, const Qt::WindowFlags &flags) const = 0;
    private:
        Q_DISABLE_COPY(WindowItemDelegate)
src/quick/quickitemdelegate.cpp
@@ -10,7 +10,7 @@
    QuickItemDelegate::~QuickItemDelegate() = default;
    QWindow *QuickItemDelegate::window(QObject *obj) const {
    QWindow *QuickItemDelegate::window(const QObject *obj) const {
        return static_cast<const QQuickItem *>(obj)->window();
    }
@@ -29,8 +29,8 @@
        return QRectF(originPoint, size).toRect();
    }
    QWindow *QuickItemDelegate::hostWindow(QObject *host) const {
        return static_cast<QQuickWindow *>(host);
    QWindow *QuickItemDelegate::hostWindow(const QObject *host) const {
        return static_cast<QQuickWindow *>(const_cast<QObject *>(host));
    }
    bool QuickItemDelegate::isHostSizeFixed(const QObject *host) const {
@@ -42,4 +42,28 @@
        return static_cast<const QQuickWindow *>(host)->isActive();
    }
    Qt::WindowStates QuickItemDelegate::getWindowState(const QObject *host) const {
        return static_cast<const QQuickWindow *>(host)->windowStates();
    }
    void QuickItemDelegate::setWindowState(QObject *host, const Qt::WindowStates &state) const {
        static_cast<QQuickWindow *>(host)->setWindowStates(state);
    }
    void QuickItemDelegate::setCursorShape(QObject *host, const Qt::CursorShape shape) const {
        static_cast<QQuickWindow *>(host)->setCursor(QCursor(shape));
    }
    void QuickItemDelegate::restoreCursorShape(QObject *host) const {
        static_cast<QQuickWindow *>(host)->unsetCursor();
    }
    Qt::WindowFlags QuickItemDelegate::getWindowFlags(const QObject *host) const {
        return static_cast<const QQuickWindow *>(host)->flags();
    }
    void QuickItemDelegate::setWindowFlags(QObject *host, const Qt::WindowFlags &flags) const {
        static_cast<QQuickWindow *>(host)->setFlags(flags);
    }
}
src/quick/quickitemdelegate_p.h
@@ -15,14 +15,21 @@
        ~QuickItemDelegate() override;
    public:
        QWindow *window(QObject *obj) const override;
        QWindow *window(const QObject *obj) const override;
        bool isEnabled(const QObject *obj) const override;
        bool isVisible(const QObject *obj) const override;
        QRect mapGeometryToScene(const QObject *obj) const override;
        QWindow *hostWindow(QObject *host) const override;
        QWindow *hostWindow(const QObject *host) const override;
        bool isHostSizeFixed(const QObject *host) const override;
        bool isWindowActive(const QObject *host) const override;
        Qt::WindowStates getWindowState(const QObject *host) const override;
        Qt::WindowFlags getWindowFlags(const QObject *host) const override;
        void setWindowState(QObject *host, const Qt::WindowStates &state) const override;
        void setCursorShape(QObject *host, const Qt::CursorShape shape) const override;
        void restoreCursorShape(QObject *host) const override;
        void setWindowFlags(QObject *host, const Qt::WindowFlags &flags) const override;
    };
}
src/widgets/widgetitemdelegate.cpp
@@ -12,7 +12,7 @@
    WidgetItemDelegate::~WidgetItemDelegate() = default;
    QWindow *WidgetItemDelegate::window(QObject *obj) const {
    QWindow *WidgetItemDelegate::window(const QObject *obj) const {
        return static_cast<const QWidget *>(obj)->windowHandle();
    }
@@ -31,7 +31,7 @@
        return {originPoint, size};
    }
    QWindow *WidgetItemDelegate::hostWindow(QObject *host) const {
    QWindow *WidgetItemDelegate::hostWindow(const QObject *host) const {
        return static_cast<const QWidget *>(host)->windowHandle();
    }
@@ -60,7 +60,8 @@
        return static_cast<const QWidget *>(host)->isActiveWindow();
    }
    void WidgetItemDelegate::resetQtGrabbedControl() const {
    void WidgetItemDelegate::resetQtGrabbedControl(QObject *host) const {
        Q_UNUSED(host);
        if (!qt_button_down) {
            return;
        }
@@ -69,8 +70,32 @@
        const auto event = new QMouseEvent(
            QEvent::MouseButtonRelease, invalidPos, invalidPos, invalidPos, Qt::LeftButton,
            QGuiApplication::mouseButtons() ^ Qt::LeftButton, QGuiApplication::keyboardModifiers());
        QApplication::postEvent(qt_button_down, event);
        QCoreApplication::postEvent(qt_button_down, event);
        qt_button_down = nullptr;
    }
    Qt::WindowStates WidgetItemDelegate::getWindowState(const QObject *host) const {
        return static_cast<const QWidget *>(host)->windowState();
    }
    void WidgetItemDelegate::setWindowState(QObject *host, const Qt::WindowStates &state) const {
        static_cast<QWidget *>(host)->setWindowState(state);
    }
    void WidgetItemDelegate::setCursorShape(QObject *host, const Qt::CursorShape shape) const {
        static_cast<QWidget *>(host)->setCursor(QCursor(shape));
    }
    void WidgetItemDelegate::restoreCursorShape(QObject *host) const {
        static_cast<QWidget *>(host)->unsetCursor();
    }
    Qt::WindowFlags WidgetItemDelegate::getWindowFlags(const QObject *host) const {
        return static_cast<const QWidget *>(host)->windowFlags();
    }
    void WidgetItemDelegate::setWindowFlags(QObject *host, const Qt::WindowFlags &flags) const {
        static_cast<QWidget *>(host)->setWindowFlags(flags);
    }
}
src/widgets/widgetitemdelegate_p.h
@@ -15,16 +15,22 @@
        ~WidgetItemDelegate() override;
    public:
        QWindow *window(QObject *obj) const override;
        QWindow *window(const QObject *obj) const override;
        bool isEnabled(const QObject *obj) const override;
        bool isVisible(const QObject *obj) const override;
        QRect mapGeometryToScene(const QObject *obj) const override;
        QWindow *hostWindow(QObject *host) const override;
        QWindow *hostWindow(const QObject *host) const override;
        bool isHostSizeFixed(const QObject *host) const override;
        bool isWindowActive(const QObject *host) const override;
        Qt::WindowStates getWindowState(const QObject *host) const override;
        Qt::WindowFlags getWindowFlags(const QObject *host) const override;
        void resetQtGrabbedControl() const override;
        void resetQtGrabbedControl(QObject *host) const override;
        void setWindowState(QObject *host, const Qt::WindowStates &state) const override;
        void setCursorShape(QObject *host, const Qt::CursorShape shape) const override;
        void restoreCursorShape(QObject *host) const override;
        void setWindowFlags(QObject *host, const Qt::WindowFlags &flags) const override;
    };
}
src/widgets/widgetwindowagent_cocoa.cpp
@@ -77,8 +77,10 @@
                }
                break;
            }
            default:
                break;
            default: {
                Q_UNREACHABLE();
                return false;
            }
        }
        return false;
    }