src/core/contexts/abstractwindowcontext_p.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/core/contexts/cocoawindowcontext.mm | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/core/contexts/qtwindowcontext.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/core/contexts/qtwindowcontext_p.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/core/windowitemdelegate.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/core/windowitemdelegate_p.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/quick/quickitemdelegate.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/quick/quickitemdelegate_p.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/widgets/widgetitemdelegate.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/widgets/widgetitemdelegate_p.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/widgets/widgetwindowagent_cocoa.cpp | ●●●●● 补丁 | 查看 | 原始文档 | 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; }