SineStriker
2023-12-01 2d944e7bd4e435e216ae301b6826515d9f385574
Add basic project structure
3个文件已修改
36个文件已添加
1516 ■■■■■ 已修改文件
.clang-format 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore 120 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitmodules 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CMakeLists.txt 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LICENSE 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
examples/CMakeLists.txt 补丁 | 查看 | 原始文档 | blame | 历史
share/msbuild/.gitkeep 补丁 | 查看 | 原始文档 | blame | 历史
share/qmake/.gitkeep 补丁 | 查看 | 原始文档 | blame | 历史
src/CMakeLists.txt 208 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/QWindowKitConfig.cmake.in 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/CMakeLists.txt 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/corewindowagent.cpp 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/corewindowagent.h 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/corewindowagent_p.h 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/handler/abstractwindowcontext.cpp 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/handler/abstractwindowcontext_p.h 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/handler/qtwindowcontext.cpp 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/handler/qtwindowcontext_p.h 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/handler/win32windowcontext.cpp 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/handler/win32windowcontext_p.h 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/qwindowkit_linux.h 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/qwindowkit_windows.h 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/qwkcoreglobal.h 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/windowitemdelegate.h 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/quick/CMakeLists.txt 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/quick/quickitemdelegate.cpp 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/quick/quickitemdelegate_p.h 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/quick/quickwindowagent.cpp 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/quick/quickwindowagent.h 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/quick/quickwindowagent_p.h 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/quick/qwkquickglobal.h 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/widgets/CMakeLists.txt 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/widgets/qwkwidgetsglobal.h 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/widgets/widgetitemdelegate.cpp 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/widgets/widgetitemdelegate_p.h 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/widgets/widgetwindowagent.cpp 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/widgets/widgetwindowagent.h 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/widgets/widgetwindowagent_p.h 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.clang-format
New file
@@ -0,0 +1,130 @@
# References:
#   https://clang.llvm.org/docs/ClangFormatStyleOptions.html
#   https://code.qt.io/cgit/qt/qt5.git/tree/_clang-format
BasedOnStyle: LLVM
Standard: c++17
# 指针和引用的对齐方式。
# 可能的值有:
# PAS_Left (在配置中: Left) 指针左对齐。
# PAS_Right (在配置中: Right) 指针右对齐。
# PAS_Middle (在配置中: Middle) 指针中间对齐。
PointerAlignment: Right
# public/protected/private 等访问修饰符偏移量
AccessModifierOffset: -4
# 缩进长度
IndentWidth: 4
# 连续空行的最大数
MaxEmptyLinesToKeep: 999
# 在OC中的@property后面添加一个空格。例如:使用“@property (readonly)”而不是“@property(readonly)”
ObjCSpaceAfterProperty: true
# OC块中所拍的字符数
ObjCBlockIndentWidth: 4
# 取决于值, 语句“int f() { return 0; }”可以被放到一个单行。
# 可能的值有:
# SFS_None (在配置中: None) 从不合并方法或函数到单独的一行。
# SFS_Empty (在配置中: Empty) 仅合并空的函数。
# SFS_Inline (在配置中: Inline) 仅合并类中定义的方法或函数. 意味着 “empty”.
# SFS_All (在配置中: All) 合并所有的方法适应单行.
AllowShortFunctionsOnASingleLine: None
# 如果为真(true), 语句“if (a) return;” 能被放到单行。
AllowShortIfStatementsOnASingleLine: false
# 如果为真(true), 对齐注释。
AlignTrailingComments: true
# 如果为真,对齐连续的宏定义
AlignConsecutiveMacros: true
# 如果为真(true),将会在“[”之后和“]”之前插入空格。
SpacesInSquareBrackets: false
# 如果为真(true), 将会在“(”之后和“)”之前插入空格。
SpacesInParentheses : false
# 如果为真(true), 校准连续的声明。
# 这将会校准连续多行的声明的名字。这将会导致像下面这样的格式:
# int         aaaa = 12;
# float       b = 23;
# std::string ccc = 23;
AlignConsecutiveDeclarations: false
# 如果为真(true),连续调整多行
# 这将会调整连续行中的分配操作符。这将会导致像下面这样的格式:
# int aaaa = 12;
# int b    = 23;
# int ccc  = 23;
AlignConsecutiveAssignments: false
# 如果为假(false),移除分配操作符(=)前空格。
SpaceBeforeAssignmentOperators: true
# 如果为真(true), 将会在字面量容器中插入空格(例如 OC和Javascript的数组和字典字面量)。
SpacesInContainerLiterals: false
# 缩进case标签
IndentCaseLabels: true
# 如果表达式中包含函数调用,并且函数调用因为表达式太长被放到了下一行,是否缩进
IndentWrappedFunctionNames: true
# 如果为真(true), 保持块的起始空行。
# true:                                  false:
# if (foo) {                     vs.     if (foo) {
#                                          bar();
#   bar();                               }
# }
KeepEmptyLinesAtTheStartOfBlocks: true
# 允许所有参数都被放在下一行
AllowAllParametersOfDeclarationOnNextLine: false
# 使用C风格强制类型转换后,是否在中间添加一个空格
SpaceAfterCStyleCast: true
# 在模板定义后换行
AlwaysBreakTemplateDeclarations: Yes
# Tab长度
TabWidth: 4
# 是否使用Tab
UseTab: Never
# 在括号后对齐参数
# someLongFunction(argument1,
#                  argument2);
AlignAfterOpenBracket: Align
# 名字空间内部缩进
NamespaceIndentation: All
# 一行最长列数
ColumnLimit: 100
# 按层次缩进宏定义
IndentPPDirectives: AfterHash
# 预处理语句缩进为 2
PPIndentWidth: 2
# 数组元素对齐
AlignArrayOfStructures: Left
# 不对头文件排序
SortIncludes: Never
FixNamespaceComments: false
StatementMacros: ['__qas_attr__', '__qas_exclude__', '__qas_include__']
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE ]
.gitignore
@@ -1,32 +1,98 @@
# Prerequisites
*.d
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
# Compiled Object files
*.slo
*.lo
*~
*.log
*.autosave
*.a
*.core
*.moc
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.orig
*.rej
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
.directory
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
# *.res
# *.rc
/.qmake.cache
/.qmake.stash
# qtcreator generated files
*.pro.user*
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*
# MinGW generated files
*.Debug
*.Release
# Python byte code
__pycache__
*.pyc
# Binaries
# --------
*.dll
*.exe
.DS_Store
*/.DS_Store
build-src*
build/
cmake-build*
*.user
*.lnk
_workingDir*
.vscode
.idea
.cache
cache
.vs
out/
CMakeSettings.json
# /vcpkg
/data
/*.natvis
*.sublime-*
setup-vcpkg.json
setup-vcpkg-temp*
.gitmodules
New file
@@ -0,0 +1,4 @@
[submodule "qmsetup"]
    path = qmsetup
    url = ../../stdware/qmsetup.git
    branch = main
CMakeLists.txt
New file
@@ -0,0 +1,71 @@
cmake_minimum_required(VERSION 3.17)
project(QWindowKit VERSION 0.0.1.1 LANGUAGES CXX)
# ----------------------------------
# Build Options
# ----------------------------------
option(QWINDOWKIT_BUILD_STATIC "Build static libraries" OFF)
option(QWINDOWKIT_BUILD_WIDGETS "Build widgets module" ON)
option(QWINDOWKIT_BUILD_QUICK "Build quick module" ON)
option(QWINDOWKIT_BUILD_EXAMPLES "Build examples" OFF)
option(QWINDOWKIT_BUILD_DOCUMENTATIONS "Build documentations" OFF)
option(QWINDOWKIT_INSTALL "Install library" ON)
# ----------------------------------
# CMake Settings
# ----------------------------------
if(MSVC)
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /manifest:no")
    set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /manifest:no")
    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /manifest:no")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8")
    if(NOT DEFINED CMAKE_DEBUG_POSTFIX)
        set(CMAKE_DEBUG_POSTFIX "d")
    endif()
endif()
if(QWINDOWKIT_INSTALL)
    include(GNUInstallDirs)
    include(CMakePackageConfigHelpers)
endif()
# ----------------------------------
# Project Variables
# ----------------------------------
set(QWINDOWKIT_VERSION ${PROJECT_VERSION})
set(QWINDOWKIT_INSTALL_NAME ${PROJECT_NAME})
# ----------------------------------
# Main Project
# ----------------------------------
find_package(qmsetup QUIET)
if(NOT TARGET qmsetup::library)
    # Modify this variable according to your project structure
    set(_source_dir ${CMAKE_CURRENT_SOURCE_DIR}/qmsetup)
    # Import install function
    include("${_source_dir}/cmake/modules/InstallPackage.cmake")
    # Install package in place
    set(_package_path)
    qm_install_package(qmsetup
        SOURCE_DIR ${_source_dir}
        BUILD_TYPE Release
        RESULT_PATH _package_path
    )
    # Find package again
    find_package(qmsetup REQUIRED PATHS ${_package_path})
    # Update import path
    set(qmsetup_DIR ${_package_path} CACHE PATH "" FORCE)
endif()
add_subdirectory(src)
if(QWINDOWKIT_BUILD_EXAMPLES)
    add_subdirectory(examples)
endif()
LICENSE
@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2023 Fake歌手创作者社群
Copyright (c) 2023 Stdware Collections
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
README.md
@@ -1,2 +1,28 @@
# qwindowkit
Cross-platform window customization framework for Qt Widgets and Qt Quick. Supports Windows, Linux and macOS.
# QWindowKit
Cross-platform window customization framework for Qt Widgets and Qt Quick.
The next generation of [FramelessHelper](https://github.com/wangwenx190/framelesshelper).
## Supported Platforms
+ Microsoft Windows (Vista ~ 11)
+ Apple Mac OSX (11+)
+ GNU/Linux (Tested on Ubuntu)
## Requirements
| Component | Requirement |               Detailed               |
|:---------:|:-----------:|:------------------------------------:|
|    Qt     |  \>=5.15.2  |      Core, Gui, Widgets, Quick       |
| Compiler  |  \>=C++17   |        MSVC 2019, GCC, Clang         |
|   CMake   |   \>=3.17   |        >=3.20 is recommended         |
## Dependencies
+ [qmsetup](https://github.com/stdware/qmsetup)
## License
QWindowKit is licensed under the MIT License.
examples/CMakeLists.txt
share/msbuild/.gitkeep
share/qmake/.gitkeep
src/CMakeLists.txt
New file
@@ -0,0 +1,208 @@
qm_import(Filesystem Preprocess)
qm_init_directories()
set(QWINDOWKIT_PROJECT_DESCRIPTION "Cross-platform window customization framework")
set(QWINDOWKIT_PROJECT_COPYRIGHT "Copyright 2023 Stdware Collections")
set(QWINDOWKIT_GENERATED_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/../include)
set(QWINDOWKIT_BUILD_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/../etc/include)
# ----------------------------------
# Configurations
# ----------------------------------
set(QMSETUP_DEFINITION_SCOPE DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
set(QMSETUP_DEFINITION_NUMERICAL on)
qm_add_definition(QWINDOWKIT_TEST_CONFIG true)
qm_generate_config(${QWINDOWKIT_BUILD_INCLUDE_DIR}/QWKCore/qwkconfig.h)
if(QWINDOWKIT_INSTALL)
    install(FILES ${QWINDOWKIT_BUILD_INCLUDE_DIR}/QWKCore/qwkconfig.h
        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${QWINDOWKIT_INSTALL_NAME}/QWKCore
    )
endif()
# ----------------------------------
# CMake API
# ----------------------------------
function(qwk_add_library _target)
    set(options AUTOGEN NO_SYNC_INCLUDE NO_WIN_RC)
    set(oneValueArgs SYNC_INCLUDE_PREFIX PREFIX)
    set(multiValueArgs SYNC_INCLUDE_OPTIONS)
    cmake_parse_arguments(FUNC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
    if(FUNC_AUTOGEN)
        set(CMAKE_AUTOMOC ON)
        set(CMAKE_AUTOUIC ON)
        set(CMAKE_AUTORCC ON)
    endif()
    if(QWINDOWKIT_BUILD_STATIC)
        set(_type STATIC)
    else()
        set(_type SHARED)
    endif()
    add_library(${_target} ${_type})
    if(WIN32 AND NOT FUNC_NO_WIN_RC AND(${_type} STREQUAL "SHARED"))
        qm_add_win_rc(${_target}
            NAME ${QWINDOWKIT_INSTALL_NAME}
            DESCRIPTION ${QWINDOWKIT_PROJECT_DESCRIPTION}
            COPYRIGHT ${QWINDOWKIT_PROJECT_COPYRIGHT}
        )
    endif()
    if(FUNC_PREFIX)
        set(_prefix_option PREFIX ${FUNC_PREFIX})
    else()
        set(_prefix_option)
    endif()
    # Set global definitions
    qm_export_defines(${_target} ${_prefix_option})
    # Configure target
    qm_configure_target(${_target} ${FUNC_UNPARSED_ARGUMENTS})
    # Add include directories
    target_include_directories(${_target} PRIVATE ${QWINDOWKIT_BUILD_INCLUDE_DIR})
    # Library name
    if(${_target} MATCHES "^QWK(.+)")
        set(_name ${CMAKE_MATCH_1})
        set_target_properties(${_target} PROPERTIES EXPORT_NAME ${_name})
    else()
        set(_name ${_target})
    endif()
    add_library(${QWINDOWKIT_INSTALL_NAME}::${_name} ALIAS ${_target})
    if(FUNC_SYNC_INCLUDE_PREFIX)
        set(_inc_name ${FUNC_SYNC_INCLUDE_PREFIX})
    else()
        set(_inc_name ${_target})
    endif()
    set(_install_options)
    if(QWINDOWKIT_INSTALL)
        install(TARGETS ${_target}
            EXPORT ${QWINDOWKIT_INSTALL_NAME}Targets
            RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" OPTIONAL
            LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" OPTIONAL
            ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" OPTIONAL
        )
        target_include_directories(${_target} PUBLIC
            "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${QWINDOWKIT_INSTALL_NAME}>"
        )
        set(_install_options
            INSTALL_DIR "${CMAKE_INSTALL_INCLUDEDIR}/${QWINDOWKIT_INSTALL_NAME}/${_inc_name}"
        )
    endif()
    if(NOT FUNC_NO_SYNC_INCLUDE)
        # Generate a standard include directory in build directory
        qm_sync_include(. "${QWINDOWKIT_GENERATED_INCLUDE_DIR}/${_inc_name}" ${_install_options}
            ${FUNC_SYNC_INCLUDE_OPTIONS}
        )
        target_include_directories(${_target} PUBLIC
            "$<BUILD_INTERFACE:${QWINDOWKIT_GENERATED_INCLUDE_DIR}>"
        )
    endif()
endfunction()
# ----------------------------------
# Main Project
# ----------------------------------
add_subdirectory(core)
if(QWINDOWKIT_BUILD_WIDGETS)
    add_subdirectory(widgets)
endif()
if(QWINDOWKIT_BUILD_QUICK)
    add_subdirectory(quick)
endif()
# ----------------------------------
# Documentation
# ----------------------------------
if(QWINDOWKIT_BUILD_DOCUMENTATIONS)
    if(NOT DOXYGEN_EXECUTABLE)
        find_package(Doxygen REQUIRED)
    endif()
    set(_install_options)
    if(QWINDOWKIT_INSTALL)
        set(_install_options INSTALL_DIR share/doc/${QWINDOWKIT_INSTALL_NAME})
    endif()
    set(_doc_targets)
    qm_collect_targets(_doc_targets SHARED STATIC)
    set(QWINDOWKIT_DOXYGEN_TAGFILE
        ${CMAKE_BUILD_SHARE_DIR}/doc/${QWINDOWKIT_INSTALL_NAME}/${QWINDOWKIT_INSTALL_NAME}_tagfile.xml
        CACHE FILEPATH "QWINDOWKIT doxygen tag file path" FORCE
    )
    qm_import(Doxygen)
    qm_setup_doxygen(QWINDOWKIT_RunDoxygen
        NAME "QWINDOWKIT"
        DESCRIPTION "${QWINDOWKIT_PROJECT_DESCRIPTION}"
        MDFILE ../README.md
        OUTPUT_DIR ${CMAKE_BUILD_SHARE_DIR}/doc/${QWINDOWKIT_INSTALL_NAME}
        INPUT QWINDOWKIT
        TARGETS ${_doc_targets}
        DEPENDS ${_doc_targets}
        NO_EXPAND_MACROS Q_OBJECT Q_GADGET Q_DECLARE_TR_FUNCTIONS
        COMPILE_DEFINITIONS Q_SIGNALS=Q_SIGNALS Q_SLOTS=Q_SLOTS
        GENERATE_TAGFILE "${QWINDOWKIT_DOXYGEN_TAGFILE}"
        ${_install_options}
    )
endif()
# ----------------------------------
# Install
# ----------------------------------
if(QWINDOWKIT_INSTALL)
    # Add install target
    set(_install_dir ${CMAKE_INSTALL_LIBDIR}/cmake/${QWINDOWKIT_INSTALL_NAME})
    # Add version file
    write_basic_package_version_file(
        "${CMAKE_CURRENT_BINARY_DIR}/${QWINDOWKIT_INSTALL_NAME}ConfigVersion.cmake"
        VERSION ${PROJECT_VERSION}
        COMPATIBILITY AnyNewerVersion
    )
    # Add configuration file
    configure_package_config_file(
        ${CMAKE_CURRENT_LIST_DIR}/${QWINDOWKIT_INSTALL_NAME}Config.cmake.in
        "${CMAKE_CURRENT_BINARY_DIR}/${QWINDOWKIT_INSTALL_NAME}Config.cmake"
        INSTALL_DESTINATION ${_install_dir}
        NO_CHECK_REQUIRED_COMPONENTS_MACRO
    )
    # Install cmake files
    install(FILES
        "${CMAKE_CURRENT_BINARY_DIR}/${QWINDOWKIT_INSTALL_NAME}Config.cmake"
        "${CMAKE_CURRENT_BINARY_DIR}/${QWINDOWKIT_INSTALL_NAME}ConfigVersion.cmake"
        DESTINATION ${_install_dir}
    )
    # Install cmake targets files
    install(EXPORT ${QWINDOWKIT_INSTALL_NAME}Targets
        FILE "${QWINDOWKIT_INSTALL_NAME}Targets.cmake"
        NAMESPACE ${QWINDOWKIT_INSTALL_NAME}::
        DESTINATION ${_install_dir}
    )
    # Install shared files
    install(DIRECTORY ../share/
        DESTINATION share/${QWINDOWKIT_INSTALL_NAME}
    )
endif()
src/QWindowKitConfig.cmake.in
New file
@@ -0,0 +1,5 @@
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
include("${CMAKE_CURRENT_LIST_DIR}/substateTargets.cmake")
src/core/CMakeLists.txt
New file
@@ -0,0 +1,47 @@
project(QWKCore
    VERSION ${QWINDOWKIT_VERSION}
    LANGUAGES CXX
)
set(_src
    qwkcoreglobal.h
    corewindowagent.h
    corewindowagent_p.h
    corewindowagent.cpp
    windowitemdelegate.h
    handler/abstractwindowcontext_p.h
    handler/abstractwindowcontext.cpp
)
if(WIN32)
    list(APPEND _src
        qwindowkit_windows.h
        handler/win32windowcontext_p.h
        handler/win32windowcontext.cpp
    )
else()
    list(APPEND _src
        handler/qtwindowcontext_p.h
        handler/qtwindowcontext.cpp
    )
    if(APPLE)
        # add files
    else()
        list(APPEND _src
            qwindowkit_linux.h
        )
    endif()
endif()
qwk_add_library(${PROJECT_NAME} AUTOGEN
    SOURCES ${_src}
    LINKS
    QT_LINKS Core Gui
    QT_INCLUDE_PRIVATE Core Gui
    PREFIX QWK_CORE
)
set_target_properties(${PROJECT_NAME} PROPERTIES
    CXX_STANDARD 17
    CXX_STANDARD_REQUIRED TRUE
)
src/core/corewindowagent.cpp
New file
@@ -0,0 +1,72 @@
#include "corewindowagent.h"
#include "corewindowagent_p.h"
#ifdef Q_OS_WINDOWS
#  include "handler/win32windowcontext_p.h"
#else
#  include "handler/qtwindowcontext_p.h"
#endif
namespace QWK {
    CoreWindowAgentPrivate::CoreWindowAgentPrivate() {
    }
    CoreWindowAgentPrivate::~CoreWindowAgentPrivate() {
    }
    void CoreWindowAgentPrivate::init() {
    }
    void CoreWindowAgentPrivate::setup(QWindow *window, WindowItemDelegate *delegate) {
#ifdef Q_OS_WINDOWS
        m_eventHandler = new Win32WindowContext(window, delegate);
#else
        m_eventHandler = new QtWindowContext(window, delegate);
#endif
    }
    CoreWindowAgent::~CoreWindowAgent() {
    }
    void CoreWindowAgent::showSystemMenu(const QPoint &pos) {
        Q_D(CoreWindowAgent);
        d->m_eventHandler->showSystemMenu(pos);
    }
    void CoreWindowAgent::startSystemMove(const QPoint &pos) {
        Q_D(CoreWindowAgent);
        auto win = d->m_eventHandler->window();
        if (!win) {
            return;
        }
        Q_UNUSED(pos)
        win->startSystemMove();
    }
    void CoreWindowAgent::startSystemResize(Qt::Edges edges, const QPoint &pos) {
        Q_D(CoreWindowAgent);
        auto win = d->m_eventHandler->window();
        if (!win) {
            return;
        }
        Q_UNUSED(pos)
        win->startSystemResize(edges);
    }
    void CoreWindowAgent::centralize() {
    }
    void CoreWindowAgent::raise() {
    }
    CoreWindowAgent::CoreWindowAgent(CoreWindowAgentPrivate &d, QObject *parent)
        : QObject(parent), d_ptr(&d) {
        d.q_ptr = this;
        d.init();
    }
}
src/core/corewindowagent.h
New file
@@ -0,0 +1,43 @@
#ifndef COREWINDOWAGENT_H
#define COREWINDOWAGENT_H
#include <QtCore/QObject>
#include <QWKCore/qwkcoreglobal.h>
namespace QWK {
    class CoreWindowAgentPrivate;
    class QWK_CORE_EXPORT CoreWindowAgent : public QObject {
        Q_OBJECT
        Q_DECLARE_PRIVATE(CoreWindowAgent)
    public:
        ~CoreWindowAgent();
        enum SystemButton {
            Unknown,
            WindowIcon,
            Help,
            Minimize,
            Maximize,
            Close,
            NumSystemButton,
        };
    public Q_SLOTS:
        void showSystemMenu(const QPoint &pos);
        void startSystemMove(const QPoint &pos);
        void startSystemResize(Qt::Edges edges, const QPoint &pos);
        void centralize();
        void raise();
    protected:
        CoreWindowAgent(CoreWindowAgentPrivate &d, QObject *parent = nullptr);
        QScopedPointer<CoreWindowAgentPrivate> d_ptr;
    };
}
#endif // COREWINDOWAGENT_H
src/core/corewindowagent_p.h
New file
@@ -0,0 +1,26 @@
#ifndef COREWINDOWAGENTPRIVATE_H
#define COREWINDOWAGENTPRIVATE_H
#include <QWKCore/corewindowagent.h>
#include <QWKCore/private/abstractwindowcontext_p.h>
namespace QWK {
    class QWK_CORE_EXPORT CoreWindowAgentPrivate {
        Q_DECLARE_PUBLIC(CoreWindowAgent)
    public:
        CoreWindowAgentPrivate();
        virtual ~CoreWindowAgentPrivate();
        void init();
        CoreWindowAgent *q_ptr; // no need to initialize
        void setup(QWindow *window, WindowItemDelegate *delegate);
        AbstractWindowContext *m_eventHandler{};
    };
}
#endif // COREWINDOWAGENTPRIVATE_H
src/core/handler/abstractwindowcontext.cpp
New file
@@ -0,0 +1,73 @@
#include "abstractwindowcontext_p.h"
namespace QWK {
    AbstractWindowContext::~AbstractWindowContext() {
        delete m_delegate;
    }
    void AbstractWindowContext::setupWindow(QWindow *window) {
        m_windowHandle = window;
    }
    bool AbstractWindowContext::setHitTestVisible(QObject *obj, bool visible) {
        Q_ASSERT(obj);
        if (!obj) {
            return false;
        }
        if (visible) {
            m_hitTestVisibleItems.insert(obj);
        } else {
            m_hitTestVisibleItems.remove(obj);
        }
        return true;
    }
    bool AbstractWindowContext::setHitTestVisible(const QRect &rect, bool visible) {
        Q_ASSERT(rect.isValid());
        if (!rect.isValid()) {
            return false;
        }
        if (visible) {
            m_hitTestVisibleRects.append(rect);
        } else {
            m_hitTestVisibleRects.removeAll(rect);
        }
        return true;
    }
    bool AbstractWindowContext::setSystemButton(CoreWindowAgent::SystemButton button,
                                                     QObject *obj) {
        Q_ASSERT(obj);
        Q_ASSERT(button != CoreWindowAgent::Unknown);
        if (!obj || (button == CoreWindowAgent::Unknown)) {
            return false;
        }
        if (m_systemButtons[button] == obj) {
            return false;
        }
        m_systemButtons[button] = obj;
        return true;
    }
    bool AbstractWindowContext::setTitleBar(QObject *item) {
        Q_ASSERT(item);
        if (!item) {
            return false;
        }
        if (m_titleBar == item) {
            return false;
        }
        m_titleBar = item;
        return true;
    }
    void AbstractWindowContext::showSystemMenu(const QPoint &pos) {
        // ?
    }
}
src/core/handler/abstractwindowcontext_p.h
New file
@@ -0,0 +1,70 @@
#ifndef ABSTRACTWINDOWCONTEXT_P_H
#define ABSTRACTWINDOWCONTEXT_P_H
#include <QtCore/QSet>
#include <QtGui/QWindow>
#include <QtGui/QPolygon>
#include <QWKCore/corewindowagent.h>
#include <QWKCore/windowitemdelegate.h>
namespace QWK {
    class QWK_CORE_EXPORT AbstractWindowContext : public QObject {
        Q_OBJECT
    public:
        inline AbstractWindowContext(QWindow *window, WindowItemDelegate *delegate)
            : m_windowHandle(window), m_delegate(delegate) {
        }
        ~AbstractWindowContext();
    public:
        inline QWindow *window() const;
        void setupWindow(QWindow *window);
        inline bool isHitTestVisible(QObject *obj) const;
        bool setHitTestVisible(QObject *obj, bool visible);
        bool setHitTestVisible(const QRect &rect, bool visible);
        inline QObject *systemButton(CoreWindowAgent::SystemButton button) const;
        bool setSystemButton(CoreWindowAgent::SystemButton button, QObject *obj);
        inline QObject *titleBar() const;
        bool setTitleBar(QObject *obj);
        void showSystemMenu(const QPoint &pos);
    protected:
        QWindow *m_windowHandle;
        WindowItemDelegate *m_delegate;
        QSet<QObject *> m_hitTestVisibleItems;
        QList<QRect> m_hitTestVisibleRects;
        QObject *m_titleBar{};
        QObject *m_systemButtons[CoreWindowAgent::NumSystemButton]{};
        mutable bool hitTestVisibleShapeDirty{};
        mutable QPolygon hitTestVisibleShape;
    };
    inline QWindow *AbstractWindowContext::window() const {
        return m_windowHandle;
    }
    inline bool AbstractWindowContext::isHitTestVisible(QObject *obj) const {
        return m_hitTestVisibleItems.contains(obj);
    }
    inline QObject *
        AbstractWindowContext::systemButton(CoreWindowAgent::SystemButton button) const {
        return m_systemButtons[button];
    }
    inline QObject *AbstractWindowContext::titleBar() const {
        return m_titleBar;
    }
}
#endif // ABSTRACTWINDOWCONTEXT_P_H
src/core/handler/qtwindowcontext.cpp
New file
@@ -0,0 +1,12 @@
#include "qtwindowcontext_p.h"
namespace QWK {
    QtWindowContext::QtWindowContext(QWindow *window, WindowItemDelegate *delegate)
        : AbstractWindowContext(window, delegate) {
    }
    QtWindowContext::~QtWindowContext() {
    }
}
src/core/handler/qtwindowcontext_p.h
New file
@@ -0,0 +1,17 @@
#ifndef QTWINDOWCONTEXT_P_H
#define QTWINDOWCONTEXT_P_H
#include <QWKCore/private/abstractwindowcontext_p.h>
namespace QWK {
    class QWK_CORE_EXPORT QtWindowContext : public AbstractWindowContext {
        Q_OBJECT
    public:
        QtWindowContext(QWindow *window, WindowItemDelegate *delegate);
        ~QtWindowContext();
    };
}
#endif // QTWINDOWCONTEXT_P_H
src/core/handler/win32windowcontext.cpp
New file
@@ -0,0 +1,22 @@
#include "win32windowcontext_p.h"
#include <windows.h>
namespace QWK {
    static LRESULT CALLBACK QWKWindowsWndProc(const HWND hWnd, const UINT uMsg, const WPARAM wParam,
                                              const LPARAM lParam) {
        // Implement
        return 0;
    }
    Win32WindowContext::Win32WindowContext(QWindow *window,
                                                     WindowItemDelegate *delegate)
        : AbstractWindowContext(window, delegate) {
        // Install windows hook
    }
    Win32WindowContext::~Win32WindowContext() {
    }
}
src/core/handler/win32windowcontext_p.h
New file
@@ -0,0 +1,17 @@
#ifndef WIN32WINDOWCONTEXT_P_H
#define WIN32WINDOWCONTEXT_P_H
#include <QWKCore/private/abstractwindowcontext_p.h>
namespace QWK {
    class QWK_CORE_EXPORT Win32WindowContext : public AbstractWindowContext {
        Q_OBJECT
    public:
        Win32WindowContext(QWindow *window, WindowItemDelegate *delegate);
        ~Win32WindowContext();
    };
}
#endif // WIN32WINDOWCONTEXT_P_H
src/core/qwindowkit_linux.h
New file
@@ -0,0 +1,5 @@
#ifndef QWINDOWKIT_LINUX_H
#define QWINDOWKIT_LINUX_H
#endif // QWINDOWKIT_LINUX_H
src/core/qwindowkit_windows.h
New file
@@ -0,0 +1,5 @@
#ifndef QWINDOWKIT_WINDOWS_H
#define QWINDOWKIT_WINDOWS_H
#endif // QWINDOWKIT_WINDOWS_H
src/core/qwkcoreglobal.h
New file
@@ -0,0 +1,18 @@
#ifndef QWKCOREGLOBAL_H
#define QWKCOREGLOBAL_H
#include <QtGlobal>
#ifndef QWK_CORE_EXPORT
#  ifdef QWK_CORE_STATIC
#    define QWK_CORE_EXPORT
#  else
#    ifdef QWK_CORE_LIBRARY
#      define QWK_CORE_EXPORT Q_DECL_EXPORT
#    else
#      define QWK_CORE_EXPORT Q_DECL_IMPORT
#    endif
#  endif
#endif
#endif // QWKCOREGLOBAL_H
src/core/windowitemdelegate.h
New file
@@ -0,0 +1,24 @@
#ifndef WINDOWITEMDELEGATE_H
#define WINDOWITEMDELEGATE_H
#include <QtCore/QObject>
#include <QtGui/QWindow>
#include <QWKCore/qwkcoreglobal.h>
namespace QWK {
    class WindowItemDelegate {
    public:
        virtual ~WindowItemDelegate() = default;
    public:
        virtual QWindow *window(QObject *obj) const = 0;
        virtual bool isEnabled(QObject *obj) const = 0;
        virtual bool isVisible(QObject *obj) const = 0;
    };
}
#endif // WINDOWITEMDELEGATE_H
src/quick/CMakeLists.txt
New file
@@ -0,0 +1,26 @@
project(QWKQuick
    VERSION ${QWINDOWKIT_VERSION}
    LANGUAGES CXX
)
set(_src
    qwkquickglobal.h
    quickitemdelegate_p.h
    quickitemdelegate.cpp
    quickwindowagent.h
    quickwindowagent_p.h
    quickwindowagent.cpp
)
qwk_add_library(${PROJECT_NAME} AUTOGEN
    SOURCES ${_src}
    LINKS QWKCore
    QT_LINKS Core Quick
    QT_INCLUDE_PRIVATE Core Quick
    PREFIX QWK_QUICK
)
set_target_properties(${PROJECT_NAME} PROPERTIES
    CXX_STANDARD 17
    CXX_STANDARD_REQUIRED TRUE
)
src/quick/quickitemdelegate.cpp
New file
@@ -0,0 +1,26 @@
#include "quickitemdelegate_p.h"
#include <QtQuick/QQuickItem>
#include <QtQuick/QQuickWindow>
namespace QWK {
    QuickItemDelegate::QuickItemDelegate() {
    }
    QuickItemDelegate::~QuickItemDelegate() {
    }
    QWindow *QuickItemDelegate::window(QObject *obj) const {
        return static_cast<QQuickItem *>(obj)->window();
    }
    bool QuickItemDelegate::isEnabled(QObject *obj) const {
        return static_cast<QQuickItem *>(obj)->isEnabled();
    }
    bool QuickItemDelegate::isVisible(QObject *obj) const {
        return static_cast<QQuickItem *>(obj)->isVisible();
    }
}
src/quick/quickitemdelegate_p.h
New file
@@ -0,0 +1,26 @@
#ifndef QUICKITEMDELEGATE_P_H
#define QUICKITEMDELEGATE_P_H
#include <QtCore/QObject>
#include <QtGui/QWindow>
#include <QWKCore/windowitemdelegate.h>
#include <QWKQuick/qwkquickglobal.h>
namespace QWK {
    class QWK_QUICK_EXPORT QuickItemDelegate : public WindowItemDelegate {
    public:
        QuickItemDelegate();
        ~QuickItemDelegate();
    public:
        QWindow *window(QObject *obj) const override;
        bool isEnabled(QObject *obj) const override;
        bool isVisible(QObject *obj) const override;
    };
}
#endif // QUICKITEMDELEGATE_P_H
src/quick/quickwindowagent.cpp
New file
@@ -0,0 +1,86 @@
#include "quickwindowagent.h"
#include "quickwindowagent_p.h"
#include "quickitemdelegate_p.h"
#include <QtQuick/QQuickWindow>
namespace QWK {
    QuickWindowAgentPrivate::QuickWindowAgentPrivate() {
    }
    QuickWindowAgentPrivate::~QuickWindowAgentPrivate() {
    }
    void QuickWindowAgentPrivate::init() {
    }
    QuickWindowAgent::QuickWindowAgent(QObject *parent)
        : QuickWindowAgent(*new QuickWindowAgentPrivate(), parent) {
    }
    QuickWindowAgent::~QuickWindowAgent() {
    }
    void QuickWindowAgent::setup(QQuickWindow *window) {
        Q_ASSERT(window);
        if (!window) {
            return;
        }
        Q_D(QuickWindowAgent);
        if (d->host) {
            return;
        }
        d->host = window;
        d->setup(window, new QuickItemDelegate());
    }
    bool QuickWindowAgent::isHitTestVisible(QQuickItem *item) const {
        Q_D(const QuickWindowAgent);
        return d->m_eventHandler->isHitTestVisible(item);
    }
    void QuickWindowAgent::setHitTestVisible(QQuickItem *item, bool visible) {
        Q_D(QuickWindowAgent);
        d->m_eventHandler->setHitTestVisible(item, visible);
    }
    void QuickWindowAgent::setHitTestVisible(const QRect &rect, bool visible) {
        Q_D(QuickWindowAgent);
        d->m_eventHandler->setHitTestVisible(rect, visible);
    }
    QQuickItem *QuickWindowAgent::systemButton(SystemButton button) const {
        Q_D(const QuickWindowAgent);
        return static_cast<QQuickItem *>(d->m_eventHandler->systemButton(button));
    }
    void QuickWindowAgent::setSystemButton(SystemButton button, QQuickItem *item) {
        Q_D(QuickWindowAgent);
        if (!d->m_eventHandler->setSystemButton(button, item)) {
            return;
        }
        Q_EMIT systemButtonChanged(button, item);
    }
    QQuickItem *QuickWindowAgent::titleBar() const {
        Q_D(const QuickWindowAgent);
        return static_cast<QQuickItem *>(d->m_eventHandler->titleBar());
    }
    void QuickWindowAgent::setTitleBar(QQuickItem *item) {
        Q_D(QuickWindowAgent);
        if (!d->m_eventHandler->setTitleBar(item)) {
            return;
        }
        Q_EMIT titleBarWidgetChanged(item);
    }
    QuickWindowAgent::QuickWindowAgent(QuickWindowAgentPrivate &d, QObject *parent)
        : CoreWindowAgent(d, parent) {
        d.init();
    }
}
src/quick/quickwindowagent.h
New file
@@ -0,0 +1,44 @@
#ifndef QUICKWINDOWAGENT_H
#define QUICKWINDOWAGENT_H
#include <QtQuick/QQuickItem>
#include <QtQuick/QQuickWindow>
#include <QWKCore/corewindowagent.h>
#include <QWKQuick/qwkquickglobal.h>
namespace QWK {
    class QuickWindowAgentPrivate;
    class QWK_QUICK_EXPORT QuickWindowAgent : public CoreWindowAgent {
        Q_OBJECT
        Q_DECLARE_PRIVATE(QuickWindowAgent)
    public:
        explicit QuickWindowAgent(QObject *parent = nullptr);
        ~QuickWindowAgent();
    public:
        void setup(QQuickWindow *window);
        bool isHitTestVisible(QQuickItem *item) const;
        void setHitTestVisible(QQuickItem *item, bool visible);
        void setHitTestVisible(const QRect &rect, bool visible);
        QQuickItem *systemButton(SystemButton button) const;
        void setSystemButton(SystemButton button, QQuickItem *item);
        QQuickItem *titleBar() const;
        void setTitleBar(QQuickItem *item);
    Q_SIGNALS:
        void titleBarWidgetChanged(QQuickItem *item);
        void systemButtonChanged(SystemButton button, QQuickItem *item);
    protected:
        QuickWindowAgent(QuickWindowAgentPrivate &d, QObject *parent = nullptr);
    };
}
#endif // QUICKWINDOWAGENT_H
src/quick/quickwindowagent_p.h
New file
@@ -0,0 +1,23 @@
#ifndef QUICKWINDOWAGENTPRIVATE_H
#define QUICKWINDOWAGENTPRIVATE_H
#include <QWKCore/private/corewindowagent_p.h>
#include <QWKQuick/quickwindowagent.h>
namespace QWK {
    class QuickWindowAgentPrivate : public CoreWindowAgentPrivate {
        Q_DECLARE_PUBLIC(QuickWindowAgent)
    public:
        QuickWindowAgentPrivate();
        ~QuickWindowAgentPrivate();
        void init();
        // Host
        QQuickWindow *host{};
    };
}
#endif // QUICKWINDOWAGENTPRIVATE_H
src/quick/qwkquickglobal.h
New file
@@ -0,0 +1,18 @@
#ifndef QWKQUICKGLOBAL_H
#define QWKQUICKGLOBAL_H
#include <QtGlobal>
#ifndef QWK_QUICK_EXPORT
#  ifdef QWK_QUICK_STATIC
#    define QWK_QUICK_EXPORT
#  else
#    ifdef QWK_QUICK_LIBRARY
#      define QWK_QUICK_EXPORT Q_DECL_EXPORT
#    else
#      define QWK_QUICK_EXPORT Q_DECL_IMPORT
#    endif
#  endif
#endif
#endif // QWKQUICKGLOBAL_H
src/widgets/CMakeLists.txt
New file
@@ -0,0 +1,26 @@
project(QWKWidgets
    VERSION ${QWINDOWKIT_VERSION}
    LANGUAGES CXX
)
set(_src
    qwkwidgetsglobal.h
    widgetitemdelegate_p.h
    widgetitemdelegate.cpp
    widgetwindowagent.h
    widgetwindowagent_p.h
    widgetwindowagent.cpp
)
qwk_add_library(${PROJECT_NAME} AUTOGEN
    SOURCES ${_src}
    LINKS QWKCore
    QT_LINKS Core Gui Widgets
    QT_INCLUDE_PRIVATE Core Gui Widgets
    PREFIX QWK_WIDGETS
)
set_target_properties(${PROJECT_NAME} PROPERTIES
    CXX_STANDARD 17
    CXX_STANDARD_REQUIRED TRUE
)
src/widgets/qwkwidgetsglobal.h
New file
@@ -0,0 +1,18 @@
#ifndef QWKWIDGETSGLOBAL_H
#define QWKWIDGETSGLOBAL_H
#include <QtGlobal>
#ifndef QWK_WIDGETS_EXPORT
#  ifdef QWK_WIDGETS_STATIC
#    define QWK_WIDGETS_EXPORT
#  else
#    ifdef QWK_WIDGETS_LIBRARY
#      define QWK_WIDGETS_EXPORT Q_DECL_EXPORT
#    else
#      define QWK_WIDGETS_EXPORT Q_DECL_IMPORT
#    endif
#  endif
#endif
#endif // QWKWIDGETSGLOBAL_H
src/widgets/widgetitemdelegate.cpp
New file
@@ -0,0 +1,25 @@
#include "widgetitemdelegate_p.h"
#include <QtWidgets/QWidget>
namespace QWK {
    WidgetItemDelegate::WidgetItemDelegate() {
    }
    WidgetItemDelegate::~WidgetItemDelegate() {
    }
    QWindow *WidgetItemDelegate::window(QObject *obj) const {
        return static_cast<QWidget *>(obj)->windowHandle();
    }
    bool WidgetItemDelegate::isEnabled(QObject *obj) const {
        return static_cast<QWidget *>(obj)->isEnabled();
    }
    bool WidgetItemDelegate::isVisible(QObject *obj) const {
        return static_cast<QWidget *>(obj)->isVisible();
    }
}
src/widgets/widgetitemdelegate_p.h
New file
@@ -0,0 +1,26 @@
#ifndef WIDGETITEMDELEGATE_P_H
#define WIDGETITEMDELEGATE_P_H
#include <QtCore/QObject>
#include <QtGui/QWindow>
#include <QWKCore/windowitemdelegate.h>
#include <QWKWidgets/qwkwidgetsglobal.h>
namespace QWK {
    class QWK_WIDGETS_EXPORT WidgetItemDelegate : public WindowItemDelegate {
    public:
        WidgetItemDelegate();
        ~WidgetItemDelegate();
    public:
        QWindow *window(QObject *obj) const override;
        bool isEnabled(QObject *obj) const override;
        bool isVisible(QObject *obj) const override;
    };
}
#endif // WIDGETITEMDELEGATE_P_H
src/widgets/widgetwindowagent.cpp
New file
@@ -0,0 +1,85 @@
#include "widgetwindowagent.h"
#include "widgetwindowagent_p.h"
#include "widgetitemdelegate_p.h"
namespace QWK {
    WidgetWindowAgentPrivate::WidgetWindowAgentPrivate() {
    }
    WidgetWindowAgentPrivate::~WidgetWindowAgentPrivate() {
    }
    void WidgetWindowAgentPrivate::init() {
    }
    WidgetWindowAgent::WidgetWindowAgent(QObject *parent)
        : WidgetWindowAgent(*new WidgetWindowAgentPrivate(), parent) {
    }
    WidgetWindowAgent::~WidgetWindowAgent() {
    }
    void WidgetWindowAgent::setup(QWidget *w) {
        Q_ASSERT(w);
        if (!w) {
            return;
        }
        Q_D(WidgetWindowAgent);
        if (d->host) {
            return;
        }
        d->host = w;
        std::ignore = w->winId(); // Make sure the window handle is created
        d->setup(w->windowHandle(), new WidgetItemDelegate());
    }
    bool WidgetWindowAgent::isHitTestVisible(QWidget *w) const {
        Q_D(const WidgetWindowAgent);
        return d->m_eventHandler->isHitTestVisible(w);
    }
    void WidgetWindowAgent::setHitTestVisible(QWidget *w, bool visible) {
        Q_D(WidgetWindowAgent);
        d->m_eventHandler->setHitTestVisible(w, visible);
    }
    void WidgetWindowAgent::setHitTestVisible(const QRect &rect, bool visible) {
        Q_D(WidgetWindowAgent);
        d->m_eventHandler->setHitTestVisible(rect, visible);
    }
    QWidget *WidgetWindowAgent::systemButton(CoreWindowAgent::SystemButton button) const {
        Q_D(const WidgetWindowAgent);
        return static_cast<QWidget *>(d->m_eventHandler->systemButton(button));
    }
    void WidgetWindowAgent::setSystemButton(CoreWindowAgent::SystemButton button, QWidget *w) {
        Q_D(WidgetWindowAgent);
        if (!d->m_eventHandler->setSystemButton(button, w)) {
            return;
        }
        Q_EMIT systemButtonChanged(button, w);
    }
    QWidget *WidgetWindowAgent::titleBar() const {
        Q_D(const WidgetWindowAgent);
        return static_cast<QWidget *>(d->m_eventHandler->titleBar());
    }
    void WidgetWindowAgent::setTitleBar(QWidget *w) {
        Q_D(WidgetWindowAgent);
        if (!d->m_eventHandler->setTitleBar(w)) {
            return;
        }
        Q_EMIT titleBarWidgetChanged(w);
    }
    WidgetWindowAgent::WidgetWindowAgent(WidgetWindowAgentPrivate &d, QObject *parent)
        : CoreWindowAgent(d, parent) {
        d.init();
    }
}
src/widgets/widgetwindowagent.h
New file
@@ -0,0 +1,43 @@
#ifndef WIDGETWINDOWAGENT_H
#define WIDGETWINDOWAGENT_H
#include <QtWidgets/QWidget>
#include <QWKCore/corewindowagent.h>
#include <QWKWidgets/qwkwidgetsglobal.h>
namespace QWK {
    class WidgetWindowAgentPrivate;
    class QWK_WIDGETS_EXPORT WidgetWindowAgent : public CoreWindowAgent {
        Q_OBJECT
        Q_DECLARE_PRIVATE(WidgetWindowAgent)
    public:
        explicit WidgetWindowAgent(QObject *parent = nullptr);
        ~WidgetWindowAgent();
    public:
        void setup(QWidget *w);
        bool isHitTestVisible(QWidget *w) const;
        void setHitTestVisible(QWidget *w, bool visible);
        void setHitTestVisible(const QRect &rect, bool visible);
        QWidget *systemButton(SystemButton button) const;
        void setSystemButton(SystemButton button, QWidget *w);
        QWidget *titleBar() const;
        void setTitleBar(QWidget *w);
    Q_SIGNALS:
        void titleBarWidgetChanged(QWidget *w);
        void systemButtonChanged(SystemButton button, QWidget *w);
    protected:
        WidgetWindowAgent(WidgetWindowAgentPrivate &d, QObject *parent = nullptr);
    };
}
#endif // WIDGETWINDOWAGENT_H
src/widgets/widgetwindowagent_p.h
New file
@@ -0,0 +1,23 @@
#ifndef WIDGETWINDOWAGENTPRIVATE_H
#define WIDGETWINDOWAGENTPRIVATE_H
#include <QWKCore/private/corewindowagent_p.h>
#include <QWKWidgets/widgetwindowagent.h>
namespace QWK {
    class WidgetWindowAgentPrivate : public CoreWindowAgentPrivate {
        Q_DECLARE_PUBLIC(WidgetWindowAgent)
    public:
        WidgetWindowAgentPrivate();
        ~WidgetWindowAgentPrivate();
        void init();
        // Host
        QWidget *host{};
    };
}
#endif // WIDGETWINDOWAGENTPRIVATE_H