src/core/contexts/abstractwindowcontext.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/core/contexts/abstractwindowcontext_p.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/core/contexts/win32windowcontext.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/quick/quickwindowagent.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/quick/quickwindowagent_p.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/widgets/widgetwindowagent.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/core/contexts/abstractwindowcontext.cpp
@@ -181,20 +181,15 @@ void AbstractWindowContext::virtual_hook(int id, void *data) { switch (id) { case ShowSystemMenuHook: { const auto &pos = *reinterpret_cast<const QPoint *>(data); std::ignore = pos; return; } case NeedsDrawBordersHook: { auto &result = *reinterpret_cast<bool *>(data); auto &result = *static_cast<bool *>(data); result = false; return; } case DrawBordersHook: { auto args = reinterpret_cast<void **>(data); auto &painter = *reinterpret_cast<QPainter *>(args[0]); auto &rect = *reinterpret_cast<const QRect *>(args[1]); auto args = static_cast<void **>(data); auto &painter = *static_cast<QPainter *>(args[0]); const auto &rect = *static_cast<const QRect *>(args[1]); // Top painter.setPen(kSampleColorSet.grass); src/core/contexts/abstractwindowcontext_p.h
@@ -48,6 +48,7 @@ ShowSystemMenuHook, NeedsDrawBordersHook, DrawBordersHook, QueryBorderThicknessHook }; virtual void virtual_hook(int id, void *data); src/core/contexts/win32windowcontext.cpp
@@ -781,22 +781,22 @@ return; } case ShowSystemMenuHook: { const auto &pos = *reinterpret_cast<const QPoint *>(data); const auto &pos = *static_cast<const QPoint *>(data); auto hWnd = reinterpret_cast<HWND>(m_windowHandle->winId()); showSystemMenu2(hWnd, qpoint2point(pos), false, m_delegate->isHostSizeFixed(m_host)); return; } case NeedsDrawBordersHook: { auto &result = *reinterpret_cast<bool *>(data); auto &result = *static_cast<bool *>(data); result = isWin10OrGreater() && !isWin11OrGreater(); return; } case DrawBordersHook: { auto args = reinterpret_cast<void **>(data); auto &painter = *reinterpret_cast<QPainter *>(args[0]); auto &rect = *reinterpret_cast<const QRect *>(args[1]); auto ®ion = *reinterpret_cast<const QRegion *>(args[2]); auto args = static_cast<void **>(data); auto &painter = *static_cast<QPainter *>(args[0]); const auto &rect = *static_cast<const QRect *>(args[1]); const auto ®ion = *static_cast<const QRegion *>(args[2]); const auto hwnd = reinterpret_cast<HWND>(m_windowHandle->winId()); QPen pen{}; const auto borderThickness = int(QHighDpi::fromNativePixels(getWindowFrameBorderThickness(hwnd), m_windowHandle)); @@ -827,6 +827,19 @@ painter.restore(); return; } case QueryBorderThicknessHook: { auto args = static_cast<void **>(data); const bool requireNative = *static_cast<const bool *>(args[0]); quint32 &thickness = *static_cast<quint32 *>(args[1]); const auto hwnd = reinterpret_cast<HWND>(m_windowHandle->winId()); const auto nativeThickness = getWindowFrameBorderThickness(hwnd); if (requireNative) { thickness = nativeThickness; } else { thickness = QHighDpi::fromNativePixels(nativeThickness, m_windowHandle); } return; } default: { // unreachable break; src/quick/quickwindowagent.cpp
@@ -3,8 +3,81 @@ #include "quickitemdelegate_p.h" #include <QtQuick/QQuickWindow> #include <QtQuick/QQuickPaintedItem> #include <QtQuick/private/qquickitem_p.h> #include <QtQuick/private/qquickanchors_p.h> namespace QWK { class BorderItem : public QQuickPaintedItem { Q_OBJECT public: explicit BorderItem(AbstractWindowContext *ctx, QQuickItem *parent = nullptr); ~BorderItem() override; void updateHeight(); void paint(QPainter *painter) override; void itemChange(ItemChange change, const ItemChangeData &data) override; private: AbstractWindowContext *context; }; BorderItem::BorderItem(AbstractWindowContext *ctx, QQuickItem *parent) : QQuickPaintedItem(parent), context(ctx) { setAntialiasing(true); // ### FIXME: do we need to enable or disable this? setMipmap(true); // ### FIXME: do we need to enable or disable this? setFillColor({}); // Will improve the performance a little bit. setOpaquePainting(true); // Will also improve the performance, we don't draw semi-transparent borders of course. auto parentPri = QQuickItemPrivate::get(parent); auto anchors = QQuickItemPrivate::get(this)->anchors(); anchors->setTop(parentPri->top()); anchors->setLeft(parentPri->left()); anchors->setRight(parentPri->right()); setZ(std::numeric_limits<qreal>::max()); } BorderItem::~BorderItem() = default; void BorderItem::updateHeight() { bool native = false; quint32 thickness = 0; void *args[] = { &native, &thickness }; context->virtual_hook(AbstractWindowContext::QueryBorderThicknessHook, &args); setHeight(thickness); } void BorderItem::paint(QPainter *painter) { auto rect = QRect{ QPoint{ 0, 0}, size().toSize() }; auto region = QRegion{ rect }; void *args[] = { painter, &rect, ®ion }; context->virtual_hook(AbstractWindowContext::DrawBordersHook, args); } void BorderItem::itemChange(ItemChange change, const ItemChangeData &data) { QQuickPaintedItem::itemChange(change, data); switch (change) { case ItemSceneChange: if (data.window) { connect(data.window, &QQuickWindow::activeChanged, this, [this](){ update(); }); } Q_FALLTHROUGH(); case ItemVisibleHasChanged: case ItemDevicePixelRatioHasChanged: updateHeight(); break; default: break; } } QuickWindowAgentPrivate::QuickWindowAgentPrivate() { } @@ -13,6 +86,7 @@ } void QuickWindowAgentPrivate::init() { borderItem = std::make_unique<BorderItem>(context.get(), hostWindow->contentItem()); } QuickWindowAgent::QuickWindowAgent(QObject *parent) @@ -34,7 +108,7 @@ } if (!d->setup(window, new QuickItemDelegate())) { return true; return false; } d->hostWindow = window; return true; @@ -87,3 +161,5 @@ } } #include "quickwindowagent.moc" src/quick/quickwindowagent_p.h
@@ -6,6 +6,8 @@ namespace QWK { class BorderItem; class QuickWindowAgentPrivate : public WindowAgentBasePrivate { Q_DECLARE_PUBLIC(QuickWindowAgent) public: @@ -16,6 +18,8 @@ // Host QQuickWindow *hostWindow{}; std::unique_ptr<BorderItem> borderItem; }; } src/widgets/widgetwindowagent.cpp
@@ -18,16 +18,16 @@ bool eventFilter(QObject *obj, QEvent *event) override { switch (event->type()) { case QEvent::Paint: { auto e = static_cast<QPaintEvent *>(event); auto pe = static_cast<QPaintEvent *>(event); QPainter painter(widget); QRect rect = e->rect(); QRegion region = e->region(); void *a[] = { QRect rect = pe->rect(); QRegion region = pe->region(); void *args[] = { &painter, &rect, ®ion, }; ctx->virtual_hook(AbstractWindowContext::DrawBordersHook, a); ctx->virtual_hook(AbstractWindowContext::DrawBordersHook, args); return true; } default: