| | |
| | | |
| | | namespace QWK { |
| | | |
| | | AbstractWindowContext::AbstractWindowContext(QWindow *window, WindowItemDelegate *delegate) |
| | | : m_windowHandle(window), m_delegate(delegate) { |
| | | AbstractWindowContext::AbstractWindowContext(QObject *host, WindowItemDelegate *delegate) |
| | | : m_host(host), m_delegate(delegate), m_windowHandle(delegate->hostWindow(host)) { |
| | | } |
| | | |
| | | AbstractWindowContext::~AbstractWindowContext() { |
| | | } |
| | | |
| | | void AbstractWindowContext::setupWindow(QWindow *window) { |
| | | Q_ASSERT(window); |
| | | if (!window) { |
| | | return; |
| | | } |
| | | m_windowHandle = window; |
| | | } |
| | | AbstractWindowContext::~AbstractWindowContext() = default; |
| | | |
| | | bool AbstractWindowContext::setHitTestVisible(QObject *obj, bool visible) { |
| | | Q_ASSERT(obj); |
| | |
| | | } |
| | | } |
| | | |
| | | if (hitTestShape().contains(pos)) { |
| | | if (!m_hitTestVisibleRects.isEmpty() && hitTestShape().contains(pos)) { |
| | | return false; |
| | | } |
| | | |
| | |
| | | class QWK_CORE_EXPORT AbstractWindowContext : public QObject { |
| | | Q_OBJECT |
| | | public: |
| | | AbstractWindowContext(QWindow *window, WindowItemDelegate *delegate); |
| | | AbstractWindowContext(QObject *host, WindowItemDelegate *delegate); |
| | | ~AbstractWindowContext() override; |
| | | |
| | | public: |
| | | virtual bool setup() = 0; |
| | | |
| | | inline QObject *host() const; |
| | | inline QWindow *window() const; |
| | | void setupWindow(QWindow *window); |
| | | |
| | | inline bool isHitTestVisible(QObject *obj) const; |
| | | bool setHitTestVisible(QObject *obj, bool visible); |
| | |
| | | bool isInTitleBarDraggableArea(const QPoint &pos) const; |
| | | |
| | | protected: |
| | | QWindow *m_windowHandle; |
| | | QObject *m_host; |
| | | std::unique_ptr<WindowItemDelegate> m_delegate; |
| | | QWindow *m_windowHandle; |
| | | |
| | | QSet<QObject *> m_hitTestVisibleItems; |
| | | QList<QRect> m_hitTestVisibleRects; |
| | |
| | | mutable QRegion hitTestVisibleShape; |
| | | }; |
| | | |
| | | inline QObject *AbstractWindowContext::host() const { |
| | | return m_host; |
| | | } |
| | | |
| | | inline QWindow *AbstractWindowContext::window() const { |
| | | return m_windowHandle; |
| | | } |
| | |
| | | #endif |
| | | } |
| | | |
| | | QtWindowContext::QtWindowContext(QWindow *window, WindowItemDelegate *delegate) |
| | | : AbstractWindowContext(window, delegate) { |
| | | QtWindowContext::QtWindowContext(QObject *host, WindowItemDelegate *delegate) |
| | | : AbstractWindowContext(host, delegate) { |
| | | } |
| | | |
| | | QtWindowContext::~QtWindowContext() { |
| | | } |
| | | |
| | | bool QtWindowContext::setup() { |
| | | if (!m_windowHandle) { |
| | | return false; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | |
| | | class QWK_CORE_EXPORT QtWindowContext : public AbstractWindowContext { |
| | | Q_OBJECT |
| | | public: |
| | | QtWindowContext(QWindow *window, WindowItemDelegate *delegate); |
| | | QtWindowContext(QObject *host, WindowItemDelegate *delegate); |
| | | ~QtWindowContext(); |
| | | |
| | | public: |
| | |
| | | |
| | | QSystemLibrary dwmapi(QStringLiteral("dwmapi.dll")); |
| | | pDwmFlush = reinterpret_cast<decltype(pDwmFlush)>(dwmapi.resolve("DwmFlush")); |
| | | pDwmIsCompositionEnabled = reinterpret_cast<decltype(pDwmIsCompositionEnabled)>(dwmapi.resolve("DwmIsCompositionEnabled")); |
| | | pDwmIsCompositionEnabled = reinterpret_cast<decltype(pDwmIsCompositionEnabled)>( |
| | | dwmapi.resolve("DwmIsCompositionEnabled")); |
| | | } |
| | | |
| | | ~DynamicApis() = default; |
| | |
| | | if (!hwnd) { |
| | | return; |
| | | } |
| | | ::SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_FRAMECHANGED); |
| | | ::SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, |
| | | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER | |
| | | SWP_FRAMECHANGED); |
| | | } |
| | | |
| | | static inline quint32 getDpiForWindow(HWND hwnd) { |
| | |
| | | return ::CallWindowProcW(g_qtWindowProc, hWnd, message, wParam, lParam); |
| | | } |
| | | |
| | | Win32WindowContext::Win32WindowContext(QWindow *window, WindowItemDelegate *delegate) |
| | | : AbstractWindowContext(window, delegate) { |
| | | Win32WindowContext::Win32WindowContext(QObject *host, WindowItemDelegate *delegate) |
| | | : AbstractWindowContext(host, delegate) { |
| | | } |
| | | |
| | | Win32WindowContext::~Win32WindowContext() { |
| | |
| | | } |
| | | |
| | | bool Win32WindowContext::setup() { |
| | | auto winId = m_windowHandle->winId(); |
| | | if (!m_windowHandle) { |
| | | return false; |
| | | } |
| | | |
| | | // Install window hook |
| | | auto winId = m_windowHandle->winId(); |
| | | auto hWnd = reinterpret_cast<HWND>(winId); |
| | | |
| | | // Store original window proc |
| | |
| | | class QWK_CORE_EXPORT Win32WindowContext : public AbstractWindowContext { |
| | | Q_OBJECT |
| | | public: |
| | | Win32WindowContext(QWindow *window, WindowItemDelegate *delegate); |
| | | Win32WindowContext(QObject *host, WindowItemDelegate *delegate); |
| | | ~Win32WindowContext() override; |
| | | |
| | | enum WindowPart { |
| | |
| | | void CoreWindowAgentPrivate::init() { |
| | | } |
| | | |
| | | bool CoreWindowAgentPrivate::setup(QWindow *window, WindowItemDelegate *delegate) { |
| | | Q_ASSERT(window); |
| | | if (!window) { |
| | | return false; |
| | | } |
| | | |
| | | auto handler = |
| | | bool CoreWindowAgentPrivate::setup(QObject *host, WindowItemDelegate *delegate) { |
| | | auto ctx = |
| | | #ifdef Q_OS_WINDOWS |
| | | new Win32WindowContext(window, delegate) |
| | | std::make_unique<Win32WindowContext>(host, delegate) |
| | | #else |
| | | new QtWindowContext(window, delegate) |
| | | std::make_unique<QtWindowContext>(host, window, delegate) |
| | | #endif |
| | | ; |
| | | if (!handler->setup()) { |
| | | delete handler; |
| | | if (!ctx->setup()) { |
| | | return false; |
| | | } |
| | | context.reset(handler); |
| | | context = std::move(ctx); |
| | | return true; |
| | | } |
| | | |
| | |
| | | |
| | | CoreWindowAgent *q_ptr; // no need to initialize |
| | | |
| | | bool setup(QWindow *window, WindowItemDelegate *delegate); |
| | | bool setup(QObject *host, WindowItemDelegate *delegate); |
| | | |
| | | std::unique_ptr<AbstractWindowContext> context; |
| | | |
| | |
| | | virtual ~WindowItemDelegate(); |
| | | |
| | | public: |
| | | // Item property query |
| | | virtual QWindow *window(QObject *obj) const = 0; |
| | | |
| | | // Property query |
| | | virtual bool isEnabled(QObject *obj) const = 0; |
| | | virtual bool isVisible(QObject *obj) const = 0; |
| | | virtual QRect mapGeometryToScene(const QObject *obj) const = 0; |
| | | |
| | | // Host property query |
| | | virtual QWindow *hostWindow(QObject *host) const = 0; |
| | | virtual bool isHostSizeFixed(QObject *host) const = 0; |
| | | |
| | | // Callbacks |
| | | virtual bool resetQtGrabbedControl() const; |
| | | |
| | |
| | | return QRectF(originPoint, size).toRect(); |
| | | } |
| | | |
| | | QWindow *QuickItemDelegate::hostWindow(QObject *host) const { |
| | | return static_cast<QQuickWindow *>(host); |
| | | } |
| | | |
| | | bool QuickItemDelegate::isHostSizeFixed(QObject *host) const { |
| | | return false; |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | public: |
| | | QWindow *window(QObject *obj) const override; |
| | | |
| | | bool isEnabled(QObject *obj) const override; |
| | | bool isVisible(QObject *obj) const override; |
| | | QRect mapGeometryToScene(const QObject *obj) const override; |
| | | |
| | | QWindow * hostWindow(QObject *host) const override; |
| | | bool isHostSizeFixed(QObject *host) const override; |
| | | }; |
| | | |
| | | } |
| | |
| | | return {originPoint, size}; |
| | | } |
| | | |
| | | QWindow *WidgetItemDelegate::hostWindow(QObject *host) const { |
| | | return static_cast<QWidget *>(host)->windowHandle(); |
| | | } |
| | | |
| | | bool WidgetItemDelegate::isHostSizeFixed(QObject *host) const { |
| | | return false; |
| | | } |
| | | |
| | | bool WidgetItemDelegate::resetQtGrabbedControl() const { |
| | | if (qt_button_down) { |
| | | static constexpr const auto invalidPos = QPoint{-99999, -99999}; |
| | |
| | | |
| | | public: |
| | | QWindow *window(QObject *obj) const override; |
| | | |
| | | bool isEnabled(QObject *obj) const override; |
| | | bool isVisible(QObject *obj) const override; |
| | | QRect mapGeometryToScene(const QObject *obj) const override; |
| | | |
| | | QWindow * hostWindow(QObject *host) const override; |
| | | bool isHostSizeFixed(QObject *host) const override; |
| | | |
| | | bool resetQtGrabbedControl() const override; |
| | | }; |
| | | |
| | |
| | | } |
| | | |
| | | std::ignore = w->winId(); // Make sure the window handle is created |
| | | if (!d->setup(w->windowHandle(), new WidgetItemDelegate())) { |
| | | if (!d->setup(w, new WidgetItemDelegate())) { |
| | | return false; |
| | | } |
| | | d->hostWidget = w; |