Sine Striker
2023-12-11 c3c6647e7888b7dbe9d9d22fb77bf08104a3653c
refactor
19个文件已修改
8个文件已添加
2 文件已重命名
8个文件已删除
942 ■■■■ 已修改文件
examples/mainwindow/mainwindow.cpp 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/CMakeLists.txt 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/abstractwindowcontext.cpp 51 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/abstractwindowcontext_p.h 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/qtwindowcontext.cpp 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/qtwindowcontext_p.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/win32windowcontext.cpp 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/win32windowcontext_p.h 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/corewindowagent.cpp 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/corewindowagent_p.h 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/kernel/nativeeventfilter.cpp 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/kernel/nativeeventfilter.h 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/kernel/sharedeventfilter.cpp 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/kernel/sharedeventfilter.h 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/qwkcoreglobal.cpp 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/qwkcoreglobal_p.h 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/qwkglobal.h 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/qwkglobal_p.h 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/windowagentbase.cpp 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/windowagentbase.h 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/windowagentbase_p.h 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/windowitemdelegate.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/windowitemdelegate_p.h 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/quick/CMakeLists.txt 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/quick/contexts/quickwindowcontext.cpp 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/quick/contexts/quickwindowcontext_p.h 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/quick/quickitemdelegate_p.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/quick/quickwindowagent.cpp 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/quick/quickwindowagent.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/quick/quickwindowagent_p.h 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/widgets/CMakeLists.txt 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/widgets/contexts/widgetwindowcontext.cpp 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/widgets/contexts/widgetwindowcontext_p.h 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/widgets/widgetitemdelegate_p.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/widgets/widgetwindowagent.cpp 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/widgets/widgetwindowagent.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/widgets/widgetwindowagent_p.h 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
examples/mainwindow/mainwindow.cpp
@@ -77,10 +77,10 @@
    windowBar->setHostWidget(this);
    agent->setTitleBar(windowBar);
    agent->setSystemButton(QWK::CoreWindowAgent::WindowIcon, iconButton);
    agent->setSystemButton(QWK::CoreWindowAgent::Minimize, minButton);
    agent->setSystemButton(QWK::CoreWindowAgent::Maximize, maxButton);
    agent->setSystemButton(QWK::CoreWindowAgent::Close, closeButton);
    agent->setSystemButton(QWK::WindowAgentBase::WindowIcon, iconButton);
    agent->setSystemButton(QWK::WindowAgentBase::Minimize, minButton);
    agent->setSystemButton(QWK::WindowAgentBase::Maximize, maxButton);
    agent->setSystemButton(QWK::WindowAgentBase::Close, closeButton);
    agent->setHitTestVisible(menuBar, true);
    connect(windowBar, &QWK::WindowBar::minimizeRequested, this, &QWidget::showMinimized);
src/core/CMakeLists.txt
@@ -5,13 +5,17 @@
set(_src
    qwkcoreglobal.h
    qwkcoreglobal_p.h
    qwkcoreglobal.cpp
    corewindowagent.h
    corewindowagent_p.h
    corewindowagent.cpp
    windowitemdelegate.h
    qwkglobal.h
    qwkglobal_p.h
    windowagentbase.h
    windowagentbase_p.h
    windowagentbase.cpp
    windowitemdelegate_p.h
    windowitemdelegate.cpp
    kernel/nativeeventfilter.h
    kernel/nativeeventfilter.cpp
    kernel/sharedeventfilter.h
    kernel/sharedeventfilter.cpp
    contexts/abstractwindowcontext_p.h
    contexts/abstractwindowcontext.cpp
)
@@ -43,7 +47,7 @@
    LINKS
    QT_LINKS Core Gui
    QT_INCLUDE_PRIVATE Core Gui
    INCLUDE_PRIVATE contexts
    INCLUDE_PRIVATE kernel contexts
    PREFIX QWK_CORE
)
src/core/contexts/abstractwindowcontext.cpp
@@ -8,24 +8,6 @@
    AbstractWindowContext::~AbstractWindowContext() = default;
    class EventFilterForwarder : public QObject {
    public:
        using EventProc = bool (*)(QEvent *, void *);
        EventFilterForwarder(EventProc proc, void *user, QObject *parent = nullptr)
            : QObject(parent), proc(proc), user(user) {
        }
        bool eventFilter(QObject *obj, QEvent *event) override {
            Q_UNUSED(obj)
            return proc(event, user);
        }
    protected:
        EventProc proc;
        void *user;
    };
    bool AbstractWindowContext::setup(QObject *host, WindowItemDelegate *delegate) {
        if (!host || !delegate) {
            return false;
@@ -46,14 +28,6 @@
            m_windowHandle = nullptr;
            return false;
        }
        // Install specific event filter
        host->installEventFilter(new EventFilterForwarder(
            [](QEvent *event, void *user) {
                return static_cast<AbstractWindowContext *>(user)->hostEventFilter(event);
            },
            this, this));
        return true;
    }
