├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ ├── bug-report-template-🐞.md │ ├── bug-报告模板-🐞.md │ ├── new-feature-suggestion-🐚.md │ └── 新功能建议-🐚.md ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.html ├── README.md ├── assets ├── assets.qrc ├── fonts │ └── HarmonyOS_Sans_SC │ │ ├── HarmonyOS_Sans_SC_Regular.ttf │ │ └── LICENSE ├── qss │ ├── dark-style.qss │ ├── light-style.qss │ └── modules │ │ ├── dark-mouseclickpage.qss │ │ ├── dark-settingspage.qss │ │ ├── light-mouseclickpage.qss │ │ ├── light-settingspage.qss │ │ └── messagebox.qss └── svg │ ├── close-black.svg │ ├── close-white.svg │ ├── down-line-black.svg │ ├── down-line-gray.svg │ ├── down-line-light-gray.svg │ ├── down-line-white.svg │ ├── favicon.svg │ ├── maximize-black.svg │ ├── maximize-blue.svg │ ├── maximize-white.svg │ ├── minimize-black.svg │ ├── minimize-blue.svg │ ├── minimize-white.svg │ ├── mouse-click-item-black.svg │ ├── mouse-click-item-white.svg │ ├── mouse-left.svg │ ├── mouse-middle.svg │ ├── mouse-right.svg │ ├── restore-black.svg │ ├── restore-blue.svg │ ├── restore-white.svg │ ├── settings-item-black.svg │ ├── settings-item-white.svg │ ├── toggle-left-line-gray.svg │ ├── toggle-left-line-light-gray.svg │ ├── toggle-right-fill-blue.svg │ ├── toggle-right-fill-light-blue.svg │ ├── up-line-black.svg │ ├── up-line-gray.svg │ ├── up-line-light-gray.svg │ └── up-line-white.svg ├── deps ├── qhotkey │ ├── LICENSE │ ├── include │ │ ├── QHotkey │ │ └── qhotkey.h │ └── lib │ │ ├── cmake │ │ └── QHotkey │ │ │ ├── QHotkeyConfig-noconfig.cmake │ │ │ ├── QHotkeyConfig.cmake │ │ │ └── QHotkeyConfigVersion.cmake │ │ └── libqhotkey.a └── qwindowkit │ ├── LICENSE │ ├── bin │ ├── QWKCore.dll │ └── QWKWidgets.dll │ ├── include │ └── QWindowKit │ │ ├── QWKCore │ │ ├── private │ │ │ ├── abstractwindowcontext_p.h │ │ │ ├── cocoawindowcontext_p.h │ │ │ ├── nativeeventfilter_p.h │ │ │ ├── qtwindowcontext_p.h │ │ │ ├── qwkglobal_p.h │ │ │ ├── qwkwindowsextra_p.h │ │ │ ├── sharedeventfilter_p.h │ │ │ ├── styleagent_p.h │ │ │ ├── systemwindow_p.h │ │ │ ├── win32windowcontext_p.h │ │ │ ├── windowagentbase_p.h │ │ │ ├── windowitemdelegate_p.h │ │ │ ├── windows10borderhandler_p.h │ │ │ └── winidchangeeventfilter_p.h │ │ ├── qwindowkit_linux.h │ │ ├── qwindowkit_windows.h │ │ ├── qwkconfig.h │ │ ├── qwkglobal.h │ │ ├── styleagent.h │ │ └── windowagentbase.h │ │ └── QWKWidgets │ │ ├── private │ │ ├── widgetitemdelegate_p.h │ │ └── widgetwindowagent_p.h │ │ ├── qwkwidgetsglobal.h │ │ └── widgetwindowagent.h │ ├── lib │ ├── cmake │ │ └── QWindowKit │ │ │ ├── QWindowKitConfig.cmake │ │ │ ├── QWindowKitConfigVersion.cmake │ │ │ ├── QWindowKitTargets-debug.cmake │ │ │ ├── QWindowKitTargets-release.cmake │ │ │ └── QWindowKitTargets.cmake │ ├── libQWKCore.dll.a │ └── libQWKWidgets.dll.a │ └── share │ └── QWindowKit │ └── qmake │ ├── QWKCore.pri │ ├── QWKQuick.pri │ └── QWKWidgets.pri ├── docs ├── SeaEpoch_2024-10-22_09-51-39.jpg └── screenshots │ ├── SeaEpoch_2024-05-28_22-44-45.jpg │ ├── SeaEpoch_2024-07-25_16-52-41.jpg │ ├── SeaEpoch_2024-08-07_17-29-15.jpg │ ├── SeaEpoch_2024-10-10_15-56-05.jpg │ ├── SeaEpoch_2024-10-10_16-04-27.jpg │ ├── SeaEpoch_2024-10-10_17-41-01.jpg │ ├── SeaEpoch_2024-10-10_17-42-32.jpg │ ├── SeaEpoch_2024-12-24_22-35-32.jpg │ ├── SeaEpoch_2024-12-24_22-36-07.jpg │ ├── SeaEpoch_2024-12-24_22-36-48.jpg │ └── SeaEpoch_2024-12-24_22-37-07.jpg ├── i18n ├── MouseClick_en_US.ts ├── MouseClick_zh_CN.ts └── MouseClick_zh_TW.ts └── src ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── modules ├── hotkeylineedit.cpp ├── hotkeylineedit.h ├── messagebox.cpp ├── messagebox.h ├── nav_pages │ ├── mouseclickpage.cpp │ ├── mouseclickpage.h │ ├── navpage.cpp │ ├── navpage.h │ ├── settingspage.cpp │ └── settingspage.h ├── settingsagent.cpp ├── settingsagent.h ├── shared.cpp └── shared.h ├── qwk_window_bar ├── private │ ├── windowbar_p.h │ └── windowbutton_p.h ├── windowbar.cpp ├── windowbar.h ├── windowbutton.cpp └── windowbutton.h └── utils ├── clicker.cpp └── clicker.h /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | polar: # Replace with a single Polar username 13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username 14 | thanks_dev: # Replace with a single thanks.dev username 15 | custom: ['https://www.seayj.cn/coffeecompa'] 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report-template-🐞.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Bug Report Template \U0001F41E" 3 | about: Write a bug report that allows developers to quickly reproduce and fix the problem. 4 | title: "[BUG]" 5 | labels: bug 6 | assignees: SeaYJ 7 | 8 | --- 9 | 10 | ### Describe the problem 11 | Describe clearly and concisely what the problem is. 12 | Example: After clicking the "Submit" button, the page freezes and does not jump to the expected page. 13 | 14 | ### Steps to reproduce 15 | Detailed steps are provided to reproduce the issue. 16 | 1. Open the page: [a page]. 17 | 2. Click on the "Some" button. 18 | 3. Wait for the page to load. 19 | 4. The page is not responding and is blank. 20 | 21 | ### Expected behavior 22 | Describe the correct behavior you expect. 23 | For example, when you click the "Some" button, you will be redirected to the corresponding page. 24 | 25 | ### Actual behavior 26 | Describe what actually went wrong. 27 | Example: The page is stuck and the software is unresponsive. 28 | 29 | ### Environmental information 30 | Provides information about the runtime environment so that developers can diagnose problems. 31 | - Operating System: [e.g. Windows 10, macOS Ventura, Ubuntu 20.4] 32 | - Software version: [e.g. 1.2.3] 33 | - Network Environment: [e.g. WiFi / Mobile Network] 34 | -other 35 | 36 | ### Additional Information (Recommended) 37 | Other information that can help diagnose the problem. 38 | - Relevant screenshots or screen recordings (if possible). 39 | - Whether there is an error message (if so, attach an error log or screenshot). 40 | - Whether there are special operating procedures or environmental requirements. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-报告模板-🐞.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Bug 报告模板 \U0001F41E" 3 | about: 编写一个 bug 报告,让开发人员能够快速重现和修复问题。 4 | title: "[BUG]" 5 | labels: bug 6 | assignees: SeaYJ 7 | 8 | --- 9 | 10 | ### 描述问题 11 | 清晰简明地描述问题是什么。 12 | 例:点击“提交”按钮后,页面卡死,未跳转到预期页面。 13 | 14 | ### 重现步骤 15 | 提供详细的步骤以重现问题。 16 | 1. 打开页面:[某个页面]。 17 | 2. 点击“某个”按钮。 18 | 3. 等待页面加载。 19 | 4. 页面未响应,显示空白。 20 | 21 | ### 预期行为 22 | 描述你预期的正确行为。 23 | 例:点击“某个”按钮后,应跳转到对应的页面。 24 | 25 | ### 实际行为 26 | 描述实际发生了什么问题。 27 | 例:页面卡死,软件无响应。 28 | 29 | ### 环境信息 30 | 提供有关运行环境的信息,以便开发者诊断问题。 31 | - 操作系统: [例如 Windows 10、macOS Ventura、Ubuntu 20.4] 32 | - 软件版本: [例如 1.2.3] 33 | - 网络环境: [例如 WiFi / 移动网络] 34 | - 其他 35 | 36 | ### 附加信息(建议) 37 | 其他有助于问题诊断的信息。 38 | - 相关截图或录屏(如果可能)。 39 | - 是否有报错信息(如果有,请附加错误日志或截图)。 40 | - 是否有特殊操作步骤或环境要求。 41 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/new-feature-suggestion-🐚.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "New Feature Suggestion \U0001F41A" 3 | about: Provide a creative suggestion for the project to help make the software more useful and accessible. 4 | title: "[Suggestion/Request]" 5 | labels: enhancement 6 | assignees: SeaYJ 7 | 8 | --- 9 | 10 | ### Overview of feature requests 11 | Outline in one sentence what you'd like to see new features or improvements, for example: "I want to add the ability to export user data." 12 | 13 | ### Background of the issue 14 | Briefly describe the current problem or inconvenience: 15 | - When will you encounter problems? 16 | - How does the issue affect users? 17 | 18 | ### Desired solution 19 | Be specific about what you want the feature to achieve or what you want the feature to do: 20 | - What are the core requirements for the feature? 21 | - Ideally, how should it be done and feedback? 22 | 23 | ### Potential Alternatives (Optional) 24 | Make a list of alternatives or temporary solutions you've considered, explaining their pros and cons. 25 | 26 | ### Additional Information (Optional) 27 | Supplement anything that helps you understand your needs: 28 | - Example scenario 29 | - Relevant screenshots or flowcharts 30 | - Technical limitations or specific needs -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/新功能建议-🐚.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "新功能建议 \U0001F41A" 3 | about: 为该项目提供一个创意性建议,帮助软件变得更加实用和便利。 4 | title: "[建议/请求]" 5 | labels: enhancement 6 | assignees: SeaYJ 7 | 8 | --- 9 | 10 | ### 功能请求概述 11 | 用一句话概述您希望新增的功能或改进,例如:“希望添加用户数据导出的功能”。 12 | 13 | ### 问题背景 14 | 简洁描述当前遇到的问题或不便: 15 | - 什么情境下会遇到问题? 16 | - 问题对用户的影响如何? 17 | 18 | ### 期望的解决方案 19 | 具体描述您希望该功能实现的目标或效果: 20 | - 功能的核心需求是什么? 21 | - 理想情况下应该如何操作和反馈? 22 | 23 | ### 潜在的替代方案(可选) 24 | 列出您考虑过的替代方案或临时解决方案,说明其优缺点。 25 | 26 | ### 附加信息(可选) 27 | 补充任何有助于理解需求的内容: 28 | - 示例场景 29 | - 相关截图或流程图 30 | - 技术限制或特定需求 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | *.slo 3 | *.lo 4 | *.o 5 | *.a 6 | *.la 7 | *.lai 8 | *.so 9 | *.so.* 10 | *.dll 11 | *.dylib 12 | 13 | # Qt-es 14 | object_script.*.Release 15 | object_script.*.Debug 16 | *_plugin_import.cpp 17 | /.qmake.cache 18 | /.qmake.stash 19 | *.pro.user 20 | *.pro.user.* 21 | *.qbs.user 22 | *.qbs.user.* 23 | *.moc 24 | moc_*.cpp 25 | moc_*.h 26 | qrc_*.cpp 27 | ui_*.h 28 | *.qmlc 29 | *.jsc 30 | Makefile* 31 | *build-* 32 | *.qm 33 | *.prl 34 | build 35 | 36 | # Qt unit tests 37 | target_wrapper.* 38 | 39 | # QtCreator 40 | *.autosave 41 | 42 | # QtCreator Qml 43 | *.qmlproject.user 44 | *.qmlproject.user.* 45 | 46 | # QtCreator CMake 47 | CMakeLists.txt.user* 48 | 49 | # QtCreator 4.8< compilation database 50 | compile_commands.json 51 | 52 | # QtCreator local machine specific files for imported projects 53 | *creator.user* 54 | 55 | *_qmlcache.qrc 56 | 57 | # 排除 deps 目录及其子目录 58 | !deps/ 59 | !deps/** -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(MouseClick VERSION 0.1 LANGUAGES CXX) 4 | 5 | set(CMAKE_AUTOUIC ON) 6 | set(CMAKE_AUTOMOC ON) 7 | set(CMAKE_AUTORCC ON) 8 | 9 | set(CMAKE_CXX_STANDARD 17) 10 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 11 | 12 | find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets LinguistTools) 13 | find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets LinguistTools) 14 | 15 | set(QWINDOWKIT_ROOT "${CMAKE_SOURCE_DIR}/deps/qwindowkit") 16 | set(QWindowKit_DIR "${QWINDOWKIT_ROOT}/lib/cmake/QWindowKit") 17 | find_package(QWindowKit REQUIRED) 18 | 19 | set(QHOTKEY_ROOT "${CMAKE_SOURCE_DIR}/deps/qhotkey") 20 | set(QHotkey_DIR "${QHOTKEY_ROOT}/lib/cmake/QHotkey") 21 | find_package(QHotkey REQUIRED) 22 | 23 | set(QWK_WINDOWBAR_FILES 24 | src/qwk_window_bar/windowbar.h src/qwk_window_bar/windowbar.cpp 25 | src/qwk_window_bar/windowbutton.h src/qwk_window_bar/windowbutton.cpp 26 | src/qwk_window_bar/private/windowbar_p.h 27 | src/qwk_window_bar/private/windowbutton_p.h 28 | ) 29 | 30 | set(TRANSLATIONS_FILES 31 | i18n/MouseClick_zh_CN.ts 32 | i18n/MouseClick_zh_TW.ts 33 | i18n/MouseClick_en_US.ts 34 | ) 35 | 36 | set(QRC_FILES assets/assets.qrc) 37 | 38 | set(PROJECT_SOURCES 39 | src/main.cpp 40 | src/mainwindow.h src/mainwindow.cpp 41 | src/modules/nav_pages/navpage.h src/modules/nav_pages/navpage.cpp 42 | src/modules/nav_pages/mouseclickpage.h src/modules/nav_pages/mouseclickpage.cpp 43 | src/modules/nav_pages/settingspage.h src/modules/nav_pages/settingspage.cpp 44 | src/modules/settingsagent.h src/modules/settingsagent.cpp 45 | src/modules/shared.h src/modules/shared.cpp 46 | src/modules/hotkeylineedit.h src/modules/hotkeylineedit.cpp 47 | src/modules/messagebox.h src/modules/messagebox.cpp 48 | src/utils/clicker.h src/utils/clicker.cpp 49 | ${QWK_WINDOWBAR_FILES} 50 | ${TRANSLATIONS_FILES} 51 | ${QRC_FILES} 52 | ) 53 | 54 | if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) 55 | qt_add_executable(${PROJECT_NAME} 56 | MANUAL_FINALIZATION 57 | ${PROJECT_SOURCES} 58 | ) 59 | # Define target properties for Android with Qt 6 as: 60 | # set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR 61 | # ${CMAKE_CURRENT_SOURCE_DIR}/android) 62 | # For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation 63 | 64 | # qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TRANSLATIONS_FILES}) 65 | qt_add_translations(${PROJECT_NAME} TS_FILES ${TRANSLATIONS_FILES}) 66 | else() 67 | if(ANDROID) 68 | add_library(${PROJECT_NAME} SHARED 69 | ${PROJECT_SOURCES} 70 | ) 71 | # Define properties for Android with Qt 5 after find_package() calls as: 72 | # set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android") 73 | else() 74 | add_executable(${PROJECT_NAME} 75 | ${PROJECT_SOURCES} 76 | ) 77 | endif() 78 | 79 | qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TRANSLATIONS_FILES}) 80 | endif() 81 | 82 | target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets) 83 | 84 | target_include_directories(${PROJECT_NAME} PRIVATE "${QWINDOWKIT_ROOT}/include/QWindowKit::Widgets") 85 | target_link_libraries(${PROJECT_NAME} PRIVATE QWindowKit::Widgets) 86 | 87 | target_include_directories(${PROJECT_NAME} PRIVATE ${QHOTKEY_ROOT}/include) 88 | target_link_libraries(${PROJECT_NAME} PRIVATE qhotkey) 89 | 90 | # Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. 91 | # If you are developing for iOS or macOS you should consider setting an 92 | # explicit, fixed bundle identifier manually though. 93 | if(${QT_VERSION} VERSION_LESS 6.1.0) 94 | set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER cn.seayj.MouseClick) 95 | endif() 96 | set_target_properties(${PROJECT_NAME} PROPERTIES 97 | ${BUNDLE_ID_OPTION} 98 | MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} 99 | MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} 100 | MACOSX_BUNDLE TRUE 101 | WIN32_EXECUTABLE TRUE 102 | ) 103 | 104 | include(GNUInstallDirs) 105 | install(TARGETS ${PROJECT_NAME} 106 | BUNDLE DESTINATION . 107 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 108 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 109 | ) 110 | 111 | if(QT_VERSION_MAJOR EQUAL 6) 112 | qt_finalize_executable(${PROJECT_NAME}) 113 | endif() 114 | 115 | 116 | # 构建打包环境 dist 目录 117 | # 1. 复制 QWindowKit 的 dll 文件到构建目录 118 | add_custom_command( 119 | TARGET MouseClick 120 | PRE_BUILD # 在构建之前执行 121 | COMMAND ${CMAKE_COMMAND} -E copy_directory 122 | "${CMAKE_SOURCE_DIR}/deps/qwindowkit/bin" 123 | "${CMAKE_BINARY_DIR}/dist" 124 | COMMENT "Copy the dll files of QWindowKit to the build directory!" 125 | ) 126 | 127 | # 2. 复制生成的可执行文件到 dist 目录 128 | add_custom_command( 129 | TARGET MouseClick 130 | POST_BUILD # 在可执行文件生成之后执行 131 | COMMAND ${CMAKE_COMMAND} -E copy 132 | "$" # 目标文件,即生成的 MouseClick.exe 133 | "${CMAKE_BINARY_DIR}/dist" 134 | COMMENT "Copy the generated executable to the dist directory!" 135 | ) 136 | -------------------------------------------------------------------------------- /README.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 🐀 MouseClick 6 | 21 | 22 | 23 | 24 | 31 | 42 | 53 | 66 | 138 | 139 | 140 | 141 |

🐀 MouseClick

142 |

这是我学习编程的第一个 GITHUB 项目仓库,对我个人而言算是一个新开始,但项目本身而言还远不是结束!

143 |

🎉 项目重构

144 |

第二代更新了,使用 Qt6 Widget 对项目进行了完全重构,相较于之前的代码,这次的代码质量有明显提升。并且,这次真正的实现了一个相对于优美的 UI 界面,风格偏向于 Fluent2 Design 那一套,但是也有不同。

145 |

下面是软件运行截图: 146 | 软件运行截图 147 | 软件运行截图

148 |

📋 项目计划

149 | 172 |

⚙ 环境要求

173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 |
ComponentRequirement
Compiler>= C++17
CMake>= 3.19
Qt>= 6.7.0 ?
195 |

🧤 编译项目

196 |
    197 |
  1. 首先先克隆本项目:
  2. 198 |
199 |
git clone git@github.com:SeaYJ/MouseClick.git
200 | 
201 |
    202 |
  1. 检查一下两个项目依赖库 CMAKE 环境是否配置正确(如果是 Qt Creator,则在“项目-CMake-Current Configuration”中添加):
  2. 203 |
204 |
-DQHotkey_DIR:PATH=<your_path>/MouseClick/deps/qhotkey/lib/cmake/QHotkey
205 | 
206 |
-DQWindowKit_DIR:PATH=<your_path>/MouseClick/deps/qwindowkit/lib/cmake/QWindowKit
207 | 
208 |
    209 |
  1. 配置完成后,直接编译即可。
  2. 210 |
211 |

📄 开源证书

212 |

MouseClick(本项目)遵守 GPL-3.0 license 开源证书。

