Compare commits

...

361 Commits
2.3.2 ... main

Author SHA1 Message Date
Yuhang Zhao 3102b4ea3b add deprecation notice 2023-12-19 17:36:57 +08:00
Zhao Yuhang 6b6b54d5b5 fix macos crash 2023-12-17 18:01:49 +08:00
Yuhang Zhao 585a82fbe8 fix clang-cl builds 2023-11-22 10:21:00 +08:00
kirakira 1764a8a918
#325 win: don't show two tooltips (#326)
Co-authored-by: yangzhenghan <yangzhenghan@sinap.ac.cn>
2023-11-20 12:59:47 +08:00
Yuhang Zhao 2765d18634 win: don't show two tooltips
Fixes: #325
2023-11-20 10:31:03 +08:00
Zhao Yuhang 096d30b8cf update submodule 2023-11-16 12:16:20 +08:00
Zhao Yuhang 529b9d3f93 update submodule 2023-11-16 11:28:47 +08:00
Yuhang Zhao 5670a28559 win: minor improvements 2023-11-13 17:29:52 +08:00
Yuhang Zhao a1b0568630 qmake: remove moc limitations for non apple platforms 2023-11-13 11:17:45 +08:00
Zhao Yuhang 7fdea56785 minor tweaks 2023-11-11 16:26:32 +08:00
kirakira bb3f8e0d40
Modified system button colors for hover and press states (#318)
* 窗口关闭按钮鼠标悬浮时的前景色修改为白色

* #243 修改系统按钮的鼠标悬浮背景色和按下时背景色

---------

Co-authored-by: yangzhenghan <yangzhenghan@sinap.ac.cn>
2023-11-11 16:08:19 +08:00
czy 8ab8822448
#307 Fix the compilation error of qt6.x (#317) 2023-11-10 12:02:08 +08:00
Zhao Yuhang 85a3fe1b2f win: fix some minor bugs 2023-11-03 21:25:24 +08:00
Zhao Yuhang a6c7b44b5d moc: code cleanup 2023-11-03 20:35:34 +08:00
Yuhang Zhao 79a9327c01 minor tweaks 2023-11-02 16:39:49 +08:00
Zhao Yuhang 33a6f0df91 adapt to latest qtbase changes 2023-10-31 19:57:01 +08:00
Yuhang Zhao 14dfa52d0b minor tweaks 2023-10-31 11:27:19 +08:00
czy bbfea2c29b
fix #303 mingw compile error (#306) 2023-10-31 10:55:53 +08:00
haikü 46ac2f684d
Fix Windows FramelessHelperHookWindowProc crash (#305)
Application can crash on Windows in the FramelessHelperHookWindowProc callback if the underlying FramelessQuickHelper* has already been deleted. This protects against that crash by using a QPointer to invalidate the instance if it has been deleted which the callback then guards against.
2023-10-29 18:38:23 +08:00
Zhao Yuhang c4a7bc80d0 fix crash 2023-10-21 18:19:56 +08:00
Zhao Yuhang 415fb55222 win: adapt to latest qtbase changes 2023-10-21 11:07:34 +08:00
Zhao Yuhang 78fc5057ab misc: general cleanup 2023-10-21 10:44:07 +08:00
Yuhang Zhao c7f48684ec win: system menu: fix separator can't be removed 2023-10-20 10:59:41 +08:00
Yuhang Zhao 4821e8982f win: system menu: allow user remove menu items 2023-10-20 10:47:53 +08:00
Zhao Yuhang 2cb8ec0aeb win: minor fix 2023-10-19 20:13:34 +08:00
Zhao Yuhang aa489b25d0 win: don't repaint superflus 2023-10-19 19:51:53 +08:00
Yuhang Zhao 3ed04dedeb cmake: minor tweaks 2023-10-19 13:30:49 +08:00
Zhao Yuhang ff4b9f3879 minor tweaks 2023-10-15 13:16:10 +08:00
Yuhang Zhao b13f13a41f win: fix top border color on win10 2023-10-12 19:14:08 +08:00
Yuhang Zhao 12d580cc06 win: workaround Qt bug 2023-10-12 10:56:47 +08:00
Yuhang Zhao 77c3eb57e9 qmake: fix build 2023-10-12 10:18:14 +08:00
Zhao Yuhang b98f1e7a6d cmake: update submodule 2023-10-09 19:48:43 +08:00
Yuhang Zhao a9642dccfc support elided title text 2023-10-08 13:27:15 +08:00
Yuhang Zhao e169c219a0 win: minor tweaks 2023-10-08 10:54:29 +08:00
Yuhang Zhao c8511bacf6 demo: update 2023-10-08 10:16:58 +08:00
Yuhang Zhao ad595c59e4 mica material: don't assume thread is always available 2023-10-07 17:58:57 +08:00
Zhao Yuhang 7a84744dc3 quick: add a way to import static plugin 2023-10-06 16:40:05 +08:00
Yuhang Zhao d86f55832f refactor 2023-10-04 11:37:39 +08:00
Zhao Yuhang b946809927 cmake: fix wrong comipler message 2023-10-02 19:08:12 +08:00
Zhao Yuhang 10a9ba0a62 cmake: remove unreleased clang parameters 2023-10-02 18:15:26 +08:00
Zhao Yuhang d10b8e024c cmake: update submodule 2023-10-02 17:13:17 +08:00
Zhao Yuhang e62885fefc cmake: update submodule 2023-09-30 13:00:43 +08:00
Zhao Yuhang ba7aab0276 win: improve blur mode 2023-09-29 16:06:06 +08:00
Zhao Yuhang 786926e7ab cmake: update submodule 2023-09-29 15:03:04 +08:00
Yuhang Zhao 8f98ab865c win: minor tweaks 2023-09-28 18:06:47 +08:00
Yuhang Zhao 27a9e0857c widget: minor simply 2023-09-26 12:47:23 +08:00
Yuhang Zhao 79d5087df5 quick: fix qml import error
Fixes: #288
Fixes: #233
2023-09-26 12:42:32 +08:00
Zhao Yuhang 8c37fa628a cmake: fix build with static Qt 2023-09-24 16:22:24 +08:00
Zhao Yuhang d48b84ea53 fix linux builds
The #if condition was wrongly inverted during the last huge refactor process.

Fixes: #286
2023-09-23 22:27:56 +08:00
Zhao Yuhang 26b9996ec6 fix qmake build and version 2023-09-14 19:27:07 +08:00
Zhao Yuhang 322c448bc1 minor tweaks 2023-09-13 21:10:57 +08:00
Yuhang Zhao 7b41f9aa31 cmake fixes 2023-09-12 18:15:10 +08:00
Zhao Yuhang 66206aa420 cmake: update 2023-09-10 14:28:38 +08:00
Yuhang Zhao 4df552d526 cmake: move config system to cmake 2023-09-04 18:08:18 +08:00
Yuhang Zhao 97112f853f win: allow square corner on win11 2023-08-31 18:26:49 +08:00
Yuhang Zhao 64a4362580 win: fix regression 2023-08-31 17:20:27 +08:00
Yuhang Zhao c175d16d3d widget: style fix 2023-08-31 16:51:57 +08:00
SineStriker 040027a6e3
Emulate leave event for max button (#278) 2023-08-31 15:55:25 +08:00
Yuhang Zhao 9279500c18 minor tweaks 2023-08-28 11:18:45 +08:00
SineStriker 0ce47469a9
Use better workaround to emulate mouse events (#273) 2023-08-28 11:01:24 +08:00
Yuhang Zhao 7d09a6b9c9 update 2023-08-27 17:33:48 +08:00
Yuhang Zhao f584bd3a34 little fix 2023-08-27 15:59:38 +08:00
Yuhang Zhao 6abb636a19 large refactor 2023-08-27 15:12:06 +08:00
SineStriker 2db829884d
Fix hover bug caused by system popup menu (#272) 2023-08-26 17:59:17 +08:00
SineStriker 102bf93b84
Improve mouse move handler (#271) 2023-08-26 16:21:48 +08:00
SineStriker 2d639071cc
Fix bugs after mouse press (#270) 2023-08-26 16:04:29 +08:00
SineStriker 6ff0bc9300
Fix emulate message bug and git modules, window part mistakes, non client leave mistakes and crash (#269)
* Fix emulate message bug and git modules

* Fix window part mistakes

* Fix WM_NCMOUSELEAVE message mistakes and crash

* Fix maximize minimize button hover problem
2023-08-26 12:18:36 +08:00
Yuhang Zhao bdb1b5d68f snap layout: improve 2023-08-25 18:19:32 +08:00
Yuhang Zhao f7368d0a08 widgets: PIMPL refactor 2023-08-25 17:50:22 +08:00
Yuhang Zhao e6a4849f81 snap layout: refactor 2023-08-25 15:30:20 +08:00
Yuhang Zhao e0abdb04ce snap layout: improve 2023-08-25 14:13:39 +08:00
Yuhang Zhao e8977c7486 snap layout: improve 2023-08-25 13:17:51 +08:00
Yuhang Zhao 95e5791288 win: refactor 2023-08-25 11:09:06 +08:00
Yuhang Zhao 5c8ac2736f quick: PIMPL refactor 2023-08-24 18:05:48 +08:00
Yuhang Zhao 15212abd85 win: fix dialog maximize
issue: #266
2023-08-24 15:00:04 +08:00
Yuhang Zhao 3bc44c267d core: PIMPL refactor 2023-08-24 14:41:43 +08:00
Yuhang Zhao 01f3750efd win: minor tweaks 2023-08-24 13:10:11 +08:00
Yuhang Zhao 4a1f5fb1f4 win: replace an old workaround with new one 2023-08-24 10:24:33 +08:00
Yuhang Zhao a130fef677 win: refactor 2023-08-23 18:04:31 +08:00
Yuhang Zhao 644266923b win: snap layout refactor 2023-08-21 15:07:07 +08:00
Yuhang Zhao 469c686ade refactor 2023-08-21 12:43:44 +08:00
Yuhang Zhao 2202fbf1c2 snap layout: get rid of the transparent window 2023-08-20 16:58:26 +08:00
Yuhang Zhao 58afa6aa95 snap layout: try improve the maximize button handling 2023-08-19 15:45:49 +08:00
Yuhang Zhao 54e3f6232e mica material: fix high dpi scaling 2023-08-19 15:33:11 +08:00
SineStriker 8ac3d747a1
Fix hover event and system buttons (#262)
* Fix hover event

* Fix system button
2023-08-19 14:48:26 +08:00
Yuhang Zhao ca968b7ba6 snap layout: fix qt events 2023-08-19 13:24:29 +08:00
Yuhang Zhao 2c8bd8ce8c win: minor improvements 2023-08-18 17:25:13 +08:00
Yuhang Zhao 44eeb537a2 cmake: update submodule 2023-08-18 12:11:55 +08:00
Yuhang Zhao 9265735ac7 win: use Qt events to set system button state 2023-08-17 14:24:27 +08:00
Yuhang Zhao c85c6d6fc5 fix qt5 build 2023-08-17 11:58:00 +08:00
Yuhang Zhao 4f7919ef5e cmake: update submodule 2023-08-17 11:56:32 +08:00
Yuhang Zhao 861b94d8ac win: improve an old workaround 2023-08-17 11:55:50 +08:00
Yuhang Zhao fc643613c3 cmake: update submodule 2023-08-15 19:51:57 +08:00
Yuhang Zhao a29f30efc3 cmake: update submodule 2023-08-15 11:23:51 +08:00
Yuhang Zhao 013f2e845f win: minor improvement 2023-08-14 11:02:17 +08:00
Yuhang Zhao 2035fed510 win: fix regression 2023-08-07 17:41:15 +08:00
Yuhang Zhao 95e0062264 cmake: fix msvc error 2023-08-07 15:18:40 +08:00
Yuhang Zhao e1e38acd6c linux: workaround qt missing mouse release event 2023-08-07 15:11:03 +08:00
Yuhang Zhao 177e377bb4 mica material: fix multi monitor scenario 2023-08-07 14:31:40 +08:00
Yuhang Zhao 8d3ef93885 win: fix theme not updating 2023-08-05 13:46:23 +08:00
Yuhang Zhao cb3827210c win: minor improvement 2023-08-04 19:27:18 +08:00
Yuhang Zhao 11ad8cce00 cmake: fix wrong target name 2023-08-04 18:50:11 +08:00
Yuhang Zhao 2289c4be73 cmake: fix duplicated target name 2023-08-02 20:00:56 +08:00
Yuhang Zhao 90b2fe42c6 macos: fix compile error 2023-08-01 16:18:57 +08:00
Yuhang Zhao 60a691eb61 macos: fix syntax error 2023-08-01 15:48:12 +08:00
Yuhang Zhao 5500e50075 cmake: update submodule 2023-08-01 15:43:18 +08:00
Yuhang Zhao 3342a28895 refactor 2023-08-01 14:28:09 +08:00
Yuhang Zhao f2758aba25 cmake: minor tweaks 2023-07-30 18:56:07 +08:00
Yuhang Zhao 563a3cfb2d update README 2023-07-30 18:44:18 +08:00
Yuhang Zhao cb21815934 bump version to 2.5.0 2023-07-30 18:29:54 +08:00
Yuhang Zhao 86bc1c0142 cleanup & optimize, part 2
The file size of FramelessHelper binaries should be smaller than before. Core: Win32 MSVC2022 x64 release build, -20KB
The general performance should be improved, due to double lookups are all eliminated.
2023-07-30 18:28:38 +08:00
Yuhang Zhao 20ab4f7d4b mica material: prefer speed over quality 2023-07-30 15:14:16 +08:00
Yuhang Zhao 5b0d06307a cmake: use unique target name and fix install failure 2023-07-29 17:09:35 +08:00
Yuhang Zhao 8cc6a15535 fix qt5 builds 2023-07-29 16:33:04 +08:00
Yuhang Zhao ad90846797 fix qt5 builds 2023-07-29 16:29:05 +08:00
Yuhang Zhao 1b4b5b620f fix qt5 builds 2023-07-29 16:25:47 +08:00
Yuhang Zhao 2f7a104ebd string: use better name 2023-07-29 16:17:13 +08:00
Yuhang Zhao c6ca6cc794 include std headers, avoid transitive include 2023-07-29 15:57:03 +08:00
Yuhang Zhao 4ed21585b4 cleanup core module
Core mostly done. TODO: Widgets & Quick module
2023-07-29 15:29:38 +08:00
Yuhang Zhao d9ce1c4302 win: fix snap layout not working unless resize once 2023-07-28 15:20:25 +08:00
Yuhang Zhao 03832ac86f cmake: update submodule 2023-07-28 14:15:40 +08:00
Yuhang Zhao e84d3a8bd5 cmake: update submodule 2023-07-28 14:13:02 +08:00
Yuhang Zhao 1ed7b7521c cmake: update submodule 2023-07-28 14:11:06 +08:00
Yuhang Zhao b57da216e9 win: minor tweaks 2023-07-22 14:26:25 +08:00
Yuhang Zhao 8e73e3eac8 win: add more sanity checks 2023-07-18 17:53:44 +08:00
Yuhang Zhao 2cd4d133f3 minor tweaks 2023-07-17 16:44:13 +08:00
Yuhang Zhao c1234ed5fb bump version to 2.4.2 2023-07-17 14:55:26 +08:00
Yuhang Zhao 75ca85ec42 cmake: fix wrong file name 2023-07-16 20:35:36 +08:00
Yuhang Zhao f1aec45333 update README 2023-07-16 17:38:12 +08:00
Yuhang Zhao 4ee10e05ba update README 2023-07-15 16:33:18 +08:00
Yuhang Zhao 27663fcb28 quick: minor code simplification 2023-07-15 16:27:30 +08:00
Yuhang Zhao d71dc75b77 mica material: fix drawing on multi-monitor scenario 2023-07-15 16:10:48 +08:00
Dylan Liu 43f632f261
Fix the bug of unregistered datatype QuickGlobal::SystemTheme in Qt 5. (#240) 2023-07-06 11:50:05 +08:00
Yuhang Zhao 9dce992112 cmake: update submodule 2023-07-04 15:14:49 +08:00
Yuhang Zhao d1b4aadb76 mica material: use separate thread to do time-consuming task 2023-07-02 13:48:38 +08:00
Yuhang Zhao 6b09aa9e91 bump version to 2.4.0 2023-07-02 11:56:21 +08:00
Yuhang Zhao 617a015b97 mica material: minor fixes of previous implementation 2023-07-02 11:44:54 +08:00
Yuhang Zhao 7c0d8c4b11 mica material: support reading very large image files 2023-07-01 18:16:57 +08:00
Yuhang Zhao fa5389a0fc ci: try fix ci 2023-06-30 17:31:01 +08:00
Yuhang Zhao 2a49e9fcaf cmake: support ninja multi-config
Fixes: #231
2023-06-30 16:55:26 +08:00
Yuhang Zhao 6ccb25db0a cmake: update submodule 2023-06-29 14:52:42 +08:00
Yuhang Zhao 8f321e2e54 cmake: allow produce same binary
Task-number: #238
2023-06-29 10:59:39 +08:00
Yuhang Zhao f15412cf5b cmake: update submodule 2023-06-26 13:24:56 +08:00
Yuhang Zhao a5ec49d0a2 cmake: update submodule 2023-06-26 11:16:45 +08:00
Yuhang Zhao 86a9b85d04 cmake: fix cmake error on Apple 2023-06-20 11:07:38 +08:00
Yuhang Zhao b7556d467e cmake: update 2023-06-19 18:04:04 +08:00
Yuhang Zhao 074664afc2 cmake: update submodule 2023-06-19 17:48:40 +08:00
Yuhang Zhao 6229a0db3c README: fix wrong function name 2023-06-19 17:14:31 +08:00
Yuhang Zhao 6c27125d69 win: guard some code with proper version check 2023-06-19 16:07:43 +08:00
Yuhang Zhao fdd6640d5c cmake: fix wrong compilation flags 2023-06-19 15:29:14 +08:00
Yuhang Zhao 10b661f541 cmake: update submodule 2023-06-17 12:41:55 +08:00
Yuhang Zhao c1370c4897 cmake: minor change 2023-06-17 12:34:30 +08:00
Dylan Liu af200adf63
Remove unused function in NSWindowProxy. (#236) 2023-06-15 18:48:21 +08:00
Yuhang Zhao 85be988760 ci: fix macos ci 2023-06-10 20:54:07 +08:00
Yuhang Zhao 273e3e204c update submodule 2023-06-10 20:41:46 +08:00
Yuhang Zhao 00b67ead0e win: remove unnecessary code & add some comments
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-06-04 13:28:14 +08:00
Yuhang Zhao 907fdeae67 fix ci: remove unused functions
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-06-03 15:24:04 +08:00
Yuhang Zhao 5a344f3e23 minor fixes & some refactorings
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-06-03 15:13:50 +08:00
Yuhang Zhao b28b6e8d27 update submodule
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-06-03 13:35:02 +08:00
Yuhang Zhao 1e754c1612 minor fixes 2023-06-02 14:51:12 +08:00
Yuhang Zhao f7f8fc3dd0 core: fix wrong override condition
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-05-28 13:55:44 +08:00
Yuhang Zhao e1cf95f208 cmake: fix link with mingw
Signed-off-by: Yuhang Zhao <zhaoyuhang@rankyee.com>
2023-05-26 11:08:08 +08:00
Yuhang Zhao 9778582d9b update README
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-05-25 19:35:29 +08:00
Yuhang Zhao 0424d0ee1b README: add more info
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-05-25 19:30:12 +08:00
Yuhang Zhao 13e93cfed5 cmake: code simplify
Signed-off-by: Yuhang Zhao <zhaoyuhang@rankyee.com>
2023-05-24 15:41:11 +08:00
zhuzichu 9376e4d6e7
fix mingw dont work (#229) 2023-05-24 15:38:51 +08:00
Yuhang Zhao 59fb61d981 cmake: fix old mingw toolchain
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-05-22 19:27:26 +08:00
zhuzichu e090359d9a
fix setOverrideTheme render multiple times (#228)
* fix setOverrideTheme render multiple times

* fix setOverrideTheme render multiple times

* fix encoding utf8

* fix setOverrideTheme render multiple times

---------

Co-authored-by: 朱子楚\zhuzi <zhuzichu520@outlook.com>
2023-05-22 19:15:51 +08:00
Yuhang Zhao e7da37d06a deprecated unused function & other minor tweaks
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-05-21 12:04:57 +08:00
Dylan Liu 3a18f36d3f
Fix the native titlebar buttons don't show below Qt 6.2.4. (#226) 2023-05-20 21:01:23 +08:00
Yuhang Zhao 9df1e9d7b5 mac: add a comment
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-05-20 20:07:43 +08:00
Dylan Liu e48fc7e01f
Fix the native titlebar buttons don't show in Qt 6.0.0 - Qt 6.2.4. (#225) 2023-05-20 19:57:00 +08:00
Yuhang Zhao 2b1623fbd6 cmake: hide detailed info if the user don't want it
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-05-20 15:32:48 +08:00
Yuhang Zhao e67a91d668 refactor: remove all mutexes
They are currently not used and slow down the general performance.
2023-05-19 13:31:20 +08:00
Dylan Liu ec93740bd7
Add manual control of darkmode for Quick. (#220)
Add the function of manual control of dark mode in Quick module.
2023-05-19 13:12:25 +08:00
Yuhang Zhao e4fdb9c260 refactor 2023-05-19 11:58:32 +08:00
Yuhang Zhao de2cad679b update submodule 2023-05-19 11:56:14 +08:00
Yuhang Zhao 1ba9c9c918 refactor 2023-05-19 11:55:41 +08:00
Yuhang Zhao 721f46307b fix cmake syntax error
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-05-18 20:40:46 +08:00
Yuhang Zhao 32b055a7ab cmake: dump more info
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-05-18 20:38:05 +08:00
Yuhang Zhao 8b7ee7a24d cmake: don't touch AppleClang flags
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-05-18 19:58:42 +08:00
Dylan Liu 951dd5f931
Add version check for universal build. (#219) 2023-05-18 19:54:50 +08:00
Yuhang Zhao 2c1164b834 fix win ci warning 2023-05-18 16:49:07 +08:00
Yuhang Zhao 0be45565dc update ci 2023-05-18 16:41:44 +08:00
Yuhang Zhao 2fa3140b0f update submodule 2023-05-18 16:13:48 +08:00
Yuhang Zhao 8d5ea49d52 allow user override system theme
Task-number: #216
2023-05-18 16:08:33 +08:00
Yuhang Zhao 66c2c60a09 DPI change event improve 2023-05-18 14:40:28 +08:00
Yuhang Zhao 82e29f37bb try fix macOS ci 2023-05-18 09:47:30 +08:00
Dylan Liu 84745db4d9
Add Universal build for macOS and compile error fixed. (#217)
* Add Universal build for macOS.

* Fix compile error in example quick.

* Use cmake_dependent_option instead of option.
2023-05-17 20:19:31 +08:00
Yuhang Zhao 84a9a76021 try fix ci 2023-05-17 20:05:06 +08:00
Yuhang Zhao 901aaee7e3 try fix ci 2023-05-17 19:50:11 +08:00
Yuhang Zhao a9ee1c5fff fix ci 2023-05-17 19:31:26 +08:00
Yuhang Zhao 76453b123e fix ci: 6.5.1 has not been released yet 2023-05-17 18:06:00 +08:00
Yuhang Zhao cfcf9f4178 fix ci 2023-05-17 18:04:19 +08:00
Yuhang Zhao 8ece315390 update submodule 2023-05-17 17:51:37 +08:00
Yuhang Zhao 92d850c2a9 add support for Qt 6.6's DPR change event 2023-05-17 13:22:42 +08:00
Yuhang Zhao 224302500d cmake: quick: fix build with version below 6.3
Fixes: #215
2023-05-17 09:20:53 +08:00
Yuhang Zhao cf568b6e7a cmake: use Qt's official function to get the quick plugin info 2023-05-16 18:01:06 +08:00
Yuhang Zhao a3cfa59d1d improve dpi change experience
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-05-13 11:30:54 +08:00
Yuhang Zhao 250aff0faf cmake: fix build on arm64 platforms 2023-05-04 17:37:43 +08:00
Yuhang Zhao b039a9130a win: minor refactor 2023-04-28 09:14:06 +08:00
Yuhang Zhao 4d063369fa mica material: add fallback color and fix the qtquick one
I don't understand why I didn't make QuickMicaMaterial configurable.
2023-04-27 10:36:47 +08:00
Yuhang Zhao 41e91bb39a win: fix wrong restore geometry when after DPI changes 2023-04-25 15:19:31 +08:00
Yuhang Zhao 30d2261baf bump version to 2.3.7 2023-04-24 15:43:17 +08:00
Yuhang Zhao fe724271da unix: fix wrong system menu position 2023-04-24 13:18:57 +08:00
Yuhang Zhao b2561c16ba minor refactor 2023-04-23 13:42:27 +08:00
Yuhang Zhao a203e2c3ca win32: fix restore geometry bug
The upstream fix has not been merged yet, however, it will be in 6.5.1 for sure.

Fixes: #20

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-04-22 15:21:49 +08:00
Yuhang Zhao 8930ea128f minor tweaks
Signed-off-by: Yuhang Zhao <zhaoyuhang@rankyee.com>
2023-04-17 11:16:50 +08:00
Yuhang Zhao 3b8571401f minor refactor 2023-04-11 17:09:58 +08:00
Yuhang Zhao 99417bf916 fix coordinate calculation in multi-monitor scenarios 2023-04-11 15:12:33 +08:00
Yuhang Zhao b9dcaac87d remove unused tool
Signed-off-by: Yuhang Zhao <zhaoyuhang@rankyee.com>
2023-04-07 17:22:39 +08:00
Yuhang Zhao 9dd57367a7 bump version to 2.3.6
Signed-off-by: Yuhang Zhao <zhaoyuhang@rankyee.com>
2023-04-07 17:22:16 +08:00
Yuhang Zhao b4a27c059b fix system menu wrong position
Signed-off-by: Yuhang Zhao <zhaoyuhang@rankyee.com>
2023-04-07 16:56:58 +08:00
Yuhang Zhao b597d2c91a update submodule 2023-04-07 16:42:11 +08:00
Yuhang Zhao 632a708c8a fix white-line issue for QWidget applications
Fixes: #204

Signed-off-by: Yuhang Zhao <zhaoyuhang@rankyee.com>
2023-04-07 16:41:39 +08:00
Yuhang Zhao d49c3be147 fix runtime error
Signed-off-by: Yuhang Zhao <zhaoyuhang@rankyee.com>
2023-04-04 16:47:03 +08:00
Yuhang Zhao 55ecb4f5dd fix invalid parameter for msvc
Signed-off-by: Yuhang Zhao <zhaoyuhang@rankyee.com>
2023-04-04 10:52:54 +08:00
Yuhang Zhao 48a3270356 update submodule
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-04-01 20:15:25 +08:00
Yuhang Zhao 1effb497ce update cmake scripts, fix clang-cl build
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-04-01 14:00:10 +08:00
Yuhang Zhao b5c9f85f62 allow user force use system blur
Signed-off-by: Yuhang Zhao <zhaoyuhang@rankyee.com>
2023-03-30 14:16:34 +08:00
Yuhang Zhao 9e208bb77c fix build on qt5
Task-number: #210

Signed-off-by: Yuhang Zhao <zhaoyuhang@rankyee.com>
2023-03-30 11:47:34 +08:00
Yuhang Zhao 5ade3cfb74 fix hidpi position calculation
Task-number: #210

Signed-off-by: Yuhang Zhao <zhaoyuhang@rankyee.com>
2023-03-30 11:39:05 +08:00
Yuhang Zhao 2a6b8e6ebe fix compilation error
Fixes: #211
2023-03-30 10:28:31 +08:00
Yuhang Zhao b864e39894 cmake: update submodule
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-03-10 20:09:19 +08:00
Yuhang Zhao 0b0da5f4b1 cmake: update
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-03-04 16:44:23 +08:00
Yuhang Zhao b9cd887dbc msbuild: install & tweaks
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-03-04 16:21:49 +08:00
Yuhang Zhao c4a29df155 Add MSBuild support
Thanks to @MouriNaruto !

Co-authored-by: MouriNaruto <Mouri_Naruto@Outlook.com>
2023-02-26 10:00:27 +08:00
Yuhang Zhao a0c825930e win: allow user disable specific system menu items
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-24 15:40:08 +08:00
Yuhang Zhao 598de50290 add synchronize api to wait for the ready signal
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-24 13:13:01 +08:00
Yuhang Zhao e2652fc2a9 cmake: minor tweaks
Fixes: #205

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-24 10:03:10 +08:00
Yuhang Zhao 45c1c005fe cmake: update submodule
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-23 13:17:06 +08:00
Yuhang Zhao c197653efe examples: improve cmake script
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-21 09:34:44 +08:00
Yuhang Zhao b6af9f58f6 fix x86 build
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-20 13:13:04 +08:00
Yuhang Zhao c944655e63 cmake: fix wrong syntax
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-19 17:32:28 +08:00
Yuhang Zhao 5bd4db212e ci: fix
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-19 17:20:37 +08:00
Yuhang Zhao 1fb3b282ed ci: temporarily unblock ci
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-19 17:08:46 +08:00
Yuhang Zhao fa5a21f7ca cmake: minor tweaks
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-19 17:01:56 +08:00
Yuhang Zhao 9e341e4e40 examples: update cmake project
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-19 16:31:24 +08:00
Yuhang Zhao cf2bc7c1b9 update submodule
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-19 13:17:25 +08:00
Yuhang Zhao b5bbb341a4 cmake: minor improvement
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-19 13:14:45 +08:00
Yuhang Zhao f6383c5832 ci: fix ci
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-19 13:00:11 +08:00
Yuhang Zhao 9a81cf1503 cmake: improve the package code
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-19 12:36:41 +08:00
Yuhang Zhao a375bc6748 sysapiloader: minor improvements of previous refactor
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-17 09:59:41 +08:00
Yuhang Zhao fa8ca1ae2f cmake: let user be able to change the namespace
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-17 09:21:52 +08:00
Yuhang Zhao 4929707806 fix header search path
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-17 09:17:15 +08:00
Yuhang Zhao 02f70d1ade sysapiloader: minor improvements
And some other minor refactors.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-16 14:55:26 +08:00
Yuhang Zhao 7fb9b312b1 ci: try fix
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-15 17:14:28 +08:00
Yuhang Zhao 11c85a9229 ci: try fix
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-15 17:12:13 +08:00
Yuhang Zhao 4e01917b35 ci: try fix
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-15 17:05:03 +08:00
Yuhang Zhao 75fc33325b ci: try fix
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-15 16:56:39 +08:00
Yuhang Zhao 0034927378 ci: try fix
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-15 16:51:01 +08:00
Yuhang Zhao 36c691e239 ci: try fix
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-15 16:44:44 +08:00
Yuhang Zhao d43551e6e4 ci: try fix
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-15 15:50:41 +08:00
Yuhang Zhao a246b25019 ci: try fix
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-15 15:28:14 +08:00
Yuhang Zhao 5566a0cbc4 ci: try fix ci
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-15 15:14:56 +08:00
Yuhang Zhao 3523ea67ea cmake: update submodule
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-15 14:53:29 +08:00
Yuhang Zhao 9bf6361171 qt: adapt to latest qt dev code
It was decided to rename the property from Appearance to ColorScheme.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-15 11:22:52 +08:00
Yuhang Zhao 8bd2a777d1 cmake: update submodule
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-14 11:50:06 +08:00
Yuhang Zhao 2b9d810002 cmake: minor tweaks
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-10 14:10:46 +08:00
Yuhang Zhao 16c10d7569 linux: fix typo in code memo
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-08 13:44:15 +08:00
Yuhang Zhao 6048349e52 cmake: allow turn off cmake summary
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-08 13:19:23 +08:00
Yuhang Zhao c461a1cf51 linux: add some code memo
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-08 10:02:20 +08:00
Yuhang Zhao e7e6426dca linux: another attempt to fix the segfault
Related: #202

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-07 14:38:18 +08:00
Yuhang Zhao 91239fca90 update macos screenshots
Fixes: #203

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-07 13:32:16 +08:00
Yuhang Zhao 4d43296e28 update readme
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-07 11:15:54 +08:00
Yuhang Zhao dc848b3da2 update screenshot for macos
Related issue: #203

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-07 11:11:48 +08:00
Yuhang Zhao c56aa7b594 linux: try fix segfault further
Related reports: #201 #202

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-06 15:12:12 +08:00
Yuhang Zhao 8b6dd746eb refactor
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-06 15:08:19 +08:00
Yuhang Zhao 4cb9c9c60d linux: fix segfault on some distros
Task-number: #201
Task-number: #202

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-06 13:40:12 +08:00
Yuhang Zhao a0125df8cd fix macos build
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-06 09:13:40 +08:00
Yuhang Zhao fc92783af9 misc modifications
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-05 18:54:34 +08:00
Yuhang Zhao e9a2abf663 fix macos build
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-05 14:12:01 +08:00
Yuhang Zhao 9cadad625a fix linux build
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-05 14:06:33 +08:00
Yuhang Zhao 14ccc990cf general refactor, remove useless code
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-05 14:01:46 +08:00
Yuhang Zhao 3d37d87c81 win: tweak some enum values
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-03 11:18:08 +08:00
Yuhang Zhao 2040e7c747 try fix ci
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-02 13:24:46 +08:00
Yuhang Zhao 544d3b898b minor cmake tweaks
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-02-02 13:07:09 +08:00
Yuhang Zhao 0a85d47390 update README
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-31 17:45:09 +08:00
Yuhang Zhao c69ede0fca update submodule
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-30 17:35:44 +08:00
Yuhang Zhao 0b5df78866 update submodule
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-28 15:16:22 +08:00
Yuhang Zhao ed75e2f3e8 adapt to latest Qt code style
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-27 18:16:32 +08:00
Yuhang Zhao f16fb95cba try fix ci
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-27 17:31:46 +08:00
Yuhang Zhao 6063a962eb simplify cmake scripts
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-27 16:27:16 +08:00
Yuhang Zhao 5cd386a419 qmake: adapt latest cmake changes
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-25 13:49:06 +08:00
Yuhang Zhao 69ef2a6ca1 linux: fix potential segment faults
Fixes: #199

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-24 16:57:44 +08:00
Yuhang Zhao a23438b02b win: add one more safe guard
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-18 18:01:10 +08:00
Yuhang Zhao 7534a4631c migrate to the <module/file> include pattern
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-18 14:27:10 +08:00
Yuhang Zhao 378aa7db12 fix nested frameless windows & other minor tweaks
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-18 13:43:51 +08:00
Yuhang Zhao 4896869123 use better name
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-18 10:00:18 +08:00
Yuhang Zhao 139d5a41df quick demo: a little improvement
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-15 14:34:14 +08:00
Yuhang Zhao 5e7ddb1864 quick: adapt macos updates
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-15 14:11:52 +08:00
Yuhang Zhao d25666b0e6 titlebar: fix calculation error of previous commit
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-14 20:54:29 +08:00
Yuhang Zhao 819ffb79fb macOS: widgets: preserve the native title bar elements
Quick part to be done.
2023-01-14 18:32:47 +08:00
Yuhang Zhao 9e975e02e0 cmake: fix export error
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-14 12:59:18 +08:00
Yuhang Zhao d1f17eb239 cmake: add option to disable install
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-14 12:23:04 +08:00
Yuhang Zhao eb6fc55006 quick: remove unneeded enums, fix warning
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-13 17:47:37 +08:00
Yuhang Zhao 6e79ba3f33 minor tweaks
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-13 13:39:21 +08:00
Yuhang Zhao 653fa1d6f1 quick demo: fix for latest qt
The onClosing signal was removed in latest qt.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-12 09:11:29 +08:00
Yuhang Zhao 814d2ad12d cmake: detect qt library type
Fixes: #200

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-05 15:07:38 +08:00
Yuhang Zhao 16479be799 quick demo: minor tweaks
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-03 13:38:00 +08:00
Yuhang Zhao 3a97e712fb fixes repaint issue on macos
fixes:  #197

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2023-01-01 14:19:14 +08:00
Yuhang Zhao f651116fda msvc: allow disable permissive checks
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-30 11:01:43 +08:00
micpub 32457c5538
fix qmake linux build, and fix the "Quick" example (#194)
* fix: qmake linux build

* little fix for the "Quick" example

Window.qml / ApplicationWindow.qml: fix: "FramelessApplicationWindow.onClosing" is not available in org.wangwenx190.FramelessHelper 1.0.

* remove xcb - as requested
2022-12-30 10:35:20 +08:00
Yuhang Zhao 4a903a5805 linux: improve configure log
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-28 11:33:24 +08:00
Yuhang Zhao a5586604e9 quick: fix build error
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-28 11:22:40 +08:00
Yuhang Zhao d4c087f627 linux: comment out some code that doesn't work
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-25 13:36:18 +08:00
Yuhang Zhao 7327179d77 linux: add temporary solution to get theme color
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-25 13:33:34 +08:00
Yuhang Zhao 8a1dcfb808 minor refactor
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-23 10:11:59 +08:00
Yuhang Zhao 0924aeb51f linux: finalize x11 function tweaks
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-21 11:43:37 +08:00
Yuhang Zhao ea6a070766 linux: fix the regression caused by previous refactoring
Sadly we have to bring back the GTK dependency at compile time.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-20 16:39:20 +08:00
Yuhang Zhao ba709ec598 fix linux ci
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-20 13:06:13 +08:00
Yuhang Zhao 62527f4f88 minor code tidies
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-20 11:59:25 +08:00
Yuhang Zhao 16501e9bd7 fix linux ci, finally
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-19 17:59:34 +08:00
Yuhang Zhao 55f67ac707 fix linux ci
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-19 17:53:28 +08:00
Yuhang Zhao 4e46ba4fb5 linux: fix build on Qt5
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-19 17:49:00 +08:00
Yuhang Zhao 768ab6da4b win: fix the border color, take 2
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-19 17:39:36 +08:00
Yuhang Zhao a381836ef7 linux: further improvements
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-19 16:37:48 +08:00
Yuhang Zhao 840cf3060d general fixes
fixed some minor issues

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-19 11:35:05 +08:00
Yuhang Zhao c3fa2f6920 minor fixes of previous commit 2022-12-16 10:48:38 +08:00
Yuhang Zhao 5b36fe8a81 linux: add missing file
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-15 15:56:42 +08:00
Yuhang Zhao 34ba90376b linux: remove the build-time dependency of libxcb and libgtk
We can load them dynamically at run-time.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-15 15:48:56 +08:00
Yuhang Zhao 8683a14a3c fix compilation error
fixes: #191

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-15 13:09:51 +08:00
1bbb 4844257fc8 支持嵌套无边框组件 2022-12-15 11:32:57 +08:00
Yuhang Zhao d5d1edd690 win: add ms license header
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-14 16:23:27 +08:00
Yuhang Zhao 493663a787 win: minor tweaks
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-14 16:17:07 +08:00
Yuhang Zhao 45225d11d8 remove needless terminate character
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-13 16:31:00 +08:00
Yuhang Zhao b420e67fad cmake: fix warning from Qt 6.5
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-13 15:58:49 +08:00
Yuhang Zhao d4293e0a55 win: refactor
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-13 11:36:41 +08:00
Yuhang Zhao c849217d43 fix build on linux and macos
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-12 14:55:17 +08:00
Yuhang Zhao d04eaabde7 minor tweaks
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-12 13:42:18 +08:00
Yuhang Zhao f00adba67c replace QScopedPointer with std::unique_ptr
QScopedPointer is being deprecated in latest qtbase code.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-12 11:59:53 +08:00
Yuhang Zhao ed3771c949 replace qRound with std::round
It's better to do so.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-12 09:34:46 +08:00
Yuhang Zhao b1f52837d2 replace qAsConst with std::as_const
qAsConst is being deprecated in latest qtbase code.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-12 09:30:16 +08:00
Yuhang Zhao e77341d128 win: adjust one version condition
It's decided that the fix will not be cherry-picked to the 6.2 branch.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-08 15:36:27 +08:00
Yuhang Zhao 61eb467f94 remove license header from qrc files
They may break compilation.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-08 11:37:21 +08:00
Yuhang Zhao 8003f79e17 icon: replace Micon with our own custom one
Because Micon has some license issues.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-06 16:53:37 +08:00
Yuhang Zhao 64ef4b25ca fix MSVC warning found by /W4
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-06 16:06:13 +08:00
Yuhang Zhao 1e429b363b cmake: minor tweaks
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-06 14:35:04 +08:00
Yuhang Zhao 87953f1382 cmake: minor tweaks
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-06 11:43:05 +08:00
Yuhang Zhao 3df052de81 cmake: minor tweaks
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-06 11:18:34 +08:00
Yuhang Zhao f956c1c002 cmake: minor tweaks
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-05 17:12:17 +08:00
Yuhang Zhao cb88b602fe minor tweaks
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-05 14:33:38 +08:00
Yuhang Zhao 7e6b629396 ci: minor tweaks
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-04 14:53:21 +08:00
Yuhang Zhao 7daa1facc7 fix build on Qt version < 6.2.1
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-04 14:49:16 +08:00
Yuhang Zhao 48a1106fc0 Allow build with no private Qt modules
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-12-04 14:25:09 +08:00
Yuhang Zhao d14a0e62d9 bump version
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-11-29 19:51:33 +08:00
Yuhang Zhao 40058a1e79 cmake: allow disable resource bundle
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-11-26 16:44:41 +08:00
Yuhang Zhao 9c08c69a4d bump version to 2.3.4
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-11-24 13:47:29 +08:00
Yuhang Zhao 1cf5a53ecb fix build error
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-11-24 10:47:55 +08:00
Yuhang Zhao a26df61c33 win: fix multi-monitor bug, take 3
#141
#184

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-11-24 10:38:21 +08:00
Yuhang Zhao ff5b171566 win: final fix of the multi-monitor bug
#141
#184

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-11-23 14:54:46 +08:00
Yuhang Zhao ebd3d6573f win: fix the multi monitor window expand issue
#141
#184

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-11-22 15:03:11 +08:00
Yuhang Zhao 3961ecb505 quick: fix a regression
Looks like we can't use overloads in QML documents.

Should fix #183

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-11-21 17:12:33 +08:00
Yuhang Zhao 648876b6b0 win: add a little delay to some operations
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-11-20 12:56:36 +08:00
Yuhang Zhao 04f254556d minor tweaks
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-11-17 10:24:45 +08:00
Yuhang Zhao 3791802d3b win: add support for mica alt and other tweaks
Add some more comments to the windows header.
Remove the usages of UseRoundWindowCorner.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-11-16 14:10:49 +08:00
Yuhang Zhao b09acecac6 try re-trigger ci
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-11-13 13:29:41 +08:00
Yuhang Zhao 2c93d7fe38 some minor tweaks
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-11-13 13:24:30 +08:00
Yuhang Zhao 524f65cc9b win: some minor improvements
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-11-11 15:25:39 +08:00
Yuhang Zhao 766c1e148e linux & macos: add missing code
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-11-11 11:46:44 +08:00
Yuhang Zhao 027780429d win: add more safe guards to dpi hacks
And some other minor improvements.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
2022-11-11 11:38:06 +08:00
187 changed files with 14585 additions and 9935 deletions

View File

@ -11,26 +11,32 @@ on:
- "**.jpeg"
- ".gitignore"
workflow_dispatch:
pull_request:
jobs:
build:
name: Build
strategy:
matrix:
qt-version: [5.15.2, 6.4.0]
build-type: [Debug, Release]
qt-version: [5.15.2, 6.5.3]
library-type: [shared, static]
platform: [windows-latest, ubuntu-latest, macos-latest]
include:
- platform: windows-latest
CC: cl
CXX: cl
CC: cl.exe
CXX: cl.exe
LD: link.exe
EXTRA_FLAGS: -DFRAMELESSHELPER_ENABLE_SPECTRE=ON -DFRAMELESSHELPER_ENABLE_EHCONTGUARD=ON -DFRAMELESSHELPER_ENABLE_INTELCET=ON -DFRAMELESSHELPER_ENABLE_CFGUARD=ON
- platform: ubuntu-latest
CC: gcc
CXX: g++
LD: ld
EXTRA_FLAGS: -DFRAMELESSHELPER_ENABLE_SPECTRE=ON -DFRAMELESSHELPER_ENABLE_INTELCET=ON -DFRAMELESSHELPER_ENABLE_CFGUARD=ON
- platform: macos-latest
CC: clang
CXX: clang++
CC: /usr/local/opt/llvm/bin/clang
CXX: /usr/local/opt/llvm/bin/clang++
LD: /usr/local/opt/llvm/bin/ld64.lld
EXTRA_FLAGS: -DFRAMELESSHELPER_ENABLE_UNIVERSAL_BUILD=OFF
- library-type: shared
lib_type_flag: -DFRAMELESSHELPER_BUILD_STATIC=OFF
- library-type: static
@ -41,6 +47,8 @@ jobs:
steps:
- name: Check out repository
uses: actions/checkout@v3
with:
submodules: recursive
- name: Install Qt SDK
uses: jurplel/install-qt-action@v3
@ -60,12 +68,20 @@ jobs:
- name: Install Linux dependencies
if: ${{ matrix.platform == 'ubuntu-latest' }}
run: |
sudo apt install -y libxcb1-dev libgtk-3-dev
sudo apt install -y libgl1-mesa-dev libxcb1-dev libgtk-3-dev
- name: Install macOS dependencies
if: ${{ matrix.platform == 'macos-latest' }}
run: |
brew update
brew upgrade
brew install llvm
export PATH="/usr/local/opt/llvm/bin:$PATH"
- name: Build library with CMake
run: |
mkdir ci-test-build
cd ci-test-build
cmake -DCMAKE_C_COMPILER=${{ matrix.CC }} -DCMAKE_CXX_COMPILER=${{ matrix.CXX }} -DCMAKE_INSTALL_PREFIX=../ci-test-install -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} -DFRAMELESSHELPER_EXAMPLES_DEPLOYQT=OFF ${{ matrix.lib_type_flag }} -GNinja ..
cmake --build . --target all --config ${{ matrix.build-type }} --parallel
cmake --install . --config ${{ matrix.build-type }}
mkdir ci
cd ci
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_C_COMPILER=${{ matrix.CC }} -DCMAKE_CXX_COMPILER=${{ matrix.CXX }} -DCMAKE_LINKER=${{ matrix.LD }} -DCMAKE_INSTALL_PREFIX=../../install -DCMAKE_BUILD_TYPE=Release -DFRAMELESSHELPER_BUILD_EXAMPLES=ON -DFRAMELESSHELPER_NO_SUMMARY=OFF ${{ matrix.lib_type_flag }} ${{ matrix.EXTRA_FLAGS }} -GNinja ..
cmake --build . --target all --config Release --parallel
cmake --install . --config Release --strip

4
.gitignore vendored
View File

@ -45,7 +45,7 @@ target_wrapper.*
# QtCreator CMake
CMakeLists.txt.user*
# QtCreator 4.8< compilation database
# QtCreator 4.8< compilation database
compile_commands.json
# QtCreator local machine specific files for imported projects
@ -54,6 +54,8 @@ compile_commands.json
# My
[Bb]in/
[Bb]in64/
[Ll]ib/
[Ll]ib64/
[Bb]uild*/
*.7z
*.zip

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "cmake"]
path = cmake
url = ../../wangwenx190/cmake-utils.git

View File

@ -1,7 +1,7 @@
#[[
MIT License
Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -25,80 +25,44 @@
cmake_minimum_required(VERSION 3.20)
project(FramelessHelper
VERSION 2.3.2.0
VERSION "2.5.0"
DESCRIPTION "Cross-platform window customization framework for Qt Widgets and Qt Quick."
HOMEPAGE_URL "https://github.com/wangwenx190/framelesshelper/"
LANGUAGES CXX
)
include(CMakeDependentOption)
include(cmake/utils.cmake)
# TODO: Use add_feature_info() for every option below? Is it worth doing?
option(FRAMELESSHELPER_BUILD_STATIC "Build FramelessHelper as a static library." OFF)
option(FRAMELESSHELPER_BUILD_WIDGETS "Build FramelessHelper's Widgets module." ON)
option(FRAMELESSHELPER_BUILD_QUICK "Build FramelessHelper's Quick module." ON)
option(FRAMELESSHELPER_BUILD_EXAMPLES "Build FramelessHelper demo applications." ON)
option(FRAMELESSHELPER_EXAMPLES_DEPLOYQT "Deploy the Qt framework after building the demo projects." ON)
option(FRAMELESSHELPER_NO_DEBUG_OUTPUT "Suppress the debug messages from FramelessHelper." OFF)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
if(NOT DEFINED CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
if(NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE)
# MinGW has many bugs when LTO is enabled, and they are all very
# hard to workaround, so just don't enable LTO at all for MinGW.
if(NOT MINGW)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON)
endif()
endif()
if(NOT DEFINED CMAKE_DEBUG_POSTFIX)
if(WIN32)
set(CMAKE_DEBUG_POSTFIX d)
else()
set(CMAKE_DEBUG_POSTFIX _debug)
endif()
endif()
if(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
endif()
if(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
endif()
if(NOT DEFINED CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
endif()
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(PROJECT_VERSION_COMMIT "UNKNOWN")
find_program(GIT_EXECUTABLE_PATH git)
if(GIT_EXECUTABLE_PATH AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git")
execute_process(
COMMAND ${GIT_EXECUTABLE_PATH} rev-parse HEAD
OUTPUT_VARIABLE PROJECT_VERSION_COMMIT
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
endif()
set(PROJECT_COMPILE_DATETIME "UNKNOWN")
string(TIMESTAMP PROJECT_COMPILE_DATETIME UTC)
option(FRAMELESSHELPER_BUILD_EXAMPLES "Build FramelessHelper demo applications." OFF)
option(FRAMELESSHELPER_EXAMPLES_DEPLOYQT "Deploy the Qt framework after building the demo projects." OFF)
option(FRAMELESSHELPER_NO_DEBUG_OUTPUT "Suppress the debug messages from FramelessHelper." ON)
option(FRAMELESSHELPER_NO_BUNDLE_RESOURCE "Do not bundle any resources within FramelessHelper." OFF)
option(FRAMELESSHELPER_NO_PRIVATE "Do not use any private functionalities from Qt." OFF)
option(FRAMELESSHELPER_ENABLE_VCLTL "MSVC only: link to the system MSVCRT/UCRT and get rid of API sets." OFF)
option(FRAMELESSHELPER_ENABLE_YYTHUNKS "MSVC only: dynamic load most Win32 APIs to give better compatibility for old Windows versions." OFF)
option(FRAMELESSHELPER_NO_PERMISSIVE_CHECKS "MSVC only: disable the additional permissive checks." OFF)
option(FRAMELESSHELPER_NO_INSTALL "Don't install any files." OFF)
option(FRAMELESSHELPER_NO_SUMMARY "Don't show CMake configure summary." ON)
option(FRAMELESSHELPER_ENABLE_SPECTRE "Mitigate Spectre security vulnerabilities." OFF)
option(FRAMELESSHELPER_ENABLE_EHCONTGUARD "MSVC only: Enable EH Continuation (EHCONT) Metadata." OFF)
option(FRAMELESSHELPER_ENABLE_INTELCET "Enable Intel CET." OFF)
#option(FRAMELESSHELPER_ENABLE_INTELJCC "Enable Intel JCC." OFF) # Always enabled now.
option(FRAMELESSHELPER_ENABLE_CFGUARD "Enable Control Flow Guard (CFG)." OFF)
option(FRAMELESSHELPER_EXAMPLES_STANDALONE "Build the demo projects as standalone CMake projects." OFF)
cmake_dependent_option(FRAMELESSHELPER_ENABLE_UNIVERSAL_BUILD "macOS only: build universal library/example for Mac." ON APPLE OFF)
option(FRAMELESSHELPER_FORCE_LTO "Force enable LTO/LTCG even when building static libraries." OFF)
#option(FRAMELESSHELPER_REPRODUCIBLE_OUTPUT "Don't update the build commit and date dynamically." ON) # Always enabled now.
option(FRAMELESSHELPER_NO_WINDOW "Disable the pre-defined FramelessWindow wrapper class." OFF)
option(FRAMELESSHELPER_NO_TITLEBAR "Disable the pre-defined StandardTitleBar control." OFF)
option(FRAMELESSHELPER_NO_TRANSLATION "Don't bundle the I18N translations into the library." OFF)
option(FRAMELESSHELPER_NO_MICA_MATERIAL "Disable the cross-platform homemade Mica Material." OFF)
option(FRAMELESSHELPER_NO_BORDER_PAINTER "Disable the cross-platform window frame border painter." OFF)
option(FRAMELESSHELPER_NO_SYSTEM_BUTTON "Disable the pre-defined StandardSystemButton control." OFF)
cmake_dependent_option(FRAMELESSHELPER_NATIVE_IMPL "Use platform native implementation instead of Qt to get best experience." ON WIN32 OFF)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Gui)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Gui)
@ -106,25 +70,172 @@ find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Gui)
find_package(QT NAMES Qt6 Qt5 QUIET COMPONENTS Widgets Quick)
find_package(Qt${QT_VERSION_MAJOR} QUIET COMPONENTS Widgets Quick)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion
if(FRAMELESSHELPER_NATIVE_IMPL AND NOT WIN32)
message(WARNING "FRAMELESSHELPER_NATIVE_IMPL currently only supports the Windows platform!")
set(FRAMELESSHELPER_NATIVE_IMPL OFF)
endif()
if(FRAMELESSHELPER_NO_WINDOW AND FRAMELESSHELPER_BUILD_EXAMPLES)
message(WARNING "You can't build the examples when the FramelessWindow class is disabled at the same time!")
set(FRAMELESSHELPER_BUILD_EXAMPLES OFF)
endif()
if(FRAMELESSHELPER_ENABLE_UNIVERSAL_BUILD AND NOT APPLE)
message(WARNING "Universal build is a macOS only feature, it will be disabled on current platform.")
set(FRAMELESSHELPER_ENABLE_UNIVERSAL_BUILD OFF)
elseif(APPLE AND ((QT_VERSION VERSION_LESS "6.2" AND QT_VERSION VERSION_GREATER_EQUAL "6.0") OR (QT_VERSION VERSION_LESS "5.15.9")))
message(WARNING "Your Qt version ${QT_VERSION} doesn't support universal build, it will be disabled.")
set(FRAMELESSHELPER_ENABLE_UNIVERSAL_BUILD OFF)
endif()
if(FRAMELESSHELPER_NO_BUNDLE_RESOURCE)
message(WARNING "Nothing will be embeded into the FramelessHelper library, the chrome buttons will have no icon.")
endif()
if(FRAMELESSHELPER_ENABLE_VCLTL AND NOT MSVC)
message(WARNING "VC-LTL is only available for the MSVC toolchain.")
set(FRAMELESSHELPER_ENABLE_VCLTL OFF)
endif()
if(FRAMELESSHELPER_ENABLE_YYTHUNKS AND NOT MSVC)
message(WARNING "YY-Thunks is only available for the MSVC toolchain.")
set(FRAMELESSHELPER_ENABLE_YYTHUNKS OFF)
endif()
if(NOT TARGET Qt${QT_VERSION_MAJOR}::Core OR NOT TARGET Qt${QT_VERSION_MAJOR}::Gui)
message(WARNING "Can't find the QtCore and/or QtGui module. Nothing will be built.")
set(FRAMELESSHELPER_BUILD_WIDGETS OFF)
set(FRAMELESSHELPER_BUILD_QUICK OFF)
set(FRAMELESSHELPER_BUILD_EXAMPLES OFF)
endif()
if(FRAMELESSHELPER_BUILD_QUICK AND NOT TARGET Qt${QT_VERSION_MAJOR}::Quick)
message(WARNING "Can't find the QtQuick module. FramelessHelper's QtQuick implementation and the QtQuick demo won't be built.")
set(FRAMELESSHELPER_BUILD_QUICK OFF)
endif()
set(FRAMELESSHELPER_64BIT_POSTFIX "")
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(FRAMELESSHELPER_64BIT_POSTFIX "64")
endif()
set(FRAMELESSHELPER_LICENSE_HEADER "/*
* MIT License
*
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the \"Software\"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/")
set(__extra_flags "")
if(NOT FRAMELESSHELPER_BUILD_STATIC)
list(APPEND __extra_flags ENABLE_LTO)
endif()
setup_project(
QT_PROJECT
QML_IMPORT_DIR "${PROJECT_BINARY_DIR}/imports"
LICENSE_HEADER "${FRAMELESSHELPER_LICENSE_HEADER}"
LANGUAGES CXX RC
MAX_WARNING
RTTI
EXCEPTIONS
${__extra_flags}
)
unset(__extra_flags)
if(MINGW AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(FRAMELESSHELPER_ENABLE_SPECTRE OFF)
set(FRAMELESSHELPER_ENABLE_EHCONTGUARD OFF)
set(FRAMELESSHELPER_ENABLE_INTELCET OFF)
#set(FRAMELESSHELPER_ENABLE_INTELJCC OFF)
set(FRAMELESSHELPER_ENABLE_CFGUARD OFF)
endif()
if(FRAMELESSHELPER_ENABLE_VCLTL)
include(cmake/VC-LTL.cmake)
if("x${SupportLTL}" STREQUAL "xtrue")
# Make sure we will always overwrite the previous settings.
unset(CMAKE_MSVC_RUNTIME_LIBRARY)
unset(CMAKE_MSVC_RUNTIME_LIBRARY CACHE)
#unset(CMAKE_MSVC_RUNTIME_LIBRARY PARENT_SCOPE)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>" CACHE STRING "" FORCE)
endif()
endif()
if(FRAMELESSHELPER_ENABLE_YYTHUNKS)
unset(YYTHUNKS_TARGET_OS)
unset(YYTHUNKS_TARGET_OS CACHE)
#unset(YYTHUNKS_TARGET_OS PARENT_SCOPE)
set(YYTHUNKS_TARGET_OS "WinXP" CACHE STRING "" FORCE)
include(cmake/YY-Thunks.cmake)
endif()
set(__extra_flags "")
if(FRAMELESSHELPER_NO_INSTALL)
list(APPEND __extra_flags NO_INSTALL)
endif()
prepare_package_export(
PACKAGE_NAME "${PROJECT_NAME}"
PACKAGE_VERSION "${PROJECT_VERSION}"
${__extra_flags}
)
unset(__extra_flags)
set(FRAMELESSHELPER_VERSION_FILE "${PROJECT_BINARY_DIR}/framelesshelper.version")
generate_project_version(
PATH "${FRAMELESSHELPER_VERSION_FILE}"
COMMIT_HASH COMMIT_SUBJECT COMMIT_AUTHOR
COMMIT_DATETIME COMMIT_BRANCH COMPILER_NAME
COMPILER_VENDOR COMPILER_VERSION BUILD_DATETIME
ARCHITECTURE CMAKE_VERSION GENERATOR
)
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}Config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
NO_CHECK_REQUIRED_COMPONENTS_MACRO
)
set(FRAMELESSHELPER_CONFIG_FILE "${PROJECT_BINARY_DIR}/framelesshelper.config")
add_project_config(KEY "static_build" CONDITION FRAMELESSHELPER_BUILD_STATIC)
add_project_config(KEY "widgets" CONDITION FRAMELESSHELPER_BUILD_WIDGETS)
add_project_config(KEY "quick" CONDITION FRAMELESSHELPER_BUILD_QUICK)
add_project_config(KEY "debug_output" CONDITION NOT FRAMELESSHELPER_NO_DEBUG_OUTPUT)
add_project_config(KEY "bundle_resource" CONDITION NOT FRAMELESSHELPER_NO_BUNDLE_RESOURCE)
add_project_config(KEY "private_qt" CONDITION NOT FRAMELESSHELPER_NO_PRIVATE)
add_project_config(KEY "window" CONDITION NOT FRAMELESSHELPER_NO_WINDOW)
add_project_config(KEY "titlebar" CONDITION NOT FRAMELESSHELPER_NO_TITLEBAR)
add_project_config(KEY "translation" CONDITION NOT FRAMELESSHELPER_NO_TRANSLATION)
add_project_config(KEY "mica_material" CONDITION NOT FRAMELESSHELPER_NO_MICA_MATERIAL)
add_project_config(KEY "border_painter" CONDITION NOT FRAMELESSHELPER_NO_BORDER_PAINTER)
add_project_config(KEY "system_button" CONDITION NOT FRAMELESSHELPER_NO_SYSTEM_BUTTON)
add_project_config(KEY "native_impl" CONDITION FRAMELESSHELPER_NATIVE_IMPL)
generate_project_config(PATH "${FRAMELESSHELPER_CONFIG_FILE}")
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
)
function(setup_custom_moc_macros)
cmake_parse_arguments(arg "" "" "TARGETS" ${ARGN})
if(arg_UNPARSED_ARGUMENTS)
message(AUTHOR_WARNING "setup_custom_moc_macros: Unrecognized arguments: ${arg_UNPARSED_ARGUMENTS}")
endif()
foreach(__target ${arg_TARGETS})
if(NOT TARGET ${__target})
message(AUTHOR_WARNING "${__target} is not a valid CMake target!")
continue()
endif()
set_property(TARGET ${__target} APPEND PROPERTY AUTOMOC_MACRO_NAMES "FRAMELESSHELPER_QT_CLASS;FRAMELESSHELPER_PUBLIC_QT_CLASS;FRAMELESSHELPER_PRIVATE_QT_CLASS")
endforeach()
endfunction()
if(TARGET Qt${QT_VERSION_MAJOR}::Core AND TARGET Qt${QT_VERSION_MAJOR}::Gui)
if(FRAMELESSHELPER_BUILD_WIDGETS OR FRAMELESSHELPER_BUILD_QUICK)
add_subdirectory(src)
endif()
@ -132,37 +243,87 @@ if(FRAMELESSHELPER_BUILD_EXAMPLES)
add_subdirectory(examples)
endif()
message("#######################################")
message("CMake version: ${CMAKE_VERSION}")
message("Host system: ${CMAKE_HOST_SYSTEM}")
message("Host processor: ${CMAKE_HOST_SYSTEM_PROCESSOR}")
#message("C compiler: ${CMAKE_C_COMPILER}") # Currently we are not using any C compilers.
message("C++ compiler: ${CMAKE_CXX_COMPILER}")
message("Linker: ${CMAKE_LINKER}")
message("Make program: ${CMAKE_MAKE_PROGRAM}")
message("Build type: ${CMAKE_BUILD_TYPE}")
message("Install prefix: ${CMAKE_INSTALL_PREFIX}")
message("#######################################")
set(__qt_inst_dir)
if(DEFINED Qt6_DIR)
set(__qt_inst_dir "${Qt6_DIR}")
else()
set(__qt_inst_dir "${Qt5_DIR}")
if(WIN32 AND NOT FRAMELESSHELPER_NO_INSTALL)
set(__data_dir ".")
compute_install_dir(DATA_DIR __data_dir)
install(FILES "msbuild/FramelessHelper.props" DESTINATION "${__data_dir}")
endif()
if(NOT FRAMELESSHELPER_NO_SUMMARY)
message("--------------------------- Toolchain ----------------------------")
message("CMake version: ${CMAKE_VERSION} (${CMAKE_COMMAND})")
message("Host system: ${CMAKE_HOST_SYSTEM}")
message("Host processor: ${CMAKE_HOST_SYSTEM_PROCESSOR}")
#[[message("C compiler: ${CMAKE_C_COMPILER_ID} (${CMAKE_C_COMPILER})") # Currently we are not using any C compilers.
message("C compiler version: ${CMAKE_C_COMPILER_VERSION}")
message("C common flags: ${CMAKE_C_FLAGS}")
message("C debug flags: ${CMAKE_C_FLAGS_DEBUG}")
message("C release flags: ${CMAKE_C_FLAGS_RELEASE}")
message("C minsizerel flags: ${CMAKE_C_FLAGS_MINSIZEREL}")
message("C relwithdebinfo flags: ${CMAKE_C_FLAGS_RELWITHDEBINFO}")]]
message("C++ compiler: ${CMAKE_CXX_COMPILER_ID} (${CMAKE_CXX_COMPILER})")
message("C++ compiler version: ${CMAKE_CXX_COMPILER_VERSION}")
message("C++ common flags: ${CMAKE_CXX_FLAGS}")
message("C++ debug flags: ${CMAKE_CXX_FLAGS_DEBUG}")
message("C++ release flags: ${CMAKE_CXX_FLAGS_RELEASE}")
message("C++ minsizerel flags: ${CMAKE_CXX_FLAGS_MINSIZEREL}")
message("C++ relwithdebinfo flags: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
message("Linker: ${CMAKE_LINKER}")
message("Linker exe common flags: ${CMAKE_EXE_LINKER_FLAGS}")
message("Linker exe debug flags: ${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
message("Linker exe release flags: ${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
message("Linker exe minsizerel flags: ${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL}")
message("Linker exe relwithdebinfo flags: ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}")
message("Linker dll common flags: ${CMAKE_SHARED_LINKER_FLAGS}")
message("Linker dll debug flags: ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}")
message("Linker dll release flags: ${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
message("Linker dll minsizerel flags: ${CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL}")
message("Linker dll relwithdebinfo flags: ${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}")
message("Make program: ${CMAKE_MAKE_PROGRAM}")
message("Generator: ${CMAKE_GENERATOR}")
message("Build type: ${CMAKE_BUILD_TYPE}")
message("Configuration types: ${CMAKE_CONFIGURATION_TYPES}")
message("Install prefix: ${CMAKE_INSTALL_PREFIX}")
message("Prefix paths: ${CMAKE_PREFIX_PATH}")
message("Toolchain file: ${CMAKE_TOOLCHAIN_FILE}")
message("------------------------------ Qt -------------------------------")
query_qt_paths(SDK_DIR __qt_inst_dir)
query_qt_library_info(STATIC __qt_static_lib)
message("Qt SDK installation directory: ${__qt_inst_dir}")
message("Qt SDK version: ${QT_VERSION}")
if(__qt_static_lib)
message("Qt SDK library type: static")
else()
message("Qt SDK library type: shared")
endif()
message("------------------------ FramelessHelper ------------------------")
message("FramelessHelper version: ${PROJECT_VERSION}")
message("Build the static version of FramelessHelper: ${FRAMELESSHELPER_BUILD_STATIC}")
message("Build the FramelessHelper::Widgets module: ${FRAMELESSHELPER_BUILD_WIDGETS}")
message("Build the FramelessHelper::Quick module: ${FRAMELESSHELPER_BUILD_QUICK}")
message("Build the FramelessHelper demo applications: ${FRAMELESSHELPER_BUILD_EXAMPLES}")
message("Deploy Qt libraries after compilation: ${FRAMELESSHELPER_EXAMPLES_DEPLOYQT}")
message("Suppress debug messages from FramelessHelper: ${FRAMELESSHELPER_NO_DEBUG_OUTPUT}")
message("Do not bundle any resources within FramelessHelper: ${FRAMELESSHELPER_NO_BUNDLE_RESOURCE}")
message("Do not use any private functionalities from Qt: ${FRAMELESSHELPER_NO_PRIVATE}")
message("[MSVC] Link to system C runtime library: ${FRAMELESSHELPER_ENABLE_VCLTL}")
message("[MSVC] Thunk system APIs for old system: ${FRAMELESSHELPER_ENABLE_YYTHUNKS}")
message("[MSVC] Disable permissive checks: ${FRAMELESSHELPER_NO_PERMISSIVE_CHECKS}")
message("Do not install anything for CMake install: ${FRAMELESSHELPER_NO_INSTALL}")
message("Mitigate Spectre security vulnerabilities: ${FRAMELESSHELPER_ENABLE_SPECTRE}")
message("[MSVC] Enable EH Continuation (EHCONT) Metadata: ${FRAMELESSHELPER_ENABLE_EHCONTGUARD}")
message("Enable Intel CET: ${FRAMELESSHELPER_ENABLE_INTELCET}")
#message("Enable Intel JCC: ${FRAMELESSHELPER_ENABLE_INTELJCC}")
message("Enable Control Flow Guard (CFG): ${FRAMELESSHELPER_ENABLE_CFGUARD}")
message("Build standalone demo projects: ${FRAMELESSHELPER_EXAMPLES_STANDALONE}")
message("[macOS]: Build universal library/example: ${FRAMELESSHELPER_ENABLE_UNIVERSAL_BUILD}")
message("Force enable LTO: ${FRAMELESSHELPER_FORCE_LTO}")
#message("Make output reproducible: ${FRAMELESSHELPER_REPRODUCIBLE_OUTPUT}")
message("Disable the FramelessWindow class (to reduce file size): ${FRAMELESSHELPER_NO_WINDOW}")
message("Disable the StandardTitleBar class (to reduce file size): ${FRAMELESSHELPER_NO_TITLEBAR}")
message("Don't embed the I18N resources (to reduce file size): ${FRAMELESSHELPER_NO_TRANSLATION}")
message("Disable the MicaMaterial class (to reduce file size): ${FRAMELESSHELPER_NO_MICA_MATERIAL}")
message("Disable the WindowBorderPainter class (to reduce file size): ${FRAMELESSHELPER_NO_BORDER_PAINTER}")
message("Disable the StandardSystemButton class (to reduce file size): ${FRAMELESSHELPER_NO_SYSTEM_BUTTON}")
message("-----------------------------------------------------------------")
endif()
# /whatever/Qt/6.4.0/gcc_64/lib/cmake/Qt6
set(__qt_inst_dir ${__qt_inst_dir}/../../..)
cmake_path(NORMAL_PATH __qt_inst_dir)
message("Qt install dir: ${__qt_inst_dir}")
message("Qt version: ${QT_VERSION}")
# TODO: output shared/static Qt.
message("#######################################")
message("FramelessHelper version: ${PROJECT_VERSION}")
message("FramelessHelper commit hash: ${PROJECT_VERSION_COMMIT}")
message("FramelessHelper configure date and time: ${PROJECT_COMPILE_DATETIME}")
message("Build the static version of FramelessHelper: ${FRAMELESSHELPER_BUILD_STATIC}")
message("Build the FramelessHelper::Widgets module: ${FRAMELESSHELPER_BUILD_WIDGETS}")
message("Build the FramelessHelper::Quick module: ${FRAMELESSHELPER_BUILD_QUICK}")
message("Build the FramelessHelper demo applications: ${FRAMELESSHELPER_BUILD_EXAMPLES}")
message("Deploy Qt libraries after compilation: ${FRAMELESSHELPER_EXAMPLES_DEPLOYQT}")
message("Suppress debug messages from FramelessHelper: ${FRAMELESSHELPER_NO_DEBUG_OUTPUT}")
message("#######################################")

View File

@ -1,11 +1,80 @@
#[[
MIT License
Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]]
@PACKAGE_INIT@
set(_@PROJECT_NAME@_supported_components Core Widgets Quick)
include(CMakeFindDependencyMacro)
foreach(_comp ${@PROJECT_NAME@_FIND_COMPONENTS})
if(NOT _comp IN_LIST _@PROJECT_NAME@_supported_components)
set(_@PROJECT_NAME@_supported_components Core Widgets Quick)
set(_@PROJECT_NAME@_available_components Core Gui)
foreach(_component ${@PROJECT_NAME@_FIND_COMPONENTS})
if(_component IN_LIST _@PROJECT_NAME@_supported_components)
set(__target @PROJECT_NAME@::${_component})
if(TARGET ${__target})
continue()
else()
set(__target_full @PROJECT_NAME@${_component})
set(__targets_file "${CMAKE_CURRENT_LIST_DIR}/${__target_full}Targets.cmake")
if(EXISTS "${__targets_file}")
include("${__targets_file}")
add_library(${__target} ALIAS @PROJECT_NAME@::${__target_full})
list(APPEND _@PROJECT_NAME@_available_components ${_component})
else()
set(@PROJECT_NAME@_FOUND FALSE)
set(@PROJECT_NAME@_NOT_FOUND_MESSAGE "Can't find necessary configuration file for ${__target}, please make sure this component is built successfully and installed properly.")
break()
endif()
endif()
else()
set(@PROJECT_NAME@_FOUND FALSE)
set(@PROJECT_NAME@_NOT_FOUND_MESSAGE "Unsupported component: ${_comp}")
set(@PROJECT_NAME@_NOT_FOUND_MESSAGE "Unknown component: ${__target}.")
break()
endif()
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@${_comp}Targets.cmake")
endforeach()
if(NOT DEFINED @PROJECT_NAME@_FOUND)
set(@PROJECT_NAME@_FOUND TRUE)
set(@PROJECT_NAME@_VERSION "@PROJECT_VERSION@")
set(@PROJECT_NAME@_VERSION_MAJOR "@PROJECT_VERSION_MAJOR@")
set(@PROJECT_NAME@_VERSION_MINOR "@PROJECT_VERSION_MINOR@")
set(@PROJECT_NAME@_VERSION_PATCH "@PROJECT_VERSION_PATCH@")
#set(@PROJECT_NAME@_VERSION_TWEAK "@PROJECT_VERSION_TWEAK@")
set(@PROJECT_NAME@_DESCRIPTION "@PROJECT_DESCRIPTION@")
set(@PROJECT_NAME@_HOMEPAGE_URL "@PROJECT_HOMEPAGE_URL@")
set(@PROJECT_NAME@_COMMIT "@PROJECT_VERSION_COMMIT@")
set(@PROJECT_NAME@_COMPILE_DATETIME "@PROJECT_COMPILE_DATETIME@")
endif()
include(FeatureSummary)
set_package_properties(@PROJECT_NAME@ PROPERTIES
DESCRIPTION "@PROJECT_DESCRIPTION@"
URL "@PROJECT_HOMEPAGE_URL@"
)
if(${@PROJECT_NAME@_FOUND})
list(REMOVE_DUPLICATES _@PROJECT_NAME@_available_components)
find_dependency(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS ${_@PROJECT_NAME@_available_components})
find_dependency(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS ${_@PROJECT_NAME@_available_components})
endif()

View File

@ -1,6 +1,6 @@
MIT License
Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

132
README.md
View File

@ -1,3 +1,7 @@
# ATTENTION! THIS REPO HAS BEEN DEPRECATED!
# PLEASE USE THE BRAND NEW [QWINDOWKIT](https://github.com/stdware/qwindowkit) INSTEAD!
# THIS REPO IS NO LONGER MAINTAINED.
# FramelessHelper 2.x
[![CI: Build Test](https://github.com/wangwenx190/framelesshelper/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/wangwenx190/framelesshelper/actions/workflows/ci.yml)
@ -8,21 +12,38 @@ Cross-platform window customization framework for Qt Widgets and Qt Quick. Suppo
You can join our [Discord channel](https://discord.gg/grrM4Tmesy) to communicate with us. You can share your findings, thoughts and ideas on improving / implementing FramelessHelper functionalities on more platforms and apps!
## HELP WANTED!
1. The current CMake package code is not complete and still has some small issues. Need some experienced CMake developers to help me improve it!
2. The current Linux/X11 implementation is not stable enough and still has some bugs. Need some experienced Linux developers to help me improve it!
3. The current macOS implementation is not stable enough and still has some bugs. Need some experienced macOS developers to help me improve it!
## Roadmap
## TODO
- Common: Add cross-platform customizable system menu for both Qt Widgets and Qt Quick. Also supports both light and dark theme.
- Examples: Add QtWebEngine based demo projects for both Qt Widgets and Qt Quick. The whole user interface will be written in HTML instead of C++/QML.
- Examples: Add demo projects that emulate the classic appearance of UWP applications. They will have a backward button on the left side of the title bar and a search box in the middle of the title bar. And maybe a side bar on the left side to switch between different pages.
- Examples: Add demo projects that the main window is not resizable.
- Examples: Add demo projects that have transparent background and doesn't have rectangular window frame.
- Examples: Add demo projects based on QRhiWidget and QRhiQuickItem.
- Feature requests are welcome!
## Highlights v2.5
- General: The file size of FramelessHelper binaries should be smaller than before, due to most static string literals and some internal structures are constexpr now, this change may also help to improve the general performance.
- General: The performance should be improved quite some bit, due to most double lookups of Qt container types and unnecessary data copies are avoided now.
- Snap Layout: The snap layout implementation has been COMPLETELY rewritten. It now behaves almost exactly the same with native windows!
- Mica Material: FramelessHelper now prefers speed over quality. This change will lower the image quality but since the image is highly blurred anyway, there should not be any significant differences in the final user experience.
- Build system: Improved RPATH support (UNIX systems).
- Build system: Support modular build.
- Routine bug fixes and internal refactorings.
## Highlights v2.4
- Widgets: Nested frameless windows are supported now!
- Linux: There have been many improvements to the Linux/X11 implementation! Most of them won't be directly visible to the user, but the code quality has been greatly improved.
- macOS: The frameless windows will now use native window frame and buttons, only the title bar itself is hidden, which also means the window will have round corners as all other native windows on macOS.
- Mica Material: It is now possible to load wallpaper images with very large file size or resolution, for example, 4K pictures. However, if the images have larger resolution than 1920x1080, they will be shrinked to reduce memory usage, and this process will also lower the image quality and break the aspect ratio of them.
- Mica Material: FramelessHelper will now use a seperate thread to load and apply special effects to the wallpaper image, to speed up application startup performance and avoid such process block the main thread.
- Window management: It is now possible to close the window (the dtor is executed) and show it again without breaking the frameless functionalities.
- Theme: It is now possible to force a desired theme instead of always respecting the system theme.
- Build system: The [**Ninja Multi-Config**](https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html) generator is fully supported now, finally!
- Docs: There have been some improvements of the build instructions.
- Routine bug fixes and internal refactorings.
## Highlights v2.3
- Widgets & Quick: When you clicks the window icon, the system menu will now popup, and when you double clicks it, the window will be closed. This emulates the traditional window behavior on Windows.
@ -110,39 +131,83 @@ Vogen editor using **QSynthesis** framework. Repository URL: <https://gitee.com/
## Supported Platforms
- Windows: Windows 7, Windows 8, Windows 8.1, Windows 10, Windows 11 (only actively tested on Windows 10 & 11)
- Windows: Windows Vista \~ 11 (only actively tested on Windows 10 & 11)
- Linux: any modern Linux distros should work, but only tested on Ubuntu 20.04 and Ubuntu 22.04
- macOS: only tested on macOS 12.3 due to lack of Apple devices
- macOS: only tested on macOS 12 & 13 due to lack of Apple devices
There are some additional restrictions for each platform, please refer to the _Platform notes_ section below.
## Build
```bash
git clone https://github.com/wangwenx190/framelesshelper.git
mkdir A_TEMP_DIR
cd A_TEMP_DIR
git clone --recursive https://github.com/wangwenx190/framelesshelper.git # "--recursive" is necessary to clone the submodules.
mkdir build # Please change to your own build directory!
cd build
cmake -DCMAKE_PREFIX_PATH=<YOUR_QT_SDK_DIR_PATH> -DCMAKE_INSTALL_PREFIX=<WHERE_YOU_WANT_TO_INSTALL> -DCMAKE_BUILD_TYPE=Release -GNinja <PATH_TO_THE_REPOSITORY>
cmake --build . --config Release --target all --parallel
cmake --install . --config Release --strip
cmake --install . --config Release --strip # Don't add "--strip" for MSVC/Clang-CL/Intel-CL toolchains!
# YOUR_QT_SDK_DIR_PATH: the Qt SDK directory, something like "C:/Qt/6.5.1/msvc2019_64" or "/opt/Qt/6.5.1/gcc_64". Please change to your own path!
# WHERE_YOU_WANT_TO_INSTALL: the install directory of FramelessHelper, something like "../install". You can ignore this setting if you don't need to install the CMake package. Please change to your own path!
# PATH_TO_THE_REPOSITORY: the source code directory of FramelessHelper, something like "../framelesshelper". Please change to your own path!
```
**IMPORTANT NOTE**: On Linux you need to install the _GTK3_ and _X11_ development packages first.
You can also use `Qt6_DIR` or `Qt5_DIR` to replace `CMAKE_PREFIX_PATH`:
Once the compilation and installation is done, you will be able to use the `find_package(FramelessHelper REQUIRED COMPONENTS Core Widgets Quick)` command to find and link to the FramelessHelper library. But before doing that, please make sure CMake knows where to find FramelessHelper, by passing the `CMAKE_PREFIX_PATH` variable to it. For example: `-DCMAKE_PREFIX_PATH=C:/my-cmake-packages;C:/my-toolchain;etc...`. Build FramelessHelper as a sub-directory of your CMake project is of course also supported. The supported FramelessHelper target names are `FramelessHelper::FramelessHelperCore`, `FramelessHelper::FramelessHelperWidgets` and `FramelessHelper::FramelessHelperQuick`.
```bash
cmake -DQt6_DIR=C:/Qt/6.5.1/msvc2019_64/lib/cmake/Qt6 [other parameters ...]
# Or
cmake -DQt5_DIR=C:/Qt/5.15.2/msvc2019_64/lib/cmake/Qt5 [other parameters ...]
```
If there are any errors when cloning the submodules, try run `git submodule update --init --recursive --remote` in the project directory, that command will download & update all the submodules. If it fails again, try execute it multiple times until it finally succeeds.
Once the compilation and installation is done, you will be able to use the `find_package(FramelessHelper REQUIRED COMPONENTS Core Widgets Quick)` command to find and link to the FramelessHelper library. But before doing that, please make sure CMake knows where to find FramelessHelper, by passing the `CMAKE_PREFIX_PATH` or `FramelessHelper_DIR` variable to it. For example: `-DCMAKE_PREFIX_PATH=C:/my-cmake-packages;C:/my-toolchain;etc...` or `-DFramelessHelper_DIR=C:/Projects/FramelessHelper/lib64/cmake/FramelessHelper`. Build FramelessHelper as a sub-directory of your CMake project is of course also supported. The supported FramelessHelper target names are `FramelessHelper::Core`, `FramelessHelper::Widgets` and `FramelessHelper::Quick`. Example code:
```cmake
# Find Qt:
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
# Find FramelessHelper:
find_package(FramelessHelper REQUIRED COMPONENTS Core Widgets)
# Create your target:
add_executable(demo)
# Add your source code:
target_sources(demo PRIVATE main.cpp)
# Link to Qt and FramelessHelper:
target_link_libraries(demo PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
FramelessHelper::Core
FramelessHelper::Widgets
)
```
If you need the syntax highlighting of FramelessHelper's Quick module, please set up the `QML_IMPORT_PATH` variable. Example code:
```cmake
# This is the path where you want FramelessHelper's Quick plugin (it only contains the QML meta
# info and an optional dummy library, for QtCreator's QML tooling purpose, it's not the Quick
# module) to place. Please change to your own path!
# If you are using add_subdirectory() to include FramelessHelper directly, you can change it to
# "${PROJECT_BINARY_DIR}/imports" instead of the install location.
set(FRAMELESSHELPER_IMPORT_DIR "C:/packages/FramelessHelper/qml")
list(APPEND QML_IMPORT_PATH "${FRAMELESSHELPER_IMPORT_DIR}")
list(REMOVE_DUPLICATES QML_IMPORT_PATH)
# Force cache refresh:
set(QML_IMPORT_PATH ${QML_IMPORT_PATH} CACHE STRING "Qt Creator extra QML import paths" FORCE)
```
## Use
### Qt Widgets
To customize the window frame of a QWidget, you need to instantiate a `FramelessWidgetsHelper` object and then attach it to the widget's top level widget, and then `FramelessWidgetsHelper` will do all the rest work for you: the window frame will be removed automatically once it has been attached to the top level widget successfully. In theory you can instantiate multiple `FramelessWidgetsHelper` objects for a same widget, in this case there will be only one object that keeps functional, all other objects will become a wrapper of that one. But to make sure everything goes smoothly and normally, you should not do that in any case. The simplest way to instantiate a `FramelessWidgetsHelper`
object is to call the static method `FramelessWidgetsHelper *FramelessWidgetsHelper::get(QObject *)`. It will return the handle of the previously instantiated object if any, or it will instantiate a new object if it can't find one. It's safe to call this method multiple times for a same widget, it won't instantiate any new objects if there is one already. It also does not matter when and where you call that function as long as the top level widget is the same. The internally created objects will always be parented to the top level widget. Once you get the handle of the `FramelessWidgetsHelper` object, you can call `void FramelessWidgetsHelper::setContentExtendedIntoTitleBar(true)` to let it hide the default title bar provided by the operating system. In order to make sure `FramelessWidgetsHelper` can find the correct top level widget, you should call the `FramelessWidgetsHelper *FramelessWidgetsHelper::get(QObject *)` function on a widget which has a complete parent-chain whose root parent is the top level widget. To make the frameless window draggable, you should provide a homemade title bar widget yourself, the title bar widget doesn't need to be in rectangular shape, it also doesn't need to be placed on the first row of the window. Call `void FramelessWidgetsHelper::setTitleBarWidget(QWidget *)` to let `FramelessHelper` know what's your title bar widget. By default, all the widgets in the title bar area won't be responsible to any mouse and keyboard events due to they have been intercepted by FramelessHelper. To make them recover the responsible state, you should make them visible to hit test. Call `void FramelessWidgetsHelper::setHitTestVisible(QWidget* )` to do that. You can of course call it on a widget that is not inside the title bar at all, it won't have any effect though. Due to Qt's own limitations, you need to make sure your widget has a complete parent-chain whose root parent is the top level widget. Do not ever try to delete the `FramelessWidgetsHelper` object, it may still be monitoring and controlling your widget, and Qt will delete it for you automatically. No need to worry about memory leaks.
object is to call the static method `FramelessWidgetsHelper *FramelessWidgetsHelper::get(QObject *)`. It will return the handle of the previously instantiated object if any, or it will instantiate a new object if it can't find one. It's safe to call this method multiple times for a same widget, it won't instantiate any new objects if there is one already. It also does not matter when and where you call that function as long as the top level widget is the same. The internally created objects will always be parented to the top level widget. Once you get the handle of the `FramelessWidgetsHelper` object, you can call `void FramelessWidgetsHelper::extendsContentIntoTitleBar()` to let it hide the default title bar provided by the operating system. In order to make sure `FramelessWidgetsHelper` can find the correct top level widget, you should call the `FramelessWidgetsHelper *FramelessWidgetsHelper::get(QObject *)` function on a widget which has a complete parent-chain whose root parent is the top level widget. To make the frameless window draggable, you should provide a homemade title bar widget yourself, the title bar widget doesn't need to be in rectangular shape, it also doesn't need to be placed on the first row of the window. Call `void FramelessWidgetsHelper::setTitleBarWidget(QWidget *)` to let `FramelessHelper` know what's your title bar widget. By default, all the widgets in the title bar area won't be responsible to any mouse and keyboard events due to they have been intercepted by FramelessHelper. To make them recover the responsible state, you should make them visible to hit test. Call `void FramelessWidgetsHelper::setHitTestVisible(QWidget* )` to do that. You can of course call it on a widget that is not inside the title bar at all, it won't have any effect though. Due to Qt's own limitations, you need to make sure your widget has a complete parent-chain whose root parent is the top level widget. Do not ever try to delete the `FramelessWidgetsHelper` object, it may still be monitoring and controlling your widget, and Qt will delete it for you automatically. No need to worry about memory leaks.
There are also two classes called `FramelessWidget` and `FramelessMainWindow`, they are only simple wrappers of `FramelessWidgetsHelper`, which just saves the call of the `void FramelessWidgetsHelper::setContentExtendedIntoTitleBar(true)` function for you. You can absolutely use plain `QWidget` instead.
There are also two classes called `FramelessWidget` and `FramelessMainWindow`, they are only simple wrappers of `FramelessWidgetsHelper`, which just saves the call of the `void FramelessWidgetsHelper::extendsContentIntoTitleBar()` function for you. You can absolutely use plain `QWidget` instead.
#### Code Snippet
First of all, call `void FramelessHelper::Widgets::initialize()` in your `main` function in a very early stage:
First of all, call `void FramelessHelper::Widgets::initialize()` in your `main` function in a very early stage (**MUST** before the construction of any `Q(Gui|Core)Application` objects):
```cpp
int main(int, char **)
@ -158,7 +223,7 @@ Then hide the standard title bar provided by the OS:
MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
{
// You should do this early enough.
FramelessWidgetsHelper::get(this)->setContentExtendedIntoTitleBar(true);
FramelessWidgetsHelper::get(this)->extendsContentIntoTitleBar();
// ...
}
```
@ -193,7 +258,7 @@ void MyWidget::myFunction2()
#### Code Snippet
First of all, you should call `void FramelessHelper::Quick::initialize()` in your `main` function in a very early stage:
First of all, you should call `void FramelessHelper::Quick::initialize()` in your `main` function in a very early stage (**MUST** before the construction of any `Q(Gui|Core)Application` objects):
```cpp
int main(int, char **)
@ -289,8 +354,6 @@ Window {
}
```
**IMPORTANT NOTE for all applications**: Once you called `QWidget::close()` or `Q(Quick)Window::close()`, Qt will release all the resources of the corresponding widget/window, and thus FramelessHelper's custom event handler will also be removed from them at the same time. However, this will make the title bar become unresponsible if you re-open the widget/window. The current workaround for this issue is to hide the widget/window instead of closing it, if you are going to show it again later. But if you have no plan to show the widget/window again after it has been closed, you don't need to do anything to workaround this issue.
### More
Please refer to the demo projects to see more detailed usages: [examples](./examples/)
@ -326,12 +389,7 @@ Please refer to the demo projects to see more detailed usages: [examples](./exam
- Due to there are many sub-versions of Windows 10, it's highly recommended to use the latest version of Windows 10, at least **no older than Windows 10 1809**. If you try to use this framework on some very old Windows 10 versions such as 1507 or 1607, there may be some compatibility issues. Using this framework on Windows 7 is also supported but not recommended. To get the most stable behavior and the best appearance, you should use it on the latest version of Windows 10 or Windows 11.
- To make the snap layout work as expected, there are some additional rules for your homemade system buttons to follow:
- **Add a manifest file to your application. In the manifest file, you need to claim your application supports Windows 11 explicitly. This step is VERY VERY IMPORTANT. Without this step, the snap layout feature can't be enabled.**
- Make sure there are two public invokable functions (slot functions are always invokable): `void setHovered(bool)` and `void setPressed(bool)`. These two functions will be invoked by FramelessHelper when the button is being hovered or pressed. You should change the button's visual state inside these functions. If you need to show tooltips, you'll have to do it manually in these functions.
- Make sure there's a public signal: `void clicked()`. When the button is being clicked, that signal will be triggered by FramelessHelper. You should connect your event handler to that signal.
- For Qt Quick applications, for the C++ side, you need to inherit your button from the `QQuickAbstractButton` class, for the QML side, you need to inherit your button from the `Button` type (from the `QtQuick.Controls.Basic` module). They have all the invokable functions and signals we need, so no more extra work is needed.
- Don't forget to call `setSystemButton()` for each button to let FramelessHelper know which is the minimize/maximize/close button.
- System buttons will not be able to receive any actual mouse and keyboard events so there's no need to handle these events inside these buttons. That's also why we need to set the button's visual state manually.
- I know this is making everything complicated but unfortunately we can't avoid this mess if we need to support the snap layout feature. Snap layout is really only designed for the original standard window frame, so if we want to forcely support it without a standard window frame, many black magic will be needed.
- Call `setSystemButton()` for each button (it can be any *QWidget* or *QQuickItem*) to let FramelessHelper know which is the minimize/maximize/close button.
### Linux
@ -340,8 +398,6 @@ Please refer to the demo projects to see more detailed usages: [examples](./exam
### macOS
- The frameless windows will appear in square corners instead of round corners (Qt Widgets applications only).
- The resize area is inside of the window.
- Some users reported that the window is not resizable on some old macOS versions.
## FAQs
@ -362,12 +418,24 @@ First of all, it's a Qt issue, not caused by FramelessHelper. And it should not
Short answer: it's impossible. Full explaination: of course we can use the same technique we use on Win10 to remove the whole top part of the window and preserve the other three frame borders at the same time, but on Win10 we can bring the top border back, either by doing some black magic in the `WM_PAINT` handler or draw a thin frame border manually ourself, however, it's impossible to do this on Win7. I've tried it on Win7 already and sadly the result is the `WM_PAINT` trick won't work on Win7, and we also can't draw a frame border which looks very similar to the original one (a semi-transparent rectangle, blended with system's accent color and the visual content behind the window, also with some blur effect applied). But it seems Google Chrome/Microsoft Edge's installer have achieved what we wanted to do, how? Well, their installer is open source and I've read it's code already. They achieve that by overlapping two windows, one normal window on the bottom, another border-less window on the top to cover the bottom window's title bar. They draw their homemade title bar on the border-less window and use it to emulate the standard title bar's behavior. The original title bar provided by the system is still there, but it can't be seen by anyone just because it's covered by another window. I admit it's a good solution in such cases but for our library it's not appropriate because the code complexity will blow up.
## Special Thanks
*Ordered by first contribution time (it may not be very accurate, sorry)*
- [Yuhang Zhao](https://github.com/wangwenx190): Help me create this project. This project is mainly based on his code.
- [Julien](https://github.com/JulienMaille): Help me test this library on many various environments and help me fix the bugs we found. Contributed many code to improve this library. The MainWindow example is mostly based on his code.
- [Altair Wei](https://github.com/altairwei): Help me fix quite some small bugs and give me many important suggestions, the 2.x version is also inspired by his idea during our discussions.
- [Kenji Mouri](https://github.com/MouriNaruto): Give me a lot of help on Win32 native developing.
- [Dylan Liu](https://github.com/mentalfl0w): Help me improve the build process on macOS.
- [SineStriker](https://github.com/SineStriker): Spent over a whole week helping me improve the Snap Layout implementation, fixing potential bugs and also give me a lot of professional and useful suggestions. Without his great effort, the new implementation may never come.
- And also thanks to other contributors not listed here! Without their valuable help, this library wouldn't have such good quality and user experience!
## License
```text
MIT License
Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

47
build.bat Normal file
View File

@ -0,0 +1,47 @@
@echo off
title Building FramelessHelper ...
setlocal
cls
set __vs_bat=%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat
if not exist "%__vs_bat%" set __vs_bat=%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat
if not exist "%__vs_bat%" set __vs_bat=%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat
if not exist "%__vs_bat%" set __vs_bat=%ProgramFiles(x86)%\Microsoft Visual Studio\2015\Community\VC\Auxiliary\Build\vcvars64.bat
if not exist "%__vs_bat%" (
echo Cannot find a valid Visual Studio toolchain!
echo Please install at least Visual Studio 2015 to the default location
echo and install the English language pack at the same time.
echo If you want to use clang-cl or MinGW to build this project, please
echo make sure you have added their directory to your PATH environment
echo variable.
echo Press the ENTER key to continue, or close this window directly.
pause
) else (
call "%__vs_bat%"
)
cmake --version
echo ninja build
ninja --version
cd /d "%~dp0"
if exist build.user.bat call build.user.bat
if not defined CC set CC=cl.exe
if not defined CXX set CXX=cl.exe
if not defined QTDIR set QTDIR=%SystemDrive%\Qt\6.6.0\msvc2019_64
echo CC=%CC%
echo CXX=%CXX%
echo QTDIR=%QTDIR%
if exist build rd /s /q build
md build
cd build
md cmake
cd cmake
cmake -DCMAKE_C_COMPILER="%CC%" -DCMAKE_CXX_COMPILER="%CXX%" -DCMAKE_PREFIX_PATH="%QTDIR%" -DCMAKE_INSTALL_PREFIX="%~dp0build\install" -DCMAKE_CONFIGURATION_TYPES=Release;Debug -G"Ninja Multi-Config" -DFRAMELESSHELPER_ENABLE_VCLTL=ON -DFRAMELESSHELPER_ENABLE_YYTHUNKS=ON -DFRAMELESSHELPER_ENABLE_SPECTRE=ON -DFRAMELESSHELPER_ENABLE_EHCONTGUARD=ON -DFRAMELESSHELPER_ENABLE_INTELCET=ON -DFRAMELESSHELPER_ENABLE_INTELJCC=ON -DFRAMELESSHELPER_ENABLE_CFGUARD=ON -DFRAMELESSHELPER_FORCE_LTO=ON "%~dp0"
cmake --build . --target all --config Release --parallel
cmake --build . --target all --config Debug --parallel
cmake --install . --config Release --strip
cmake --install . --config Debug
goto fin
:fin
endlocal
cd /d "%~dp0"
pause
exit /b 0

1
cmake Submodule

@ -0,0 +1 @@
Subproject commit aa2a9bcf09e4f28e3b351b4f8353a30e3e71bfad

Binary file not shown.

Before

Width:  |  Height:  |  Size: 686 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 524 KiB

After

Width:  |  Height:  |  Size: 68 KiB

View File

@ -1,7 +1,7 @@
#[[
MIT License
Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -25,10 +25,10 @@
if(FRAMELESSHELPER_BUILD_WIDGETS AND TARGET Qt${QT_VERSION_MAJOR}::Widgets)
add_subdirectory(widget)
add_subdirectory(mainwindow)
add_subdirectory(openglwidget)
#add_subdirectory(openglwidget) # Currently not functional.
add_subdirectory(dialog)
endif()
if(FRAMELESSHELPER_BUILD_QUICK AND TARGET Qt${QT_VERSION_MAJOR}::Quick AND ${QT_VERSION_MAJOR} GREATER_EQUAL 6)
if(FRAMELESSHELPER_BUILD_QUICK AND TARGET Qt${QT_VERSION_MAJOR}::Quick AND (QT_VERSION_MAJOR GREATER_EQUAL 6) AND (NOT FRAMELESSHELPER_NO_PRIVATE))
add_subdirectory(quick)
endif()

View File

@ -1,7 +1,7 @@
#[[
MIT License
Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -22,7 +22,30 @@
SOFTWARE.
]]
set(SOURCES
set(DEMO_NAME FramelessHelperDemo-Dialog)
if(FRAMELESSHELPER_ENABLE_UNIVERSAL_BUILD)
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
endif()
if(FRAMELESSHELPER_EXAMPLES_STANDALONE)
cmake_minimum_required(VERSION 3.20)
project(${DEMO_NAME} VERSION 1.0)
include(../../cmake/utils.cmake)
setup_project(
QT_PROJECT
LANGUAGES CXX RC
NO_WARNING
ENABLE_LTO
)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
find_package(FramelessHelper REQUIRED COMPONENTS Core Widgets)
endif()
add_executable(${DEMO_NAME})
target_sources(${DEMO_NAME} PRIVATE
../shared/log.h
../shared/log.cpp
../shared/settings.h
@ -33,27 +56,85 @@ set(SOURCES
)
if(WIN32)
enable_language(RC)
list(APPEND SOURCES
../shared/example.rc
../shared/example.manifest
set(__rc_path "${PROJECT_BINARY_DIR}/${DEMO_NAME}.rc")
if(NOT EXISTS "${__rc_path}")
generate_win32_rc_file(
PATH "${__rc_path}"
VERSION "${PROJECT_VERSION}"
COMPANY "wangwenx190"
DESCRIPTION "FramelessHelper Demo Application: Dialog"
COPYRIGHT "MIT License"
PRODUCT "FramelessHelper Demo"
ICONS "../shared/example.ico"
)
endif()
set(__manifest_path "${PROJECT_BINARY_DIR}/${DEMO_NAME}.manifest")
if(NOT EXISTS "${__manifest_path}")
generate_win32_manifest_file(
PATH "${__manifest_path}"
ID "org.wangwenx190.demo.Dialog"
VERSION "${PROJECT_VERSION}"
DESCRIPTION "FramelessHelper Demo Application: Dialog"
VISTA_COMPAT
WIN7_COMPAT
WIN8_COMPAT
WIN8_1_COMPAT
WIN10_COMPAT
WIN11_COMPAT
XAML_ISLANDS_COMPAT
UTF8_CODEPAGE
)
endif()
target_sources(${DEMO_NAME} PRIVATE
"${__rc_path}"
"${__manifest_path}"
)
endif()
add_executable(Dialog ${SOURCES})
target_link_libraries(Dialog PRIVATE
target_link_libraries(${DEMO_NAME} PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
FramelessHelper::Core
FramelessHelper::Widgets
)
target_compile_definitions(Dialog PRIVATE
QT_NO_KEYWORDS
setup_gui_app(
TARGETS ${DEMO_NAME}
BUNDLE_ID "org.wangwenx190.demo.Dialog"
BUNDLE_VERSION "1.0.0"
BUNDLE_VERSION_SHORT "1.0"
)
include(../../src/core/cmakehelper.cmake)
setup_gui_app(Dialog)
setup_compile_params(Dialog)
if(FRAMELESSHELPER_EXAMPLES_DEPLOYQT)
deploy_qt_runtime(Dialog)
setup_target_rpaths(TARGETS ${DEMO_NAME})
setup_qt_stuff(TARGETS ${DEMO_NAME})
set(__extra_flags "")
if(NOT FRAMELESSHELPER_NO_PERMISSIVE_CHECKS)
list(APPEND __extra_flags PERMISSIVE)
endif()
if(FRAMELESSHELPER_ENABLE_SPECTRE)
list(APPEND __extra_flags SPECTRE)
endif()
if(FRAMELESSHELPER_ENABLE_EHCONTGUARD)
list(APPEND __extra_flags EHCONTGUARD)
endif()
if(FRAMELESSHELPER_ENABLE_INTELCET)
list(APPEND __extra_flags INTELCET)
endif()
if(FRAMELESSHELPER_ENABLE_CFGUARD)
list(APPEND __extra_flags CFGUARD)
endif()
if(FRAMELESSHELPER_FORCE_LTO)
list(APPEND __extra_flags FORCE_LTO)
endif()
setup_compile_params(TARGETS ${DEMO_NAME} ${__extra_flags})
if(FRAMELESSHELPER_EXAMPLES_DEPLOYQT)
set(__extra_flags)
if(FRAMELESSHELPER_NO_INSTALL)
set(__extra_flags NO_INSTALL)
endif()
deploy_qt_runtime(TARGET ${DEMO_NAME} ${__extra_flags})
endif()
#dump_target_info(TARGETS ${DEMO_NAME})

View File

@ -10,17 +10,24 @@
#include <QtWidgets/qboxlayout.h>
#include <QtWidgets/qfileiconprovider.h>
#include <QtWidgets/qmessagebox.h>
#include <StandardTitleBar>
#include <FramelessWidgetsHelper>
#include <StandardSystemButton>
#include <private/framelesswidgetshelper_p.h>
#include <FramelessHelper/Widgets/standardtitlebar.h>
#include <FramelessHelper/Widgets/framelesswidgetshelper.h>
#include <FramelessHelper/Widgets/standardsystembutton.h>
#include <FramelessHelper/Widgets/private/framelesswidgetshelper_p.h>
#include "../shared/settings.h"
extern template void Settings::set<QRect>(const QString &, const QString &, const QRect &);
extern template void Settings::set<qreal>(const QString &, const QString &, const qreal &);
extern template QRect Settings::get<QRect>(const QString &, const QString &);
extern template qreal Settings::get<qreal>(const QString &, const QString &);
FRAMELESSHELPER_USE_NAMESPACE
using namespace Global;
FRAMELESSHELPER_STRING_CONSTANT(Geometry)
FRAMELESSHELPER_STRING_CONSTANT(DevicePixelRatio)
Dialog::Dialog(QWidget *parent) : FramelessDialog(parent)
{
@ -31,18 +38,32 @@ Dialog::~Dialog() = default;
void Dialog::closeEvent(QCloseEvent *event)
{
Settings::set({}, kGeometry, saveGeometry());
if (!parent()) {
const QString id = objectName();
Settings::set(id, kGeometry, geometry());
Settings::set(id, kDevicePixelRatio, devicePixelRatioF());
}
FramelessDialog::closeEvent(event);
}
void Dialog::setupUi()
{
setWindowTitle(tr("Qt Dialog demo"));
setWindowTitle(tr("FramelessHelper demo application - QDialog"));
setWindowIcon(QFileIconProvider().icon(QFileIconProvider::Computer));
connect(this, &Dialog::objectNameChanged, this, [this](const QString &name){
if (name.isEmpty()) {
return;
}
setWindowTitle(windowTitle() + FRAMELESSHELPER_STRING_LITERAL(" [%1]").arg(name));
});
#if FRAMELESSHELPER_CONFIG(titlebar)
titleBar = new StandardTitleBar(this);
titleBar->setWindowIconVisible(true);
# if (!defined(Q_OS_MACOS) && FRAMELESSHELPER_CONFIG(system_button))
titleBar->maximizeButton()->hide();
# endif
#endif
label = new QLabel(tr("Find &what:"));
lineEdit = new QLineEdit;
@ -79,12 +100,11 @@ void Dialog::setupUi()
connect(moreButton, &QPushButton::toggled, extension, &QWidget::setVisible);
QVBoxLayout *extensionLayout = new QVBoxLayout;
QVBoxLayout *extensionLayout = new QVBoxLayout(extension);
extensionLayout->setContentsMargins(0, 0, 0, 0);
extensionLayout->addWidget(wholeWordsCheckBox);
extensionLayout->addWidget(backwardCheckBox);
extensionLayout->addWidget(searchSelectionCheckBox);
extension->setLayout(extensionLayout);
QHBoxLayout *topLeftLayout = new QHBoxLayout;
topLeftLayout->addWidget(label);
@ -102,32 +122,48 @@ void Dialog::setupUi()
controlsLayout->addWidget(extension, 1, 0, 1, 2);
controlsLayout->setRowStretch(2, 1);
QVBoxLayout *mainLayout = new QVBoxLayout;
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->setSizeConstraint(QLayout::SetFixedSize);
#if FRAMELESSHELPER_CONFIG(titlebar)
mainLayout->addWidget(titleBar);
#endif
mainLayout->addLayout(controlsLayout);
setLayout(mainLayout);
extension->hide();
#if FRAMELESSHELPER_CONFIG(titlebar)
FramelessWidgetsHelper *helper = FramelessWidgetsHelper::get(this);
helper->setTitleBarWidget(titleBar);
# ifdef Q_OS_WINDOWS
FramelessWidgetsHelperPrivate *helperPriv = FramelessWidgetsHelperPrivate::get(helper);
helperPriv->setProperty(kSysMenuRemoveRestoreVar, true);
helperPriv->setProperty(kSysMenuRemoveSizeVar, true);
helperPriv->setProperty(kSysMenuRemoveMinimizeVar, true);
helperPriv->setProperty(kSysMenuRemoveMaximizeVar, true);
helperPriv->setProperty(kSysMenuRemoveSeparatorVar, true);
# endif
# if (!defined(Q_OS_MACOS) && FRAMELESSHELPER_CONFIG(system_button))
helper->setSystemButton(titleBar->minimizeButton(), SystemButtonType::Minimize);
helper->setSystemButton(titleBar->maximizeButton(), SystemButtonType::Maximize);
helper->setSystemButton(titleBar->closeButton(), SystemButtonType::Close);
// Special hack to disable the overriding of the mouse cursor, it's totally different
// with making the window un-resizable: we still want the window be able to resize
// programatically, but we also want the user not able to resize the window manually.
// So apparently we can't use QWidget::setFixedWidth/Height/Size() here.
FramelessWidgetsHelperPrivate::get(helper)->setProperty(kDontOverrideCursorVar, true);
connect(helper, &FramelessWidgetsHelper::ready, this, [this, helper](){
const QByteArray data = Settings::get({}, kGeometry);
if (data.isEmpty()) {
helper->moveWindowToDesktopCenter();
} else {
restoreGeometry(data);
}
});
# endif
#endif
}
void Dialog::waitReady()
{
FramelessWidgetsHelper *helper = FramelessWidgetsHelper::get(this);
helper->waitForReady();
const QString id = objectName();
const auto savedGeometry = Settings::get<QRect>(id, kGeometry);
if (savedGeometry.isValid() && !parent()) {
const auto savedDpr = Settings::get<qreal>(id, kDevicePixelRatio);
// Qt doesn't support dpr < 1.
const qreal oldDpr = std::max(savedDpr, qreal(1));
const qreal scale = (devicePixelRatioF() / oldDpr);
setGeometry({savedGeometry.topLeft() * scale, savedGeometry.size() * scale});
} else {
helper->moveWindowToDesktopCenter();
}
}

View File

@ -3,7 +3,9 @@
#pragma once
#include <FramelessDialog>
#include <FramelessHelper/Widgets/framelessdialog.h>
FRAMELESSHELPER_REQUIRE_CONFIG(window)
QT_BEGIN_NAMESPACE
class QCheckBox;
@ -14,19 +16,23 @@ class QLineEdit;
class QPushButton;
QT_END_NAMESPACE
#if FRAMELESSHELPER_CONFIG(titlebar)
FRAMELESSHELPER_BEGIN_NAMESPACE
class StandardTitleBar;
FRAMELESSHELPER_END_NAMESPACE
#endif
class Dialog : public FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessDialog)
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(Dialog)
Q_DISABLE_COPY(Dialog)
public:
explicit Dialog(QWidget *parent = nullptr);
~Dialog() override;
void waitReady();
protected:
void closeEvent(QCloseEvent *event) override;
@ -34,7 +40,9 @@ private:
void setupUi();
private:
#if FRAMELESSHELPER_CONFIG(titlebar)
FRAMELESSHELPER_PREPEND_NAMESPACE(StandardTitleBar) *titleBar = nullptr;
#endif
QLabel *label = nullptr;
QLineEdit *lineEdit = nullptr;
QCheckBox *caseCheckBox = nullptr;

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -23,41 +23,45 @@
*/
#include <QtWidgets/qapplication.h>
#include <framelessconfig_p.h>
#include <clocale>
#include <FramelessHelper/Core/private/framelessconfig_p.h>
#include "dialog.h"
#include "../shared/log.h"
FRAMELESSHELPER_USE_NAMESPACE
#define CREATE_WINDOW(Name) \
const auto Name = std::make_unique<Dialog>(); \
Name->setObjectName(FRAMELESSHELPER_STRING_LITERAL(#Name)); \
Name->waitReady(); \
Name->show();
int main(int argc, char *argv[])
{
std::setlocale(LC_ALL, "en_US.UTF-8");
Log::setup(FRAMELESSHELPER_STRING_LITERAL("dialog"));
// Not necessary, but better call this function, before the construction
// of any Q(Core|Gui)Application instances.
FramelessHelper::Widgets::initialize();
FramelessHelperWidgetsInitialize();
const QScopedPointer<QApplication> application(new QApplication(argc, argv));
#if 0
if (!qEnvironmentVariableIsSet("QT_WIDGETS_RHI")) {
qputenv("QT_WIDGETS_RHI", FRAMELESSHELPER_BYTEARRAY_LITERAL("1"));
}
#endif
const auto application = std::make_unique<QApplication>(argc, argv);
// Must be called after QGuiApplication has been constructed, we are using
// some private functions from QPA which won't be available until there's
// a QGuiApplication instance.
FramelessHelper::Core::setApplicationOSThemeAware();
FramelessHelperEnableThemeAware();
FramelessConfig::instance()->set(Global::Option::WindowUseRoundCorners);
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);
FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial);
//FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial);
const QScopedPointer<Dialog> dialog(new Dialog);
dialog->show();
CREATE_WINDOW(dialog1)
CREATE_WINDOW(dialog2)
CREATE_WINDOW(dialog3)
const int exec = QCoreApplication::exec();
// Not necessary, but if you don't call it, there will be some small memory leaks.
FramelessHelper::Widgets::uninitialize();
return exec;
return QCoreApplication::exec();
}

View File

@ -1,7 +1,7 @@
#[[
MIT License
Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -22,11 +22,38 @@
SOFTWARE.
]]
set(SOURCES
set(DEMO_NAME FramelessHelperDemo-MainWindow)
if(FRAMELESSHELPER_ENABLE_UNIVERSAL_BUILD)
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
endif()
if(FRAMELESSHELPER_EXAMPLES_STANDALONE)
cmake_minimum_required(VERSION 3.20)
project(${DEMO_NAME} VERSION 1.0)
include(../../cmake/utils.cmake)
setup_project(
QT_PROJECT
LANGUAGES CXX RC
NO_WARNING
ENABLE_LTO
)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
find_package(FramelessHelper REQUIRED COMPONENTS Core Widgets)
endif()
add_executable(${DEMO_NAME})
target_sources(${DEMO_NAME} PRIVATE
../shared/log.h
../shared/log.cpp
../shared/settings.h
../shared/settings.cpp
../dialog/dialog.h
../dialog/dialog.cpp
../widget/widget.h
../widget/widget.cpp
mainwindow.ui
mainwindow.h
mainwindow.cpp
@ -34,27 +61,85 @@ set(SOURCES
)
if(WIN32)
enable_language(RC)
list(APPEND SOURCES
../shared/example.rc
../shared/example.manifest
set(__rc_path "${PROJECT_BINARY_DIR}/${DEMO_NAME}.rc")
if(NOT EXISTS "${__rc_path}")
generate_win32_rc_file(
PATH "${__rc_path}"
VERSION "${PROJECT_VERSION}"
COMPANY "wangwenx190"
DESCRIPTION "FramelessHelper Demo Application: MainWindow"
COPYRIGHT "MIT License"
PRODUCT "FramelessHelper Demo"
ICONS "../shared/example.ico"
)
endif()
set(__manifest_path "${PROJECT_BINARY_DIR}/${DEMO_NAME}.manifest")
if(NOT EXISTS "${__manifest_path}")
generate_win32_manifest_file(
PATH "${__manifest_path}"
ID "org.wangwenx190.demo.MainWindow"
VERSION "${PROJECT_VERSION}"
DESCRIPTION "FramelessHelper Demo Application: MainWindow"
VISTA_COMPAT
WIN7_COMPAT
WIN8_COMPAT
WIN8_1_COMPAT
WIN10_COMPAT
WIN11_COMPAT
XAML_ISLANDS_COMPAT
UTF8_CODEPAGE
)
endif()
target_sources(${DEMO_NAME} PRIVATE
"${__rc_path}"
"${__manifest_path}"
)
endif()
add_executable(MainWindow ${SOURCES})
target_link_libraries(MainWindow PRIVATE
target_link_libraries(${DEMO_NAME} PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
FramelessHelper::Core
FramelessHelper::Widgets
)
target_compile_definitions(MainWindow PRIVATE
QT_NO_KEYWORDS
setup_gui_app(
TARGETS ${DEMO_NAME}
BUNDLE_ID "org.wangwenx190.demo.MainWindow"
BUNDLE_VERSION "1.0.0"
BUNDLE_VERSION_SHORT "1.0"
)
include(../../src/core/cmakehelper.cmake)
setup_gui_app(MainWindow)
setup_compile_params(MainWindow)
if(FRAMELESSHELPER_EXAMPLES_DEPLOYQT)
deploy_qt_runtime(MainWindow)
setup_target_rpaths(TARGETS ${DEMO_NAME})
setup_qt_stuff(TARGETS ${DEMO_NAME})
set(__extra_flags "")
if(NOT FRAMELESSHELPER_NO_PERMISSIVE_CHECKS)
list(APPEND __extra_flags PERMISSIVE)
endif()
if(FRAMELESSHELPER_ENABLE_SPECTRE)
list(APPEND __extra_flags SPECTRE)
endif()
if(FRAMELESSHELPER_ENABLE_EHCONTGUARD)
list(APPEND __extra_flags EHCONTGUARD)
endif()
if(FRAMELESSHELPER_ENABLE_INTELCET)
list(APPEND __extra_flags INTELCET)
endif()
if(FRAMELESSHELPER_ENABLE_CFGUARD)
list(APPEND __extra_flags CFGUARD)
endif()
if(FRAMELESSHELPER_FORCE_LTO)
list(APPEND __extra_flags FORCE_LTO)
endif()
setup_compile_params(TARGETS ${DEMO_NAME} ${__extra_flags})
if(FRAMELESSHELPER_EXAMPLES_DEPLOYQT)
set(__extra_flags)
if(FRAMELESSHELPER_NO_INSTALL)
set(__extra_flags NO_INSTALL)
endif()
deploy_qt_runtime(TARGET ${DEMO_NAME} ${__extra_flags})
endif()
#dump_target_info(TARGETS ${DEMO_NAME})

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -23,41 +23,45 @@
*/
#include <QtWidgets/qapplication.h>
#include <framelessconfig_p.h>
#include <clocale>
#include <FramelessHelper/Core/private/framelessconfig_p.h>
#include "mainwindow.h"
#include "../shared/log.h"
FRAMELESSHELPER_USE_NAMESPACE
#define CREATE_WINDOW(Name) \
const auto Name = std::make_unique<MainWindow>(); \
Name->setObjectName(FRAMELESSHELPER_STRING_LITERAL(#Name)); \
Name->waitReady(); \
Name->show();
int main(int argc, char *argv[])
{
std::setlocale(LC_ALL, "en_US.UTF-8");
Log::setup(FRAMELESSHELPER_STRING_LITERAL("mainwindow"));
// Not necessary, but better call this function, before the construction
// of any Q(Core|Gui)Application instances.
FramelessHelper::Widgets::initialize();
FramelessHelperWidgetsInitialize();
const QScopedPointer<QApplication> application(new QApplication(argc, argv));
#if 0
if (!qEnvironmentVariableIsSet("QT_WIDGETS_RHI")) {
qputenv("QT_WIDGETS_RHI", FRAMELESSHELPER_BYTEARRAY_LITERAL("1"));
}
#endif
const auto application = std::make_unique<QApplication>(argc, argv);
// Must be called after QGuiApplication has been constructed, we are using
// some private functions from QPA which won't be available until there's
// a QGuiApplication instance.
FramelessHelper::Core::setApplicationOSThemeAware();
FramelessHelperEnableThemeAware();
FramelessConfig::instance()->set(Global::Option::WindowUseRoundCorners);
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);
FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial);
//FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial);
const QScopedPointer<MainWindow> mainWindow(new MainWindow);
mainWindow->show();
CREATE_WINDOW(mainWindow1)
CREATE_WINDOW(mainWindow2)
CREATE_WINDOW(mainWindow3)
const int exec = QCoreApplication::exec();
// Not necessary, but if you don't call it, there will be some small memory leaks.
FramelessHelper::Widgets::uninitialize();
return exec;
return QCoreApplication::exec();
}

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -26,11 +26,21 @@
#include "ui_mainwindow.h"
#include <QtWidgets/qboxlayout.h>
#include <QtWidgets/qfileiconprovider.h>
#include <Utils>
#include <StandardTitleBar>
#include <StandardSystemButton>
#include <FramelessWidgetsHelper>
#include <FramelessHelper/Core/utils.h>
#include <FramelessHelper/Widgets/standardtitlebar.h>
#include <FramelessHelper/Widgets/standardsystembutton.h>
#include <FramelessHelper/Widgets/framelesswidgetshelper.h>
#include "../shared/settings.h"
#include "../widget/widget.h"
#include "../dialog/dialog.h"
extern template void Settings::set<QRect>(const QString &, const QString &, const QRect &);
extern template void Settings::set<qreal>(const QString &, const QString &, const qreal &);
extern template void Settings::set<QByteArray>(const QString &, const QString &, const QByteArray &);
extern template QRect Settings::get<QRect>(const QString &, const QString &);
extern template qreal Settings::get<qreal>(const QString &, const QString &);
extern template QByteArray Settings::get<QByteArray>(const QString &, const QString &);
FRAMELESSHELPER_USE_NAMESPACE
@ -38,6 +48,7 @@ using namespace Global;
FRAMELESSHELPER_STRING_CONSTANT(Geometry)
FRAMELESSHELPER_STRING_CONSTANT(State)
FRAMELESSHELPER_STRING_CONSTANT(DevicePixelRatio)
MainWindow::MainWindow(QWidget *parent, const Qt::WindowFlags flags) : FramelessMainWindow(parent, flags)
{
@ -48,16 +59,22 @@ MainWindow::~MainWindow() = default;
void MainWindow::closeEvent(QCloseEvent *event)
{
Settings::set({}, kGeometry, saveGeometry());
Settings::set({}, kState, saveState());
if (!parent()) {
const QString id = objectName();
Settings::set(id, kGeometry, geometry());
Settings::set(id, kState, saveState());
Settings::set(id, kDevicePixelRatio, devicePixelRatioF());
}
FramelessMainWindow::closeEvent(event);
}
void MainWindow::initialize()
{
m_titleBar.reset(new StandardTitleBar(this));
#if FRAMELESSHELPER_CONFIG(titlebar)
m_titleBar = new StandardTitleBar(this);
m_titleBar->setTitleLabelAlignment(Qt::AlignCenter);
m_mainWindow.reset(new Ui::MainWindow);
#endif
m_mainWindow = new Ui::MainWindow;
m_mainWindow->setupUi(this);
QMenuBar * const mb = menuBar();
@ -79,31 +96,64 @@ QMenuBar::item:pressed {
background: #888888;
}
)"));
#if FRAMELESSHELPER_CONFIG(titlebar)
const auto titleBarLayout = static_cast<QHBoxLayout *>(m_titleBar->layout());
titleBarLayout->insertWidget(0, mb);
// setMenuWidget(): make the menu widget become the first row of the window.
setMenuWidget(m_titleBar.data());
setMenuWidget(m_titleBar);
#endif
#if FRAMELESSHELPER_CONFIG(titlebar)
FramelessWidgetsHelper *helper = FramelessWidgetsHelper::get(this);
helper->setTitleBarWidget(m_titleBar.data());
helper->setTitleBarWidget(m_titleBar);
# if (!defined(Q_OS_MACOS) && FRAMELESSHELPER_CONFIG(system_button))
helper->setSystemButton(m_titleBar->minimizeButton(), SystemButtonType::Minimize);
helper->setSystemButton(m_titleBar->maximizeButton(), SystemButtonType::Maximize);
helper->setSystemButton(m_titleBar->closeButton(), SystemButtonType::Close);
# endif
#endif
helper->setHitTestVisible(mb); // IMPORTANT!
connect(helper, &FramelessWidgetsHelper::ready, this, [this, helper](){
const QByteArray geoData = Settings::get({}, kGeometry);
const QByteArray stateData = Settings::get({}, kState);
if (geoData.isEmpty()) {
helper->moveWindowToDesktopCenter();
} else {
restoreGeometry(geoData);
}
if (!stateData.isEmpty()) {
restoreState(stateData);
}
});
setWindowTitle(tr("FramelessHelper demo application - Qt MainWindow"));
setWindowTitle(tr("FramelessHelper demo application - QMainWindow"));
setWindowIcon(QFileIconProvider().icon(QFileIconProvider::Computer));
connect(this, &MainWindow::objectNameChanged, this, [this](const QString &name){
if (name.isEmpty()) {
return;
}
setWindowTitle(windowTitle() + FRAMELESSHELPER_STRING_LITERAL(" [%1]").arg(name));
});
connect(m_mainWindow->pushButton, &QPushButton::clicked, this, [this]{
const auto dialog = new Dialog(this);
dialog->waitReady();
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->exec();
});
connect(m_mainWindow->pushButton_2, &QPushButton::clicked, this, [this]{
const auto widget = new Widget(this);
widget->waitReady();
widget->setAttribute(Qt::WA_DeleteOnClose);
widget->show();
});
}
void MainWindow::waitReady()
{
FramelessWidgetsHelper *helper = FramelessWidgetsHelper::get(this);
helper->waitForReady();
const QString id = objectName();
const auto savedGeometry = Settings::get<QRect>(id, kGeometry);
if (savedGeometry.isValid() && !parent()) {
const auto savedDpr = Settings::get<qreal>(id, kDevicePixelRatio);
// Qt doesn't support dpr < 1.
const qreal oldDpr = std::max(savedDpr, qreal(1));
const qreal scale = (devicePixelRatioF() / oldDpr);
setGeometry({savedGeometry.topLeft() * scale, savedGeometry.size() * scale});
} else {
helper->moveWindowToDesktopCenter();
}
const QByteArray savedState = Settings::get<QByteArray>(id, kState);
if (!savedState.isEmpty() && !parent()) {
restoreState(savedState);
}
}

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,11 +24,15 @@
#pragma once
#include <FramelessMainWindow>
#include <FramelessHelper/Widgets/framelessmainwindow.h>
FRAMELESSHELPER_REQUIRE_CONFIG(window)
#if FRAMELESSHELPER_CONFIG(titlebar)
FRAMELESSHELPER_BEGIN_NAMESPACE
class StandardTitleBar;
FRAMELESSHELPER_END_NAMESPACE
#endif
namespace Ui
{
@ -38,12 +42,14 @@ class MainWindow;
class MainWindow : public FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessMainWindow)
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(MainWindow)
Q_DISABLE_COPY(MainWindow)
public:
explicit MainWindow(QWidget *parent = nullptr, const Qt::WindowFlags flags = {});
~MainWindow() override;
void waitReady();
protected:
void closeEvent(QCloseEvent *event) override;
@ -51,6 +57,8 @@ private:
void initialize();
private:
QScopedPointer<FRAMELESSHELPER_PREPEND_NAMESPACE(StandardTitleBar)> m_titleBar;
QScopedPointer<Ui::MainWindow> m_mainWindow;
#if FRAMELESSHELPER_CONFIG(titlebar)
FRAMELESSHELPER_PREPEND_NAMESPACE(StandardTitleBar) *m_titleBar = nullptr;
#endif
Ui::MainWindow *m_mainWindow = nullptr;
};

View File

@ -1,7 +1,7 @@
#[[
MIT License
Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -22,15 +22,33 @@
SOFTWARE.
]]
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS OpenGL)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS OpenGL)
set(DEMO_NAME FramelessHelperDemo-OpenGLWidget)
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS OpenGLWidgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS OpenGLWidgets)
if(FRAMELESSHELPER_ENABLE_UNIVERSAL_BUILD)
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
endif()
set(SOURCES
if(FRAMELESSHELPER_EXAMPLES_STANDALONE)
cmake_minimum_required(VERSION 3.20)
project(${DEMO_NAME} VERSION 1.0)
include(../../cmake/utils.cmake)
setup_project(
QT_PROJECT
LANGUAGES CXX RC
NO_WARNING
ENABLE_LTO
)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets OpenGL)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets OpenGL)
if(QT_VERSION_MAJOR GREATER_EQUAL 6)
find_package(Qt6 REQUIRED COMPONENTS OpenGLWidgets)
endif()
find_package(FramelessHelper REQUIRED COMPONENTS Core Widgets)
endif()
add_executable(${DEMO_NAME})
target_sources(${DEMO_NAME} PRIVATE
../shared/log.h
../shared/log.cpp
../shared/settings.h
@ -46,34 +64,66 @@ set(SOURCES
)
if(WIN32)
enable_language(RC)
list(APPEND SOURCES
../shared/example.rc
../shared/example.manifest
set(__rc_path "${PROJECT_BINARY_DIR}/${DEMO_NAME}.rc")
if(NOT EXISTS "${__rc_path}")
generate_win32_rc_file(
PATH "${__rc_path}"
VERSION "${PROJECT_VERSION}"
COMPANY "wangwenx190"
DESCRIPTION "FramelessHelper Demo Application: OpenGLWidget"
COPYRIGHT "MIT License"
PRODUCT "FramelessHelper Demo"
ICONS "../shared/example.ico"
)
endif()
set(__manifest_path "${PROJECT_BINARY_DIR}/${DEMO_NAME}.manifest")
if(NOT EXISTS "${__manifest_path}")
generate_win32_manifest_file(
PATH "${__manifest_path}"
ID "org.wangwenx190.demo.OpenGLWidget"
VERSION "${PROJECT_VERSION}"
VISTA_COMPAT
WIN7_COMPAT
WIN8_COMPAT
WIN8_1_COMPAT
WIN10_COMPAT
WIN11_COMPAT
XAML_ISLANDS_COMPAT
UTF8_CODEPAGE
)
endif()
target_sources(${DEMO_NAME} PRIVATE
"${__rc_path}"
"${__manifest_path}"
)
endif()
add_executable(OpenGLWidget ${SOURCES})
target_link_libraries(OpenGLWidget PRIVATE
target_link_libraries(${DEMO_NAME} PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::OpenGL
FramelessHelper::Core
FramelessHelper::Widgets
)
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
target_link_libraries(OpenGLWidget PRIVATE
Qt${QT_VERSION_MAJOR}::OpenGLWidgets
if(TARGET Qt6::OpenGLWidgets)
target_link_libraries(${DEMO_NAME} PRIVATE
Qt6::OpenGLWidgets
)
endif()
target_compile_definitions(OpenGLWidget PRIVATE
QT_NO_KEYWORDS
setup_gui_app(
TARGETS ${DEMO_NAME}
BUNDLE_ID "org.wangwenx190.demo.OpenGLWidget"
BUNDLE_VERSION "1.0.0"
BUNDLE_VERSION_SHORT "1.0"
)
include(../../src/core/cmakehelper.cmake)
setup_gui_app(OpenGLWidget)
setup_compile_params(OpenGLWidget)
if(FRAMELESSHELPER_EXAMPLES_DEPLOYQT)
deploy_qt_runtime(OpenGLWidget)
set(__extra_flags)
if(FRAMELESSHELPER_NO_INSTALL)
set(__extra_flags NO_INSTALL)
endif()
deploy_qt_runtime(TARGET ${DEMO_NAME} ${__extra_flags})
endif()
#dump_target_info(TARGETS ${DEMO_NAME})

View File

@ -52,7 +52,7 @@
#include <QApplication>
#include <QSurfaceFormat>
#include <QOpenGLContext>
#include <framelessconfig_p.h>
#include <FramelessHelper/Core/private/framelessconfig_p.h>
#include <clocale>
#include "mainwindow.h"
#include "../shared/log.h"
@ -77,14 +77,13 @@ int main(int argc, char *argv[])
// of any Q(Core|Gui)Application instances.
FramelessHelper::Widgets::initialize();
const QScopedPointer<QApplication> application(new QApplication(argc, argv));
const auto application = std::make_unique<QApplication>(argc, argv);
// Must be called after QGuiApplication has been constructed, we are using
// some private functions from QPA which won't be available until there's
// a QGuiApplication instance.
FramelessHelper::Core::setApplicationOSThemeAware();
FramelessConfig::instance()->set(Global::Option::WindowUseRoundCorners);
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);
FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial);
@ -103,13 +102,9 @@ int main(int argc, char *argv[])
QSurfaceFormat::setDefaultFormat(fmt);
const QScopedPointer<MainWindow> mainWindow(new MainWindow);
const auto mainWindow = std::make_unique<MainWindow>();
mainWindow->waitReady();
mainWindow->show();
const int exec = QCoreApplication::exec();
// Not necessary, but if you don't call it, there will be some small memory leaks.
FramelessHelper::Widgets::uninitialize();
return exec;
return QCoreApplication::exec();
}

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -26,16 +26,23 @@
#include "glwidget.h"
#include <QtWidgets/qboxlayout.h>
#include <QtWidgets/qfileiconprovider.h>
#include <FramelessWidgetsHelper>
#include <StandardTitleBar>
#include <StandardSystemButton>
#include <FramelessHelper/Widgets/framelesswidgetshelper.h>
#include <FramelessHelper/Widgets/standardtitlebar.h>
#include <FramelessHelper/Widgets/standardsystembutton.h>
#include "../shared/settings.h"
extern template void Settings::set<QRect>(const QString &, const QString &, const QRect &);
extern template void Settings::set<qreal>(const QString &, const QString &, const qreal &);
extern template QRect Settings::get<QRect>(const QString &, const QString &);
extern template qreal Settings::get<qreal>(const QString &, const QString &);
FRAMELESSHELPER_USE_NAMESPACE
using namespace Global;
FRAMELESSHELPER_STRING_CONSTANT(Geometry)
FRAMELESSHELPER_STRING_CONSTANT(DevicePixelRatio)
MainWindow::MainWindow(QWidget *parent) : FramelessWidget(parent)
{
@ -46,7 +53,10 @@ MainWindow::~MainWindow() = default;
void MainWindow::closeEvent(QCloseEvent *event)
{
Settings::set({}, kGeometry, saveGeometry());
if (!parent()) {
Settings::set({}, kGeometry, geometry());
Settings::set({}, kDevicePixelRatio, devicePixelRatioF());
}
FramelessWidget::closeEvent(event);
}
@ -63,19 +73,28 @@ void MainWindow::initialize()
mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->addWidget(m_titleBar);
mainLayout->addWidget(m_glWidget);
setLayout(mainLayout);
FramelessWidgetsHelper *helper = FramelessWidgetsHelper::get(this);
helper->setTitleBarWidget(m_titleBar);
#ifndef Q_OS_MACOS
helper->setSystemButton(m_titleBar->minimizeButton(), SystemButtonType::Minimize);
helper->setSystemButton(m_titleBar->maximizeButton(), SystemButtonType::Maximize);
helper->setSystemButton(m_titleBar->closeButton(), SystemButtonType::Close);
connect(helper, &FramelessWidgetsHelper::ready, this, [this, helper](){
const QByteArray data = Settings::get({}, kGeometry);
if (data.isEmpty()) {
helper->moveWindowToDesktopCenter();
} else {
restoreGeometry(data);
}
});
#endif // Q_OS_MACOS
}
void MainWindow::waitReady()
{
FramelessWidgetsHelper *helper = FramelessWidgetsHelper::get(this);
helper->waitForReady();
const auto savedGeometry = Settings::get<QRect>({}, kGeometry);
if (savedGeometry.isValid() && !parent()) {
const auto savedDpr = Settings::get<qreal>({}, kDevicePixelRatio);
// Qt doesn't support dpr < 1.
const qreal oldDpr = std::max(savedDpr, qreal(1));
const qreal scale = (devicePixelRatioF() / oldDpr);
setGeometry({savedGeometry.topLeft() * scale, savedGeometry.size() * scale});
} else {
helper->moveWindowToDesktopCenter();
}
}

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,7 +24,7 @@
#pragma once
#include <FramelessWidget>
#include <FramelessHelper/Widgets/framelesswidget.h>
FRAMELESSHELPER_BEGIN_NAMESPACE
class StandardTitleBar;
@ -35,12 +35,14 @@ class GLWidget;
class MainWindow : public FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessWidget)
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(MainWindow)
Q_DISABLE_COPY(MainWindow)
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow() override;
void waitReady();
protected:
void closeEvent(QCloseEvent *event) override;

View File

@ -1,7 +1,7 @@
#[[
MIT License
Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -22,10 +22,30 @@
SOFTWARE.
]]
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Qml Quick QuickControls2)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Qml Quick QuickControls2)
set(DEMO_NAME FramelessHelperDemo-Quick)
set(SOURCES
if(FRAMELESSHELPER_ENABLE_UNIVERSAL_BUILD)
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
endif()
if(FRAMELESSHELPER_EXAMPLES_STANDALONE)
cmake_minimum_required(VERSION 3.20)
project(${DEMO_NAME} VERSION 1.0)
include(../../cmake/utils.cmake)
setup_project(
QT_PROJECT
LANGUAGES CXX RC
NO_WARNING
ENABLE_LTO
)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Quick)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Quick)
find_package(FramelessHelper REQUIRED COMPONENTS Core Quick)
endif()
add_executable(${DEMO_NAME})
target_sources(${DEMO_NAME} PRIVATE
../shared/log.h
../shared/log.cpp
../shared/settings.h
@ -35,63 +55,122 @@ set(SOURCES
quicksettings.cpp
)
if(${QT_VERSION} VERSION_LESS 6.2)
list(APPEND SOURCES resources.qrc)
endif()
if(WIN32)
enable_language(RC)
list(APPEND SOURCES
../shared/example.rc
../shared/example.manifest
set(__rc_path "${PROJECT_BINARY_DIR}/${DEMO_NAME}.rc")
if(NOT EXISTS "${__rc_path}")
generate_win32_rc_file(
PATH "${__rc_path}"
VERSION "${PROJECT_VERSION}"
COMPANY "wangwenx190"
DESCRIPTION "FramelessHelper Demo Application: Quick"
COPYRIGHT "MIT License"
PRODUCT "FramelessHelper Demo"
ICONS "../shared/example.ico"
)
endif()
set(__manifest_path "${PROJECT_BINARY_DIR}/${DEMO_NAME}.manifest")
if(NOT EXISTS "${__manifest_path}")
generate_win32_manifest_file(
PATH "${__manifest_path}"
ID "org.wangwenx190.demo.Quick"
VERSION "${PROJECT_VERSION}"
DESCRIPTION "FramelessHelper Demo Application: Quick"
VISTA_COMPAT
WIN7_COMPAT
WIN8_COMPAT
WIN8_1_COMPAT
WIN10_COMPAT
WIN11_COMPAT
XAML_ISLANDS_COMPAT
UTF8_CODEPAGE
)
endif()
target_sources(${DEMO_NAME} PRIVATE
"${__rc_path}"
"${__manifest_path}"
)
endif()
add_executable(Quick ${SOURCES})
if(${QT_VERSION} VERSION_GREATER_EQUAL 6.2)
qt_add_qml_module(Quick
if(QT_VERSION VERSION_GREATER_EQUAL "6.2")
set(QML_SOURCES
"qml/Window.qml"
"qml/ApplicationWindow.qml"
"qml/HomePage.qml"
)
set_source_files_properties(${QML_SOURCES}
PROPERTIES QT_DISCARD_FILE_CONTENTS TRUE
)
qt_add_qml_module(${DEMO_NAME}
URI Demo
VERSION 1.0
IMPORT_PATH "${PROJECT_BINARY_DIR}/imports"
RESOURCE_PREFIX "/"
NO_RESOURCE_TARGET_PATH
IMPORTS
QtQml/auto
QtQuick/auto
QtQuick.Controls.Basic/auto
DEPENDENCIES
org.wangwenx190.FramelessHelper/auto
QML_FILES
Window.qml
ApplicationWindow.qml
HomePage.qml
#ENABLE_TYPE_COMPILER # We can't use it for now due to it still can't compile singletons.
# There's some hope to get it supported in Qt 6.5.
QML_FILES ${QML_SOURCES}
#ENABLE_TYPE_COMPILER
)
qt_add_resources(Quick resources
qt_add_resources(${DEMO_NAME} resources
PREFIX
"/Demo"
"/"
FILES
"images/microsoft.svg"
)
else()
target_sources(${DEMO_NAME} PRIVATE resources.qrc)
endif()
target_link_libraries(Quick PRIVATE
Qt${QT_VERSION_MAJOR}::QmlPrivate
target_link_libraries(${DEMO_NAME} PRIVATE
Qt${QT_VERSION_MAJOR}::Quick
Qt${QT_VERSION_MAJOR}::QuickPrivate
Qt${QT_VERSION_MAJOR}::QuickControls2Private
FramelessHelper::Core
FramelessHelper::Quick
)
target_compile_definitions(Quick PRIVATE
QT_NO_KEYWORDS
$<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>
setup_gui_app(
TARGETS ${DEMO_NAME}
BUNDLE_ID "org.wangwenx190.demo.Quick"
BUNDLE_VERSION "1.0.0"
BUNDLE_VERSION_SHORT "1.0"
)
include(../../src/core/cmakehelper.cmake)
setup_gui_app(Quick)
setup_compile_params(Quick)
setup_target_rpaths(TARGETS ${DEMO_NAME})
setup_qt_stuff(TARGETS ${DEMO_NAME})
set(__extra_flags "")
if(NOT FRAMELESSHELPER_NO_PERMISSIVE_CHECKS)
list(APPEND __extra_flags PERMISSIVE)
endif()
if(FRAMELESSHELPER_ENABLE_SPECTRE)
list(APPEND __extra_flags SPECTRE)
endif()
if(FRAMELESSHELPER_ENABLE_EHCONTGUARD)
list(APPEND __extra_flags EHCONTGUARD)
endif()
if(FRAMELESSHELPER_ENABLE_INTELCET)
list(APPEND __extra_flags INTELCET)
endif()
if(FRAMELESSHELPER_ENABLE_CFGUARD)
list(APPEND __extra_flags CFGUARD)
endif()
if(FRAMELESSHELPER_FORCE_LTO)
list(APPEND __extra_flags FORCE_LTO)
endif()
setup_compile_params(TARGETS ${DEMO_NAME} ${__extra_flags})
if(FRAMELESSHELPER_EXAMPLES_DEPLOYQT)
deploy_qt_runtime(Quick
QML_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
#QML_IMPORT_DIR "${PROJECT_BINARY_DIR}/qml" # Some applications failed to start.
set(__extra_flags)
if(FRAMELESSHELPER_NO_INSTALL)
set(__extra_flags NO_INSTALL)
endif()
deploy_qt_runtime(
TARGET ${DEMO_NAME}
QML_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/qml"
${__extra_flags}
)
endif()
#dump_target_info(TARGETS ${DEMO_NAME})

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -23,45 +23,50 @@
*/
#ifndef QMLTC_ENABLED
# define QMLTC_ENABLED 0 // We disable it for now, because currently (6.4) it can't process singletons yet.
// There's some hope to get it supported in Qt 6.5
# define QMLTC_ENABLED 0
#endif
#include <QtGui/qguiapplication.h>
#include <QtQml/qqmlapplicationengine.h>
#include <QtQml/qqmlcontext.h>
#include <QtQuick/qquickwindow.h>
#include <QtQuickControls2/qquickstyle.h>
#include <framelessquickmodule.h>
#include <framelessconfig_p.h>
#include <clocale>
#include <FramelessHelper/Quick/framelessquickmodule.h>
#include <FramelessHelper/Core/private/framelessconfig_p.h>
#include "quicksettings.h"
#if QMLTC_ENABLED
# include <homepage.h>
#endif
#include "../shared/log.h"
FRAMELESSHELPER_REQUIRE_CONFIG(window)
FRAMELESSHELPER_USE_NAMESPACE
static constexpr const bool IS_MACOS_HOST =
#ifdef Q_OS_MACOS
true
#else // !Q_OS_MACOS
false
#endif // Q_OS_MACOS
;
int main(int argc, char *argv[])
{
std::setlocale(LC_ALL, "en_US.UTF-8");
Log::setup(FRAMELESSHELPER_STRING_LITERAL("quick"));
// Not necessary, but better call this function, before the construction
// of any Q(Core|Gui)Application instances.
FramelessHelper::Quick::initialize();
FramelessHelperQuickInitialize();
const QScopedPointer<QGuiApplication> application(new QGuiApplication(argc, argv));
const auto application = std::make_unique<QGuiApplication>(argc, argv);
// Must be called after QGuiApplication has been constructed, we are using
// some private functions from QPA which won't be available until there's
// a QGuiApplication instance.
FramelessHelper::Core::setApplicationOSThemeAware();
FramelessHelperEnableThemeAware();
FramelessConfig::instance()->set(Global::Option::WindowUseRoundCorners);
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);
FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial);
//FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial);
// Enable QtRHI debug output if not explicitly requested by the user.
if (!qEnvironmentVariableIsSet("QSG_INFO")) {
@ -83,14 +88,35 @@ int main(int argc, char *argv[])
#endif
}
const QScopedPointer<QQmlApplicationEngine> engine(new QQmlApplicationEngine);
#if (!QMLTC_ENABLED && !defined(QUICK_USE_QMAKE))
engine->addImportPath(FRAMELESSHELPER_STRING_LITERAL("../imports"));
if (!qEnvironmentVariableIsSet("QT_QUICK_CONTROLS_STYLE")) {
// This line is not relevant to FramelessHelper, we change the default
// Qt Quick Controls theme to "Basic" (Qt6) or "Default" (Qt5) just
// because other themes will make our homemade system buttons look
// not good. This line has nothing to do with FramelessHelper itself.
qputenv("QT_QUICK_CONTROLS_STYLE", []() -> QByteArray {
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
return FRAMELESSHELPER_BYTEARRAY_LITERAL("Basic");
#else
return FRAMELESSHELPER_BYTEARRAY_LITERAL("Default");
#endif
}());
}
#if 0
// Enable some helpful debugging messages.
if (!qEnvironmentVariableIsSet("QML_IMPORT_TRACE")) {
qputenv("QML_IMPORT_TRACE", FRAMELESSHELPER_BYTEARRAY_LITERAL("1"));
}
#endif
const auto engine = std::make_unique<QQmlApplicationEngine>();
engine->rootContext()->setContextProperty(
FRAMELESSHELPER_STRING_LITERAL("$isMacOSHost"), QVariant(IS_MACOS_HOST));
#if (((QT_VERSION < QT_VERSION_CHECK(6, 2, 0)) || defined(QUICK_USE_QMAKE)) && !QMLTC_ENABLED)
// Don't forget to register our own custom QML types!
FramelessHelper::Quick::registerTypes(engine.data());
FramelessHelperQuickRegisterTypes(engine.get());
qmlRegisterSingletonType<QuickSettings>("Demo", 1, 0, "Settings",
[](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * {
@ -101,30 +127,18 @@ int main(int argc, char *argv[])
#endif
#if !QMLTC_ENABLED
// This line is not relevant to FramelessHelper, we change the default
// Qt Quick Controls theme to "Basic" (Qt6) or "Default" (Qt5) just
// because other themes will make our homemade system buttons look
// not good. This line has nothing to do with FramelessHelper itself.
# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
QQuickStyle::setStyle(FRAMELESSHELPER_STRING_LITERAL("Basic"));
# else
QQuickStyle::setStyle(FRAMELESSHELPER_STRING_LITERAL("Default"));
# endif
#endif
#if !QMLTC_ENABLED
const QUrl mainUrl(FRAMELESSHELPER_STRING_LITERAL("qrc:///Demo/HomePage.qml"));
const QUrl mainUrl(FRAMELESSHELPER_STRING_LITERAL("qrc:///qml/HomePage.qml"));
#endif
#if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
QObject::connect(engine.data(), &QQmlApplicationEngine::objectCreationFailed, qApp,
QObject::connect(engine.get(), &QQmlApplicationEngine::objectCreationFailed, application.get(),
[](const QUrl &url){
qCritical() << "The QML engine failed to create component:" << url;
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
#elif !QMLTC_ENABLED
const QMetaObject::Connection connection = QObject::connect(
engine.data(), &QQmlApplicationEngine::objectCreated, &application,
engine.get(), &QQmlApplicationEngine::objectCreated, application.get(),
[&mainUrl, &connection](QObject *object, const QUrl &url) {
if (url != mainUrl) {
return;
@ -142,13 +156,9 @@ int main(int argc, char *argv[])
#endif
#if QMLTC_ENABLED
QScopedPointer<HomePage> homePage(new HomePage(engine.data()));
const auto homePage = std::make_unique<HomePage>(engine.get());
homePage->show();
#endif
const int exec = QCoreApplication::exec();
FramelessHelper::Quick::uninitialize();
return exec;
return QCoreApplication::exec();
}

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -33,9 +33,9 @@ FramelessApplicationWindow {
visible: false // Hide the window before we sets up it's correct size and position.
width: 800
height: 600
title: qsTr("FramelessHelper demo application - Qt Quick")
title: qsTr("FramelessHelper demo application - Qt Quick [") + objectName + ']'
color: {
if (FramelessHelper.blurBehindWindowEnabled) {
if (FramelessHelper.blurBehindWindowEnabled && FramelessUtils.blurBehindWindowSupported) {
return "transparent";
}
if (FramelessUtils.systemTheme === FramelessHelperConstants.Dark) {
@ -43,17 +43,20 @@ FramelessApplicationWindow {
}
return FramelessUtils.defaultSystemLightColor;
}
onClosing: Settings.saveGeometry(window)
Component.onDestruction: Settings.saveGeometry(window)
FramelessHelper.onReady: {
// Let FramelessHelper know what's our homemade title bar, otherwise
// our window won't be draggable.
FramelessHelper.titleBarItem = titleBar;
// Make our own items visible to the hit test and on Windows, enable
// the snap layout feature (available since Windows 11).
FramelessHelper.setSystemButton(titleBar.minimizeButton, FramelessHelperConstants.Minimize);
FramelessHelper.setSystemButton(titleBar.maximizeButton, FramelessHelperConstants.Maximize);
FramelessHelper.setSystemButton(titleBar.closeButton, FramelessHelperConstants.Close);
if (!$isMacOSHost) {
// Make our own items visible to the hit test and on Windows, enable
// the snap layout feature (available since Windows 11).
FramelessHelper.setSystemButton(titleBar.minimizeButton, FramelessHelperConstants.Minimize);
FramelessHelper.setSystemButton(titleBar.maximizeButton, FramelessHelperConstants.Maximize);
FramelessHelper.setSystemButton(titleBar.closeButton, FramelessHelperConstants.Close);
}
if (!Settings.restoreGeometry(window)) {
FramelessHelper.moveWindowToDesktopCenter();
}
@ -78,7 +81,7 @@ FramelessApplicationWindow {
}
Timer {
interval: 500
interval: 100
running: true
repeat: true
onTriggered: timeLabel.text = Qt.formatTime(new Date(), "hh:mm:ss")
@ -102,7 +105,7 @@ FramelessApplicationWindow {
left: parent.left
right: parent.right
}
windowIcon: "qrc:///Demo/images/microsoft.svg"
windowIcon: "qrc:///images/microsoft.svg"
windowIconVisible: true
}
}

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -33,9 +33,9 @@ FramelessWindow {
visible: false // Hide the window before we sets up it's correct size and position.
width: 800
height: 600
title: qsTr("FramelessHelper demo application - Qt Quick")
title: qsTr("FramelessHelper demo application - Qt Quick [") + objectName +']'
color: {
if (FramelessHelper.blurBehindWindowEnabled) {
if (FramelessHelper.blurBehindWindowEnabled && FramelessUtils.blurBehindWindowSupported) {
return "transparent";
}
if (FramelessUtils.systemTheme === FramelessHelperConstants.Dark) {
@ -43,17 +43,20 @@ FramelessWindow {
}
return FramelessUtils.defaultSystemLightColor;
}
onClosing: Settings.saveGeometry(window)
Component.onDestruction: Settings.saveGeometry(window)
FramelessHelper.onReady: {
// Let FramelessHelper know what's our homemade title bar, otherwise
// our window won't be draggable.
FramelessHelper.titleBarItem = titleBar;
// Make our own items visible to the hit test and on Windows, enable
// the snap layout feature (available since Windows 11).
FramelessHelper.setSystemButton(titleBar.minimizeButton, FramelessHelperConstants.Minimize);
FramelessHelper.setSystemButton(titleBar.maximizeButton, FramelessHelperConstants.Maximize);
FramelessHelper.setSystemButton(titleBar.closeButton, FramelessHelperConstants.Close);
if (!$isMacOSHost) {
// Make our own items visible to the hit test and on Windows, enable
// the snap layout feature (available since Windows 11).
FramelessHelper.setSystemButton(titleBar.minimizeButton, FramelessHelperConstants.Minimize);
FramelessHelper.setSystemButton(titleBar.maximizeButton, FramelessHelperConstants.Maximize);
FramelessHelper.setSystemButton(titleBar.closeButton, FramelessHelperConstants.Close);
}
if (!Settings.restoreGeometry(window)) {
FramelessHelper.moveWindowToDesktopCenter();
}
@ -78,7 +81,7 @@ FramelessWindow {
}
Timer {
interval: 500
interval: 100
running: true
repeat: true
onTriggered: timeLabel.text = Qt.formatTime(new Date(), "hh:mm:ss")
@ -102,7 +105,7 @@ FramelessWindow {
left: parent.left
right: parent.right
}
windowIcon: "qrc:///Demo/images/microsoft.svg"
windowIcon: "qrc:///images/microsoft.svg"
windowIconVisible: true
}
}

View File

@ -1,7 +1,6 @@
TEMPLATE = app
TARGET = Quick
TARGET = FramelessHelperDemo-Quick
QT += qml quick quickcontrols2
win32: CONFIG -= embed_manifest_exe
DEFINES += QUICK_USE_QMAKE
HEADERS += \
../shared/log.h \
@ -13,6 +12,5 @@ SOURCES += \
quicksettings.cpp \
main.cpp
RESOURCES += resources.qrc
win32: RC_FILE = ../shared/example.rc
include(../../qmake/core.pri)
include(../../qmake/quick.pri)

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -23,10 +23,16 @@
*/
#include "quicksettings.h"
#include <QtCore/qdatastream.h>
#include "../shared/settings.h"
FRAMELESSHELPER_STRING_CONSTANT(Geometry)
FRAMELESSHELPER_STRING_CONSTANT(DevicePixelRatio)
extern template void Settings::set<QRect>(const QString &, const QString &, const QRect &);
extern template void Settings::set<qreal>(const QString &, const QString &, const qreal &);
extern template QRect Settings::get<QRect>(const QString &, const QString &);
extern template qreal Settings::get<qreal>(const QString &, const QString &);
QuickSettings::QuickSettings(QObject *parent) : QObject(parent)
{
@ -40,11 +46,9 @@ void QuickSettings::saveGeometry(QWindow *window)
if (!window) {
return;
}
QByteArray data = {};
QDataStream stream(&data, QDataStream::WriteOnly);
stream.setVersion(QDataStream::Qt_5_6);
stream << window->geometry();
Settings::set(window->objectName(), kGeometry, data);
const QString objName = window->objectName();
Settings::set(objName, kGeometry, window->geometry());
Settings::set(objName, kDevicePixelRatio, window->devicePixelRatio());
}
bool QuickSettings::restoreGeometry(QWindow *window)
@ -53,17 +57,15 @@ bool QuickSettings::restoreGeometry(QWindow *window)
if (!window) {
return false;
}
const QByteArray data = Settings::get(window->objectName(), kGeometry);
if (data.isEmpty()) {
const QString objName = window->objectName();
const auto savedGeometry = Settings::get<QRect>(objName, kGeometry);
if (!savedGeometry.isValid()) {
return false;
}
QRect geometry = {};
QDataStream stream(data);
stream.setVersion(QDataStream::Qt_5_6);
stream >> geometry;
if (!geometry.isValid()) {
return false;
}
window->setGeometry(geometry);
const auto savedDpr = Settings::get<qreal>(objName, kDevicePixelRatio);
// Qt doesn't support dpr < 1.
const qreal oldDpr = std::max(savedDpr, qreal(1));
const qreal scale = (window->devicePixelRatio() / oldDpr);
window->setGeometry({savedGeometry.topLeft() * scale, savedGeometry.size() * scale});
return true;
}

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -25,7 +25,7 @@
#pragma once
#include <QtGui/qwindow.h>
#include <framelesshelperquick_global.h>
#include <FramelessHelper/Quick/framelesshelperquick_global.h>
class QuickSettings : public QObject
{
@ -36,7 +36,7 @@ class QuickSettings : public QObject
#ifdef QML_SINGLETON
QML_SINGLETON
#endif
Q_DISABLE_COPY_MOVE(QuickSettings)
Q_DISABLE_COPY(QuickSettings)
public:
explicit QuickSettings(QObject *parent = nullptr);

View File

@ -1,8 +1,8 @@
<RCC>
<qresource prefix="/Demo">
<qresource prefix="/">
<file>images/microsoft.svg</file>
<file>Window.qml</file>
<file>ApplicationWindow.qml</file>
<file>HomePage.qml</file>
<file>qml/Window.qml</file>
<file>qml/ApplicationWindow.qml</file>
<file>qml/HomePage.qml</file>
</qresource>
</RCC>

View File

@ -1,6 +1,6 @@
:: MIT License
::
:: Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
:: Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
::
:: Permission is hereby granted, free of charge, to any person obtaining a copy
:: of this software and associated documentation files (the "Software"), to deal
@ -23,6 +23,6 @@
@echo off
setlocal
set QSG_RHI_BACKEND=d3d11
"%~dp0Quick.exe"
"%~dp0FramelessHelperDemo-Quick.exe"
endlocal
exit /b 0

View File

@ -0,0 +1,28 @@
:: MIT License
::
:: Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
::
:: Permission is hereby granted, free of charge, to any person obtaining a copy
:: of this software and associated documentation files (the "Software"), to deal
:: in the Software without restriction, including without limitation the rights
:: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
:: copies of the Software, and to permit persons to whom the Software is
:: furnished to do so, subject to the following conditions:
::
:: The above copyright notice and this permission notice shall be included in
:: all copies or substantial portions of the Software.
::
:: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
:: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
:: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
:: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
:: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
:: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
:: SOFTWARE.
@echo off
setlocal
set QSG_RHI_BACKEND=d3d12
"%~dp0FramelessHelperDemo-Quick.exe"
endlocal
exit /b 0

View File

@ -1,6 +1,6 @@
:: MIT License
::
:: Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
:: Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
::
:: Permission is hereby granted, free of charge, to any person obtaining a copy
:: of this software and associated documentation files (the "Software"), to deal
@ -23,6 +23,6 @@
@echo off
setlocal
set QSG_RHI_BACKEND=opengl
"%~dp0Quick.exe"
"%~dp0FramelessHelperDemo-Quick.exe"
endlocal
exit /b 0

View File

@ -1,6 +1,6 @@
:: MIT License
::
:: Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
:: Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
::
:: Permission is hereby granted, free of charge, to any person obtaining a copy
:: of this software and associated documentation files (the "Software"), to deal
@ -23,6 +23,6 @@
@echo off
setlocal
set QSG_RHI_BACKEND=vulkan
"%~dp0Quick.exe"
"%~dp0FramelessHelperDemo-Quick.exe"
endlocal
exit /b 0

View File

@ -1,86 +0,0 @@
<!--
MIT License
Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-->
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="org.wangwenx190.framelesshelper.demo" version="1.0.0.0"/>
<description>FramelessHelper Demo</description>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 10 Version 1809 (October 2018 Update) -->
<maxversiontested Id="10.0.17763.0"/>
<!-- Windows 10 Version 1903 (May 2019 Update) -->
<maxversiontested Id="10.0.18362.0"/>
<!-- Windows 10 Version 1909 (November 2019 Update) -->
<maxversiontested Id="10.0.18363.0"/>
<!-- Windows 10 Version 2004 (May 2020 Update) -->
<maxversiontested Id="10.0.19041.0"/>
<!-- Windows 10 Version 20H2 (October 2020 Update) -->
<maxversiontested Id="10.0.19042.0"/>
<!-- Windows 10 Version 21H1 (May 2021 Update) -->
<maxversiontested Id="10.0.19043.0"/>
<!-- Windows 10 Version 21H2 (November 2021 Update) -->
<maxversiontested Id="10.0.19044.0"/>
<!-- Windows 10 Version 22H2 (October 2022 Update) -->
<maxversiontested Id="10.0.19045.0"/>
<!-- Windows 11 Version 21H2 -->
<maxversiontested Id="10.0.22000.0"/>
<!-- Windows 11 Version 22H2 (October 2022 Update) -->
<maxversiontested Id="10.0.22621.0"/>
<!-- Windows Vista and Windows Server 2008 -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!-- Windows 7 and Windows Server 2008 R2 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Windows 8 and Windows Server 2012 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Windows 8.1 and Windows Server 2012 R2 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows 10 and Windows 11 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
<printerDriverIsolation xmlns="http://schemas.microsoft.com/SMI/2011/WindowsSettings">True</printerDriverIsolation>
<disableWindowFiltering xmlns="http://schemas.microsoft.com/SMI/2011/WindowsSettings">True</disableWindowFiltering>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">True</longPathAware>
<activeCodePage xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">UTF-8</activeCodePage>
<heapType xmlns="http://schemas.microsoft.com/SMI/2020/WindowsSettings">SegmentHeap</heapType>
</windowsSettings>
</application>
</assembly>

View File

@ -1,70 +0,0 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <windows.h>
IDI_ICON1 ICON "example.ico"
#if 0
#if (defined(WIDGET_USE_QMAKE) || defined(QUICK_USE_QMAKE))
#ifndef CREATEPROCESS_MANIFEST_RESOURCE_ID
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
#endif
#ifndef RT_MANIFEST
#define RT_MANIFEST 24
#endif
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "example.manifest"
#endif
#endif
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,0
PRODUCTVERSION 1,0,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_APP
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "wangwenx190"
VALUE "FileDescription", "FramelessHelper Demo Application"
VALUE "FileVersion", "1.0.0.0"
VALUE "LegalCopyright", "MIT License"
VALUE "ProductName", "Demo"
VALUE "ProductVersion", "1.0.0.0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -40,8 +40,8 @@
static QString g_app = {};
static bool g_logError = false;
static QScopedPointer<QFile> g_logFile;
static QScopedPointer<QTextStream> g_logStream;
static std::unique_ptr<QFile> g_logFile = nullptr;
static std::unique_ptr<QTextStream> g_logStream = nullptr;
static inline void myMessageHandler(const QtMsgType type, const QMessageLogContext &context, const QString &message)
{
@ -57,8 +57,8 @@ static inline void myMessageHandler(const QtMsgType type, const QMessageLogConte
if (g_logError) {
return;
}
if (g_logFile.isNull()) {
g_logFile.reset(new QFile);
if (!g_logFile) {
g_logFile = std::make_unique<QFile>();
g_logFile->setFileName(FRAMELESSHELPER_STRING_LITERAL("debug-%1.log").arg(g_app));
if (!g_logFile->open(QFile::WriteOnly | QFile::Text | QFile::Append)) {
std::cerr << "Can't open file to write: " << qUtf8Printable(g_logFile->errorString()) << std::endl;
@ -67,9 +67,9 @@ static inline void myMessageHandler(const QtMsgType type, const QMessageLogConte
return;
}
}
if (g_logStream.isNull()) {
g_logStream.reset(new QTextStream);
g_logStream->setDevice(g_logFile.data());
if (!g_logStream) {
g_logStream = std::make_unique<QTextStream>();
g_logStream->setDevice(g_logFile.get());
}
(*g_logStream) << finalMessage << QT_ENDL;
}
@ -86,9 +86,9 @@ void Log::setup(const QString &app)
}
once = true;
g_app = app;
qInstallMessageHandler(myMessageHandler);
qSetMessagePattern(FRAMELESSHELPER_STRING_LITERAL(
"[%{time yyyy/MM/dd hh:mm:ss.zzz}] <%{if-info}INFO%{endif}%{if-debug}DEBUG"
"%{endif}%{if-warning}WARNING%{endif}%{if-critical}CRITICAL%{endif}%{if-fatal}"
"FATAL%{endif}> %{if-category}%{category}: %{endif}%{message}"));
qInstallMessageHandler(myMessageHandler);
}

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -26,9 +26,10 @@
#include <QtCore/qsettings.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qfileinfo.h>
#include <QtCore/qrect.h>
#include <framelesshelpercore_global.h>
static QScopedPointer<QSettings> g_settings;
static std::unique_ptr<QSettings> g_settings = nullptr;
[[nodiscard]] static inline QSettings *appConfigFile()
{
@ -47,27 +48,36 @@ static QScopedPointer<QSettings> g_settings;
return (id.isEmpty() ? key : (id + u'/' + key));
}
void Settings::set(const QString &id, const QString &key, const QByteArray &data)
template<typename T>
void Settings::set(const QString &id, const QString &key, const T &data)
{
Q_ASSERT(!key.isEmpty());
Q_ASSERT(!data.isEmpty());
if (key.isEmpty() || data.isEmpty()) {
if (key.isEmpty()) {
return;
}
if (g_settings.isNull()) {
if (!g_settings) {
g_settings.reset(appConfigFile());
}
g_settings->setValue(appKey(id, key), data);
}
QByteArray Settings::get(const QString &id, const QString &key)
template<typename T>
T Settings::get(const QString &id, const QString &key)
{
Q_ASSERT(!key.isEmpty());
if (key.isEmpty()) {
return {};
return T{};
}
if (g_settings.isNull()) {
if (!g_settings) {
g_settings.reset(appConfigFile());
}
return g_settings->value(appKey(id, key)).toByteArray();
return qvariant_cast<T>(g_settings->value(appKey(id, key)));
}
template void Settings::set<QRect>(const QString &, const QString &, const QRect &);
template void Settings::set<qreal>(const QString &, const QString &, const qreal &);
template void Settings::set<QByteArray>(const QString &, const QString &, const QByteArray &);
template QRect Settings::get<QRect>(const QString &, const QString &);
template qreal Settings::get<qreal>(const QString &, const QString &);
template QByteArray Settings::get<QByteArray>(const QString &, const QString &);

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -28,6 +28,9 @@
namespace Settings
{
void set(const QString &id, const QString &key, const QByteArray &data);
[[nodiscard]] QByteArray get(const QString &id, const QString &key);
template<typename T>
void set(const QString &id, const QString &key, const T &data);
template<typename T>
[[nodiscard]] T get(const QString &id, const QString &key);
} // namespace Settings

View File

@ -1,7 +1,7 @@
#[[
MIT License
Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -22,7 +22,30 @@
SOFTWARE.
]]
set(SOURCES
set(DEMO_NAME FramelessHelperDemo-Widget)
if(FRAMELESSHELPER_ENABLE_UNIVERSAL_BUILD)
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
endif()
if(FRAMELESSHELPER_EXAMPLES_STANDALONE)
cmake_minimum_required(VERSION 3.20)
project(${DEMO_NAME} VERSION 1.0)
include(../../cmake/utils.cmake)
setup_project(
QT_PROJECT
LANGUAGES CXX RC
NO_WARNING
ENABLE_LTO
)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
find_package(FramelessHelper REQUIRED COMPONENTS Core Widgets)
endif()
add_executable(${DEMO_NAME})
target_sources(${DEMO_NAME} PRIVATE
../shared/log.h
../shared/log.cpp
../shared/settings.h
@ -33,27 +56,85 @@ set(SOURCES
)
if(WIN32)
enable_language(RC)
list(APPEND SOURCES
../shared/example.rc
../shared/example.manifest
set(__rc_path "${PROJECT_BINARY_DIR}/${DEMO_NAME}.rc")
if(NOT EXISTS "${__rc_path}")
generate_win32_rc_file(
PATH "${__rc_path}"
VERSION "${PROJECT_VERSION}"
COMPANY "wangwenx190"
DESCRIPTION "FramelessHelper Demo Application: Widget"
COPYRIGHT "MIT License"
PRODUCT "FramelessHelper Demo"
ICONS "../shared/example.ico"
)
endif()
set(__manifest_path "${PROJECT_BINARY_DIR}/${DEMO_NAME}.manifest")
if(NOT EXISTS "${__manifest_path}")
generate_win32_manifest_file(
PATH "${__manifest_path}"
ID "org.wangwenx190.demo.Widget"
VERSION "${PROJECT_VERSION}"
DESCRIPTION "FramelessHelper Demo Application: Widget"
VISTA_COMPAT
WIN7_COMPAT
WIN8_COMPAT
WIN8_1_COMPAT
WIN10_COMPAT
WIN11_COMPAT
XAML_ISLANDS_COMPAT
UTF8_CODEPAGE
)
endif()
target_sources(${DEMO_NAME} PRIVATE
"${__rc_path}"
"${__manifest_path}"
)
endif()
add_executable(Widget ${SOURCES})
target_link_libraries(Widget PRIVATE
target_link_libraries(${DEMO_NAME} PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
FramelessHelper::Core
FramelessHelper::Widgets
)
target_compile_definitions(Widget PRIVATE
QT_NO_KEYWORDS
setup_gui_app(
TARGETS ${DEMO_NAME}
BUNDLE_ID "org.wangwenx190.demo.Widget"
BUNDLE_VERSION "1.0.0"
BUNDLE_VERSION_SHORT "1.0"
)
include(../../src/core/cmakehelper.cmake)
setup_gui_app(Widget)
setup_compile_params(Widget)
if(FRAMELESSHELPER_EXAMPLES_DEPLOYQT)
deploy_qt_runtime(Widget)
setup_target_rpaths(TARGETS ${DEMO_NAME})
setup_qt_stuff(TARGETS ${DEMO_NAME})
set(__extra_flags "")
if(NOT FRAMELESSHELPER_NO_PERMISSIVE_CHECKS)
list(APPEND __extra_flags PERMISSIVE)
endif()
if(FRAMELESSHELPER_ENABLE_SPECTRE)
list(APPEND __extra_flags SPECTRE)
endif()
if(FRAMELESSHELPER_ENABLE_EHCONTGUARD)
list(APPEND __extra_flags EHCONTGUARD)
endif()
if(FRAMELESSHELPER_ENABLE_INTELCET)
list(APPEND __extra_flags INTELCET)
endif()
if(FRAMELESSHELPER_ENABLE_CFGUARD)
list(APPEND __extra_flags CFGUARD)
endif()
if(FRAMELESSHELPER_FORCE_LTO)
list(APPEND __extra_flags FORCE_LTO)
endif()
setup_compile_params(TARGETS ${DEMO_NAME} ${__extra_flags})
if(FRAMELESSHELPER_EXAMPLES_DEPLOYQT)
set(__extra_flags)
if(FRAMELESSHELPER_NO_INSTALL)
set(__extra_flags NO_INSTALL)
endif()
deploy_qt_runtime(TARGET ${DEMO_NAME} ${__extra_flags})
endif()
#dump_target_info(TARGETS ${DEMO_NAME})

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -23,46 +23,45 @@
*/
#include <QtWidgets/qapplication.h>
#include <framelessconfig_p.h>
#include <clocale>
#include <FramelessHelper/Core/private/framelessconfig_p.h>
#include "widget.h"
#include "../shared/log.h"
FRAMELESSHELPER_USE_NAMESPACE
#define CREATE_WINDOW(Name) \
const auto Name = std::make_unique<Widget>(); \
Name->setObjectName(FRAMELESSHELPER_STRING_LITERAL(#Name)); \
Name->waitReady(); \
Name->show();
int main(int argc, char *argv[])
{
std::setlocale(LC_ALL, "en_US.UTF-8");
Log::setup(FRAMELESSHELPER_STRING_LITERAL("widget"));
// Not necessary, but better call this function, before the construction
// of any Q(Core|Gui)Application instances.
FramelessHelper::Widgets::initialize();
FramelessHelperWidgetsInitialize();
const QScopedPointer<QApplication> application(new QApplication(argc, argv));
#if 0
if (!qEnvironmentVariableIsSet("QT_WIDGETS_RHI")) {
qputenv("QT_WIDGETS_RHI", FRAMELESSHELPER_BYTEARRAY_LITERAL("1"));
}
#endif
const auto application = std::make_unique<QApplication>(argc, argv);
// Must be called after QGuiApplication has been constructed, we are using
// some private functions from QPA which won't be available until there's
// a QGuiApplication instance.
FramelessHelper::Core::setApplicationOSThemeAware();
FramelessHelperEnableThemeAware();
FramelessConfig::instance()->set(Global::Option::WindowUseRoundCorners);
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);
FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial);
//FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial);
const QScopedPointer<Widget> window1(new Widget);
window1->setObjectName(FRAMELESSHELPER_STRING_LITERAL("window1"));
window1->show();
CREATE_WINDOW(widget1)
CREATE_WINDOW(widget2)
CREATE_WINDOW(widget3)
const QScopedPointer<Widget> window2(new Widget);
window2->setObjectName(FRAMELESSHELPER_STRING_LITERAL("window2"));
window2->show();
const int exec = QCoreApplication::exec();
// Not necessary, but if you don't call it, there will be some small memory leaks.
FramelessHelper::Widgets::uninitialize();
return exec;
return QCoreApplication::exec();
}

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,6 +24,7 @@
#include "widget.h"
#include <QtCore/qdatetime.h>
#include <QtCore/qcoreevent.h>
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
# include <QtGui/qshortcut.h>
#else
@ -32,23 +33,30 @@
#include <QtWidgets/qlabel.h>
#include <QtWidgets/qboxlayout.h>
#include <QtWidgets/qfileiconprovider.h>
#include <FramelessManager>
#include <Utils>
#include <FramelessWidgetsHelper>
#include <StandardTitleBar>
#include <StandardSystemButton>
#include <FramelessHelper/Core/framelessmanager.h>
#include <FramelessHelper/Core/utils.h>
#include <FramelessHelper/Widgets/framelesswidgetshelper.h>
#include <FramelessHelper/Widgets/standardtitlebar.h>
#include <FramelessHelper/Widgets/standardsystembutton.h>
#include "../shared/settings.h"
extern template void Settings::set<QRect>(const QString &, const QString &, const QRect &);
extern template void Settings::set<qreal>(const QString &, const QString &, const qreal &);
extern template QRect Settings::get<QRect>(const QString &, const QString &);
extern template qreal Settings::get<qreal>(const QString &, const QString &);
FRAMELESSHELPER_USE_NAMESPACE
using namespace Global;
FRAMELESSHELPER_STRING_CONSTANT(Geometry)
FRAMELESSHELPER_STRING_CONSTANT(DevicePixelRatio)
Widget::Widget(QWidget *parent) : FramelessWidget(parent)
{
initialize();
startTimer(500);
m_timerId = startTimer(100);
connect(FramelessManager::instance(), &FramelessManager::systemThemeChanged, this, &Widget::updateStyleSheet);
}
@ -57,47 +65,86 @@ Widget::~Widget() = default;
void Widget::timerEvent(QTimerEvent *event)
{
FramelessWidget::timerEvent(event);
if (m_clockLabel) {
if ((event->timerId() == m_timerId) && m_clockLabel) {
m_clockLabel->setText(QTime::currentTime().toString(FRAMELESSHELPER_STRING_LITERAL("hh:mm:ss")));
}
}
void Widget::closeEvent(QCloseEvent *event)
{
Settings::set(objectName(), kGeometry, saveGeometry());
if (!parent()) {
const QString objName = objectName();
Settings::set(objName, kGeometry, geometry());
Settings::set(objName, kDevicePixelRatio, devicePixelRatioF());
}
FramelessWidget::closeEvent(event);
}
void Widget::initialize()
{
setWindowTitle(tr("FramelessHelper demo application - Qt Widgets"));
setWindowTitle(tr("FramelessHelper demo application - QWidget"));
setWindowIcon(QFileIconProvider().icon(QFileIconProvider::Computer));
resize(800, 600);
m_titleBar.reset(new StandardTitleBar(this));
#if FRAMELESSHELPER_CONFIG(titlebar)
m_titleBar = new StandardTitleBar(this);
m_titleBar->setWindowIconVisible(true);
m_clockLabel.reset(new QLabel(this));
#endif
m_clockLabel = new QLabel(this);
m_clockLabel->setFrameShape(QFrame::NoFrame);
m_clockLabel->setAlignment(Qt::AlignCenter);
QFont clockFont = font();
clockFont.setBold(true);
clockFont.setPointSize(70);
m_clockLabel->setFont(clockFont);
const auto contentLayout = new QHBoxLayout;
contentLayout->setContentsMargins(0, 0, 0, 0);
contentLayout->setSpacing(0);
contentLayout->addStretch();
contentLayout->addWidget(m_clockLabel.data());
contentLayout->addStretch();
m_compilerInfoLabel = new QLabel(this);
m_compilerInfoLabel->setFrameShape(QFrame::NoFrame);
m_compilerInfoLabel->setAlignment(Qt::AlignCenter);
static const VersionInfo versionInfo = FramelessHelperVersion();
m_compilerInfoLabel->setText(
FRAMELESSHELPER_STRING_LITERAL("Compiler: %1 %2")
.arg(QString::fromUtf8(versionInfo.compiler.name),
QString::fromUtf8(versionInfo.compiler.version)));
m_commitInfoLabel = new QLabel(this);
m_commitInfoLabel->setFrameShape(QFrame::NoFrame);
m_commitInfoLabel->setAlignment(Qt::AlignCenter);
m_commitInfoLabel->setText(
FRAMELESSHELPER_STRING_LITERAL("Commit: %1 (%2)")
.arg(QString::fromUtf8(versionInfo.commit.hash),
QString::fromUtf8(versionInfo.commit.author)));
const auto clockLabelLayout = new QHBoxLayout;
clockLabelLayout->setContentsMargins(0, 0, 0, 0);
clockLabelLayout->setSpacing(0);
clockLabelLayout->addStretch();
clockLabelLayout->addWidget(m_clockLabel);
clockLabelLayout->addStretch();
const auto compilerInfoLabelLayout = new QHBoxLayout;
compilerInfoLabelLayout->setContentsMargins(0, 0, 0, 0);
compilerInfoLabelLayout->setSpacing(0);
compilerInfoLabelLayout->addStretch();
compilerInfoLabelLayout->addWidget(m_compilerInfoLabel);
compilerInfoLabelLayout->addStretch();
const auto commitInfoLabelLayout = new QHBoxLayout;
commitInfoLabelLayout->setContentsMargins(0, 0, 0, 0);
commitInfoLabelLayout->setSpacing(0);
commitInfoLabelLayout->addStretch();
commitInfoLabelLayout->addWidget(m_commitInfoLabel);
commitInfoLabelLayout->addStretch();
const auto mainLayout = new QVBoxLayout(this);
mainLayout->setSpacing(0);
mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->addWidget(m_titleBar.data());
mainLayout->addLayout(contentLayout);
setLayout(mainLayout);
#if FRAMELESSHELPER_CONFIG(titlebar)
mainLayout->addWidget(m_titleBar);
#endif
mainLayout->addStretch();
mainLayout->addLayout(clockLabelLayout);
mainLayout->addStretch();
mainLayout->addLayout(compilerInfoLabelLayout);
mainLayout->addLayout(commitInfoLabelLayout);
updateStyleSheet();
m_cancelShortcut.reset(new QShortcut(this));
m_cancelShortcut = new QShortcut(this);
m_cancelShortcut->setKey(FRAMELESSHELPER_STRING_LITERAL("ESC"));
connect(m_cancelShortcut.data(), &QShortcut::activated, this, [this](){
connect(m_cancelShortcut, &QShortcut::activated, this, [this](){
if (isFullScreen()) {
Q_EMIT m_fullScreenShortcut->activated();
} else {
@ -105,9 +152,9 @@ void Widget::initialize()
}
});
m_fullScreenShortcut.reset(new QShortcut(this));
m_fullScreenShortcut = new QShortcut(this);
m_fullScreenShortcut->setKey(FRAMELESSHELPER_STRING_LITERAL("ALT+RETURN"));
connect(m_fullScreenShortcut.data(), &QShortcut::activated, this, [this](){
connect(m_fullScreenShortcut, &QShortcut::activated, this, [this](){
if (isFullScreen()) {
setWindowState(windowState() & ~Qt::WindowFullScreen);
} else {
@ -115,28 +162,33 @@ void Widget::initialize()
}
});
connect(this, &Widget::objectNameChanged, this, [this](const QString &name){
if (name.isEmpty()) {
return;
}
setWindowTitle(windowTitle() + FRAMELESSHELPER_STRING_LITERAL(" [%1]").arg(name));
});
#if FRAMELESSHELPER_CONFIG(titlebar)
FramelessWidgetsHelper *helper = FramelessWidgetsHelper::get(this);
helper->setTitleBarWidget(m_titleBar.data());
helper->setTitleBarWidget(m_titleBar);
# if (!defined(Q_OS_MACOS) && FRAMELESSHELPER_CONFIG(system_button))
helper->setSystemButton(m_titleBar->minimizeButton(), SystemButtonType::Minimize);
helper->setSystemButton(m_titleBar->maximizeButton(), SystemButtonType::Maximize);
helper->setSystemButton(m_titleBar->closeButton(), SystemButtonType::Close);
connect(helper, &FramelessWidgetsHelper::ready, this, [this, helper](){
const QByteArray data = Settings::get(objectName(), kGeometry);
if (data.isEmpty()) {
helper->moveWindowToDesktopCenter();
} else {
restoreGeometry(data);
}
});
# endif
#endif
}
void Widget::updateStyleSheet()
{
const bool dark = Utils::shouldAppsUseDarkMode();
const QColor clockLabelTextColor = (dark ? kDefaultWhiteColor : kDefaultBlackColor);
m_clockLabel->setStyleSheet(FRAMELESSHELPER_STRING_LITERAL("background-color: transparent; color: %1;")
.arg(clockLabelTextColor.name()));
if (FramelessWidgetsHelper::get(this)->isBlurBehindWindowEnabled()) {
const bool dark = (FramelessManager::instance()->systemTheme() == SystemTheme::Dark);
const QColor labelTextColor = (dark ? kDefaultWhiteColor : kDefaultBlackColor);
const QString labelStyleSheet = FRAMELESSHELPER_STRING_LITERAL("background-color: transparent; color: %1;").arg(labelTextColor.name());
m_clockLabel->setStyleSheet(labelStyleSheet);
m_compilerInfoLabel->setStyleSheet(labelStyleSheet);
m_commitInfoLabel->setStyleSheet(labelStyleSheet);
if (FramelessWidgetsHelper::get(this)->isBlurBehindWindowEnabled() && Utils::isBlurBehindWindowSupported()) {
setStyleSheet(FRAMELESSHELPER_STRING_LITERAL("background-color: transparent;"));
} else {
const QColor windowBackgroundColor = (dark ? kDefaultSystemDarkColor : kDefaultSystemLightColor);
@ -144,3 +196,20 @@ void Widget::updateStyleSheet()
}
update();
}
void Widget::waitReady()
{
FramelessWidgetsHelper *helper = FramelessWidgetsHelper::get(this);
helper->waitForReady();
const QString objName = objectName();
const auto savedGeometry = Settings::get<QRect>(objName, kGeometry);
if (savedGeometry.isValid() && !parent()) {
const auto savedDpr = Settings::get<qreal>(objName, kDevicePixelRatio);
// Qt doesn't support dpr < 1.
const qreal oldDpr = std::max(savedDpr, qreal(1));
const qreal scale = (devicePixelRatioF() / oldDpr);
setGeometry({savedGeometry.topLeft() * scale, savedGeometry.size() * scale});
} else {
helper->moveWindowToDesktopCenter();
}
}

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,26 +24,32 @@
#pragma once
#include <FramelessWidget>
#include <FramelessHelper/Widgets/framelesswidget.h>
FRAMELESSHELPER_REQUIRE_CONFIG(window)
QT_BEGIN_NAMESPACE
class QLabel;
class QShortcut;
QT_END_NAMESPACE
#if FRAMELESSHELPER_CONFIG(titlebar)
FRAMELESSHELPER_BEGIN_NAMESPACE
class StandardTitleBar;
FRAMELESSHELPER_END_NAMESPACE
#endif
class Widget : public FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessWidget)
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(Widget)
Q_DISABLE_COPY(Widget)
public:
explicit Widget(QWidget *parent = nullptr);
~Widget() override;
void waitReady();
protected:
void timerEvent(QTimerEvent *event) override;
void closeEvent(QCloseEvent *event) override;
@ -55,8 +61,13 @@ private Q_SLOTS:
void updateStyleSheet();
private:
QScopedPointer<QLabel> m_clockLabel;
QScopedPointer<FRAMELESSHELPER_PREPEND_NAMESPACE(StandardTitleBar)> m_titleBar;
QScopedPointer<QShortcut> m_fullScreenShortcut;
QScopedPointer<QShortcut> m_cancelShortcut;
#if FRAMELESSHELPER_CONFIG(titlebar)
FRAMELESSHELPER_PREPEND_NAMESPACE(StandardTitleBar) *m_titleBar = nullptr;
#endif
QLabel *m_clockLabel = nullptr;
QLabel *m_compilerInfoLabel = nullptr;
QLabel *m_commitInfoLabel = nullptr;
QShortcut *m_fullScreenShortcut = nullptr;
QShortcut *m_cancelShortcut = nullptr;
int m_timerId = -1;
};

View File

@ -1,8 +1,6 @@
TEMPLATE = app
TARGET = Widget
TARGET = FramelessHelperDemo-Widget
QT += widgets
win32: CONFIG -= embed_manifest_exe
DEFINES += WIDGET_USE_QMAKE
HEADERS += \
../shared/log.h \
../shared/settings.h \
@ -12,6 +10,5 @@ SOURCES += \
../shared/settings.cpp \
widget.cpp \
main.cpp
win32: RC_FILE = ../shared/example.rc
include(../../qmake/core.pri)
include(../../qmake/widgets.pri)

View File

@ -1 +1 @@
#include <chromepalette.h>
#include "chromepalette.h"

View File

@ -0,0 +1 @@
#include "framelesshelper_linux.h"

View File

@ -1 +1 @@
#include <framelesshelper_qt.h>
#include "framelesshelper_qt.h"

View File

@ -1 +1 @@
#include <framelesshelper_win.h>
#include "framelesshelper_win.h"

View File

@ -1 +1 @@
#include <framelesshelper_windows.h>
#include "framelesshelper_windows.h"

View File

@ -1 +1 @@
#include <framelessmanager.h>
#include "framelessmanager.h"

View File

@ -1 +1 @@
#include <framelesshelpercore_global.h>
#include "framelesshelpercore_global.h"

View File

@ -1 +1 @@
#include <micamaterial.h>
#include "micamaterial.h"

View File

@ -1 +1 @@
#include <utils.h>
#include "utils.h"

View File

@ -1 +1 @@
#include <windowborderpainter.h>
#include "windowborderpainter.h"

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,19 +24,17 @@
#pragma once
#include "framelesshelpercore_global.h"
#include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <memory>
#if FRAMELESSHELPER_CONFIG(titlebar)
FRAMELESSHELPER_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcChromePalette)
class ChromePalettePrivate;
class FRAMELESSHELPER_CORE_API ChromePalette : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(ChromePalette)
Q_DISABLE_COPY_MOVE(ChromePalette)
FRAMELESSHELPER_PUBLIC_QT_CLASS(ChromePalette)
Q_PROPERTY(QColor titleBarActiveBackgroundColor READ titleBarActiveBackgroundColor
WRITE setTitleBarActiveBackgroundColor RESET resetTitleBarActiveBackgroundColor
@ -119,11 +117,8 @@ Q_SIGNALS:
void closeButtonPressColorChanged();
void titleBarColorChanged();
void chromeButtonColorChanged();
private:
QScopedPointer<ChromePalettePrivate> d_ptr;
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(ChromePalette))
#endif

View File

@ -0,0 +1,526 @@
/*
* MIT License
*
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#pragma once
#include <FramelessHelper/Core/framelesshelpercore_global.h>
/*
* Copyright (C) 2001-2006 Bart Massey, Jamey Sharp, and Josh Triplett.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the names of the authors or their
* institutions shall not be used in advertising or otherwise to promote the
* sale, use or other dealings in this Software without prior written
* authorization from the authors.
*/
// This one is not included in any public headers.
using Display = struct _XDisplay;
#if 0 // Causes segfault
#ifndef FRAMELESSHELPER_HAS_XLIB
extern "C"
{
FRAMELESSHELPER_CORE_API int
XInitThreads(
void
);
} // extern "C"
#endif // FRAMELESSHELPER_HAS_XLIB
#endif
#if __has_include(<xcb/xcb.h>)
# include <xcb/xcb.h>
# define FRAMELESSHELPER_HAS_XCB
#else // !__has_include(<xcb/xcb.h>)
using xcb_connection_t = struct xcb_connection_t;
using xcb_button_t = uint8_t;
using xcb_window_t = uint32_t;
using xcb_timestamp_t = uint32_t;
using xcb_atom_t = uint32_t;
using xcb_generic_error_t = struct xcb_generic_error_t
{
uint8_t response_type;
uint8_t error_code;
uint16_t sequence;
uint32_t resource_id;
uint16_t minor_code;
uint8_t major_code;
uint8_t pad0;
uint32_t pad[5];
uint32_t full_sequence;
};
using xcb_client_message_data_t = union xcb_client_message_data_t
{
uint8_t data8[20];
uint16_t data16[10];
uint32_t data32[5];
};
using xcb_button_press_event_t = struct xcb_button_press_event_t
{
uint8_t response_type;
xcb_button_t detail;
uint16_t sequence;
xcb_timestamp_t time;
xcb_window_t root;
xcb_window_t event;
xcb_window_t child;
int16_t root_x;
int16_t root_y;
int16_t event_x;
int16_t event_y;
uint16_t state;
uint8_t same_screen;
uint8_t pad0;
};
using xcb_button_release_event_t = xcb_button_press_event_t;
using xcb_void_cookie_t = struct xcb_void_cookie_t
{
unsigned int sequence;
};
using xcb_intern_atom_cookie_t = struct xcb_intern_atom_cookie_t
{
unsigned int sequence;
};
using xcb_intern_atom_reply_t = struct xcb_intern_atom_reply_t
{
uint8_t response_type;
uint8_t pad0;
uint16_t sequence;
uint32_t length;
xcb_atom_t atom;
};
using xcb_client_message_event_t = struct xcb_client_message_event_t
{
uint8_t response_type;
uint8_t format;
uint16_t sequence;
xcb_window_t window;
xcb_atom_t type;
xcb_client_message_data_t data;
};
using xcb_get_property_reply_t = struct xcb_get_property_reply_t
{
uint8_t response_type;
uint8_t format;
uint16_t sequence;
uint32_t length;
xcb_atom_t type;
uint32_t bytes_after;
uint32_t value_len;
uint8_t pad0[12];
};
using xcb_get_property_cookie_t = struct xcb_get_property_cookie_t
{
unsigned int sequence;
};
using xcb_list_properties_cookie_t = struct xcb_list_properties_cookie_t
{
unsigned int sequence;
};
using xcb_list_properties_reply_t = struct xcb_list_properties_reply_t
{
uint8_t response_type;
uint8_t pad0;
uint16_t sequence;
uint32_t length;
uint16_t atoms_len;
uint8_t pad1[22];
};
[[maybe_unused]] inline constexpr const auto XCB_NONE = 0;
[[maybe_unused]] inline constexpr const auto XCB_WINDOW_NONE = 0;
[[maybe_unused]] inline constexpr const auto XCB_CURRENT_TIME = 0;
[[maybe_unused]] inline constexpr const auto XCB_PROP_MODE_REPLACE = 0;
[[maybe_unused]] inline constexpr const auto XCB_ATOM_ATOM = 4;
[[maybe_unused]] inline constexpr const auto XCB_ATOM_CARDINAL = 6;
[[maybe_unused]] inline constexpr const auto XCB_ATOM_WINDOW = 33;
[[maybe_unused]] inline constexpr const auto XCB_BUTTON_INDEX_ANY = 0;
[[maybe_unused]] inline constexpr const auto XCB_BUTTON_INDEX_1 = 1;
[[maybe_unused]] inline constexpr const auto XCB_BUTTON_INDEX_2 = 2;
[[maybe_unused]] inline constexpr const auto XCB_BUTTON_INDEX_3 = 3;
[[maybe_unused]] inline constexpr const auto XCB_BUTTON_RELEASE = 5;
[[maybe_unused]] inline constexpr const auto XCB_CLIENT_MESSAGE = 33;
[[maybe_unused]] inline constexpr const auto XCB_EVENT_MASK_STRUCTURE_NOTIFY = 131072;
[[maybe_unused]] inline constexpr const auto XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT = 1048576;
[[maybe_unused]] inline constexpr const auto XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY = 524288;
#endif // __has_include(<xcb/xcb.h>)
[[maybe_unused]] inline constexpr const auto _NET_WM_MOVERESIZE_SIZE_TOPLEFT = 0;
[[maybe_unused]] inline constexpr const auto _NET_WM_MOVERESIZE_SIZE_TOP = 1;
[[maybe_unused]] inline constexpr const auto _NET_WM_MOVERESIZE_SIZE_TOPRIGHT = 2;
[[maybe_unused]] inline constexpr const auto _NET_WM_MOVERESIZE_SIZE_RIGHT = 3;
[[maybe_unused]] inline constexpr const auto _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT = 4;
[[maybe_unused]] inline constexpr const auto _NET_WM_MOVERESIZE_SIZE_BOTTOM = 5;
[[maybe_unused]] inline constexpr const auto _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT = 6;
[[maybe_unused]] inline constexpr const auto _NET_WM_MOVERESIZE_SIZE_LEFT = 7;
[[maybe_unused]] inline constexpr const auto _NET_WM_MOVERESIZE_MOVE = 8;
[[maybe_unused]] inline constexpr const auto _NET_WM_MOVERESIZE_SIZE_KEYBOARD = 9;
[[maybe_unused]] inline constexpr const auto _NET_WM_MOVERESIZE_MOVE_KEYBOARD = 10;
[[maybe_unused]] inline constexpr const auto _NET_WM_MOVERESIZE_CANCEL = 11;
[[maybe_unused]] inline constexpr const char ATOM_NET_SUPPORTED[] = "_NET_SUPPORTED";
[[maybe_unused]] inline constexpr const char ATOM_NET_WM_NAME[] = "_NET_WM_NAME";
[[maybe_unused]] inline constexpr const char ATOM_NET_WM_MOVERESIZE[] = "_NET_WM_MOVERESIZE";
[[maybe_unused]] inline constexpr const char ATOM_NET_SUPPORTING_WM_CHECK[] = "_NET_SUPPORTING_WM_CHECK";
[[maybe_unused]] inline constexpr const char ATOM_NET_KDE_COMPOSITE_TOGGLING[] = "_NET_KDE_COMPOSITE_TOGGLING";
[[maybe_unused]] inline constexpr const char ATOM_KDE_NET_WM_BLUR_BEHIND_REGION[] = "_KDE_NET_WM_BLUR_BEHIND_REGION";
[[maybe_unused]] inline constexpr const char ATOM_GTK_SHOW_WINDOW_MENU[] = "_GTK_SHOW_WINDOW_MENU";
[[maybe_unused]] inline constexpr const char ATOM_DEEPIN_NO_TITLEBAR[] = "_DEEPIN_NO_TITLEBAR";
[[maybe_unused]] inline constexpr const char ATOM_DEEPIN_FORCE_DECORATE[] = "_DEEPIN_FORCE_DECORATE";
[[maybe_unused]] inline constexpr const char ATOM_NET_WM_DEEPIN_BLUR_REGION_MASK[] = "_NET_WM_DEEPIN_BLUR_REGION_MASK";
[[maybe_unused]] inline constexpr const char ATOM_NET_WM_DEEPIN_BLUR_REGION_ROUNDED[] = "_NET_WM_DEEPIN_BLUR_REGION_ROUNDED";
[[maybe_unused]] inline constexpr const char ATOM_UTF8_STRING[] = "UTF8_STRING";
#ifndef FRAMELESSHELPER_HAS_XCB
extern "C"
{
FRAMELESSHELPER_CORE_API xcb_void_cookie_t
xcb_send_event(
xcb_connection_t *connection,
uint8_t propagate,
xcb_window_t destination,
uint32_t event_mask,
const char *event
);
FRAMELESSHELPER_CORE_API int
xcb_flush(
xcb_connection_t *connection
);
FRAMELESSHELPER_CORE_API xcb_intern_atom_cookie_t
xcb_intern_atom(
xcb_connection_t *connection,
uint8_t only_if_exists,
uint16_t name_len,
const char *name
);
FRAMELESSHELPER_CORE_API xcb_intern_atom_reply_t *
xcb_intern_atom_reply(
xcb_connection_t *connection,
xcb_intern_atom_cookie_t cookie,
xcb_generic_error_t **error
);
FRAMELESSHELPER_CORE_API xcb_void_cookie_t
xcb_ungrab_pointer(
xcb_connection_t *connection,
xcb_timestamp_t time
);
FRAMELESSHELPER_CORE_API xcb_void_cookie_t
xcb_change_property(
xcb_connection_t *connection,
uint8_t mode,
xcb_window_t window,
xcb_atom_t property,
xcb_atom_t type,
uint8_t format,
uint32_t data_len,
const void *data
);
FRAMELESSHELPER_CORE_API xcb_void_cookie_t
xcb_delete_property_checked(
xcb_connection_t *connection,
xcb_window_t window,
xcb_atom_t property
);
FRAMELESSHELPER_CORE_API xcb_get_property_cookie_t
xcb_get_property(
xcb_connection_t *connection,
uint8_t _delete,
xcb_window_t window,
xcb_atom_t property,
xcb_atom_t type,
uint32_t long_offset,
uint32_t long_length
);
FRAMELESSHELPER_CORE_API xcb_get_property_reply_t *
xcb_get_property_reply(
xcb_connection_t *connection,
xcb_get_property_cookie_t cookie,
xcb_generic_error_t **error
);
FRAMELESSHELPER_CORE_API void *
xcb_get_property_value(
const xcb_get_property_reply_t *reply
);
FRAMELESSHELPER_CORE_API int
xcb_get_property_value_length(
const xcb_get_property_reply_t *reply
);
FRAMELESSHELPER_CORE_API xcb_list_properties_cookie_t
xcb_list_properties(
xcb_connection_t *connection,
xcb_window_t window
);
FRAMELESSHELPER_CORE_API xcb_list_properties_reply_t *
xcb_list_properties_reply(
xcb_connection_t *connection,
xcb_list_properties_cookie_t cookie,
xcb_generic_error_t **error
);
FRAMELESSHELPER_CORE_API int
xcb_list_properties_atoms_length(
const xcb_list_properties_reply_t *atom
);
FRAMELESSHELPER_CORE_API xcb_atom_t *
xcb_list_properties_atoms(
const xcb_list_properties_reply_t *atom
);
FRAMELESSHELPER_CORE_API xcb_get_property_cookie_t
xcb_get_property_unchecked(
xcb_connection_t *connection,
uint8_t _delete,
xcb_window_t window,
xcb_atom_t property,
xcb_atom_t type,
uint32_t long_offset,
uint32_t long_length
);
} // extern "C"
#endif // FRAMELESSHELPER_HAS_XCB
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#if __has_include(<gtk/gtk.h>)
# undef signals // Workaround a compilation issue caused by GTK.
# include <gtk/gtk.h>
# define FRAMELESSHELPER_HAS_GTK
#else // !__has_include(<gtk/gtk.h>)
#define G_VALUE_INIT { 0, { { 0 } } }
#define g_signal_connect(instance, detailed_signal, c_handler, data) \
g_signal_connect_data((instance), (detailed_signal), (c_handler), (data), nullptr, G_CONNECT_DEFAULT)
using gint = int;
using glong = long;
using gshort = short;
using gboolean = int;
using gushort = unsigned short;
using guint = unsigned int;
using gulong = unsigned long;
using gfloat = float;
using gdouble = double;
using gchar = char;
using guchar = unsigned char;
using gchararray = char *;
using gpointer = void *;
using gint64 = signed long;
using guint64 = unsigned long;
using gsize = unsigned int;
using GType = unsigned long; // TODO: or unsigned int?
using GValue = struct _GValue;
using GObject = struct _GObject;
using GClosure = struct _GClosure;
using GtkSettings = struct _GtkSettings;
using GConnectFlags = enum GConnectFlags
{
G_CONNECT_DEFAULT = 0,
G_CONNECT_AFTER = 1 << 0,
G_CONNECT_SWAPPED = 1 << 1
};
using GCallback = void(*)(void);
using GClosureNotify = void(*)(gpointer data, GClosure *closure);
struct _GValue
{
GType g_type;
union
{
gint v_int;
guint v_uint;
glong v_long;
gulong v_ulong;
gint64 v_int64;
guint64 v_uint64;
gfloat v_float;
gdouble v_double;
gpointer v_pointer;
} data[2];
};
#endif // __has_include(<gtk/gtk.h>)
[[maybe_unused]] inline constexpr const char GTK_THEME_NAME_ENV_VAR[] = "GTK_THEME";
[[maybe_unused]] inline constexpr const char GTK_THEME_NAME_PROP[] = "gtk-theme-name";
[[maybe_unused]] inline constexpr const char GTK_THEME_PREFER_DARK_PROP[] = "gtk-application-prefer-dark-theme";
#ifndef FRAMELESSHELPER_HAS_GTK
extern "C"
{
FRAMELESSHELPER_CORE_API void
gtk_init(
int *argc,
char ***argv
);
FRAMELESSHELPER_CORE_API GValue *
g_value_init(
GValue *value,
GType g_type
);
FRAMELESSHELPER_CORE_API GValue *
g_value_reset(
GValue *value
);
FRAMELESSHELPER_CORE_API void
g_value_unset(
GValue *value
);
FRAMELESSHELPER_CORE_API gboolean
g_value_get_boolean(
const GValue *value
);
FRAMELESSHELPER_CORE_API const gchar *
g_value_get_string(
const GValue *value
);
FRAMELESSHELPER_CORE_API GtkSettings *
gtk_settings_get_default(
void
);
FRAMELESSHELPER_CORE_API void
g_object_get_property(
GObject *object,
const gchar *property_name,
GValue *value
);
FRAMELESSHELPER_CORE_API gulong
g_signal_connect_data(
gpointer instance,
const gchar *detailed_signal,
GCallback c_handler,
gpointer data,
GClosureNotify destroy_data,
GConnectFlags connect_flags
);
FRAMELESSHELPER_CORE_API void
g_free(
gpointer mem
);
FRAMELESSHELPER_CORE_API void
g_object_unref(
GObject *object
);
FRAMELESSHELPER_CORE_API void
g_clear_object(
GObject **object_ptr
);
} // extern "C"
#endif // FRAMELESSHELPER_HAS_GTK
FRAMELESSHELPER_BEGIN_NAMESPACE
template<typename T>
[[nodiscard]] T gtkSettings(const gchar *property);
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
using x11_return_type = quint32;
#else // (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
using x11_return_type = unsigned long;
#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
FRAMELESSHELPER_END_NAMESPACE

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,23 +24,24 @@
#pragma once
#include "framelesshelpercore_global.h"
#include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <memory>
#if !FRAMELESSHELPER_CONFIG(native_impl)
FRAMELESSHELPER_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcFramelessHelperQt)
class FramelessHelperQtPrivate;
class FRAMELESSHELPER_CORE_API FramelessHelperQt : public QObject
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(FramelessHelperQt)
FRAMELESSHELPER_PUBLIC_QT_CLASS(FramelessHelperQt)
public:
explicit FramelessHelperQt(QObject *parent = nullptr);
~FramelessHelperQt() override;
static void addWindow(const Global::SystemParameters &params);
static void removeWindow(const WId windowId);
static void addWindow(const QObject *window);
static void removeWindow(const QObject *window);
protected:
Q_NODISCARD bool eventFilter(QObject *object, QEvent *event) override;
@ -48,4 +49,4 @@ protected:
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessHelperQt))
#endif // !native_impl

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,27 +24,31 @@
#pragma once
#include "framelesshelpercore_global.h"
#include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <QtCore/qabstractnativeeventfilter.h>
#ifdef Q_OS_WINDOWS
#if FRAMELESSHELPER_CONFIG(native_impl)
FRAMELESSHELPER_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcFramelessHelperWin)
class FRAMELESSHELPER_CORE_API FramelessHelperWin : public QAbstractNativeEventFilter
{
Q_DISABLE_COPY_MOVE(FramelessHelperWin)
FRAMELESSHELPER_CLASS(FramelessHelperWin)
public:
explicit FramelessHelperWin();
~FramelessHelperWin() override;
static void addWindow(const Global::SystemParameters &params);
static void removeWindow(const WId windowId);
static void addWindow(const QObject *window);
static void removeWindow(const QObject *window);
Q_NODISCARD bool nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result) override;
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessHelperWin))
#endif // native_impl
#endif // Q_OS_WINDOWS

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,71 +24,87 @@
#pragma once
#include "framelesshelper.config"
#include <QtCore/qglobal.h>
#include <QtCore/qmath.h>
#include <QtCore/qpoint.h>
#include <QtCore/qsize.h>
#include <QtCore/qrect.h>
#include <QtCore/qobject.h>
#include <QtCore/qpointer.h>
#include <QtCore/qloggingcategory.h>
#include <QtGui/qcolor.h>
#include <QtGui/qwindowdefs.h>
#include <functional>
#include <optional>
#include <memory>
#include <cmath>
QT_BEGIN_NAMESPACE
class QScreen;
class QEvent;
class QEnterEvent;
QT_END_NAMESPACE
/*
The FRAMELESSHELPER_CONFIG macro implements a safe compile time check for features of FramelessHelper.
Features can be in three states:
0 or undefined: This will lead to a compile error when testing for it
-1: The feature is not available
1: The feature is available
*/
#ifndef FRAMELESSHELPER_CONFIG
# define FRAMELESSHELPER_CONFIG(feature) ((1 / FRAMELESSHELPER_FEATURE_##feature) == 1)
#endif
#ifndef FRAMELESSHELPER_CORE_API
# ifdef FRAMELESSHELPER_CORE_STATIC
# if FRAMELESSHELPER_CONFIG(static_build)
# define FRAMELESSHELPER_CORE_API
# else // FRAMELESSHELPER_CORE_STATIC
# else // !FRAMELESSHELPER_CORE_STATIC
# ifdef FRAMELESSHELPER_CORE_LIBRARY
# define FRAMELESSHELPER_CORE_API Q_DECL_EXPORT
# else // FRAMELESSHELPER_CORE_LIBRARY
# else // !FRAMELESSHELPER_CORE_LIBRARY
# define FRAMELESSHELPER_CORE_API Q_DECL_IMPORT
# endif // FRAMELESSHELPER_CORE_LIBRARY
# endif // FRAMELESSHELPER_CORE_STATIC
#endif // FRAMELESSHELPER_CORE_API
#if (defined(Q_OS_WIN) && !defined(Q_OS_WINDOWS))
# define Q_OS_WINDOWS // Since 5.14
#endif
#if defined(Q_OS_WIN) && !defined(Q_OS_WINDOWS)
# define Q_OS_WINDOWS
#endif
#ifndef Q_DISABLE_COPY_MOVE
# define Q_DISABLE_COPY_MOVE(Class) \
Q_DISABLE_COPY(Class) \
#ifndef Q_DISABLE_MOVE
# define Q_DISABLE_MOVE(Class) \
Class(Class &&) = delete; \
Class &operator=(Class &&) = delete;
#endif
#if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0))
# define qAsConst(i) std::as_const(i)
#ifndef Q_DISABLE_COPY_MOVE // Since 5.13
# define Q_DISABLE_COPY_MOVE(Class) \
Q_DISABLE_COPY(Class) \
Q_DISABLE_MOVE(Class)
#endif
#if (QT_VERSION < QT_VERSION_CHECK(5, 10, 0))
using QStringView = const QString &;
#else
# include <QtCore/qstringview.h>
#endif
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
# define qExchange(a, b) std::exchange(a, b)
#endif
#ifndef Q_NAMESPACE_EXPORT // Since 5.14
# define Q_NAMESPACE_EXPORT(...) Q_NAMESPACE
#endif
// QColor can't be constexpr before 5.14
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
# define Q_COLOR_CONSTEXPR constexpr
#else
# define Q_COLOR_CONSTEXPR
#endif
// MOC can't handle C++ attributes before 5.15.
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
# define Q_NODISCARD [[nodiscard]]
# define Q_MAYBE_UNUSED [[maybe_unused]]
# define Q_CONSTEXPR2 constexpr
#else
# define Q_NODISCARD
# define Q_MAYBE_UNUSED
# define Q_CONSTEXPR2
#endif
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
@ -99,20 +115,23 @@ QT_END_NAMESPACE
using QT_ENTER_EVENT_TYPE = QEvent;
#endif
#ifndef Q_DECLARE_METATYPE2
# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
# define Q_DECLARE_METATYPE2 Q_DECLARE_METATYPE
# else
# define Q_DECLARE_METATYPE2(Type)
# endif
// QLatin1StringView can't be constexpr until Qt6?
#if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
# define Q_STRING_CONSTEXPR constexpr
#else
# define Q_STRING_CONSTEXPR
#endif
#ifndef QUtf8String
# define QUtf8String(str) QString::fromUtf8(str)
#endif
#ifndef Q_GADGET_EXPORT // Since 6.3
# define Q_GADGET_EXPORT(...) Q_GADGET
#endif
#if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
using namespace Qt::StringLiterals;
using namespace Qt::Literals::StringLiterals;
#endif
#ifndef FRAMELESSHELPER_BYTEARRAY_LITERAL
@ -135,14 +154,66 @@ QT_END_NAMESPACE
# endif
#endif
#ifndef FRAMELESSHELPER_BYTEARRAY
# define FRAMELESSHELPER_BYTEARRAY(ba) ba
#endif
#ifndef FRAMELESSHELPER_STRING
# if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
# define FRAMELESSHELPER_STRING(str) str##_L1
# else
# define FRAMELESSHELPER_STRING(str) QLatin1String(str)
# endif
#endif
#ifndef FRAMELESSHELPER_STRING_TYPE
# if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
# define FRAMELESSHELPER_STRING_TYPE QLatin1StringView
# else
# define FRAMELESSHELPER_STRING_TYPE QLatin1String
# endif
#endif
#ifndef Q_UNREACHABLE_RETURN // Since 6.5
# define Q_UNREACHABLE_RETURN(...) \
do { \
Q_UNREACHABLE(); \
return __VA_ARGS__; \
} while (false)
#endif
#ifndef FRAMELESSHELPER_QUOTE
# define FRAMELESSHELPER_QUOTE(x) #x
#endif
#ifndef FRAMELESSHELPER_QUOTE2
# define FRAMELESSHELPER_QUOTE2(x) FRAMELESSHELPER_QUOTE(x)
#endif
#ifndef FRAMELESSHELPER_CONCAT
# define FRAMELESSHELPER_CONCAT(a, b) a##b
#endif
#ifndef FRAMELESSHELPER_CONCAT2
# define FRAMELESSHELPER_CONCAT2(a, b) FRAMELESSHELPER_CONCAT(a, b)
#endif
#ifndef FRAMELESSHELPER_REQUIRE_CONFIG
# define FRAMELESSHELPER_REQUIRE_CONFIG(feature) static_assert(FRAMELESSHELPER_FEATURE_##feature == 1, "Required feature " #feature " for file " __FILE__ " is not available!");
#endif
#ifndef FRAMELESSHELPER_CLASS_INFO
# define FRAMELESSHELPER_CLASS_INFO Q_CLASSINFO("__FRAMELESSHELPER__", FRAMELESSHELPER_QUOTE2(__FRAMELESSHELPER__))
#endif
#ifndef FRAMELESSHELPER_BYTEARRAY_CONSTANT2
# define FRAMELESSHELPER_BYTEARRAY_CONSTANT2(name, ba) \
[[maybe_unused]] static const auto k##name = FRAMELESSHELPER_BYTEARRAY_LITERAL(ba);
[[maybe_unused]] static constexpr const auto k##name = FRAMELESSHELPER_BYTEARRAY(ba);
#endif
#ifndef FRAMELESSHELPER_STRING_CONSTANT2
# define FRAMELESSHELPER_STRING_CONSTANT2(name, str) \
[[maybe_unused]] static const auto k##name = FRAMELESSHELPER_STRING_LITERAL(str);
[[maybe_unused]] static Q_STRING_CONSTEXPR const auto k##name = FRAMELESSHELPER_STRING(str);
#endif
#ifndef FRAMELESSHELPER_BYTEARRAY_CONSTANT
@ -174,29 +245,112 @@ QT_END_NAMESPACE
#endif
#ifndef FRAMELESSHELPER_MAKE_VERSION
# define FRAMELESSHELPER_MAKE_VERSION(Major, Minor, Patch, Tweak) \
((((Major) & 0xff) << 24) | (((Minor) & 0xff) << 16) | (((Patch) & 0xff) << 8) | ((Tweak) & 0xff))
# define FRAMELESSHELPER_MAKE_VERSION(Major, Minor, Patch) \
((((Major) & 0xff) << 24) | (((Minor) & 0xff) << 16) | (((Patch) & 0xff) << 8))
#endif
#ifndef FRAMELESSHELPER_EXTRACT_VERSION
# define FRAMELESSHELPER_EXTRACT_VERSION(Version, Major, Minor, Patch, Tweak) \
# define FRAMELESSHELPER_EXTRACT_VERSION(Version, Major, Minor, Patch) \
{ \
(Major) = (((Version) & 0xff) >> 24); \
(Minor) = (((Version) & 0xff) >> 16); \
(Patch) = (((Version) & 0xff) >> 8); \
(Tweak) = ((Version) & 0xff); \
}
#endif
#ifndef FRAMELESSHELPER_CLASS
# define FRAMELESSHELPER_CLASS(Class) \
private: \
Q_DISABLE_COPY(Class)
#endif
#ifndef FRAMELESSHELPER_CLASS_DPTR
# define FRAMELESSHELPER_CLASS_DPTR(Class) \
private: \
Q_DECLARE_PRIVATE(Class) \
const std::unique_ptr<Class##Private> d_ptr;
#endif
#ifndef FRAMELESSHELPER_CLASS_QPTR
# define FRAMELESSHELPER_CLASS_QPTR(Class) \
private: \
Q_DECLARE_PUBLIC(Class) \
public: \
Class *q_ptr = nullptr;
#endif
#ifndef FRAMELESSHELPER_PRIVATE_CLASS_GETTER
# define FRAMELESSHELPER_PRIVATE_CLASS_GETTER(Class) \
public: \
Q_NODISCARD static Class##Private *get(Class *q); \
Q_NODISCARD static const Class##Private *get(const Class *q);
#endif
#ifndef FRAMELESSHELPER_PRIVATE_CLASS_GETTER_IMPL
# define FRAMELESSHELPER_PRIVATE_CLASS_GETTER_IMPL(Class) \
Class##Private *Class##Private::get(Class *q) { \
Q_ASSERT(q); \
return (q ? q->d_func() : nullptr); \
} \
const Class##Private *Class##Private::get(const Class *q) { \
Q_ASSERT(q); \
return (q ? q->d_func() : nullptr); \
}
#endif
#ifndef FRAMELESSHELPER_PUBLIC_CLASS
# define FRAMELESSHELPER_PUBLIC_CLASS(Class) \
private: \
FRAMELESSHELPER_CLASS(Class) \
FRAMELESSHELPER_CLASS_DPTR(Class)
#endif
#ifndef FRAMELESSHELPER_PRIVATE_CLASS
# define FRAMELESSHELPER_PRIVATE_CLASS(Class) \
private: \
FRAMELESSHELPER_CLASS(Class##Private) \
FRAMELESSHELPER_CLASS_QPTR(Class) \
FRAMELESSHELPER_PRIVATE_CLASS_GETTER(Class)
#endif
#ifndef FRAMELESSHELPER_QT_CLASS
# define FRAMELESSHELPER_QT_CLASS(Class) \
private: \
Q_OBJECT \
FRAMELESSHELPER_CLASS_INFO \
FRAMELESSHELPER_CLASS(Class)
#endif
#ifndef FRAMELESSHELPER_PUBLIC_QT_CLASS
# define FRAMELESSHELPER_PUBLIC_QT_CLASS(Class) \
private: \
FRAMELESSHELPER_QT_CLASS(Class) \
FRAMELESSHELPER_CLASS_DPTR(Class)
#endif
#ifndef FRAMELESSHELPER_PRIVATE_QT_CLASS
# define FRAMELESSHELPER_PRIVATE_QT_CLASS(Class) \
private: \
FRAMELESSHELPER_QT_CLASS(Class##Private) \
FRAMELESSHELPER_CLASS_QPTR(Class) \
FRAMELESSHELPER_PRIVATE_CLASS_GETTER(Class)
#endif
#if FRAMELESSHELPER_CONFIG(bundle_resource)
// Call this function in your main() function if you are using FramelessHelper as a static library,
// it can make sure the resources bundled in the static library are correctly initialized.
// NOTE: This function is intentionally not inside any namespaces.
FRAMELESSHELPER_CORE_API void FramelessHelperCoreInitResource();
inline void framelesshelpercore_initResource() { FramelessHelperCoreInitResource(); }
#endif // FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE
FRAMELESSHELPER_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcCoreGlobal)
#include "framelesshelper.version"
#include <framelesshelper.version>
[[maybe_unused]] inline constexpr const int FRAMELESSHELPER_VERSION =
FRAMELESSHELPER_MAKE_VERSION(FRAMELESSHELPER_VERSION_MAJOR, FRAMELESSHELPER_VERSION_MINOR,
FRAMELESSHELPER_VERSION_PATCH, FRAMELESSHELPER_VERSION_TWEAK);
#ifndef __FRAMELESSHELPER__
# define __FRAMELESSHELPER__ __FRAMELESSHELPER_VERSION__
#endif // __FRAMELESSHELPER__
namespace Global
{
@ -210,181 +364,196 @@ Q_NAMESPACE_EXPORT(FRAMELESSHELPER_CORE_API)
[[maybe_unused]] inline constexpr const int kDefaultWindowFrameBorderThickness = 1;
[[maybe_unused]] inline constexpr const int kDefaultTitleBarFontPointSize = 11;
[[maybe_unused]] inline constexpr const int kDefaultTitleBarContentsMargin = 10;
[[maybe_unused]] inline constexpr const int kMacOSChromeButtonAreaWidth = 60;
[[maybe_unused]] inline constexpr const QSize kDefaultWindowIconSize = {16, 16};
// We have to use "qRound()" here because "std::round()" is not constexpr, yet.
[[maybe_unused]] inline constexpr const QSize kDefaultSystemButtonSize = {qRound(qreal(kDefaultTitleBarHeight) * 1.5), kDefaultTitleBarHeight};
[[maybe_unused]] inline constexpr const QSize kDefaultSystemButtonIconSize = kDefaultWindowIconSize;
[[maybe_unused]] inline constexpr const QSize kDefaultWindowSize = {160, 160}; // Value taken from QPA.
[[maybe_unused]] inline constexpr const QSize kDefaultWindowSize = {160, 160}; // Value taken from Windows QPA.
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
# define kDefaultBlackColor QColorConstants::Black
# define kDefaultWhiteColor QColorConstants::White
# define kDefaultBlackColor QColorConstants::Black
# define kDefaultTransparentColor QColorConstants::Transparent
# define kDefaultLightGrayColor QColorConstants::LightGray
# define kDefaultDarkGrayColor QColorConstants::DarkGray
#else // (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
[[maybe_unused]] inline Q_CONSTEXPR2 const QColor kDefaultBlackColor = {0, 0, 0}; // #000000
[[maybe_unused]] inline Q_CONSTEXPR2 const QColor kDefaultWhiteColor = {255, 255, 255}; // #FFFFFF
[[maybe_unused]] inline Q_CONSTEXPR2 const QColor kDefaultTransparentColor = {0, 0, 0, 0};
[[maybe_unused]] inline Q_CONSTEXPR2 const QColor kDefaultDarkGrayColor = {169, 169, 169}; // #A9A9A9
[[maybe_unused]] inline Q_COLOR_CONSTEXPR const QColor kDefaultWhiteColor = {255, 255, 255}; // #FFFFFF
[[maybe_unused]] inline Q_COLOR_CONSTEXPR const QColor kDefaultBlackColor = {0, 0, 0}; // #000000
[[maybe_unused]] inline Q_COLOR_CONSTEXPR const QColor kDefaultTransparentColor = {0, 0, 0, 0};
[[maybe_unused]] inline Q_COLOR_CONSTEXPR const QColor kDefaultLightGrayColor = {211, 211, 211}; // #D3D3D3
[[maybe_unused]] inline Q_COLOR_CONSTEXPR const QColor kDefaultDarkGrayColor = {169, 169, 169}; // #A9A9A9
#endif // (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
[[maybe_unused]] inline Q_CONSTEXPR2 const QColor kDefaultSystemLightColor = {240, 240, 240}; // #F0F0F0
[[maybe_unused]] inline Q_CONSTEXPR2 const QColor kDefaultSystemDarkColor = {32, 32, 32}; // #202020
[[maybe_unused]] inline Q_CONSTEXPR2 const QColor kDefaultFrameBorderActiveColor = {77, 77, 77}; // #4D4D4D
[[maybe_unused]] inline Q_CONSTEXPR2 const QColor kDefaultFrameBorderInactiveColorDark = {87, 89, 89}; // #575959
[[maybe_unused]] inline Q_CONSTEXPR2 const QColor kDefaultFrameBorderInactiveColorLight = {166, 166, 166}; // #A6A6A6
[[maybe_unused]] inline Q_CONSTEXPR2 const QColor kDefaultSystemButtonBackgroundColor = {204, 204, 204}; // #CCCCCC
[[maybe_unused]] inline Q_CONSTEXPR2 const QColor kDefaultSystemCloseButtonBackgroundColor = {232, 17, 35}; // #E81123
[[maybe_unused]] inline Q_COLOR_CONSTEXPR const QColor kDefaultSystemLightColor = {240, 240, 240}; // #F0F0F0
[[maybe_unused]] inline Q_COLOR_CONSTEXPR const QColor kDefaultSystemDarkColor = {32, 32, 32}; // #202020
[[maybe_unused]] inline Q_COLOR_CONSTEXPR const QColor kDefaultFrameBorderActiveColorLight = {110, 110, 110}; // #6E6E6E
[[maybe_unused]] inline Q_COLOR_CONSTEXPR const QColor kDefaultFrameBorderActiveColorDark = {51, 51, 51}; // #333333
[[maybe_unused]] inline Q_COLOR_CONSTEXPR const QColor kDefaultFrameBorderInactiveColorLight = {167, 167, 167}; // #A7A7A7
[[maybe_unused]] inline Q_COLOR_CONSTEXPR const QColor kDefaultFrameBorderInactiveColorDark = {61, 61, 62}; // #3D3D3E
[[maybe_unused]] inline Q_COLOR_CONSTEXPR const QColor kDefaultSystemButtonBackgroundColor = {204, 204, 204}; // #CCCCCC
[[maybe_unused]] inline Q_COLOR_CONSTEXPR const QColor kDefaultSystemCloseButtonBackgroundColor = {232, 17, 35}; // #E81123
[[maybe_unused]] inline const QByteArray kDontOverrideCursorVar
= FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_DONT_OVERRIDE_CURSOR");
[[maybe_unused]] inline const QByteArray kDontToggleMaximizeVar
= FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_DONT_TOGGLE_MAXIMIZE");
[[maybe_unused]] inline constexpr const char kDontOverrideCursorVar[] = "FRAMELESSHELPER_DONT_OVERRIDE_CURSOR";
[[maybe_unused]] inline constexpr const char kDontToggleMaximizeVar[] = "FRAMELESSHELPER_DONT_TOGGLE_MAXIMIZE";
[[maybe_unused]] inline constexpr const char kSysMenuDisableMoveVar[] = "FRAMELESSHELPER_SYSTEM_MENU_DISABLE_MOVE";
[[maybe_unused]] inline constexpr const char kSysMenuDisableSizeVar[] = "FRAMELESSHELPER_SYSTEM_MENU_DISABLE_SIZE";
[[maybe_unused]] inline constexpr const char kSysMenuDisableMinimizeVar[] = "FRAMELESSHELPER_SYSTEM_MENU_DISABLE_MINIMIZE";
[[maybe_unused]] inline constexpr const char kSysMenuDisableMaximizeVar[] = "FRAMELESSHELPER_SYSTEM_MENU_DISABLE_MAXIMIZE";
[[maybe_unused]] inline constexpr const char kSysMenuDisableRestoreVar[] = "FRAMELESSHELPER_SYSTEM_MENU_DISABLE_RESTORE";
[[maybe_unused]] inline constexpr const char kSysMenuDisableCloseVar[] = "FRAMELESSHELPER_SYSTEM_MENU_DISABLE_CLOSE";
[[maybe_unused]] inline constexpr const char kSysMenuRemoveMoveVar[] = "FRAMELESSHELPER_SYSTEM_MENU_REMOVE_MOVE";
[[maybe_unused]] inline constexpr const char kSysMenuRemoveSizeVar[] = "FRAMELESSHELPER_SYSTEM_MENU_REMOVE_SIZE";
[[maybe_unused]] inline constexpr const char kSysMenuRemoveMinimizeVar[] = "FRAMELESSHELPER_SYSTEM_MENU_REMOVE_MINIMIZE";
[[maybe_unused]] inline constexpr const char kSysMenuRemoveMaximizeVar[] = "FRAMELESSHELPER_SYSTEM_MENU_REMOVE_MAXIMIZE";
[[maybe_unused]] inline constexpr const char kSysMenuRemoveRestoreVar[] = "FRAMELESSHELPER_SYSTEM_MENU_REMOVE_RESTORE";
[[maybe_unused]] inline constexpr const char kSysMenuRemoveSeparatorVar[] = "FRAMELESSHELPER_SYSTEM_MENU_REMOVE_SEPARATOR";
[[maybe_unused]] inline constexpr const char kSysMenuRemoveCloseVar[] = "FRAMELESSHELPER_SYSTEM_MENU_REMOVE_CLOSE";
enum class Option
enum class Option : quint8
{
UseCrossPlatformQtImplementation = 0,
ForceHideWindowFrameBorder = 1,
ForceShowWindowFrameBorder = 2,
DisableWindowsSnapLayout = 3,
WindowUseRoundCorners = 4,
CenterWindowBeforeShow = 5,
EnableBlurBehindWindow = 6,
ForceNonNativeBackgroundBlur = 7,
DisableLazyInitializationForMicaMaterial = 8
UseCrossPlatformQtImplementation,
ForceHideWindowFrameBorder,
ForceShowWindowFrameBorder,
DisableWindowsSnapLayout,
WindowUseRoundCorners,
CenterWindowBeforeShow,
EnableBlurBehindWindow,
ForceNonNativeBackgroundBlur,
DisableLazyInitializationForMicaMaterial,
ForceNativeBackgroundBlur,
WindowUseSquareCorners,
Last = WindowUseSquareCorners
};
Q_ENUM_NS(Option)
enum class SystemTheme
enum class SystemTheme : quint8
{
Unknown = -1,
Light = 0,
Dark = 1,
HighContrast = 2
Unknown,
Light,
Dark,
HighContrast
};
Q_ENUM_NS(SystemTheme)
enum class SystemButtonType
enum class SystemButtonType : quint8
{
Unknown = -1,
WindowIcon = 0,
Help = 1,
Minimize = 2,
Maximize = 3,
Restore = 4,
Close = 5
Unknown,
WindowIcon,
Help,
Minimize,
Maximize,
Restore,
Close,
Last = Close
};
Q_ENUM_NS(SystemButtonType)
#ifdef Q_OS_WINDOWS
enum class DwmColorizationArea
enum class DwmColorizationArea : quint8
{
None = 0,
StartMenu_TaskBar_ActionCenter = 1,
TitleBar_WindowBorder = 2,
All = 3
None,
StartMenu_TaskBar_ActionCenter,
TitleBar_WindowBorder,
All
};
Q_ENUM_NS(DwmColorizationArea)
#endif // Q_OS_WINDOWS
enum class ButtonState
enum class ButtonState : quint8
{
Unspecified = -1,
Hovered = 0,
Pressed = 1,
Clicked = 2
Normal,
Hovered,
Pressed,
Released
};
Q_ENUM_NS(ButtonState)
#ifdef Q_OS_WINDOWS
enum class WindowsVersion
enum class WindowsVersion : quint8
{
_2000 = 0,
_XP = 1,
_XP_64 = 2,
_2000,
_XP,
_XP_64,
_Vista,
_Vista_SP1,
_Vista_SP2,
_7,
_7_SP1,
_8,
_8_1,
_8_1_Update1,
_10_1507,
_10_1511,
_10_1607,
_10_1703,
_10_1709,
_10_1803,
_10_1809,
_10_1903,
_10_1909,
_10_2004,
_10_20H2,
_10_21H1,
_10_21H2,
_10_22H2,
_11_21H2,
_11_22H2,
_WS_03 = _XP_64, // Windows Server 2003
_Vista = 3,
_Vista_SP1 = 4,
_Vista_SP2 = 5,
_7 = 6,
_7_SP1 = 7,
_8 = 8,
_8_1 = 9,
_8_1_Update1 = 10,
_10_1507 = 11,
_10_1511 = 12,
_10_1607 = 13,
_10_1703 = 14,
_10_1709 = 15,
_10_1803 = 16,
_10_1809 = 17,
_10_1903 = 18,
_10_1909 = 19,
_10_2004 = 20,
_10_20H2 = 21,
_10_21H1 = 22,
_10_21H2 = 23,
_10_22H2 = 24,
_10 = _10_1507,
_11_21H2 = 25,
_11_22H2 = 26,
_11 = _11_21H2,
Latest = _11_22H2
};
Q_ENUM_NS(WindowsVersion)
#endif // Q_OS_WINDOWS
enum class ApplicationType
enum class BlurMode : quint8
{
Widgets = 0, // Pure QtWidgets applications
Quick = 1, // Pure QtQuick applications
Hybrid = 2 // Use both QtWidgets and QtQuick
};
Q_ENUM_NS(ApplicationType)
enum class BlurMode
{
Disable = 0, // Do not enable blur behind window
Default = 1, // Use platform default blur mode
Windows_Aero = 2, // Windows only, use the traditional DWM blur
Windows_Acrylic = 3, // Windows only, use the Acrylic blur
Windows_Mica = 4 // Windows only, use the Mica material
Disable, // Do not enable blur behind window
Default, // Use platform default blur mode
Windows_Aero, // Windows only, use the traditional DWM blur
Windows_Acrylic, // Windows only, use the Acrylic blur
Windows_Mica, // Windows only, use the Mica material
Windows_MicaAlt // Windows only, use the Mica Alt material
};
Q_ENUM_NS(BlurMode)
enum class WallpaperAspectStyle
enum class WallpaperAspectStyle : quint8
{
Fill = 0, // Keep aspect ratio to fill, expand/crop if necessary.
Fit = 1, // Keep aspect ratio to fill, but don't expand/crop.
Stretch = 2, // Ignore aspect ratio to fill.
Tile = 3,
Center = 4,
Span = 5 // ???
Fill, // Keep aspect ratio to fill, expand/crop if necessary.
Fit, // Keep aspect ratio to fill, but don't expand/crop.
Stretch, // Ignore aspect ratio to fill.
Tile,
Center,
Span // ???
};
Q_ENUM_NS(WallpaperAspectStyle)
#ifdef Q_OS_WINDOWS
enum class RegistryRootKey
enum class RegistryRootKey : quint8
{
ClassesRoot = 0,
CurrentUser = 1,
LocalMachine = 2,
Users = 3,
PerformanceData = 4,
CurrentConfig = 5,
DynData = 6,
CurrentUserLocalSettings = 7,
PerformanceText = 8,
PerformanceNlsText = 9
ClassesRoot,
CurrentUser,
LocalMachine,
Users,
PerformanceData,
CurrentConfig,
DynData,
CurrentUserLocalSettings,
PerformanceText,
PerformanceNlsText
};
Q_ENUM_NS(RegistryRootKey)
#endif // Q_OS_WINDOWS
enum class WindowEdge
enum class WindowEdge : quint8
{
Left = 0x00000000,
Top = 0x00000001,
Right = 0x00000002,
Bottom = 0x00000004
Left = 1 << 0,
Top = 1 << 1,
Right = 1 << 2,
Bottom = 1 << 3
};
Q_ENUM_NS(WindowEdge)
Q_DECLARE_FLAGS(WindowEdges, WindowEdge)
@ -392,235 +561,112 @@ Q_FLAG_NS(WindowEdges)
Q_DECLARE_OPERATORS_FOR_FLAGS(WindowEdges)
#ifdef Q_OS_WINDOWS
enum class DpiAwareness
enum class DpiAwareness : quint8
{
Unknown = -1,
Unaware = 0,
System = 1,
PerMonitor = 2,
PerMonitorVersion2 = 3,
Unaware_GdiScaled = 4
Unknown,
Unaware,
System,
PerMonitor,
PerMonitorVersion2,
Unaware_GdiScaled
};
Q_ENUM_NS(DpiAwareness)
#endif // Q_OS_WINDOWS
struct VersionNumber
enum class WindowCornerStyle : quint8
{
int major = 0;
int minor = 0;
int patch = 0;
int tweak = 0;
Default,
Square,
Round
};
Q_ENUM_NS(WindowCornerStyle)
[[nodiscard]] friend constexpr bool operator==(const VersionNumber &lhs, const VersionNumber &rhs) noexcept
struct VersionInfo
{
struct {
unsigned long num = 0;
const char *str = nullptr;
} version = {};
struct {
const char *hash = nullptr;
const char *subject = nullptr;
const char *author = nullptr;
const char *datetime = nullptr;
const char *branch = nullptr;
} commit = {};
struct {
const char *name = nullptr;
const char *version = nullptr;
const char *vendor = nullptr;
} compiler = {};
struct {
const char *cmake_version = nullptr;
const char *configure_datetime = nullptr;
const char *generator = nullptr;
const char *architecture = nullptr;
bool is_debug = false;
bool is_static = false;
} build = {};
};
struct Dpi
{
quint32 x = 0;
quint32 y = 0;
[[nodiscard]] friend constexpr bool operator==(const Dpi &lhs, const Dpi &rhs) noexcept
{
return ((lhs.major == rhs.major) && (lhs.minor == rhs.minor) && (lhs.patch == rhs.patch) && (lhs.tweak == rhs.tweak));
return ((lhs.x == rhs.x) && (lhs.y == rhs.y));
}
[[nodiscard]] friend constexpr bool operator!=(const VersionNumber &lhs, const VersionNumber &rhs) noexcept
[[nodiscard]] friend constexpr bool operator!=(const Dpi &lhs, const Dpi &rhs) noexcept
{
return !operator==(lhs, rhs);
}
[[nodiscard]] friend constexpr bool operator>(const VersionNumber &lhs, const VersionNumber &rhs) noexcept
[[nodiscard]] friend constexpr bool operator>(const Dpi &lhs, const Dpi &rhs) noexcept
{
if (operator==(lhs, rhs)) {
return false;
}
if (lhs.major > rhs.major) {
return true;
}
if (lhs.major < rhs.major) {
return false;
}
if (lhs.minor > rhs.minor) {
return true;
}
if (lhs.minor < rhs.minor) {
return false;
}
if (lhs.patch > rhs.patch) {
return true;
}
if (lhs.patch < rhs.patch) {
return false;
}
return (lhs.tweak > rhs.tweak);
return ((lhs.x * lhs.y) > (rhs.x * rhs.y));
}
[[nodiscard]] friend constexpr bool operator<(const VersionNumber &lhs, const VersionNumber &rhs) noexcept
{
return (operator!=(lhs, rhs) && !operator>(lhs, rhs));
}
[[nodiscard]] friend constexpr bool operator>=(const VersionNumber &lhs, const VersionNumber &rhs) noexcept
[[nodiscard]] friend constexpr bool operator>=(const Dpi &lhs, const Dpi &rhs) noexcept
{
return (operator>(lhs, rhs) || operator==(lhs, rhs));
}
[[nodiscard]] friend constexpr bool operator<=(const VersionNumber &lhs, const VersionNumber &rhs) noexcept
[[nodiscard]] friend constexpr bool operator<(const Dpi &lhs, const Dpi &rhs) noexcept
{
return (operator!=(lhs, rhs) && !operator>(lhs, rhs));
}
[[nodiscard]] friend constexpr bool operator<=(const Dpi &lhs, const Dpi &rhs) noexcept
{
return (operator<(lhs, rhs) || operator==(lhs, rhs));
}
};
using InitializeHookCallback = std::function<void()>;
using UninitializeHookCallback = std::function<void()>;
using GetWindowFlagsCallback = std::function<Qt::WindowFlags()>;
using SetWindowFlagsCallback = std::function<void(const Qt::WindowFlags)>;
using GetWindowSizeCallback = std::function<QSize()>;
using SetWindowSizeCallback = std::function<void(const QSize &)>;
using GetWindowPositionCallback = std::function<QPoint()>;
using SetWindowPositionCallback = std::function<void(const QPoint &)>;
using GetWindowScreenCallback = std::function<QScreen *()>;
using IsWindowFixedSizeCallback = std::function<bool()>;
using SetWindowFixedSizeCallback = std::function<void(const bool)>;
using GetWindowStateCallback = std::function<Qt::WindowState()>;
using SetWindowStateCallback = std::function<void(const Qt::WindowState)>;
using GetWindowHandleCallback = std::function<QWindow *()>;
using WindowToScreenCallback = std::function<QPoint(const QPoint &)>;
using ScreenToWindowCallback = std::function<QPoint(const QPoint &)>;
using IsInsideSystemButtonsCallback = std::function<bool(const QPoint &, SystemButtonType *)>;
using IsInsideTitleBarDraggableAreaCallback = std::function<bool(const QPoint &)>;
using GetWindowDevicePixelRatioCallback = std::function<qreal()>;
using SetSystemButtonStateCallback = std::function<void(const SystemButtonType, const ButtonState)>;
using GetWindowIdCallback = std::function<WId()>;
using ShouldIgnoreMouseEventsCallback = std::function<bool(const QPoint &)>;
using ShowSystemMenuCallback = std::function<void(const QPoint &)>;
using GetCurrentApplicationTypeCallback = std::function<ApplicationType()>;
using SetPropertyCallback = std::function<void(const QByteArray &, const QVariant &)>;
using GetPropertyCallback = std::function<QVariant(const QByteArray &, const QVariant &)>;
using SetCursorCallback = std::function<void(const QCursor &)>;
using UnsetCursorCallback = std::function<void()>;
struct SystemParameters
{
GetWindowFlagsCallback getWindowFlags = nullptr;
SetWindowFlagsCallback setWindowFlags = nullptr;
GetWindowSizeCallback getWindowSize = nullptr;
SetWindowSizeCallback setWindowSize = nullptr;
GetWindowPositionCallback getWindowPosition = nullptr;
SetWindowPositionCallback setWindowPosition = nullptr;
GetWindowScreenCallback getWindowScreen = nullptr;
IsWindowFixedSizeCallback isWindowFixedSize = nullptr;
SetWindowFixedSizeCallback setWindowFixedSize = nullptr;
GetWindowStateCallback getWindowState = nullptr;
SetWindowStateCallback setWindowState = nullptr;
GetWindowHandleCallback getWindowHandle = nullptr;
WindowToScreenCallback windowToScreen = nullptr;
ScreenToWindowCallback screenToWindow = nullptr;
IsInsideSystemButtonsCallback isInsideSystemButtons = nullptr;
IsInsideTitleBarDraggableAreaCallback isInsideTitleBarDraggableArea = nullptr;
GetWindowDevicePixelRatioCallback getWindowDevicePixelRatio = nullptr;
SetSystemButtonStateCallback setSystemButtonState = nullptr;
GetWindowIdCallback getWindowId = nullptr;
ShouldIgnoreMouseEventsCallback shouldIgnoreMouseEvents = nullptr;
ShowSystemMenuCallback showSystemMenu = nullptr;
GetCurrentApplicationTypeCallback getCurrentApplicationType = nullptr;
SetPropertyCallback setProperty = nullptr;
GetPropertyCallback getProperty = nullptr;
SetCursorCallback setCursor = nullptr;
UnsetCursorCallback unsetCursor = nullptr;
[[nodiscard]] inline bool isValid() const
{
Q_ASSERT(getWindowFlags);
Q_ASSERT(setWindowFlags);
Q_ASSERT(getWindowSize);
Q_ASSERT(setWindowSize);
Q_ASSERT(getWindowPosition);
Q_ASSERT(setWindowPosition);
Q_ASSERT(getWindowScreen);
Q_ASSERT(isWindowFixedSize);
Q_ASSERT(setWindowFixedSize);
Q_ASSERT(getWindowState);
Q_ASSERT(setWindowState);
Q_ASSERT(getWindowHandle);
Q_ASSERT(windowToScreen);
Q_ASSERT(screenToWindow);
Q_ASSERT(isInsideSystemButtons);
Q_ASSERT(isInsideTitleBarDraggableArea);
Q_ASSERT(getWindowDevicePixelRatio);
Q_ASSERT(setSystemButtonState);
Q_ASSERT(getWindowId);
Q_ASSERT(shouldIgnoreMouseEvents);
Q_ASSERT(showSystemMenu);
Q_ASSERT(getCurrentApplicationType);
Q_ASSERT(setProperty);
Q_ASSERT(getProperty);
Q_ASSERT(setCursor);
Q_ASSERT(unsetCursor);
return (getWindowFlags && setWindowFlags && getWindowSize
&& setWindowSize && getWindowPosition && setWindowPosition
&& getWindowScreen && isWindowFixedSize && setWindowFixedSize
&& getWindowState && setWindowState && getWindowHandle
&& windowToScreen && screenToWindow && isInsideSystemButtons
&& isInsideTitleBarDraggableArea && getWindowDevicePixelRatio
&& setSystemButtonState && getWindowId && shouldIgnoreMouseEvents
&& showSystemMenu && getCurrentApplicationType && setProperty
&& getProperty && setCursor && unsetCursor);
}
};
#ifdef Q_OS_WINDOWS
[[maybe_unused]] inline constexpr const VersionNumber WindowsVersions[] =
{
{ 5, 0, 2195}, // Windows 2000
{ 5, 1, 2600}, // Windows XP
{ 5, 2, 3790}, // Windows XP x64 Edition or Windows Server 2003
{ 6, 0, 6000}, // Windows Vista
{ 6, 0, 6001}, // Windows Vista with Service Pack 1 or Windows Server 2008
{ 6, 0, 6002}, // Windows Vista with Service Pack 2
{ 6, 1, 7600}, // Windows 7 or Windows Server 2008 R2
{ 6, 1, 7601}, // Windows 7 with Service Pack 1 or Windows Server 2008 R2 with Service Pack 1
{ 6, 2, 9200}, // Windows 8 or Windows Server 2012
{ 6, 3, 9200}, // Windows 8.1 or Windows Server 2012 R2
{ 6, 3, 9600}, // Windows 8.1 with Update 1
{10, 0, 10240}, // Windows 10 Version 1507 (TH1)
{10, 0, 10586}, // Windows 10 Version 1511 (November Update) (TH2)
{10, 0, 14393}, // Windows 10 Version 1607 (Anniversary Update) (RS1) or Windows Server 2016
{10, 0, 15063}, // Windows 10 Version 1703 (Creators Update) (RS2)
{10, 0, 16299}, // Windows 10 Version 1709 (Fall Creators Update) (RS3)
{10, 0, 17134}, // Windows 10 Version 1803 (April 2018 Update) (RS4)
{10, 0, 17763}, // Windows 10 Version 1809 (October 2018 Update) (RS5) or Windows Server 2019
{10, 0, 18362}, // Windows 10 Version 1903 (May 2019 Update) (19H1)
{10, 0, 18363}, // Windows 10 Version 1909 (November 2019 Update) (19H2)
{10, 0, 19041}, // Windows 10 Version 2004 (May 2020 Update) (20H1)
{10, 0, 19042}, // Windows 10 Version 20H2 (October 2020 Update) (20H2)
{10, 0, 19043}, // Windows 10 Version 21H1 (May 2021 Update) (21H1)
{10, 0, 19044}, // Windows 10 Version 21H2 (November 2021 Update) (21H2)
{10, 0, 19045}, // Windows 10 Version 22H2 (October 2022 Update) (22H2)
{10, 0, 22000}, // Windows 11 Version 21H2 (21H2)
{10, 0, 22621} // Windows 11 Version 22H2 (October 2022 Update) (22H2)
};
#endif // Q_OS_WINDOWS
struct VersionInfo
{
const int version = 0;
const char *version_str = nullptr;
const char *commit = nullptr;
const char *compileDateTime = nullptr;
const char *compiler = nullptr;
const bool isDebug = false;
const bool isStatic = false;
};
} // namespace Global
FRAMELESSHELPER_CORE_API void FramelessHelperCoreInitialize();
FRAMELESSHELPER_CORE_API void FramelessHelperCoreUninitialize();
[[nodiscard]] FRAMELESSHELPER_CORE_API Global::VersionInfo FramelessHelperVersion();
FRAMELESSHELPER_CORE_API void FramelessHelperEnableThemeAware();
FRAMELESSHELPER_CORE_API void FramelessHelperPrintLogo();
namespace FramelessHelper::Core
{
FRAMELESSHELPER_CORE_API void initialize();
FRAMELESSHELPER_CORE_API void uninitialize();
[[nodiscard]] FRAMELESSHELPER_CORE_API Global::VersionInfo version();
FRAMELESSHELPER_CORE_API void registerInitializeHook(const Global::InitializeHookCallback &cb);
FRAMELESSHELPER_CORE_API void registerUninitializeHook(const Global::UninitializeHookCallback &cb);
FRAMELESSHELPER_CORE_API void setApplicationOSThemeAware();
FRAMELESSHELPER_CORE_API void outputLogo();
inline void initialize() { FramelessHelperCoreInitialize(); }
inline void uninitialize() { FramelessHelperCoreUninitialize(); }
[[nodiscard]] inline Global::VersionInfo version() { return FramelessHelperVersion(); }
inline void setApplicationOSThemeAware() { FramelessHelperEnableThemeAware(); }
inline void outputLogo() { FramelessHelperPrintLogo(); }
} // namespace FramelessHelper::Core
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(Global)::VersionNumber)
Q_DECLARE_METATYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(Global)::SystemParameters)
Q_DECLARE_METATYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(Global)::VersionInfo)
#ifndef QT_NO_DEBUG_STREAM
QT_BEGIN_NAMESPACE
FRAMELESSHELPER_CORE_API QDebug operator<<(QDebug, const FRAMELESSHELPER_PREPEND_NAMESPACE(Global)::VersionInfo &);
FRAMELESSHELPER_CORE_API QDebug operator<<(QDebug, const FRAMELESSHELPER_PREPEND_NAMESPACE(Global)::Dpi &);
QT_END_NAMESPACE
#endif // QT_NO_DEBUG_STREAM

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,28 +24,21 @@
#pragma once
#include "framelesshelpercore_global.h"
#include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <memory>
FRAMELESSHELPER_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcFramelessManager)
class FramelessManagerPrivate;
class FRAMELESSHELPER_CORE_API FramelessManager : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(FramelessManager)
Q_DISABLE_COPY_MOVE(FramelessManager)
Q_PROPERTY(Global::SystemTheme systemTheme READ systemTheme NOTIFY systemThemeChanged FINAL)
FRAMELESSHELPER_PUBLIC_QT_CLASS(FramelessManager)
Q_PROPERTY(Global::SystemTheme systemTheme READ systemTheme WRITE setOverrideTheme NOTIFY systemThemeChanged FINAL)
Q_PROPERTY(QColor systemAccentColor READ systemAccentColor NOTIFY systemThemeChanged FINAL)
Q_PROPERTY(QString wallpaper READ wallpaper NOTIFY wallpaperChanged FINAL)
Q_PROPERTY(Global::WallpaperAspectStyle wallpaperAspectStyle READ wallpaperAspectStyle NOTIFY wallpaperChanged FINAL)
public:
explicit FramelessManager(QObject *parent = nullptr);
~FramelessManager() override;
Q_NODISCARD static FramelessManager *instance();
Q_NODISCARD Global::SystemTheme systemTheme() const;
@ -54,17 +47,17 @@ public:
Q_NODISCARD Global::WallpaperAspectStyle wallpaperAspectStyle() const;
public Q_SLOTS:
void addWindow(const Global::SystemParameters &params);
void removeWindow(const WId windowId);
Q_NODISCARD bool addWindow(const QObject *window, const WId windowId);
Q_NODISCARD bool removeWindow(const QObject *window);
void setOverrideTheme(const Global::SystemTheme theme);
Q_SIGNALS:
void systemThemeChanged();
void wallpaperChanged();
private:
QScopedPointer<FramelessManagerPrivate> d_ptr;
explicit FramelessManager(QObject *parent = nullptr);
~FramelessManager() override;
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessManager))

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,23 +24,23 @@
#pragma once
#include "framelesshelpercore_global.h"
#include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <memory>
#if FRAMELESSHELPER_CONFIG(mica_material)
FRAMELESSHELPER_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcMicaMaterial)
class MicaMaterialPrivate;
class FRAMELESSHELPER_CORE_API MicaMaterial : public QObject
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(MicaMaterial)
Q_DECLARE_PRIVATE(MicaMaterial)
FRAMELESSHELPER_PUBLIC_QT_CLASS(MicaMaterial)
Q_PROPERTY(QColor tintColor READ tintColor WRITE setTintColor NOTIFY tintColorChanged FINAL)
Q_PROPERTY(qreal tintOpacity READ tintOpacity WRITE setTintOpacity NOTIFY tintOpacityChanged FINAL)
Q_PROPERTY(QColor fallbackColor READ fallbackColor WRITE setFallbackColor NOTIFY fallbackColorChanged FINAL)
Q_PROPERTY(qreal noiseOpacity READ noiseOpacity WRITE setNoiseOpacity NOTIFY noiseOpacityChanged FINAL)
Q_PROPERTY(bool fallbackEnabled READ isFallbackEnabled WRITE setFallbackEnabled NOTIFY fallbackEnabledChanged FINAL)
public:
explicit MicaMaterial(QObject *parent = nullptr);
@ -52,22 +52,33 @@ public:
Q_NODISCARD qreal tintOpacity() const;
void setTintOpacity(const qreal value);
Q_NODISCARD QColor fallbackColor() const;
void setFallbackColor(const QColor &value);
Q_NODISCARD qreal noiseOpacity() const;
void setNoiseOpacity(const qreal value);
Q_NODISCARD bool isFallbackEnabled() const;
void setFallbackEnabled(const bool value);
public Q_SLOTS:
void paint(QPainter *painter, const QSize &size, const QPoint &pos);
void paint(QPainter *painter, const QRect &rect, const bool active = true);
[[deprecated("Use another overload instead.")]]
void paint(QPainter *painter, const QSize &size, const QPoint &pos, const bool active = true)
{
paint(painter, QRect{ pos, size }, active);
}
Q_SIGNALS:
void tintColorChanged();
void tintOpacityChanged();
void fallbackColorChanged();
void noiseOpacityChanged();
void fallbackEnabledChanged();
void shouldRedraw();
private:
QScopedPointer<MicaMaterialPrivate> d_ptr;
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(MicaMaterial))
#endif

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,29 +24,24 @@
#pragma once
#include "framelesshelpercore_global.h"
#include "chromepalette.h"
#include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <optional>
#if FRAMELESSHELPER_CONFIG(titlebar)
FRAMELESSHELPER_BEGIN_NAMESPACE
class ChromePalette;
class FRAMELESSHELPER_CORE_API ChromePalettePrivate : public QObject
{
Q_OBJECT
Q_DECLARE_PUBLIC(ChromePalette)
Q_DISABLE_COPY_MOVE(ChromePalettePrivate)
FRAMELESSHELPER_PRIVATE_QT_CLASS(ChromePalette)
public:
explicit ChromePalettePrivate(ChromePalette *q);
~ChromePalettePrivate() override;
Q_NODISCARD static ChromePalettePrivate *get(ChromePalette *q);
Q_NODISCARD static const ChromePalettePrivate *get(const ChromePalette *q);
Q_SLOT void refresh();
public Q_SLOTS:
void refresh();
private:
QPointer<ChromePalette> q_ptr = nullptr;
// System-defined ones:
QColor titleBarActiveBackgroundColor_sys = {};
QColor titleBarInactiveBackgroundColor_sys = {};
@ -73,4 +68,4 @@ private:
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(ChromePalettePrivate))
#endif

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,20 +24,15 @@
#pragma once
#include "framelesshelpercore_global.h"
#include <QtCore/qvariant.h>
#include <FramelessHelper/Core/framelesshelpercore_global.h>
FRAMELESSHELPER_BEGIN_NAMESPACE
class FRAMELESSHELPER_CORE_API FramelessConfig : public QObject
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(FramelessConfig)
FRAMELESSHELPER_QT_CLASS(FramelessConfig)
public:
explicit FramelessConfig(QObject *parent = nullptr);
~FramelessConfig() override;
Q_NODISCARD static FramelessConfig *instance();
void reload(const bool force = false);
@ -48,19 +43,9 @@ public:
static void setLoadFromEnvironmentVariablesDisabled(const bool on = true);
static void setLoadFromConfigurationFileDisabled(const bool on = true);
Q_NODISCARD QVariant setInternal(const QString &key, const QVariant &value);
Q_NODISCARD QVariant getInternal(const QString &key) const;
template<typename T>
Q_NODISCARD std::optional<T> getInternal(const QString &key) const
{
const QVariant var = getInternal(key);
if (var.isValid()) {
return qvariant_cast<T>(var);
}
return std::nullopt;
}
private:
explicit FramelessConfig(QObject *parent = nullptr);
~FramelessConfig() override;
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessConfig))

View File

@ -0,0 +1,184 @@
/*
* MIT License
*
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#pragma once
#include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <QtCore/qhash.h>
#include <QtGui/qwindowdefs.h>
#include <functional>
#include <memory>
QT_BEGIN_NAMESPACE
class QScreen;
QT_END_NAMESPACE
FRAMELESSHELPER_BEGIN_NAMESPACE
using GetWindowFlagsCallback = std::function<Qt::WindowFlags()>;
using SetWindowFlagsCallback = std::function<void(const Qt::WindowFlags)>;
using GetWindowSizeCallback = std::function<QSize()>;
using SetWindowSizeCallback = std::function<void(const QSize &)>;
using GetWindowPositionCallback = std::function<QPoint()>;
using SetWindowPositionCallback = std::function<void(const QPoint &)>;
using GetWindowScreenCallback = std::function<QScreen *()>;
using IsWindowFixedSizeCallback = std::function<bool()>;
using SetWindowFixedSizeCallback = std::function<void(const bool)>;
using GetWindowStateCallback = std::function<Qt::WindowState()>;
using SetWindowStateCallback = std::function<void(const Qt::WindowState)>;
using GetWindowHandleCallback = std::function<QWindow *()>;
using WindowToScreenCallback = std::function<QPoint(const QPoint &)>;
using ScreenToWindowCallback = std::function<QPoint(const QPoint &)>;
using IsInsideSystemButtonsCallback = std::function<bool(const QPoint &, Global::SystemButtonType *)>;
using IsInsideTitleBarDraggableAreaCallback = std::function<bool(const QPoint &)>;
using GetWindowDevicePixelRatioCallback = std::function<qreal()>;
using SetSystemButtonStateCallback = std::function<void(const Global::SystemButtonType, const Global::ButtonState)>;
using GetWindowIdCallback = std::function<WId()>;
using ShouldIgnoreMouseEventsCallback = std::function<bool(const QPoint &)>;
using ShowSystemMenuCallback = std::function<void(const QPoint &)>;
using SetPropertyCallback = std::function<void(const char *, const QVariant &)>;
using GetPropertyCallback = std::function<QVariant(const char *, const QVariant &)>;
using SetCursorCallback = std::function<void(const QCursor &)>;
using UnsetCursorCallback = std::function<void()>;
using GetWidgetHandleCallback = std::function<QObject *()>;
using ForceChildrenRepaintCallback = std::function<void()>;
using ResetQtGrabbedControlCallback = std::function<bool()>;
struct FRAMELESSHELPER_CORE_API FramelessCallbacks
{
GetWindowFlagsCallback getWindowFlags = nullptr;
SetWindowFlagsCallback setWindowFlags = nullptr;
GetWindowSizeCallback getWindowSize = nullptr;
SetWindowSizeCallback setWindowSize = nullptr;
GetWindowPositionCallback getWindowPosition = nullptr;
SetWindowPositionCallback setWindowPosition = nullptr;
GetWindowScreenCallback getWindowScreen = nullptr;
IsWindowFixedSizeCallback isWindowFixedSize = nullptr;
SetWindowFixedSizeCallback setWindowFixedSize = nullptr;
GetWindowStateCallback getWindowState = nullptr;
SetWindowStateCallback setWindowState = nullptr;
GetWindowHandleCallback getWindowHandle = nullptr;
WindowToScreenCallback windowToScreen = nullptr;
ScreenToWindowCallback screenToWindow = nullptr;
IsInsideSystemButtonsCallback isInsideSystemButtons = nullptr;
IsInsideTitleBarDraggableAreaCallback isInsideTitleBarDraggableArea = nullptr;
GetWindowDevicePixelRatioCallback getWindowDevicePixelRatio = nullptr;
SetSystemButtonStateCallback setSystemButtonState = nullptr;
GetWindowIdCallback getWindowId = nullptr;
ShouldIgnoreMouseEventsCallback shouldIgnoreMouseEvents = nullptr;
ShowSystemMenuCallback showSystemMenu = nullptr;
SetPropertyCallback setProperty = nullptr;
GetPropertyCallback getProperty = nullptr;
SetCursorCallback setCursor = nullptr;
UnsetCursorCallback unsetCursor = nullptr;
GetWidgetHandleCallback getWidgetHandle = nullptr;
ForceChildrenRepaintCallback forceChildrenRepaint = nullptr;
ResetQtGrabbedControlCallback resetQtGrabbedControl = nullptr;
FramelessCallbacks();
virtual ~FramelessCallbacks();
using PtrType = std::shared_ptr<FramelessCallbacks>;
[[nodiscard]] static PtrType create();
private:
FRAMELESSHELPER_CLASS(FramelessCallbacks)
};
using FramelessCallbacksPtr = FramelessCallbacks::PtrType;
enum class ExtraDataType : quint8
{
WindowsUtilities,
LinuxUtilities,
MacOSUtilities,
FramelessWidgetsHelper,
FramelessQuickHelper
};
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
inline uint qHash(const ExtraDataType key, const uint seed = 0) noexcept {
return ::qHash(static_cast<quint8>(key), seed);
}
#endif
struct FRAMELESSHELPER_CORE_API FramelessExtraData
{
FramelessExtraData();
virtual ~FramelessExtraData();
using PtrType = std::shared_ptr<FramelessExtraData>;
private:
FRAMELESSHELPER_CLASS(FramelessExtraData)
};
using FramelessExtraDataPtr = FramelessExtraData::PtrType;
using FramelessExtraDataPtrs = QList<FramelessExtraDataPtr>;
using FramelessExtraDataHash = QHash<ExtraDataType, FramelessExtraDataPtr>;
struct FRAMELESSHELPER_CORE_API FramelessData
{
QObject *window = nullptr;
WId windowId = 0;
QObject *internalEventHandler = nullptr;
bool frameless = false;
FramelessCallbacksPtr callbacks = nullptr;
FramelessExtraDataHash extraData = {};
FramelessData();
virtual ~FramelessData();
using PtrType = std::shared_ptr<FramelessData>;
[[nodiscard]] static PtrType create();
private:
FRAMELESSHELPER_CLASS(FramelessData)
};
using FramelessDataPtr = FramelessData::PtrType;
using FramelessDataPtrs = QList<FramelessDataPtr>;
using FramelessDataHash = QHash<QObject *, FramelessDataPtr>;
FRAMELESSHELPER_END_NAMESPACE
#define DECLARE_SIZE_COMPARE_OPERATORS(Type1, Type2) \
[[maybe_unused]] [[nodiscard]] inline constexpr bool operator>(const Type1 &lhs, const Type2 &rhs) noexcept \
{ \
return ((lhs.width() * lhs.height()) > (rhs.width() * rhs.height())); \
} \
[[maybe_unused]] [[nodiscard]] inline constexpr bool operator>=(const Type1 &lhs, const Type2 &rhs) noexcept \
{ \
return (operator>(lhs, rhs) || operator==(lhs, rhs)); \
} \
[[maybe_unused]] [[nodiscard]] inline constexpr bool operator<(const Type1 &lhs, const Type2 &rhs) noexcept \
{ \
return (operator!=(lhs, rhs) && !operator>(lhs, rhs)); \
} \
[[maybe_unused]] [[nodiscard]] inline constexpr bool operator<=(const Type1 &lhs, const Type2 &rhs) noexcept \
{ \
return (operator<(lhs, rhs) || operator==(lhs, rhs)); \
}
DECLARE_SIZE_COMPARE_OPERATORS(QSize, QSize)
DECLARE_SIZE_COMPARE_OPERATORS(QSizeF, QSizeF)
DECLARE_SIZE_COMPARE_OPERATORS(QSize, QSizeF)
DECLARE_SIZE_COMPARE_OPERATORS(QSizeF, QSize)

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,54 +24,68 @@
#pragma once
#include "framelesshelpercore_global.h"
#include "framelessmanager.h"
#include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <QtCore/qtimer.h>
#include <optional>
FRAMELESSHELPER_BEGIN_NAMESPACE
struct FramelessData;
using FramelessDataPtr = std::shared_ptr<FramelessData>;
class FramelessManager;
class FRAMELESSHELPER_CORE_API FramelessManagerPrivate : public QObject
{
Q_OBJECT
Q_DECLARE_PUBLIC(FramelessManager)
Q_DISABLE_COPY_MOVE(FramelessManagerPrivate)
FRAMELESSHELPER_PRIVATE_QT_CLASS(FramelessManager)
public:
explicit FramelessManagerPrivate(FramelessManager *q);
~FramelessManagerPrivate() override;
Q_NODISCARD static FramelessManagerPrivate *get(FramelessManager *pub);
Q_NODISCARD static const FramelessManagerPrivate *get(const FramelessManager *pub);
static void initializeIconFont();
Q_NODISCARD static QFont getIconFont();
Q_NODISCARD Global::SystemTheme systemTheme() const;
Q_NODISCARD QColor systemAccentColor() const;
Q_NODISCARD QString wallpaper() const;
Q_NODISCARD Global::WallpaperAspectStyle wallpaperAspectStyle() const;
Q_SLOT void notifySystemThemeHasChangedOrNot();
Q_SLOT void notifyWallpaperHasChangedOrNot();
static void addWindow(const Global::SystemParameters &params);
static void removeWindow(const WId windowId);
Q_NODISCARD bool isThemeOverrided() const;
Q_INVOKABLE void notifySystemThemeHasChangedOrNot();
Q_INVOKABLE void notifyWallpaperHasChangedOrNot();
Q_NODISCARD static bool usePureQtImplementation();
private:
void initialize();
private:
QPointer<FramelessManager> q_ptr = nullptr;
Global::SystemTheme m_systemTheme = Global::SystemTheme::Unknown;
QColor m_accentColor = {};
void doNotifySystemThemeHasChangedOrNot();
void doNotifyWallpaperHasChangedOrNot();
Q_NODISCARD static FramelessDataPtr getData(const QObject *window);
Q_NODISCARD static FramelessDataPtr createData(const QObject *window, const WId windowId);
Q_NODISCARD static WId getWindowId(const QObject *window);
Q_NODISCARD static QObject *getWindow(const WId windowId);
static void updateWindowId(const QObject *window, const WId newWindowId);
Global::SystemTheme systemTheme = Global::SystemTheme::Unknown;
std::optional<Global::SystemTheme> overrideTheme = std::nullopt;
QColor accentColor = {};
#ifdef Q_OS_WINDOWS
Global::DwmColorizationArea m_colorizationArea = Global::DwmColorizationArea::None;
Global::DwmColorizationArea colorizationArea = Global::DwmColorizationArea::None;
#endif
QString m_wallpaper = {};
Global::WallpaperAspectStyle m_wallpaperAspectStyle = Global::WallpaperAspectStyle::Fill;
QString wallpaper = {};
Global::WallpaperAspectStyle wallpaperAspectStyle = Global::WallpaperAspectStyle::Fill;
QTimer themeTimer{};
QTimer wallpaperTimer{};
};
class InternalEventFilter : public QObject
{
FRAMELESSHELPER_QT_CLASS(InternalEventFilter)
public:
explicit InternalEventFilter(const QObject *window, QObject *parent = nullptr);
~InternalEventFilter() override;
protected:
Q_NODISCARD bool eventFilter(QObject *object, QEvent *event) override;
private:
const QObject *m_window = nullptr;
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessManagerPrivate))

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,43 +24,80 @@
#pragma once
#include "framelesshelpercore_global.h"
#include "micamaterial.h"
#include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <QtGui/qbrush.h>
#ifdef FRAMELESSHELPER_HAS_THREAD
# undef FRAMELESSHELPER_HAS_THREAD
#endif
#if QT_CONFIG(thread)
# define FRAMELESSHELPER_HAS_THREAD 1
# include <QtCore/qthread.h>
#else // !QT_CONFIG(thread)
# define FRAMELESSHELPER_HAS_THREAD 0
#endif // QT_CONFIG(thread)
#if FRAMELESSHELPER_CONFIG(mica_material)
FRAMELESSHELPER_BEGIN_NAMESPACE
#if FRAMELESSHELPER_HAS_THREAD
using FramelessHelperThreadClass = QThread;
#else
using FramelessHelperThreadClass = QObject;
#endif
class MicaMaterial;
class FRAMELESSHELPER_CORE_API MicaMaterialPrivate : public QObject
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(MicaMaterialPrivate)
Q_DECLARE_PUBLIC(MicaMaterial)
FRAMELESSHELPER_PRIVATE_QT_CLASS(MicaMaterial)
public:
explicit MicaMaterialPrivate(MicaMaterial *q);
~MicaMaterialPrivate() override;
Q_NODISCARD static MicaMaterialPrivate *get(MicaMaterial *q);
Q_NODISCARD static const MicaMaterialPrivate *get(const MicaMaterial *q);
Q_NODISCARD static QColor systemFallbackColor();
public Q_SLOTS:
void maybeGenerateBlurredWallpaper(const bool force = false);
void updateMaterialBrush();
void paint(QPainter *painter, const QSize &size, const QPoint &pos);
Q_NODISCARD QPoint mapToWallpaper(const QPoint &pos) const;
Q_NODISCARD QSize mapToWallpaper(const QSize &size) const;
Q_NODISCARD QRect mapToWallpaper(const QRect &rect) const;
Q_SLOT void maybeGenerateBlurredWallpaper(const bool force = false);
Q_SLOT void updateMaterialBrush();
Q_SLOT void forceRebuildWallpaper();
private:
void initialize();
void prepareGraphicsResources();
private:
QPointer<MicaMaterial> q_ptr = nullptr;
QColor tintColor = {};
qreal tintOpacity = 0.0;
qreal noiseOpacity = 0.0;
qreal tintOpacity = qreal(0);
QColor fallbackColor = {};
qreal noiseOpacity = qreal(0);
bool fallbackEnabled = true;
QBrush micaBrush = {};
bool initialized = false;
QSize wallpaperSize = {};
};
class WallpaperThread : public FramelessHelperThreadClass
{
FRAMELESSHELPER_QT_CLASS(WallpaperThread)
public:
explicit WallpaperThread(QObject *parent = nullptr);
~WallpaperThread() override;
Q_SIGNALS:
void imageUpdated();
#if FRAMELESSHELPER_HAS_THREAD
protected:
void run() override;
#else
public:
void start();
#endif
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(MicaMaterialPrivate))
#endif

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,19 +24,23 @@
#pragma once
#include "framelesshelpercore_global.h"
#include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <QtCore/qvariant.h>
#include <optional>
#include <memory>
#ifdef Q_OS_WINDOWS
#ifndef REGISTRYKEY_FORCE_QSETTINGS
# define REGISTRYKEY_FORCE_QSETTINGS (0)
#endif // REGISTRYKEY_FORCE_QSETTINGS
#ifndef REGISTRYKEY_IMPL
# if ((QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) && !(REGISTRYKEY_FORCE_QSETTINGS))
# if ((QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) && !(REGISTRYKEY_FORCE_QSETTINGS) && !defined(FRAMELESSHELPER_CORE_NO_PRIVATE))
# define REGISTRYKEY_IMPL (1)
# else // ((QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) || REGISTRYKEY_FORCE_QSETTINGS)
# else // ((QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) || REGISTRYKEY_FORCE_QSETTINGS || defined(FRAMELESSHELPER_CORE_NO_PRIVATE))
# define REGISTRYKEY_IMPL (2)
# endif // ((QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) && !REGISTRYKEY_FORCE_QSETTINGS)
# endif // ((QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) && !REGISTRYKEY_FORCE_QSETTINGS && !defined(FRAMELESSHELPER_CORE_NO_PRIVATE))
#endif // REGISTRYKEY_IMPL
#ifndef REGISTRYKEY_QWINREGISTRYKEY
@ -56,8 +60,7 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
class FRAMELESSHELPER_CORE_API RegistryKey : public QObject
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(RegistryKey)
FRAMELESSHELPER_QT_CLASS(RegistryKey)
public:
explicit RegistryKey(const Global::RegistryRootKey root, const QString &key, QObject *parent = nullptr);
@ -73,7 +76,7 @@ public:
Q_NODISCARD std::optional<T> value(const QString &name) const
{
const QVariant var = value(name);
if (var.isValid()) {
if (var.isValid() && !var.isNull()) {
return qvariant_cast<T>(var);
}
return std::nullopt;
@ -83,12 +86,12 @@ private:
Global::RegistryRootKey m_rootKey = Global::RegistryRootKey::CurrentUser;
QString m_subKey = {};
#if REGISTRYKEY_QWINREGISTRYKEY
QScopedPointer<QWinRegistryKey> m_registryKey;
std::unique_ptr<QWinRegistryKey> m_registryKey;
#else
QScopedPointer<QSettings> m_settings;
std::unique_ptr<QSettings> m_settings;
#endif
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(RegistryKey))
#endif // Q_OS_WINDOWS

View File

@ -0,0 +1,102 @@
/*
* MIT License
*
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#pragma once
#include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <functional>
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
# include <QtCore/qscopeguard.h>
#else // (QT_VERSION < QT_VERSION_CHECK(5, 12, 0))
FRAMELESSHELPER_BEGIN_NAMESPACE
using ScopeGuardCallback = std::function<void()>;
class [[nodiscard]] ScopeGuard
{
FRAMELESSHELPER_CLASS(ScopeGuard)
public:
ScopeGuard()
{
}
explicit ScopeGuard(const ScopeGuardCallback &cb)
{
// For the ctor, we require a non-null function.
Q_ASSERT(cb);
if (!cb) {
return;
}
m_callback = cb;
}
explicit ScopeGuard(ScopeGuardCallback &&cb)
{
// For the ctor, we require a non-null function.
Q_ASSERT(cb);
if (!cb) {
return;
}
m_callback = std::move(cb);
}
ScopeGuard(ScopeGuard &&other) : m_callback(std::move(other.m_callback))
{
}
~ScopeGuard()
{
if (m_callback) {
m_callback();
}
}
[[nodiscard]] ScopeGuardCallback callback() const
{
return m_callback;
}
void setCallback(const ScopeGuardCallback &cb)
{
// But we allow null functions here.
m_callback = cb;
}
private:
ScopeGuardCallback m_callback = nullptr;
};
[[nodiscard]] inline ScopeGuard make_guard(ScopeGuardCallback &&cb)
{
return ScopeGuard(cb);
}
#define qScopeGuard make_guard
FRAMELESSHELPER_END_NAMESPACE
#endif // (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,61 +24,69 @@
#pragma once
#include "framelesshelpercore_global.h"
#include <FramelessHelper/Core/framelesshelpercore_global.h>
FRAMELESSHELPER_BEGIN_NAMESPACE
class FRAMELESSHELPER_CORE_API SysApiLoader : public QObject
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(SysApiLoader)
FRAMELESSHELPER_QT_CLASS(SysApiLoader)
public:
explicit SysApiLoader(QObject *parent = nullptr);
~SysApiLoader() override;
Q_NODISCARD static SysApiLoader *instance();
Q_NODISCARD static QString platformSharedLibrarySuffixName();
Q_NODISCARD static QString platformSystemLibraryDirectory();
Q_NODISCARD static QString generateUniqueKey(const QString &library, const QString &function);
Q_NODISCARD static QFunctionPointer resolve(const QString &library, const char *function);
Q_NODISCARD static QFunctionPointer resolve(const QString &library, const QByteArray &function);
Q_NODISCARD static QFunctionPointer resolve(const QString &library, const QString &function);
Q_NODISCARD bool isAvailable(const QString &library, const QString &function);
Q_NODISCARD QFunctionPointer get(const QString &function);
Q_NODISCARD QFunctionPointer get(const QString &library, const QString &function);
template<typename T>
Q_NODISCARD T get(const QString &function)
Q_NODISCARD T get(const QString &library, const QString &function)
{
return reinterpret_cast<T>(get(function));
return reinterpret_cast<T>(get(library, function));
}
private:
explicit SysApiLoader(QObject *parent = nullptr);
~SysApiLoader() override;
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader))
#define API_AVAILABLE(lib, func) \
(FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->isAvailable(k##lib, k##func))
#define API_CALL_FUNCTION(lib, func, ...) \
((FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->get<decltype(&func)>(k##lib, k##func))(__VA_ARGS__))
#define API_CALL_FUNCTION2(lib, func, type, ...) \
((FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->get<type>(k##lib, k##func))(__VA_ARGS__))
#define API_CALL_FUNCTION3(lib, func, name, ...) \
((FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->get<decltype(&func)>(k##lib, k##name))(__VA_ARGS__))
#define API_CALL_FUNCTION4(lib, func, ...) API_CALL_FUNCTION3(lib, _##func, func, __VA_ARGS__)
#define API_CALL_FUNCTION5(lib, func, ...) API_CALL_FUNCTION3(lib, func##2, func, __VA_ARGS__)
#ifdef Q_OS_WINDOWS
# define API_WIN_AVAILABLE(lib, func) \
(FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->isAvailable(k##lib, k##func))
# define API_USER_AVAILABLE(func) API_WIN_AVAILABLE(user32, func)
# define API_THEME_AVAILABLE(func) API_WIN_AVAILABLE(uxtheme, func)
# define API_DWM_AVAILABLE(func) API_WIN_AVAILABLE(dwmapi, func)
# define API_SHCORE_AVAILABLE(func) API_WIN_AVAILABLE(shcore, func)
# define API_WINMM_AVAILABLE(func) API_WIN_AVAILABLE(winmm, func)
# define API_D2D_AVAILABLE(func) API_WIN_AVAILABLE(d2d1, func)
# define API_NT_AVAILABLE(func) API_WIN_AVAILABLE(ntdll, func)
#endif
# define API_USER_AVAILABLE(func) API_AVAILABLE(user32, func)
# define API_THEME_AVAILABLE(func) API_AVAILABLE(uxtheme, func)
# define API_DWM_AVAILABLE(func) API_AVAILABLE(dwmapi, func)
# define API_SHCORE_AVAILABLE(func) API_AVAILABLE(shcore, func)
# define API_WINMM_AVAILABLE(func) API_AVAILABLE(winmm, func)
# define API_D2D_AVAILABLE(func) API_AVAILABLE(d2d1, func)
# define API_NT_AVAILABLE(func) API_AVAILABLE(ntdll, func)
#endif // Q_OS_WINDOWS
#define API_CALL_FUNCTION(func, ...) \
((FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->get<decltype(&func)>(k##func))(__VA_ARGS__))
#define API_CALL_FUNCTION2(func, type, ...) \
((FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->get<type>(k##func))(__VA_ARGS__))
#define API_CALL_FUNCTION3(func, name, ...) \
((FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->get<decltype(&func)>(k##name))(__VA_ARGS__))
#define API_CALL_FUNCTION4(func, ...) API_CALL_FUNCTION3(_##func, func, __VA_ARGS__)
#define API_CALL_FUNCTION5(func, ...) API_CALL_FUNCTION3(func##2, func, __VA_ARGS__)
#if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
# define API_XLIB_AVAILABLE(func) API_AVAILABLE(libX11, func)
# define API_XCB_AVAILABLE(func) API_AVAILABLE(libxcb, func)
# define API_GTK_AVAILABLE(func) API_AVAILABLE(libgtk, func)
#endif // Q_OS_LINUX

View File

@ -0,0 +1,130 @@
/*
* MIT License
*
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#pragma once
#include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <array>
FRAMELESSHELPER_BEGIN_NAMESPACE
struct VersionNumber
{
unsigned long Major = 0;
unsigned long Minor = 0;
unsigned long Patch = 0;
unsigned long Tweak = 0;
[[nodiscard]] friend constexpr bool operator==(const VersionNumber &lhs, const VersionNumber &rhs) noexcept
{
return ((lhs.Major == rhs.Major) && (lhs.Minor == rhs.Minor) && (lhs.Patch == rhs.Patch) && (lhs.Tweak == rhs.Tweak));
}
[[nodiscard]] friend constexpr bool operator!=(const VersionNumber &lhs, const VersionNumber &rhs) noexcept
{
return !operator==(lhs, rhs);
}
[[nodiscard]] friend constexpr bool operator>(const VersionNumber &lhs, const VersionNumber &rhs) noexcept
{
if (operator==(lhs, rhs)) {
return false;
}
if (lhs.Major > rhs.Major) {
return true;
}
if (lhs.Major < rhs.Major) {
return false;
}
if (lhs.Minor > rhs.Minor) {
return true;
}
if (lhs.Minor < rhs.Minor) {
return false;
}
if (lhs.Patch > rhs.Patch) {
return true;
}
if (lhs.Patch < rhs.Patch) {
return false;
}
return (lhs.Tweak > rhs.Tweak);
}
[[nodiscard]] friend constexpr bool operator<(const VersionNumber &lhs, const VersionNumber &rhs) noexcept
{
return (operator!=(lhs, rhs) && !operator>(lhs, rhs));
}
[[nodiscard]] friend constexpr bool operator>=(const VersionNumber &lhs, const VersionNumber &rhs) noexcept
{
return (operator>(lhs, rhs) || operator==(lhs, rhs));
}
[[nodiscard]] friend constexpr bool operator<=(const VersionNumber &lhs, const VersionNumber &rhs) noexcept
{
return (operator<(lhs, rhs) || operator==(lhs, rhs));
}
};
#ifdef Q_OS_WINDOWS
[[maybe_unused]] inline constexpr const std::array<VersionNumber, static_cast<int>(Global::WindowsVersion::Latest) + 1> WindowsVersions =
{
VersionNumber{ 5, 0, 2195 }, // Windows 2000
VersionNumber{ 5, 1, 2600 }, // Windows XP
VersionNumber{ 5, 2, 3790 }, // Windows XP x64 Edition or Windows Server 2003
VersionNumber{ 6, 0, 6000 }, // Windows Vista
VersionNumber{ 6, 0, 6001 }, // Windows Vista with Service Pack 1 or Windows Server 2008
VersionNumber{ 6, 0, 6002 }, // Windows Vista with Service Pack 2
VersionNumber{ 6, 1, 7600 }, // Windows 7 or Windows Server 2008 R2
VersionNumber{ 6, 1, 7601 }, // Windows 7 with Service Pack 1 or Windows Server 2008 R2 with Service Pack 1
VersionNumber{ 6, 2, 9200 }, // Windows 8 or Windows Server 2012
VersionNumber{ 6, 3, 9200 }, // Windows 8.1 or Windows Server 2012 R2
VersionNumber{ 6, 3, 9600 }, // Windows 8.1 with Update 1
VersionNumber{ 10, 0, 10240 }, // Windows 10 Version 1507 (TH1)
VersionNumber{ 10, 0, 10586 }, // Windows 10 Version 1511 (November Update) (TH2)
VersionNumber{ 10, 0, 14393 }, // Windows 10 Version 1607 (Anniversary Update) (RS1) or Windows Server 2016
VersionNumber{ 10, 0, 15063 }, // Windows 10 Version 1703 (Creators Update) (RS2)
VersionNumber{ 10, 0, 16299 }, // Windows 10 Version 1709 (Fall Creators Update) (RS3)
VersionNumber{ 10, 0, 17134 }, // Windows 10 Version 1803 (April 2018 Update) (RS4)
VersionNumber{ 10, 0, 17763 }, // Windows 10 Version 1809 (October 2018 Update) (RS5) or Windows Server 2019
VersionNumber{ 10, 0, 18362 }, // Windows 10 Version 1903 (May 2019 Update) (19H1)
VersionNumber{ 10, 0, 18363 }, // Windows 10 Version 1909 (November 2019 Update) (19H2)
VersionNumber{ 10, 0, 19041 }, // Windows 10 Version 2004 (May 2020 Update) (20H1)
VersionNumber{ 10, 0, 19042 }, // Windows 10 Version 20H2 (October 2020 Update) (20H2)
VersionNumber{ 10, 0, 19043 }, // Windows 10 Version 21H1 (May 2021 Update) (21H1)
VersionNumber{ 10, 0, 19044 }, // Windows 10 Version 21H2 (November 2021 Update) (21H2)
VersionNumber{ 10, 0, 19045 }, // Windows 10 Version 22H2 (October 2022 Update) (22H2)
VersionNumber{ 10, 0, 22000 }, // Windows 11 Version 21H2 (21H2)
VersionNumber{ 10, 0, 22621 } // Windows 11 Version 22H2 (October 2022 Update) (22H2)
};
#endif // Q_OS_WINDOWS
FRAMELESSHELPER_END_NAMESPACE
#ifndef QT_NO_DEBUG_STREAM
QT_BEGIN_NAMESPACE
FRAMELESSHELPER_CORE_API QDebug operator<<(QDebug, const FRAMELESSHELPER_PREPEND_NAMESPACE(VersionNumber) &);
QT_END_NAMESPACE
#endif // QT_NO_DEBUG_STREAM

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,42 +24,28 @@
#pragma once
#include "framelesshelpercore_global.h"
#include "windowborderpainter.h"
#include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <optional>
#if FRAMELESSHELPER_CONFIG(border_painter)
FRAMELESSHELPER_BEGIN_NAMESPACE
class WindowBorderPainter;
class FRAMELESSHELPER_CORE_API WindowBorderPainterPrivate : public QObject
{
Q_OBJECT
Q_DECLARE_PUBLIC(WindowBorderPainter)
Q_DISABLE_COPY_MOVE(WindowBorderPainterPrivate)
FRAMELESSHELPER_PRIVATE_QT_CLASS(WindowBorderPainter)
public:
explicit WindowBorderPainterPrivate(WindowBorderPainter *q);
~WindowBorderPainterPrivate() override;
Q_NODISCARD static WindowBorderPainterPrivate *get(WindowBorderPainter *q);
Q_NODISCARD static const WindowBorderPainterPrivate *get(const WindowBorderPainter *q);
Q_NODISCARD static int getNativeBorderThickness();
Q_NODISCARD static QColor getNativeBorderColor(const bool active);
Q_NODISCARD static Global::WindowEdges getNativeBorderEdges();
public Q_SLOTS:
void paint(QPainter *painter, const QSize &size, const bool active) const;
private:
void initialize();
private:
QPointer<WindowBorderPainter> q_ptr = nullptr;
std::optional<int> m_thickness = std::nullopt;
std::optional<Global::WindowEdges> m_edges = std::nullopt;
std::optional<QColor> m_activeColor = std::nullopt;
std::optional<QColor> m_inactiveColor = std::nullopt;
std::optional<int> thickness = std::nullopt;
std::optional<Global::WindowEdges> edges = std::nullopt;
std::optional<QColor> activeColor = std::nullopt;
std::optional<QColor> inactiveColor = std::nullopt;
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(WindowBorderPainterPrivate))
#endif

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,7 +24,9 @@
#pragma once
#include "framelesshelpercore_global.h"
#include <FramelessHelper/Core/framelesshelpercore_global.h>
#ifdef Q_OS_WINDOWS
FRAMELESSHELPER_BEGIN_NAMESPACE
@ -68,3 +70,5 @@ DECL(1122H2)
} // namespace WindowsVersionHelper
FRAMELESSHELPER_END_NAMESPACE
#endif // Q_OS_WINDOWS

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,114 +24,150 @@
#pragma once
#include "framelesshelpercore_global.h"
#include <FramelessHelper/Core/framelesshelpercore_global.h>
#if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
# include <FramelessHelper/Core/framelesshelper_linux.h>
#endif // Q_OS_LINUX
#if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
QT_BEGIN_NAMESPACE
class QScreen;
QT_END_NAMESPACE
#endif // Q_OS_LINUX
FRAMELESSHELPER_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcUtilsCommon)
#ifdef Q_OS_WINDOWS
Q_DECLARE_LOGGING_CATEGORY(lcUtilsWin)
#elif defined(Q_OS_LINUX)
Q_DECLARE_LOGGING_CATEGORY(lcUtilsLinux)
#elif defined(Q_OS_MACOS)
Q_DECLARE_LOGGING_CATEGORY(lcUtilsMac)
#endif
namespace Utils
{
[[nodiscard]] FRAMELESSHELPER_CORE_API
Qt::CursorShape calculateCursorShape(const QWindow *window, const QPoint &pos);
[[nodiscard]] FRAMELESSHELPER_CORE_API
Qt::Edges calculateWindowEdges(const QWindow *window, const QPoint &pos);
FRAMELESSHELPER_CORE_API void startSystemMove(QWindow *window, const QPoint &globalPos);
FRAMELESSHELPER_CORE_API void startSystemResize(QWindow *window, const Qt::Edges edges, const QPoint &globalPos);
[[nodiscard]] FRAMELESSHELPER_CORE_API QString getSystemButtonIconCode(const Global::SystemButtonType button);
[[nodiscard]] FRAMELESSHELPER_CORE_API Qt::CursorShape calculateCursorShape(const QWindow *window, const QPoint &pos);
[[nodiscard]] FRAMELESSHELPER_CORE_API Qt::Edges calculateWindowEdges(const QWindow *window, const QPoint &pos);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool startSystemMove(QWindow *window, const QPoint &globalPos);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool startSystemResize(QWindow *window, const Qt::Edges edges, const QPoint &globalPos);
[[nodiscard]] FRAMELESSHELPER_CORE_API QString getSystemButtonGlyph(const Global::SystemButtonType button);
[[nodiscard]] FRAMELESSHELPER_CORE_API QWindow *findWindow(const WId windowId);
FRAMELESSHELPER_CORE_API void moveWindowToDesktopCenter(
const Global::GetWindowScreenCallback &getWindowScreen,
const Global::GetWindowSizeCallback &getWindowSize,
const Global::SetWindowPositionCallback &setWindowPosition,
const bool considerTaskBar);
[[nodiscard]] FRAMELESSHELPER_CORE_API Global::SystemTheme getSystemTheme();
[[nodiscard]] FRAMELESSHELPER_CORE_API Qt::WindowState windowStatesToWindowState(
const Qt::WindowStates states);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool moveWindowToDesktopCenter(const WId windowId, const bool considerTaskBar);
[[nodiscard]] FRAMELESSHELPER_CORE_API Qt::WindowState windowStatesToWindowState(const Qt::WindowStates states);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isThemeChangeEvent(const QEvent * const event);
[[nodiscard]] FRAMELESSHELPER_CORE_API QColor calculateSystemButtonBackgroundColor(
const Global::SystemButtonType button, const Global::ButtonState state);
[[nodiscard]] FRAMELESSHELPER_CORE_API QColor calculateSystemButtonBackgroundColor(const Global::SystemButtonType button, const Global::ButtonState state);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool shouldAppsUseDarkMode();
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isTitleBarColorized();
[[nodiscard]] FRAMELESSHELPER_CORE_API bool
setBlurBehindWindowEnabled(const WId windowId, const Global::BlurMode mode, const QColor &color);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool setBlurBehindWindowEnabled(const WId windowId, const Global::BlurMode mode, const QColor &color);
[[nodiscard]] FRAMELESSHELPER_CORE_API QString getWallpaperFilePath();
[[nodiscard]] FRAMELESSHELPER_CORE_API Global::WallpaperAspectStyle getWallpaperAspectStyle();
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isBlurBehindWindowSupported();
FRAMELESSHELPER_CORE_API void registerThemeChangeNotification();
[[nodiscard]] FRAMELESSHELPER_CORE_API bool registerThemeChangeNotification();
[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getFrameBorderColor(const bool active);
[[nodiscard]] FRAMELESSHELPER_CORE_API qreal roundScaleFactor(const qreal factor);
[[nodiscard]] FRAMELESSHELPER_CORE_API int toNativePixels(const QWindow *window, const int value);
[[nodiscard]] FRAMELESSHELPER_CORE_API QPoint toNativePixels(const QWindow *window, const QPoint &point);
[[nodiscard]] FRAMELESSHELPER_CORE_API QSize toNativePixels(const QWindow *window, const QSize &size);
[[nodiscard]] FRAMELESSHELPER_CORE_API QRect toNativePixels(const QWindow *window, const QRect &rect);
[[nodiscard]] FRAMELESSHELPER_CORE_API int fromNativePixels(const QWindow *window, const int value);
[[nodiscard]] FRAMELESSHELPER_CORE_API QPoint fromNativePixels(const QWindow *window, const QPoint &point);
[[nodiscard]] FRAMELESSHELPER_CORE_API QSize fromNativePixels(const QWindow *window, const QSize &size);
[[nodiscard]] FRAMELESSHELPER_CORE_API QRect fromNativePixels(const QWindow *window, const QRect &rect);
[[nodiscard]] FRAMELESSHELPER_CORE_API QPoint toNativeLocalPosition(const QWindow *window, const QPoint &point);
[[nodiscard]] FRAMELESSHELPER_CORE_API QPoint toNativeGlobalPosition(const QWindow *window, const QPoint &point);
[[nodiscard]] FRAMELESSHELPER_CORE_API QPoint fromNativeLocalPosition(const QWindow *window, const QPoint &point);
[[nodiscard]] FRAMELESSHELPER_CORE_API QPoint fromNativeGlobalPosition(const QWindow *window, const QPoint &point);
[[nodiscard]] FRAMELESSHELPER_CORE_API int horizontalAdvance(const QFontMetrics &fm, const QString &str);
[[nodiscard]] FRAMELESSHELPER_CORE_API qreal getRelativeScaleFactor(const quint32 oldDpi, const quint32 newDpi);
[[nodiscard]] FRAMELESSHELPER_CORE_API QSizeF rescaleSize(const QSizeF &oldSize, const quint32 oldDpi, const quint32 newDpi);
[[nodiscard]] FRAMELESSHELPER_CORE_API QSize rescaleSize(const QSize &oldSize, const quint32 oldDpi, const quint32 newDpi);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isValidGeometry(const QRectF &rect);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isValidGeometry(const QRect &rect);
[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getAccentColor();
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 defaultScreenDpi();
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isWindowAccelerated(const QWindow *window);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isWindowTransparent(const QWindow *window);
[[nodiscard]] FRAMELESSHELPER_CORE_API QColor calculateForegroundColor(const QColor &backgroundColor);
#ifdef Q_OS_WINDOWS
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isWindowsVersionOrGreater(const Global::WindowsVersion version);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isDwmCompositionEnabled();
FRAMELESSHELPER_CORE_API void triggerFrameChange(const WId windowId);
FRAMELESSHELPER_CORE_API void updateWindowFrameMargins(const WId windowId, const bool reset);
FRAMELESSHELPER_CORE_API void updateInternalWindowFrameMargins(QWindow *window, const bool enable);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool triggerFrameChange(const WId windowId);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool updateWindowFrameMargins(const WId windowId, const bool reset);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool updateInternalWindowFrameMargins(QWindow *window, const bool enable);
[[nodiscard]] FRAMELESSHELPER_CORE_API QString getSystemErrorMessage(const QString &function);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isFullScreen(const WId windowId);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isWindowNoState(const WId windowId);
FRAMELESSHELPER_CORE_API void syncWmPaintWithDwm();
FRAMELESSHELPER_CORE_API void showSystemMenu(
const WId windowId,
const QPoint &pos,
const bool selectFirstEntry,
const Global::IsWindowFixedSizeCallback &isWindowFixedSize);
[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getDwmColorizationColor();
[[nodiscard]] FRAMELESSHELPER_CORE_API bool syncWmPaintWithDwm();
[[nodiscard]] FRAMELESSHELPER_CORE_API bool showSystemMenu(const WId windowId, const QPoint &pos, const bool selectFirstEntry);
[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getDwmColorizationColor(bool *opaque = nullptr, bool *ok = nullptr);
[[nodiscard]] FRAMELESSHELPER_CORE_API Global::DwmColorizationArea getDwmColorizationArea();
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isHighContrastModeEnabled();
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getPrimaryScreenDpi(const bool horizontal);
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getWindowDpi(const WId windowId, const bool horizontal);
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getResizeBorderThickness(const WId windowId,
const bool horizontal,
const bool scaled);
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getCaptionHeight(const WId windowId, const bool scaled);
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getResizeBorderThicknessForDpi(const bool horizontal, const quint32 dpi);
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getResizeBorderThickness(const WId windowId, const bool horizontal, const bool scaled);
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getCaptionBarHeightForDpi(const quint32 dpi);
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getCaptionBarHeight(const WId windowId, const bool scaled);
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getTitleBarHeightForDpi(const quint32 dpi);
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getTitleBarHeight(const WId windowId, const bool scaled);
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getFrameBorderThickness(const WId windowId,
const bool scaled);
FRAMELESSHELPER_CORE_API void maybeFixupQtInternals(const WId windowId);
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getFrameBorderThicknessForDpi(const quint32 dpi);
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getFrameBorderThickness(const WId windowId, const bool scaled);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool maybeFixupQtInternals(const WId windowId);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isWindowFrameBorderVisible();
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isFrameBorderColorized();
FRAMELESSHELPER_CORE_API void installSystemMenuHook(
const WId windowId,
const Global::IsWindowFixedSizeCallback &isWindowFixedSize,
const Global::IsInsideTitleBarDraggableAreaCallback &isInTitleBarArea,
const Global::GetWindowDevicePixelRatioCallback &getDevicePixelRatio);
FRAMELESSHELPER_CORE_API void uninstallSystemMenuHook(const WId windowId);
FRAMELESSHELPER_CORE_API void setAeroSnappingEnabled(const WId windowId, const bool enable);
FRAMELESSHELPER_CORE_API void tryToEnableHighestDpiAwarenessLevel();
FRAMELESSHELPER_CORE_API void updateGlobalWin32ControlsTheme(const WId windowId, const bool dark);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool installWindowProcHook(const WId windowId);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool uninstallWindowProcHook(const WId windowId);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool setAeroSnappingEnabled(const WId windowId, const bool enable);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool tryToEnableHighestDpiAwarenessLevel();
[[nodiscard]] FRAMELESSHELPER_CORE_API bool updateGlobalWin32ControlsTheme(const WId windowId, const bool dark);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool shouldAppsUseDarkMode_windows();
FRAMELESSHELPER_CORE_API void forceSquareCornersForWindow(const WId windowId, const bool force);
[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getDwmAccentColor();
FRAMELESSHELPER_CORE_API void hideOriginalTitleBarElements
(const WId windowId, const bool disable = true);
FRAMELESSHELPER_CORE_API void setQtDarkModeAwareEnabled(const bool enable);
FRAMELESSHELPER_CORE_API void refreshWin32ThemeResources(const WId windowId, const bool dark);
FRAMELESSHELPER_CORE_API void enableNonClientAreaDpiScalingForWindow(const WId windowId);
[[nodiscard]] FRAMELESSHELPER_CORE_API
Global::DpiAwareness getDpiAwarenessForCurrentProcess(bool *highest = nullptr);
FRAMELESSHELPER_CORE_API void fixupChildWindowsDpiMessage(const WId windowId);
FRAMELESSHELPER_CORE_API void fixupDialogsDpiScaling();
FRAMELESSHELPER_CORE_API void setDarkModeAllowedForApp(const bool allow = true);
[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getAccentColor_windows();
[[nodiscard]] FRAMELESSHELPER_CORE_API bool setCornerStyleForWindow(const WId windowId, const Global::WindowCornerStyle style);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool hideOriginalTitleBarElements(const WId windowId, const bool disable = true);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool setQtDarkModeAwareEnabled(const bool enable);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool refreshWin32ThemeResources(const WId windowId, const bool dark);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool enableNonClientAreaDpiScalingForWindow(const WId windowId);
[[nodiscard]] FRAMELESSHELPER_CORE_API Global::DpiAwareness getDpiAwarenessForCurrentProcess(bool *highest = nullptr);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool fixupChildWindowsDpiMessage(const WId windowId);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool fixupDialogsDpiScaling();
[[nodiscard]] FRAMELESSHELPER_CORE_API bool setDarkModeAllowedForApp(const bool allow = true);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool bringWindowToFront(const WId windowId);
[[nodiscard]] FRAMELESSHELPER_CORE_API QPoint getWindowPlacementOffset(const WId windowId);
[[nodiscard]] FRAMELESSHELPER_CORE_API QRect getWindowRestoreGeometry(const WId windowId);
[[nodiscard]] FRAMELESSHELPER_CORE_API quint64 getKeyState();
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isValidWindow(const WId windowId, const bool checkVisible, const bool checkTopLevel);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool updateFramebufferTransparency(const WId windowId);
[[nodiscard]] FRAMELESSHELPER_CORE_API QMargins getWindowSystemFrameMargins(const WId windowId);
[[nodiscard]] FRAMELESSHELPER_CORE_API QMargins getWindowCustomFrameMargins(const QWindow *window);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool updateAllDirectXSurfaces();
FRAMELESSHELPER_CORE_API void printWin32Message(void *msg);
#endif // Q_OS_WINDOWS
#ifdef Q_OS_LINUX
#if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
[[nodiscard]] FRAMELESSHELPER_CORE_API QScreen *x11_findScreenForVirtualDesktop(const int virtualDesktopNumber);
[[nodiscard]] FRAMELESSHELPER_CORE_API x11_return_type x11_appRootWindow(const int screen);
[[nodiscard]] FRAMELESSHELPER_CORE_API int x11_appScreen();
[[nodiscard]] FRAMELESSHELPER_CORE_API x11_return_type x11_appTime();
[[nodiscard]] FRAMELESSHELPER_CORE_API x11_return_type x11_appUserTime();
[[nodiscard]] FRAMELESSHELPER_CORE_API x11_return_type x11_getTimestamp();
[[nodiscard]] FRAMELESSHELPER_CORE_API QByteArray x11_nextStartupId();
[[nodiscard]] FRAMELESSHELPER_CORE_API Display *x11_display();
[[nodiscard]] FRAMELESSHELPER_CORE_API xcb_connection_t *x11_connection();
[[nodiscard]] FRAMELESSHELPER_CORE_API QByteArray getWindowProperty(const WId windowId, const xcb_atom_t prop, const xcb_atom_t type, const quint32 data_len);
FRAMELESSHELPER_CORE_API void setWindowProperty(const WId windowId, const xcb_atom_t prop, const xcb_atom_t type, const void *data, const quint32 data_len, const uint8_t format);
FRAMELESSHELPER_CORE_API void clearWindowProperty(const WId windowId, const xcb_atom_t prop);
[[nodiscard]] FRAMELESSHELPER_CORE_API xcb_atom_t internAtom(const char *name);
[[nodiscard]] FRAMELESSHELPER_CORE_API QString getWindowManagerName();
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isSupportedByWindowManager(const xcb_atom_t atom);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isSupportedByRootWindow(const xcb_atom_t atom);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool tryHideSystemTitleBar(const WId windowId, const bool hide = true);
FRAMELESSHELPER_CORE_API void openSystemMenu(const WId windowId, const QPoint &globalPos);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool shouldAppsUseDarkMode_linux();
[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getWmThemeColor();
[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getAccentColor_linux();
FRAMELESSHELPER_CORE_API void sendMoveResizeMessage(const WId windowId, const uint32_t action, const QPoint &globalPos, const Qt::MouseButton button = Qt::LeftButton);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isCustomDecorationSupported();
[[nodiscard]] FRAMELESSHELPER_CORE_API bool setPlatformPropertiesForWindow(QWindow *window, const QVariantHash &props);
#endif // Q_OS_LINUX
#ifdef Q_OS_MACOS
[[nodiscard]] FRAMELESSHELPER_CORE_API bool shouldAppsUseDarkMode_macos();
[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getAccentColor_macos();
FRAMELESSHELPER_CORE_API void setSystemTitleBarVisible(const WId windowId, const bool visible);
[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getControlsAccentColor();
FRAMELESSHELPER_CORE_API void removeWindowProxy(const WId windowId);
#endif // Q_OS_MACOS
} // namespace Utils

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,19 +24,17 @@
#pragma once
#include "framelesshelpercore_global.h"
#include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <memory>
#if FRAMELESSHELPER_CONFIG(border_painter)
FRAMELESSHELPER_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcWindowBorderPainter)
class WindowBorderPainterPrivate;
class FRAMELESSHELPER_CORE_API WindowBorderPainter : public QObject
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(WindowBorderPainter)
Q_DECLARE_PRIVATE(WindowBorderPainter)
FRAMELESSHELPER_PUBLIC_QT_CLASS(WindowBorderPainter)
Q_PROPERTY(int thickness READ thickness WRITE setThickness NOTIFY thicknessChanged FINAL)
Q_PROPERTY(Global::WindowEdges edges READ edges WRITE setEdges NOTIFY edgesChanged FINAL)
@ -63,7 +61,7 @@ public:
Q_NODISCARD QColor nativeInactiveColor() const;
public Q_SLOTS:
void paint(QPainter *painter, const QSize &size, const bool active) const;
void paint(QPainter *painter, const QSize &size, const bool active);
void setThickness(const int value);
void setEdges(const Global::WindowEdges value);
void setActiveColor(const QColor &value);
@ -76,11 +74,8 @@ Q_SIGNALS:
void inactiveColorChanged();
void nativeBorderChanged();
void shouldRepaint();
private:
QScopedPointer<WindowBorderPainterPrivate> d_ptr;
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(WindowBorderPainter))
#endif

View File

@ -1 +1 @@
#include <framelessquickhelper.h>
#include "framelessquickhelper.h"

View File

@ -1 +1 @@
#include <framelessquickmodule.h>
#include "framelessquickmodule.h"

View File

@ -1 +1 @@
#include <framelessquickutils.h>
#include "framelessquickutils.h"

View File

@ -1 +1 @@
#include <framelesshelperquick_global.h>
#include "framelesshelperquick_global.h"

View File

@ -1 +1 @@
#include <quickchromepalette.h>
#include "quickchromepalette.h"

View File

@ -1 +0,0 @@
#include <quickimageitem.h>

View File

@ -1 +1 @@
#include <quickmicamaterial.h>
#include "quickmicamaterial.h"

View File

@ -1 +1 @@
#include <quickwindowborder.h>
#include "quickwindowborder.h"

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,14 +24,14 @@
#pragma once
#include <framelesshelpercore_global.h>
#include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <QtQml/qqml.h>
#if __has_include(<QtQml/qqmlregistration.h>)
# include <QtQml/qqmlregistration.h>
#endif
#ifndef FRAMELESSHELPER_QUICK_API
# ifdef FRAMELESSHELPER_QUICK_STATIC
# if FRAMELESSHELPER_CONFIG(static_build)
# define FRAMELESSHELPER_QUICK_API
# else // FRAMELESSHELPER_QUICK_STATIC
# ifdef FRAMELESSHELPER_QUICK_LIBRARY
@ -71,16 +71,23 @@
}
#endif
#ifndef FRAMELESSHELPER_IMPORT_QUICK_PLUGIN
# define FRAMELESSHELPER_IMPORT_QUICK_PLUGIN Q_IMPORT_PLUGIN(org_wangwenx190_FramelessHelperPlugin)
#endif
FRAMELESSHELPER_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcQuickGlobal)
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_QUICK_URI[] = "org.wangwenx190.FramelessHelper";
[[maybe_unused]] inline constexpr const int FRAMELESSHELPER_QUICK_VERSION_MAJOR = 1;
[[maybe_unused]] inline constexpr const int FRAMELESSHELPER_QUICK_VERSION_MINOR = 0;
FRAMELESSHELPER_QUICK_API void FramelessHelperQuickInitialize();
FRAMELESSHELPER_QUICK_API void FramelessHelperQuickUninitialize();
FRAMELESSHELPER_QUICK_API void FramelessHelperQuickRegisterTypes(QQmlEngine *);
class FRAMELESSHELPER_QUICK_API QuickGlobal : public QObject
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(QuickGlobal)
FRAMELESSHELPER_QT_CLASS(QuickGlobal)
#ifdef QML_NAMED_ELEMENT
QML_NAMED_ELEMENT(FramelessHelperConstants)
#endif
@ -92,7 +99,7 @@ public:
explicit QuickGlobal(QObject *parent = nullptr);
~QuickGlobal() override;
enum class SystemTheme
enum class SystemTheme : quint8
{
FRAMELESSHELPER_QUICK_ENUM_VALUE(SystemTheme, Unknown)
FRAMELESSHELPER_QUICK_ENUM_VALUE(SystemTheme, Light)
@ -101,7 +108,7 @@ public:
};
Q_ENUM(SystemTheme)
enum class SystemButtonType
enum class SystemButtonType : quint8
{
FRAMELESSHELPER_QUICK_ENUM_VALUE(SystemButtonType, Unknown)
FRAMELESSHELPER_QUICK_ENUM_VALUE(SystemButtonType, WindowIcon)
@ -113,83 +120,27 @@ public:
};
Q_ENUM(SystemButtonType)
#ifdef Q_OS_WINDOWS
enum class DwmColorizationArea
enum class ButtonState : quint8
{
FRAMELESSHELPER_QUICK_ENUM_VALUE(DwmColorizationArea, None)
FRAMELESSHELPER_QUICK_ENUM_VALUE(DwmColorizationArea, StartMenu_TaskBar_ActionCenter)
FRAMELESSHELPER_QUICK_ENUM_VALUE(DwmColorizationArea, TitleBar_WindowBorder)
FRAMELESSHELPER_QUICK_ENUM_VALUE(DwmColorizationArea, All)
};
Q_ENUM(DwmColorizationArea)
#endif // Q_OS_WINDOWS
enum class ButtonState
{
FRAMELESSHELPER_QUICK_ENUM_VALUE(ButtonState, Unspecified)
FRAMELESSHELPER_QUICK_ENUM_VALUE(ButtonState, Normal)
FRAMELESSHELPER_QUICK_ENUM_VALUE(ButtonState, Hovered)
FRAMELESSHELPER_QUICK_ENUM_VALUE(ButtonState, Pressed)
FRAMELESSHELPER_QUICK_ENUM_VALUE(ButtonState, Clicked)
FRAMELESSHELPER_QUICK_ENUM_VALUE(ButtonState, Released)
};
Q_ENUM(ButtonState)
#ifdef Q_OS_WINDOWS
enum class WindowsVersion
{
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _2000)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _XP)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _XP_64)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _WS_03)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _Vista)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _Vista_SP1)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _Vista_SP2)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _7)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _7_SP1)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _8)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _8_1)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _8_1_Update1)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _10_1507)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _10_1511)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _10_1607)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _10_1703)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _10_1709)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _10_1803)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _10_1809)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _10_1903)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _10_1909)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _10_2004)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _10_20H2)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _10_21H1)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _10_21H2)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _10_22H2)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _10)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _11_21H2)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _11_22H2)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, _11)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowsVersion, Latest)
};
Q_ENUM(WindowsVersion)
#endif // Q_OS_WINDOWS
enum class ApplicationType
{
FRAMELESSHELPER_QUICK_ENUM_VALUE(ApplicationType, Widgets)
FRAMELESSHELPER_QUICK_ENUM_VALUE(ApplicationType, Quick)
FRAMELESSHELPER_QUICK_ENUM_VALUE(ApplicationType, Hybrid)
};
Q_ENUM(ApplicationType)
enum class BlurMode
enum class BlurMode : quint8
{
FRAMELESSHELPER_QUICK_ENUM_VALUE(BlurMode, Disable)
FRAMELESSHELPER_QUICK_ENUM_VALUE(BlurMode, Default)
FRAMELESSHELPER_QUICK_ENUM_VALUE(BlurMode, Windows_Aero)
FRAMELESSHELPER_QUICK_ENUM_VALUE(BlurMode, Windows_Acrylic)
FRAMELESSHELPER_QUICK_ENUM_VALUE(BlurMode, Windows_Mica)
FRAMELESSHELPER_QUICK_ENUM_VALUE(BlurMode, Windows_MicaAlt)
};
Q_ENUM(BlurMode)
enum class WindowEdge
enum class WindowEdge : quint8
{
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowEdge, Left)
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowEdge, Top)
@ -204,10 +155,8 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QuickGlobal::WindowEdges)
namespace FramelessHelper::Quick
{
FRAMELESSHELPER_QUICK_API void initialize();
FRAMELESSHELPER_QUICK_API void uninitialize();
inline void initialize() { FramelessHelperQuickInitialize(); }
inline void uninitialize() { FramelessHelperQuickUninitialize(); }
} // namespace FramelessHelper::Quick
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(QuickGlobal))

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,29 +24,30 @@
#pragma once
#include "framelesshelperquick_global.h"
#include <FramelessHelper/Quick/framelesshelperquick_global.h>
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickwindow.h>
#include <memory>
FRAMELESSHELPER_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcFramelessQuickHelper)
#if FRAMELESSHELPER_CONFIG(mica_material)
class QuickMicaMaterial;
#endif
#if FRAMELESSHELPER_CONFIG(border_painter)
class QuickWindowBorder;
#endif
class FramelessQuickHelperPrivate;
class QuickMicaMaterial;
class QuickWindowBorder;
class FRAMELESSHELPER_QUICK_API FramelessQuickHelper : public QQuickItem
{
Q_OBJECT
FRAMELESSHELPER_PUBLIC_QT_CLASS(FramelessQuickHelper)
#ifdef QML_NAMED_ELEMENT
QML_NAMED_ELEMENT(FramelessHelper)
#endif
#ifdef QML_ATTACHED
QML_ATTACHED(FramelessQuickHelper)
#endif
Q_DECLARE_PRIVATE(FramelessQuickHelper)
Q_DISABLE_COPY_MOVE(FramelessQuickHelper)
Q_PROPERTY(QQuickItem* titleBarItem READ titleBarItem WRITE setTitleBarItem NOTIFY titleBarItemChanged FINAL)
Q_PROPERTY(bool windowFixedSize READ isWindowFixedSize WRITE setWindowFixedSize NOTIFY windowFixedSizeChanged FINAL)
Q_PROPERTY(bool blurBehindWindowEnabled READ isBlurBehindWindowEnabled WRITE setBlurBehindWindowEnabled NOTIFY blurBehindWindowEnabledChanged FINAL)
@ -65,8 +66,15 @@ public:
Q_NODISCARD bool isBlurBehindWindowEnabled() const;
Q_NODISCARD bool isContentExtendedIntoTitleBar() const;
#if FRAMELESSHELPER_CONFIG(mica_material)
Q_NODISCARD QuickMicaMaterial *micaMaterial() const;
#endif
#if FRAMELESSHELPER_CONFIG(border_painter)
Q_NODISCARD QuickWindowBorder *windowBorder() const;
#endif
Q_NODISCARD bool isReady() const;
void waitForReady();
public Q_SLOTS:
void extendsContentIntoTitleBar(const bool value = true);
@ -74,7 +82,9 @@ public Q_SLOTS:
void setTitleBarItem(QQuickItem *value);
void setSystemButton(QQuickItem *item, const QuickGlobal::SystemButtonType buttonType);
void setHitTestVisible(QQuickItem *item, const bool visible = true);
void setHitTestVisible(const QRect &rect, const bool visible = true);
void setHitTestVisible_rect(const QRect &rect, const bool visible = true);
void setHitTestVisible_object(QObject *object, const bool visible = true);
void setHitTestVisible_item(QQuickItem *item, const bool visible = true);
void showSystemMenu(const QPoint &pos);
void windowStartSystemMove2(const QPoint &pos);
@ -97,13 +107,8 @@ Q_SIGNALS:
void blurBehindWindowEnabledChanged();
void windowChanged2();
void ready();
private:
QScopedPointer<FramelessQuickHelperPrivate> d_ptr;
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickHelper))
QML_DECLARE_TYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickHelper))
QML_DECLARE_TYPEINFO(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickHelper), QML_HAS_ATTACHED_PROPERTIES)

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,7 +24,7 @@
#pragma once
#include "framelesshelperquick_global.h"
#include <FramelessHelper/Quick/framelesshelperquick_global.h>
QT_BEGIN_NAMESPACE
class QQmlEngine;
@ -32,11 +32,9 @@ QT_END_NAMESPACE
FRAMELESSHELPER_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcQuickModule)
namespace FramelessHelper::Quick
{
FRAMELESSHELPER_QUICK_API void registerTypes(QQmlEngine *engine);
inline void registerTypes(QQmlEngine *engine) { FramelessHelperQuickRegisterTypes(engine); }
} // namespace FramelessHelper::Quick
FRAMELESSHELPER_END_NAMESPACE

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,7 +24,7 @@
#pragma once
#include "framelesshelperquick_global.h"
#include <FramelessHelper/Quick/framelesshelperquick_global.h>
#include <QtQml/qqmlparserstatus.h>
QT_BEGIN_NAMESPACE
@ -33,12 +33,9 @@ QT_END_NAMESPACE
FRAMELESSHELPER_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcFramelessQuickUtils)
class FRAMELESSHELPER_QUICK_API FramelessQuickUtils : public QObject, public QQmlParserStatus
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(FramelessQuickUtils)
FRAMELESSHELPER_QT_CLASS(FramelessQuickUtils)
Q_INTERFACES(QQmlParserStatus)
#ifdef QML_NAMED_ELEMENT
QML_NAMED_ELEMENT(FramelessUtils)
@ -49,7 +46,7 @@ class FRAMELESSHELPER_QUICK_API FramelessQuickUtils : public QObject, public QQm
Q_PROPERTY(qreal titleBarHeight READ titleBarHeight CONSTANT FINAL)
Q_PROPERTY(bool frameBorderVisible READ frameBorderVisible CONSTANT FINAL)
Q_PROPERTY(qreal frameBorderThickness READ frameBorderThickness CONSTANT FINAL)
Q_PROPERTY(QuickGlobal::SystemTheme systemTheme READ systemTheme NOTIFY systemThemeChanged FINAL)
Q_PROPERTY(QuickGlobal::SystemTheme systemTheme READ systemTheme WRITE setOverrideTheme NOTIFY systemThemeChanged FINAL)
Q_PROPERTY(QColor systemAccentColor READ systemAccentColor NOTIFY systemAccentColorChanged FINAL)
Q_PROPERTY(bool titleBarColorized READ titleBarColorized NOTIFY titleBarColorizedChanged FINAL)
Q_PROPERTY(QColor defaultSystemLightColor READ defaultSystemLightColor CONSTANT FINAL)
@ -58,6 +55,7 @@ class FRAMELESSHELPER_QUICK_API FramelessQuickUtils : public QObject, public QQm
Q_PROPERTY(QSizeF defaultSystemButtonIconSize READ defaultSystemButtonIconSize CONSTANT FINAL)
Q_PROPERTY(QColor defaultSystemButtonBackgroundColor READ defaultSystemButtonBackgroundColor CONSTANT FINAL)
Q_PROPERTY(QColor defaultSystemCloseButtonBackgroundColor READ defaultSystemCloseButtonBackgroundColor CONSTANT FINAL)
Q_PROPERTY(bool blurBehindWindowSupported READ blurBehindWindowSupported CONSTANT FINAL)
public:
explicit FramelessQuickUtils(QObject *parent = nullptr);
@ -67,6 +65,7 @@ public:
Q_NODISCARD bool frameBorderVisible() const;
Q_NODISCARD qreal frameBorderThickness() const;
Q_NODISCARD QuickGlobal::SystemTheme systemTheme() const;
void setOverrideTheme(const QuickGlobal::SystemTheme theme);
Q_NODISCARD QColor systemAccentColor() const;
Q_NODISCARD bool titleBarColorized() const;
Q_NODISCARD QColor defaultSystemLightColor() const;
@ -75,8 +74,9 @@ public:
Q_NODISCARD QSizeF defaultSystemButtonIconSize() const;
Q_NODISCARD QColor defaultSystemButtonBackgroundColor() const;
Q_NODISCARD QColor defaultSystemCloseButtonBackgroundColor() const;
Q_NODISCARD bool blurBehindWindowSupported() const;
Q_NODISCARD Q_INVOKABLE QColor getSystemButtonBackgroundColor(
Q_NODISCARD Q_SLOT QColor getSystemButtonBackgroundColor(
const QuickGlobal::SystemButtonType button, const QuickGlobal::ButtonState state);
protected:
@ -90,6 +90,3 @@ Q_SIGNALS:
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickUtils))
QML_DECLARE_TYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickUtils))

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,21 +24,22 @@
#pragma once
#include "framelesshelperquick_global.h"
#include <FramelessHelper/Quick/framelesshelperquick_global.h>
#include <memory>
#if (FRAMELESSHELPER_CONFIG(private_qt) && FRAMELESSHELPER_CONFIG(window) && (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)))
#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h>
FRAMELESSHELPER_BEGIN_NAMESPACE
class FramelessQuickApplicationWindowPrivate;
class FRAMELESSHELPER_QUICK_API FramelessQuickApplicationWindow : public QQuickApplicationWindow
{
Q_OBJECT
FRAMELESSHELPER_PUBLIC_QT_CLASS(FramelessQuickApplicationWindow)
#ifdef QML_NAMED_ELEMENT
QML_NAMED_ELEMENT(FramelessApplicationWindow)
#endif
Q_DECLARE_PRIVATE(FramelessQuickApplicationWindow)
Q_DISABLE_COPY_MOVE(FramelessQuickApplicationWindow)
Q_PROPERTY(bool hidden READ isHidden NOTIFY hiddenChanged FINAL)
Q_PROPERTY(bool normal READ isNormal NOTIFY normalChanged FINAL)
Q_PROPERTY(bool minimized READ isMinimized NOTIFY minimizedChanged FINAL)
@ -73,12 +74,8 @@ Q_SIGNALS:
void maximizedChanged();
void zoomedChanged();
void fullScreenChanged();
private:
QScopedPointer<FramelessQuickApplicationWindowPrivate> d_ptr;
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickApplicationWindow))
QML_DECLARE_TYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickApplicationWindow))
#endif

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,47 +24,33 @@
#pragma once
#include "framelesshelperquick_global.h"
#include "framelessquickapplicationwindow_p.h"
#include <FramelessHelper/Quick/framelesshelperquick_global.h>
#if (FRAMELESSHELPER_CONFIG(private_qt) && FRAMELESSHELPER_CONFIG(window) && (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)))
#include <QtQuick/qquickwindow.h>
FRAMELESSHELPER_BEGIN_NAMESPACE
#if FRAMELESSHELPER_CONFIG(border_painter)
class QuickWindowBorder;
#endif
class FramelessQuickApplicationWindow;
class FRAMELESSHELPER_QUICK_API FramelessQuickApplicationWindowPrivate : public QObject
{
Q_OBJECT
Q_DECLARE_PUBLIC(FramelessQuickApplicationWindow)
Q_DISABLE_COPY_MOVE(FramelessQuickApplicationWindowPrivate)
FRAMELESSHELPER_PRIVATE_QT_CLASS(FramelessQuickApplicationWindow)
public:
explicit FramelessQuickApplicationWindowPrivate(FramelessQuickApplicationWindow *q);
~FramelessQuickApplicationWindowPrivate() override;
Q_NODISCARD static FramelessQuickApplicationWindowPrivate *get(FramelessQuickApplicationWindow *pub);
Q_NODISCARD static const FramelessQuickApplicationWindowPrivate *get(const FramelessQuickApplicationWindow *pub);
Q_INVOKABLE Q_NODISCARD bool isHidden() const;
Q_INVOKABLE Q_NODISCARD bool isNormal() const;
Q_INVOKABLE Q_NODISCARD bool isMinimized() const;
Q_INVOKABLE Q_NODISCARD bool isMaximized() const;
Q_INVOKABLE Q_NODISCARD bool isZoomed() const;
Q_INVOKABLE Q_NODISCARD bool isFullScreen() const;
public Q_SLOTS:
void showMinimized2();
void toggleMaximized();
void toggleFullScreen();
private:
void initialize();
private:
QPointer<FramelessQuickApplicationWindow> q_ptr = nullptr;
QScopedPointer<QuickWindowBorder> m_windowBorder;
QQuickWindow::Visibility m_savedVisibility = QQuickWindow::Windowed;
QQuickWindow::Visibility savedVisibility = QQuickWindow::Windowed;
#if FRAMELESSHELPER_CONFIG(border_painter)
QuickWindowBorder *windowBorder = nullptr;
#endif
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickApplicationWindowPrivate))
#endif

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,8 +24,9 @@
#pragma once
#include "framelesshelperquick_global.h"
#include "framelessquickhelper.h"
#include <FramelessHelper/Quick/framelesshelperquick_global.h>
#include <QtCore/qtimer.h>
#include <optional>
QT_BEGIN_NAMESPACE
class QQuickItem;
@ -33,76 +34,58 @@ QT_END_NAMESPACE
FRAMELESSHELPER_BEGIN_NAMESPACE
struct QuickHelperData;
#if FRAMELESSHELPER_CONFIG(mica_material)
class QuickMicaMaterial;
#endif
#if FRAMELESSHELPER_CONFIG(border_painter)
class QuickWindowBorder;
#endif
class FramelessQuickHelper;
class FRAMELESSHELPER_QUICK_API FramelessQuickHelperPrivate : public QObject
{
Q_OBJECT
Q_DECLARE_PUBLIC(FramelessQuickHelper)
Q_DISABLE_COPY_MOVE(FramelessQuickHelperPrivate)
FRAMELESSHELPER_PRIVATE_QT_CLASS(FramelessQuickHelper)
public:
explicit FramelessQuickHelperPrivate(FramelessQuickHelper *q);
~FramelessQuickHelperPrivate() override;
Q_NODISCARD static FramelessQuickHelperPrivate *get(FramelessQuickHelper *pub);
Q_NODISCARD static const FramelessQuickHelperPrivate *get(const FramelessQuickHelper *pub);
Q_NODISCARD bool isContentExtendedIntoTitleBar() const;
void extendsContentIntoTitleBar(const bool value);
Q_NODISCARD QQuickItem *getTitleBarItem() const;
void setTitleBarItem(QQuickItem *value);
void attach();
void detach();
void setSystemButton(QQuickItem *item, const QuickGlobal::SystemButtonType buttonType);
void setHitTestVisible(QQuickItem *item, const bool visible = true);
void setHitTestVisible(const QRect &rect, const bool visible = true);
void showSystemMenu(const QPoint &pos);
void windowStartSystemMove2(const QPoint &pos);
void windowStartSystemResize2(const Qt::Edges edges, const QPoint &pos);
void moveWindowToDesktopCenter();
void bringWindowToFront();
void emitSignalForAllInstances(const char *signal);
Q_NODISCARD bool isWindowFixedSize() const;
void setWindowFixedSize(const bool value);
void emitSignalForAllInstances(const QByteArray &signal);
Q_NODISCARD bool isBlurBehindWindowEnabled() const;
void setBlurBehindWindowEnabled(const bool value, const QColor &color);
void setProperty(const QByteArray &name, const QVariant &value);
Q_NODISCARD QVariant getProperty(const QByteArray &name, const QVariant &defaultValue = {});
void setProperty(const char *name, const QVariant &value);
Q_NODISCARD QVariant getProperty(const char *name, const QVariant &defaultValue = {});
#if FRAMELESSHELPER_CONFIG(mica_material)
Q_NODISCARD QuickMicaMaterial *findOrCreateMicaMaterial() const;
#endif
#if FRAMELESSHELPER_CONFIG(border_painter)
Q_NODISCARD QuickWindowBorder *findOrCreateWindowBorder() const;
#endif
Q_NODISCARD static FramelessQuickHelper *findOrCreateFramelessHelper(QObject *object);
protected:
Q_NODISCARD bool eventFilter(QObject *object, QEvent *event) override;
void repaintAllChildren();
Q_INVOKABLE void doRepaintAllChildren();
Q_NODISCARD quint32 readyWaitTime() const;
void setReadyWaitTime(const quint32 time);
private:
Q_NODISCARD QRect mapItemGeometryToScene(const QQuickItem * const item) const;
Q_NODISCARD bool isInSystemButtons(const QPoint &pos, QuickGlobal::SystemButtonType *button) const;
Q_NODISCARD bool isInTitleBarDraggableArea(const QPoint &pos) const;
Q_NODISCARD bool shouldIgnoreMouseEvents(const QPoint &pos) const;
void setSystemButtonState(const QuickGlobal::SystemButtonType button, const QuickGlobal::ButtonState state);
Q_NODISCARD QuickHelperData getWindowData() const;
Q_NODISCARD QuickHelperData *getWindowDataMutable() const;
void rebindWindow();
private:
QPointer<FramelessQuickHelper> q_ptr = nullptr;
QColor m_savedWindowBackgroundColor = {};
bool m_blurBehindWindowEnabled = false;
std::optional<bool> m_extendIntoTitleBar = std::nullopt;
bool m_destroying = false;
QColor savedWindowBackgroundColor = {};
bool blurBehindWindowEnabled = false;
std::optional<bool> extendIntoTitleBar = std::nullopt;
bool qpaReady = false;
quint32 qpaWaitTime = 0;
QTimer repaintTimer{};
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickHelperPrivate))

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,21 +24,22 @@
#pragma once
#include "framelesshelperquick_global.h"
#include <FramelessHelper/Quick/framelesshelperquick_global.h>
#include <memory>
#if (FRAMELESSHELPER_CONFIG(private_qt) && FRAMELESSHELPER_CONFIG(window))
#include <QtQuick/private/qquickwindowmodule_p.h>
FRAMELESSHELPER_BEGIN_NAMESPACE
class FramelessQuickWindowPrivate;
class FRAMELESSHELPER_QUICK_API FramelessQuickWindow : public QQuickWindowQmlImpl
{
Q_OBJECT
FRAMELESSHELPER_PUBLIC_QT_CLASS(FramelessQuickWindow)
#ifdef QML_NAMED_ELEMENT
QML_NAMED_ELEMENT(FramelessWindow)
#endif
Q_DECLARE_PRIVATE(FramelessQuickWindow)
Q_DISABLE_COPY_MOVE(FramelessQuickWindow)
Q_PROPERTY(bool hidden READ isHidden NOTIFY hiddenChanged FINAL)
Q_PROPERTY(bool normal READ isNormal NOTIFY normalChanged FINAL)
Q_PROPERTY(bool minimized READ isMinimized NOTIFY minimizedChanged FINAL)
@ -73,12 +74,8 @@ Q_SIGNALS:
void maximizedChanged();
void zoomedChanged();
void fullScreenChanged();
private:
QScopedPointer<FramelessQuickWindowPrivate> d_ptr;
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickWindow))
QML_DECLARE_TYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickWindow))
#endif

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,47 +24,33 @@
#pragma once
#include "framelesshelperquick_global.h"
#include "framelessquickwindow_p.h"
#include <FramelessHelper/Quick/framelesshelperquick_global.h>
#if (FRAMELESSHELPER_CONFIG(private_qt) && FRAMELESSHELPER_CONFIG(window))
#include <QtQuick/qquickwindow.h>
FRAMELESSHELPER_BEGIN_NAMESPACE
#if FRAMELESSHELPER_CONFIG(border_painter)
class QuickWindowBorder;
#endif
class FramelessQuickWindow;
class FRAMELESSHELPER_QUICK_API FramelessQuickWindowPrivate : public QObject
{
Q_OBJECT
Q_DECLARE_PUBLIC(FramelessQuickWindow)
Q_DISABLE_COPY_MOVE(FramelessQuickWindowPrivate)
FRAMELESSHELPER_PRIVATE_QT_CLASS(FramelessQuickWindow)
public:
explicit FramelessQuickWindowPrivate(FramelessQuickWindow *q);
~FramelessQuickWindowPrivate() override;
Q_NODISCARD static FramelessQuickWindowPrivate *get(FramelessQuickWindow *pub);
Q_NODISCARD static const FramelessQuickWindowPrivate *get(const FramelessQuickWindow *pub);
Q_INVOKABLE Q_NODISCARD bool isHidden() const;
Q_INVOKABLE Q_NODISCARD bool isNormal() const;
Q_INVOKABLE Q_NODISCARD bool isMinimized() const;
Q_INVOKABLE Q_NODISCARD bool isMaximized() const;
Q_INVOKABLE Q_NODISCARD bool isZoomed() const;
Q_INVOKABLE Q_NODISCARD bool isFullScreen() const;
public Q_SLOTS:
void showMinimized2();
void toggleMaximized();
void toggleFullScreen();
private:
void initialize();
private:
QPointer<FramelessQuickWindow> q_ptr = nullptr;
QScopedPointer<QuickWindowBorder> m_windowBorder;
QQuickWindow::Visibility m_savedVisibility = QQuickWindow::Windowed;
QQuickWindow::Visibility savedVisibility = QQuickWindow::Windowed;
#if FRAMELESSHELPER_CONFIG(border_painter)
QuickWindowBorder *windowBorder = nullptr;
#endif
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickWindowPrivate))
#endif

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,44 +24,47 @@
#pragma once
#include "framelesshelperquick_global.h"
#include "quickimageitem.h"
#include <FramelessHelper/Quick/framelesshelperquick_global.h>
#include <QtCore/qvariant.h>
#include <QtQuick/qquickpainteditem.h>
FRAMELESSHELPER_BEGIN_NAMESPACE
class FRAMELESSHELPER_QUICK_API QuickImageItemPrivate : public QObject
class FRAMELESSHELPER_QUICK_API QuickImageItem : public QQuickPaintedItem
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(QuickImageItemPrivate)
Q_DECLARE_PUBLIC(QuickImageItem)
FRAMELESSHELPER_QT_CLASS(QuickImageItem)
#ifdef QML_NAMED_ELEMENT
QML_NAMED_ELEMENT(ImageItem)
#endif
Q_PROPERTY(QVariant source READ source WRITE setSource NOTIFY sourceChanged FINAL)
public:
explicit QuickImageItemPrivate(QuickImageItem *q);
~QuickImageItemPrivate() override;
explicit QuickImageItem(QQuickItem *parent = nullptr);
~QuickImageItem() override;
Q_NODISCARD static QuickImageItemPrivate *get(QuickImageItem *q);
Q_NODISCARD static const QuickImageItemPrivate *get(const QuickImageItem *q);
void paint(QPainter *painter) const;
void paint(QPainter *painter) override;
Q_NODISCARD QVariant source() const;
void setSource(const QVariant &value);
Q_SIGNALS:
void sourceChanged();
protected:
void classBegin() override;
void componentComplete() override;
private:
void initialize();
void fromUrl(const QUrl &value, QPainter *painter) const;
void fromString(const QString &value, QPainter *painter) const;
void fromImage(const QImage &value, QPainter *painter) const;
void fromPixmap(const QPixmap &value, QPainter *painter) const;
void fromIcon(const QIcon &value, QPainter *painter) const;
Q_NODISCARD QRect paintArea() const;
Q_NODISCARD QRectF paintArea() const;
private:
QPointer<QuickImageItem> q_ptr = nullptr;
QVariant m_source = {};
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(QuickImageItemPrivate))

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,41 +24,33 @@
#pragma once
#include "framelesshelperquick_global.h"
#include "quickmicamaterial.h"
#include <FramelessHelper/Quick/framelesshelperquick_global.h>
#if FRAMELESSHELPER_CONFIG(mica_material)
FRAMELESSHELPER_BEGIN_NAMESPACE
class WallpaperImageNode;
class MicaMaterial;
class QuickMicaMaterial;
class FRAMELESSHELPER_QUICK_API QuickMicaMaterialPrivate : public QObject
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(QuickMicaMaterialPrivate)
Q_DECLARE_PUBLIC(QuickMicaMaterial)
FRAMELESSHELPER_PRIVATE_QT_CLASS(QuickMicaMaterial)
public:
explicit QuickMicaMaterialPrivate(QuickMicaMaterial *q);
~QuickMicaMaterialPrivate() override;
Q_NODISCARD static QuickMicaMaterialPrivate *get(QuickMicaMaterial *q);
Q_NODISCARD static const QuickMicaMaterialPrivate *get(const QuickMicaMaterial *q);
Q_SLOT void rebindWindow();
public Q_SLOTS:
void rebindWindow();
void forceRegenerateWallpaperImageCache();
void appendNode(WallpaperImageNode *node);
private:
void initialize();
private:
QPointer<QuickMicaMaterial> q_ptr = nullptr;
QMetaObject::Connection m_rootWindowXChangedConnection = {};
QMetaObject::Connection m_rootWindowYChangedConnection = {};
QList<QPointer<WallpaperImageNode>> m_nodes = {};
QMetaObject::Connection rootWindowXChangedConnection = {};
QMetaObject::Connection rootWindowYChangedConnection = {};
QMetaObject::Connection rootWindowActiveChangedConnection = {};
MicaMaterial *micaMaterial = nullptr;
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(QuickMicaMaterialPrivate))
#endif

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,8 +24,10 @@
#pragma once
#include "framelesshelperquick_global.h"
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
#include <FramelessHelper/Quick/framelesshelperquick_global.h>
#if (FRAMELESSHELPER_CONFIG(private_qt) && FRAMELESSHELPER_CONFIG(system_button) && (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)))
#include <QtQuickTemplates2/private/qquickbutton_p.h>
QT_BEGIN_NAMESPACE
@ -37,19 +39,18 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
class FRAMELESSHELPER_QUICK_API QuickStandardSystemButton : public QQuickButton
{
Q_OBJECT
FRAMELESSHELPER_QT_CLASS(QuickStandardSystemButton)
#ifdef QML_NAMED_ELEMENT
QML_NAMED_ELEMENT(StandardSystemButton)
#endif
Q_DISABLE_COPY_MOVE(QuickStandardSystemButton)
Q_PROPERTY(QuickGlobal::SystemButtonType buttonType READ buttonType WRITE setButtonType NOTIFY buttonTypeChanged FINAL)
Q_PROPERTY(QString code READ code WRITE setCode NOTIFY codeChanged FINAL)
Q_PROPERTY(QString glyph READ glyph WRITE setGlyph NOTIFY glyphChanged FINAL)
Q_PROPERTY(QColor hoverColor READ hoverColor WRITE setHoverColor NOTIFY hoverColorChanged FINAL)
Q_PROPERTY(QColor pressColor READ pressColor WRITE setPressColor NOTIFY pressColorChanged FINAL)
Q_PROPERTY(QColor normalColor READ normalColor WRITE setNormalColor NOTIFY normalColorChanged FINAL)
Q_PROPERTY(QColor activeForegroundColor READ activeForegroundColor WRITE setActiveForegroundColor NOTIFY activeForegroundColorChanged FINAL)
Q_PROPERTY(QColor inactiveForegroundColor READ inactiveForegroundColor WRITE setInactiveForegroundColor NOTIFY inactiveForegroundColorChanged FINAL)
Q_PROPERTY(qreal iconSize READ iconSize WRITE setIconSize NOTIFY iconSizeChanged FINAL)
Q_PROPERTY(qreal glyphSize READ glyphSize WRITE setGlyphSize NOTIFY glyphChanged FINAL)
public:
explicit QuickStandardSystemButton(QQuickItem *parent = nullptr);
@ -57,24 +58,24 @@ public:
~QuickStandardSystemButton() override;
Q_NODISCARD QuickGlobal::SystemButtonType buttonType() const;
Q_NODISCARD QString code() const;
Q_NODISCARD QString glyph() const;
Q_NODISCARD QColor normalColor() const;
Q_NODISCARD QColor hoverColor() const;
Q_NODISCARD QColor pressColor() const;
Q_NODISCARD QColor activeForegroundColor() const;
Q_NODISCARD QColor inactiveForegroundColor() const;
Q_NODISCARD qreal iconSize() const;
Q_NODISCARD qreal glyphSize() const;
public Q_SLOTS:
void updateColor();
void setButtonType(const QuickGlobal::SystemButtonType type);
void setCode(const QString &value);
void setGlyph(const QString &value);
void setNormalColor(const QColor &value);
void setHoverColor(const QColor &value);
void setPressColor(const QColor &value);
void setActiveForegroundColor(const QColor &value);
void setInactiveForegroundColor(const QColor &value);
void setIconSize(const qreal value);
void setGlyphSize(const qreal value);
protected:
void classBegin() override;
@ -85,19 +86,19 @@ private:
Q_SIGNALS:
void buttonTypeChanged();
void codeChanged();
void glyphChanged();
void normalColorChanged();
void hoverColorChanged();
void pressColorChanged();
void activeForegroundColorChanged();
void inactiveForegroundColorChanged();
void iconSizeChanged();
void glyphSizeChanged();
private:
QScopedPointer<QQuickText> m_contentItem;
QScopedPointer<QQuickRectangle> m_backgroundItem;
QQuickText *m_contentItem = nullptr;
QQuickRectangle *m_backgroundItem = nullptr;
QuickGlobal::SystemButtonType m_buttonType = QuickGlobal::SystemButtonType::Unknown;
QString m_code = {};
QString m_glyph = {};
QColor m_normalColor = {};
QColor m_hoverColor = {};
QColor m_pressColor = {};
@ -107,6 +108,4 @@ private:
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(QuickStandardSystemButton))
QML_DECLARE_TYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(QuickStandardSystemButton))
#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
#endif

View File

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,10 +24,14 @@
#pragma once
#include "framelesshelperquick_global.h"
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
#include "quickchromepalette.h"
#include "quickstandardsystembutton_p.h"
#include <FramelessHelper/Quick/framelesshelperquick_global.h>
#if (FRAMELESSHELPER_CONFIG(private_qt) && FRAMELESSHELPER_CONFIG(titlebar) && (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)))
#include <FramelessHelper/Quick/quickchromepalette.h>
#if FRAMELESSHELPER_CONFIG(system_button)
# include <FramelessHelper/Quick/private/quickstandardsystembutton_p.h>
#endif
#include <QtQuick/private/qquickrectangle_p.h>
#include <QtQuickTemplates2/private/qquicklabel_p.h>
@ -41,16 +45,17 @@ class QuickImageItem;
class FRAMELESSHELPER_QUICK_API QuickStandardTitleBar : public QQuickRectangle
{
Q_OBJECT
FRAMELESSHELPER_QT_CLASS(QuickStandardTitleBar)
#ifdef QML_NAMED_ELEMENT
QML_NAMED_ELEMENT(StandardTitleBar)
#endif
Q_DISABLE_COPY_MOVE(QuickStandardTitleBar)
#endif // QML_NAMED_ELEMENT
Q_PROPERTY(Qt::Alignment titleLabelAlignment READ titleLabelAlignment WRITE setTitleLabelAlignment NOTIFY titleLabelAlignmentChanged FINAL)
Q_PROPERTY(QQuickLabel* titleLabel READ titleLabel CONSTANT FINAL)
#if (!defined(Q_OS_MACOS) && FRAMELESSHELPER_CONFIG(system_button))
Q_PROPERTY(QuickStandardSystemButton* minimizeButton READ minimizeButton CONSTANT FINAL)
Q_PROPERTY(QuickStandardSystemButton* maximizeButton READ maximizeButton CONSTANT FINAL)
Q_PROPERTY(QuickStandardSystemButton* closeButton READ closeButton CONSTANT FINAL)
#endif // Q_OS_MACOS
Q_PROPERTY(bool extended READ isExtended WRITE setExtended NOTIFY extendedChanged FINAL)
Q_PROPERTY(bool hideWhenClose READ isHideWhenClose WRITE setHideWhenClose NOTIFY hideWhenCloseChanged FINAL)
Q_PROPERTY(QuickChromePalette* chromePalette READ chromePalette CONSTANT FINAL)
@ -66,9 +71,11 @@ public:
void setTitleLabelAlignment(const Qt::Alignment value);
Q_NODISCARD QQuickLabel *titleLabel() const;
#if (!defined(Q_OS_MACOS) && FRAMELESSHELPER_CONFIG(system_button))
Q_NODISCARD QuickStandardSystemButton *minimizeButton() const;
Q_NODISCARD QuickStandardSystemButton *maximizeButton() const;
Q_NODISCARD QuickStandardSystemButton *closeButton() const;
#endif // Q_OS_MACOS
Q_NODISCARD bool isExtended() const;
void setExtended(const bool value);
@ -122,23 +129,23 @@ private:
private:
Qt::Alignment m_labelAlignment = {};
QScopedPointer<QuickImageItem> m_windowIcon;
QScopedPointer<QQuickLabel> m_windowTitleLabel;
QScopedPointer<QQuickRow> m_systemButtonsRow;
QScopedPointer<QuickStandardSystemButton> m_minimizeButton;
QScopedPointer<QuickStandardSystemButton> m_maximizeButton;
QScopedPointer<QuickStandardSystemButton> m_closeButton;
QuickImageItem *m_windowIcon = nullptr;
QQuickLabel *m_windowTitleLabel = nullptr;
#if (!defined(Q_OS_MACOS) && FRAMELESSHELPER_CONFIG(system_button))
QQuickRow *m_systemButtonsRow = nullptr;
QuickStandardSystemButton *m_minimizeButton = nullptr;
QuickStandardSystemButton *m_maximizeButton = nullptr;
QuickStandardSystemButton *m_closeButton = nullptr;
#endif // Q_OS_MACOS
QMetaObject::Connection m_windowStateChangeConnection = {};
QMetaObject::Connection m_windowActiveChangeConnection = {};
QMetaObject::Connection m_windowTitleChangeConnection = {};
bool m_extended = false;
bool m_hideWhenClose = false;
QScopedPointer<QuickChromePalette> m_chromePalette;
QuickChromePalette *m_chromePalette = nullptr;
bool m_closeTriggered = false;
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(QuickStandardTitleBar))
QML_DECLARE_TYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(QuickStandardTitleBar))
#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
#endif

Some files were not shown because too many files have changed in this diff Show More