Sine Striker
2023-12-11 573488a6fec17a9fc71e4d8b0a4741c107ab4ef8
Add virtual hook
8个文件已修改
139 ■■■■ 已修改文件
src/core/contexts/abstractwindowcontext.cpp 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/abstractwindowcontext_p.h 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/win32windowcontext.cpp 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/quick/quickwindowagent.cpp 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/quick/quickwindowagent.h 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/widgets/widgetwindowagent.cpp 54 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/widgets/widgetwindowagent.h 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/widgets/widgetwindowagent_p.h 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/abstractwindowcontext.cpp
@@ -61,7 +61,7 @@
    }
    bool AbstractWindowContext::setSystemButton(WindowAgentBase::SystemButton button,
                                                const QObject *obj) {
                                                QObject *obj) {
        Q_ASSERT(obj);
        Q_ASSERT(button != WindowAgentBase::Unknown);
        if (!obj || (button == WindowAgentBase::Unknown)) {
@@ -75,7 +75,7 @@
        return true;
    }
    bool AbstractWindowContext::setTitleBar(const QObject *item) {
    bool AbstractWindowContext::setTitleBar(QObject *item) {
        Q_ASSERT(item);
        if (!item) {
            return false;
@@ -170,8 +170,11 @@
    void AbstractWindowContext::virtual_hook(int id, void *data) {
        switch (id) {
            case CentralizeHook:
            case NeedsDrawBordersHook: {
                auto &result = *reinterpret_cast<bool *>(data);
                result = false;
                break;
            }
            default:
                break;
        }
src/core/contexts/abstractwindowcontext_p.h
@@ -29,11 +29,11 @@
        bool setHitTestVisible(const QObject *obj, bool visible);
        bool setHitTestVisible(const QRect &rect, bool visible);
        inline const QObject *systemButton(WindowAgentBase::SystemButton button) const;
        bool setSystemButton(WindowAgentBase::SystemButton button, const QObject *obj);
        inline QObject *systemButton(WindowAgentBase::SystemButton button) const;
        bool setSystemButton(WindowAgentBase::SystemButton button, QObject *obj);
        inline const QObject *titleBar() const;
        bool setTitleBar(const QObject *obj);
        inline QObject *titleBar() const;
        bool setTitleBar(QObject *obj);
        void showSystemMenu(const QPoint &pos);
@@ -46,6 +46,8 @@
        enum WindowContextHook {
            CentralizeHook = 1,
            ShowSystemMenuHook,
            NeedsDrawBordersHook,
            DrawBordersHook,
        };
        virtual void virtual_hook(int id, void *data);
@@ -60,8 +62,8 @@
        QSet<const QObject *> m_hitTestVisibleItems;
        QList<QRect> m_hitTestVisibleRects;
        const QObject *m_titleBar{};
        std::array<const QObject *, WindowAgentBase::NumSystemButton> m_systemButtons{};
        QObject *m_titleBar{};
        std::array<QObject *, WindowAgentBase::NumSystemButton> m_systemButtons{};
        // Cached shape
        mutable bool hitTestVisibleShapeDirty{};
@@ -80,12 +82,12 @@
        return m_hitTestVisibleItems.contains(obj);
    }
    inline const QObject *
    inline QObject *
        AbstractWindowContext::systemButton(WindowAgentBase::SystemButton button) const {
        return m_systemButtons[button];
    }
    inline const QObject *AbstractWindowContext::titleBar() const {
    inline QObject *AbstractWindowContext::titleBar() const {
        return m_titleBar;
    }
src/core/contexts/win32windowcontext.cpp
@@ -5,6 +5,7 @@
#include <QtCore/QHash>
#include <QtCore/QScopeGuard>
#include <QtGui/QGuiApplication>
#include <QtGui/QPainter>
#include <QtCore/private/qsystemlibrary_p.h>
#include <QtGui/private/qhighdpiscaling_p.h>
@@ -683,6 +684,24 @@
                                m_delegate->isHostSizeFixed(m_host));
                return;
            }
            case NeedsDrawBordersHook: {
                auto &result = *reinterpret_cast<bool *>(data);
                result = isWin10OrGreater() && !isWin11OrGreater();
                return;
            }
            case DrawBordersHook: {
                auto a = reinterpret_cast<void **>(data);
                auto &painter = *reinterpret_cast<QPainter *>(a[0]);
                auto &rect = *reinterpret_cast<const QRect *>(a[1]);
                auto &region = *reinterpret_cast<const QRegion *>(a[2]);
                qDebug() << "paint" << &painter << rect << region;
                // TODO: Draw border
                // ...
                break;
            }
            default:
                break;
        }
src/quick/quickwindowagent.cpp
@@ -41,12 +41,12 @@
        return true;
    }
    const QQuickItem *QuickWindowAgent::titleBar() const {
    QQuickItem *QuickWindowAgent::titleBar() const {
        Q_D(const QuickWindowAgent);
        return static_cast<const QQuickItem *>(d->context->titleBar());
        return static_cast<QQuickItem *>(d->context->titleBar());
    }
    void QuickWindowAgent::setTitleBar(const QQuickItem *item) {
    void QuickWindowAgent::setTitleBar(QQuickItem *item) {
        Q_D(QuickWindowAgent);
        if (!d->context->setTitleBar(item)) {
            return;
@@ -54,12 +54,12 @@
        Q_EMIT titleBarWidgetChanged(item);
    }
    const QQuickItem *QuickWindowAgent::systemButton(SystemButton button) const {
    QQuickItem *QuickWindowAgent::systemButton(SystemButton button) const {
        Q_D(const QuickWindowAgent);
        return static_cast<const QQuickItem *>(d->context->systemButton(button));
        return static_cast<QQuickItem *>(d->context->systemButton(button));
    }
    void QuickWindowAgent::setSystemButton(SystemButton button, const QQuickItem *item) {
    void QuickWindowAgent::setSystemButton(SystemButton button, QQuickItem *item) {
        Q_D(QuickWindowAgent);
        if (!d->context->setSystemButton(button, item)) {
            return;
@@ -86,4 +86,5 @@
        : WindowAgentBase(d, parent) {
        d.init();
    }
}
src/quick/quickwindowagent.h
@@ -21,16 +21,14 @@
    public:
        Q_INVOKABLE bool setup(QQuickWindow *window);
        Q_INVOKABLE const QQuickItem *titleBar() const;
        Q_INVOKABLE void setTitleBar(const QQuickItem *item);
        Q_INVOKABLE QQuickItem *titleBar() const;
        Q_INVOKABLE void setTitleBar(QQuickItem *item);
        Q_INVOKABLE const QQuickItem *systemButton(SystemButton button) const;
        Q_INVOKABLE void setSystemButton(SystemButton button, const QQuickItem *item);
        Q_INVOKABLE QQuickItem *systemButton(SystemButton button) const;
        Q_INVOKABLE void setSystemButton(SystemButton button, QQuickItem *item);
        Q_INVOKABLE bool isHitTestVisible(const QQuickItem *item) const;
        Q_INVOKABLE inline void setHitTestVisible(const QQuickItem *item, bool visible = true) {
            setHitTestVisible_item(item, visible);
        }
        Q_INVOKABLE inline void setHitTestVisible(const QQuickItem *item, bool visible = true);
        Q_INVOKABLE void setHitTestVisible_item(const QQuickItem *item, bool visible = true);
        Q_INVOKABLE void setHitTestVisible_rect(const QRect &rect, bool visible = true);
@@ -42,6 +40,10 @@
        QuickWindowAgent(QuickWindowAgentPrivate &d, QObject *parent = nullptr);
    };
    inline void QuickWindowAgent::setHitTestVisible(const QQuickItem *item, bool visible) {
        setHitTestVisible_item(item, visible);
    }
}
#endif // QUICKWINDOWAGENT_H
src/widgets/widgetwindowagent.cpp
@@ -1,9 +1,44 @@
#include "widgetwindowagent.h"
#include "widgetwindowagent_p.h"
#include <QtGui/QtEvents>
#include <QtGui/QPainter>
#include "widgetitemdelegate_p.h"
namespace QWK {
    class WidgetPaintFilter : public QObject {
    public:
        WidgetPaintFilter(QWidget *widget, AbstractWindowContext *ctx) : widget(widget), ctx(ctx) {
            widget->installEventFilter(this);
        }
    protected:
        bool eventFilter(QObject *obj, QEvent *event) override {
            switch (event->type()) {
                case QEvent::Paint: {
                    auto e = static_cast<QPaintEvent *>(event);
                    QPainter painter(widget);
                    QRect rect = e->rect();
                    QRegion region = e->region();
                    void *a[3] = {
                        &painter,
                        &rect,
                        &region,
                    };
                    ctx->virtual_hook(AbstractWindowContext::DrawBordersHook, a);
                    return true;
                }
                default:
                    break;
            }
            return false;
        }
        QWidget *widget;
        AbstractWindowContext *ctx;
    };
    WidgetWindowAgentPrivate::WidgetWindowAgentPrivate() {
    }
@@ -39,15 +74,22 @@
            return false;
        }
        d->hostWidget = w;
        // Install painting hook
        if (bool needPaintBorder = false;
            d->context->virtual_hook(AbstractWindowContext::NeedsDrawBordersHook, &needPaintBorder),
            needPaintBorder) {
            d->paintFilter = std::make_unique<WidgetPaintFilter>(w, d->context.get());
        }
        return true;
    }
    const QWidget *WidgetWindowAgent::titleBar() const {
    QWidget *WidgetWindowAgent::titleBar() const {
        Q_D(const WidgetWindowAgent);
        return static_cast<const QWidget *>(d->context->titleBar());
        return static_cast<QWidget *>(d->context->titleBar());
    }
    void WidgetWindowAgent::setTitleBar(const QWidget *w) {
    void WidgetWindowAgent::setTitleBar(QWidget *w) {
        Q_D(WidgetWindowAgent);
        if (!d->context->setTitleBar(w)) {
            return;
@@ -55,12 +97,12 @@
        Q_EMIT titleBarWidgetChanged(w);
    }
    const QWidget *WidgetWindowAgent::systemButton(SystemButton button) const {
    QWidget *WidgetWindowAgent::systemButton(SystemButton button) const {
        Q_D(const WidgetWindowAgent);
        return static_cast<const QWidget *>(d->context->systemButton(button));
        return static_cast<QWidget *>(d->context->systemButton(button));
    }
    void WidgetWindowAgent::setSystemButton(SystemButton button, const QWidget *w) {
    void WidgetWindowAgent::setSystemButton(SystemButton button, QWidget *w) {
        Q_D(WidgetWindowAgent);
        if (!d->context->setSystemButton(button, w)) {
            return;
src/widgets/widgetwindowagent.h
@@ -20,11 +20,11 @@
    public:
        bool setup(QWidget *w);
        const QWidget *titleBar() const;
        void setTitleBar(const QWidget *w);
        QWidget *titleBar() const;
        void setTitleBar(QWidget *w);
        const QWidget *systemButton(SystemButton button) const;
        void setSystemButton(SystemButton button, const QWidget *w);
        QWidget *systemButton(SystemButton button) const;
        void setSystemButton(SystemButton button, QWidget *w);
        bool isHitTestVisible(const QWidget *w) const;
        void setHitTestVisible(const QWidget *w, bool visible = true);
src/widgets/widgetwindowagent_p.h
@@ -16,6 +16,8 @@
        // Host
        QWidget *hostWidget{};
        std::unique_ptr<QObject> paintFilter;
    };
}