213 | 214 | 215 | 216 | 217 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🐀 MouseClick 2 | 3 | 这是我学习编程的**第一个 GITHUB 项目仓库**,对我个人而言算是一个新开始,但项目本身而言还远不是结束! 4 | 5 | # 🎉 项目重构 6 | 7 | 第二代更新了,使用 Qt6 Widget 对项目进行了完全重构,相较于之前的代码,这次的代码质量有明显提升。并且,这次真正的实现了一个相对于优美的 UI 界面,风格偏向于 [**Fluent2 Design**](https://fluent2.microsoft.design/) 那一套,但是也有不同。 8 | 9 | 下面是软件运行截图: 10 | 11 | ## 简体中文 12 | 13 | ![软件运行截图](./docs/screenshots/SeaEpoch_2024-12-24_22-35-32.jpg) 14 | ![软件运行截图](./docs/screenshots/SeaEpoch_2024-12-24_22-36-07.jpg) 15 | 16 | ## 繁体中文 17 | 18 | ![软件运行截图](./docs/screenshots/SeaEpoch_2024-12-24_22-36-48.jpg) 19 | 20 | ## English 21 | 22 | ![软件运行截图](./docs/screenshots/SeaEpoch_2024-12-24_22-37-07.jpg) 23 | 24 | # 🧱 软件功能 25 | 26 | - [x] ~~V1 NULL~~ 27 | - [x] V2 功能 28 | - [x] 鼠标连点 29 | - [x] 普通连点(等间隔时间) 30 | - [x] 随件间隔时间 31 | - [x] 记忆配置参数 32 | - [ ] ~~Mouse Record~~ 33 | - [ ] ~~Mouse Macro~~ 34 | - [x] 软件设置 35 | - [x] 全局快捷键设置 36 | - [x] 黑夜模式 37 | - [x] 语言切换 38 | - [x] 国际化(多语言支持) 39 | - [x] 简体中文 40 | - [x] English 41 | - [x] 繁体中文 42 | 43 | # ⚙ 环境要求 44 | 45 | |Component|Requirement| 46 | |:--|:--| 47 | |Compiler|>= C++17| 48 | |CMake|>= 3.19| 49 | |Qt|>= 6.7.0 ?| 50 | 51 | # 🧤 编译项目 52 | 53 | 1. 首先先克隆本项目: 54 | ```cmd 55 | git clone git@github.com:SeaYJ/MouseClick.git 56 | ``` 57 | 2. 直接编译即可。 58 | 59 | # 🛒 打包项目 60 | 61 | 1. 进入 **/MouseClick/build/Desktop_Qt_x_x_x_xxxxx_xxx_bit-Release/dist** 目录中,里面的文件就是打包所需全部文件(需要先编译才能看到)。 62 | 2. 打开与你编译项目时使用的编译器**版本一致**的 **Qt CMD**(例如下图),并 cd 进入该目录。 63 | ![Qt CMD](docs/SeaEpoch_2024-10-22_09-51-39.jpg) 64 | 3. 执行命令 `windeployqt.exe ./MouseClick.exe`,等待命令结束即可打包成功。 65 | 66 | ## Star History 67 | 68 | [![Star History Chart](https://api.star-history.com/svg?repos=SeaYJ/MouseClick&type=Date)](https://star-history.com/#SeaYJ/MouseClick&Date) 69 | 70 | # 📄 开源证书 71 | 72 | MouseClick(本项目)遵守 [GPL-3.0 license](https://github.com/SeaYJ/MouseClick?tab=GPL-3.0-1-ov-file) 开源证书。 73 | -------------------------------------------------------------------------------- /assets/assets.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | qss/light-style.qss 4 | svg/favicon.svg 5 | qss/dark-style.qss 6 | svg/close-white.svg 7 | svg/maximize-blue.svg 8 | svg/minimize-blue.svg 9 | svg/restore-blue.svg 10 | qss/modules/light-mouseclickpage.qss 11 | qss/modules/dark-mouseclickpage.qss 12 | svg/mouse-middle.svg 13 | svg/mouse-right.svg 14 | svg/mouse-left.svg 15 | qss/modules/messagebox.qss 16 | qss/modules/light-settingspage.qss 17 | qss/modules/dark-settingspage.qss 18 | svg/restore-white.svg 19 | svg/minimize-white.svg 20 | svg/maximize-white.svg 21 | svg/settings-item-white.svg 22 | svg/toggle-right-fill-blue.svg 23 | svg/up-line-black.svg 24 | svg/down-line-light-gray.svg 25 | svg/up-line-gray.svg 26 | svg/up-line-light-gray.svg 27 | svg/down-line-black.svg 28 | svg/down-line-gray.svg 29 | svg/minimize-black.svg 30 | svg/settings-item-black.svg 31 | svg/toggle-right-fill-light-blue.svg 32 | svg/mouse-click-item-white.svg 33 | svg/mouse-click-item-black.svg 34 | svg/restore-black.svg 35 | svg/maximize-black.svg 36 | svg/close-black.svg 37 | svg/toggle-left-line-light-gray.svg 38 | svg/toggle-left-line-gray.svg 39 | svg/up-line-white.svg 40 | svg/down-line-white.svg 41 | fonts/HarmonyOS_Sans_SC/HarmonyOS_Sans_SC_Regular.ttf 42 | 43 | 44 | -------------------------------------------------------------------------------- /assets/fonts/HarmonyOS_Sans_SC/HarmonyOS_Sans_SC_Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeaEpoch/MouseClick/dbd84f3aecd7b1e6254825396d19c353d15fa535/assets/fonts/HarmonyOS_Sans_SC/HarmonyOS_Sans_SC_Regular.ttf -------------------------------------------------------------------------------- /assets/qss/dark-style.qss: -------------------------------------------------------------------------------- 1 | * { 2 | color: #fafafa; 3 | } 4 | 5 | *:disabled { 6 | color: #a5a5a5; 7 | } 8 | 9 | MainWindow { 10 | background-color: #1f1f1f; 11 | } 12 | 13 | #titlebar-label, 14 | #titlebar-icon-button, 15 | #titlebar-min-button, 16 | #titlebar-max-button, 17 | #titlebar-close-button { 18 | border: none; 19 | background-color: transparent; 20 | } 21 | 22 | #titlebar-label { 23 | font-size: 14px; 24 | } 25 | 26 | #titlebar-label, 27 | #titlebar-icon-button { 28 | height: 32px; 29 | } 30 | 31 | #titlebar-icon-button { 32 | width: 32px; 33 | icon-size: 18px; 34 | } 35 | 36 | #titlebar-min-button, 37 | #titlebar-max-button, 38 | #titlebar-close-button { 39 | margin: 2px; 40 | width: 32px; 41 | height: 30px; 42 | icon-size: 16px; 43 | border-radius: 2px; 44 | } 45 | 46 | #titlebar-min-button { 47 | icon: url(:/svg/minimize-white.svg); 48 | } 49 | 50 | #titlebar-max-button { 51 | icon: url(:/svg/maximize-white.svg); 52 | } 53 | 54 | #titlebar-max-button:checked { 55 | icon: url(:/svg/restore-white.svg); 56 | } 57 | 58 | #titlebar-close-button { 59 | icon: url(:/svg/close-white.svg); 60 | } 61 | 62 | #titlebar-min-button:hover, 63 | #titlebar-max-button:hover { 64 | background-color: #3d3d3d; 65 | } 66 | 67 | #titlebar-min-button:hover { 68 | icon: url(:/svg/minimize-blue.svg); 69 | } 70 | 71 | #titlebar-max-button:hover { 72 | icon: url(:/svg/maximize-blue.svg); 73 | } 74 | 75 | #titlebar-max-button:checked:hover { 76 | icon: url(:/svg/restore-blue.svg); 77 | } 78 | 79 | #titlebar-close-button:hover { 80 | icon: url(:/svg/close-white.svg); 81 | background-color: #e53c3c; 82 | } 83 | 84 | #central-widget { 85 | background-color: transparent; 86 | } 87 | 88 | /********************/ 89 | 90 | #side-nav, 91 | #side-nav::item { 92 | border: none; 93 | outline: none; 94 | background-color: transparent; 95 | } 96 | #side-nav { 97 | padding: 4px; 98 | } 99 | 100 | #side-nav::item QPushButton { 101 | text-align: left; 102 | font-size: 14px; 103 | color: #fafafa; 104 | outline: none; 105 | height: 32px; 106 | padding-left: 12px; 107 | margin-top: 2px; 108 | margin-bottom: 2px; 109 | border-radius: 4px; 110 | border-left: none; 111 | border-top: none; 112 | border-right: none; 113 | border-bottom: 2px solid transparent; 114 | background-color: transparent; 115 | } 116 | 117 | #side-nav::item QPushButton:hover { 118 | border-bottom: 2px solid #2987D5; 119 | background-color: #4DAAF7; 120 | } 121 | 122 | #side-nav::item QPushButton:checked { 123 | border-bottom: 2px solid #2987D5; 124 | background-color: #3AA0F5; 125 | } 126 | 127 | #side-nav::item QPushButton:checked:pressed { 128 | border-bottom: 2px solid #5CB0F7; 129 | background-color: #5CB0F7; 130 | } 131 | 132 | #nav-item-mouse-click { 133 | icon: url(:/svg/mouse-click-item-white.svg); 134 | } 135 | #nav-item-settings { 136 | icon: url(:/svg/settings-item-white.svg); 137 | } 138 | 139 | #nav-item-mouse-click:pressed, 140 | #nav-item-mouse-click:checked, 141 | #nav-item-mouse-click:checked:pressed, 142 | #nav-item-mouse-click:hover { 143 | icon: url(:/svg/mouse-click-item-white.svg); 144 | } 145 | #nav-item-settings:pressed, 146 | #nav-item-settings:checked, 147 | #nav-item-settings:checked:pressed, 148 | #nav-item-settings:hover { 149 | icon: url(:/svg/settings-item-white.svg); 150 | } 151 | 152 | /********************/ 153 | 154 | #nav-page { 155 | margin-left: 8px; 156 | margin-top: 4px; 157 | padding: 24px; 158 | border-radius: 8px; 159 | background-color: #333333; 160 | } 161 | 162 | /********************/ 163 | 164 | 165 | -------------------------------------------------------------------------------- /assets/qss/light-style.qss: -------------------------------------------------------------------------------- 1 | * { 2 | color: #1e1e1e; 3 | } 4 | 5 | *:disabled { 6 | color: #787878; 7 | } 8 | 9 | MainWindow { 10 | background-color: #eeeef2; 11 | } 12 | 13 | #titlebar-label, 14 | #titlebar-icon-button, 15 | #titlebar-min-button, 16 | #titlebar-max-button, 17 | #titlebar-close-button { 18 | border: none; 19 | background-color: transparent; 20 | } 21 | 22 | #titlebar-label { 23 | font-size: 14px; 24 | } 25 | 26 | #titlebar-label, 27 | #titlebar-icon-button { 28 | height: 32px; 29 | } 30 | 31 | #titlebar-icon-button { 32 | width: 32px; 33 | icon-size: 18px; 34 | } 35 | 36 | #titlebar-min-button, 37 | #titlebar-max-button, 38 | #titlebar-close-button { 39 | margin: 2px; 40 | width: 32px; 41 | height: 30px; 42 | icon-size: 16px; 43 | border-radius: 2px; 44 | } 45 | 46 | #titlebar-min-button { 47 | icon: url(:/svg/minimize-black.svg); 48 | } 49 | 50 | #titlebar-max-button { 51 | icon: url(:/svg/maximize-black.svg); 52 | } 53 | 54 | #titlebar-max-button:checked { 55 | icon: url(:/svg/restore-black.svg); 56 | } 57 | 58 | #titlebar-close-button { 59 | icon: url(:/svg/close-black.svg); 60 | } 61 | 62 | #titlebar-min-button:hover, 63 | #titlebar-max-button:hover { 64 | background-color: #fcfcfd; 65 | } 66 | 67 | #titlebar-min-button:hover { 68 | icon: url(:/svg/minimize-blue.svg); 69 | } 70 | 71 | #titlebar-max-button:hover { 72 | icon: url(:/svg/maximize-blue.svg); 73 | } 74 | 75 | #titlebar-max-button:checked:hover { 76 | icon: url(:/svg/restore-blue.svg); 77 | } 78 | 79 | #titlebar-close-button:hover { 80 | icon: url(:/svg/close-white.svg); 81 | background-color: #e53c3c; 82 | } 83 | 84 | #central-widget { 85 | background-color: transparent; 86 | } 87 | 88 | /********************/ 89 | 90 | #side-nav, 91 | #side-nav::item { 92 | border: none; 93 | outline: none; 94 | background-color: transparent; 95 | } 96 | #side-nav { 97 | padding: 4px; 98 | } 99 | 100 | #side-nav::item QPushButton { 101 | text-align: left; 102 | font-size: 14px; 103 | color: #1e1e1e; 104 | outline: none; 105 | height: 32px; 106 | padding-left: 12px; 107 | margin-top: 2px; 108 | margin-bottom: 2px; 109 | border-radius: 4px; 110 | border-left: none; 111 | border-top: none; 112 | border-right: none; 113 | border-bottom: 2px solid transparent; 114 | background-color: transparent; 115 | } 116 | 117 | #side-nav::item QPushButton:hover { 118 | color: #fafafa; 119 | border-bottom: 2px solid #2987D5; 120 | background-color: #4DAAF7; 121 | } 122 | 123 | #side-nav::item QPushButton:checked { 124 | color: #fafafa; 125 | border-bottom: 2px solid #2987D5; 126 | background-color: #3AA0F5; 127 | } 128 | 129 | #side-nav::item QPushButton:checked:pressed { 130 | color: #fafafa; 131 | border-bottom: 2px solid #5CB0F7; 132 | background-color: #5CB0F7; 133 | } 134 | 135 | #nav-item-mouse-click { 136 | icon: url(:/svg/mouse-click-item-black.svg); 137 | } 138 | #nav-item-settings { 139 | icon: url(:/svg/settings-item-black.svg); 140 | } 141 | 142 | #nav-item-mouse-click:pressed, 143 | #nav-item-mouse-click:checked, 144 | #nav-item-mouse-click:checked:pressed, 145 | #nav-item-mouse-click:hover { 146 | icon: url(:/svg/mouse-click-item-white.svg); 147 | } 148 | #nav-item-settings:pressed, 149 | #nav-item-settings:checked, 150 | #nav-item-settings:checked:pressed, 151 | #nav-item-settings:hover { 152 | icon: url(:/svg/settings-item-white.svg); 153 | } 154 | 155 | /********************/ 156 | 157 | #nav-page { 158 | margin-left: 8px; 159 | margin-top: 4px; 160 | padding: 24px; 161 | border-radius: 8px; 162 | background-color: #ffffff; 163 | } 164 | 165 | /********************/ 166 | 167 | 168 | -------------------------------------------------------------------------------- /assets/qss/modules/dark-mouseclickpage.qss: -------------------------------------------------------------------------------- 1 | #page-title { 2 | border: none; 3 | outline: none; 4 | font-size: 30px; 5 | background-color: transparent; 6 | } 7 | 8 | #page-content { 9 | background-color: transparent; 10 | } 11 | 12 | #page-content QLabel { 13 | border: none; 14 | outline: none; 15 | margin: 0px; 16 | padding: 0px; 17 | font-size: 14px; 18 | background-color: transparent; 19 | } 20 | 21 | #page-content QPushButton { 22 | text-align: center; 23 | font-size: 14px; 24 | color: #ffffff; 25 | outline: none; 26 | border-radius: 4px; 27 | border-left: none; 28 | border-top: none; 29 | border-right: none; 30 | border-bottom: 2px solid #2987D5; 31 | background-color: #3AA0F5; 32 | } 33 | 34 | #page-content QPushButton:hover { 35 | color: #f6f6f6; 36 | border-bottom: 2px solid #2987D5; 37 | background-color: #4DAAF7; 38 | } 39 | 40 | #page-content QPushButton:pressed { 41 | color: #fafafa; 42 | border-bottom: 2px solid #5CB0F7; 43 | background-color: #5CB0F7; 44 | } 45 | 46 | #page-content QPushButton:disabled { 47 | border-bottom-color: #95CBF5; 48 | background-color: #9BD2FF; 49 | } 50 | 51 | #page-content QLineEdit, 52 | #page-content QComboBox, 53 | #page-content QDoubleSpinBox { 54 | font-size: 14px; 55 | padding-left: 12px; 56 | border-radius: 4px; 57 | border: 2px solid #3aa1f5; 58 | background-color: #464646; 59 | } 60 | 61 | #page-content QComboBox::drop-down { 62 | width: 32px; 63 | border: none; 64 | background-color: transparent; 65 | } 66 | 67 | #page-content QComboBox::down-arrow { 68 | image: url(:/svg/down-line-white.svg); 69 | width: 24px; 70 | height: 24px; 71 | } 72 | 73 | #page-content QComboBox QAbstractItemView { 74 | outline: none; 75 | border-top: 1px solid #3aa1f5; 76 | border-left: 2px solid #3aa1f5; 77 | border-right: 2px solid #3aa1f5; 78 | border-bottom: 2px solid #3aa1f5; 79 | background-color: #464646; 80 | } 81 | 82 | #page-content QComboBox QAbstractItemView::item { 83 | color: #fafafa; 84 | padding-left: 12px; 85 | height: 32px; 86 | background-color: transparent; 87 | } 88 | 89 | #page-content QComboBox QAbstractItemView::item:hover { 90 | background-color: #2a2d2e; 91 | } 92 | 93 | #page-content QComboBox::down-arrow:disabled { 94 | image: url(:/svg/down-line-light-gray.svg); 95 | } 96 | 97 | #page-content QRadioButton::indicator { 98 | border: none; 99 | width: 32px; 100 | height: 32px; 101 | } 102 | 103 | #page-content QRadioButton::indicator:unchecked { 104 | image: url(:/svg/toggle-left-line-gray.svg); 105 | } 106 | #page-content QRadioButton::indicator:unchecked:disabled { 107 | image: url(:/svg/toggle-left-line-light-gray.svg); 108 | } 109 | 110 | #page-content QRadioButton::indicator:checked { 111 | image: url(:/svg/toggle-right-fill-blue.svg); 112 | } 113 | #page-content QRadioButton::indicator:checked:disabled { 114 | image: url(:/svg/toggle-right-fill-light-blue.svg); 115 | } 116 | 117 | #page-content QDoubleSpinBox:disabled, 118 | #page-content QComboBox:disabled, 119 | #page-content QLineEdit:disabled { 120 | border-color: #95cbf5; 121 | } 122 | 123 | #page-content QDoubleSpinBox::up-button, 124 | #page-content QDoubleSpinBox::down-button { 125 | border: none; 126 | outline: none; 127 | background-color: transparent; 128 | } 129 | 130 | #page-content QDoubleSpinBox::up-arrow, 131 | #page-content QDoubleSpinBox::down-arrow { 132 | width: 16px; 133 | height: 16px; 134 | } 135 | 136 | #page-content QDoubleSpinBox::up-arrow { 137 | image: url(:/svg/up-line-white.svg); 138 | } 139 | 140 | #page-content QDoubleSpinBox::down-arrow { 141 | image: url(:/svg/down-line-white.svg); 142 | } 143 | 144 | #page-content QDoubleSpinBox::up-arrow:pressed { 145 | image: url(:/svg/up-line-gray.svg); 146 | height: 15px; 147 | } 148 | 149 | #page-content QDoubleSpinBox::up-arrow:disabled { 150 | image: url(:/svg/up-line-light-gray.svg); 151 | } 152 | 153 | #page-content QDoubleSpinBox::down-arrow:pressed { 154 | image: url(:/svg/down-line-gray.svg); 155 | height: 15px; 156 | } 157 | 158 | #page-content QDoubleSpinBox::down-arrow:disabled { 159 | image: url(:/svg/down-line-light-gray.svg); 160 | } 161 | 162 | #page-content #hotkey-reader:focus { 163 | background-color: #ecf5ff; 164 | } 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | -------------------------------------------------------------------------------- /assets/qss/modules/dark-settingspage.qss: -------------------------------------------------------------------------------- 1 | #page-title { 2 | border: none; 3 | outline: none; 4 | font-size: 30px; 5 | background-color: transparent; 6 | } 7 | 8 | #page-content { 9 | background-color: transparent; 10 | } 11 | 12 | #page-content QLabel { 13 | border: none; 14 | outline: none; 15 | margin: 0px; 16 | padding: 0px; 17 | font-size: 14px; 18 | background-color: transparent; 19 | } 20 | 21 | #page-content QPushButton { 22 | text-align: center; 23 | font-size: 14px; 24 | color: #ffffff; 25 | outline: none; 26 | border-radius: 4px; 27 | border-left: none; 28 | border-top: none; 29 | border-right: none; 30 | border-bottom: 2px solid #2987D5; 31 | background-color: #3AA0F5; 32 | } 33 | 34 | #page-content QPushButton:hover { 35 | color: #f6f6f6; 36 | border-bottom: 2px solid #2987D5; 37 | background-color: #4DAAF7; 38 | } 39 | 40 | #page-content QPushButton:pressed { 41 | color: #fafafa; 42 | border-bottom: 2px solid #5CB0F7; 43 | background-color: #5CB0F7; 44 | } 45 | 46 | #page-content QPushButton:disabled { 47 | border-bottom-color: #95CBF5; 48 | background-color: #9BD2FF; 49 | } 50 | 51 | #page-content QLineEdit, 52 | #page-content QComboBox { 53 | font-size: 14px; 54 | padding-left: 12px; 55 | border-radius: 4px; 56 | border: 2px solid #3aa1f5; 57 | background-color: #464646; 58 | } 59 | 60 | #page-content QLineEdit:disabled, 61 | #page-content QComboBox:disabled { 62 | border-color: #95cbf5; 63 | } 64 | 65 | #page-content QComboBox::drop-down { 66 | width: 32px; 67 | border: none; 68 | background-color: transparent; 69 | } 70 | 71 | #page-content QComboBox::down-arrow { 72 | image: url(:/svg/down-line-white.svg); 73 | width: 24px; 74 | height: 24px; 75 | } 76 | 77 | #page-content QComboBox QAbstractItemView { 78 | outline: none; 79 | border-top: 1px solid #3aa1f5; 80 | border-left: 2px solid #3aa1f5; 81 | border-right: 2px solid #3aa1f5; 82 | border-bottom: 2px solid #3aa1f5; 83 | background-color: #464646; 84 | } 85 | 86 | #page-content QComboBox QAbstractItemView::item { 87 | color: #fafafa; 88 | padding-left: 12px; 89 | height: 32px; 90 | background-color: transparent; 91 | } 92 | 93 | #page-content QComboBox QAbstractItemView::item:hover { 94 | background-color: #2a2d2e; 95 | } 96 | 97 | #page-content QComboBox::down-arrow:disabled { 98 | image: url(:/svg/down-line-light-gray.svg); 99 | } 100 | 101 | #page-content QRadioButton::indicator { 102 | border: none; 103 | width: 32px; 104 | height: 32px; 105 | } 106 | 107 | #page-content QRadioButton::indicator:unchecked { 108 | image: url(:/svg/toggle-left-line-gray.svg); 109 | } 110 | #page-content QRadioButton::indicator:unchecked:disabled { 111 | image: url(:/svg/toggle-left-line-light-gray.svg); 112 | } 113 | 114 | #page-content QRadioButton::indicator:checked { 115 | image: url(:/svg/toggle-right-fill-blue.svg); 116 | } 117 | #page-content QRadioButton::indicator:checked:disabled { 118 | image: url(:/svg/toggle-right-fill-light-blue.svg); 119 | } 120 | -------------------------------------------------------------------------------- /assets/qss/modules/light-mouseclickpage.qss: -------------------------------------------------------------------------------- 1 | #page-title { 2 | border: none; 3 | outline: none; 4 | font-size: 30px; 5 | background-color: transparent; 6 | } 7 | 8 | #page-content { 9 | background-color: transparent; 10 | } 11 | 12 | #page-content QLabel { 13 | border: none; 14 | outline: none; 15 | margin: 0px; 16 | padding: 0px; 17 | font-size: 14px; 18 | background-color: transparent; 19 | } 20 | 21 | #page-content QPushButton { 22 | text-align: center; 23 | font-size: 14px; 24 | color: #fafafa; 25 | outline: none; 26 | border-radius: 4px; 27 | border-left: none; 28 | border-top: none; 29 | border-right: none; 30 | border-bottom: 2px solid #2987D5; 31 | background-color: #3AA0F5; 32 | } 33 | 34 | #page-content QPushButton:hover { 35 | border-bottom: 2px solid #2987D5; 36 | background-color: #4DAAF7; 37 | } 38 | 39 | #page-content QPushButton:pressed { 40 | border-bottom: 2px solid #5CB0F7; 41 | background-color: #5CB0F7; 42 | } 43 | 44 | #page-content QPushButton:disabled { 45 | border-bottom-color: #95CBF5; 46 | background-color: #9BD2FF; 47 | } 48 | 49 | #page-content QLineEdit, 50 | #page-content QComboBox, 51 | #page-content QDoubleSpinBox { 52 | font-size: 14px; 53 | padding-left: 12px; 54 | border-radius: 4px; 55 | border: 2px solid #3aa1f5; 56 | background-color: #ffffff; 57 | } 58 | 59 | #page-content QComboBox::drop-down { 60 | width: 32px; 61 | border: none; 62 | background-color: transparent; 63 | } 64 | 65 | #page-content QComboBox::down-arrow { 66 | image: url(:/svg/down-line-black.svg); 67 | width: 24px; 68 | height: 24px; 69 | } 70 | 71 | #page-content QComboBox QAbstractItemView { 72 | outline: none; 73 | border-top: 1px solid #3aa1f5; 74 | border-left: 2px solid #3aa1f5; 75 | border-right: 2px solid #3aa1f5; 76 | border-bottom: 2px solid #3aa1f5; 77 | background-color: #ffffff; 78 | } 79 | 80 | #page-content QComboBox QAbstractItemView::item { 81 | color: #1e1e1e; 82 | padding-left: 12px; 83 | height: 32px; 84 | background-color: transparent; 85 | } 86 | 87 | #page-content QComboBox QAbstractItemView::item:hover { 88 | background-color: #cce8ff; 89 | } 90 | 91 | #page-content QComboBox::down-arrow:disabled { 92 | image: url(:/svg/down-line-light-gray.svg); 93 | } 94 | 95 | #page-content QRadioButton::indicator { 96 | border: none; 97 | width: 32px; 98 | height: 32px; 99 | } 100 | 101 | #page-content QRadioButton::indicator:unchecked { 102 | image: url(:/svg/toggle-left-line-gray.svg); 103 | } 104 | #page-content QRadioButton::indicator:unchecked:disabled { 105 | image: url(:/svg/toggle-left-line-light-gray.svg); 106 | } 107 | 108 | #page-content QRadioButton::indicator:checked { 109 | image: url(:/svg/toggle-right-fill-blue.svg); 110 | } 111 | #page-content QRadioButton::indicator:checked:disabled { 112 | image: url(:/svg/toggle-right-fill-light-blue.svg); 113 | } 114 | 115 | #page-content QDoubleSpinBox:disabled, 116 | #page-content QComboBox:disabled, 117 | #page-content QLineEdit:disabled { 118 | border-color: #95cbf5; 119 | } 120 | 121 | #page-content QDoubleSpinBox::up-button, 122 | #page-content QDoubleSpinBox::down-button { 123 | border: none; 124 | outline: none; 125 | background-color: transparent; 126 | } 127 | 128 | #page-content QDoubleSpinBox::up-arrow, 129 | #page-content QDoubleSpinBox::down-arrow { 130 | width: 16px; 131 | height: 16px; 132 | } 133 | 134 | #page-content QDoubleSpinBox::up-arrow { 135 | image: url(:/svg/up-line-black.svg); 136 | } 137 | 138 | #page-content QDoubleSpinBox::down-arrow { 139 | image: url(:/svg/down-line-black.svg); 140 | } 141 | 142 | #page-content QDoubleSpinBox::up-arrow:pressed { 143 | image: url(:/svg/up-line-gray.svg); 144 | height: 15px; 145 | } 146 | 147 | #page-content QDoubleSpinBox::up-arrow:disabled { 148 | image: url(:/svg/up-line-light-gray.svg); 149 | } 150 | 151 | #page-content QDoubleSpinBox::down-arrow:pressed { 152 | image: url(:/svg/down-line-gray.svg); 153 | height: 15px; 154 | } 155 | 156 | #page-content QDoubleSpinBox::down-arrow:disabled { 157 | image: url(:/svg/down-line-light-gray.svg); 158 | } 159 | 160 | #page-content #hotkey-reader:focus { 161 | background-color: #ecf5ff; 162 | } 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /assets/qss/modules/light-settingspage.qss: -------------------------------------------------------------------------------- 1 | #page-title { 2 | border: none; 3 | outline: none; 4 | font-size: 30px; 5 | background-color: transparent; 6 | } 7 | 8 | #page-content { 9 | background-color: transparent; 10 | } 11 | 12 | #page-content QLabel { 13 | border: none; 14 | outline: none; 15 | margin: 0px; 16 | padding: 0px; 17 | font-size: 14px; 18 | background-color: transparent; 19 | } 20 | 21 | #page-content QPushButton { 22 | text-align: center; 23 | font-size: 14px; 24 | color: #fafafa; 25 | outline: none; 26 | border-radius: 4px; 27 | border-left: none; 28 | border-top: none; 29 | border-right: none; 30 | border-bottom: 2px solid #2987D5; 31 | background-color: #3AA0F5; 32 | } 33 | 34 | #page-content QPushButton:hover { 35 | border-bottom: 2px solid #2987D5; 36 | background-color: #4DAAF7; 37 | } 38 | 39 | #page-content QPushButton:pressed { 40 | border-bottom: 2px solid #5CB0F7; 41 | background-color: #5CB0F7; 42 | } 43 | 44 | #page-content QPushButton:disabled { 45 | border-bottom-color: #95CBF5; 46 | background-color: #9BD2FF; 47 | } 48 | 49 | #page-content QLineEdit, 50 | #page-content QComboBox { 51 | font-size: 14px; 52 | padding-left: 12px; 53 | border-radius: 4px; 54 | border: 2px solid #3aa1f5; 55 | background-color: #ffffff; 56 | } 57 | 58 | #page-content QLineEdit:disabled, 59 | #page-content QComboBox:disabled { 60 | border-color: #95cbf5; 61 | } 62 | 63 | #page-content QComboBox::drop-down { 64 | width: 32px; 65 | border: none; 66 | background-color: transparent; 67 | } 68 | 69 | #page-content QComboBox::down-arrow { 70 | image: url(:/svg/down-line-black.svg); 71 | width: 24px; 72 | height: 24px; 73 | } 74 | 75 | #page-content QComboBox QAbstractItemView { 76 | outline: none; 77 | border-top: 1px solid #3aa1f5; 78 | border-left: 2px solid #3aa1f5; 79 | border-right: 2px solid #3aa1f5; 80 | border-bottom: 2px solid #3aa1f5; 81 | background-color: #ffffff; 82 | } 83 | 84 | #page-content QComboBox QAbstractItemView::item { 85 | color: #1e1e1e; 86 | padding-left: 12px; 87 | height: 32px; 88 | background-color: transparent; 89 | } 90 | 91 | #page-content QComboBox QAbstractItemView::item:hover { 92 | background-color: #cce8ff; 93 | } 94 | 95 | #page-content QComboBox::down-arrow:disabled { 96 | image: url(:/svg/down-line-light-gray.svg); 97 | } 98 | 99 | #page-content QRadioButton::indicator { 100 | border: none; 101 | width: 32px; 102 | height: 32px; 103 | } 104 | 105 | #page-content QRadioButton::indicator:unchecked { 106 | image: url(:/svg/toggle-left-line-gray.svg); 107 | } 108 | #page-content QRadioButton::indicator:unchecked:disabled { 109 | image: url(:/svg/toggle-left-line-light-gray.svg); 110 | } 111 | 112 | #page-content QRadioButton::indicator:checked { 113 | image: url(:/svg/toggle-right-fill-blue.svg); 114 | } 115 | #page-content QRadioButton::indicator:checked:disabled { 116 | image: url(:/svg/toggle-right-fill-light-blue.svg); 117 | } 118 | -------------------------------------------------------------------------------- /assets/qss/modules/messagebox.qss: -------------------------------------------------------------------------------- 1 | QMessageBox { 2 | background-color: #ffffff; 3 | border-bottom: 50px solid #eeeef2; 4 | } 5 | 6 | QMessageBox QLabel#qt_msgbox_label { /* textLabel */ 7 | background-color: transparent; 8 | min-height: 40px; /* textLabel和iconLabel高度保持一致 */ 9 | } 10 | 11 | QMessageBox QLabel#qt_msgboxex_icon_label { /* iconLabel */ 12 | width: 40px; 13 | min-height: 40px; /* textLabel和iconLabel高度保持一致 */ 14 | } 15 | 16 | QMessageBox QPushButton { 17 | text-align: center; 18 | font-size: 14px; 19 | color: #fafafa; 20 | outline: none; 21 | border-radius: 4px; 22 | border-left: none; 23 | border-top: none; 24 | border-right: none; 25 | border-bottom: 2px solid #2987D5; 26 | background-color: #3AA0F5; 27 | min-width: 70px; 28 | min-height: 25px; 29 | } 30 | 31 | QMessageBox QPushButton:hover { 32 | border-bottom: 2px solid #2987D5; 33 | background-color: #4DAAF7; 34 | } 35 | 36 | QMessageBox QPushButton:pressed { 37 | border-bottom: 2px solid #5CB0F7; 38 | background-color: #5CB0F7; 39 | } 40 | -------------------------------------------------------------------------------- /assets/svg/close-black.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/close-white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/down-line-black.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/down-line-gray.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/down-line-light-gray.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/down-line-white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/favicon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/maximize-black.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/maximize-blue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/maximize-white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/minimize-black.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/minimize-blue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/minimize-white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/mouse-click-item-black.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/mouse-click-item-white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/restore-black.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/restore-blue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/restore-white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/settings-item-black.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/settings-item-white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/toggle-left-line-gray.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/toggle-left-line-light-gray.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/toggle-right-fill-blue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/toggle-right-fill-light-blue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/up-line-black.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/up-line-gray.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/up-line-light-gray.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/up-line-white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /deps/qhotkey/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Felix Barz 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of QHotkey nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /deps/qhotkey/include/QHotkey: -------------------------------------------------------------------------------- 1 | #include "qhotkey.h" 2 | -------------------------------------------------------------------------------- /deps/qhotkey/include/qhotkey.h: -------------------------------------------------------------------------------- 1 | #ifndef QHOTKEY_H 2 | #define QHOTKEY_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #ifdef QHOTKEY_SHARED 10 | # ifdef QHOTKEY_LIBRARY 11 | # define QHOTKEY_EXPORT Q_DECL_EXPORT 12 | # else 13 | # define QHOTKEY_EXPORT Q_DECL_IMPORT 14 | # endif 15 | #else 16 | # define QHOTKEY_EXPORT 17 | #endif 18 | 19 | #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 20 | #define QHOTKEY_HASH_SEED size_t 21 | #else 22 | #define QHOTKEY_HASH_SEED uint 23 | #endif 24 | 25 | //! A class to define global, systemwide Hotkeys 26 | class QHOTKEY_EXPORT QHotkey : public QObject 27 | { 28 | Q_OBJECT 29 | //! @private 30 | friend class QHotkeyPrivate; 31 | 32 | //! Specifies whether this hotkey is currently registered or not 33 | Q_PROPERTY(bool registered READ isRegistered WRITE setRegistered NOTIFY registeredChanged) 34 | //! Holds the shortcut this hotkey will be triggered on 35 | Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut RESET resetShortcut) 36 | 37 | public: 38 | //! Defines shortcut with native keycodes 39 | class QHOTKEY_EXPORT NativeShortcut { 40 | public: 41 | //! The native keycode 42 | quint32 key; 43 | //! The native modifiers 44 | quint32 modifier; 45 | 46 | //! Creates an invalid native shortcut 47 | NativeShortcut(); 48 | //! Creates a valid native shortcut, with the given key and modifiers 49 | NativeShortcut(quint32 key, quint32 modifier = 0); 50 | 51 | //! Checks, whether this shortcut is valid or not 52 | bool isValid() const; 53 | 54 | //! Equality operator 55 | bool operator ==(NativeShortcut other) const; 56 | //! Inequality operator 57 | bool operator !=(NativeShortcut other) const; 58 | 59 | private: 60 | bool valid; 61 | }; 62 | 63 | //! Adds a global mapping of a key sequence to a replacement native shortcut 64 | static void addGlobalMapping(const QKeySequence &shortcut, NativeShortcut nativeShortcut); 65 | 66 | //! Checks if global shortcuts are supported by the current platform 67 | static bool isPlatformSupported(); 68 | 69 | //! Default Constructor 70 | explicit QHotkey(QObject *parent = nullptr); 71 | //! Constructs a hotkey with a shortcut and optionally registers it 72 | explicit QHotkey(const QKeySequence &shortcut, bool autoRegister = false, QObject *parent = nullptr); 73 | //! Constructs a hotkey with a key and modifiers and optionally registers it 74 | explicit QHotkey(Qt::Key keyCode, Qt::KeyboardModifiers modifiers, bool autoRegister = false, QObject *parent = nullptr); 75 | //! Constructs a hotkey from a native shortcut and optionally registers it 76 | explicit QHotkey(NativeShortcut shortcut, bool autoRegister = false, QObject *parent = nullptr); 77 | ~QHotkey() override; 78 | 79 | //! @readAcFn{QHotkey::registered} 80 | bool isRegistered() const; 81 | //! @readAcFn{QHotkey::shortcut} 82 | QKeySequence shortcut() const; 83 | //! @readAcFn{QHotkey::shortcut} - the key only 84 | Qt::Key keyCode() const; 85 | //! @readAcFn{QHotkey::shortcut} - the modifiers only 86 | Qt::KeyboardModifiers modifiers() const; 87 | 88 | //! Get the current native shortcut 89 | NativeShortcut currentNativeShortcut() const; 90 | 91 | public slots: 92 | //! @writeAcFn{QHotkey::registered} 93 | bool setRegistered(bool registered); 94 | 95 | //! @writeAcFn{QHotkey::shortcut} 96 | bool setShortcut(const QKeySequence &shortcut, bool autoRegister = false); 97 | //! @writeAcFn{QHotkey::shortcut} 98 | bool setShortcut(Qt::Key keyCode, Qt::KeyboardModifiers modifiers, bool autoRegister = false); 99 | //! @resetAcFn{QHotkey::shortcut} 100 | bool resetShortcut(); 101 | 102 | //! Set this hotkey to a native shortcut 103 | bool setNativeShortcut(QHotkey::NativeShortcut nativeShortcut, bool autoRegister = false); 104 | 105 | signals: 106 | //! Will be emitted if the shortcut is pressed 107 | void activated(QPrivateSignal); 108 | 109 | //! Will be emitted if the shortcut press is released 110 | void released(QPrivateSignal); 111 | 112 | //! @notifyAcFn{QHotkey::registered} 113 | void registeredChanged(bool registered); 114 | 115 | private: 116 | Qt::Key _keyCode; 117 | Qt::KeyboardModifiers _modifiers; 118 | 119 | NativeShortcut _nativeShortcut; 120 | bool _registered; 121 | }; 122 | 123 | QHOTKEY_HASH_SEED QHOTKEY_EXPORT qHash(QHotkey::NativeShortcut key); 124 | QHOTKEY_HASH_SEED QHOTKEY_EXPORT qHash(QHotkey::NativeShortcut key, QHOTKEY_HASH_SEED seed); 125 | 126 | QHOTKEY_EXPORT Q_DECLARE_LOGGING_CATEGORY(logQHotkey) 127 | 128 | Q_DECLARE_METATYPE(QHotkey::NativeShortcut) 129 | 130 | #endif // QHOTKEY_H 131 | -------------------------------------------------------------------------------- /deps/qhotkey/lib/cmake/QHotkey/QHotkeyConfig-noconfig.cmake: -------------------------------------------------------------------------------- 1 | #---------------------------------------------------------------- 2 | # Generated CMake target import file. 3 | #---------------------------------------------------------------- 4 | 5 | # Commands may need to know the format version. 6 | set(CMAKE_IMPORT_FILE_VERSION 1) 7 | 8 | # Import target "qhotkey" for configuration "" 9 | set_property(TARGET qhotkey APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG) 10 | set_target_properties(qhotkey PROPERTIES 11 | IMPORTED_LINK_INTERFACE_LANGUAGES_NOCONFIG "CXX" 12 | IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/lib/libqhotkey.a" 13 | ) 14 | 15 | list(APPEND _cmake_import_check_targets qhotkey ) 16 | list(APPEND _cmake_import_check_files_for_qhotkey "${_IMPORT_PREFIX}/lib/libqhotkey.a" ) 17 | 18 | # Commands beyond this point should not need to know the version. 19 | set(CMAKE_IMPORT_FILE_VERSION) 20 | -------------------------------------------------------------------------------- /deps/qhotkey/lib/cmake/QHotkey/QHotkeyConfig.cmake: -------------------------------------------------------------------------------- 1 | # Generated by CMake 2 | 3 | if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.8) 4 | message(FATAL_ERROR "CMake >= 2.8.0 required") 5 | endif() 6 | if(CMAKE_VERSION VERSION_LESS "2.8.3") 7 | message(FATAL_ERROR "CMake >= 2.8.3 required") 8 | endif() 9 | cmake_policy(PUSH) 10 | cmake_policy(VERSION 2.8.3...3.25) 11 | #---------------------------------------------------------------- 12 | # Generated CMake target import file. 13 | #---------------------------------------------------------------- 14 | 15 | # Commands may need to know the format version. 16 | set(CMAKE_IMPORT_FILE_VERSION 1) 17 | 18 | # Protect against multiple inclusion, which would fail when already imported targets are added once more. 19 | set(_cmake_targets_defined "") 20 | set(_cmake_targets_not_defined "") 21 | set(_cmake_expected_targets "") 22 | foreach(_cmake_expected_target IN ITEMS qhotkey) 23 | list(APPEND _cmake_expected_targets "${_cmake_expected_target}") 24 | if(TARGET "${_cmake_expected_target}") 25 | list(APPEND _cmake_targets_defined "${_cmake_expected_target}") 26 | else() 27 | list(APPEND _cmake_targets_not_defined "${_cmake_expected_target}") 28 | endif() 29 | endforeach() 30 | unset(_cmake_expected_target) 31 | if(_cmake_targets_defined STREQUAL _cmake_expected_targets) 32 | unset(_cmake_targets_defined) 33 | unset(_cmake_targets_not_defined) 34 | unset(_cmake_expected_targets) 35 | unset(CMAKE_IMPORT_FILE_VERSION) 36 | cmake_policy(POP) 37 | return() 38 | endif() 39 | if(NOT _cmake_targets_defined STREQUAL "") 40 | string(REPLACE ";" ", " _cmake_targets_defined_text "${_cmake_targets_defined}") 41 | string(REPLACE ";" ", " _cmake_targets_not_defined_text "${_cmake_targets_not_defined}") 42 | message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_cmake_targets_defined_text}\nTargets not yet defined: ${_cmake_targets_not_defined_text}\n") 43 | endif() 44 | unset(_cmake_targets_defined) 45 | unset(_cmake_targets_not_defined) 46 | unset(_cmake_expected_targets) 47 | 48 | 49 | # Compute the installation prefix relative to this file. 50 | get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH) 51 | get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) 52 | get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) 53 | get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) 54 | if(_IMPORT_PREFIX STREQUAL "/") 55 | set(_IMPORT_PREFIX "") 56 | endif() 57 | 58 | # Create imported target qhotkey 59 | add_library(qhotkey STATIC IMPORTED) 60 | 61 | set_target_properties(qhotkey PROPERTIES 62 | COMPATIBLE_INTERFACE_STRING "QHotkey_MAJOR_VERSION" 63 | INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include" 64 | INTERFACE_LINK_LIBRARIES "Qt6::Core;Qt6::Gui" 65 | INTERFACE_QHotkey_MAJOR_VERSION "1" 66 | ) 67 | 68 | if(CMAKE_VERSION VERSION_LESS 2.8.12) 69 | message(FATAL_ERROR "This file relies on consumers using CMake 2.8.12 or greater.") 70 | endif() 71 | 72 | # Load information for each installed configuration. 73 | file(GLOB _cmake_config_files "${CMAKE_CURRENT_LIST_DIR}/QHotkeyConfig-*.cmake") 74 | foreach(_cmake_config_file IN LISTS _cmake_config_files) 75 | include("${_cmake_config_file}") 76 | endforeach() 77 | unset(_cmake_config_file) 78 | unset(_cmake_config_files) 79 | 80 | # Cleanup temporary variables. 81 | set(_IMPORT_PREFIX) 82 | 83 | # Loop over all imported files and verify that they actually exist 84 | foreach(_cmake_target IN LISTS _cmake_import_check_targets) 85 | foreach(_cmake_file IN LISTS "_cmake_import_check_files_for_${_cmake_target}") 86 | if(NOT EXISTS "${_cmake_file}") 87 | message(FATAL_ERROR "The imported target \"${_cmake_target}\" references the file 88 | \"${_cmake_file}\" 89 | but this file does not exist. Possible reasons include: 90 | * The file was deleted, renamed, or moved to another location. 91 | * An install or uninstall procedure did not complete successfully. 92 | * The installation package was faulty and contained 93 | \"${CMAKE_CURRENT_LIST_FILE}\" 94 | but not all the files it references. 95 | ") 96 | endif() 97 | endforeach() 98 | unset(_cmake_file) 99 | unset("_cmake_import_check_files_for_${_cmake_target}") 100 | endforeach() 101 | unset(_cmake_target) 102 | unset(_cmake_import_check_targets) 103 | 104 | # This file does not depend on other imported targets which have 105 | # been exported from the same project but in a separate export set. 106 | 107 | # Commands beyond this point should not need to know the version. 108 | set(CMAKE_IMPORT_FILE_VERSION) 109 | cmake_policy(POP) 110 | -------------------------------------------------------------------------------- /deps/qhotkey/lib/cmake/QHotkey/QHotkeyConfigVersion.cmake: -------------------------------------------------------------------------------- 1 | # This is a basic version file for the Config-mode of find_package(). 2 | # It is used by write_basic_package_version_file() as input file for configure_file() 3 | # to create a version-file which can be installed along a config.cmake file. 4 | # 5 | # The created file sets PACKAGE_VERSION_EXACT if the current version string and 6 | # the requested version string are exactly the same and it sets 7 | # PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version. 8 | # The variable CVF_VERSION must be set before calling configure_file(). 9 | 10 | set(PACKAGE_VERSION "1.5.0") 11 | 12 | if (PACKAGE_FIND_VERSION_RANGE) 13 | # Package version must be in the requested version range 14 | if ((PACKAGE_FIND_VERSION_RANGE_MIN STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MIN) 15 | OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_GREATER PACKAGE_FIND_VERSION_MAX) 16 | OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND PACKAGE_VERSION VERSION_GREATER_EQUAL PACKAGE_FIND_VERSION_MAX))) 17 | set(PACKAGE_VERSION_COMPATIBLE FALSE) 18 | else() 19 | set(PACKAGE_VERSION_COMPATIBLE TRUE) 20 | endif() 21 | else() 22 | if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) 23 | set(PACKAGE_VERSION_COMPATIBLE FALSE) 24 | else() 25 | set(PACKAGE_VERSION_COMPATIBLE TRUE) 26 | if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) 27 | set(PACKAGE_VERSION_EXACT TRUE) 28 | endif() 29 | endif() 30 | endif() 31 | 32 | 33 | # if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: 34 | if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "") 35 | return() 36 | endif() 37 | 38 | # check that the installed version has the same 32/64bit-ness as the one which is currently searching: 39 | if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "8") 40 | math(EXPR installedBits "8 * 8") 41 | set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") 42 | set(PACKAGE_VERSION_UNSUITABLE TRUE) 43 | endif() 44 | -------------------------------------------------------------------------------- /deps/qhotkey/lib/libqhotkey.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeaEpoch/MouseClick/dbd84f3aecd7b1e6254825396d19c353d15fa535/deps/qhotkey/lib/libqhotkey.a -------------------------------------------------------------------------------- /deps/qwindowkit/bin/QWKCore.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeaEpoch/MouseClick/dbd84f3aecd7b1e6254825396d19c353d15fa535/deps/qwindowkit/bin/QWKCore.dll -------------------------------------------------------------------------------- /deps/qwindowkit/bin/QWKWidgets.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeaEpoch/MouseClick/dbd84f3aecd7b1e6254825396d19c353d15fa535/deps/qwindowkit/bin/QWKWidgets.dll -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKCore/private/abstractwindowcontext_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef ABSTRACTWINDOWCONTEXT_P_H 6 | #define ABSTRACTWINDOWCONTEXT_P_H 7 | 8 | // 9 | // W A R N I N G !!! 10 | // ----------------- 11 | // 12 | // This file is not part of the QWindowKit API. It is used purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or may even be removed. 15 | // 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | namespace QWK { 32 | 33 | class QWK_CORE_EXPORT AbstractWindowContext : public QObject, 34 | public NativeEventDispatcher, 35 | public SharedEventDispatcher { 36 | Q_OBJECT 37 | public: 38 | AbstractWindowContext(); 39 | ~AbstractWindowContext() override; 40 | 41 | public: 42 | void setup(QObject *host, WindowItemDelegate *delegate); 43 | 44 | inline QObject *host() const; 45 | inline QWindow *window() const; 46 | inline WId windowId() const; 47 | inline WindowItemDelegate *delegate() const; 48 | 49 | inline bool isHitTestVisible(const QObject *obj) const; 50 | bool setHitTestVisible(const QObject *obj, bool visible); 51 | 52 | inline QObject *systemButton(WindowAgentBase::SystemButton button) const; 53 | bool setSystemButton(WindowAgentBase::SystemButton button, QObject *obj); 54 | 55 | inline QObject *titleBar() const; 56 | bool setTitleBar(QObject *obj); 57 | 58 | #ifdef Q_OS_MAC 59 | inline ScreenRectCallback systemButtonAreaCallback() const; 60 | void setSystemButtonAreaCallback(const ScreenRectCallback &callback); 61 | #endif 62 | 63 | bool isInSystemButtons(const QPoint &pos, WindowAgentBase::SystemButton *button) const; 64 | bool isInTitleBarDraggableArea(const QPoint &pos) const; 65 | 66 | inline bool isHostWidthFixed() const { 67 | return m_windowHandle 68 | ? ((m_windowHandle->flags() & Qt::MSWindowsFixedSizeDialogHint) || 69 | m_windowHandle->minimumWidth() == m_windowHandle->maximumWidth()) 70 | : false; 71 | } 72 | inline bool isHostHeightFixed() const { 73 | return m_windowHandle 74 | ? ((m_windowHandle->flags() & Qt::MSWindowsFixedSizeDialogHint) || 75 | m_windowHandle->minimumHeight() == m_windowHandle->maximumHeight()) 76 | : false; 77 | } 78 | inline bool isHostSizeFixed() const { 79 | return m_windowHandle ? ((m_windowHandle->flags() & Qt::MSWindowsFixedSizeDialogHint) || 80 | m_windowHandle->minimumSize() == m_windowHandle->maximumSize()) 81 | : false; 82 | } 83 | 84 | virtual QString key() const; 85 | 86 | enum WindowContextHook { 87 | CentralizeHook = 1, 88 | RaiseWindowHook, 89 | ShowSystemMenuHook, 90 | DefaultColorsHook, 91 | DrawWindows10BorderHook, // Only works on Windows 10, emulated workaround 92 | DrawWindows10BorderHook2, // Only works on Windows 10, native workaround 93 | SystemButtonAreaChangedHook, // Only works on Mac 94 | }; 95 | virtual void virtual_hook(int id, void *data); 96 | 97 | void showSystemMenu(const QPoint &pos); 98 | void notifyWinIdChange(); 99 | 100 | virtual QVariant windowAttribute(const QString &key) const; 101 | virtual bool setWindowAttribute(const QString &key, const QVariant &attribute); 102 | 103 | protected: 104 | bool eventFilter(QObject *obj, QEvent *event) override; 105 | 106 | protected: 107 | virtual void winIdChanged(WId winId, WId oldWinId) = 0; 108 | virtual bool windowAttributeChanged(const QString &key, const QVariant &attribute, 109 | const QVariant &oldAttribute); 110 | 111 | protected: 112 | QObject *m_host{}; 113 | std::unique_ptr m_delegate; 114 | QPointer m_windowHandle; 115 | WId m_windowId{}; 116 | 117 | QSet m_hitTestVisibleItems; 118 | #ifdef Q_OS_MAC 119 | ScreenRectCallback m_systemButtonAreaCallback; 120 | #endif 121 | 122 | QObject *m_titleBar{}; 123 | std::array m_systemButtons{}; 124 | 125 | QVariantHash m_windowAttributes; 126 | std::unique_ptr m_winIdChangeEventFilter; 127 | }; 128 | 129 | inline QObject *AbstractWindowContext::host() const { 130 | return m_host; 131 | } 132 | 133 | inline QWindow *AbstractWindowContext::window() const { 134 | return m_windowHandle; 135 | } 136 | 137 | inline WId AbstractWindowContext::windowId() const { 138 | return m_windowId; 139 | } 140 | 141 | inline WindowItemDelegate *AbstractWindowContext::delegate() const { 142 | return m_delegate.get(); 143 | } 144 | 145 | inline bool AbstractWindowContext::isHitTestVisible(const QObject *obj) const { 146 | return m_hitTestVisibleItems.contains(obj); 147 | } 148 | 149 | inline QObject * 150 | AbstractWindowContext::systemButton(WindowAgentBase::SystemButton button) const { 151 | return m_systemButtons[button]; 152 | } 153 | 154 | inline QObject *AbstractWindowContext::titleBar() const { 155 | return m_titleBar; 156 | } 157 | 158 | #ifdef Q_OS_MAC 159 | inline ScreenRectCallback AbstractWindowContext::systemButtonAreaCallback() const { 160 | return m_systemButtonAreaCallback; 161 | } 162 | #endif 163 | 164 | } 165 | 166 | #endif // ABSTRACTWINDOWCONTEXT_P_H 167 | -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKCore/private/cocoawindowcontext_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef COCOAWINDOWCONTEXT_P_H 6 | #define COCOAWINDOWCONTEXT_P_H 7 | 8 | // 9 | // W A R N I N G !!! 10 | // ----------------- 11 | // 12 | // This file is not part of the QWindowKit API. It is used purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or may even be removed. 15 | // 16 | 17 | #include 18 | 19 | namespace QWK { 20 | 21 | class CocoaWindowContext : public AbstractWindowContext { 22 | Q_OBJECT 23 | public: 24 | CocoaWindowContext(); 25 | ~CocoaWindowContext() override; 26 | 27 | QString key() const override; 28 | void virtual_hook(int id, void *data) override; 29 | 30 | QVariant windowAttribute(const QString &key) const override; 31 | 32 | protected: 33 | void winIdChanged(WId winId, WId oldWinId) override; 34 | bool windowAttributeChanged(const QString &key, const QVariant &attribute, 35 | const QVariant &oldAttribute) override; 36 | 37 | protected: 38 | std::unique_ptr cocoaWindowEventFilter; 39 | }; 40 | 41 | } 42 | 43 | #endif // COCOAWINDOWCONTEXT_P_H 44 | -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKCore/private/nativeeventfilter_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef NATIVEEVENTFILTER_P_H 6 | #define NATIVEEVENTFILTER_P_H 7 | 8 | // 9 | // W A R N I N G !!! 10 | // ----------------- 11 | // 12 | // This file is not part of the QWindowKit API. It is used purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or may even be removed. 15 | // 16 | 17 | #include 18 | 19 | namespace QWK { 20 | 21 | class NativeEventFilter; 22 | 23 | class QWK_CORE_EXPORT NativeEventDispatcher { 24 | public: 25 | NativeEventDispatcher(); 26 | virtual ~NativeEventDispatcher(); 27 | 28 | public: 29 | virtual bool nativeDispatch(const QByteArray &eventType, void *message, 30 | QT_NATIVE_EVENT_RESULT_TYPE *result); 31 | 32 | public: 33 | void installNativeEventFilter(NativeEventFilter *filter); 34 | void removeNativeEventFilter(NativeEventFilter *filter); 35 | 36 | protected: 37 | QVector m_nativeEventFilters; 38 | 39 | friend class NativeEventFilter; 40 | 41 | Q_DISABLE_COPY(NativeEventDispatcher) 42 | }; 43 | 44 | class QWK_CORE_EXPORT NativeEventFilter { 45 | public: 46 | NativeEventFilter(); 47 | virtual ~NativeEventFilter(); 48 | 49 | public: 50 | virtual bool nativeEventFilter(const QByteArray &eventType, void *message, 51 | QT_NATIVE_EVENT_RESULT_TYPE *result) = 0; 52 | 53 | protected: 54 | NativeEventDispatcher *m_nativeDispatcher; 55 | 56 | friend class NativeEventDispatcher; 57 | 58 | Q_DISABLE_COPY(NativeEventFilter) 59 | }; 60 | 61 | // Automatically install to QCoreApplication at construction 62 | class QWK_CORE_EXPORT AppNativeEventFilter : public NativeEventFilter { 63 | public: 64 | AppNativeEventFilter(); 65 | ~AppNativeEventFilter() override; 66 | }; 67 | 68 | } 69 | 70 | #endif // NATIVEEVENTFILTER_P_H 71 | -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKCore/private/qtwindowcontext_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef QTWINDOWCONTEXT_P_H 6 | #define QTWINDOWCONTEXT_P_H 7 | 8 | // 9 | // W A R N I N G !!! 10 | // ----------------- 11 | // 12 | // This file is not part of the QWindowKit API. It is used purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or may even be removed. 15 | // 16 | 17 | #include 18 | 19 | namespace QWK { 20 | 21 | class QtWindowContext : public AbstractWindowContext { 22 | Q_OBJECT 23 | public: 24 | QtWindowContext(); 25 | ~QtWindowContext() override; 26 | 27 | QString key() const override; 28 | void virtual_hook(int id, void *data) override; 29 | 30 | protected: 31 | void winIdChanged(WId winId, WId oldWinId) override; 32 | 33 | protected: 34 | std::unique_ptr qtWindowEventFilter; 35 | }; 36 | 37 | } 38 | 39 | #endif // QTWINDOWCONTEXT_P_H 40 | -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKCore/private/qwkglobal_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef QWKGLOBAL_P_H 6 | #define QWKGLOBAL_P_H 7 | 8 | // 9 | // W A R N I N G !!! 10 | // ----------------- 11 | // 12 | // This file is not part of the QWindowKit API. It is used purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or may even be removed. 15 | // 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | 23 | QWK_CORE_EXPORT Q_DECLARE_LOGGING_CATEGORY(qWindowKitLog) 24 | 25 | #define QWK_INFO qCInfo(qWindowKitLog) 26 | #define QWK_DEBUG qCDebug(qWindowKitLog) 27 | #define QWK_WARNING qCWarning(qWindowKitLog) 28 | #define QWK_CRITICAL qCCritical(qWindowKitLog) 29 | #if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0) 30 | # define QWK_FATAL qCFatal(qWindowKitLog) 31 | #endif 32 | 33 | #define MAKE_RGB_COLOR(r, g, b) ((quint32) (((r) &0xFF) << 16) | (((g) &0xFF) << 8) | ((b) &0xFF)) 34 | 35 | #define MAKE_RGBA_COLOR(r, g, b, a) \ 36 | ((quint32) (((a) &0xFF) << 24) | (((r) &0xFF) << 16) | (((g) &0xFF) << 8) | ((b) &0xFF)) 37 | 38 | #if defined(Q_CC_MSVC) 39 | # define QWK_NOINLINE __declspec(noinline) 40 | # define QWK_INLINE __forceinline 41 | # define QWK_USED 42 | #else 43 | # define QWK_NOINLINE __attribute__((noinline)) 44 | # define QWK_INLINE __attribute__((always_inline)) 45 | # define QWK_USED __attribute__((used)) 46 | #endif 47 | 48 | namespace QWK { 49 | 50 | inline QPoint getMouseEventScenePos(const QMouseEvent *event) { 51 | #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 52 | return event->scenePosition().toPoint(); 53 | #else 54 | return event->windowPos().toPoint(); 55 | #endif 56 | } 57 | 58 | inline QPoint getMouseEventGlobalPos(const QMouseEvent *event) { 59 | #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 60 | return event->globalPosition().toPoint(); 61 | #else 62 | return event->screenPos().toPoint(); 63 | #endif 64 | } 65 | 66 | // Be careful when apply this function to a widget 67 | QWK_CORE_EXPORT bool forwardObjectEventFilters(QObject *currentFilter, QObject *receiver, 68 | QEvent *event); 69 | } 70 | 71 | #endif // QWKGLOBAL_P_H 72 | -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKCore/private/sharedeventfilter_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef SHAREDEVENTFILTER_P_H 6 | #define SHAREDEVENTFILTER_P_H 7 | 8 | // 9 | // W A R N I N G !!! 10 | // ----------------- 11 | // 12 | // This file is not part of the QWindowKit API. It is used purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or may even be removed. 15 | // 16 | 17 | #include 18 | 19 | namespace QWK { 20 | 21 | class SharedEventFilter; 22 | 23 | class QWK_CORE_EXPORT SharedEventDispatcher { 24 | public: 25 | SharedEventDispatcher(); 26 | virtual ~SharedEventDispatcher(); 27 | 28 | public: 29 | virtual bool sharedDispatch(QObject *obj, QEvent *event); 30 | 31 | public: 32 | void installSharedEventFilter(SharedEventFilter *filter); 33 | void removeSharedEventFilter(SharedEventFilter *filter); 34 | 35 | protected: 36 | QVector m_sharedEventFilters; 37 | 38 | friend class SharedEventFilter; 39 | 40 | Q_DISABLE_COPY(SharedEventDispatcher) 41 | }; 42 | 43 | class QWK_CORE_EXPORT SharedEventFilter { 44 | public: 45 | SharedEventFilter(); 46 | virtual ~SharedEventFilter(); 47 | 48 | public: 49 | virtual bool sharedEventFilter(QObject *obj, QEvent *event) = 0; 50 | 51 | protected: 52 | SharedEventDispatcher *m_sharedDispatcher; 53 | 54 | friend class SharedEventDispatcher; 55 | 56 | Q_DISABLE_COPY(SharedEventFilter) 57 | }; 58 | 59 | } 60 | 61 | #endif // SHAREDEVENTFILTER_P_H 62 | -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKCore/private/styleagent_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef STYLEAGENTPRIVATE_H 6 | #define STYLEAGENTPRIVATE_H 7 | 8 | // 9 | // W A R N I N G !!! 10 | // ----------------- 11 | // 12 | // This file is not part of the QWindowKit API. It is used purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or may even be removed. 15 | // 16 | 17 | #include 18 | 19 | #include 20 | 21 | namespace QWK { 22 | 23 | class StyleAgentPrivate : public QObject { 24 | Q_DECLARE_PUBLIC(StyleAgent) 25 | public: 26 | StyleAgentPrivate(); 27 | ~StyleAgentPrivate() override; 28 | 29 | void init(); 30 | 31 | StyleAgent *q_ptr; 32 | 33 | StyleAgent::SystemTheme systemTheme = StyleAgent::Unknown; 34 | 35 | void setupSystemThemeHook(); 36 | void removeSystemThemeHook(); 37 | 38 | void notifyThemeChanged(StyleAgent::SystemTheme theme); 39 | }; 40 | 41 | } 42 | 43 | #endif // STYLEAGENTPRIVATE_H -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKCore/private/systemwindow_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef SYSTEMWINDOW_P_H 6 | #define SYSTEMWINDOW_P_H 7 | 8 | // 9 | // W A R N I N G !!! 10 | // ----------------- 11 | // 12 | // This file is not part of the QWindowKit API. It is used purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or may even be removed. 15 | // 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | namespace QWK { 23 | 24 | class WindowMoveManipulator : public QObject { 25 | public: 26 | explicit WindowMoveManipulator(QWindow *targetWindow) 27 | : QObject(targetWindow), target(targetWindow), initialMousePosition(QCursor::pos()), 28 | initialWindowPosition(targetWindow->position()) { 29 | target->installEventFilter(this); 30 | } 31 | 32 | protected: 33 | bool eventFilter(QObject *obj, QEvent *event) override { 34 | switch (event->type()) { 35 | case QEvent::MouseMove: { 36 | auto mouseEvent = static_cast(event); 37 | QPoint delta = getMouseEventGlobalPos(mouseEvent) - initialMousePosition; 38 | target->setPosition(initialWindowPosition + delta); 39 | return true; 40 | } 41 | 42 | case QEvent::MouseButtonRelease: { 43 | if (target->y() < 0) { 44 | target->setPosition(target->x(), 0); 45 | } 46 | target->removeEventFilter(this); 47 | deleteLater(); 48 | } 49 | 50 | default: 51 | break; 52 | } 53 | return false; 54 | } 55 | 56 | private: 57 | QWindow *target; 58 | QPoint initialMousePosition; 59 | QPoint initialWindowPosition; 60 | }; 61 | 62 | class WindowResizeManipulator : public QObject { 63 | public: 64 | WindowResizeManipulator(QWindow *targetWindow, Qt::Edges edges) 65 | : QObject(targetWindow), target(targetWindow), resizeEdges(edges), 66 | initialMousePosition(QCursor::pos()), initialWindowRect(target->geometry()) { 67 | target->installEventFilter(this); 68 | } 69 | 70 | protected: 71 | bool eventFilter(QObject *obj, QEvent *event) override { 72 | switch (event->type()) { 73 | case QEvent::MouseMove: { 74 | auto mouseEvent = static_cast(event); 75 | QPoint globalMousePos = getMouseEventGlobalPos(mouseEvent); 76 | QRect windowRect = initialWindowRect; 77 | 78 | if (resizeEdges & Qt::LeftEdge) { 79 | int delta = globalMousePos.x() - initialMousePosition.x(); 80 | windowRect.setLeft(initialWindowRect.left() + delta); 81 | } 82 | if (resizeEdges & Qt::RightEdge) { 83 | int delta = globalMousePos.x() - initialMousePosition.x(); 84 | windowRect.setRight(initialWindowRect.right() + delta); 85 | } 86 | if (resizeEdges & Qt::TopEdge) { 87 | int delta = globalMousePos.y() - initialMousePosition.y(); 88 | windowRect.setTop(initialWindowRect.top() + delta); 89 | } 90 | if (resizeEdges & Qt::BottomEdge) { 91 | int delta = globalMousePos.y() - initialMousePosition.y(); 92 | windowRect.setBottom(initialWindowRect.bottom() + delta); 93 | } 94 | 95 | target->setGeometry(windowRect); 96 | return true; 97 | } 98 | 99 | case QEvent::MouseButtonRelease: { 100 | target->removeEventFilter(this); 101 | deleteLater(); 102 | } 103 | 104 | default: 105 | break; 106 | } 107 | return false; 108 | } 109 | 110 | private: 111 | QWindow *target; 112 | QPoint initialMousePosition; 113 | QRect initialWindowRect; 114 | Qt::Edges resizeEdges; 115 | }; 116 | 117 | // QWindow::startSystemMove() and QWindow::startSystemResize() is first supported at Qt 5.15 118 | // QWindow::startSystemResize() returns false on macOS 119 | // QWindow::startSystemMove() and QWindow::startSystemResize() returns false on Linux Unity DE 120 | 121 | // When the new API fails, we emulate the window actions using the classical API. 122 | 123 | inline void startSystemMove(QWindow *window) { 124 | #if (QT_VERSION < QT_VERSION_CHECK(5, 15, 0)) 125 | std::ignore = new WindowMoveManipulator(window); 126 | #elif defined(Q_OS_LINUX) 127 | if (window->startSystemMove()) { 128 | return; 129 | } 130 | std::ignore = new WindowMoveManipulator(window); 131 | #else 132 | window->startSystemMove(); 133 | #endif 134 | } 135 | 136 | inline void startSystemResize(QWindow *window, Qt::Edges edges) { 137 | #if (QT_VERSION < QT_VERSION_CHECK(5, 15, 0)) 138 | std::ignore = new WindowResizeManipulator(window, edges); 139 | #elif defined(Q_OS_MAC) || defined(Q_OS_LINUX) 140 | if (window->startSystemResize(edges)) { 141 | return; 142 | } 143 | std::ignore = new WindowResizeManipulator(window, edges); 144 | #else 145 | window->startSystemResize(edges); 146 | #endif 147 | } 148 | 149 | } 150 | 151 | #endif // SYSTEMWINDOW_P_H 152 | -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKCore/private/win32windowcontext_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef WIN32WINDOWCONTEXT_P_H 6 | #define WIN32WINDOWCONTEXT_P_H 7 | 8 | // 9 | // W A R N I N G !!! 10 | // ----------------- 11 | // 12 | // This file is not part of the QWindowKit API. It is used purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or may even be removed. 15 | // 16 | 17 | #include 18 | #include 19 | 20 | namespace QWK { 21 | 22 | class Win32WindowContext : public AbstractWindowContext { 23 | Q_OBJECT 24 | public: 25 | Win32WindowContext(); 26 | ~Win32WindowContext() override; 27 | 28 | enum WindowPart { 29 | Outside, 30 | ClientArea, 31 | ChromeButton, 32 | ResizeBorder, 33 | FixedBorder, 34 | TitleBar, 35 | }; 36 | Q_ENUM(WindowPart) 37 | 38 | QString key() const override; 39 | void virtual_hook(int id, void *data) override; 40 | 41 | QVariant windowAttribute(const QString &key) const override; 42 | 43 | protected: 44 | void winIdChanged(WId winId, WId oldWinId) override; 45 | bool windowAttributeChanged(const QString &key, const QVariant &attribute, 46 | const QVariant &oldAttribute) override; 47 | 48 | public: 49 | bool windowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result); 50 | 51 | bool systemMenuHandler(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, 52 | LRESULT *result); 53 | 54 | // In order to perfectly apply Windows 11 Snap Layout into the Qt window, we need to 55 | // intercept and emulate most of the mouse events, so that the processing logic 56 | // is quite complex. Simultaneously, in order to make the handling code of other 57 | // Windows messages clearer, we have separated them into this function. 58 | bool snapLayoutHandler(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, 59 | LRESULT *result); 60 | 61 | bool customWindowHandler(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, 62 | LRESULT *result); 63 | 64 | bool nonClientCalcSizeHandler(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, 65 | LRESULT *result); 66 | 67 | protected: 68 | // The last hit test result, helpful to handle WM_MOUSEMOVE and WM_NCMOUSELEAVE. 69 | WindowPart lastHitTestResult = WindowPart::Outside; 70 | int lastHitTestResultRaw = HTNOWHERE; 71 | 72 | // Whether the last mouse leave message is blocked, mainly for handling the unexpected 73 | // WM_MOUSELEAVE. 74 | bool mouseLeaveBlocked = false; 75 | 76 | // For emulating traditional icon button behavior 77 | uint64_t iconButtonClickTime = 0; 78 | int iconButtonClickLevel = 0; 79 | }; 80 | 81 | } 82 | 83 | #endif // WIN32WINDOWCONTEXT_P_H 84 | -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKCore/private/windowagentbase_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef WINDOWAGENTBASEPRIVATE_H 6 | #define WINDOWAGENTBASEPRIVATE_H 7 | 8 | // 9 | // W A R N I N G !!! 10 | // ----------------- 11 | // 12 | // This file is not part of the QWindowKit API. It is used purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or may even be removed. 15 | // 16 | 17 | #include 18 | #include 19 | 20 | namespace QWK { 21 | 22 | class QWK_CORE_EXPORT WindowAgentBasePrivate { 23 | Q_DECLARE_PUBLIC(WindowAgentBase) 24 | public: 25 | WindowAgentBasePrivate(); 26 | virtual ~WindowAgentBasePrivate(); 27 | 28 | void init(); 29 | 30 | WindowAgentBase *q_ptr; // no need to initialize 31 | 32 | virtual AbstractWindowContext *createContext() const; 33 | 34 | void setup(QObject *host, WindowItemDelegate *delegate); 35 | 36 | std::unique_ptr context; 37 | 38 | public: 39 | using WindowContextFactoryMethod = AbstractWindowContext *(*) (); 40 | 41 | static WindowContextFactoryMethod windowContextFactoryMethod; 42 | 43 | private: 44 | Q_DISABLE_COPY(WindowAgentBasePrivate) 45 | }; 46 | 47 | } 48 | 49 | #endif // WINDOWAGENTBASEPRIVATE_H -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKCore/private/windowitemdelegate_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef WINDOWITEMDELEGATE_P_H 6 | #define WINDOWITEMDELEGATE_P_H 7 | 8 | // 9 | // W A R N I N G !!! 10 | // ----------------- 11 | // 12 | // This file is not part of the QWindowKit API. It is used purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or may even be removed. 15 | // 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | namespace QWK { 25 | 26 | class QWK_CORE_EXPORT WindowItemDelegate { 27 | public: 28 | WindowItemDelegate(); 29 | virtual ~WindowItemDelegate(); 30 | 31 | public: 32 | // Item property query 33 | virtual QWindow *window(const QObject *obj) const = 0; 34 | virtual bool isEnabled(const QObject *obj) const = 0; 35 | virtual bool isVisible(const QObject *obj) const = 0; 36 | virtual QRect mapGeometryToScene(const QObject *obj) const = 0; 37 | 38 | // Host property query 39 | virtual QWindow *hostWindow(const QObject *host) const = 0; 40 | virtual bool isWindowActive(const QObject *host) const = 0; 41 | virtual Qt::WindowStates getWindowState(const QObject *host) const = 0; 42 | virtual Qt::WindowFlags getWindowFlags(const QObject *host) const = 0; 43 | virtual QRect getGeometry(const QObject *host) const = 0; 44 | 45 | // Callbacks 46 | virtual void resetQtGrabbedControl(QObject *host) const; 47 | virtual void setWindowState(QObject *host, Qt::WindowStates state) const = 0; 48 | virtual void setCursorShape(QObject *host, Qt::CursorShape shape) const = 0; 49 | virtual void restoreCursorShape(QObject *host) const = 0; 50 | virtual void setWindowFlags(QObject *host, Qt::WindowFlags flags) const = 0; 51 | virtual void setWindowVisible(QObject *host, bool visible) const = 0; 52 | virtual void setGeometry(QObject *host, const QRect &rect) = 0; 53 | virtual void bringWindowToTop(QObject *host) const = 0; 54 | 55 | // Factories 56 | virtual WinIdChangeEventFilter * 57 | createWinIdEventFilter(QObject *host, AbstractWindowContext *context) const; 58 | 59 | private: 60 | Q_DISABLE_COPY(WindowItemDelegate) 61 | }; 62 | 63 | } 64 | 65 | #endif // WINDOWITEMDELEGATE_P_H 66 | -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKCore/private/windows10borderhandler_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef WINDOWS10BORDERHANDLER_P_H 6 | #define WINDOWS10BORDERHANDLER_P_H 7 | 8 | // 9 | // W A R N I N G !!! 10 | // ----------------- 11 | // 12 | // This file is not part of the QWindowKit API. It is used purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or may even be removed. 15 | // 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | namespace QWK { 25 | 26 | class Windows10BorderHandler : public NativeEventFilter, public SharedEventFilter { 27 | public: 28 | inline Windows10BorderHandler(AbstractWindowContext *ctx) : ctx(ctx) { 29 | ctx->installNativeEventFilter(this); 30 | ctx->installSharedEventFilter(this); 31 | } 32 | 33 | inline void setupNecessaryAttributes() { 34 | // https://github.com/microsoft/terminal/blob/71a6f26e6ece656084e87de1a528c4a8072eeabd/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp#L940 35 | // Must extend top frame to client area 36 | static QVariant defaultMargins = QVariant::fromValue(QMargins(0, 1, 0, 0)); 37 | ctx->setWindowAttribute(QStringLiteral("extra-margins"), defaultMargins); 38 | 39 | // Enable dark mode by default, otherwise the system borders are white 40 | ctx->setWindowAttribute(QStringLiteral("dark-mode"), true); 41 | } 42 | 43 | inline bool isNormalWindow() const { 44 | return !(ctx->window()->windowStates() & 45 | (Qt::WindowMinimized | Qt::WindowMaximized | Qt::WindowFullScreen)); 46 | } 47 | 48 | inline void drawBorder() { 49 | ctx->virtual_hook(AbstractWindowContext::DrawWindows10BorderHook2, nullptr); 50 | } 51 | 52 | inline int borderThickness() const { 53 | return ctx->windowAttribute(QStringLiteral("border-thickness")).toInt(); 54 | } 55 | 56 | inline void updateExtraMargins(bool windowActive) { 57 | if (windowActive) { 58 | // Restore margins when the window is active 59 | static QVariant defaultMargins = QVariant::fromValue(QMargins(0, 1, 0, 0)); 60 | ctx->setWindowAttribute(QStringLiteral("extra-margins"), defaultMargins); 61 | return; 62 | } 63 | 64 | // https://github.com/microsoft/terminal/blob/71a6f26e6ece656084e87de1a528c4a8072eeabd/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp#L904 65 | // When the window is inactive, there is a transparency bug in the top 66 | // border, and we need to extend the non-client area to the whole title 67 | // bar. 68 | QRect frame = ctx->windowAttribute(QStringLiteral("window-rect")).toRect(); 69 | QMargins margins{0, -frame.top(), 0, 0}; 70 | ctx->setWindowAttribute(QStringLiteral("extra-margins"), QVariant::fromValue(margins)); 71 | } 72 | 73 | virtual void updateGeometry() = 0; 74 | 75 | virtual bool isWindowActive() const { 76 | return ctx->window()->isActive(); 77 | } 78 | 79 | protected: 80 | bool nativeEventFilter(const QByteArray &eventType, void *message, 81 | QT_NATIVE_EVENT_RESULT_TYPE *result) override { 82 | Q_UNUSED(eventType) 83 | 84 | const auto msg = static_cast(message); 85 | switch (msg->message) { 86 | case WM_DPICHANGED: { 87 | updateGeometry(); 88 | updateExtraMargins(isWindowActive()); 89 | break; 90 | } 91 | 92 | case WM_ACTIVATE: { 93 | updateExtraMargins(LOWORD(msg->wParam) != WA_INACTIVE); 94 | break; 95 | } 96 | 97 | default: 98 | break; 99 | } 100 | return false; 101 | } 102 | 103 | bool sharedEventFilter(QObject *obj, QEvent *event) override { 104 | Q_UNUSED(obj) 105 | 106 | if (event->type() == QEvent::WinIdChange) { 107 | if (ctx->windowId()) { 108 | setupNecessaryAttributes(); 109 | updateGeometry(); 110 | } 111 | } 112 | return false; 113 | } 114 | 115 | protected: 116 | AbstractWindowContext *ctx; 117 | }; 118 | 119 | } 120 | 121 | #endif // WINDOWS10BORDERHANDLER_P_H 122 | -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKCore/private/winidchangeeventfilter_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef WINIDCHANGEEVENTFILTER_P_H 6 | #define WINIDCHANGEEVENTFILTER_P_H 7 | 8 | // 9 | // W A R N I N G !!! 10 | // ----------------- 11 | // 12 | // This file is not part of the QWindowKit API. It is used purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or may even be removed. 15 | // 16 | 17 | #include 18 | 19 | #include 20 | 21 | namespace QWK { 22 | 23 | class AbstractWindowContext; 24 | 25 | class WinIdChangeEventFilter : public QObject { 26 | public: 27 | WinIdChangeEventFilter(QObject *host, AbstractWindowContext *context) 28 | : host(host), context(context) { 29 | } 30 | 31 | virtual WId winId() const = 0; 32 | 33 | protected: 34 | QObject *host; 35 | AbstractWindowContext *context; 36 | }; 37 | 38 | class QWK_CORE_EXPORT WindowWinIdChangeEventFilter : public WinIdChangeEventFilter { 39 | public: 40 | WindowWinIdChangeEventFilter(QWindow *host, AbstractWindowContext *context); 41 | 42 | WId winId() const override; 43 | 44 | protected: 45 | QWindow *win; 46 | bool isAboutToBeDestroyed; 47 | 48 | bool eventFilter(QObject *obj, QEvent *event) override; 49 | }; 50 | 51 | } 52 | 53 | #endif // WINIDCHANGEEVENTFILTER_P_H 54 | -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKCore/qwindowkit_linux.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef QWINDOWKIT_LINUX_H 6 | #define QWINDOWKIT_LINUX_H 7 | 8 | 9 | #endif // QWINDOWKIT_LINUX_H 10 | -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKCore/qwindowkit_windows.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef QWINDOWKIT_WINDOWS_H 6 | #define QWINDOWKIT_WINDOWS_H 7 | 8 | #include 9 | #include 10 | 11 | #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) 12 | # include 13 | #endif 14 | 15 | #include 16 | 17 | #ifndef GET_X_LPARAM 18 | # define GET_X_LPARAM(lp) (static_cast(static_cast(LOWORD(lp)))) 19 | #endif 20 | 21 | #ifndef GET_Y_LPARAM 22 | # define GET_Y_LPARAM(lp) (static_cast(static_cast(HIWORD(lp)))) 23 | #endif 24 | 25 | #ifndef RECT_WIDTH 26 | # define RECT_WIDTH(rect) ((rect).right - (rect).left) 27 | #endif 28 | 29 | #ifndef RECT_HEIGHT 30 | # define RECT_HEIGHT(rect) ((rect).bottom - (rect).top) 31 | #endif 32 | 33 | // Maybe undocumented Windows messages 34 | // https://github.com/tinysec/public/blob/master/win32k/MessageTable.md 35 | // https://ulib.sourceforge.io/doxy/a00239.html 36 | #ifndef WM_UAHDESTROYWINDOW 37 | # define WM_UAHDESTROYWINDOW (0x0090) 38 | #endif 39 | 40 | #ifndef WM_UNREGISTER_WINDOW_SERVICES 41 | # define WM_UNREGISTER_WINDOW_SERVICES (0x0272) 42 | #endif 43 | 44 | #ifndef WM_NCUAHDRAWCAPTION 45 | # define WM_NCUAHDRAWCAPTION (0x00AE) 46 | #endif 47 | 48 | #ifndef WM_NCUAHDRAWFRAME 49 | # define WM_NCUAHDRAWFRAME (0x00AF) 50 | #endif 51 | 52 | namespace QWK { 53 | 54 | namespace Private { 55 | 56 | QWK_CORE_EXPORT RTL_OSVERSIONINFOW GetRealOSVersion(); 57 | 58 | inline bool IsWindows1122H2OrGreater_Real() { 59 | RTL_OSVERSIONINFOW rovi = GetRealOSVersion(); 60 | return (rovi.dwMajorVersion > 10) || 61 | (rovi.dwMajorVersion == 10 && rovi.dwMinorVersion >= 0 && 62 | rovi.dwBuildNumber >= 22621); 63 | } 64 | 65 | inline bool IsWindows11OrGreater_Real() { 66 | RTL_OSVERSIONINFOW rovi = GetRealOSVersion(); 67 | return (rovi.dwMajorVersion > 10) || 68 | (rovi.dwMajorVersion == 10 && rovi.dwMinorVersion >= 0 && 69 | rovi.dwBuildNumber >= 22000); 70 | } 71 | 72 | inline bool IsWindows101903OrGreater_Real() { 73 | RTL_OSVERSIONINFOW rovi = GetRealOSVersion(); 74 | return (rovi.dwMajorVersion > 10) || 75 | (rovi.dwMajorVersion == 10 && rovi.dwMinorVersion >= 0 && 76 | rovi.dwBuildNumber >= 18362); 77 | } 78 | 79 | inline bool IsWindows101809OrGreater_Real() { 80 | RTL_OSVERSIONINFOW rovi = GetRealOSVersion(); 81 | return (rovi.dwMajorVersion > 10) || 82 | (rovi.dwMajorVersion == 10 && rovi.dwMinorVersion >= 0 && 83 | rovi.dwBuildNumber >= 17763); 84 | } 85 | 86 | inline bool IsWindows10OrGreater_Real() { 87 | RTL_OSVERSIONINFOW rovi = GetRealOSVersion(); 88 | return (rovi.dwMajorVersion > 10) || 89 | (rovi.dwMajorVersion == 10 && rovi.dwMinorVersion >= 0); 90 | } 91 | 92 | inline bool IsWindows8Point1OrGreater_Real() { 93 | RTL_OSVERSIONINFOW rovi = GetRealOSVersion(); 94 | return (rovi.dwMajorVersion > 6) || 95 | (rovi.dwMajorVersion == 6 && rovi.dwMinorVersion >= 3); 96 | } 97 | 98 | inline bool IsWindows8OrGreater_Real() { 99 | RTL_OSVERSIONINFOW rovi = GetRealOSVersion(); 100 | return (rovi.dwMajorVersion > 6) || 101 | (rovi.dwMajorVersion == 6 && rovi.dwMinorVersion >= 2); 102 | } 103 | 104 | inline bool IsWindows10Only_Real() { 105 | return IsWindows10OrGreater_Real() && !IsWindows11OrGreater_Real(); 106 | } 107 | 108 | } 109 | 110 | // 111 | // Registry Helpers 112 | // 113 | 114 | #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 115 | class QWK_CORE_EXPORT WindowsRegistryKey { 116 | public: 117 | WindowsRegistryKey(HKEY parentHandle, QStringView subKey, REGSAM permissions = KEY_READ, 118 | REGSAM access = 0); 119 | 120 | ~WindowsRegistryKey(); 121 | 122 | inline bool isValid() const; 123 | 124 | void close(); 125 | QString stringValue(QStringView subKey) const; 126 | QPair dwordValue(QStringView subKey) const; 127 | 128 | private: 129 | HKEY m_key; 130 | 131 | Q_DISABLE_COPY(WindowsRegistryKey) 132 | }; 133 | 134 | inline bool WindowsRegistryKey::isValid() const { 135 | return m_key != nullptr; 136 | } 137 | #else 138 | using WindowsRegistryKey = QWinRegistryKey; 139 | #endif 140 | 141 | // 142 | // Version Helpers 143 | // 144 | 145 | static inline bool isWin8OrGreater() { 146 | static const bool result = Private::IsWindows8OrGreater_Real(); 147 | return result; 148 | } 149 | 150 | static inline bool isWin8Point1OrGreater() { 151 | static const bool result = Private::IsWindows8Point1OrGreater_Real(); 152 | return result; 153 | } 154 | 155 | static inline bool isWin10OrGreater() { 156 | static const bool result = Private::IsWindows10OrGreater_Real(); 157 | return result; 158 | } 159 | 160 | static inline bool isWin101809OrGreater() { 161 | static const bool result = Private::IsWindows101809OrGreater_Real(); 162 | return result; 163 | } 164 | 165 | static inline bool isWin101903OrGreater() { 166 | static const bool result = Private::IsWindows101903OrGreater_Real(); 167 | return result; 168 | } 169 | 170 | static inline bool isWin11OrGreater() { 171 | static const bool result = Private::IsWindows11OrGreater_Real(); 172 | return result; 173 | } 174 | 175 | static inline bool isWin1122H2OrGreater() { 176 | static const bool result = Private::IsWindows1122H2OrGreater_Real(); 177 | return result; 178 | } 179 | 180 | static inline bool isWin10Only() { 181 | static const bool result = Private::IsWindows10Only_Real(); 182 | return result; 183 | }; 184 | 185 | // 186 | // Native Event Helpers 187 | // 188 | 189 | inline bool isImmersiveColorSetChange(WPARAM wParam, LPARAM lParam) { 190 | return !wParam && lParam && 191 | std::wcscmp(reinterpret_cast(lParam), L"ImmersiveColorSet") == 0; 192 | } 193 | 194 | } 195 | 196 | #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 197 | Q_DECLARE_METATYPE(QMargins) 198 | #endif 199 | 200 | #endif // QWINDOWKIT_WINDOWS_H 201 | -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKCore/qwkconfig.h: -------------------------------------------------------------------------------- 1 | #ifndef QWKCONFIG_H 2 | #define QWKCONFIG_H 3 | 4 | // Caution: This file is generated by CMake automatically during configure. 5 | // WARNING!!! DO NOT EDIT THIS FILE MANUALLY!!! 6 | // ALL YOUR MODIFICATIONS HERE WILL GET LOST AFTER RE-CONFIGURING!!! 7 | 8 | // SHA256: 5eedba1d60d689379aac55a9b6e19aefaf5d77f89fe4e633de5642b1f2d87e86 9 | 10 | #define QWINDOWKIT_ENABLE_QT_WINDOW_CONTEXT -1 11 | #define QWINDOWKIT_ENABLE_STYLE_AGENT 1 12 | #define QWINDOWKIT_ENABLE_WINDOWS_SYSTEM_BORDERS 1 13 | 14 | #endif // QWKCONFIG_H 15 | -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKCore/qwkglobal.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef QWKGLOBAL_H 6 | #define QWKGLOBAL_H 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #ifndef QWK_CORE_EXPORT 14 | # ifdef QWK_CORE_STATIC 15 | # define QWK_CORE_EXPORT 16 | # else 17 | # ifdef QWK_CORE_LIBRARY 18 | # define QWK_CORE_EXPORT Q_DECL_EXPORT 19 | # else 20 | # define QWK_CORE_EXPORT Q_DECL_IMPORT 21 | # endif 22 | # endif 23 | #endif 24 | 25 | #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) 26 | using QT_NATIVE_EVENT_RESULT_TYPE = qintptr; 27 | using QT_ENTER_EVENT_TYPE = QEnterEvent; 28 | #else 29 | using QT_NATIVE_EVENT_RESULT_TYPE = long; 30 | using QT_ENTER_EVENT_TYPE = QEvent; 31 | #endif 32 | 33 | #ifndef QWINDOWKIT_CONFIG 34 | # define QWINDOWKIT_CONFIG(feature) ((1 / QWINDOWKIT_##feature) == 1) 35 | #endif 36 | 37 | namespace QWK { 38 | 39 | using ScreenRectCallback = std::function; 40 | 41 | } 42 | 43 | #endif // QWKGLOBAL_H 44 | -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKCore/styleagent.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef STYLEAGENT_H 6 | #define STYLEAGENT_H 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace QWK { 16 | 17 | class StyleAgentPrivate; 18 | 19 | class QWK_CORE_EXPORT StyleAgent : public QObject { 20 | Q_OBJECT 21 | Q_DECLARE_PRIVATE(StyleAgent) 22 | public: 23 | explicit StyleAgent(QObject *parent = nullptr); 24 | ~StyleAgent() override; 25 | 26 | enum SystemTheme { 27 | Unknown, 28 | Light, 29 | Dark, 30 | HighContrast, 31 | }; 32 | Q_ENUM(SystemTheme) 33 | 34 | public: 35 | SystemTheme systemTheme() const; 36 | 37 | Q_SIGNALS: 38 | void systemThemeChanged(); 39 | 40 | protected: 41 | StyleAgent(StyleAgentPrivate &d, QObject *parent = nullptr); 42 | 43 | const std::unique_ptr d_ptr; 44 | }; 45 | 46 | } 47 | 48 | #endif // STYLEAGENT_H -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKCore/windowagentbase.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef WINDOWAGENTBASE_H 6 | #define WINDOWAGENTBASE_H 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | 14 | namespace QWK { 15 | 16 | class WindowAgentBasePrivate; 17 | 18 | class QWK_CORE_EXPORT WindowAgentBase : public QObject { 19 | Q_OBJECT 20 | Q_DECLARE_PRIVATE(WindowAgentBase) 21 | public: 22 | ~WindowAgentBase() override; 23 | 24 | enum SystemButton { 25 | Unknown, 26 | WindowIcon, 27 | Help, 28 | Minimize, 29 | Maximize, 30 | Close, 31 | }; 32 | Q_ENUM(SystemButton) 33 | 34 | QVariant windowAttribute(const QString &key) const; 35 | Q_INVOKABLE bool setWindowAttribute(const QString &key, const QVariant &attribute); 36 | 37 | public Q_SLOTS: 38 | void showSystemMenu(const QPoint &pos); // Only available on Windows now 39 | void centralize(); 40 | void raise(); 41 | 42 | protected: 43 | explicit WindowAgentBase(WindowAgentBasePrivate &d, QObject *parent = nullptr); 44 | 45 | const std::unique_ptr d_ptr; 46 | }; 47 | 48 | } 49 | 50 | #endif // WINDOWAGENTBASE_H -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKWidgets/private/widgetitemdelegate_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef WIDGETITEMDELEGATE_P_H 6 | #define WIDGETITEMDELEGATE_P_H 7 | 8 | // 9 | // W A R N I N G !!! 10 | // ----------------- 11 | // 12 | // This file is not part of the QWindowKit API. It is used purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or may even be removed. 15 | // 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | namespace QWK { 24 | 25 | class QWK_WIDGETS_EXPORT WidgetItemDelegate : public WindowItemDelegate { 26 | public: 27 | WidgetItemDelegate(); 28 | ~WidgetItemDelegate() override; 29 | 30 | public: 31 | QWindow *window(const QObject *obj) const override; 32 | bool isEnabled(const QObject *obj) const override; 33 | bool isVisible(const QObject *obj) const override; 34 | QRect mapGeometryToScene(const QObject *obj) const override; 35 | 36 | QWindow *hostWindow(const QObject *host) const override; 37 | bool isWindowActive(const QObject *host) const override; 38 | Qt::WindowStates getWindowState(const QObject *host) const override; 39 | Qt::WindowFlags getWindowFlags(const QObject *host) const override; 40 | QRect getGeometry(const QObject *host) const override; 41 | 42 | void resetQtGrabbedControl(QObject *host) const override; 43 | void setWindowState(QObject *host, Qt::WindowStates state) const override; 44 | void setCursorShape(QObject *host, Qt::CursorShape shape) const override; 45 | void restoreCursorShape(QObject *host) const override; 46 | void setWindowFlags(QObject *host, Qt::WindowFlags flags) const override; 47 | void setWindowVisible(QObject *host, bool visible) const override; 48 | void setGeometry(QObject *host, const QRect &rect) override; 49 | void bringWindowToTop(QObject *host) const override; 50 | 51 | WinIdChangeEventFilter * 52 | createWinIdEventFilter(QObject *host, AbstractWindowContext *context) const override; 53 | }; 54 | 55 | } 56 | 57 | #endif // WIDGETITEMDELEGATE_P_H 58 | -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKWidgets/private/widgetwindowagent_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef WIDGETWINDOWAGENTPRIVATE_H 6 | #define WIDGETWINDOWAGENTPRIVATE_H 7 | 8 | // 9 | // W A R N I N G !!! 10 | // ----------------- 11 | // 12 | // This file is not part of the QWindowKit API. It is used purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or may even be removed. 15 | // 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | namespace QWK { 22 | 23 | class WidgetWindowAgentPrivate : public WindowAgentBasePrivate { 24 | Q_DECLARE_PUBLIC(WidgetWindowAgent) 25 | public: 26 | WidgetWindowAgentPrivate(); 27 | ~WidgetWindowAgentPrivate(); 28 | 29 | void init(); 30 | 31 | // Host 32 | QWidget *hostWidget{}; 33 | 34 | #ifdef Q_OS_MAC 35 | QWidget *systemButtonAreaWidget{}; 36 | std::unique_ptr systemButtonAreaWidgetEventFilter; 37 | #endif 38 | 39 | #if defined(Q_OS_WINDOWS) && QWINDOWKIT_CONFIG(ENABLE_WINDOWS_SYSTEM_BORDERS) 40 | void setupWindows10BorderWorkaround(); 41 | std::unique_ptr borderHandler; 42 | #endif 43 | }; 44 | 45 | } 46 | 47 | #endif // WIDGETWINDOWAGENTPRIVATE_H 48 | -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKWidgets/qwkwidgetsglobal.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef QWKWIDGETSGLOBAL_H 6 | #define QWKWIDGETSGLOBAL_H 7 | 8 | #include 9 | 10 | #ifndef QWK_WIDGETS_EXPORT 11 | # ifdef QWK_WIDGETS_STATIC 12 | # define QWK_WIDGETS_EXPORT 13 | # else 14 | # ifdef QWK_WIDGETS_LIBRARY 15 | # define QWK_WIDGETS_EXPORT Q_DECL_EXPORT 16 | # else 17 | # define QWK_WIDGETS_EXPORT Q_DECL_IMPORT 18 | # endif 19 | # endif 20 | #endif 21 | 22 | #endif // QWKWIDGETSGLOBAL_H 23 | -------------------------------------------------------------------------------- /deps/qwindowkit/include/QWindowKit/QWKWidgets/widgetwindowagent.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef WIDGETWINDOWAGENT_H 6 | #define WIDGETWINDOWAGENT_H 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | namespace QWK { 14 | 15 | class WidgetWindowAgentPrivate; 16 | 17 | class QWK_WIDGETS_EXPORT WidgetWindowAgent : public WindowAgentBase { 18 | Q_OBJECT 19 | Q_DECLARE_PRIVATE(WidgetWindowAgent) 20 | public: 21 | explicit WidgetWindowAgent(QObject *parent = nullptr); 22 | ~WidgetWindowAgent() override; 23 | 24 | public: 25 | bool setup(QWidget *w); 26 | 27 | QWidget *titleBar() const; 28 | void setTitleBar(QWidget *w); 29 | 30 | QWidget *systemButton(SystemButton button) const; 31 | void setSystemButton(SystemButton button, QWidget *w); 32 | 33 | #ifdef Q_OS_MAC 34 | // The system button area APIs are experimental, very likely to change in the future. 35 | QWidget *systemButtonArea() const; 36 | void setSystemButtonArea(QWidget *widget); 37 | 38 | ScreenRectCallback systemButtonAreaCallback() const; 39 | void setSystemButtonAreaCallback(const ScreenRectCallback &callback); 40 | #endif 41 | 42 | bool isHitTestVisible(const QWidget *w) const; 43 | void setHitTestVisible(const QWidget *w, bool visible = true); 44 | 45 | Q_SIGNALS: 46 | void titleBarChanged(QWidget *w); 47 | void systemButtonChanged(SystemButton button, QWidget *w); 48 | 49 | protected: 50 | WidgetWindowAgent(WidgetWindowAgentPrivate &d, QObject *parent = nullptr); 51 | }; 52 | 53 | } 54 | 55 | #endif // WIDGETWINDOWAGENT_H -------------------------------------------------------------------------------- /deps/qwindowkit/lib/cmake/QWindowKit/QWindowKitConfig.cmake: -------------------------------------------------------------------------------- 1 | 2 | ####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() ####### 3 | ####### Any changes to this file will be overwritten by the next CMake run #### 4 | ####### The input file was QWindowKitConfig.cmake.in ######## 5 | 6 | get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE) 7 | 8 | macro(set_and_check _var _file) 9 | set(${_var} "${_file}") 10 | if(NOT EXISTS "${_file}") 11 | message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !") 12 | endif() 13 | endmacro() 14 | 15 | #################################################################################### 16 | 17 | include(CMakeFindDependencyMacro) 18 | 19 | find_dependency(QT NAMES Qt6 Qt5 COMPONENTS Core Gui REQUIRED) 20 | find_dependency(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui REQUIRED) 21 | 22 | if ("Widgets" IN_LIST QWindowKit_FIND_COMPONENTS) 23 | find_dependency(QT NAMES Qt6 Qt5 COMPONENTS Widgets REQUIRED) 24 | find_dependency(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets REQUIRED) 25 | endif() 26 | 27 | if ("Quick" IN_LIST QWindowKit_FIND_COMPONENTS) 28 | find_dependency(QT NAMES Qt6 Qt5 COMPONENTS Quick REQUIRED) 29 | find_dependency(Qt${QT_VERSION_MAJOR} COMPONENTS Quick REQUIRED) 30 | endif() 31 | 32 | include("${CMAKE_CURRENT_LIST_DIR}/QWindowKitTargets.cmake") 33 | -------------------------------------------------------------------------------- /deps/qwindowkit/lib/cmake/QWindowKit/QWindowKitConfigVersion.cmake: -------------------------------------------------------------------------------- 1 | # This is a basic version file for the Config-mode of find_package(). 2 | # It is used by write_basic_package_version_file() as input file for configure_file() 3 | # to create a version-file which can be installed along a config.cmake file. 4 | # 5 | # The created file sets PACKAGE_VERSION_EXACT if the current version string and 6 | # the requested version string are exactly the same and it sets 7 | # PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version. 8 | # The variable CVF_VERSION must be set before calling configure_file(). 9 | 10 | set(PACKAGE_VERSION "1.1.1.0") 11 | 12 | if (PACKAGE_FIND_VERSION_RANGE) 13 | # Package version must be in the requested version range 14 | if ((PACKAGE_FIND_VERSION_RANGE_MIN STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MIN) 15 | OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_GREATER PACKAGE_FIND_VERSION_MAX) 16 | OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND PACKAGE_VERSION VERSION_GREATER_EQUAL PACKAGE_FIND_VERSION_MAX))) 17 | set(PACKAGE_VERSION_COMPATIBLE FALSE) 18 | else() 19 | set(PACKAGE_VERSION_COMPATIBLE TRUE) 20 | endif() 21 | else() 22 | if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) 23 | set(PACKAGE_VERSION_COMPATIBLE FALSE) 24 | else() 25 | set(PACKAGE_VERSION_COMPATIBLE TRUE) 26 | if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) 27 | set(PACKAGE_VERSION_EXACT TRUE) 28 | endif() 29 | endif() 30 | endif() 31 | 32 | 33 | # if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: 34 | if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "") 35 | return() 36 | endif() 37 | 38 | # check that the installed version has the same 32/64bit-ness as the one which is currently searching: 39 | if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "8") 40 | math(EXPR installedBits "8 * 8") 41 | set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") 42 | set(PACKAGE_VERSION_UNSUITABLE TRUE) 43 | endif() 44 | -------------------------------------------------------------------------------- /deps/qwindowkit/lib/cmake/QWindowKit/QWindowKitTargets-debug.cmake: -------------------------------------------------------------------------------- 1 | #---------------------------------------------------------------- 2 | # Generated CMake target import file for configuration "Debug". 3 | #---------------------------------------------------------------- 4 | 5 | # Commands may need to know the format version. 6 | set(CMAKE_IMPORT_FILE_VERSION 1) 7 | 8 | # Import target "QWindowKit::Core" for configuration "Debug" 9 | set_property(TARGET QWindowKit::Core APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) 10 | set_target_properties(QWindowKit::Core PROPERTIES 11 | IMPORTED_IMPLIB_DEBUG "${_IMPORT_PREFIX}/lib/libQWKCore.dll.a" 12 | IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/bin/QWKCore.dll" 13 | ) 14 | 15 | list(APPEND _cmake_import_check_targets QWindowKit::Core ) 16 | list(APPEND _cmake_import_check_files_for_QWindowKit::Core "${_IMPORT_PREFIX}/lib/libQWKCore.dll.a" "${_IMPORT_PREFIX}/bin/QWKCore.dll" ) 17 | 18 | # Import target "QWindowKit::Widgets" for configuration "Debug" 19 | set_property(TARGET QWindowKit::Widgets APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) 20 | set_target_properties(QWindowKit::Widgets PROPERTIES 21 | IMPORTED_IMPLIB_DEBUG "${_IMPORT_PREFIX}/lib/libQWKWidgets.dll.a" 22 | IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/bin/QWKWidgets.dll" 23 | ) 24 | 25 | list(APPEND _cmake_import_check_targets QWindowKit::Widgets ) 26 | list(APPEND _cmake_import_check_files_for_QWindowKit::Widgets "${_IMPORT_PREFIX}/lib/libQWKWidgets.dll.a" "${_IMPORT_PREFIX}/bin/QWKWidgets.dll" ) 27 | 28 | # Commands beyond this point should not need to know the version. 29 | set(CMAKE_IMPORT_FILE_VERSION) 30 | -------------------------------------------------------------------------------- /deps/qwindowkit/lib/cmake/QWindowKit/QWindowKitTargets-release.cmake: -------------------------------------------------------------------------------- 1 | #---------------------------------------------------------------- 2 | # Generated CMake target import file for configuration "Release". 3 | #---------------------------------------------------------------- 4 | 5 | # Commands may need to know the format version. 6 | set(CMAKE_IMPORT_FILE_VERSION 1) 7 | 8 | # Import target "QWindowKit::Core" for configuration "Release" 9 | set_property(TARGET QWindowKit::Core APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) 10 | set_target_properties(QWindowKit::Core PROPERTIES 11 | IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/libQWKCore.dll.a" 12 | IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/QWKCore.dll" 13 | ) 14 | 15 | list(APPEND _cmake_import_check_targets QWindowKit::Core ) 16 | list(APPEND _cmake_import_check_files_for_QWindowKit::Core "${_IMPORT_PREFIX}/lib/libQWKCore.dll.a" "${_IMPORT_PREFIX}/bin/QWKCore.dll" ) 17 | 18 | # Import target "QWindowKit::Widgets" for configuration "Release" 19 | set_property(TARGET QWindowKit::Widgets APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) 20 | set_target_properties(QWindowKit::Widgets PROPERTIES 21 | IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/libQWKWidgets.dll.a" 22 | IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/QWKWidgets.dll" 23 | ) 24 | 25 | list(APPEND _cmake_import_check_targets QWindowKit::Widgets ) 26 | list(APPEND _cmake_import_check_files_for_QWindowKit::Widgets "${_IMPORT_PREFIX}/lib/libQWKWidgets.dll.a" "${_IMPORT_PREFIX}/bin/QWKWidgets.dll" ) 27 | 28 | # Commands beyond this point should not need to know the version. 29 | set(CMAKE_IMPORT_FILE_VERSION) 30 | -------------------------------------------------------------------------------- /deps/qwindowkit/lib/cmake/QWindowKit/QWindowKitTargets.cmake: -------------------------------------------------------------------------------- 1 | # Generated by CMake 2 | 3 | if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.8) 4 | message(FATAL_ERROR "CMake >= 2.8.0 required") 5 | endif() 6 | if(CMAKE_VERSION VERSION_LESS "2.8.12") 7 | message(FATAL_ERROR "CMake >= 2.8.12 required") 8 | endif() 9 | cmake_policy(PUSH) 10 | cmake_policy(VERSION 2.8.12...3.27) 11 | #---------------------------------------------------------------- 12 | # Generated CMake target import file. 13 | #---------------------------------------------------------------- 14 | 15 | # Commands may need to know the format version. 16 | set(CMAKE_IMPORT_FILE_VERSION 1) 17 | 18 | # Protect against multiple inclusion, which would fail when already imported targets are added once more. 19 | set(_cmake_targets_defined "") 20 | set(_cmake_targets_not_defined "") 21 | set(_cmake_expected_targets "") 22 | foreach(_cmake_expected_target IN ITEMS QWindowKit::Core QWindowKit::Widgets) 23 | list(APPEND _cmake_expected_targets "${_cmake_expected_target}") 24 | if(TARGET "${_cmake_expected_target}") 25 | list(APPEND _cmake_targets_defined "${_cmake_expected_target}") 26 | else() 27 | list(APPEND _cmake_targets_not_defined "${_cmake_expected_target}") 28 | endif() 29 | endforeach() 30 | unset(_cmake_expected_target) 31 | if(_cmake_targets_defined STREQUAL _cmake_expected_targets) 32 | unset(_cmake_targets_defined) 33 | unset(_cmake_targets_not_defined) 34 | unset(_cmake_expected_targets) 35 | unset(CMAKE_IMPORT_FILE_VERSION) 36 | cmake_policy(POP) 37 | return() 38 | endif() 39 | if(NOT _cmake_targets_defined STREQUAL "") 40 | string(REPLACE ";" ", " _cmake_targets_defined_text "${_cmake_targets_defined}") 41 | string(REPLACE ";" ", " _cmake_targets_not_defined_text "${_cmake_targets_not_defined}") 42 | message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_cmake_targets_defined_text}\nTargets not yet defined: ${_cmake_targets_not_defined_text}\n") 43 | endif() 44 | unset(_cmake_targets_defined) 45 | unset(_cmake_targets_not_defined) 46 | unset(_cmake_expected_targets) 47 | 48 | 49 | # Compute the installation prefix relative to this file. 50 | get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH) 51 | get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) 52 | get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) 53 | get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) 54 | if(_IMPORT_PREFIX STREQUAL "/") 55 | set(_IMPORT_PREFIX "") 56 | endif() 57 | 58 | # Create imported target QWindowKit::Core 59 | add_library(QWindowKit::Core SHARED IMPORTED) 60 | 61 | set_target_properties(QWindowKit::Core PROPERTIES 62 | INTERFACE_COMPILE_FEATURES "cxx_std_17" 63 | INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include/QWindowKit" 64 | INTERFACE_LINK_LIBRARIES "Qt6::Core;Qt6::Gui" 65 | ) 66 | 67 | # Create imported target QWindowKit::Widgets 68 | add_library(QWindowKit::Widgets SHARED IMPORTED) 69 | 70 | set_target_properties(QWindowKit::Widgets PROPERTIES 71 | INTERFACE_COMPILE_FEATURES "cxx_std_17" 72 | INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include/QWindowKit" 73 | INTERFACE_LINK_LIBRARIES "QWindowKit::Core;Qt6::Core;Qt6::Gui;Qt6::Widgets" 74 | ) 75 | 76 | # Load information for each installed configuration. 77 | file(GLOB _cmake_config_files "${CMAKE_CURRENT_LIST_DIR}/QWindowKitTargets-*.cmake") 78 | foreach(_cmake_config_file IN LISTS _cmake_config_files) 79 | include("${_cmake_config_file}") 80 | endforeach() 81 | unset(_cmake_config_file) 82 | unset(_cmake_config_files) 83 | 84 | # Cleanup temporary variables. 85 | set(_IMPORT_PREFIX) 86 | 87 | # Loop over all imported files and verify that they actually exist 88 | foreach(_cmake_target IN LISTS _cmake_import_check_targets) 89 | if(CMAKE_VERSION VERSION_LESS "3.28" 90 | OR NOT DEFINED _cmake_import_check_xcframework_for_${_cmake_target} 91 | OR NOT IS_DIRECTORY "${_cmake_import_check_xcframework_for_${_cmake_target}}") 92 | foreach(_cmake_file IN LISTS "_cmake_import_check_files_for_${_cmake_target}") 93 | if(NOT EXISTS "${_cmake_file}") 94 | message(FATAL_ERROR "The imported target \"${_cmake_target}\" references the file 95 | \"${_cmake_file}\" 96 | but this file does not exist. Possible reasons include: 97 | * The file was deleted, renamed, or moved to another location. 98 | * An install or uninstall procedure did not complete successfully. 99 | * The installation package was faulty and contained 100 | \"${CMAKE_CURRENT_LIST_FILE}\" 101 | but not all the files it references. 102 | ") 103 | endif() 104 | endforeach() 105 | endif() 106 | unset(_cmake_file) 107 | unset("_cmake_import_check_files_for_${_cmake_target}") 108 | endforeach() 109 | unset(_cmake_target) 110 | unset(_cmake_import_check_targets) 111 | 112 | # This file does not depend on other imported targets which have 113 | # been exported from the same project but in a separate export set. 114 | 115 | # Commands beyond this point should not need to know the version. 116 | set(CMAKE_IMPORT_FILE_VERSION) 117 | cmake_policy(POP) 118 | -------------------------------------------------------------------------------- /deps/qwindowkit/lib/libQWKCore.dll.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeaEpoch/MouseClick/dbd84f3aecd7b1e6254825396d19c353d15fa535/deps/qwindowkit/lib/libQWKCore.dll.a -------------------------------------------------------------------------------- /deps/qwindowkit/lib/libQWKWidgets.dll.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeaEpoch/MouseClick/dbd84f3aecd7b1e6254825396d19c353d15fa535/deps/qwindowkit/lib/libQWKWidgets.dll.a -------------------------------------------------------------------------------- /deps/qwindowkit/share/QWindowKit/qmake/QWKCore.pri: -------------------------------------------------------------------------------- 1 | !defined(QMAKE_QWK_CORE_INCLUDED, var) { 2 | QMAKE_QWK_CORE_INCLUDED = 1 3 | 4 | # CMake variables 5 | QMAKE_QWK_INSTALL_PREFIX = $$PWD/../../.. 6 | QMAKE_QWK_INSTALL_BINDIR = bin 7 | QMAKE_QWK_INSTALL_LIBDIR = lib 8 | QMAKE_QWK_INSTALL_INCDIR = include 9 | 10 | # Shared include directory 11 | INCLUDEPATH += \ 12 | $$QMAKE_QWK_INSTALL_PREFIX/$$QMAKE_QWK_INSTALL_INCDIR/QWindowKit 13 | 14 | # Shared link directory 15 | LIBS += \ 16 | "-L$$QMAKE_QWK_INSTALL_PREFIX/$$QMAKE_QWK_INSTALL_LIBDIR" 17 | 18 | CONFIG(debug, debug|release) { 19 | LIBS += -lQWKCore 20 | } else { 21 | LIBS += -lQWKCore 22 | } 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /deps/qwindowkit/share/QWindowKit/qmake/QWKQuick.pri: -------------------------------------------------------------------------------- 1 | !defined(QMAKE_QWK_QUICK_INCLUDED, var) { 2 | QMAKE_QWK_QUICK_INCLUDED = 1 3 | 4 | include($$PWD/QWKCore.pri) 5 | 6 | CONFIG(debug, debug|release) { 7 | LIBS += -lQWKQuick 8 | } else { 9 | LIBS += -lQWKQuick 10 | } 11 | 12 | 13 | } 14 | -------------------------------------------------------------------------------- /deps/qwindowkit/share/QWindowKit/qmake/QWKWidgets.pri: -------------------------------------------------------------------------------- 1 | !defined(QMAKE_QWK_WIDGETS_INCLUDED, var) { 2 | QMAKE_QWK_WIDGETS_INCLUDED = 1 3 | 4 | include($$PWD/QWKCore.pri) 5 | 6 | CONFIG(debug, debug|release) { 7 | LIBS += -lQWKWidgets 8 | } else { 9 | LIBS += -lQWKWidgets 10 | } 11 | 12 | 13 | } 14 | -------------------------------------------------------------------------------- /docs/SeaEpoch_2024-10-22_09-51-39.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeaEpoch/MouseClick/dbd84f3aecd7b1e6254825396d19c353d15fa535/docs/SeaEpoch_2024-10-22_09-51-39.jpg -------------------------------------------------------------------------------- /docs/screenshots/SeaEpoch_2024-05-28_22-44-45.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeaEpoch/MouseClick/dbd84f3aecd7b1e6254825396d19c353d15fa535/docs/screenshots/SeaEpoch_2024-05-28_22-44-45.jpg -------------------------------------------------------------------------------- /docs/screenshots/SeaEpoch_2024-07-25_16-52-41.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeaEpoch/MouseClick/dbd84f3aecd7b1e6254825396d19c353d15fa535/docs/screenshots/SeaEpoch_2024-07-25_16-52-41.jpg -------------------------------------------------------------------------------- /docs/screenshots/SeaEpoch_2024-08-07_17-29-15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeaEpoch/MouseClick/dbd84f3aecd7b1e6254825396d19c353d15fa535/docs/screenshots/SeaEpoch_2024-08-07_17-29-15.jpg -------------------------------------------------------------------------------- /docs/screenshots/SeaEpoch_2024-10-10_15-56-05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeaEpoch/MouseClick/dbd84f3aecd7b1e6254825396d19c353d15fa535/docs/screenshots/SeaEpoch_2024-10-10_15-56-05.jpg -------------------------------------------------------------------------------- /docs/screenshots/SeaEpoch_2024-10-10_16-04-27.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeaEpoch/MouseClick/dbd84f3aecd7b1e6254825396d19c353d15fa535/docs/screenshots/SeaEpoch_2024-10-10_16-04-27.jpg -------------------------------------------------------------------------------- /docs/screenshots/SeaEpoch_2024-10-10_17-41-01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeaEpoch/MouseClick/dbd84f3aecd7b1e6254825396d19c353d15fa535/docs/screenshots/SeaEpoch_2024-10-10_17-41-01.jpg -------------------------------------------------------------------------------- /docs/screenshots/SeaEpoch_2024-10-10_17-42-32.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeaEpoch/MouseClick/dbd84f3aecd7b1e6254825396d19c353d15fa535/docs/screenshots/SeaEpoch_2024-10-10_17-42-32.jpg -------------------------------------------------------------------------------- /docs/screenshots/SeaEpoch_2024-12-24_22-35-32.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeaEpoch/MouseClick/dbd84f3aecd7b1e6254825396d19c353d15fa535/docs/screenshots/SeaEpoch_2024-12-24_22-35-32.jpg -------------------------------------------------------------------------------- /docs/screenshots/SeaEpoch_2024-12-24_22-36-07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeaEpoch/MouseClick/dbd84f3aecd7b1e6254825396d19c353d15fa535/docs/screenshots/SeaEpoch_2024-12-24_22-36-07.jpg -------------------------------------------------------------------------------- /docs/screenshots/SeaEpoch_2024-12-24_22-36-48.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeaEpoch/MouseClick/dbd84f3aecd7b1e6254825396d19c353d15fa535/docs/screenshots/SeaEpoch_2024-12-24_22-36-48.jpg -------------------------------------------------------------------------------- /docs/screenshots/SeaEpoch_2024-12-24_22-37-07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeaEpoch/MouseClick/dbd84f3aecd7b1e6254825396d19c353d15fa535/docs/screenshots/SeaEpoch_2024-12-24_22-37-07.jpg -------------------------------------------------------------------------------- /i18n/MouseClick_en_US.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HotkeyLineEdit 6 | 7 | 8 | Please set a shortcut hotkey 9 | Please set a shortcut hotkey 10 | 11 | 12 | 13 | ERROR 14 | ERROR 15 | 16 | 17 | 18 | Failed to register global hotkey. 19 | Failed to register global hotkey. 20 | 21 | 22 | 23 | OK 24 | OK 25 | 26 | 27 | 28 | MainWindow 29 | 30 | 31 | MouseClick 32 | MouseClick 33 | 34 | 35 | 36 | Mouse Click 37 | Mouse Click 38 | 39 | 40 | 41 | Settings 42 | Settings 43 | 44 | 45 | 46 | MouseClickPage 47 | 48 | 49 | Click Type 50 | Click Type 51 | 52 | 53 | 54 | Left Mouse Button 55 | Left Mouse Button 56 | 57 | 58 | 59 | Right Mouse Button 60 | Right Mouse Button 61 | 62 | 63 | 64 | Middle Mouse Button 65 | Middle Mouse Button 66 | 67 | 68 | 69 | Interval Time 70 | Interval Time 71 | 72 | 73 | 74 | Random Start Interval 75 | Random Start Interval 76 | 77 | 78 | 79 | Set Max Random Interval 80 | Set Max Random Interval 81 | 82 | 83 | 84 | Memory Configuration 85 | Memory Configuration 86 | 87 | 88 | 89 | SettingsAgent 90 | 91 | 92 | WARNING 93 | WARNING 94 | 95 | 96 | 97 | The configuration file 'condig.ini' was not found. The program may have been modified. It is recommended to reinstall the program, which may resolve this issue. 98 | The configuration file 'condig.ini' was not found. The program may have been modified. It is recommended to reinstall the program, which may resolve this issue. 99 | 100 | 101 | 102 | Ignore 103 | Ignore 104 | 105 | 106 | 107 | Reinstall 108 | Reinstall 109 | 110 | 111 | 112 | SettingsPage 113 | 114 | 115 | Start/End Hotkey 116 | Start/End Hotkey 117 | 118 | 119 | 120 | Hotkey Clean 121 | Hotkey Clean 122 | 123 | 124 | 125 | Dark Theme 126 | Dark Theme 127 | 128 | 129 | 130 | Language 131 | Language 132 | 133 | 134 | 135 | English(United States) 136 | English(United States) 137 | 138 | 139 | 140 | Chinese(Simplified) 141 | 中文(简体) 142 | 143 | 144 | 145 | Chinese(Traditional) 146 | 中文(繁體) 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /i18n/MouseClick_zh_CN.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HotkeyLineEdit 6 | 7 | 8 | Please set a shortcut hotkey 9 | 请设置一个快捷键 10 | 11 | 12 | 13 | ERROR 14 | 错误 15 | 16 | 17 | 18 | Failed to register global hotkey. 19 | 未能注册全局快捷键。 20 | 21 | 22 | 23 | OK 24 | 好的 25 | 26 | 27 | 28 | MainWindow 29 | 30 | 31 | MouseClick 32 | 鼠标连点器 33 | 34 | 35 | 36 | Mouse Click 37 | 鼠标连点 38 | 39 | 40 | 41 | Settings 42 | 软件设置 43 | 44 | 45 | 46 | MouseClickPage 47 | 48 | 49 | Click Type 50 | 点击类型 51 | 52 | 53 | 54 | Left Mouse Button 55 | 鼠标左键 56 | 57 | 58 | 59 | Right Mouse Button 60 | 鼠标右键 61 | 62 | 63 | 64 | Middle Mouse Button 65 | 鼠标中键 66 | 67 | 68 | 69 | Interval Time 70 | 间隔时间 71 | 72 | 73 | 74 | Random Start Interval 75 | 随机间隔时间 76 | 77 | 78 | 79 | Set Max Random Interval 80 | 最大随机时间 81 | 82 | 83 | 84 | Memory Configuration 85 | 记住配置参数 86 | 87 | 88 | 89 | SettingsAgent 90 | 91 | 92 | WARNING 93 | 警告 94 | 95 | 96 | 97 | The configuration file 'condig.ini' was not found. The program may have been modified. It is recommended to reinstall the program, which may resolve this issue. 98 | 配置文件“condig.ini”未找到。程序可能已被修改。建议重新安装程序,这可能解决此问题。 99 | 100 | 101 | 102 | Ignore 103 | 忽略 104 | 105 | 106 | 107 | Reinstall 108 | 重新安装 109 | 110 | 111 | 112 | SettingsPage 113 | 114 | 115 | Start/End Hotkey 116 | "开始/结束"快捷键 117 | 118 | 119 | 120 | Hotkey Clean 121 | 清除快捷键 122 | 123 | 124 | 125 | Dark Theme 126 | 深色模式 127 | 128 | 129 | 130 | Language 131 | 语言设置 132 | 133 | 134 | 135 | English(United States) 136 | English(United States) 137 | 138 | 139 | 140 | Chinese(Simplified) 141 | 中文(简体) 142 | 143 | 144 | 145 | Chinese(Traditional) 146 | 中文(繁體) 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /i18n/MouseClick_zh_TW.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HotkeyLineEdit 6 | 7 | 8 | Please set a shortcut hotkey 9 | 請設定一個快捷鍵 10 | 11 | 12 | 13 | ERROR 14 | 錯誤 15 | 16 | 17 | 18 | Failed to register global hotkey. 19 | 未能註冊全域快捷鍵。 20 | 21 | 22 | 23 | OK 24 | 好的 25 | 26 | 27 | 28 | MainWindow 29 | 30 | 31 | MouseClick 32 | 滑鼠連點器 33 | 34 | 35 | 36 | Mouse Click 37 | 滑鼠連點 38 | 39 | 40 | 41 | Settings 42 | 軟體設置 43 | 44 | 45 | 46 | MouseClickPage 47 | 48 | 49 | Click Type 50 | 點擊類型 51 | 52 | 53 | 54 | Left Mouse Button 55 | 滑鼠左鍵 56 | 57 | 58 | 59 | Right Mouse Button 60 | 滑鼠右鍵 61 | 62 | 63 | 64 | Middle Mouse Button 65 | 滑鼠中鍵 66 | 67 | 68 | 69 | Interval Time 70 | 間隔時間 71 | 72 | 73 | 74 | Random Start Interval 75 | 隨機間隔時間 76 | 77 | 78 | 79 | Set Max Random Interval 80 | 最大隨機時間 81 | 82 | 83 | 84 | Memory Configuration 85 | 記住配置參數 86 | 87 | 88 | 89 | SettingsAgent 90 | 91 | 92 | WARNING 93 | 警告 94 | 95 | 96 | 97 | The configuration file 'condig.ini' was not found. The program may have been modified. It is recommended to reinstall the program, which may resolve this issue. 98 | 配置檔「condig.ini」未找到。程式可能已被修改。建議重新安裝程式,這可能解決此問題。 99 | 100 | 101 | 102 | Ignore 103 | 忽略 104 | 105 | 106 | 107 | Reinstall 108 | 重新安裝 109 | 110 | 111 | 112 | SettingsPage 113 | 114 | 115 | Start/End Hotkey 116 | “開始/結束”快捷鍵 117 | 118 | 119 | 120 | Hotkey Clean 121 | 清除快速鍵 122 | 123 | 124 | 125 | Dark Theme 126 | 深色模式 127 | 128 | 129 | 130 | Language 131 | 語言設定 132 | 133 | 134 | 135 | English(United States) 136 | English(United States) 137 | 138 | 139 | 140 | Chinese(Simplified) 141 | 中文(简体) 142 | 143 | 144 | 145 | Chinese(Traditional) 146 | 中文(繁體) 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "modules/settingsagent.h" 12 | 13 | int main(int argc, char* argv[]) 14 | { 15 | QGuiApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); 16 | qputenv("QT_WIN_DEBUG_CONSOLE", "attach"); 17 | qputenv("QSG_INFO", "1"); 18 | 19 | QApplication app(argc, argv); 20 | 21 | // 国际化 22 | SettingsAgent& app_settings = SettingsAgent::instance(); // 全局第一次初始化 23 | QTranslator translator; 24 | const QString base_name = "MouseClick_" + app_settings.Language(); 25 | if (translator.load(":/i18n/" + base_name)) { 26 | app.installTranslator(&translator); 27 | } 28 | 29 | // 设置字体 30 | int font_id = QFontDatabase::addApplicationFont(":/fonts/HarmonyOS_Sans_SC/HarmonyOS_Sans_SC_Regular.ttf"); 31 | if (font_id != -1) { 32 | QStringList font_families = QFontDatabase::applicationFontFamilies(font_id); 33 | if (!font_families.empty()) { 34 | QFont font(font_families.at(0), 12); 35 | app.setFont(font); 36 | } 37 | } 38 | 39 | MainWindow window; 40 | window.show(); 41 | 42 | return app.exec(); 43 | } 44 | -------------------------------------------------------------------------------- /src/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include "modules/shared.h" 5 | 6 | #include 7 | 8 | namespace QWK 9 | { 10 | class WidgetWindowAgent; 11 | } 12 | 13 | template class QMap; 14 | 15 | class MainWindow : public QMainWindow 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit MainWindow(QWidget* parent = nullptr); 21 | ~MainWindow(); 22 | 23 | protected: 24 | bool event(QEvent *event) override; 25 | 26 | signals: 27 | void windowStateChanged(Qt::WindowStates newState); 28 | 29 | private: 30 | Q_DISABLE_COPY(MainWindow) 31 | 32 | QWK::WidgetWindowAgent* _window_agent; 33 | static QMap _theme_files; 34 | 35 | void windowInit(const QString& title, const QIcon& icon); 36 | void loadThemeStyelSheet(Theme::ThemeMode theme); 37 | void UIWidgetInit(); 38 | void connectInit(); 39 | 40 | }; 41 | #endif // MAINWINDOW_H 42 | -------------------------------------------------------------------------------- /src/modules/hotkeylineedit.cpp: -------------------------------------------------------------------------------- 1 | #include "hotkeylineedit.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | HotkeyLineEdit::HotkeyLineEdit(QWidget* parent) 13 | : QLineEdit{parent}, 14 | _hotkey(new QHotkey()) 15 | { 16 | setReadOnly(true); 17 | setPlaceholderText(tr("Please set a shortcut hotkey")); 18 | connect(_hotkey, &QHotkey::activated, this, &HotkeyLineEdit::hotkeyActivated); 19 | } 20 | 21 | HotkeyLineEdit::~HotkeyLineEdit() 22 | { 23 | unregisterGlobalHotkey(); 24 | 25 | delete _hotkey; 26 | } 27 | 28 | void HotkeyLineEdit::cleanHotKey() 29 | { 30 | clear(); 31 | unregisterGlobalHotkey(); 32 | } 33 | 34 | const QString HotkeyLineEdit::getHotkey() const 35 | { 36 | return _key_sequence; 37 | } 38 | 39 | void HotkeyLineEdit::setHotkey(const QString& key_sequence) 40 | { 41 | _key_sequence = key_sequence; 42 | 43 | setText(_key_sequence); 44 | 45 | if (!_key_sequence.isEmpty()) { 46 | registerGlobalHotkey(); 47 | } 48 | } 49 | 50 | void HotkeyLineEdit::mousePressEvent(QMouseEvent* event) 51 | { 52 | if (!hasFocus()) { 53 | setFocus(); 54 | } 55 | QLineEdit::mousePressEvent(event); 56 | } 57 | 58 | void HotkeyLineEdit::focusInEvent(QFocusEvent* event) 59 | { 60 | // 清空之前的内容 61 | cleanHotKey(); 62 | // 设置焦点时监听键盘事件 63 | grabKeyboard(); 64 | QLineEdit::focusInEvent(event); 65 | } 66 | 67 | void HotkeyLineEdit::focusOutEvent(QFocusEvent* event) 68 | { 69 | // 失去焦点时取消监听 70 | releaseKeyboard(); 71 | QLineEdit::focusOutEvent(event); 72 | } 73 | 74 | void HotkeyLineEdit::keyPressEvent(QKeyEvent* event) 75 | { 76 | int key = event->key(); // 获取按键编码 77 | Qt::KeyboardModifiers modifiers = event->modifiers(); 78 | 79 | if (key != Qt::Key_unknown && key != Qt::Key_Control && key != Qt::Key_Shift && 80 | key != Qt::Key_Alt && key != Qt::Key_Meta) { 81 | _key_sequence = QKeySequence(modifiers | key).toString(); 82 | } else { 83 | _key_sequence = QKeySequence(modifiers).toString(); 84 | } 85 | 86 | setText(_key_sequence); 87 | 88 | _pressed_keys.insert(key); 89 | 90 | QLineEdit::keyPressEvent(event); 91 | } 92 | 93 | void HotkeyLineEdit::keyReleaseEvent(QKeyEvent* event) 94 | { 95 | int key = event->key(); 96 | 97 | _pressed_keys.remove(key); 98 | 99 | if (_pressed_keys.isEmpty()) { 100 | clearFocus(); 101 | 102 | registerGlobalHotkey(); 103 | } 104 | 105 | QLineEdit::keyReleaseEvent(event); 106 | } 107 | 108 | void HotkeyLineEdit::registerGlobalHotkey() 109 | { 110 | #ifdef QT_DEBUG 111 | qDebug() << "[HotkeyLineEdit]_key_sequence = " << _key_sequence << Qt::endl; 112 | #endif 113 | 114 | unregisterGlobalHotkey(); // 先注销之前的快捷键 115 | 116 | QStringList keys = _key_sequence.split('+'); 117 | Qt::KeyboardModifiers modifiers = Qt::NoModifier; 118 | int key = 0; 119 | 120 | for (const QString& k : keys) { 121 | if (k == "Ctrl") { 122 | modifiers |= Qt::ControlModifier; 123 | } else if (k == "Shift") { 124 | modifiers |= Qt::ShiftModifier; 125 | } else if (k == "Alt") { 126 | modifiers |= Qt::AltModifier; 127 | } else if (k == "Meta") { 128 | modifiers |= Qt::MetaModifier; 129 | } else { 130 | QKeySequence keySequence(k, QKeySequence::PortableText); 131 | if (!keySequence.isEmpty()) { 132 | key = keySequence[0].key(); 133 | } 134 | } 135 | } 136 | 137 | if (key != 0) { 138 | if (!_hotkey->setShortcut(QKeySequence(modifiers | key), true)) { 139 | // 设置失败 140 | QMessageBox msgBox(QMessageBox::Critical, tr("ERROR"), tr("Failed to register global hotkey."), QMessageBox::NoButton, this); 141 | QPushButton* okButton = msgBox.addButton(tr("OK"), QMessageBox::ActionRole); 142 | okButton->setStyleSheet("QPushButton{width: 60px;}"); 143 | msgBox.exec(); 144 | 145 | // 清空 146 | _key_sequence.clear(); 147 | clear(); 148 | } else { 149 | emit currentHotkeyChanged(_key_sequence); // 发送信号,快捷键已更改 150 | } 151 | } 152 | } 153 | 154 | void HotkeyLineEdit::unregisterGlobalHotkey() 155 | { 156 | _hotkey->setShortcut(QKeySequence(), true); 157 | } 158 | -------------------------------------------------------------------------------- /src/modules/hotkeylineedit.h: -------------------------------------------------------------------------------- 1 | #ifndef HOTKEYLINEEDIT_H 2 | #define HOTKEYLINEEDIT_H 3 | 4 | #include 5 | 6 | class QWidget; 7 | class QKeyEvent; 8 | class QMouseEvent; 9 | class QFocusEvent; 10 | class QHotkey; 11 | 12 | class HotkeyLineEdit : public QLineEdit 13 | { 14 | Q_OBJECT 15 | public: 16 | explicit HotkeyLineEdit(QWidget* parent = nullptr); 17 | ~HotkeyLineEdit(); 18 | 19 | void cleanHotKey(); 20 | 21 | const QString getHotkey() const; 22 | void setHotkey(const QString& key_sequence); 23 | 24 | Q_SIGNALS: 25 | void hotkeyActivated(); 26 | void currentHotkeyChanged(const QString& key_sequence); 27 | 28 | protected: 29 | void mousePressEvent(QMouseEvent* event) override; 30 | 31 | void focusInEvent(QFocusEvent* event) override; 32 | 33 | void focusOutEvent(QFocusEvent* event) override; 34 | 35 | void keyPressEvent(QKeyEvent* event) override; 36 | 37 | void keyReleaseEvent(QKeyEvent* event) override; 38 | 39 | private: 40 | QString _key_sequence; 41 | 42 | QSet _pressed_keys; // 当前被按下的所有按键 43 | 44 | QHotkey* _hotkey = nullptr; 45 | 46 | void registerGlobalHotkey(); 47 | void unregisterGlobalHotkey(); 48 | }; 49 | 50 | #endif // HOTKEYLINEEDIT_H 51 | -------------------------------------------------------------------------------- /src/modules/messagebox.cpp: -------------------------------------------------------------------------------- 1 | #include "messagebox.h" 2 | 3 | #include 4 | 5 | MessageBox::MessageBox(QWidget* parent) 6 | : QMessageBox{parent} 7 | { 8 | QFile style_file(":/qss/modules/messagebox.qss"); 9 | 10 | if (style_file.open(QIODevice::ReadOnly | QIODevice::Text)) { 11 | setStyleSheet(QString::fromUtf8(style_file.readAll())); 12 | } 13 | } 14 | 15 | MessageBox::~MessageBox() {} 16 | 17 | void MessageBox::setIcon(Icon icon) 18 | { 19 | QString styleSheet; 20 | switch (icon) { 21 | case QMessageBox::Information: 22 | styleSheet = "QMessageBox QLabel#qt_msgbox_label { color: #0099CC; }"; 23 | break; 24 | case QMessageBox::Warning: 25 | styleSheet = "QMessageBox QLabel#qt_msgbox_label { color: #E6A23C; }"; 26 | break; 27 | case QMessageBox::Critical: 28 | styleSheet = "QMessageBox QLabel#qt_msgbox_label { color: #F56C6C; }"; 29 | break; 30 | case QMessageBox::Question: 31 | styleSheet = "QMessageBox QLabel#qt_msgbox_label { color: #409EFF; }"; 32 | break; 33 | default: 34 | styleSheet = ""; 35 | break; 36 | } 37 | this->setStyleSheet(styleSheet); 38 | QMessageBox::setIcon(icon); 39 | } 40 | -------------------------------------------------------------------------------- /src/modules/messagebox.h: -------------------------------------------------------------------------------- 1 | #ifndef MESSAGEBOX_H 2 | #define MESSAGEBOX_H 3 | 4 | #include 5 | 6 | class MessageBox : public QMessageBox 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit MessageBox(QWidget* parent = nullptr); 11 | ~MessageBox(); 12 | 13 | void setIcon(Icon icon); 14 | 15 | private: 16 | Q_DISABLE_COPY(MessageBox) 17 | }; 18 | 19 | #endif // MESSAGEBOX_H 20 | -------------------------------------------------------------------------------- /src/modules/nav_pages/mouseclickpage.h: -------------------------------------------------------------------------------- 1 | #ifndef MOUSECLICKPAGE_H 2 | #define MOUSECLICKPAGE_H 3 | 4 | #include 5 | 6 | #include "navpage.h" 7 | #include "settingspage.h" 8 | 9 | class MouseClickPage : public NavPage 10 | { 11 | Q_OBJECT 12 | public: 13 | explicit MouseClickPage(const QString& title, SettingsPage& settings_page, QWidget* parent = nullptr); 14 | ~MouseClickPage(); 15 | 16 | private: 17 | Q_DISABLE_COPY(MouseClickPage) 18 | 19 | static QMap _theme_files; 20 | 21 | QString& getThemeFiles(Theme::ThemeMode theme) override; 22 | }; 23 | 24 | #endif // MOUSECLICKPAGE_H 25 | -------------------------------------------------------------------------------- /src/modules/nav_pages/navpage.cpp: -------------------------------------------------------------------------------- 1 | #include "navpage.h" 2 | #include "../shared.h" 3 | #include "../settingsagent.h" 4 | 5 | #include 6 | #include 7 | 8 | QMap NavPage::_theme_files {}; 9 | 10 | Clicker* NavPage::_clicker = new Clicker(); 11 | QThread* NavPage::_clicker_thread = new QThread(); 12 | bool NavPage::_is_thread_initialized = false; 13 | 14 | NavPage::NavPage(QWidget* parent) 15 | : QWidget{parent} 16 | { 17 | disconnect(&SettingsAgent::instance(), &SettingsAgent::currentThemeChanged, this, &NavPage::LoadThemeStyleSheet); 18 | connect(&SettingsAgent::instance(), &SettingsAgent::currentThemeChanged, this, &NavPage::LoadThemeStyleSheet); 19 | 20 | // Thread initialization once 21 | if (!_is_thread_initialized) { 22 | NavPage::_clicker->moveToThread(NavPage::_clicker_thread); 23 | connect(NavPage::_clicker_thread, &QThread::started, NavPage::_clicker, &Clicker::start); 24 | _is_thread_initialized = true; 25 | } 26 | } 27 | 28 | NavPage::~NavPage() 29 | { 30 | } 31 | 32 | void NavPage::LoadThemeStyleSheet(Theme::ThemeMode theme) 33 | { 34 | QFile style_file(getThemeFiles(theme)); 35 | if (style_file.open(QIODevice::ReadOnly | QIODevice::Text)) { 36 | setStyleSheet(QString::fromUtf8(style_file.readAll())); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/modules/nav_pages/navpage.h: -------------------------------------------------------------------------------- 1 | #ifndef NAVPAGE_H 2 | #define NAVPAGE_H 3 | 4 | #include 5 | #include 6 | 7 | #include "../shared.h" 8 | #include "../hotkeylineedit.h" 9 | #include "../../utils/clicker.h" 10 | 11 | class NavPage : public QWidget 12 | { 13 | Q_OBJECT 14 | public: 15 | explicit NavPage(QWidget* parent = nullptr); 16 | ~NavPage(); 17 | 18 | Q_SIGNALS: 19 | void ThemeChanged(); 20 | 21 | protected: 22 | static QMap _theme_files; 23 | 24 | static Clicker* _clicker; 25 | static QThread* _clicker_thread; 26 | static bool _is_thread_initialized; 27 | 28 | virtual QString& getThemeFiles(Theme::ThemeMode theme) = 0; 29 | void LoadThemeStyleSheet(Theme::ThemeMode theme); 30 | }; 31 | 32 | #endif // NAVPAGE_H 33 | -------------------------------------------------------------------------------- /src/modules/nav_pages/settingspage.cpp: -------------------------------------------------------------------------------- 1 | #include "settingspage.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "../hotkeylineedit.h" 17 | #include "../settingsagent.h" 18 | #include "../shared.h" 19 | 20 | QMap SettingsPage::_theme_files { 21 | {Theme::Light, (":/qss/modules/light-settingspage.qss")}, 22 | {Theme::Dark, (":/qss/modules/dark-settingspage.qss")} 23 | }; 24 | 25 | SettingsPage::SettingsPage(const QString& title, QWidget* parent) 26 | : NavPage{parent}, 27 | _hotkey_reader(nullptr), 28 | _hotkey_clean(nullptr) 29 | { 30 | SettingsAgent& app_settings = SettingsAgent::instance(); 31 | 32 | LoadThemeStyleSheet(app_settings.ThemeMode()); 33 | 34 | QVBoxLayout* central_layout = new QVBoxLayout(this); 35 | central_layout->setSpacing(0); 36 | central_layout->setContentsMargins(QMargins()); 37 | 38 | QLabel* page_title = new QLabel(this); 39 | page_title->setObjectName(QStringLiteral("page-title")); 40 | page_title->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); 41 | page_title->setFocusPolicy(Qt::NoFocus); 42 | page_title->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); 43 | page_title->setText(title); 44 | page_title->setMaximumHeight(36); 45 | 46 | QWidget* page_content = new QWidget(this); 47 | page_content->setObjectName(QStringLiteral("page-content")); 48 | page_content->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); 49 | 50 | QVBoxLayout* page_content_layout = new QVBoxLayout(page_content); 51 | page_content_layout->setSpacing(12); 52 | page_content_layout->setContentsMargins(QMargins(0, 8, 0, 8)); 53 | 54 | const int pageContentUniformHeight = 32; // 统一控件高度 55 | 56 | /********************/ 57 | 58 | QWidget* hotkey_content = new QWidget(page_content); 59 | hotkey_content->setFixedHeight(pageContentUniformHeight); 60 | 61 | QHBoxLayout* hotkey_content_layout = new QHBoxLayout(hotkey_content); 62 | hotkey_content_layout->setSpacing(0); 63 | hotkey_content_layout->setContentsMargins(QMargins()); 64 | 65 | QLabel* hotkey_desc = new QLabel(hotkey_content); 66 | hotkey_desc->setObjectName(QStringLiteral("hotkey-desc")); 67 | hotkey_desc->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); 68 | hotkey_desc->setFocusPolicy(Qt::NoFocus); 69 | hotkey_desc->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); 70 | hotkey_desc->setText(tr("Start/End Hotkey")); 71 | 72 | _hotkey_reader = new HotkeyLineEdit(hotkey_content); 73 | _hotkey_reader->setObjectName(QStringLiteral("hotkey-reader")); 74 | _hotkey_reader->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); 75 | 76 | // 设置保存的快捷键(上一次使用) 77 | const QString pre_hotkey = app_settings.Hotkey(); 78 | if (pre_hotkey.isEmpty()) { 79 | _hotkey_reader->setHotkey("Ctrl+F2"); // 默认快捷键 80 | } 81 | else { 82 | _hotkey_reader->setHotkey(pre_hotkey); // 上一次使用的快捷键 83 | } 84 | 85 | hotkey_content_layout->addWidget(hotkey_desc); 86 | hotkey_content_layout->addWidget(_hotkey_reader); 87 | hotkey_content->setLayout(hotkey_content_layout); 88 | 89 | /********************/ 90 | 91 | _hotkey_clean = new QPushButton(page_content); 92 | _hotkey_clean->setObjectName(QStringLiteral("hotkey-clean-btn")); 93 | _hotkey_clean->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); 94 | _hotkey_clean->setFixedHeight(pageContentUniformHeight); 95 | _hotkey_clean->setText(tr("Hotkey Clean")); 96 | 97 | /********************/ 98 | 99 | QWidget* theme_toggle_content = new QWidget(page_content); 100 | theme_toggle_content->setFixedHeight(pageContentUniformHeight); 101 | 102 | QHBoxLayout* theme_toggle_content_layout = new QHBoxLayout(theme_toggle_content); 103 | theme_toggle_content_layout->setSpacing(0); 104 | theme_toggle_content_layout->setContentsMargins(QMargins()); 105 | 106 | QLabel* theme_toggle_desc = new QLabel(theme_toggle_content); 107 | theme_toggle_desc->setObjectName(QStringLiteral("theme-toggle-desc")); 108 | theme_toggle_desc->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); 109 | theme_toggle_desc->setFocusPolicy(Qt::NoFocus); 110 | theme_toggle_desc->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); 111 | theme_toggle_desc->setText(tr("Dark Theme")); 112 | 113 | QRadioButton* theme_toggle_btn = new QRadioButton(theme_toggle_content); 114 | theme_toggle_btn->setObjectName(QStringLiteral("theme-toggle-btn")); 115 | theme_toggle_btn->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); 116 | theme_toggle_btn->setChecked(static_cast(app_settings.ThemeMode())); 117 | 118 | theme_toggle_content_layout->addWidget(theme_toggle_desc); 119 | theme_toggle_content_layout->addWidget(theme_toggle_btn); 120 | theme_toggle_content->setLayout(theme_toggle_content_layout); 121 | 122 | /********************/ 123 | 124 | QWidget* language_switch_content = new QWidget(page_content); 125 | language_switch_content->setFixedHeight(pageContentUniformHeight); 126 | 127 | QHBoxLayout* language_switch_content_layout = new QHBoxLayout(language_switch_content); 128 | language_switch_content_layout->setSpacing(0); 129 | language_switch_content_layout->setContentsMargins(QMargins()); 130 | 131 | QLabel* language_switch_desc = new QLabel(language_switch_content); 132 | language_switch_desc->setObjectName(QStringLiteral("language-switch-desc")); 133 | language_switch_desc->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); 134 | language_switch_desc->setFocusPolicy(Qt::NoFocus); 135 | language_switch_desc->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); 136 | language_switch_desc->setText(tr("Language")); 137 | 138 | QComboBox* language_list = new QComboBox(language_switch_content); 139 | language_list->setObjectName(QStringLiteral("language-list")); 140 | language_list->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); 141 | language_list->addItem(tr("English(United States)"), QVariant("en_US")); 142 | language_list->addItem(tr("Chinese(Simplified)"), QVariant("zh_CN")); 143 | language_list->addItem(tr("Chinese(Traditional)"), QVariant("zh_TW")); 144 | 145 | // 确定当前的语言 146 | QString current_language = app_settings.Language(); 147 | 148 | // 遍历 QComboBox 项目,找到对应的选项并设置为选中状态 149 | for (int i = 0; i < language_list->count(); ++i) { 150 | QVariant item_data = language_list->itemData(i); 151 | if (item_data.toString() == current_language) { 152 | language_list->setCurrentIndex(i); 153 | break; 154 | } 155 | } 156 | 157 | language_switch_content_layout->addWidget(language_switch_desc); 158 | language_switch_content_layout->addWidget(language_list); 159 | language_switch_content->setLayout(language_switch_content_layout); 160 | 161 | /********************/ 162 | 163 | page_content_layout->addWidget(hotkey_content); 164 | page_content_layout->addWidget(_hotkey_clean); 165 | page_content_layout->addWidget(theme_toggle_content); 166 | page_content_layout->addWidget(language_switch_content); 167 | page_content_layout->addStretch(); 168 | 169 | central_layout->addWidget(page_title); 170 | central_layout->addWidget(page_content); 171 | 172 | setLayout(central_layout); 173 | 174 | /********************/ 175 | 176 | connect(_hotkey_clean, &QPushButton::clicked, this, [this]() { 177 | _hotkey_reader->cleanHotKey(); 178 | }); 179 | 180 | connect(theme_toggle_btn, &QRadioButton::toggled, this, [this](bool checked) { 181 | auto theme_mode = static_cast(checked); 182 | SettingsAgent::instance().setThemeMode(theme_mode); 183 | }); 184 | 185 | connect(_hotkey_reader, &HotkeyLineEdit::hotkeyActivated, this, [=]() { 186 | if (NavPage::_clicker_thread->isRunning()) { 187 | _hotkey_reader->setEnabled(true); 188 | _hotkey_clean->setEnabled(true); 189 | } else { 190 | _hotkey_reader->setEnabled(false); 191 | _hotkey_clean->setEnabled(false); 192 | } 193 | }); 194 | 195 | connect(_hotkey_reader, &HotkeyLineEdit::currentHotkeyChanged, this, [](const QString& hotkey) { 196 | SettingsAgent::instance().setHotkey(hotkey); 197 | }); 198 | 199 | connect(language_list, &QComboBox::currentIndexChanged, this, [=](int index) { 200 | SettingsAgent& app_settings = SettingsAgent::instance(); // 必须重新获取才能使用接口 201 | QString selected_language = language_list->itemData(index).toString(); 202 | 203 | // 判断选择的语言是否和当前语言相同,不同则进行切换 204 | if (selected_language != app_settings.Language()) { 205 | app_settings.setLanguage(selected_language); 206 | 207 | // 重新启动应用程序以应用新语言 208 | restartApplication(); 209 | } 210 | }); 211 | } 212 | 213 | SettingsPage::~SettingsPage() 214 | { 215 | delete _hotkey_reader; 216 | delete _hotkey_clean; 217 | } 218 | 219 | QString& SettingsPage::getThemeFiles(Theme::ThemeMode theme) 220 | { 221 | return SettingsPage::_theme_files[theme]; 222 | } 223 | -------------------------------------------------------------------------------- /src/modules/nav_pages/settingspage.h: -------------------------------------------------------------------------------- 1 | #ifndef SETTINGSPAGE_H 2 | #define SETTINGSPAGE_H 3 | 4 | #include 5 | #include 6 | 7 | #include "navpage.h" 8 | 9 | class SettingsPage : public NavPage 10 | { 11 | friend class MouseClickPage; 12 | 13 | Q_OBJECT 14 | public: 15 | explicit SettingsPage(const QString& title, QWidget* parent = nullptr); 16 | ~SettingsPage(); 17 | 18 | private: 19 | Q_DISABLE_COPY(SettingsPage) 20 | 21 | static QMap _theme_files; 22 | HotkeyLineEdit* _hotkey_reader; 23 | QPushButton* _hotkey_clean; 24 | 25 | QString& getThemeFiles(Theme::ThemeMode theme) override; 26 | }; 27 | 28 | #endif // SETTINGSPAGE_H 29 | -------------------------------------------------------------------------------- /src/modules/settingsagent.h: -------------------------------------------------------------------------------- 1 | #ifndef SETTINGSAGENT_H 2 | #define SETTINGSAGENT_H 3 | 4 | #include "shared.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class SettingsAgent : public QObject 11 | { 12 | Q_OBJECT 13 | public: 14 | // 接口 15 | static SettingsAgent& instance(); 16 | 17 | /***** 相关的 getter 与 settter *****/ 18 | Theme::ThemeMode ThemeMode() const; 19 | void setThemeMode(Theme::ThemeMode& theme_mode); 20 | 21 | Qt::WindowStates WindowState() const; 22 | void setWindowState(Qt::WindowStates window_state); 23 | 24 | QString Hotkey() const; 25 | void setHotkey(const QString& hotkey); 26 | 27 | QString Language() const; 28 | void setLanguage(const QString& language); 29 | 30 | // ------------- // 31 | 32 | int ClickType() const; 33 | void setClickType(const int type); 34 | 35 | double IntervalTime() const; 36 | void setIntervalTime(const double interval_time); 37 | 38 | bool EnableRandomInterval() const; 39 | void setEnableRandomInterval(bool enable_random_interval); 40 | 41 | double RandomIntervalTime() const; 42 | void setRandomIntervalTime(const double random_interval_time); 43 | 44 | bool EnableMemoryConfiguration() const; 45 | void setEnableMemoryConfiguration(bool memory_configuration); 46 | /***********************************/ 47 | 48 | signals: 49 | void currentThemeChanged(Theme::ThemeMode current_theme); 50 | void currentLanguageChanged(const QString current_language); 51 | 52 | private: 53 | explicit SettingsAgent(QObject *parent = nullptr); 54 | ~SettingsAgent(); 55 | Q_DISABLE_COPY(SettingsAgent); 56 | 57 | // 所有配置以键值对形式存储 58 | QMap _config; 59 | 60 | // 配置文件完整文件路径 61 | QString _settings_file_path; 62 | 63 | // 支持语言列表 64 | const QStringList _language_support_list = { 65 | "en_US", 66 | "zh_CN", 67 | "zh_TW" 68 | }; 69 | 70 | // 默认值 71 | const Theme::ThemeMode _DEFAULT_THEMEMODE = Theme::Light; // 默认主题设置 72 | const Qt::WindowStates _DEFAULT_WINDOWSTATE = Qt::WindowNoState; 73 | const QString _DEFAULT_LANGUAGE = "en_US"; // 默认语言设置 74 | const QString _DEFAULT_HOTKEY = "Ctrl+F2"; 75 | const int _DEFAULT_CLICKTYPE = 0; 76 | const double _DEFAULT_INTERVALTIME = 0.01; 77 | const bool _DEFAULT_RANDOMINTERVAL = false; 78 | const double _DEFAULT_RANDOMINTERVALTIME = 0.02; 79 | const bool _DEFAULT_MEMORYCONFIGURATION = false; 80 | }; 81 | 82 | #endif // SETTINGSAGENT_H 83 | -------------------------------------------------------------------------------- /src/modules/shared.cpp: -------------------------------------------------------------------------------- 1 | #include "shared.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | void restartApplication() 8 | { 9 | // 获取当前应用路径和参数 10 | QString appPath = QCoreApplication::applicationFilePath(); 11 | QStringList args = QCoreApplication::arguments(); 12 | QString currentPid = QString::number(QCoreApplication::applicationPid()); 13 | 14 | // 根据平台生成脚本路径 15 | QString scriptPath; 16 | #ifdef Q_OS_WIN 17 | scriptPath = QCoreApplication::applicationDirPath() + "/restart.bat"; 18 | 19 | // 创建 Windows 重启脚本 20 | QFile scriptFile(scriptPath); 21 | if (!scriptFile.exists()) { 22 | scriptFile.open(QIODevice::WriteOnly); 23 | scriptFile.write( 24 | "@echo off\n" 25 | ":wait\n" 26 | "tasklist | find /i \"%1\" >nul\n" 27 | "if not errorlevel 1 (\n" 28 | " timeout /t 1 >nul\n" 29 | " goto wait\n" 30 | ")\n" 31 | "start \"\" \"%2\"\n" 32 | ); 33 | scriptFile.close(); 34 | } 35 | 36 | // 使用脚本重启程序 37 | QProcess::startDetached("cmd", {"/c", scriptPath, currentPid, appPath}); 38 | #else 39 | scriptPath = QCoreApplication::applicationDirPath() + "/restart.sh"; 40 | 41 | // 创建 Linux 重启脚本 42 | QFile scriptFile(scriptPath); 43 | if (!scriptFile.exists()) { 44 | scriptFile.open(QIODevice::WriteOnly); 45 | scriptFile.write( 46 | "#!/bin/bash\n" 47 | "while ps -p \"$1\" > /dev/null; do\n" 48 | " sleep 1\n" 49 | "done\n" 50 | "\"$2\" \"$@\" &\n" 51 | ); 52 | scriptFile.close(); 53 | 54 | // 添加执行权限 55 | QFile::Permissions permissions = scriptFile.permissions(); 56 | scriptFile.setPermissions(permissions | QFile::ExeOwner | QFile::ExeGroup | QFile::ExeOther); 57 | } 58 | 59 | // 使用脚本重启程序 60 | QProcess::startDetached("/bin/bash", {scriptPath, currentPid, appPath}); 61 | #endif 62 | 63 | // 退出当前应用 64 | QCoreApplication::quit(); 65 | } 66 | 67 | bool Theme::isValidThemeMode(const int value) 68 | { 69 | switch (value) { 70 | case Theme::Light: 71 | case Theme::Dark: 72 | return true; 73 | default: 74 | return false; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/modules/shared.h: -------------------------------------------------------------------------------- 1 | #ifndef SHARED_H 2 | #define SHARED_H 3 | 4 | // 重启程序 5 | void restartApplication(); 6 | 7 | namespace Theme 8 | { 9 | enum ThemeMode { 10 | Light, 11 | Dark 12 | }; 13 | bool isValidThemeMode(const int value); 14 | } 15 | 16 | #endif // SHARED_H 17 | -------------------------------------------------------------------------------- /src/qwk_window_bar/private/windowbar_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef WINDOWBARPRIVATE_H 6 | #define WINDOWBARPRIVATE_H 7 | 8 | #include 9 | 10 | #include "../windowbar.h" 11 | 12 | namespace QWK { 13 | 14 | class WindowBarPrivate { 15 | Q_DECLARE_PUBLIC(WindowBar) 16 | public: 17 | WindowBarPrivate(); 18 | virtual ~WindowBarPrivate(); 19 | 20 | void init(); 21 | 22 | WindowBar *q_ptr; 23 | 24 | QWidget *w; 25 | bool autoTitle; 26 | bool autoIcon; 27 | 28 | enum WindowBarItem { 29 | IconButton, 30 | MenuWidget, 31 | TitleLabel, 32 | MinimumButton, 33 | MaximumButton, 34 | CloseButton, 35 | }; 36 | 37 | QHBoxLayout *layout; 38 | 39 | inline QWidget *widgetAt(int index) const { 40 | return layout->itemAt(index)->widget(); 41 | } 42 | 43 | void setWidgetAt(int index, QWidget *widget); 44 | 45 | QWidget *takeWidgetAt(int index); 46 | 47 | inline void insertDefaultSpace(int index) { 48 | layout->insertSpacerItem(index, new QSpacerItem(0, 0)); 49 | } 50 | 51 | private: 52 | Q_DISABLE_COPY(WindowBarPrivate) 53 | }; 54 | 55 | } 56 | 57 | #endif // WINDOWBARPRIVATE_H 58 | -------------------------------------------------------------------------------- /src/qwk_window_bar/private/windowbutton_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef WINDOWBUTTONPRIVATE_H 6 | #define WINDOWBUTTONPRIVATE_H 7 | 8 | #include "../windowbutton.h" 9 | 10 | namespace QWK { 11 | 12 | class WindowButtonPrivate { 13 | Q_DECLARE_PUBLIC(WindowButton) 14 | public: 15 | WindowButtonPrivate(); 16 | virtual ~WindowButtonPrivate(); 17 | 18 | void init(); 19 | 20 | WindowButton *q_ptr; 21 | 22 | QIcon iconNormal; 23 | QIcon iconChecked; 24 | QIcon iconDisabled; 25 | 26 | void reloadIcon(); 27 | }; 28 | 29 | } 30 | 31 | #endif // WINDOWBUTTONPRIVATE_H 32 | -------------------------------------------------------------------------------- /src/qwk_window_bar/windowbar.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef WINDOWBAR_H 6 | #define WINDOWBAR_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace QWK { 14 | 15 | class WindowBarPrivate; 16 | 17 | class WindowBar : public QFrame { 18 | Q_OBJECT 19 | Q_DECLARE_PRIVATE(WindowBar) 20 | public: 21 | explicit WindowBar(QWidget *parent = nullptr); 22 | ~WindowBar(); 23 | 24 | public: 25 | QMenuBar *menuBar() const; 26 | QLabel *titleLabel() const; 27 | QAbstractButton *iconButton() const; 28 | QAbstractButton *minButton() const; 29 | QAbstractButton *maxButton() const; 30 | QAbstractButton *closeButton() const; 31 | 32 | void setMenuBar(QMenuBar *menuBar); 33 | void setTitleLabel(QLabel *label); 34 | void setIconButton(QAbstractButton *btn); 35 | void setMinButton(QAbstractButton *btn); 36 | void setMaxButton(QAbstractButton *btn); 37 | void setCloseButton(QAbstractButton *btn); 38 | 39 | QMenuBar *takeMenuBar(); 40 | QLabel *takeTitleLabel(); 41 | QAbstractButton *takeIconButton(); 42 | QAbstractButton *takeMinButton(); 43 | QAbstractButton *takeMaxButton(); 44 | QAbstractButton *takeCloseButton(); 45 | 46 | QWidget *hostWidget() const; 47 | void setHostWidget(QWidget *w); 48 | 49 | bool titleFollowWindow() const; 50 | void setTitleFollowWindow(bool value); 51 | 52 | bool iconFollowWindow() const; 53 | void setIconFollowWindow(bool value); 54 | 55 | Q_SIGNALS: 56 | void minimizeRequested(); 57 | void maximizeRequested(bool max = false); 58 | void closeRequested(); 59 | 60 | protected: 61 | bool eventFilter(QObject *obj, QEvent *event) override; 62 | 63 | virtual void titleChanged(const QString &text); 64 | virtual void iconChanged(const QIcon &icon); 65 | 66 | protected: 67 | WindowBar(WindowBarPrivate &d, QWidget *parent = nullptr); 68 | 69 | QScopedPointer d_ptr; 70 | }; 71 | 72 | } 73 | 74 | #endif // WINDOWBAR_H -------------------------------------------------------------------------------- /src/qwk_window_bar/windowbutton.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #include "windowbutton.h" 6 | #include "private/windowbutton_p.h" 7 | 8 | #include 9 | #include 10 | 11 | namespace QWK 12 | { 13 | 14 | WindowButtonPrivate::WindowButtonPrivate() = default; 15 | 16 | WindowButtonPrivate::~WindowButtonPrivate() = default; 17 | 18 | void WindowButtonPrivate::init() 19 | { 20 | } 21 | 22 | void WindowButtonPrivate::reloadIcon() 23 | { 24 | Q_Q(WindowButton); 25 | 26 | if (!q->isEnabled() && !iconDisabled.isNull()) { 27 | q->setIcon(iconDisabled); 28 | return; 29 | } 30 | 31 | if (q->isChecked() && !iconChecked.isNull()) { 32 | q->setIcon(iconChecked); 33 | return; 34 | } 35 | 36 | if (!iconNormal.isNull()) { 37 | q->setIcon(iconNormal); 38 | } 39 | } 40 | 41 | WindowButton::WindowButton(QWidget* parent) : WindowButton(*new WindowButtonPrivate(), parent) 42 | { 43 | } 44 | 45 | WindowButton::~WindowButton() = default; 46 | 47 | QIcon WindowButton::iconNormal() const 48 | { 49 | Q_D(const WindowButton); 50 | return d->iconNormal; 51 | } 52 | 53 | void WindowButton::setIconNormal(const QIcon& icon) 54 | { 55 | Q_D(WindowButton); 56 | d->iconNormal = icon; 57 | d->reloadIcon(); 58 | } 59 | 60 | QIcon WindowButton::iconChecked() const 61 | { 62 | Q_D(const WindowButton); 63 | return d->iconChecked; 64 | } 65 | 66 | void WindowButton::setIconChecked(const QIcon& icon) 67 | { 68 | Q_D(WindowButton); 69 | d->iconChecked = icon; 70 | d->reloadIcon(); 71 | } 72 | 73 | QIcon WindowButton::iconDisabled() const 74 | { 75 | Q_D(const WindowButton); 76 | return d->iconDisabled; 77 | } 78 | 79 | void WindowButton::setIconDisabled(const QIcon& icon) 80 | { 81 | Q_D(WindowButton); 82 | d->iconDisabled = icon; 83 | d->reloadIcon(); 84 | } 85 | 86 | void WindowButton::checkStateSet() 87 | { 88 | Q_D(WindowButton); 89 | d->reloadIcon(); 90 | } 91 | 92 | void WindowButton::mouseDoubleClickEvent(QMouseEvent* event) 93 | { 94 | if (event->button() == Qt::LeftButton) { 95 | Q_EMIT doubleClicked(); 96 | } 97 | } 98 | 99 | WindowButton::WindowButton(WindowButtonPrivate& d, QWidget* parent) 100 | : QPushButton(parent), d_ptr(&d) 101 | { 102 | d.q_ptr = this; 103 | 104 | d.init(); 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /src/qwk_window_bar/windowbutton.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) 2 | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #ifndef WINDOWBUTTON_H 6 | #define WINDOWBUTTON_H 7 | 8 | #include 9 | 10 | namespace QWK { 11 | 12 | class WindowButtonPrivate; 13 | 14 | class WindowButton : public QPushButton { 15 | Q_OBJECT 16 | Q_DECLARE_PRIVATE(WindowButton) 17 | Q_PROPERTY(QIcon iconNormal READ iconNormal WRITE setIconNormal FINAL) 18 | Q_PROPERTY(QIcon iconChecked READ iconChecked WRITE setIconChecked FINAL) 19 | Q_PROPERTY(QIcon iconDisabled READ iconDisabled WRITE setIconDisabled FINAL) 20 | public: 21 | explicit WindowButton(QWidget *parent = nullptr); 22 | ~WindowButton(); 23 | 24 | public: 25 | QIcon iconNormal() const; 26 | void setIconNormal(const QIcon &icon); 27 | 28 | QIcon iconChecked() const; 29 | void setIconChecked(const QIcon &icon); 30 | 31 | QIcon iconDisabled() const; 32 | void setIconDisabled(const QIcon &icon); 33 | 34 | Q_SIGNALS: 35 | void doubleClicked(); 36 | 37 | protected: 38 | void checkStateSet() override; 39 | 40 | void mouseDoubleClickEvent(QMouseEvent *event) override; 41 | 42 | protected: 43 | WindowButton(WindowButtonPrivate &d, QWidget *parent = nullptr); 44 | 45 | QScopedPointer d_ptr; 46 | }; 47 | 48 | } 49 | 50 | #endif // WINDOWBUTTON_H -------------------------------------------------------------------------------- /src/utils/clicker.cpp: -------------------------------------------------------------------------------- 1 | #include "clicker.h" 2 | 3 | #include 4 | #include 5 | 6 | #if defined(Q_OS_WIN) 7 | #include 8 | #endif 9 | 10 | Clicker::Clicker(QObject* parent) 11 | : QObject{parent}, 12 | _run(false), 13 | _btn_type(Qt::LeftButton), 14 | _interval(10), 15 | _random_interval_flag(false), 16 | _max_random_interval(20) 17 | {} 18 | 19 | Clicker::~Clicker() 20 | { 21 | } 22 | 23 | Clicker& Clicker::initParameters(Qt::MouseButton btnType, 24 | int interval, 25 | bool randomIntervalFlag, 26 | int maxRandomInterval) 27 | { 28 | _btn_type = btnType; 29 | _interval = interval; 30 | _random_interval_flag = randomIntervalFlag; 31 | _max_random_interval = maxRandomInterval; 32 | 33 | return (*this); 34 | } 35 | 36 | void Clicker::start() 37 | { 38 | _run = true; 39 | 40 | switch(_btn_type) { 41 | case Qt::LeftButton: { 42 | if (_random_interval_flag) { 43 | leftRandomClick(); 44 | } else { 45 | leftClick(); 46 | } 47 | } 48 | break; 49 | case Qt::RightButton: { 50 | if (_random_interval_flag) { 51 | rightRandomClick(); 52 | } else { 53 | rightClick(); 54 | } 55 | } 56 | break; 57 | case Qt::MiddleButton: { 58 | if (_random_interval_flag) { 59 | middleRandomClick(); 60 | } else { 61 | middleClick(); 62 | } 63 | } 64 | break; 65 | default: 66 | break; 67 | } 68 | } 69 | 70 | void Clicker::stop() 71 | { 72 | _run = false; 73 | 74 | _sleep_timer.wakeAll(); 75 | } 76 | 77 | void Clicker::msleep(int ms) 78 | { 79 | _interrupt_sleep_immediately.lock(); 80 | 81 | if (_run) { 82 | _sleep_timer.wait(&_interrupt_sleep_immediately, ms); 83 | } 84 | 85 | _interrupt_sleep_immediately.unlock(); 86 | } 87 | 88 | #if defined(Q_OS_WIN) 89 | void Clicker::leftClick() 90 | { 91 | POINT mouse_pos; 92 | 93 | while (_run) { 94 | GetCursorPos(&mouse_pos); 95 | mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, mouse_pos.x, mouse_pos.y, 0, 0); 96 | msleep(_interval); 97 | } 98 | } 99 | 100 | void Clicker::rightClick() 101 | { 102 | POINT mouse_pos; 103 | 104 | while (_run) { 105 | GetCursorPos(&mouse_pos); 106 | mouse_event(MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, mouse_pos.x, mouse_pos.y, 0, 0); 107 | msleep(_interval); 108 | } 109 | } 110 | 111 | void Clicker::middleClick() 112 | { 113 | POINT mouse_pos; 114 | 115 | while (_run) { 116 | GetCursorPos(&mouse_pos); 117 | mouse_event(MOUSEEVENTF_MIDDLEDOWN | MOUSEEVENTF_MIDDLEUP, mouse_pos.x, mouse_pos.y, 0, 0); 118 | msleep(_interval); 119 | } 120 | } 121 | 122 | void Clicker::leftRandomClick() 123 | { 124 | POINT mouse_pos; 125 | 126 | while (_run) { 127 | GetCursorPos(&mouse_pos); 128 | mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, mouse_pos.x, mouse_pos.y, 0, 0); 129 | msleep(QRandomGenerator::global()->bounded(0, _max_random_interval)); 130 | } 131 | } 132 | 133 | void Clicker::rightRandomClick() 134 | { 135 | POINT mouse_pos; 136 | 137 | while (_run) { 138 | GetCursorPos(&mouse_pos); 139 | mouse_event(MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, mouse_pos.x, mouse_pos.y, 0, 0); 140 | msleep(QRandomGenerator::global()->bounded(0, _max_random_interval)); 141 | } 142 | } 143 | 144 | void Clicker::middleRandomClick() 145 | { 146 | POINT mouse_pos; 147 | 148 | while (_run) { 149 | GetCursorPos(&mouse_pos); 150 | mouse_event(MOUSEEVENTF_MIDDLEDOWN | MOUSEEVENTF_MIDDLEUP, mouse_pos.x, mouse_pos.y, 0, 0); 151 | msleep(QRandomGenerator::global()->bounded(0, _max_random_interval)); 152 | } 153 | } 154 | #endif 155 | -------------------------------------------------------------------------------- /src/utils/clicker.h: -------------------------------------------------------------------------------- 1 | #ifndef CLICKER_H 2 | #define CLICKER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class Clicker : public QObject 9 | { 10 | Q_OBJECT 11 | public: 12 | explicit Clicker(QObject* parent = nullptr); 13 | ~Clicker(); 14 | Clicker& initParameters(Qt::MouseButton btnType, 15 | int interval, 16 | bool randomIntervalFlag, 17 | int maxRandomInterval); 18 | 19 | public Q_SLOTS: 20 | void start(); 21 | void stop(); 22 | 23 | private: 24 | bool _run; 25 | Qt::MouseButton _btn_type; 26 | int _interval; 27 | bool _random_interval_flag; 28 | int _max_random_interval; 29 | 30 | QMutex _interrupt_sleep_immediately; 31 | QWaitCondition _sleep_timer; 32 | void msleep(int ms); 33 | 34 | void leftClick(); 35 | void rightClick(); 36 | void middleClick(); 37 | 38 | void leftRandomClick(); 39 | void rightRandomClick(); 40 | void middleRandomClick(); 41 | }; 42 | 43 | #endif // CLICKER_H 44 | --------------------------------------------------------------------------------