@@ -86,11 +60,11 @@
        return true;
    }
    bool AbstractWindowContext::setSystemButton(CoreWindowAgent::SystemButton button,
    bool AbstractWindowContext::setSystemButton(WindowAgentBase::SystemButton button,
                                                const QObject *obj) {
        Q_ASSERT(obj);
        Q_ASSERT(button != CoreWindowAgent::Unknown);
        if (!obj || (button == CoreWindowAgent::Unknown)) {
        Q_ASSERT(button != WindowAgentBase::Unknown);
        if (!obj || (button == WindowAgentBase::Unknown)) {
            return false;
        }
@@ -114,9 +88,7 @@
        return true;
    }
    void AbstractWindowContext::showSystemMenu(const QPoint &pos) {
        // ?
    }
    void AbstractWindowContext::showSystemMenu(const QPoint &pos){Q_UNUSED(pos)}
    QRegion AbstractWindowContext::hitTestShape() const {
        if (hitTestVisibleShapeDirty) {
@@ -130,16 +102,16 @@
    }
    bool AbstractWindowContext::isInSystemButtons(const QPoint &pos,
                                                  CoreWindowAgent::SystemButton *button) const {
        *button = CoreWindowAgent::Unknown;
        for (int i = CoreWindowAgent::WindowIcon; i <= CoreWindowAgent::Close; ++i) {
                                                  WindowAgentBase::SystemButton *button) const {
        *button = WindowAgentBase::Unknown;
        for (int i = WindowAgentBase::WindowIcon; i <= WindowAgentBase::Close; ++i) {
            auto currentButton = m_systemButtons[i];
            if (!currentButton || !m_delegate->isVisible(currentButton) ||
                !m_delegate->isEnabled(currentButton)) {
                continue;
            }
            if (m_delegate->mapGeometryToScene(currentButton).contains(pos)) {
                *button = static_cast<CoreWindowAgent::SystemButton>(i);
                *button = static_cast<WindowAgentBase::SystemButton>(i);
                return true;
            }
        }
@@ -168,7 +140,7 @@
            return false;
        }
        for (int i = CoreWindowAgent::WindowIcon; i <= CoreWindowAgent::Close; ++i) {
        for (int i = WindowAgentBase::WindowIcon; i <= WindowAgentBase::Close; ++i) {
            auto currentButton = m_systemButtons[i];
            if (currentButton && m_delegate->isVisible(currentButton) &&
                m_delegate->isEnabled(currentButton) &&
@@ -190,9 +162,8 @@
        return true;
    }
    bool AbstractWindowContext::hostEventFilter(QEvent *event) {
        Q_UNUSED(event)
        return false;
    QObject *AbstractWindowContext::target() const {
        return m_host;
    }
}
src/core/contexts/abstractwindowcontext_p.h
@@ -8,12 +8,13 @@
#include <QtGui/QWindow>
#include <QtGui/QPolygon>
#include <QWKCore/corewindowagent.h>
#include <QWKCore/windowitemdelegate.h>
#include <QWKCore/windowagentbase.h>
#include <QWKCore/sharedeventfilter.h>
#include <QWKCore/private/windowitemdelegate_p.h>
namespace QWK {
    class QWK_CORE_EXPORT AbstractWindowContext : public QObject {
    class QWK_CORE_EXPORT AbstractWindowContext : public QObject, public SharedEventDispatcher {
        Q_OBJECT
    public:
        AbstractWindowContext();
@@ -29,21 +30,22 @@
        bool setHitTestVisible(const QObject *obj, bool visible);
        bool setHitTestVisible(const QRect &rect, bool visible);
        inline const QObject *systemButton(CoreWindowAgent::SystemButton button) const;
        bool setSystemButton(CoreWindowAgent::SystemButton button, const QObject *obj);
        inline const QObject *systemButton(WindowAgentBase::SystemButton button) const;
        bool setSystemButton(WindowAgentBase::SystemButton button, const QObject *obj);
        inline const QObject *titleBar() const;
        bool setTitleBar(const QObject *obj);
        void showSystemMenu(const QPoint &pos);
        virtual void showSystemMenu(const QPoint &pos);
        QRegion hitTestShape() const;
        bool isInSystemButtons(const QPoint &pos, CoreWindowAgent::SystemButton *button) const;
        bool isInSystemButtons(const QPoint &pos, WindowAgentBase::SystemButton *button) const;
        bool isInTitleBarDraggableArea(const QPoint &pos) const;
    protected:
        virtual bool setupHost() = 0;
        virtual bool hostEventFilter(QEvent *event);
        QObject *target() const override;
    protected:
        QObject *m_host;
@@ -54,7 +56,7 @@
        QList<QRect> m_hitTestVisibleRects;
        const QObject *m_titleBar{};
        std::array<const QObject *, CoreWindowAgent::NumSystemButton> m_systemButtons{};
        std::array<const QObject *, WindowAgentBase::NumSystemButton> m_systemButtons{};
        // Cached shape
        mutable bool hitTestVisibleShapeDirty{};
@@ -74,7 +76,7 @@
    }
    inline const QObject *
        AbstractWindowContext::systemButton(CoreWindowAgent::SystemButton button) const {
        AbstractWindowContext::systemButton(WindowAgentBase::SystemButton button) const {
        return m_systemButtons[button];
    }
src/core/contexts/qtwindowcontext.cpp
@@ -50,8 +50,4 @@
        return false;
    }
    bool QtWindowContext::hostEventFilter(QEvent *event) {
        return false;
    }
}
src/core/contexts/qtwindowcontext_p.h
@@ -13,7 +13,6 @@
    protected:
        bool setupHost() override;
        bool hostEventFilter(QEvent *event) override;
    };
}
src/core/contexts/win32windowcontext.cpp
@@ -1,10 +1,8 @@
#include "win32windowcontext_p.h"
#include "qwkcoreglobal_p.h"
#include <optional>
#include <QtCore/QHash>
#include <QtCore/QAbstractNativeEventFilter>
#include <QtCore/QScopeGuard>
#include <QtGui/QGuiApplication>
@@ -24,6 +22,8 @@
#include <dwmapi.h>
#include <timeapi.h>
#include <versionhelpers.h>
#include "nativeeventfilter.h"
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
Q_DECLARE_METATYPE(QMargins)
@@ -62,7 +62,8 @@
//            }
//        };
//
// #define DYNAMIC_API_DECLARE(NAME) decltype(&::NAME) p##NAME = DefaultFunc<decltype(&::NAME)>::func
// #define DYNAMIC_API_DECLARE(NAME) decltype(&::NAME) p##NAME =
// DefaultFunc<decltype(&::NAME)>::func
#define DYNAMIC_API_DECLARE(NAME) decltype(&::NAME) p##NAME = nullptr
        DYNAMIC_API_DECLARE(DwmFlush);
@@ -78,7 +79,8 @@
#undef DYNAMIC_API_DECLARE
        DynamicApis() {
#define DYNAMIC_API_RESOLVE(DLL, NAME) p##NAME = reinterpret_cast<decltype(p##NAME)>(DLL.resolve(#NAME))
#define DYNAMIC_API_RESOLVE(DLL, NAME)                                                             \
    p##NAME = reinterpret_cast<decltype(p##NAME)>(DLL.resolve(#NAME))
            QSystemLibrary user32(QStringLiteral("user32"));
            DYNAMIC_API_RESOLVE(user32, GetDpiForWindow);
@@ -207,7 +209,8 @@
    }
    static inline bool isWin11OrGreater() {
        static const bool result = ::IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN10), LOBYTE(_WIN32_WINNT_WIN10), 22000);
        static const bool result = ::IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN10),
                                                               LOBYTE(_WIN32_WINNT_WIN10), 22000);
        return result;
    }
@@ -383,8 +386,8 @@
        apis.ptimeEndPeriod(ms_granularity);
    }
    static inline void showSystemMenu2(HWND hWnd, const POINT &pos, const bool selectFirstEntry, const bool fixedSize)
    {
    static inline void showSystemMenu2(HWND hWnd, const POINT &pos, const bool selectFirstEntry,
                                       const bool fixedSize) {
        const HMENU hMenu = ::GetSystemMenu(hWnd, FALSE);
        if (!hMenu) {
            // The corresponding window doesn't have a system menu, most likely due to the
@@ -395,8 +398,10 @@
        const bool maxOrFull = IsMaximized(hWnd) || isFullScreen(hWnd);
        ::EnableMenuItem(hMenu, SC_CLOSE, (MF_BYCOMMAND | MFS_ENABLED));
        ::EnableMenuItem(hMenu, SC_MAXIMIZE, (MF_BYCOMMAND | ((maxOrFull || fixedSize) ? MFS_DISABLED : MFS_ENABLED)));
        ::EnableMenuItem(hMenu, SC_RESTORE, (MF_BYCOMMAND | ((maxOrFull && !fixedSize) ? MFS_ENABLED : MFS_DISABLED)));
        ::EnableMenuItem(hMenu, SC_MAXIMIZE,
                         (MF_BYCOMMAND | ((maxOrFull || fixedSize) ? MFS_DISABLED : MFS_ENABLED)));
        ::EnableMenuItem(hMenu, SC_RESTORE,
                         (MF_BYCOMMAND | ((maxOrFull && !fixedSize) ? MFS_ENABLED : MFS_DISABLED)));
        // The first menu item should be selected by default if the menu is brought
        // up by keyboard. I don't know how to pre-select a menu item but it seems
        // highlight can do the job. However, there's an annoying issue if we do
@@ -406,9 +411,11 @@
        // highlight bar will not move accordingly, the OS will generate another
        // highlight bar to indicate the current selected menu item, which will make
        // the menu look kind of weird. Currently I don't know how to fix this issue.
        ::HiliteMenuItem(hWnd, hMenu, SC_RESTORE, (MF_BYCOMMAND | (selectFirstEntry ? MFS_HILITE : MFS_UNHILITE)));
        ::HiliteMenuItem(hWnd, hMenu, SC_RESTORE,
                         (MF_BYCOMMAND | (selectFirstEntry ? MFS_HILITE : MFS_UNHILITE)));
        ::EnableMenuItem(hMenu, SC_MINIMIZE, (MF_BYCOMMAND | MFS_ENABLED));
        ::EnableMenuItem(hMenu, SC_SIZE, (MF_BYCOMMAND | ((maxOrFull || fixedSize) ? MFS_DISABLED : MFS_ENABLED)));
        ::EnableMenuItem(hMenu, SC_SIZE,
                         (MF_BYCOMMAND | ((maxOrFull || fixedSize) ? MFS_DISABLED : MFS_ENABLED)));
        ::EnableMenuItem(hMenu, SC_MOVE, (MF_BYCOMMAND | (maxOrFull ? MFS_DISABLED : MFS_ENABLED)));
        // The default menu item will appear in bold font. There can only be one default
@@ -428,7 +435,10 @@
        ::SetMenuDefaultItem(hMenu, defaultItemId, FALSE);
        // Popup the system menu at the required position.
        const auto result = ::TrackPopupMenu(hMenu, (TPM_RETURNCMD | (QGuiApplication::isRightToLeft() ? TPM_RIGHTALIGN : TPM_LEFTALIGN)), pos.x, pos.y, 0, hWnd, nullptr);
        const auto result = ::TrackPopupMenu(
            hMenu,
            (TPM_RETURNCMD | (QGuiApplication::isRightToLeft() ? TPM_RIGHTALIGN : TPM_LEFTALIGN)),
            pos.x, pos.y, 0, hWnd, nullptr);
        // Unhighlight the first menu item after the popup menu is closed, otherwise it will keep
        // highlighting until we unhighlight it manually.
@@ -511,7 +521,7 @@
    // DefWindowProc(). Consequently, we have to add a global native filter that forwards the result
    // of the hook function, telling Qt whether we have filtered the events before. Since Qt only
    // handles Windows window messages in the main thread, it is safe to do so.
    class WindowsNativeEventFilter : public QAbstractNativeEventFilter {
    class WindowsNativeEventFilter : public NativeEventFilter {
    public:
        bool nativeEventFilter(const QByteArray &eventType, void *message,
                               QT_NATIVE_EVENT_RESULT_TYPE *result) override {
@@ -546,14 +556,12 @@
                return;
            }
            instance = new WindowsNativeEventFilter();
            installNativeEventFilter(instance);
        }
        static inline void uninstall() {
            if (!instance) {
                return;
            }
            removeNativeEventFilter(instance);
            delete instance;
            instance = nullptr;
        }
@@ -659,6 +667,12 @@
                WindowsNativeEventFilter::uninstall();
            }
        }
    }
    void Win32WindowContext::showSystemMenu(const QPoint &pos) {
        auto winId = m_windowHandle->winId();
        auto hWnd = reinterpret_cast<HWND>(winId);
        showSystemMenu2(hWnd, {pos.x(), pos.y()}, false, m_delegate->isHostSizeFixed(m_host));
    }
    bool Win32WindowContext::setupHost() {
@@ -884,8 +898,9 @@
                    DWORD dwScreenPos = ::GetMessagePos();
                    POINT screenPoint{GET_X_LPARAM(dwScreenPos), GET_Y_LPARAM(dwScreenPos)};
                    ::ScreenToClient(hWnd, &screenPoint);
                    QPoint qtScenePos = QHighDpi::fromNativeLocalPosition(point2qpoint(screenPoint), m_windowHandle);
                    auto dummy = CoreWindowAgent::Unknown;
                    QPoint qtScenePos = QHighDpi::fromNativeLocalPosition(point2qpoint(screenPoint),
                                                                          m_windowHandle);
                    auto dummy = WindowAgentBase::Unknown;
                    if (isInSystemButtons(qtScenePos, &dummy)) {
                        // We must record whether the last WM_MOUSELEAVE was filtered, because if
                        // Qt does not receive this message it will not call TrackMouseEvent()
@@ -1116,13 +1131,14 @@
                auto clientWidth = RECT_WIDTH(clientRect);
                auto clientHeight = RECT_HEIGHT(clientRect);
                QPoint qtScenePos = QHighDpi::fromNativeLocalPosition(point2qpoint(nativeLocalPos), m_windowHandle);
                QPoint qtScenePos =
                    QHighDpi::fromNativeLocalPosition(point2qpoint(nativeLocalPos), m_windowHandle);
                bool isFixedSize = m_delegate->isHostSizeFixed(m_host);
                bool isTitleBar = isInTitleBarDraggableArea(qtScenePos);
                bool dontOverrideCursor = false; // ### TODO
                CoreWindowAgent::SystemButton sysButtonType = CoreWindowAgent::Unknown;
                WindowAgentBase::SystemButton sysButtonType = WindowAgentBase::Unknown;
                if (!isFixedSize && isInSystemButtons(qtScenePos, &sysButtonType)) {
                    // Firstly, we set the hit test result to a default value to be able to detect
                    // whether we have changed it or not afterwards.
@@ -1166,19 +1182,19 @@
                        // exact role of our button. The Snap Layout feature introduced in Windows
                        // 11 won't work without this.
                        switch (sysButtonType) {
                            case CoreWindowAgent::WindowIcon:
                            case WindowAgentBase::WindowIcon:
                                *result = HTSYSMENU;
                                break;
                            case CoreWindowAgent::Help:
                            case WindowAgentBase::Help:
                                *result = HTHELP;
                                break;
                            case CoreWindowAgent::Minimize:
                            case WindowAgentBase::Minimize:
                                *result = HTREDUCE;
                                break;
                            case CoreWindowAgent::Maximize:
                            case WindowAgentBase::Maximize:
                                *result = HTZOOM;
                                break;
                            case CoreWindowAgent::Close:
                            case WindowAgentBase::Close:
                                *result = HTCLOSE;
                                break;
                            default:
@@ -1628,7 +1644,8 @@
            }();
            RECT windowPos{};
            ::GetWindowRect(hWnd, &windowPos);
            return {static_cast<LONG>(windowPos.left + horizontalOffset), static_cast<LONG>(windowPos.top + verticalOffset)};
            return {static_cast<LONG>(windowPos.left + horizontalOffset),
                    static_cast<LONG>(windowPos.top + verticalOffset)};
        };
        bool shouldShowSystemMenu = false;
        bool broughtByKeyboard = false;
@@ -1636,7 +1653,8 @@
        switch (message) {
            case WM_RBUTTONUP: {
                const POINT nativeLocalPos = getNativePosFromMouse();
                const QPoint qtScenePos = QHighDpi::fromNativeLocalPosition(point2qpoint(nativeLocalPos), m_windowHandle);
                const QPoint qtScenePos =
                    QHighDpi::fromNativeLocalPosition(point2qpoint(nativeLocalPos), m_windowHandle);
                if (isInTitleBarDraggableArea(qtScenePos)) {
                    shouldShowSystemMenu = true;
                    nativeGlobalPos = nativeLocalPos;
@@ -1675,7 +1693,8 @@
                break;
        }
        if (shouldShowSystemMenu) {
            showSystemMenu2(hWnd, nativeGlobalPos, broughtByKeyboard, m_delegate->isHostSizeFixed(m_host));
            showSystemMenu2(hWnd, nativeGlobalPos, broughtByKeyboard,
                            m_delegate->isHostSizeFixed(m_host));
            // QPA's internal code will handle system menu events separately, and its
            // behavior is not what we would want to see because it doesn't know our
            // window doesn't have any window frame now, so return early here to avoid
src/core/contexts/win32windowcontext_p.h
@@ -21,6 +21,8 @@
            TitleBar,
        };
        void showSystemMenu(const QPoint &pos) override;
    protected:
        bool setupHost() override;
src/core/corewindowagent.cpp
File was deleted
src/core/corewindowagent_p.h
File was deleted
src/core/kernel/nativeeventfilter.cpp
New file
@@ -0,0 +1,65 @@
#include "nativeeventfilter.h"
#include <QtCore/QAbstractNativeEventFilter>
#include <QtGui/QGuiApplication>
namespace QWK {
    // Avoid adding multiple global native event filters to QGuiApplication
    // in this library.
    class MasterNativeEventFilter : public QAbstractNativeEventFilter {
    public:
        MasterNativeEventFilter() {
            qApp->installNativeEventFilter(this);
        }
        ~MasterNativeEventFilter() override {
            qApp->removeNativeEventFilter(this);
        }
        bool nativeEventFilter(const QByteArray &eventType, void *message,
                               QT_NATIVE_EVENT_RESULT_TYPE *result) override {
            for (const auto &child : qAsConst(m_children)) {
                if (child->nativeEventFilter(eventType, message, result)) {
                    return true;
                }
            }
            return false;
        }
        inline int count() const {
            return m_children.size();
        }
        inline void addChild(NativeEventFilter *child) {
            m_children.append(child);
        }
        inline void removeChild(NativeEventFilter *child) {
            m_children.removeOne(child);
        }
        static MasterNativeEventFilter *instance;
    protected:
        QVector<NativeEventFilter *> m_children;
    };
    MasterNativeEventFilter *MasterNativeEventFilter::instance = nullptr;
    NativeEventFilter::NativeEventFilter() {
        if (!MasterNativeEventFilter::instance) {
            MasterNativeEventFilter::instance = new MasterNativeEventFilter();
        }
        MasterNativeEventFilter::instance->addChild(this);
    }
    NativeEventFilter::~NativeEventFilter() {
        MasterNativeEventFilter::instance->removeChild(this);
        if (MasterNativeEventFilter::instance->count() == 0) {
            delete MasterNativeEventFilter::instance;
            MasterNativeEventFilter::instance = nullptr;
        }
    }
}
src/core/kernel/nativeeventfilter.h
New file
@@ -0,0 +1,23 @@
#ifndef NATIVEEVENTFILTER_H
#define NATIVEEVENTFILTER_H
#include <QWKCore/qwkglobal.h>
namespace QWK {
    class QWK_CORE_EXPORT NativeEventFilter {
    public:
        NativeEventFilter();
        virtual ~NativeEventFilter();
    public:
        virtual bool nativeEventFilter(const QByteArray &eventType, void *message,
                                       QT_NATIVE_EVENT_RESULT_TYPE *result) = 0;
    private:
        Q_DISABLE_COPY(NativeEventFilter)
    };
}
#endif // NATIVEEVENTFILTER_H
src/core/kernel/sharedeventfilter.cpp
New file
@@ -0,0 +1,90 @@
#include "sharedeventfilter.h"
namespace QWK {
    class EventFilterForwarder : public QObject {
    public:
        explicit EventFilterForwarder(SharedEventDispatcherPrivate *master,
                                      QObject *parent = nullptr)
            : QObject(parent), master(master) {
        }
        bool eventFilter(QObject *obj, QEvent *event) override;
    protected:
        SharedEventDispatcherPrivate *master;
    };
    class SharedEventDispatcherPrivate {
    public:
        explicit SharedEventDispatcherPrivate(SharedEventDispatcher *q)
            : q(q), forwarder(new EventFilterForwarder(this)) {
        }
        ~SharedEventDispatcherPrivate() = default;
        bool dispatch(QObject *obj, QEvent *event) {
            for (const auto &ef : qAsConst(eventFilters)) {
                if (ef->eventFilter(obj, event)) {
                    return true;
                }
            }
            return false;
        }
        inline void install(SharedEventFilter *eventFilter) {
            bool empty = eventFilters.isEmpty();
            eventFilters.append(eventFilter);
            eventFilter->m_dispatcher = q;
            if (empty) {
                q->target()->installEventFilter(forwarder.get());
            }
        }
        inline void uninstall(SharedEventFilter *eventFilter) {
            if (!eventFilters.removeOne(eventFilter)) {
                return;
            }
            eventFilter->m_dispatcher = nullptr;
            if (eventFilters.isEmpty()) {
                q->target()->removeEventFilter(forwarder.get());
            }
        }
        SharedEventDispatcher *q;
        std::unique_ptr<EventFilterForwarder> forwarder;
        QVector<SharedEventFilter *> eventFilters;
    };
    bool EventFilterForwarder::eventFilter(QObject *obj, QEvent *event) {
        return master->dispatch(obj, event);
    }
    SharedEventFilter::SharedEventFilter() : m_dispatcher(nullptr) {
    }
    SharedEventFilter::~SharedEventFilter() {
        if (m_dispatcher)
            m_dispatcher->removeSharedEventFilter(this);
    }
    SharedEventDispatcher::SharedEventDispatcher() : d(new SharedEventDispatcherPrivate(this)) {
    }
    SharedEventDispatcher::~SharedEventDispatcher() {
        delete d;
    }
    void SharedEventDispatcher::installSharedEventFilter(SharedEventFilter *eventFilter) {
        d->install(eventFilter);
    }
    void SharedEventDispatcher::removeSharedEventFilter(SharedEventFilter *eventFilter) {
        d->uninstall(eventFilter);
    }
}
src/core/kernel/sharedeventfilter.h
New file
@@ -0,0 +1,51 @@
#ifndef SHAREDEVENTFILTER_H
#define SHAREDEVENTFILTER_H
#include <QtCore/QObject>
#include <QtCore/QVector>
#include <QWKCore/qwkcoreglobal.h>
namespace QWK {
    class SharedEventDispatcherPrivate;
    class SharedEventDispatcher;
    class QWK_CORE_EXPORT SharedEventFilter {
    public:
        SharedEventFilter();
        virtual ~SharedEventFilter();
    public:
        virtual bool eventFilter(QObject *obj, QEvent *event) = 0;
    private:
        SharedEventDispatcher *m_dispatcher;
        Q_DISABLE_COPY(SharedEventFilter)
        friend class SharedEventDispatcher;
        friend class SharedEventDispatcherPrivate;
    };
    class QWK_CORE_EXPORT SharedEventDispatcher {
    public:
        SharedEventDispatcher();
        virtual ~SharedEventDispatcher();
    public:
        virtual QObject *target() const = 0;
        void installSharedEventFilter(SharedEventFilter *eventFilter);
        void removeSharedEventFilter(SharedEventFilter *eventFilter);
    protected:
        SharedEventDispatcherPrivate *d;
        Q_DISABLE_COPY(SharedEventDispatcher)
    };
}
#endif // SHAREDEVENTFILTER_H
src/core/qwkcoreglobal.cpp
File was deleted
src/core/qwkcoreglobal_p.h
File was deleted
src/core/qwkglobal.h
New file
@@ -0,0 +1,16 @@
#ifndef QWKGLOBAL_H
#define QWKGLOBAL_H
#include <QtCore/QEvent>
#include <QWKCore/qwkcoreglobal.h>
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
using QT_NATIVE_EVENT_RESULT_TYPE = qintptr;
using QT_ENTER_EVENT_TYPE = QEnterEvent;
#else
using QT_NATIVE_EVENT_RESULT_TYPE = long;
using QT_ENTER_EVENT_TYPE = QEvent;
#endif
#endif // QWKGLOBAL_H
src/core/qwkglobal_p.h
New file
@@ -0,0 +1,18 @@
#ifndef QWKGLOBAL_P_H
#define QWKGLOBAL_P_H
#include <QtCore/QLoggingCategory>
#include <QWKCore/qwkcoreglobal.h>
QWK_CORE_EXPORT Q_DECLARE_LOGGING_CATEGORY(qWindowKitLog)
#define QWK_INFO     qCInfo(qWindowKitLog)
#define QWK_DEBUG    qCDebug(qWindowKitLog)
#define QWK_WARNING  qCWarning(qWindowKitLog)
#define QWK_CRITICAL qCCritical(qWindowKitLog)
#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
#  define QWK_FATAL qCFatal(qWindowKitLog)
#endif
#endif // QWKGLOBAL_P_H
src/core/windowagentbase.cpp
New file
@@ -0,0 +1,86 @@
#include "windowagentbase.h"
#include "windowagentbase_p.h"
#include "qwkglobal_p.h"
#ifdef Q_OS_WINDOWS
#  include "win32windowcontext_p.h"
#else
#  include "qtwindowcontext_p.h"
#endif
Q_LOGGING_CATEGORY(qWindowKitLog, "qwindowkit")
namespace QWK {
    WindowAgentBasePrivate::WindowAgentBasePrivate() : q_ptr(nullptr), context(nullptr) {
    }
    WindowAgentBasePrivate::~WindowAgentBasePrivate() = default;
    void WindowAgentBasePrivate::init() {
    }
    AbstractWindowContext *WindowAgentBasePrivate::createContext() const {
        return
#ifdef Q_OS_WINDOWS
            new Win32WindowContext()
#else
            new QtWindowContext()
#endif
                ;
    }
    bool WindowAgentBasePrivate::setup(QObject *host, WindowItemDelegate *delegate) {
        std::unique_ptr<AbstractWindowContext> ctx(createContext());
        if (!ctx->setup(host, delegate)) {
            return false;
        }
        context = std::move(ctx);
        return true;
    }
    WindowAgentBase::~WindowAgentBase() = default;
    void WindowAgentBase::showSystemMenu(const QPoint &pos) {
        Q_D(WindowAgentBase);
        d->context->showSystemMenu(pos);
    }
    void WindowAgentBase::startSystemMove(const QPoint &pos) {
        Q_D(WindowAgentBase);
        auto win = d->context->window();
        if (!win) {
            return;
        }
        Q_UNUSED(pos)
        win->startSystemMove();
    }
    void WindowAgentBase::startSystemResize(Qt::Edges edges, const QPoint &pos) {
        Q_D(WindowAgentBase);
        auto win = d->context->window();
        if (!win) {
            return;
        }
        Q_UNUSED(pos)
        win->startSystemResize(edges);
    }
    void WindowAgentBase::centralize() {
    }
    void WindowAgentBase::raise() {
    }
    WindowAgentBase::WindowAgentBase(WindowAgentBasePrivate &d, QObject *parent)
        : QObject(parent), d_ptr(&d) {
        d.q_ptr = this;
        d.init();
    }
}
src/core/windowagentbase.h
File was renamed from src/core/corewindowagent.h
@@ -1,5 +1,5 @@
#ifndef COREWINDOWAGENT_H
#define COREWINDOWAGENT_H
#ifndef WINDOWAGENTBASE_H
#define WINDOWAGENTBASE_H
#include <memory>
@@ -9,13 +9,13 @@
namespace QWK {
    class CoreWindowAgentPrivate;
    class WindowAgentBasePrivate;
    class QWK_CORE_EXPORT CoreWindowAgent : public QObject {
    class QWK_CORE_EXPORT WindowAgentBase : public QObject {
        Q_OBJECT
        Q_DECLARE_PRIVATE(CoreWindowAgent)
        Q_DECLARE_PRIVATE(WindowAgentBase)
    public:
        ~CoreWindowAgent() override;
        ~WindowAgentBase() override;
        enum SystemButton {
            Unknown,
@@ -36,11 +36,11 @@
        void raise();
    protected:
        explicit CoreWindowAgent(CoreWindowAgentPrivate &d, QObject *parent = nullptr);
        explicit WindowAgentBase(WindowAgentBasePrivate &d, QObject *parent = nullptr);
        const std::unique_ptr<CoreWindowAgentPrivate> d_ptr;
        const std::unique_ptr<WindowAgentBasePrivate> d_ptr;
    };
}
#endif // COREWINDOWAGENT_H
#endif // WINDOWAGENTBASE_H
src/core/windowagentbase_p.h
New file
@@ -0,0 +1,30 @@
#ifndef WINDOWAGENTBASEPRIVATE_H
#define WINDOWAGENTBASEPRIVATE_H
#include <QWKCore/windowagentbase.h>
#include <QWKCore/private/abstractwindowcontext_p.h>
namespace QWK {
    class QWK_CORE_EXPORT WindowAgentBasePrivate {
        Q_DECLARE_PUBLIC(WindowAgentBase)
    public:
        WindowAgentBasePrivate();
        virtual ~WindowAgentBasePrivate();
        void init();
        WindowAgentBase *q_ptr; // no need to initialize
        virtual AbstractWindowContext *createContext() const;
        bool setup(QObject *host, WindowItemDelegate *delegate);
        std::unique_ptr<AbstractWindowContext> context;
        Q_DISABLE_COPY_MOVE(WindowAgentBasePrivate)
    };
}
#endif // WINDOWAGENTBASEPRIVATE_H
src/core/windowitemdelegate.cpp
@@ -1,4 +1,4 @@
#include "windowitemdelegate.h"
#include "windowitemdelegate_p.h"
namespace QWK {
src/core/windowitemdelegate_p.h
File was renamed from src/core/windowitemdelegate.h
@@ -1,11 +1,11 @@
#ifndef WINDOWITEMDELEGATE_H
#define WINDOWITEMDELEGATE_H
#ifndef WINDOWITEMDELEGATE_P_H
#define WINDOWITEMDELEGATE_P_H
#include <QtCore/QObject>
#include <QtCore/QPoint>
#include <QtGui/QWindow>
#include <QWKCore/corewindowagent.h>
#include <QWKCore/qwkcoreglobal.h>
namespace QWK {
@@ -34,4 +34,4 @@
}
#endif // WINDOWITEMDELEGATE_H
#endif // WINDOWITEMDELEGATE_P_H
src/quick/CMakeLists.txt
@@ -10,8 +10,6 @@
    quickwindowagent.h
    quickwindowagent_p.h
    quickwindowagent.cpp
    contexts/quickwindowcontext_p.h
    contexts/quickwindowcontext.cpp
)
qwk_add_library(${PROJECT_NAME} AUTOGEN
src/quick/contexts/quickwindowcontext.cpp
File was deleted
src/quick/contexts/quickwindowcontext_p.h
File was deleted
src/quick/quickitemdelegate_p.h
@@ -4,7 +4,7 @@
#include <QtCore/QObject>
#include <QtGui/QWindow>
#include <QWKCore/windowitemdelegate.h>
#include <QWKCore/private/windowitemdelegate_p.h>
#include <QWKQuick/qwkquickglobal.h>
namespace QWK {
src/quick/quickwindowagent.cpp
@@ -4,7 +4,6 @@
#include <QtQuick/QQuickWindow>
#include "quickitemdelegate_p.h"
#include "quickwindowcontext_p.h"
namespace QWK {
@@ -15,10 +14,6 @@
    }
    void QuickWindowAgentPrivate::init() {
    }
    AbstractWindowContext *QuickWindowAgentPrivate::createContext() const {
        return new QuickWindowContext();
    }
    QuickWindowAgent::QuickWindowAgent(QObject *parent)
@@ -88,7 +83,7 @@
    }
    QuickWindowAgent::QuickWindowAgent(QuickWindowAgentPrivate &d, QObject *parent)
        : CoreWindowAgent(d, parent) {
        : WindowAgentBase(d, parent) {
        d.init();
    }
}
src/quick/quickwindowagent.h
@@ -4,14 +4,14 @@
#include <QtQuick/QQuickItem>
#include <QtQuick/QQuickWindow>
#include <QWKCore/corewindowagent.h>
#include <QWKCore/windowagentbase.h>
#include <QWKQuick/qwkquickglobal.h>
namespace QWK {
    class QuickWindowAgentPrivate;
    class QWK_QUICK_EXPORT QuickWindowAgent : public CoreWindowAgent {
    class QWK_QUICK_EXPORT QuickWindowAgent : public WindowAgentBase {
        Q_OBJECT
        Q_DECLARE_PRIVATE(QuickWindowAgent)
    public:
src/quick/quickwindowagent_p.h
@@ -1,20 +1,18 @@
#ifndef QUICKWINDOWAGENTPRIVATE_H
#define QUICKWINDOWAGENTPRIVATE_H
#include <QWKCore/private/corewindowagent_p.h>
#include <QWKCore/private/windowagentbase_p.h>
#include <QWKQuick/quickwindowagent.h>
namespace QWK {
    class QuickWindowAgentPrivate : public CoreWindowAgentPrivate {
    class QuickWindowAgentPrivate : public WindowAgentBasePrivate {
        Q_DECLARE_PUBLIC(QuickWindowAgent)
    public:
        QuickWindowAgentPrivate();
        ~QuickWindowAgentPrivate() override;
        void init();
        AbstractWindowContext * createContext() const override;
        // Host
        QQuickWindow *hostWindow{};
src/widgets/CMakeLists.txt
@@ -10,8 +10,6 @@
    widgetwindowagent.h
    widgetwindowagent_p.h
    widgetwindowagent.cpp
    contexts/widgetwindowcontext_p.h
    contexts/widgetwindowcontext.cpp
)
qwk_add_library(${PROJECT_NAME} AUTOGEN
src/widgets/contexts/widgetwindowcontext.cpp
File was deleted
src/widgets/contexts/widgetwindowcontext_p.h
File was deleted
src/widgets/widgetitemdelegate_p.h
@@ -4,7 +4,7 @@
#include <QtCore/QObject>
#include <QtGui/QWindow>
#include <QWKCore/windowitemdelegate.h>
#include <QWKCore/private/windowitemdelegate_p.h>
#include <QWKWidgets/qwkwidgetsglobal.h>
namespace QWK {
src/widgets/widgetwindowagent.cpp
@@ -2,7 +2,6 @@
#include "widgetwindowagent_p.h"
#include "widgetitemdelegate_p.h"
#include "widgetwindowcontext_p.h"
namespace QWK {
@@ -13,10 +12,6 @@
    }
    void WidgetWindowAgentPrivate::init() {
    }
    AbstractWindowContext *WidgetWindowAgentPrivate::createContext() const {
        return new WidgetWindowContext();
    }
    WidgetWindowAgent::WidgetWindowAgent(QObject *parent)
@@ -89,7 +84,7 @@
    }
    WidgetWindowAgent::WidgetWindowAgent(WidgetWindowAgentPrivate &d, QObject *parent)
        : CoreWindowAgent(d, parent) {
        : WindowAgentBase(d, parent) {
        d.init();
    }
}
src/widgets/widgetwindowagent.h
@@ -3,14 +3,14 @@
#include <QtWidgets/QWidget>
#include <QWKCore/corewindowagent.h>
#include <QWKCore/windowagentbase.h>
#include <QWKWidgets/qwkwidgetsglobal.h>
namespace QWK {
    class WidgetWindowAgentPrivate;
    class QWK_WIDGETS_EXPORT WidgetWindowAgent : public CoreWindowAgent {
    class QWK_WIDGETS_EXPORT WidgetWindowAgent : public WindowAgentBase {
        Q_OBJECT
        Q_DECLARE_PRIVATE(WidgetWindowAgent)
    public:
src/widgets/widgetwindowagent_p.h
@@ -1,20 +1,18 @@
#ifndef WIDGETWINDOWAGENTPRIVATE_H
#define WIDGETWINDOWAGENTPRIVATE_H
#include <QWKCore/private/corewindowagent_p.h>
#include <QWKCore/private/windowagentbase_p.h>
#include <QWKWidgets/widgetwindowagent.h>
namespace QWK {
    class WidgetWindowAgentPrivate : public CoreWindowAgentPrivate {
    class WidgetWindowAgentPrivate : public WindowAgentBasePrivate {
        Q_DECLARE_PUBLIC(WidgetWindowAgent)
    public:
        WidgetWindowAgentPrivate();
        ~WidgetWindowAgentPrivate();
        void init();
        AbstractWindowContext * createContext() const override;
        // Host
        QWidget *hostWidget{};