From 573488a6fec17a9fc71e4d8b0a4741c107ab4ef8 Mon Sep 17 00:00:00 2001 From: Sine Striker <trueful@163.com> Date: 周一, 11 12月 2023 16:35:29 +0800 Subject: [PATCH] Add virtual hook --- src/quick/quickwindowagent.h | 16 +++-- src/core/contexts/abstractwindowcontext.cpp | 9 ++- src/widgets/widgetwindowagent.cpp | 54 ++++++++++++++++-- src/core/contexts/abstractwindowcontext_p.h | 18 +++-- src/widgets/widgetwindowagent.h | 8 +- src/widgets/widgetwindowagent_p.h | 2 src/core/contexts/win32windowcontext.cpp | 19 ++++++ src/quick/quickwindowagent.cpp | 13 ++-- 8 files changed, 105 insertions(+), 34 deletions(-) diff --git a/src/core/contexts/abstractwindowcontext.cpp b/src/core/contexts/abstractwindowcontext.cpp index d60a6c7..e1187fa 100644 --- a/src/core/contexts/abstractwindowcontext.cpp +++ b/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; } diff --git a/src/core/contexts/abstractwindowcontext_p.h b/src/core/contexts/abstractwindowcontext_p.h index fde76b0..a7b6767 100644 --- a/src/core/contexts/abstractwindowcontext_p.h +++ b/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; } diff --git a/src/core/contexts/win32windowcontext.cpp b/src/core/contexts/win32windowcontext.cpp index c1f3dbd..2168e44 100644 --- a/src/core/contexts/win32windowcontext.cpp +++ b/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 ®ion = *reinterpret_cast<const QRegion *>(a[2]); + + qDebug() << "paint" << &painter << rect << region; + + // TODO: Draw border + // ... + + break; + } default: break; } diff --git a/src/quick/quickwindowagent.cpp b/src/quick/quickwindowagent.cpp index 9cee1b5..77ccc9e 100644 --- a/src/quick/quickwindowagent.cpp +++ b/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(); } + } diff --git a/src/quick/quickwindowagent.h b/src/quick/quickwindowagent.h index e2460d4..0d60a7a 100644 --- a/src/quick/quickwindowagent.h +++ b/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 \ No newline at end of file diff --git a/src/widgets/widgetwindowagent.cpp b/src/widgets/widgetwindowagent.cpp index f7d016e..c85f14e 100644 --- a/src/widgets/widgetwindowagent.cpp +++ b/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, + ®ion, + }; + 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; diff --git a/src/widgets/widgetwindowagent.h b/src/widgets/widgetwindowagent.h index d13d628..bc092d2 100644 --- a/src/widgets/widgetwindowagent.h +++ b/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); diff --git a/src/widgets/widgetwindowagent_p.h b/src/widgets/widgetwindowagent_p.h index d433064..758250e 100644 --- a/src/widgets/widgetwindowagent_p.h +++ b/src/widgets/widgetwindowagent_p.h @@ -16,6 +16,8 @@ // Host QWidget *hostWidget{}; + + std::unique_ptr<QObject> paintFilter; }; } -- Gitblit v1.9.1