Author SHA1 Message Date
zach 54d4676ddf Merge branch 'main' into feat/llm-chat-tab
C++ / fmt (pull_request) Successful in 4s
C++ / build (pull_request) Failing after 2m3s
C++ / clang-tidy (pull_request) Failing after 2m2s
JS/TS / fmt (pull_request) Failing after 12s
JS/TS / lint (pull_request) Successful in 9s
Python / static (pull_request) Successful in 29s
Rust / build (pull_request) Successful in 51s
Python / verify (pull_request) Successful in 1m35s
Rust / fmt (pull_request) Successful in 33s
Rust / clippy (pull_request) Successful in 57s
2026-09-04 19:44:12 +02:00
zach bd699e72a7 fix: polkit width 2026-09-04 19:43:13 +02:00
zach cd3da1941b fix: truncate context logic
C++ / fmt (pull_request) Successful in 4s
C++ / build (pull_request) Failing after 2m6s
C++ / clang-tidy (pull_request) Failing after 2m5s
JS/TS / fmt (pull_request) Failing after 3m8s
Python / static (pull_request) Successful in 24s
Python / verify (pull_request) Successful in 1m21s
JS/TS / lint (pull_request) Successful in 5m10s
Rust / fmt (pull_request) Successful in 30s
Rust / build (pull_request) Successful in 56s
Rust / clippy (pull_request) Successful in 46s
2026-09-04 02:20:37 +02:00
zach 34dde4bbfb fix: tool call prompt
C++ / fmt (pull_request) Failing after 4s
C++ / build (pull_request) Failing after 2m4s
C++ / clang-tidy (pull_request) Failing after 2m2s
JS/TS / fmt (pull_request) Failing after 6s
JS/TS / lint (pull_request) Successful in 9s
Python / static (pull_request) Successful in 27s
Rust / build (pull_request) Successful in 47s
Python / verify (pull_request) Successful in 1m35s
Rust / fmt (pull_request) Successful in 27s
Rust / clippy (pull_request) Successful in 49s
2026-09-03 23:45:07 +02:00
zach fcb848b6d2 fix: truncate webfetch content to fit context
C++ / fmt (pull_request) Failing after 5s
C++ / build (pull_request) Failing after 2m18s
C++ / clang-tidy (pull_request) Failing after 2m7s
JS/TS / fmt (pull_request) Failing after 9s
JS/TS / lint (pull_request) Successful in 9s
Python / static (pull_request) Successful in 29s
Rust / build (pull_request) Successful in 50s
Python / verify (pull_request) Successful in 1m38s
Rust / fmt (pull_request) Successful in 26s
Rust / clippy (pull_request) Successful in 47s
2026-09-03 22:46:46 +02:00
zach ed7ec326b1 fix: idlemonitors list value 2026-09-03 16:15:55 +02:00
zach ae5c1fa148 use blobgroup for window chat interface + slim sidebar
C++ / fmt (pull_request) Successful in 4s
C++ / build (pull_request) Failing after 2m1s
C++ / clang-tidy (pull_request) Failing after 1m54s
JS/TS / fmt (pull_request) Failing after 7s
JS/TS / lint (pull_request) Successful in 7s
Python / static (pull_request) Successful in 29s
Rust / build (pull_request) Successful in 47s
Python / verify (pull_request) Successful in 1m35s
Rust / fmt (pull_request) Successful in 29s
Rust / clippy (pull_request) Successful in 51s
2026-09-01 23:14:21 +02:00
zach b254000737 feat: implement findChild* methods
C++ / fmt (pull_request) Canceled after 0s
C++ / build (pull_request) Canceled after 0s
C++ / clang-tidy (pull_request) Canceled after 0s
JS/TS / lint (pull_request) Canceled after 0s
JS/TS / fmt (pull_request) Canceled after 2s
Python / static (pull_request) Canceled after 0s
Python / verify (pull_request) Canceled after 0s
Rust / build (pull_request) Canceled after 0s
Rust / fmt (pull_request) Canceled after 0s
Rust / clippy (pull_request) Canceled after 0s
2026-09-01 15:51:10 +02:00
zach 04fe8b1e43 feat: implement findChild* methods
C++ / fmt (pull_request) Canceled after 0s
C++ / build (pull_request) Canceled after 0s
C++ / clang-tidy (pull_request) Canceled after 0s
JS/TS / fmt (pull_request) Canceled after 0s
JS/TS / lint (pull_request) Canceled after 0s
Python / static (pull_request) Canceled after 0s
Python / verify (pull_request) Canceled after 0s
Rust / build (pull_request) Canceled after 0s
Rust / fmt (pull_request) Canceled after 0s
Rust / clippy (pull_request) Canceled after 0s
2026-09-01 15:49:21 +02:00
zach dfa6b010e6 fix: property link modules
C++ / fmt (pull_request) Canceled after 0s
C++ / build (pull_request) Canceled after 0s
C++ / clang-tidy (pull_request) Canceled after 0s
JS/TS / lint (pull_request) Canceled after 0s
JS/TS / fmt (pull_request) Canceled after 1s
Python / static (pull_request) Canceled after 0s
Python / verify (pull_request) Canceled after 0s
Rust / build (pull_request) Canceled after 0s
Rust / fmt (pull_request) Canceled after 0s
Rust / clippy (pull_request) Canceled after 0s
2026-09-01 15:42:27 +02:00
zach 8a4e9bac31 fix: add gnuinstalldirs include
C++ / fmt (pull_request) Successful in 6s
C++ / build (pull_request) Canceled after 15s
C++ / clang-tidy (pull_request) Canceled after 9s
JS/TS / fmt (pull_request) Canceled after 0s
JS/TS / lint (pull_request) Canceled after 0s
Python / verify (pull_request) Canceled after 0s
Python / static (pull_request) Canceled after 1s
Rust / fmt (pull_request) Canceled after 0s
Rust / clippy (pull_request) Canceled after 0s
Rust / build (pull_request) Canceled after 6s
2026-09-01 15:28:25 +02:00
zach f20fa45b29 fix: cmake install dir
Rust / build (pull_request) Canceled after 0s
Rust / fmt (pull_request) Canceled after 0s
Rust / clippy (pull_request) Canceled after 0s
Python / static (pull_request) Canceled after 0s
Python / verify (pull_request) Canceled after 0s
JS/TS / fmt (pull_request) Canceled after 0s
JS/TS / lint (pull_request) Canceled after 0s
C++ / fmt (pull_request) Canceled after 0s
C++ / build (pull_request) Canceled after 0s
C++ / clang-tidy (pull_request) Canceled after 0s
2026-09-01 15:15:15 +02:00
zach 53a3c76dc0 fix: cmake install dir
C++ / fmt (pull_request) Successful in 7s
JS/TS / fmt (pull_request) Failing after 14s
JS/TS / lint (pull_request) Successful in 18s
Python / static (pull_request) Successful in 57s
C++ / build (pull_request) Failing after 3m50s
C++ / clang-tidy (pull_request) Failing after 3m32s
Python / verify (pull_request) Canceled after 0s
Rust / build (pull_request) Canceled after 0s
Rust / fmt (pull_request) Canceled after 0s
Rust / clippy (pull_request) Canceled after 0s
2026-09-01 15:03:42 +02:00
zach 617e87d64f fix: uncomment settings index cache path
C++ / fmt (pull_request) Successful in 10s
C++ / clang-tidy (pull_request) Failing after 15m10s
C++ / build (pull_request) Failing after 16m4s
JS/TS / fmt (pull_request) Failing after 10s
JS/TS / lint (pull_request) Successful in 11s
Python / static (pull_request) Successful in 53s
Rust / fmt (pull_request) Successful in 1m33s
Rust / build (pull_request) Successful in 3m3s
Rust / clippy (pull_request) Successful in 2m59s
Python / verify (pull_request) Successful in 3m58s
2026-09-01 14:31:44 +02:00
zach ef2fb95fab chore: split cmake into multiple files and fix settings searching regex + add enabled option to llm
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Failing after 17s
JS/TS / lint (pull_request) Successful in 19s
Python / static (pull_request) Successful in 1m11s
Rust / fmt (pull_request) Successful in 1m3s
Rust / build (pull_request) Successful in 2m26s
Rust / clippy (pull_request) Failing after 16m40s
Python / verify (pull_request) Failing after 17m52s
C++ / clang-tidy (pull_request) Failing after 18m0s
C++ / build (pull_request) Failing after 18m2s
2026-09-01 14:30:04 +02:00
zach 2150859847 fix: font family
JS/TS / fmt (pull_request) Successful in 19s
JS/TS / lint (pull_request) Successful in 18s
Rust / fmt (pull_request) Canceled after 0s
Rust / clippy (pull_request) Canceled after 0s
Rust / build (pull_request) Canceled after 5m56s
Python / static (pull_request) Canceled after 6m44s
Python / verify (pull_request) Canceled after 6m40s
C++ / fmt (pull_request) Successful in 8s
C++ / clang-tidy (pull_request) Canceled after 7m8s
C++ / build (pull_request) Failing after 1m24s
2026-08-31 22:54:52 +02:00
AramJonghu c9f7856982 fix(Docker): add required deps to dockerfile
JS/TS / fmt (pull_request) Successful in 11s
JS/TS / lint (pull_request) Successful in 11s
Python / static (pull_request) Successful in 45s
Rust / fmt (pull_request) Successful in 2m0s
Rust / build (pull_request) Successful in 2m24s
Rust / clippy (pull_request) Successful in 2m24s
Python / verify (pull_request) Successful in 2m48s
C++ / fmt (pull_request) Successful in 4s
C++ / clang-tidy (pull_request) Canceled after 5m34s
C++ / build (pull_request) Canceled after 0s
2026-08-31 22:46:42 +02:00
zachandAramJonghu 51dc0fc026 chore: format python codeicons 2026-08-31 22:44:57 +02:00
zach cef91caebc chore: format llm c files
C++ / fmt (pull_request) Successful in 16s
C++ / build (pull_request) Failing after 19s
JS/TS / fmt (pull_request) Successful in 10s
C++ / clang-tidy (pull_request) Failing after 29s
JS/TS / lint (pull_request) Successful in 23s
Python / static (pull_request) Failing after 48s
Rust / fmt (pull_request) Successful in 1m15s
Rust / build (pull_request) Successful in 1m46s
Rust / clippy (pull_request) Successful in 1m33s
Python / verify (pull_request) Successful in 2m16s
2026-08-31 19:06:49 +02:00
zach c5a089adaf chore: format llm c files
C++ / fmt (pull_request) Failing after 4s
C++ / build (pull_request) Failing after 10s
JS/TS / fmt (pull_request) Successful in 22s
JS/TS / lint (pull_request) Successful in 16s
Python / static (pull_request) Failing after 37s
C++ / clang-tidy (pull_request) Failing after 1m19s
Rust / fmt (pull_request) Successful in 1m24s
Rust / clippy (pull_request) Successful in 1m59s
Rust / build (pull_request) Successful in 2m12s
Python / verify (pull_request) Successful in 2m48s
2026-08-31 19:05:22 +02:00
zach 52feb6006a chore: format llm c files
C++ / fmt (pull_request) Failing after 4s
C++ / build (pull_request) Failing after 9s
JS/TS / lint (pull_request) Successful in 9s
JS/TS / fmt (pull_request) Successful in 16s
C++ / clang-tidy (pull_request) Failing after 43s
Python / static (pull_request) Failing after 57s
Rust / fmt (pull_request) Successful in 1m30s
Rust / build (pull_request) Successful in 2m5s
Rust / clippy (pull_request) Successful in 1m55s
Python / verify (pull_request) Successful in 2m23s
2026-08-31 19:02:26 +02:00
zach dbb51ceadd feat: config object migration path and add new options to settings
C++ / fmt (pull_request) Failing after 4s
C++ / build (pull_request) Failing after 12s
JS/TS / fmt (pull_request) Successful in 15s
JS/TS / lint (pull_request) Successful in 15s
C++ / clang-tidy (pull_request) Failing after 33s
Python / static (pull_request) Failing after 36s
Rust / fmt (pull_request) Successful in 1m14s
Rust / build (pull_request) Successful in 1m49s
Rust / clippy (pull_request) Successful in 1m33s
Python / verify (pull_request) Successful in 2m10s
2026-08-31 18:43:41 +02:00
zach 487615f482 fix: shader fade animation linear curve 2026-08-31 14:09:54 +02:00
zach d4e936a7e2 add nightlight hyprland plugin + rename hyprsunsetmanager -> nightlightmanager to control both 2026-08-31 13:53:37 +02:00
zach 04869656aa Merge pull request 'changed old appearance vars for the lockscreen + warning hunting for the polkit' (#154) from fix/lockscreen-font into main
Reviewed-on: #154
Reviewed-by: AramJonghu <aramjonghu@tutamail.com>
Reviewed-by: zach <zach@brohn.se>
2026-08-31 00:14:06 +02:00
zach 2f6847ce0e Merge branch 'main' into fix/lockscreen-font
C++ / fmt (pull_request) Successful in 3s
JS/TS / fmt (pull_request) Successful in 14s
JS/TS / lint (pull_request) Successful in 20s
Python / static (pull_request) Successful in 58s
Rust / fmt (pull_request) Successful in 55s
C++ / build (pull_request) Successful in 2m31s
Rust / build (pull_request) Successful in 2m16s
Rust / clippy (pull_request) Successful in 1m33s
Python / verify (pull_request) Successful in 2m53s
C++ / clang-tidy (pull_request) Successful in 4m5s
2026-08-31 00:13:16 +02:00
zach e5e52802de test aur 2026-08-30 23:49:53 +02:00
zach 42f02f4dd2 test aur 2026-08-30 23:33:50 +02:00
zach 9df3a64815 fix: lowercase battery device state 2026-08-30 22:20:39 +02:00
Inorishio 9370284c6b changed old appearance vars for the lockscreen + warning hunting for the polkit
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 14s
JS/TS / lint (pull_request) Successful in 16s
Python / static (pull_request) Successful in 1m14s
Rust / fmt (pull_request) Successful in 1m8s
Rust / build (pull_request) Successful in 2m14s
C++ / build (pull_request) Successful in 2m36s
Rust / clippy (pull_request) Successful in 1m15s
Python / verify (pull_request) Successful in 3m19s
C++ / clang-tidy (pull_request) Successful in 4m1s
2026-08-30 16:35:20 +02:00
zach 703d804746 fab menu and model selector 2026-08-29 18:56:59 +02:00
zach 327270f3fa better support for opening chat in floating window 2026-08-28 14:15:57 +02:00
zach 8a66c3b064 expandable dialogs for color scheme, fonts and scheduling modes 2026-08-27 16:57:02 +02:00
zach 293bf67e09 better scrollbar in codeblocks + enter anim for delegates 2026-08-27 01:47:17 +02:00
zach c33dbc147f rotated view + wheel inverter 2026-08-26 17:10:34 +02:00
zach 78988700be async parsing + tex caching 2026-08-26 02:06:40 +02:00
zach 3946541f87 async parsing + tex caching 2026-08-26 02:06:10 +02:00
zach e18875a752 add markdown parsing + latex + tree-sitter highlighting for codeblocks in llm responses 2026-08-24 23:55:51 +02:00
zach 5598f4f435 README.md 2026-08-23 17:01:27 +02:00
zach 7e02c87b91 README.md 2026-08-23 17:00:41 +02:00
zach aae3757daf better chat list view + anchor to bottom. sqlite db for chats + LIFO-ordered 2026-08-23 16:37:11 +02:00
zach 37c6a9986e start initial work on detaching chat to floating window 2026-08-20 20:24:54 +02:00
zach 9657e5092a add removal of chat sessions, auto title + icon, proper stick-to-bottom as response is streamed 2026-08-20 17:40:33 +02:00
zach 47bab21e22 initial commit for llm chat tab in sidebar 2026-08-20 00:27:48 +02:00
zach d3e61efd86 Merge pull request 'Feat: Dashboard media widget update + anim tokens restructure' (#151) from feat/dashboard-media-widget into main
Reviewed-on: #151
2026-08-19 11:26:23 +02:00
zach de95b6c8f9 fix rounding tokens
C++ / fmt (pull_request) Successful in 7s
JS/TS / fmt (pull_request) Successful in 12s
JS/TS / lint (pull_request) Successful in 16s
Python / static (pull_request) Successful in 53s
Rust / fmt (pull_request) Successful in 39s
Rust / build (pull_request) Successful in 1m57s
C++ / build (pull_request) Successful in 3m51s
Rust / clippy (pull_request) Successful in 1m39s
Python / verify (pull_request) Successful in 3m4s
C++ / clang-tidy (pull_request) Successful in 5m25s
2026-08-19 00:38:41 +02:00
zach 4ff4afa279 Merge branch 'main' into feat/dashboard-media-widget
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 18s
JS/TS / lint (pull_request) Successful in 17s
Python / static (pull_request) Successful in 58s
Rust / fmt (pull_request) Successful in 1m4s
C++ / build (pull_request) Successful in 2m39s
Rust / build (pull_request) Successful in 2m22s
Rust / clippy (pull_request) Successful in 1m48s
Python / verify (pull_request) Successful in 3m29s
C++ / clang-tidy (pull_request) Successful in 7m7s
2026-08-19 00:36:42 +02:00
zach 8a83181f11 modular quick toggles 2026-08-19 00:34:49 +02:00
zach f778335600 fix switch style
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 18s
JS/TS / lint (pull_request) Successful in 20s
Python / static (pull_request) Successful in 55s
Rust / fmt (pull_request) Successful in 1m4s
Rust / build (pull_request) Successful in 1m58s
C++ / build (pull_request) Successful in 2m32s
Rust / clippy (pull_request) Successful in 1m34s
Python / verify (pull_request) Successful in 2m40s
C++ / clang-tidy (pull_request) Successful in 4m1s
2026-08-18 22:31:32 +02:00
zach 6de7672c05 Merge branch 'main' into feat/dashboard-media-widget
C++ / fmt (pull_request) Successful in 3s
JS/TS / fmt (pull_request) Successful in 19s
JS/TS / lint (pull_request) Successful in 18s
Python / static (pull_request) Successful in 59s
Rust / fmt (pull_request) Successful in 1m3s
C++ / build (pull_request) Successful in 2m35s
Rust / build (pull_request) Successful in 2m11s
Rust / clippy (pull_request) Successful in 1m52s
Python / verify (pull_request) Successful in 3m28s
C++ / clang-tidy (pull_request) Successful in 7m18s
2026-08-18 21:46:52 +02:00
zach eb65e44ac8 remove unneeded files 2026-08-18 21:46:39 +02:00
zach d74daf96ca Merge branch 'main' into feat/dashboard-media-widget
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 14s
JS/TS / lint (pull_request) Successful in 18s
Python / static (pull_request) Successful in 1m10s
Rust / fmt (pull_request) Successful in 1m1s
Rust / build (pull_request) Successful in 2m12s
Rust / clippy (pull_request) Successful in 1m17s
C++ / build (pull_request) Successful in 2m45s
Python / verify (pull_request) Successful in 3m9s
C++ / clang-tidy (pull_request) Successful in 4m7s
2026-08-18 19:26:15 +02:00
zach de44096132 remove log file 2026-08-18 19:25:21 +02:00
zach 59213cf30d fix property changed signals firing multiple times 2026-08-18 19:25:03 +02:00
zach 7e9c05d90a adjust notification padding
C++ / fmt (pull_request) Successful in 3s
JS/TS / fmt (pull_request) Successful in 17s
JS/TS / lint (pull_request) Successful in 17s
Python / static (pull_request) Successful in 57s
Rust / fmt (pull_request) Successful in 1m3s
Rust / build (pull_request) Successful in 2m11s
C++ / build (pull_request) Successful in 2m37s
Rust / clippy (pull_request) Successful in 1m33s
Python / verify (pull_request) Successful in 2m45s
C++ / clang-tidy (pull_request) Successful in 4m3s
2026-08-18 17:46:15 +02:00
zach f9a17caaf3 fix incorrect property names
JS/TS / fmt (pull_request) Successful in 12s
C++ / fmt (pull_request) Successful in 26s
JS/TS / lint (pull_request) Successful in 16s
Python / static (pull_request) Successful in 56s
Rust / fmt (pull_request) Successful in 31s
Rust / build (pull_request) Successful in 2m2s
Rust / clippy (pull_request) Successful in 1m38s
Python / verify (pull_request) Successful in 3m21s
C++ / build (pull_request) Successful in 4m4s
C++ / clang-tidy (pull_request) Successful in 5m30s
2026-08-18 16:24:28 +02:00
zach 7d6f3cc275 initial commit for media widget update + anim tokens restructure
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 20s
JS/TS / lint (pull_request) Successful in 22s
Python / static (pull_request) Successful in 57s
Rust / fmt (pull_request) Successful in 1m2s
C++ / build (pull_request) Successful in 2m10s
Rust / build (pull_request) Successful in 1m50s
Rust / clippy (pull_request) Successful in 1m25s
Python / verify (pull_request) Successful in 2m58s
C++ / clang-tidy (pull_request) Successful in 7m8s
2026-08-18 16:14:41 +02:00
zach 8ec454306f fix popout jitter due to height changes 2026-08-18 00:47:16 +02:00
zach 968055a24e fix wallpaper preview 2026-08-17 22:15:54 +02:00
zach 46855b6a7f fix new scheme preview bug with wallpaper carousel 2026-08-17 21:21:51 +02:00
zach dfc203f905 Merge pull request 'Fix: Proper color scheme preview to avoid watcher creation spam' (#150) from fix/proper-scheme-previews into main
Reviewed-on: #150
2026-08-17 21:01:25 +02:00
zach 78c0a6fdfc Merge branch 'main' into fix/proper-scheme-previews
C++ / fmt (pull_request) Successful in 3s
JS/TS / fmt (pull_request) Successful in 20s
JS/TS / lint (pull_request) Successful in 21s
Python / static (pull_request) Successful in 1m1s
Rust / fmt (pull_request) Successful in 54s
C++ / build (pull_request) Successful in 2m31s
Rust / build (pull_request) Successful in 2m5s
Rust / clippy (pull_request) Successful in 1m29s
Python / verify (pull_request) Successful in 2m41s
C++ / clang-tidy (pull_request) Successful in 4m0s
2026-08-17 21:01:15 +02:00
zach 98fc9aa97a add wavyline slider to dash media widget 2026-08-17 21:01:04 +02:00
zach db76ae7dc6 fix dash currentTab property 2026-08-17 18:49:47 +02:00
zach de55b5f1e4 Merge branch 'main' into fix/proper-scheme-previews
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 28s
JS/TS / lint (pull_request) Successful in 20s
Python / static (pull_request) Successful in 58s
Rust / fmt (pull_request) Successful in 1m4s
Rust / build (pull_request) Successful in 1m52s
C++ / build (pull_request) Successful in 2m29s
Rust / clippy (pull_request) Successful in 1m23s
Python / verify (pull_request) Successful in 2m43s
C++ / clang-tidy (pull_request) Successful in 3m59s
2026-08-17 18:46:40 +02:00
zach 2c62ad093c fix incorrect font property for other text objects in clock 2026-08-17 18:30:43 +02:00
zach 97c48d03f4 Merge branch 'main' into fix/proper-scheme-previews
C++ / fmt (pull_request) Successful in 3s
JS/TS / fmt (pull_request) Successful in 16s
JS/TS / lint (pull_request) Successful in 17s
Python / static (pull_request) Successful in 1m0s
Rust / fmt (pull_request) Successful in 1m0s
C++ / build (pull_request) Successful in 2m14s
Rust / build (pull_request) Successful in 2m9s
Rust / clippy (pull_request) Successful in 1m26s
Python / verify (pull_request) Successful in 2m50s
C++ / clang-tidy (pull_request) Successful in 4m1s
2026-08-17 18:02:22 +02:00
zach 69d8f6d727 Merge pull request 'Feat: MD3 wallpaper launcher carousel' (#146) from feat/wallpaper-picker-rework into main
Reviewed-on: #146
Reviewed-by: AramJonghu <aramjonghu@tutamail.com>
2026-08-17 18:01:41 +02:00
zach ddfa6cd3c4 Merge branch 'main' into feat/wallpaper-picker-rework
C++ / fmt (pull_request) Successful in 11s
JS/TS / fmt (pull_request) Successful in 16s
JS/TS / lint (pull_request) Successful in 15s
Python / static (pull_request) Successful in 54s
Rust / fmt (pull_request) Successful in 34s
Rust / build (pull_request) Successful in 1m54s
C++ / build (pull_request) Successful in 3m51s
Rust / clippy (pull_request) Successful in 1m34s
Python / verify (pull_request) Successful in 3m5s
C++ / clang-tidy (pull_request) Successful in 5m15s
2026-08-17 16:55:00 +02:00
zach c35e73886a Merge branch 'main' into fix/proper-scheme-previews
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 19s
JS/TS / lint (pull_request) Successful in 21s
Python / static (pull_request) Successful in 1m0s
Rust / fmt (pull_request) Successful in 1m6s
C++ / build (pull_request) Successful in 2m38s
Rust / build (pull_request) Successful in 2m18s
Rust / clippy (pull_request) Successful in 1m51s
Python / verify (pull_request) Successful in 3m28s
C++ / clang-tidy (pull_request) Successful in 7m1s
2026-08-17 16:54:49 +02:00
zach c7bf7cdc0b fix recursive wallpaper model in settings + clock font 2026-08-17 16:53:47 +02:00
zach 177b0f319c proper color scheme preview to avoid watcher creation spam
C++ / fmt (pull_request) Successful in 6s
JS/TS / fmt (pull_request) Successful in 19s
JS/TS / lint (pull_request) Successful in 21s
Python / static (pull_request) Successful in 53s
Rust / fmt (pull_request) Successful in 47s
C++ / build (pull_request) Successful in 1m54s
Rust / build (pull_request) Successful in 2m7s
Rust / clippy (pull_request) Successful in 1m31s
Python / verify (pull_request) Successful in 2m57s
C++ / clang-tidy (pull_request) Successful in 3m49s
2026-08-17 14:23:24 +02:00
zach d3e781731e Merge branch 'main' into feat/wallpaper-picker-rework
C++ / fmt (pull_request) Successful in 5s
JS/TS / fmt (pull_request) Successful in 19s
JS/TS / lint (pull_request) Successful in 21s
Python / static (pull_request) Successful in 1m1s
Rust / fmt (pull_request) Successful in 1m2s
Rust / build (pull_request) Successful in 2m8s
Rust / clippy (pull_request) Successful in 1m31s
C++ / build (pull_request) Successful in 2m42s
Python / verify (pull_request) Successful in 2m57s
C++ / clang-tidy (pull_request) Successful in 4m3s
2026-08-17 13:24:22 +02:00
zach abb180c947 fix status icons visibility in fullscreen + wrong property name 2026-08-17 13:24:08 +02:00
zach babfe4b3de flick velocity and deceleration
C++ / fmt (pull_request) Successful in 3s
JS/TS / fmt (pull_request) Successful in 15s
JS/TS / lint (pull_request) Successful in 17s
Python / static (pull_request) Successful in 58s
Rust / fmt (pull_request) Successful in 1m4s
Rust / build (pull_request) Successful in 2m14s
C++ / build (pull_request) Successful in 2m36s
Rust / clippy (pull_request) Successful in 1m30s
Python / verify (pull_request) Successful in 2m53s
C++ / clang-tidy (pull_request) Successful in 4m4s
2026-08-17 10:37:00 +02:00
zach 31f73b05e4 Merge branch 'main' into feat/wallpaper-picker-rework
C++ / fmt (pull_request) Successful in 3s
JS/TS / fmt (pull_request) Successful in 11s
JS/TS / lint (pull_request) Successful in 21s
Python / static (pull_request) Successful in 1m6s
Rust / fmt (pull_request) Successful in 55s
Rust / build (pull_request) Successful in 2m13s
C++ / build (pull_request) Successful in 2m38s
Rust / clippy (pull_request) Successful in 1m20s
Python / verify (pull_request) Successful in 3m10s
C++ / clang-tidy (pull_request) Successful in 4m3s
2026-08-16 23:24:51 +02:00
zach a6c1985bff Merge pull request 'Feat: Reveal bar on hover in fullscreen' (#149) from feat/fullscreen-reveal-bar into main
Reviewed-on: #149
2026-08-16 23:24:36 +02:00
zach 69c2bfae9d fix search trickle through actions and variants view and mouse event stealing by wallpapertile
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 7s
JS/TS / lint (pull_request) Successful in 10s
Python / static (pull_request) Successful in 1m6s
Rust / fmt (pull_request) Successful in 1m3s
Rust / build (pull_request) Successful in 2m17s
Rust / clippy (pull_request) Successful in 1m29s
C++ / build (pull_request) Successful in 2m48s
Python / verify (pull_request) Successful in 3m16s
C++ / clang-tidy (pull_request) Successful in 4m17s
2026-08-16 23:13:37 +02:00
zach 43647dd486 fix currentItem property and signals
C++ / fmt (pull_request) Successful in 4s
JS/TS / lint (pull_request) Successful in 16s
JS/TS / fmt (pull_request) Successful in 18s
Python / static (pull_request) Successful in 58s
Rust / fmt (pull_request) Successful in 59s
C++ / build (pull_request) Successful in 2m16s
Rust / build (pull_request) Successful in 2m5s
Rust / clippy (pull_request) Successful in 1m30s
Python / verify (pull_request) Successful in 2m43s
C++ / clang-tidy (pull_request) Successful in 3m58s
2026-08-16 20:45:55 +02:00
zach 43f070f887 clean-up plugin files
C++ / fmt (pull_request) Successful in 9s
JS/TS / fmt (pull_request) Successful in 11s
JS/TS / lint (pull_request) Successful in 15s
Python / static (pull_request) Successful in 55s
Rust / fmt (pull_request) Successful in 32s
Rust / build (pull_request) Successful in 1m52s
C++ / build (pull_request) Successful in 3m56s
Rust / clippy (pull_request) Successful in 1m30s
Python / verify (pull_request) Successful in 3m3s
C++ / clang-tidy (pull_request) Successful in 5m20s
2026-08-16 20:29:48 +02:00
zach 4e75f21446 improve sizing and dynamic width for view
C++ / fmt (pull_request) Successful in 6s
JS/TS / fmt (pull_request) Successful in 12s
JS/TS / lint (pull_request) Successful in 17s
Python / static (pull_request) Successful in 1m2s
Rust / fmt (pull_request) Successful in 1m5s
C++ / build (pull_request) Successful in 2m36s
Rust / build (pull_request) Successful in 2m27s
Rust / clippy (pull_request) Successful in 1m51s
Python / verify (pull_request) Successful in 3m33s
C++ / clang-tidy (pull_request) Successful in 7m12s
2026-08-16 20:28:21 +02:00
zach 654632128f clean-up plugin files
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 9s
JS/TS / lint (pull_request) Successful in 22s
Rust / fmt (pull_request) Successful in 56s
Python / static (pull_request) Successful in 1m0s
C++ / build (pull_request) Successful in 2m9s
Rust / build (pull_request) Successful in 2m8s
Rust / clippy (pull_request) Successful in 1m9s
Python / verify (pull_request) Successful in 2m57s
C++ / clang-tidy (pull_request) Successful in 3m58s
2026-08-16 18:14:04 +02:00
zach 797fe31b2b Merge branch 'main' into feat/fullscreen-reveal-bar
C++ / fmt (pull_request) Successful in 8s
JS/TS / fmt (pull_request) Successful in 12s
JS/TS / lint (pull_request) Successful in 15s
Python / static (pull_request) Successful in 51s
Rust / fmt (pull_request) Successful in 40s
Rust / build (pull_request) Successful in 1m45s
C++ / build (pull_request) Successful in 3m40s
Rust / clippy (pull_request) Successful in 1m32s
Python / verify (pull_request) Successful in 3m19s
C++ / clang-tidy (pull_request) Successful in 5m21s
2026-08-16 18:04:01 +02:00
zach 4037a1dd0f Merge branch 'main' into feat/wallpaper-picker-rework
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 15s
JS/TS / lint (pull_request) Successful in 16s
Python / static (pull_request) Successful in 58s
Rust / fmt (pull_request) Successful in 1m9s
C++ / build (pull_request) Successful in 2m25s
Rust / build (pull_request) Successful in 2m19s
Rust / clippy (pull_request) Successful in 1m53s
Python / verify (pull_request) Successful in 3m37s
C++ / clang-tidy (pull_request) Successful in 7m5s
2026-08-16 18:03:53 +02:00
zach 03ef51cd0c Merge pull request 'Feat: Peripheral status and integration' (#140) from feat/peripheral-integration into main
Reviewed-on: #140
Reviewed-by: AramJonghu <aramjonghu@tutamail.com>
2026-08-16 18:03:42 +02:00
zach a41c0adb3e move carouselview to standalone c++ component, fix crash due to memory leak in wallpaper object creation
C++ / fmt (pull_request) Successful in 3s
JS/TS / lint (pull_request) Successful in 18s
JS/TS / fmt (pull_request) Successful in 17s
Python / fmt (pull_request) Successful in 28s
Python / lint (pull_request) Successful in 30s
Python / test (pull_request) Successful in 1m5s
Python / typecheck (pull_request) Successful in 1m24s
Rust / fmt (pull_request) Successful in 31s
C++ / build (pull_request) Successful in 2m21s
Rust / build (pull_request) Successful in 1m47s
Python / buildcheck (pull_request) Successful in 2m18s
Rust / clippy (pull_request) Successful in 1m12s
C++ / clang-tidy (pull_request) Successful in 4m3s
2026-08-16 17:59:23 +02:00
zach 33c9432390 fix python errors
C++ / fmt (pull_request) Successful in 10s
JS/TS / fmt (pull_request) Successful in 15s
JS/TS / lint (pull_request) Successful in 15s
Python / static (pull_request) Successful in 53s
Rust / fmt (pull_request) Successful in 1m6s
Rust / build (pull_request) Successful in 2m10s
C++ / build (pull_request) Successful in 2m37s
Rust / clippy (pull_request) Successful in 1m33s
Python / verify (pull_request) Successful in 2m53s
C++ / clang-tidy (pull_request) Successful in 3m59s
2026-08-16 13:11:17 +02:00
zach bfaba488f3 Merge branch 'main' into feat/peripheral-integration
C++ / fmt (pull_request) Successful in 7s
JS/TS / fmt (pull_request) Successful in 15s
JS/TS / lint (pull_request) Successful in 15s
Python / static (pull_request) Successful in 59s
Rust / fmt (pull_request) Successful in 50s
Python / verify (pull_request) Failing after 2m37s
Rust / build (pull_request) Successful in 2m1s
C++ / build (pull_request) Successful in 4m7s
Rust / clippy (pull_request) Successful in 1m36s
C++ / clang-tidy (pull_request) Successful in 5m17s
2026-08-16 12:51:07 +02:00
zach 0c788ca4dc Merge branch 'main' into feat/wallpaper-picker-rework
C++ / fmt (pull_request) Successful in 9s
JS/TS / fmt (pull_request) Successful in 13s
JS/TS / lint (pull_request) Successful in 15s
Python / fmt (pull_request) Successful in 26s
Python / lint (pull_request) Successful in 24s
Python / test (pull_request) Successful in 55s
Python / typecheck (pull_request) Successful in 1m9s
Rust / fmt (pull_request) Successful in 41s
Python / buildcheck (pull_request) Successful in 2m36s
C++ / build (pull_request) Successful in 4m3s
Rust / build (pull_request) Successful in 1m53s
Rust / clippy (pull_request) Successful in 1m44s
C++ / clang-tidy (pull_request) Successful in 8m35s
2026-08-16 12:50:58 +02:00
zach 4f4b3ce8c6 Merge branch 'main' into feat/fullscreen-reveal-bar
C++ / fmt (pull_request) Successful in 5s
JS/TS / fmt (pull_request) Successful in 18s
JS/TS / lint (pull_request) Successful in 18s
Python / fmt (pull_request) Successful in 34s
Python / lint (pull_request) Successful in 32s
Python / test (pull_request) Successful in 1m1s
Python / typecheck (pull_request) Successful in 1m21s
Rust / fmt (pull_request) Successful in 33s
C++ / build (pull_request) Successful in 2m17s
Rust / build (pull_request) Successful in 1m43s
Python / buildcheck (pull_request) Successful in 2m26s
Rust / clippy (pull_request) Successful in 1m39s
C++ / clang-tidy (pull_request) Successful in 7m58s
2026-08-16 12:50:52 +02:00
zach c42feec312 clean up code in updates singleton and popout 2026-08-16 12:50:39 +02:00
zach 4f544981c1 delete unknown json objects + write missing objects to config file 2026-08-16 12:17:50 +02:00
zach ba567efc22 fix unused vars
C++ / fmt (pull_request) Successful in 7s
Python / static (pull_request) Failing after 2s
JS/TS / fmt (pull_request) Successful in 25s
JS/TS / lint (pull_request) Successful in 21s
Rust / fmt (pull_request) Successful in 55s
Rust / build (pull_request) Successful in 2m22s
Python / verify (pull_request) Failing after 2m41s
Rust / clippy (pull_request) Successful in 1m45s
C++ / build (pull_request) Successful in 3m38s
C++ / clang-tidy (pull_request) Successful in 4m46s
2026-08-16 11:23:57 +02:00
zach cbb24a2c40 Merge branch 'main' into feat/fullscreen-reveal-bar
C++ / fmt (pull_request) Successful in 5s
JS/TS / fmt (pull_request) Successful in 15s
JS/TS / lint (pull_request) Successful in 19s
Python / fmt (pull_request) Successful in 31s
Python / lint (pull_request) Successful in 34s
Python / test (pull_request) Successful in 56s
Python / typecheck (pull_request) Successful in 1m23s
Rust / fmt (pull_request) Successful in 41s
C++ / build (pull_request) Successful in 2m35s
Rust / build (pull_request) Successful in 1m49s
Rust / clippy (pull_request) Successful in 59s
Python / buildcheck (pull_request) Successful in 2m19s
C++ / clang-tidy (pull_request) Successful in 6m2s
2026-08-16 11:20:59 +02:00
zach da21675f03 Merge branch 'main' into feat/peripheral-integration
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 18s
JS/TS / lint (pull_request) Successful in 20s
Python / static (pull_request) Failing after 59s
Rust / fmt (pull_request) Successful in 1m4s
Rust / build (pull_request) Successful in 1m56s
C++ / build (pull_request) Successful in 2m31s
Python / verify (pull_request) Failing after 2m26s
Rust / clippy (pull_request) Successful in 1m22s
C++ / clang-tidy (pull_request) Successful in 3m53s
2026-08-16 11:11:36 +02:00
zach 02bb7e43d8 Merge pull request 'Feat: Reposition bar' (#147) from feat/reposition-bar into main
Reviewed-on: #147
Reviewed-by: AramJonghu <aramjonghu@tutamail.com>
2026-08-16 11:02:22 +02:00
AramJonghu 8883d98b00 chore: added missing dependency to pyproject
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 17s
JS/TS / lint (pull_request) Successful in 21s
Python / static (pull_request) Failing after 1m24s
Rust / fmt (pull_request) Successful in 1m16s
C++ / build (pull_request) Successful in 2m26s
Rust / build (pull_request) Successful in 2m7s
Rust / clippy (pull_request) Successful in 1m4s
Python / verify (pull_request) Failing after 3m16s
C++ / clang-tidy (pull_request) Successful in 3m53s
2026-08-15 22:07:45 +02:00
AramJonghu cf907089da ci(python): rework of jobs + fix import issue 2026-08-15 22:07:45 +02:00
zach 070fe7add0 Merge branch 'main' into feat/peripheral-integration
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 20s
JS/TS / lint (pull_request) Successful in 18s
Python / lint (pull_request) Failing after 30s
Python / fmt (pull_request) Successful in 35s
Python / test (pull_request) Failing after 1m1s
Python / typecheck (pull_request) Failing after 1m24s
Rust / fmt (pull_request) Successful in 33s
Rust / build (pull_request) Successful in 1m51s
C++ / build (pull_request) Successful in 2m42s
Rust / clippy (pull_request) Successful in 1m1s
Python / buildcheck (pull_request) Successful in 2m34s
C++ / clang-tidy (pull_request) Successful in 4m2s
2026-08-15 20:54:59 +02:00
zach 052e3a7800 Merge branch 'main' into feat/fullscreen-reveal-bar
C++ / fmt (pull_request) Successful in 9s
JS/TS / fmt (pull_request) Successful in 14s
JS/TS / lint (pull_request) Successful in 16s
Python / fmt (pull_request) Successful in 25s
Python / lint (pull_request) Successful in 26s
Python / test (pull_request) Successful in 52s
Python / typecheck (pull_request) Successful in 1m6s
Rust / fmt (pull_request) Successful in 33s
Rust / build (pull_request) Successful in 1m30s
Python / buildcheck (pull_request) Successful in 2m17s
C++ / build (pull_request) Successful in 3m49s
Rust / clippy (pull_request) Successful in 1m11s
C++ / clang-tidy (pull_request) Successful in 5m7s
2026-08-15 19:53:59 +02:00
zach fb0c75a2ba remove debug logging
C++ / fmt (pull_request) Successful in 8s
JS/TS / fmt (pull_request) Successful in 11s
JS/TS / lint (pull_request) Successful in 15s
Python / fmt (pull_request) Successful in 24s
Python / lint (pull_request) Successful in 25s
Python / test (pull_request) Successful in 48s
Python / typecheck (pull_request) Successful in 1m1s
Rust / fmt (pull_request) Successful in 34s
Rust / build (pull_request) Successful in 1m45s
C++ / build (pull_request) Successful in 4m18s
Python / buildcheck (pull_request) Successful in 2m20s
Rust / clippy (pull_request) Successful in 1m1s
C++ / clang-tidy (pull_request) Successful in 5m23s
2026-08-15 19:38:33 +02:00
zach 5efa0de3a5 WidgetBase for bar widget + fixed resources and dashboard popouts in left- and bottom-edge bar
C++ / fmt (pull_request) Successful in 3s
JS/TS / fmt (pull_request) Successful in 17s
JS/TS / lint (pull_request) Successful in 20s
Python / fmt (pull_request) Successful in 31s
Python / lint (pull_request) Successful in 30s
Python / test (pull_request) Successful in 1m40s
Python / typecheck (pull_request) Successful in 1m38s
C++ / build (pull_request) Successful in 2m15s
Rust / build (pull_request) Successful in 1m41s
Rust / fmt (pull_request) Successful in 59s
Python / buildcheck (pull_request) Successful in 2m40s
Rust / clippy (pull_request) Successful in 2m15s
C++ / clang-tidy (pull_request) Successful in 6m29s
2026-08-15 19:37:44 +02:00
zach 858ef68565 Merge branch 'main' into feat/reposition-bar
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 21s
JS/TS / lint (pull_request) Successful in 22s
Python / lint (pull_request) Successful in 31s
Python / fmt (pull_request) Successful in 34s
Python / test (pull_request) Successful in 59s
Python / typecheck (pull_request) Successful in 1m22s
Rust / fmt (pull_request) Successful in 34s
Rust / build (pull_request) Successful in 1m46s
C++ / build (pull_request) Successful in 2m33s
Rust / clippy (pull_request) Successful in 1m5s
Python / buildcheck (pull_request) Successful in 2m29s
C++ / clang-tidy (pull_request) Successful in 3m56s
2026-08-15 18:04:14 +02:00
zach 5e97ea6867 Merge pull request 'CI: typecheck fixes include dependencies + arch Dockerfile build fix' (#148) from fix/cli-typecheck into main
Reviewed-on: #148
Reviewed-by: zach <zach@brohn.se>
2026-08-15 18:03:54 +02:00
zach 9823c66299 restructure bar components layout
C++ / fmt (pull_request) Successful in 4s
JS/TS / lint (pull_request) Successful in 19s
JS/TS / fmt (pull_request) Successful in 21s
Python / fmt (pull_request) Successful in 30s
Python / lint (pull_request) Successful in 31s
Python / test (pull_request) Successful in 1m2s
Python / typecheck (pull_request) Failing after 1m5s
Rust / fmt (pull_request) Successful in 43s
C++ / build (pull_request) Successful in 2m25s
Rust / build (pull_request) Successful in 1m42s
Python / buildcheck (pull_request) Successful in 2m27s
Rust / clippy (pull_request) Successful in 1m29s
C++ / clang-tidy (pull_request) Successful in 3m56s
2026-08-15 14:18:00 +02:00
zach 0092b41a05 fix config file writing + positioning issues
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 22s
JS/TS / lint (pull_request) Successful in 27s
Python / fmt (pull_request) Successful in 33s
Python / lint (pull_request) Successful in 32s
Python / test (pull_request) Successful in 1m3s
Python / typecheck (pull_request) Failing after 1m4s
Rust / fmt (pull_request) Successful in 41s
Rust / build (pull_request) Successful in 1m39s
C++ / build (pull_request) Successful in 2m33s
Rust / clippy (pull_request) Successful in 1m18s
Python / buildcheck (pull_request) Successful in 2m23s
C++ / clang-tidy (pull_request) Successful in 3m56s
2026-08-14 22:15:11 +02:00
AramJonghu abf7382771 ci: libcava dev headers
C++ / fmt (pull_request) Successful in 5s
JS/TS / fmt (pull_request) Successful in 12s
JS/TS / lint (pull_request) Successful in 16s
Python / lint (pull_request) Successful in 33s
Python / fmt (pull_request) Successful in 36s
Python / test (pull_request) Successful in 1m3s
Python / typecheck (pull_request) Successful in 1m21s
Rust / fmt (pull_request) Successful in 33s
C++ / build (pull_request) Successful in 2m26s
Rust / build (pull_request) Successful in 1m43s
Python / buildcheck (pull_request) Successful in 2m12s
Rust / clippy (pull_request) Successful in 1m41s
C++ / clang-tidy (pull_request) Successful in 4m10s
2026-08-14 20:00:27 +02:00
zach ec80adf0a5 improve image caching for better performance
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 27s
JS/TS / lint (pull_request) Successful in 33s
Python / fmt (pull_request) Successful in 27s
Python / lint (pull_request) Successful in 30s
Python / test (pull_request) Successful in 59s
Python / typecheck (pull_request) Failing after 1m5s
C++ / build (pull_request) Successful in 2m26s
Rust / build (pull_request) Successful in 1m30s
Rust / fmt (pull_request) Successful in 1m12s
Python / buildcheck (pull_request) Successful in 2m19s
Rust / clippy (pull_request) Successful in 1m56s
C++ / clang-tidy (pull_request) Successful in 4m1s
2026-08-14 19:49:48 +02:00
AramJonghu a1a8a6e695 ci: add relevant dependencies; resolves MissingImport
C++ / fmt (pull_request) Successful in 4s
JS/TS / lint (pull_request) Successful in 15s
JS/TS / fmt (pull_request) Successful in 21s
Python / fmt (pull_request) Successful in 31s
Python / lint (pull_request) Successful in 34s
Python / test (pull_request) Successful in 1m0s
Python / typecheck (pull_request) Successful in 1m20s
Rust / fmt (pull_request) Successful in 34s
C++ / build (pull_request) Successful in 2m29s
Rust / build (pull_request) Successful in 1m45s
Rust / clippy (pull_request) Successful in 1m2s
Python / buildcheck (pull_request) Successful in 2m18s
C++ / clang-tidy (pull_request) Successful in 3m52s
2026-08-14 19:40:28 +02:00
zach 88a2808a47 clean up imports
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 19s
JS/TS / lint (pull_request) Successful in 23s
Python / fmt (pull_request) Successful in 35s
Python / lint (pull_request) Successful in 34s
Python / test (pull_request) Successful in 1m1s
Python / typecheck (pull_request) Failing after 1m0s
Rust / fmt (pull_request) Successful in 55s
Rust / build (pull_request) Successful in 1m41s
C++ / build (pull_request) Successful in 2m37s
Rust / clippy (pull_request) Successful in 1m19s
Python / buildcheck (pull_request) Successful in 2m27s
C++ / clang-tidy (pull_request) Successful in 3m55s
2026-08-14 19:23:47 +02:00
zach a13daf27a6 Merge branch 'main' into feat/wallpaper-picker-rework
C++ / fmt (pull_request) Successful in 8s
JS/TS / fmt (pull_request) Successful in 13s
JS/TS / lint (pull_request) Successful in 15s
Python / fmt (pull_request) Successful in 25s
Python / lint (pull_request) Successful in 28s
Python / test (pull_request) Successful in 55s
Python / typecheck (pull_request) Failing after 58s
Rust / fmt (pull_request) Successful in 44s
C++ / build (pull_request) Successful in 3m35s
Rust / build (pull_request) Successful in 1m53s
Python / buildcheck (pull_request) Successful in 2m36s
Rust / clippy (pull_request) Successful in 1m28s
C++ / clang-tidy (pull_request) Successful in 5m15s
2026-08-14 19:18:15 +02:00
zach 75de349ff4 MD3 wallpaper launcher carousel
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 20s
JS/TS / lint (pull_request) Successful in 20s
Python / lint (pull_request) Successful in 32s
Python / fmt (pull_request) Successful in 36s
Python / test (pull_request) Successful in 1m3s
Python / typecheck (pull_request) Failing after 1m8s
C++ / build (pull_request) Successful in 1m49s
Rust / build (pull_request) Successful in 1m31s
Rust / fmt (pull_request) Successful in 47s
Rust / clippy (pull_request) Successful in 1m32s
Python / buildcheck (pull_request) Successful in 2m34s
C++ / clang-tidy (pull_request) Successful in 3m22s
2026-08-14 00:15:52 +02:00
zach 439a14d29e Initial commit implementing reveal on hover in fullscreen
C++ / fmt (pull_request) Successful in 5s
JS/TS / fmt (pull_request) Successful in 20s
JS/TS / lint (pull_request) Successful in 26s
Python / fmt (pull_request) Successful in 34s
Python / lint (pull_request) Successful in 32s
Python / test (pull_request) Successful in 59s
Python / typecheck (pull_request) Failing after 1m2s
C++ / build (pull_request) Successful in 1m50s
Rust / fmt (pull_request) Successful in 46s
Rust / build (pull_request) Successful in 1m40s
Python / buildcheck (pull_request) Successful in 2m27s
Rust / clippy (pull_request) Successful in 2m5s
C++ / clang-tidy (pull_request) Successful in 5m56s
2026-08-12 01:35:23 +02:00
zach bf5a8b8049 simplify dedupe
C++ / fmt (pull_request) Successful in 3s
JS/TS / fmt (pull_request) Successful in 16s
JS/TS / lint (pull_request) Successful in 19s
Python / fmt (pull_request) Successful in 34s
Python / lint (pull_request) Failing after 31s
Python / test (pull_request) Failing after 59s
Python / typecheck (pull_request) Failing after 1m7s
C++ / build (pull_request) Successful in 1m54s
Rust / fmt (pull_request) Successful in 49s
Rust / build (pull_request) Successful in 1m41s
Rust / clippy (pull_request) Successful in 1m33s
Python / buildcheck (pull_request) Successful in 2m38s
C++ / clang-tidy (pull_request) Successful in 3m31s
2026-07-13 22:10:41 +02:00
zach a9bbb21f54 improve device detection when plugging/unplugging
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 19s
JS/TS / lint (pull_request) Successful in 19s
Python / fmt (pull_request) Successful in 36s
Python / lint (pull_request) Failing after 34s
Python / test (pull_request) Failing after 1m2s
Python / typecheck (pull_request) Failing after 1m11s
C++ / build (pull_request) Successful in 2m11s
Rust / fmt (pull_request) Successful in 52s
Rust / build (pull_request) Successful in 1m45s
Rust / clippy (pull_request) Successful in 1m35s
Python / buildcheck (pull_request) Successful in 2m44s
C++ / clang-tidy (pull_request) Successful in 3m37s
2026-07-13 19:31:40 +02:00
zach bb50cf756d fix: cmake nuitka command again
C++ / fmt (pull_request) Successful in 9s
JS/TS / fmt (pull_request) Successful in 13s
JS/TS / lint (pull_request) Successful in 17s
Python / fmt (pull_request) Successful in 43s
Python / lint (pull_request) Failing after 32s
Python / test (pull_request) Failing after 57s
Python / typecheck (pull_request) Failing after 1m0s
C++ / build (pull_request) Successful in 3m5s
Rust / fmt (pull_request) Successful in 41s
Rust / build (pull_request) Successful in 1m39s
Python / buildcheck (pull_request) Successful in 2m36s
Rust / clippy (pull_request) Successful in 1m21s
C++ / clang-tidy (pull_request) Successful in 4m49s
2026-07-13 15:03:16 +02:00
zach 57147dc7c1 fix: cmake nuitka command
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 15s
JS/TS / lint (pull_request) Successful in 16s
Python / lint (pull_request) Failing after 32s
Python / fmt (pull_request) Successful in 36s
Python / test (pull_request) Failing after 1m3s
C++ / build (pull_request) Successful in 1m39s
Python / typecheck (pull_request) Failing after 1m9s
Rust / fmt (pull_request) Successful in 38s
Rust / build (pull_request) Successful in 1m33s
Python / buildcheck (pull_request) Successful in 2m48s
Rust / clippy (pull_request) Successful in 2m1s
C++ / clang-tidy (pull_request) Successful in 5m51s
2026-07-13 14:59:52 +02:00
zach 620fe001a4 backend now more robust, threaded writes use locks
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 11s
JS/TS / lint (pull_request) Successful in 21s
Python / lint (pull_request) Failing after 31s
Python / fmt (pull_request) Successful in 38s
Python / test (pull_request) Failing after 1m0s
Python / typecheck (pull_request) Failing after 1m1s
C++ / build (pull_request) Successful in 2m0s
Rust / fmt (pull_request) Successful in 44s
Rust / build (pull_request) Successful in 1m40s
Rust / clippy (pull_request) Successful in 1m34s
Python / buildcheck (pull_request) Successful in 2m35s
C++ / clang-tidy (pull_request) Successful in 3m44s
2026-07-13 14:56:57 +02:00
zach 85320e9ea1 prevent writing battery json when there has been no change, filter out devices with unknown state
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 11s
JS/TS / lint (pull_request) Successful in 15s
Python / fmt (pull_request) Successful in 29s
Python / lint (pull_request) Successful in 32s
Python / test (pull_request) Successful in 1m4s
Python / typecheck (pull_request) Failing after 1m10s
C++ / build (pull_request) Successful in 1m35s
Rust / fmt (pull_request) Successful in 36s
Rust / build (pull_request) Successful in 1m34s
Rust / clippy (pull_request) Successful in 1m28s
Python / buildcheck (pull_request) Successful in 2m35s
C++ / clang-tidy (pull_request) Successful in 3m32s
2026-07-13 01:33:55 +02:00
zach 259a4dde7a gitignore
C++ / fmt (pull_request) Successful in 8s
JS/TS / fmt (pull_request) Successful in 12s
JS/TS / lint (pull_request) Successful in 15s
Python / fmt (pull_request) Successful in 26s
Python / lint (pull_request) Successful in 31s
Python / test (pull_request) Successful in 54s
Python / typecheck (pull_request) Failing after 50s
C++ / build (pull_request) Successful in 3m19s
Rust / fmt (pull_request) Successful in 41s
Rust / build (pull_request) Successful in 1m43s
Python / buildcheck (pull_request) Successful in 2m35s
Rust / clippy (pull_request) Successful in 1m27s
C++ / clang-tidy (pull_request) Successful in 4m52s
2026-07-13 01:13:57 +02:00
zach d6230bef34 Fix cmake nuitka build command
C++ / fmt (pull_request) Successful in 5s
JS/TS / fmt (pull_request) Successful in 12s
JS/TS / lint (pull_request) Successful in 20s
Python / fmt (pull_request) Successful in 31s
Python / lint (pull_request) Successful in 33s
Python / test (pull_request) Successful in 1m0s
Python / typecheck (pull_request) Failing after 1m5s
C++ / build (pull_request) Successful in 1m39s
Rust / fmt (pull_request) Successful in 50s
Rust / build (pull_request) Successful in 1m41s
Python / buildcheck (pull_request) Successful in 2m35s
Rust / clippy (pull_request) Successful in 2m5s
C++ / clang-tidy (pull_request) Successful in 6m13s
2026-07-13 01:12:55 +02:00
zach 4ee9bb3f12 add support for all UPower peripherals
C++ / fmt (pull_request) Successful in 3s
JS/TS / fmt (pull_request) Successful in 17s
JS/TS / lint (pull_request) Successful in 16s
Python / fmt (pull_request) Successful in 34s
Python / lint (pull_request) Successful in 35s
Python / typecheck (pull_request) Failing after 1m5s
C++ / build (pull_request) Successful in 1m36s
Python / test (pull_request) Successful in 1m26s
Rust / fmt (pull_request) Successful in 48s
Rust / build (pull_request) Successful in 1m41s
Rust / clippy (pull_request) Successful in 1m37s
Python / buildcheck (pull_request) Successful in 2m41s
C++ / clang-tidy (pull_request) Successful in 3m32s
2026-07-13 00:48:05 +02:00
zach 8789d2d322 initial addition of battery display
JS/TS / fmt (pull_request) Successful in 7s
JS/TS / lint (pull_request) Successful in 9s
Python / fmt (pull_request) Successful in 15s
Python / lint (pull_request) Failing after 19s
Python / typecheck (pull_request) Failing after 1m5s
C++ / fmt (pull_request) Successful in 6s
Python / test (pull_request) Successful in 1m20s
Rust / fmt (pull_request) Successful in 1m42s
Python / buildcheck (pull_request) Successful in 2m23s
Rust / clippy (pull_request) Successful in 2m42s
Rust / build (pull_request) Successful in 2m53s
C++ / build (pull_request) Successful in 2m22s
C++ / clang-tidy (pull_request) Successful in 3m17s
2026-07-12 17:47:25 +02:00
354 changed files with 22251 additions and 4675 deletions
+22 -87
View File
@@ -1,12 +1,15 @@
name: Python
env:
APT_DEPS: git python3 python3-pip python3-venv python3-gi python3-cairo python3-dbus python3-pyudev python3-psutil python3-evdev python3-yaml python3-xlib python3-pillow gir1.2-gtk-3.0
on:
pull_request:
jobs:
fmt:
runs-on: alpine
container: node:26-alpine
static:
runs-on: debian
container: node:26-trixie-slim
steps:
- name: Checkout
@@ -14,10 +17,8 @@ jobs:
- name: Install tools
run: |
apk add --no-cache \
git \
python3 \
py3-pip
apt-get update
apt-get install -y --no-install-recommends git python3 python3-pip python3-venv
python3 -m venv .venv
. .venv/bin/activate
pip install --no-cache-dir ruff
@@ -27,32 +28,15 @@ jobs:
. .venv/bin/activate
ruff format --check .
lint:
runs-on: alpine
container: node:26-alpine
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install tools
run: |
apk add --no-cache \
git \
python3 \
py3-pip
python3 -m venv .venv
. .venv/bin/activate
pip install --no-cache-dir ruff
- name: Lint
run: |
. .venv/bin/activate
ruff check .
test:
runs-on: alpine
container: node:26-alpine
verify:
if: always()
runs-on: debian
container: node:26-trixie-slim
steps:
- name: Checkout
@@ -60,20 +44,16 @@ jobs:
- name: Install tools
run: |
apk add --no-cache \
git \
python3 \
py3-pip \
py3-pillow \
build-base
python3 -m venv .venv
apt-get update
apt-get install -y --no-install-recommends $APT_DEPS build-essential python3-dev
python3 -m venv --system-site-packages .venv
. .venv/bin/activate
pip install --no-cache-dir \
typer \
pillow \
materialyoucolor \
jinja2 \
pytest
pip install --no-cache-dir basedpyright nuitka .
- name: Type check
run: |
. .venv/bin/activate
basedpyright
- name: Test
run: |
@@ -81,52 +61,7 @@ jobs:
cd cli
python -m pytest tests/ -v
typecheck:
runs-on: alpine
container: node:26-alpine
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install tools
run: |
apk add --no-cache \
git \
python3 \
py3-pip
python3 -m venv .venv
. .venv/bin/activate
pip install --no-cache-dir basedpyright
- name: Type check
run: |
. .venv/bin/activate
basedpyright
buildcheck:
runs-on: alpine
container: node:26-alpine
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install tools
run: |
apk add --no-cache \
git \
python3 \
py3-pip \
build-base \
python3-dev \
gcc \
g++
python3 -m venv .venv
. .venv/bin/activate
pip install --no-cache-dir nuitka
- name: Nuitka module check
run: |
. .venv/bin/activate
nuitka --module --include-package=zshell cli/src/zshell/
nuitka --module --include-package=zshell cli/src/zshell/
+2
View File
@@ -16,3 +16,5 @@ dist/
**/test-plugins/
**/Charts/
network-dev/
**/zshell.build/
**/zshell.dist/
+2 -1
View File
@@ -3,8 +3,9 @@ FunctionsSpacing=true
IndentWidth=4
MaxColumnWidth=-1
NewlineType=native
NormalizeOrder=true
GroupAttributesTogether=false
ObjectsSpacing=true
SemicolonRule=always
SingleLineEmptyObjects=true
SortImports=false
UseTabs=true
+22 -20
View File
@@ -26,22 +26,36 @@ if(NOT DEFINED VERSION)
endif()
endif()
if(NOT DEFINED GIT_REVISION)
execute_process(COMMAND git rev-parse HEAD
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE GIT_REVISION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if("${GIT_REVISION}" STREQUAL "")
message(FATAL_ERROR "GIT_REVISION is not set and failed to get from git")
endif()
endif()
set(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
project(ZShell VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
message(STATUS "ZShell version: ${VERSION}")
include(GNUInstallDirs)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(ENABLE_MODULES "plugin;shell;m3shapes" CACHE STRING "Modules to build/install")
set(ENABLE_MODULES "plugin;shell;cli;m3shapes" CACHE STRING "Modules to build/install")
set(INSTALL_LIBDIR "usr/lib/ZShell" CACHE STRING "Library install dir")
set(INSTALL_QMLDIR "usr/lib/qt6/qml" CACHE STRING "QML install dir")
set(INSTALL_QSCONFDIR "etc/xdg/quickshell/zshell" CACHE STRING "Quickshell config install dir")
set(INSTALL_GREETERCONFDIR "etc/xdg/quickshell/zshell-greeter" CACHE STRING "Quickshell greeter install dir")
set(INSTALL_LIBDIR "${CMAKE_INSTALL_LIBDIR}/ZShell" CACHE STRING "Library install dir")
set(INSTALL_QMLDIR "${CMAKE_INSTALL_LIBDIR}/qt6/qml" CACHE STRING "QML install dir")
set(INSTALL_QSCONFDIR "${CMAKE_INSTALL_SYSCONFDIR}/xdg/quickshell/zshell" CACHE STRING "Quickshell config install dir")
set(INSTALL_GREETERCONFDIR "${CMAKE_INSTALL_SYSCONFDIR}/xdg/quickshell/zshell-greeter" CACHE STRING "Quickshell greeter install dir")
set(CMAKE_INSTALL_MESSAGE NEVER)
@@ -54,21 +68,7 @@ add_compile_options(
)
if("shell" IN_LIST ENABLE_MODULES)
# Build settings index
find_package(Python3 COMPONENTS Interpreter REQUIRED)
set(SETTINGS_INDEX_JSON "${CMAKE_BINARY_DIR}/settings-index.json")
execute_process(
COMMAND ${Python3_EXECUTABLE}
"${CMAKE_SOURCE_DIR}/scripts/build-settings-index.py"
"${CMAKE_SOURCE_DIR}/Modules/Settings"
"${SETTINGS_INDEX_JSON}"
RESULT_VARIABLE SETTINGS_INDEX_RESULT
)
if(NOT SETTINGS_INDEX_RESULT EQUAL 0)
message(FATAL_ERROR "Failed to build settings search index")
endif()
if("cli" IN_LIST ENABLE_MODULES)
# Nuitka compilation
set(ZSHELL_CLI_BUILD_DIR "${CMAKE_BINARY_DIR}/zshell-cli")
set(ZSHELL_CLI_DIST "${ZSHELL_CLI_BUILD_DIR}/zshell.dist")
@@ -93,6 +93,8 @@ if("shell" IN_LIST ENABLE_MODULES)
${NUITKA_EXECUTABLE}
--standalone
--include-data-dir=${CMAKE_SOURCE_DIR}/cli/src/zshell/assets=zshell/assets
--include-package=gi.overrides
--include-package-data=solaar
--output-dir=${ZSHELL_CLI_BUILD_DIR}
--output-filename=zshell-cli
${CMAKE_SOURCE_DIR}/cli/src/zshell/
+9 -9
View File
@@ -27,25 +27,25 @@ AnchorAnimation {
if (type == AnchorAnim.DefaultSpatial)
return Tokens.anim.durations.expressiveDefaultSpatial;
if (type == AnchorAnim.SlowSpatial)
return Tokens.anim.durations.large;
return Tokens.anim.durations.expressiveSlowSpatial;
const types = ["small", "normal", "large", "extraLarge"];
const idx = type % 4;
const idx = type % 4; // 0-7 are the 4 standard types
return Tokens.anim.durations[types[idx]];
}
easing.bezierCurve: {
easing: {
if (type == AnchorAnim.FastSpatial)
return Tokens.anim.curves.expressiveFastSpatial;
return Tokens.anim.expressiveFastSpatial;
if (type == AnchorAnim.DefaultSpatial)
return Tokens.anim.curves.expressiveDefaultSpatial;
return Tokens.anim.expressiveDefaultSpatial;
if (type == AnchorAnim.SlowSpatial)
return Tokens.anim.curves.expressiveSlowSpatial;
return Tokens.anim.expressiveSlowSpatial;
if (type >= AnchorAnim.StandardSmall && type <= AnchorAnim.StandardExtraLarge)
return Tokens.anim.curves.standard;
return Tokens.anim.standard;
if (type >= AnchorAnim.EmphasizedSmall && type <= AnchorAnim.EmphasizedExtraLarge)
return Tokens.anim.curves.emphasized;
return Tokens.anim.emphasized;
return Tokens.anim.curves.expressiveDefaultSpatial;
return Tokens.anim.expressiveDefaultSpatial;
}
}
+12 -12
View File
@@ -30,34 +30,34 @@ NumberAnimation {
if (type === Anim.DefaultSpatial)
return Tokens.anim.durations.expressiveDefaultSpatial;
if (type === Anim.SlowSpatial)
return Tokens.anim.durations.large;
return Tokens.anim.durations.expressiveSlowSpatial;
if (type === Anim.FastEffects)
return Tokens.anim.durations.expressiveFastEffects;
if (type === Anim.DefaultEffects)
return Tokens.anim.durations.expressiveEffects;
return Tokens.anim.durations.expressiveDefaultEffects;
if (type === Anim.SlowEffects)
return Tokens.anim.durations.expressiveSlowEffects;
const types = ["small", "normal", "large", "extraLarge"];
const idx = type % 4;
const idx = type % 4; // 0-7 are the 4 standard types
return Tokens.anim.durations[types[idx]];
}
easing.bezierCurve: {
easing: {
if (type === Anim.FastSpatial)
return Tokens.anim.curves.expressiveFastSpatial;
return Tokens.anim.expressiveFastSpatial;
if (type === Anim.DefaultSpatial)
return Tokens.anim.curves.expressiveDefaultSpatial;
return Tokens.anim.expressiveDefaultSpatial;
if (type === Anim.SlowSpatial)
return Tokens.anim.curves.expressiveSlowSpatial;
return Tokens.anim.expressiveSlowSpatial;
if (type === Anim.FastEffects)
return Tokens.anim.curves.expressiveFastEffects;
return Tokens.anim.expressiveFastEffects;
if (type === Anim.DefaultEffects)
return Tokens.anim.curves.expressiveDefaultEffects;
return Tokens.anim.expressiveDefaultEffects;
if (type === Anim.SlowEffects)
return Tokens.anim.curves.expressiveSlowEffects;
return Tokens.anim.expressiveSlowEffects;
if (type >= Anim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge)
return Tokens.anim.curves.emphasized;
return Tokens.anim.curves.standard;
return Tokens.anim.emphasized;
return Tokens.anim.standard;
}
}
+2 -2
View File
@@ -107,7 +107,7 @@ Slider {
Anim {
duration: Tokens.anim.durations.normal / 2
easing.bezierCurve: Tokens.anim.curves.standardAccel
easing: Tokens.anim.standardAccel
property: "scale"
target: icon
to: 0
@@ -119,7 +119,7 @@ Slider {
Anim {
duration: Tokens.anim.durations.normal / 2
easing.bezierCurve: Tokens.anim.curves.standardDecel
easing: Tokens.anim.standardDecel
property: "scale"
target: icon
to: 1
+2 -1
View File
@@ -1,5 +1,6 @@
import QtQuick
import ZShell.Config
import qs.Components
import qs.Services
CustomRect {
@@ -36,7 +37,7 @@ CustomRect {
readonly property color onColor: !enabled ? disabledOnColor : internalChecked ? activeOnColor : inactiveOnColor
property real padding
readonly property alias pressed: stateLayer.pressed
property real pressedRadius: Tokens.rounding.smallest
property real pressedRadius: Tokens.rounding.small
readonly property alias radiusAnim: radiusAnim
property bool radiusMorph: true
property alias shapeMorph: stateLayer.shapeMorph
+2 -58
View File
@@ -2,62 +2,6 @@ import QtQuick
import ZShell.Config
ColorAnimation {
enum Type {
StandardSmall = 0,
Standard,
StandardLarge,
StandardExtraLarge,
EmphasizedSmall,
Emphasized,
EmphasizedLarge,
EmphasizedExtraLarge,
FastSpatial,
DefaultSpatial,
SlowSpatial,
FastEffects,
DefaultEffects,
SlowEffects
}
property int type: CAnim.DefaultSpatial
duration: {
if (type < CAnim.StandardSmall || type > Anim.SlowEffects)
return Tokens.anim.durations.normal;
if (type === CAnim.FastSpatial)
return Tokens.anim.durations.expressiveFastSpatial;
if (type === CAnim.DefaultSpatial)
return Tokens.anim.durations.expressiveDefaultSpatial;
if (type === CAnim.SlowSpatial)
return Tokens.anim.durations.large;
if (type === CAnim.FastEffects)
return Tokens.anim.durations.expressiveFastEffects;
if (type === CAnim.DefaultEffects)
return Tokens.anim.durations.expressiveEffects;
if (type === CAnim.SlowEffects)
return Tokens.anim.durations.expressiveSlowEffects;
const types = ["small", "normal", "large", "extraLarge"];
const idx = type % 4;
return Tokens.anim.durations[types[idx]];
}
easing.bezierCurve: {
if (type === CAnim.FastSpatial)
return Tokens.anim.curves.expressiveFastSpatial;
if (type === CAnim.DefaultSpatial)
return Tokens.anim.curves.expressiveDefaultSpatial;
if (type === CAnim.SlowSpatial)
return Tokens.anim.curves.expressiveSlowSpatial;
if (type === CAnim.FastEffects)
return Tokens.anim.curves.expressiveFastEffects;
if (type === CAnim.DefaultEffects)
return Tokens.anim.curves.expressiveDefaultEffects;
if (type === CAnim.SlowEffects)
return Tokens.anim.curves.expressiveSlowEffects;
if (type >= CAnim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge)
return Tokens.anim.curves.emphasized;
return Tokens.anim.curves.standard;
}
duration: Tokens.anim.durations.expressiveSlowEffects
easing: Tokens.anim.expressiveSlowEffects
}
+1 -1
View File
@@ -23,7 +23,7 @@ BusyIndicator {
property real implicitSize: Tokens.font.size.normal * 3
property real internalStrokeWidth: strokeWidth
readonly property alias progress: manager.progress
property real strokeWidth: Tokens.padding.small * 0.8
property real strokeWidth: Tokens.padding.extraSmall * 0.8
property alias type: manager.indeterminateAnimationType
implicitHeight: implicitSize
+1 -1
View File
@@ -21,7 +21,7 @@ Item {
readonly property real size: Math.min(width, height)
property int spacing: Tokens.spacing.small
property int startAngle: -90
property int strokeWidth: Tokens.padding.small
property int strokeWidth: Tokens.padding.extraSmall
property int sweepAngle: 360
readonly property real thickness: strokeWidth * (1 + waveAmplitude) * 2
property real value
+1 -1
View File
@@ -23,7 +23,7 @@ CheckBox {
color: Colors.palette.m3surfaceVariant
implicitHeight: control.checkHeight
implicitWidth: control.checkWidth
radius: Tokens.rounding.smallest / 2
radius: Tokens.rounding.small / 2
CustomRect {
color: Colors.palette.m3primary
+3 -1
View File
@@ -28,6 +28,8 @@ Flickable {
interval: 10
running: root.doneFakeFlick
onTriggered: root.doneFakeFlick = false
onTriggered: {
root.doneFakeFlick = false;
}
}
}
+17 -14
View File
@@ -10,24 +10,27 @@ ListView {
maximumFlickVelocity: 3000
rebound: Transition {
onRunningChanged: {
if (!running && !root.doneFakeFlick) {
root.doneFakeFlick = true;
root.flick(1, 1);
root.flick(-1, -1);
Qt.callLater(() => root.cancelFlick());
}
}
// onRunningChanged: {
// if (!running && !root.doneFakeFlick) {
// root.doneFakeFlick = true;
// root.flick(1, 1);
// root.flick(-1, -1);
// Qt.callLater(() => root.cancelFlick());
// }
// }
Anim {
properties: "x,y"
type: Anim.DefaultEffects
}
}
Timer {
interval: 10
running: root.doneFakeFlick
onTriggered: root.doneFakeFlick = false
}
// Timer {
// interval: 10
// running: root.doneFakeFlick
//
// onTriggered: {
// root.doneFakeFlick = false;
// }
// }
}
+1
View File
@@ -4,6 +4,7 @@ MouseArea {
property int scrollAccumulatedY: 0
function onWheel(event: WheelEvent): void {
event.accepted = false;
}
onWheel: event => {
+1 -2
View File
@@ -6,7 +6,6 @@ Rectangle {
color: "transparent"
Behavior on color {
CAnim {
}
CAnim {}
}
}
+62 -78
View File
@@ -1,32 +1,37 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Templates
import qs.Helpers
import ZShell.Config
import qs.Services
ScrollBar {
id: root
required property Flickable flickable
readonly property bool isHorizontal: flickable && flickable.ScrollBar.horizontal === root
readonly property real axisSize: isHorizontal ? flickable.width : flickable.height
readonly property real axisContentSize: isHorizontal ? flickable.contentWidth : flickable.contentHeight
readonly property real axisContentPos: isHorizontal ? (reversed ? flickable.contentX : (flickable.contentX - flickable.originX)) : (reversed ? flickable.contentY : (flickable.contentY - flickable.originY))
readonly property real axisLength: isHorizontal ? root.width : root.height
readonly property real effectiveSize: Math.max(nonAnimHeight, root.minimumSize)
readonly property real effectiveTravel: Math.max(0, 1 - root.effectiveSize)
required property Flickable flickable
readonly property real nonAnimHeight: flickable.height / flickable.contentHeight
readonly property real nonAnimY: flickable.contentY / flickable.contentHeight
readonly property real nonAnimHeight: root.axisSize / root.axisContentSize
readonly property real nonAnimY: root.axisContentPos / root.axisContentSize
readonly property real rawTravel: Math.max(0, 1 - root.nonAnimHeight)
readonly property bool reversed: flickable instanceof ListView && flickable.verticalLayoutDirection === ListView.BottomToTop
readonly property bool reversed: isHorizontal ? (flickable instanceof ListView && flickable.layoutDirection === Qt.RightToLeft) : (flickable instanceof ListView && flickable.verticalLayoutDirection === ListView.BottomToTop)
property bool shouldBeActive
readonly property real travelScale: root.rawTravel > 0 ? root.effectiveTravel / root.rawTravel : 0
enabled: !Visibilities.getForActive().isDrawing
implicitWidth: Tokens.padding.extraSmall * 2
implicitWidth: size === 1 ? 0 : isHorizontal ? 0 : Tokens.padding.extraSmall * 2
implicitHeight: size === 1 ? 0 : isHorizontal ? Tokens.padding.extraSmall * 2 : 0
contentItem: Item {
}
contentItem: Item {}
Behavior on position {
enabled: !fullMouse.pressed
Anim {
}
Anim {}
}
onHoveredChanged: {
@@ -47,54 +52,27 @@ ScrollBar {
target: root.flickable
}
CustomClippingRect {
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.top: parent.top
implicitWidth: handle.implicitWidth
radius: Tokens.rounding.full
Loader {
anchors.fill: parent
active: root.size < 1
sourceComponent: root.isHorizontal ? horizontalTrack : verticalTrack
}
CustomRect {
id: handle
Component {
id: verticalTrack
anchors.right: parent.right
color: Colors.palette.m3secondary
implicitHeight: root.height * root.effectiveSize
implicitWidth: fullMouse.pressed || fullMouse.containsMouse ? Tokens.padding.extraSmall * 2 : Tokens.padding.extraSmall
opacity: {
if (!root.enabled)
return 0;
if (root.size === 1)
return 0;
if (fullMouse.pressed)
return 1;
if (fullMouse.containsMouse)
return 0.8;
if (root.policy === ScrollBar.AlwaysOn || root.shouldBeActive)
return 0.6;
return 0;
}
radius: Tokens.rounding.full
y: root.reversed ? root.height * (1 + root.nonAnimY) * root.travelScale : root.height * root.nonAnimY * root.travelScale
VerticalScrollBarTrack {
scrollBar: root
mouseArea: fullMouse
}
}
Behavior on implicitWidth {
Anim {
}
}
Behavior on opacity {
Anim {
type: Anim.DefaultEffects
}
}
Component {
id: horizontalTrack
MouseArea {
id: mouse
acceptedButtons: Qt.NoButton
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
}
HorizontalScrollBarTrack {
scrollBar: root
mouseArea: fullMouse
}
}
@@ -111,25 +89,40 @@ ScrollBar {
property real pressOffset: 0
function contentYFromThumbTop(thumbTop) {
var visualPos = root.effectiveTravel > 0 ? thumbTop / root.travelScale : 0;
return root.reversed ? (visualPos - 1) * root.flickable.contentHeight : visualPos * root.flickable.contentHeight;
function contentPosFromThumbStart(thumbStart) {
var visualPos = root.effectiveTravel > 0 ? thumbStart / root.travelScale : 0;
return root.reversed ? (visualPos - 1) * root.axisContentSize : visualPos * root.axisContentSize;
}
function updateFromEvent(event) {
var posInTrack = event.y / root.height;
var thumbTop = posInTrack - pressOffset;
thumbTop = Math.max(0, Math.min(root.effectiveTravel, thumbTop));
var eventPos = root.isHorizontal ? event.x : event.y;
var posInTrack = eventPos / root.axisLength;
var thumbStart = posInTrack - pressOffset;
thumbStart = Math.max(0, Math.min(root.effectiveTravel, thumbStart));
root.flickable.contentY = contentYFromThumbTop(thumbTop);
var newPos = contentPosFromThumbStart(thumbStart);
if (root.isHorizontal)
root.flickable.contentX = newPos + (root.flickable.originX + (root.reversed ? root.flickable.contentWidth : 0));
else
root.flickable.contentY = newPos + (root.flickable.originY + (root.reversed ? root.flickable.contentHeight : 0));
}
function visualThumbTop() {
function visualThumbStart() {
const visualPos = root.reversed ? (1 + root.nonAnimY) : root.nonAnimY;
return visualPos * root.travelScale;
}
function onWheel(event: WheelEvent): void {
if (root.horizontal) {
event.accepted = false;
return;
}
var delta = event.angleDelta.y > 0 ? -0.1 : 0.1;
var newPos = Math.max(0, Math.min(1 - root.size, root.position + delta));
root.position = newPos;
}
anchors.fill: parent
cursorShape: undefined
hoverEnabled: true
@@ -140,24 +133,15 @@ ScrollBar {
updateFromEvent(event);
}
onPressed: event => {
var currentTop = visualThumbTop();
var currentBottom = currentTop + root.effectiveSize;
var clickPos = event.y / root.height;
var currentStart = visualThumbStart();
var currentEnd = currentStart + root.effectiveSize;
var eventPos = root.isHorizontal ? event.x : event.y;
var clickPos = eventPos / root.axisLength;
var clickedInsideThumb = clickPos >= currentTop && clickPos <= currentBottom;
if (clickedInsideThumb) {
pressOffset = clickPos - currentTop;
} else {
pressOffset = root.effectiveSize / 2;
}
var clickedInsideThumb = clickPos >= currentStart && clickPos <= currentEnd;
pressOffset = clickedInsideThumb ? (clickPos - currentStart) : root.effectiveSize / 2;
updateFromEvent(event);
}
onWheel: event => {
var delta = event.angleDelta.y > 0 ? -0.1 : 0.1;
var newPos = Math.max(0, Math.min(1 - root.size, root.position + delta));
root.position = newPos;
}
}
}
+4 -1
View File
@@ -13,11 +13,13 @@ Slider {
property bool animateWave
property color bgColor: enabled ? Colors.palette.m3secondaryContainer : Qt.alpha(Colors.palette.m3onSurface, 0.1)
readonly property bool dragging: mouse.pressed
property color fgColor: enabled ? Colors.palette.m3primary : Qt.alpha(Colors.palette.m3onSurface, 0.38)
property real filledWidth
property alias inset: inset
property color insetColor: enabled ? (inset.attached ? Colors.palette.m3onSecondaryContainer : Colors.palette.m3onPrimary) : Colors.palette.m3onSurface
property string insetIcon: ""
property bool interactionOnMove: true
property real pos: visualPosition
property int radius: Tokens.rounding.small
property int waveDuration: 1000
@@ -186,7 +188,8 @@ Slider {
onPositionChanged: e => {
dragMovement = (e.x - pressStartX) / width;
root.interaction(posBinding.value);
if (root.interactionOnMove)
root.interaction(posBinding.value);
}
onPressed: e => {
widthBehavior.enabled = false;
+2 -2
View File
@@ -38,9 +38,9 @@ DoubleSpinBox {
horizontalAlignment: TextField.AlignHCenter
implicitWidth: 65
inputMethodHints: Qt.ImhFormattedNumbersOnly
leftPadding: Tokens.padding.larger
leftPadding: Tokens.padding.small
readOnly: !root.editable
rightPadding: Tokens.padding.larger
rightPadding: Tokens.padding.small
text: root.textFromValue(root.value, root.locale)
validator: root.validator
-70
View File
@@ -1,70 +0,0 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Layouts
import ZShell.Config
import qs.Services
Item {
id: root
property alias active: splitButton.active
property alias buttonAlias: splitButton
property alias expanded: splitButton.expanded
property int expandedZ: 100
required property string label
property alias menuItems: splitButton.menuItems
property bool shouldBeActive: true
property alias type: splitButton.type
signal selected(item: MenuItem)
anchors.left: parent.left
anchors.right: parent.right
clip: false
implicitHeight: row.implicitHeight + Tokens.padding.smaller * 2
opacity: shouldBeActive ? 1 : 0
scale: shouldBeActive ? 1 : 0.8
z: splitButton.menu.implicitHeight > 0 ? expandedZ : 1
Behavior on opacity {
Anim {
}
}
Behavior on scale {
Anim {
}
}
RowLayout {
id: row
anchors.left: parent.left
anchors.margins: Tokens.padding.small
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
spacing: Tokens.spacing.normal
CustomText {
Layout.fillWidth: true
color: root.enabled ? Colors.palette.m3onSurface : Colors.palette.m3onSurfaceVariant
font.pointSize: Tokens.font.size.larger
text: root.label
}
CustomSplitButton {
id: splitButton
enabled: root.enabled
type: CustomSplitButton.Filled
z: 2
menu.onItemSelected: item => {
root.selected(item);
}
stateLayer.onClicked: {
splitButton.expanded = !splitButton.expanded;
}
}
}
}
+20 -8
View File
@@ -13,8 +13,12 @@ Switch {
implicitWidth: implicitIndicatorWidth
indicator: CustomRect {
color: root.checked && root.enabled ? Colors.palette.m3primary : Colors.layer(Colors.palette.m3surfaceContainerHighest, root.cLayer)
implicitHeight: Tokens.font.size.medium + Tokens.padding.normal * 2
color: {
if (!root.enabled)
return root.checked ? Qt.alpha(Colors.palette.m3onSurface, 0.12) : Qt.alpha(Colors.palette.m3surfaceContainerHighest, 0.38);
return root.checked ? Colors.palette.m3primary : Colors.layer(Colors.palette.m3surfaceContainerHighest, root.cLayer);
}
implicitHeight: 14 + Tokens.padding.small * 2
implicitWidth: implicitHeight * 1.7
radius: Tokens.rounding.full
@@ -22,7 +26,11 @@ Switch {
readonly property real nonAnimWidth: root.pressed ? implicitHeight * 1.2 : implicitHeight
anchors.verticalCenter: parent.verticalCenter
color: root.checked && root.enabled ? Colors.palette.m3onPrimary : Colors.layer(Colors.palette.m3outline, root.cLayer + 1)
color: {
if (!root.enabled)
return root.checked ? Qt.alpha(Colors.palette.m3surface, 0.7) : Qt.alpha(Colors.palette.m3onSurface, 0.12);
return root.checked ? Colors.palette.m3onPrimary : Colors.layer(Colors.palette.m3outline, root.cLayer + 1);
}
implicitHeight: parent.implicitHeight - Tokens.padding.extraSmall
implicitWidth: nonAnimWidth
radius: Tokens.rounding.full
@@ -92,7 +100,7 @@ Switch {
anchors.centerIn: parent
asynchronous: true
height: parent.implicitHeight - Tokens.padding.larger
height: parent.implicitHeight - Tokens.padding.medium
preferredRendererType: Shape.CurveRenderer
width: height
@@ -114,12 +122,16 @@ Switch {
}
ShapePath {
capStyle: ShapePath.RoundCap
capStyle: Tokens.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap
fillColor: "transparent"
startX: icon.start1.x
startY: icon.start1.y
strokeColor: root.checked && root.enabled ? Colors.palette.m3primary : Colors.palette.m3surfaceContainerHighest
strokeWidth: Tokens.font.size.larger * 0.15
strokeColor: {
if (!root.enabled)
return root.checked ? Colors.palette.m3outline : Colors.palette.m3surfaceContainer;
return root.checked ? Colors.palette.m3primary : Colors.palette.m3surfaceContainerHighest;
}
strokeWidth: 16 * 0.15
Behavior on strokeColor {
CAnim {
@@ -153,6 +165,6 @@ Switch {
component PropAnim: PropertyAnimation {
duration: Tokens.anim.durations.expressiveFastSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial
easing: Tokens.anim.expressiveFastSpatial
}
}
+4 -4
View File
@@ -129,8 +129,8 @@ TextFieldBase {
}
AnchorAnim {
duration: Tokens.anim.durations.expressiveEffects
easing.bezierCurve: Tokens.anim.curves.expressiveEffects
duration: Tokens.anim.durations.expressiveDefaultEffects
easing: Tokens.anim.expressiveDefaultEffects
}
}
}
@@ -140,7 +140,7 @@ TextFieldBase {
active: root.leadingIcon
anchors.left: parent.left
anchors.leftMargin: Tokens.padding.normal
anchors.leftMargin: Tokens.padding.small
anchors.verticalCenter: parent.verticalCenter
sourceComponent: MaterialIcon {
@@ -154,7 +154,7 @@ TextFieldBase {
active: root.trailingIcon
anchors.right: parent.right
anchors.rightMargin: Tokens.padding.normal
anchors.rightMargin: Tokens.padding.small
anchors.verticalCenter: parent.verticalCenter
sourceComponent: MaterialIcon {
+56
View File
@@ -0,0 +1,56 @@
import QtQuick
import ZShell.Config
import qs.Services
CustomClippingRect {
id: track
required property var scrollBar
required property var mouseArea
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
implicitHeight: handle.implicitHeight
radius: Tokens.rounding.full
CustomRect {
id: handle
anchors.bottom: parent.bottom
color: Colors.palette.m3secondary
implicitWidth: track.scrollBar.width * track.scrollBar.effectiveSize
implicitHeight: track.mouseArea.pressed || track.mouseArea.containsMouse ? Tokens.padding.extraSmall * 2 : Tokens.padding.extraSmall
opacity: {
if (!track.scrollBar.enabled)
return 0;
if (track.scrollBar.size === 1)
return 0;
if (track.mouseArea.pressed)
return 1;
if (track.mouseArea.containsMouse)
return 0.8;
if (track.scrollBar.policy === CustomScrollBar.AlwaysOn || track.scrollBar.shouldBeActive)
return 0.6;
return 0;
}
radius: Tokens.rounding.full
x: track.scrollBar.reversed ? track.scrollBar.width * (1 + track.scrollBar.nonAnimY) * track.scrollBar.travelScale : track.scrollBar.width * track.scrollBar.nonAnimY * track.scrollBar.travelScale
Behavior on implicitHeight {
Anim {}
}
Behavior on opacity {
Anim {
type: Anim.DefaultEffects
}
}
MouseArea {
acceptedButtons: Qt.NoButton
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
}
}
}
+1 -1
View File
@@ -27,7 +27,7 @@ ButtonBase {
return Colors.palette.m3onPrimary;
return type === IconButton.Tonal ? Colors.palette.m3onSecondaryContainer : Colors.palette.m3onSurfaceVariant;
}
padding: type === IconButton.Text ? Tokens.padding.extraSmall / 2 : Tokens.padding.small
padding: type === IconButton.Text ? Tokens.padding.extraSmall / 2 : Tokens.padding.extraSmall
MaterialIcon {
id: label
+2 -2
View File
@@ -17,7 +17,7 @@ ButtonBase {
return Colors.palette.m3primary;
return type === TextButton.Filled ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondary;
}
horizontalPadding: Tokens.padding.larger
horizontalPadding: Tokens.padding.small
implicitHeight: row.implicitHeight + verticalPadding * 2
implicitWidth: row.implicitWidth + horizontalPadding * 2
inactiveColor: {
@@ -32,7 +32,7 @@ ButtonBase {
return Colors.palette.m3primary;
return type === TextButton.Filled ? Colors.palette.m3onSurface : Colors.palette.m3onSecondaryContainer;
}
verticalPadding: Tokens.padding.small
verticalPadding: Tokens.padding.extraSmall
RowLayout {
id: row
+147 -129
View File
@@ -18,13 +18,14 @@ Item {
property real leftFadeStrength: overflowing && leftFadeEnabled ? fadeStrengthMoving : fadeStrengthIdle
property int leftFadeWidth: 28
property bool marqueeEnabled: true
readonly property bool overflowing: metrics.width > root.width
readonly property bool overflowing: metrics.width > content.width
property int pauseMs: 1200
property real pixelsPerSecond: 40
property real rightFadeStrength: overflowing ? fadeStrengthMoving : fadeStrengthIdle
property int rightFadeWidth: 28
property bool sliding: false
property alias text: elideText.text
property bool vertical: false
function durationForDistance(px): int {
return Math.max(1, Math.round(Math.abs(px) / root.pixelsPerSecond * 1000));
@@ -42,7 +43,8 @@ Item {
}
clip: false
implicitHeight: elideText.implicitHeight
implicitHeight: vertical ? elideText.implicitWidth : elideText.implicitHeight
implicitWidth: vertical ? elideText.implicitHeight : elideText.implicitWidth
Behavior on leftFadeStrength {
Anim {
@@ -53,171 +55,187 @@ Item {
}
}
onHeightChanged: resetMarquee()
onTextChanged: resetMarquee()
onVerticalChanged: resetMarquee()
onVisibleChanged: if (!visible)
resetMarquee()
onWidthChanged: resetMarquee()
TextMetrics {
id: metrics
font: elideText.font
text: elideText.text
}
CustomText {
id: elideText
anchors.verticalCenter: parent.verticalCenter
animate: root.animate
animateProp: "scale,opacity"
color: root.color
elide: Text.ElideNone
visible: !root.overflowing
width: root.width
}
Item {
id: marqueeViewport
id: content
anchors.fill: parent
clip: false
layer.enabled: true
visible: root.overflowing
anchors.centerIn: parent
height: root.vertical ? root.width : root.height
width: root.vertical ? root.height : root.width
layer.effect: OpacityMask {
maskSource: rightFadeMask
transform: Rotation {
angle: root.vertical ? -90 : 0
origin.x: content.width / 2
origin.y: content.height / 2
}
TextMetrics {
id: metrics
font: elideText.font
text: elideText.text
}
CustomText {
id: elideText
anchors.verticalCenter: parent.verticalCenter
animate: root.animate
animateProp: "scale,opacity"
color: root.color
elide: Text.ElideNone
visible: !root.overflowing
width: content.width
}
Item {
id: strip
id: marqueeViewport
anchors.verticalCenter: parent.verticalCenter
height: t1.implicitHeight
width: t1.width + root.gap + t2.width
x: 0
anchors.fill: parent
clip: false
layer.enabled: true
visible: root.overflowing
CustomText {
id: t1
animate: root.animate
animateProp: "opacity"
color: root.color
font.pointSize: elideText.font.pointSize
text: elideText.text
layer.effect: OpacityMask {
maskSource: rightFadeMask
}
CustomText {
id: t2
Item {
id: strip
animate: root.animate
animateProp: "opacity"
color: root.color
font.pointSize: elideText.font.pointSize
text: t1.text
x: t1.width + root.gap
}
}
anchors.verticalCenter: parent.verticalCenter
height: t1.implicitHeight
width: t1.width + root.gap + t2.width
x: 0
SequentialAnimation {
id: marqueeAnim
CustomText {
id: t1
running: false
animate: root.animate
animateProp: "opacity"
color: root.color
font.pointSize: elideText.font.pointSize
text: elideText.text
}
onFinished: pauseTimer.restart()
CustomText {
id: t2
ScriptAction {
script: {
root.sliding = true;
root.leftFadeEnabled = true;
animate: root.animate
animateProp: "opacity"
color: root.color
font.pointSize: elideText.font.pointSize
text: t1.text
x: t1.width + root.gap
}
}
Anim {
duration: root.durationForDistance(t1.width)
easing.bezierCurve: Easing.Linear
easing.type: Easing.Linear
from: 0
property: "x"
target: strip
to: -t1.width
}
SequentialAnimation {
id: marqueeAnim
ScriptAction {
script: {
root.leftFadeEnabled = false;
running: false
onFinished: pauseTimer.restart()
ScriptAction {
script: {
root.sliding = true;
root.leftFadeEnabled = true;
}
}
Anim {
duration: root.durationForDistance(t1.width)
easing.bezierCurve: Easing.Linear
easing.type: Easing.Linear
from: 0
property: "x"
target: strip
to: -t1.width
}
ScriptAction {
script: {
root.leftFadeEnabled = false;
}
}
Anim {
duration: root.durationForDistance(root.gap)
easing.bezierCurve: Easing.Linear
easing.type: Easing.Linear
from: -t1.width
property: "x"
target: strip
to: -(t1.width + root.gap)
}
ScriptAction {
script: {
root.sliding = false;
strip.x = 0;
}
}
}
Anim {
duration: root.durationForDistance(root.gap)
easing.bezierCurve: Easing.Linear
easing.type: Easing.Linear
from: -t1.width
property: "x"
target: strip
to: -(t1.width + root.gap)
}
Timer {
id: pauseTimer
ScriptAction {
script: {
root.sliding = false;
strip.x = 0;
interval: root.pauseMs
repeat: false
running: true
onTriggered: {
if (root.marqueeEnabled)
marqueeAnim.start();
}
}
}
Timer {
id: pauseTimer
Rectangle {
id: rightFadeMask
interval: root.pauseMs
repeat: false
running: true
onTriggered: {
if (root.marqueeEnabled)
marqueeAnim.start();
readonly property real fadeStartPos: {
const w = Math.max(1, width);
return Math.max(0, Math.min(1, (w - root.rightFadeWidth) / w));
}
}
}
Rectangle {
id: rightFadeMask
readonly property real fadeStartPos: {
const w = Math.max(1, width);
return Math.max(0, Math.min(1, (w - root.rightFadeWidth) / w));
}
readonly property real leftFadeEndPos: {
const w = Math.max(1, width);
return Math.max(0, Math.min(1, root.leftFadeWidth / w));
}
anchors.fill: marqueeViewport
layer.enabled: true
visible: false
gradient: Gradient {
orientation: Gradient.Horizontal
GradientStop {
color: Qt.rgba(1, 1, 1, 1.0 - root.leftFadeStrength)
position: 0.0
readonly property real leftFadeEndPos: {
const w = Math.max(1, width);
return Math.max(0, Math.min(1, root.leftFadeWidth / w));
}
GradientStop {
color: Qt.rgba(1, 1, 1, 1.0)
position: rightFadeMask.leftFadeEndPos
}
anchors.fill: marqueeViewport
layer.enabled: true
visible: false
GradientStop {
color: Qt.rgba(1, 1, 1, 1.0)
position: rightFadeMask.fadeStartPos
}
gradient: Gradient {
orientation: Gradient.Horizontal
GradientStop {
color: Qt.rgba(1, 1, 1, 1.0 - root.rightFadeStrength)
position: 1.0
GradientStop {
color: Qt.rgba(1, 1, 1, 1.0 - root.leftFadeStrength)
position: 0.0
}
GradientStop {
color: Qt.rgba(1, 1, 1, 1.0)
position: rightFadeMask.leftFadeEndPos
}
GradientStop {
color: Qt.rgba(1, 1, 1, 1.0)
position: rightFadeMask.fadeStartPos
}
GradientStop {
color: Qt.rgba(1, 1, 1, 1.0 - root.rightFadeStrength)
position: 1.0
}
}
}
}
+9 -9
View File
@@ -78,7 +78,7 @@ MouseArea {
implicitHeight: column.implicitHeight + column.anchors.margins * 2
implicitWidth: Math.max(200, column.implicitWidth + column.anchors.margins * 2)
level: 2
radius: Tokens.rounding.medium
radius: Tokens.rounding.large
x: {
watcher.transform;
const item = root.attachTo;
@@ -126,15 +126,15 @@ MouseArea {
CustomRect {
id: item
readonly property bool active: modelData === root.active
readonly property bool active: modelData === root?.active
required property int index
required property MenuItem modelData
Layout.fillWidth: true
color: Qt.alpha(Colors.palette.m3tertiaryContainer, active ? 1 : 0)
implicitHeight: menuOptionRow.implicitHeight + Tokens.padding.larger * 2
implicitWidth: menuOptionRow.implicitWidth + Tokens.padding.larger * 2
radius: Tokens.rounding.small
implicitHeight: menuOptionRow.implicitHeight + Tokens.padding.medium * 2
implicitWidth: menuOptionRow.implicitWidth + Tokens.padding.medium * 2
radius: menu.radius - column.anchors.margins
Behavior on radius {
Anim {
@@ -157,25 +157,25 @@ MouseArea {
id: menuOptionRow
anchors.fill: parent
anchors.margins: Tokens.padding.larger
anchors.margins: Tokens.padding.medium
spacing: Tokens.spacing.small
MaterialIcon {
Layout.alignment: Qt.AlignVCenter
color: item.active ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurfaceVariant
text: item.modelData.icon
text: item.modelData?.icon ?? ""
}
CustomText {
Layout.alignment: Qt.AlignVCenter
Layout.fillWidth: true
color: item.active ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurface
text: item.modelData.text
text: item.modelData?.text ?? ""
}
Loader {
Layout.alignment: Qt.AlignVCenter
active: item.modelData.trailingIcon.length > 0
active: item.modelData?.trailingIcon.length > 0
asynchronous: true
visible: active
+1 -1
View File
@@ -70,7 +70,7 @@ TextFieldBase {
id: clearIcon
anchors.right: parent.right
anchors.rightMargin: Tokens.padding.larger
anchors.rightMargin: Tokens.padding.small
anchors.verticalCenter: parent.verticalCenter
enabled: root.text
icon: "clear"
@@ -12,14 +12,14 @@ Row {
}
property alias active: menu.active
property color color: type == CustomSplitButton.Filled ? Colors.palette.m3primary : Colors.palette.m3secondaryContainer
property color color: type == SplitButton.Filled ? Colors.palette.m3primary : Colors.palette.m3secondaryContainer
property color disabledColor: Qt.alpha(Colors.palette.m3onSurface, 0.1)
property color disabledTextColor: Qt.alpha(Colors.palette.m3onSurface, 0.38)
readonly property alias expandBtn: expandBtn
property alias expanded: menu.expanded
property string fallbackIcon
property string fallbackText
property real horizontalPadding: Tokens.padding.larger
property real horizontalPadding: Tokens.padding.medium
readonly property alias iconLabel: iconLabel
readonly property alias label: label
readonly property alias menu: menu
@@ -27,20 +27,20 @@ Row {
property bool menuOnTop
property real minLeftWidth
readonly property alias stateLayer: stateLayer
property color textColor: type == CustomSplitButton.Filled ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondaryContainer
property color textColor: type == SplitButton.Filled ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondaryContainer
readonly property alias textRow: textRow
property int type: CustomSplitButton.Filled
property int type: SplitButton.Filled
property real verticalPadding: Tokens.padding.small
spacing: Math.floor(Tokens.spacing.extraSmall)
spacing: Math.floor(Tokens.spacing.extraSmall / 2)
CustomRect {
bottomRightRadius: Tokens.rounding.small / 2
bottomRightRadius: Tokens.rounding.medium / 2
color: !root.enabled ? root.disabledColor : root.color
implicitHeight: expandBtn.implicitHeight
implicitWidth: Math.max(root.minLeftWidth, textRow.implicitWidth + root.horizontalPadding * 2)
radius: implicitHeight / 2 * Math.min(1, Tokens.rounding.scale)
topRightRadius: Tokens.rounding.small / 2
topRightRadius: Tokens.rounding.medium / 2
StateLayer {
id: stateLayer
@@ -92,7 +92,7 @@ Row {
CustomRect {
id: expandBtn
property real rad: root.expanded ? implicitHeight / 2 * Math.min(1, Tokens.rounding.scale) : Tokens.rounding.small / 2
property real rad: root.expanded ? implicitHeight / 2 * Math.min(1, Tokens.rounding.scale) : Tokens.rounding.medium / 2
bottomLeftRadius: rad
color: !root.enabled ? root.disabledColor : root.color
+2 -3
View File
@@ -1,9 +1,8 @@
import QtQuick
import QtQuick.Shapes
import ZShell
import ZShell.Components
import qs.Helpers
import ZShell.Config
import qs.Helpers
import qs.Services
MouseArea {
@@ -81,7 +80,7 @@ MouseArea {
alwaysRunToEnd: true
duration: Tokens.anim.durations.expressiveSlowEffects * 2
easing.bezierCurve: Tokens.anim.curves.standard
easing: Tokens.anim.standard
property: "circleRadius"
target: root
to: root.endRadius
+86
View File
@@ -0,0 +1,86 @@
import QtQuick
import QtQuick.Templates
import ZShell.Config
import qs.Services
TextArea {
id: root
color: Colors.palette.m3onSurface
cursorVisible: !readOnly
font.pointSize: Tokens.font.size.small
implicitHeight: contentHeight + topPadding + bottomPadding
implicitWidth: contentWidth + leftPadding + rightPadding
placeholderTextColor: Colors.palette.m3onSurfaceVariant // No anim cause placeholder is custom
renderType: TextArea.NativeRendering
selectedTextColor: color
selectionColor: Qt.alpha(Colors.palette.m3primary, 0.4)
verticalAlignment: TextInput.AlignVCenter
Behavior on color {
CAnim {}
}
Behavior on selectionColor {
CAnim {}
}
cursorDelegate: Item {}
CustomRect {
id: cursor
property bool disableBlink
color: Colors.palette.m3primary
implicitHeight: root.cursorRectangle.height
implicitWidth: 1.5
radius: Tokens.rounding.largeIncreased
x: root.cursorRectangle.x
y: root.cursorRectangle.y
Behavior on x {
Anim {
duration: Tokens.anim.durations.expressiveFastEffects
easing.bezierCurve: [0.2, 1, 0.21, 1, 1, 1]
}
}
Behavior on opacity {
Anim {
type: Anim.StandardSmall
}
}
Connections {
function onCursorPositionChanged(): void {
if (root.activeFocus && root.cursorVisible) {
cursor.opacity = 1;
cursor.disableBlink = true;
enableBlink.restart();
}
}
target: root
}
Timer {
id: enableBlink
interval: 500
onTriggered: cursor.disableBlink = false
}
Timer {
interval: 500
repeat: true
running: root.activeFocus && root.cursorVisible && !cursor.disableBlink
triggeredOnStart: true
onTriggered: parent.opacity = parent.opacity === 1 ? 0 : 1
}
Binding {
cursor.opacity: 0
when: !root.activeFocus || !root.cursorVisible
}
}
}
+2 -2
View File
@@ -14,7 +14,7 @@ ButtonBase {
return Colors.palette.m3primary;
return type === TextButton.Filled ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondary;
}
horizontalPadding: Tokens.padding.normal
horizontalPadding: Tokens.padding.small
implicitHeight: label.implicitHeight + verticalPadding * 2
implicitWidth: label.implicitWidth + horizontalPadding * 2
inactiveColor: {
@@ -29,7 +29,7 @@ ButtonBase {
return Colors.palette.m3primary;
return type === TextButton.Filled ? Colors.palette.m3onSurface : Colors.palette.m3onSecondaryContainer;
}
verticalPadding: Tokens.padding.small
verticalPadding: Tokens.padding.extraSmall
CustomText {
id: label
+100
View File
@@ -0,0 +1,100 @@
import QtQuick
import QtQuick.Templates
import ZShell.Config
import qs.Services
TextEdit {
id: root
property bool animateCursor: true
property alias cursor: cursor
color: Colors.palette.m3onSurface
cursorVisible: !readOnly
font.pointSize: Tokens.font.size.small
font.family: Config.appearance.font.family.sans
renderType: TextField.NativeRendering
selectedTextColor: color
selectionColor: Qt.alpha(Colors.palette.m3primary, 0.4)
verticalAlignment: TextInput.AlignVCenter
Behavior on color {
CAnim {
}
}
cursorDelegate: Item {
}
Behavior on selectionColor {
CAnim {
}
}
CustomRect {
id: cursor
property bool disableBlink
color: Colors.palette.m3primary
implicitHeight: root.cursorRectangle.height
implicitWidth: 1.5
radius: Tokens.rounding.largeIncreased
x: root.cursorRectangle.x
y: root.cursorRectangle.y
Behavior on opacity {
Anim {
type: Anim.StandardSmall
}
}
Behavior on x {
enabled: root.animateCursor
Anim {
duration: Tokens.anim.durations.expressiveFastEffects
easing.bezierCurve: [0.2, 1, 0.21, 1, 1, 1]
}
}
Behavior on y {
enabled: root.animateCursor
Anim {
duration: Tokens.anim.durations.expressiveFastEffects
easing.bezierCurve: [0.2, 1, 0.21, 1, 1, 1]
}
}
Connections {
function onCursorPositionChanged(): void {
if (root.activeFocus && root.cursorVisible) {
cursor.opacity = 1;
cursor.disableBlink = true;
enableBlink.restart();
}
}
target: root
}
Timer {
id: enableBlink
interval: 500
onTriggered: cursor.disableBlink = false
}
Timer {
interval: 500
repeat: true
running: root.activeFocus && root.cursorVisible && !cursor.disableBlink
triggeredOnStart: true
onTriggered: parent.opacity = parent.opacity === 1 ? 0 : 1
}
Binding {
cursor.opacity: 0
when: !root.activeFocus || !root.cursorVisible
}
}
}
+1 -1
View File
@@ -36,7 +36,7 @@ TextField {
color: Colors.palette.m3primary
implicitHeight: root.cursorRectangle.height
implicitWidth: 1.5
radius: Tokens.rounding.large
radius: Tokens.rounding.largeIncreased
x: root.cursorRectangle.x
y: root.cursorRectangle.y
+8 -8
View File
@@ -32,8 +32,8 @@ CustomRect {
return Colors.palette.m3errorContainer;
return Colors.palette.m3surface;
}
implicitHeight: layout.implicitHeight + Tokens.padding.smaller * 2
radius: Tokens.rounding.normal
implicitHeight: layout.implicitHeight + Tokens.padding.small * 2
radius: Tokens.rounding.medium
Behavior on border.color {
CAnim {
@@ -52,10 +52,10 @@ CustomRect {
id: layout
anchors.fill: parent
anchors.leftMargin: Tokens.padding.normal
anchors.margins: Tokens.padding.smaller
anchors.rightMargin: Tokens.padding.normal
spacing: Tokens.spacing.normal
anchors.leftMargin: Tokens.padding.small
anchors.margins: Tokens.padding.small
anchors.rightMargin: Tokens.padding.small
spacing: Tokens.spacing.medium
CustomRect {
color: {
@@ -67,9 +67,9 @@ CustomRect {
return Colors.palette.m3error;
return Colors.palette.m3surfaceContainerHigh;
}
implicitHeight: icon.implicitHeight + Tokens.padding.smaller * 2
implicitHeight: icon.implicitHeight + Tokens.padding.small * 2
implicitWidth: implicitHeight
radius: Tokens.rounding.normal
radius: Tokens.rounding.medium
MaterialIcon {
id: icon
+3 -3
View File
@@ -21,7 +21,7 @@ Item {
}
return h;
}
implicitWidth: Config.utilities.sizes.toastWidth - Tokens.padding.normal * 2
implicitWidth: Config.utilities.sizes.toastWidth - Tokens.padding.small * 2
Repeater {
id: repeater
@@ -82,7 +82,7 @@ Item {
Behavior on anchors.bottomMargin {
Anim {
duration: Tokens.anim.durations.expressiveDefaultSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
easing: Tokens.anim.expressiveDefaultSpatial
}
}
Behavior on opacity {
@@ -105,7 +105,7 @@ Item {
id: initAnim
duration: Tokens.anim.durations.expressiveDefaultSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
easing: Tokens.anim.expressiveDefaultSpatial
from: 0
properties: "opacity,scale"
target: toast
+3 -2
View File
@@ -8,6 +8,7 @@ CustomListView {
property real endFadeOpacity: fadeShouldBeActive(false) ? 0 : 1
property real fadeAmount: 0.1
property real fadeThreshold: 0.0
readonly property bool horizontal: orientation === ListView.Horizontal
property real startFadeOpacity: fadeShouldBeActive(true) ? 0 : 1
@@ -28,11 +29,11 @@ CustomListView {
}
function marginEnd(): real {
return horizontal ? rightMargin : bottomMargin;
return horizontal ? rightMargin - fadeThreshold : bottomMargin - fadeThreshold;
}
function marginStart(): real {
return horizontal ? leftMargin : topMargin;
return horizontal ? leftMargin - fadeThreshold : topMargin - fadeThreshold;
}
function overshootStart(): real {
+56
View File
@@ -0,0 +1,56 @@
import QtQuick
import ZShell.Config
import qs.Services
CustomClippingRect {
id: track
required property var scrollBar
required property var mouseArea
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.top: parent.top
implicitWidth: handle.implicitWidth
radius: Tokens.rounding.full
CustomRect {
id: handle
anchors.right: parent.right
color: Colors.palette.m3secondary
implicitHeight: track.scrollBar.height * track.scrollBar.effectiveSize
implicitWidth: track.mouseArea.pressed || track.mouseArea.containsMouse ? Tokens.padding.extraSmall * 2 : Tokens.padding.extraSmall
opacity: {
if (!track.scrollBar.enabled)
return 0;
if (track.scrollBar.size === 1)
return 0;
if (track.mouseArea.pressed)
return 1;
if (track.mouseArea.containsMouse)
return 0.8;
if (track.scrollBar.policy === CustomScrollBar.AlwaysOn || track.scrollBar.shouldBeActive)
return 0.6;
return 0;
}
radius: Tokens.rounding.full
y: track.scrollBar.reversed ? track.scrollBar.height * (1 + track.scrollBar.nonAnimY) * track.scrollBar.travelScale : track.scrollBar.height * track.scrollBar.nonAnimY * track.scrollBar.travelScale
Behavior on implicitWidth {
Anim {}
}
Behavior on opacity {
Anim {
type: Anim.DefaultEffects
}
}
MouseArea {
acceptedButtons: Qt.NoButton
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
}
}
}
-4
View File
@@ -27,10 +27,6 @@ Variants {
}
Connections {
function onConfigDashboardPositionChanged(): void {
Qt.callLater(scope.rebuild);
}
function onConfigPositionChanged(): void {
Qt.callLater(scope.rebuild);
}
+4
View File
@@ -1,6 +1,7 @@
pragma ComponentBehavior: Bound
import Quickshell
import Quickshell.Wayland
import QtQuick
import ZShell.Config
import qs.Components
@@ -15,6 +16,9 @@ Scope {
ExclusionZone {
id: top
WlrLayershell.layer: WlrLayer.Overlay
anchors.left: true
anchors.right: true
anchors.top: true
hasBar: root.geometry.barOnTop
}
+19 -5
View File
@@ -3,7 +3,7 @@ import QtQuick
import qs.Components
import ZShell.Config
import qs.Helpers
import qs.Modules as BarPopouts
import qs.Modules.Bar.Popouts
Item {
id: root
@@ -15,7 +15,7 @@ Item {
required property EdgeGeometry geometry
property bool osdShortcutActive
required property Panels panels
required property BarPopouts.Wrapper popouts
required property Wrapper popouts
required property ShellScreen screen
property bool singleGestureTriggered: false
property bool utilitiesShortcutActive
@@ -162,6 +162,19 @@ Item {
}
}
Timer {
id: unhideTimer
interval: Config.bar.revealDelay
repeat: false
running: false
onTriggered: {
if (hoverHandler.hovered)
root.bar.isHovered = true;
}
}
HoverHandler {
id: hoverHandler
@@ -178,7 +191,7 @@ Item {
root.popouts.hasCurrent = false;
}
if (Config.bar.autoHide)
if (Config.bar.autoHide || root.bar.fullscreen)
root.bar.isHovered = false;
}
}
@@ -200,6 +213,9 @@ Item {
if (!root.visibilities.bar && Config.bar.autoHide && root.geometry.barContains(x, y, true))
root.bar.isHovered = true;
if (root.bar.fullscreen && !root.bar.isHovered)
unhideTimer.start();
if (root.panels.sidebar.offsetScale === 1) {
const showOsd = root.inRightPanel(root.panels.osdWrapper, x, y);
@@ -302,8 +318,6 @@ Item {
root.visibilities.sidebar = false;
root.panels.popouts.hasCurrent = false;
root.visibilities.launcher = false;
} else {
Config.save();
}
}
+8 -10
View File
@@ -1,7 +1,7 @@
import Quickshell
import QtQuick
import qs.Components
import qs.Modules as Modules
import qs.Modules.Bar.Popouts as Popouts
import qs.Modules.Notifications as Notifications
import qs.Modules.Notifications.Sidebar as Sidebar
import qs.Modules.Notifications.Sidebar.Utils as Utils
@@ -53,8 +53,9 @@ Item {
Item {
id: resourcesWrapper
anchors.bottom: root.geometry.position === "bottom" ? parent.bottom : undefined
anchors.left: parent.left
anchors.top: parent.top
anchors.top: root.geometry.position !== "bottom" ? parent.top : undefined
clip: true
implicitHeight: root.geometry.horizontal ? resources.implicitHeight * (1 - resources.offsetScale) : resources.implicitHeight
implicitWidth: root.geometry.horizontal ? resources.implicitWidth : resources.implicitWidth * (1 - resources.offsetScale)
@@ -62,9 +63,7 @@ Item {
Resources.Wrapper {
id: resources
anchors.left: parent.left
anchors.top: parent.top
horizontal: root.geometry.horizontal
position: root.geometry.position
visibilities: root.visibilities
}
}
@@ -100,7 +99,7 @@ Item {
visibilities: root.visibilities
}
Modules.ClipWrapper {
Popouts.ClipWrapper {
id: popouts
borderThickness: root.borderThickness
@@ -112,7 +111,7 @@ Item {
id: toasts
anchors.bottom: sidebar.visible ? parent.bottom : utilities.top
anchors.margins: Tokens.padding.normal
anchors.margins: Tokens.padding.small
anchors.right: sidebar.left
}
@@ -141,7 +140,6 @@ Item {
anchors.bottom: parent.bottom
anchors.right: parent.right
popouts: popouts
sidebar: sidebar
visibilities: root.visibilities
}
@@ -162,15 +160,15 @@ Item {
Behavior on offsetScale {
Anim {
duration: Tokens.anim.durations.expressiveDefaultSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
easing: Tokens.anim.expressiveDefaultSpatial
}
}
Dashboard.Wrapper {
id: dashboard
horizontal: root.geometry.horizontal
offsetScale: dashboardWrapper.offsetScale
position: root.geometry.position
visibilities: root.visibilities
}
}
+22 -19
View File
@@ -51,24 +51,22 @@ CustomWindow {
readonly property HyprlandMonitor monitor: Hypr.monitorFor(screen)
property var root: Quickshell.shellDir
readonly property real sdfBorderOffset: 2 * fsTransitionProg
readonly property real shadowOpacity: 0.7 * (1 - fsTransitionProg)
readonly property real shadowOpacity: 0.7 * (1 - (bar.isHovered ? 0 : fsTransitionProg))
property color surfaceColor: Colors.tPalette.m3surface
WlrLayershell.exclusionMode: ExclusionMode.Ignore
WlrLayershell.keyboardFocus: visibilities.launcher || visibilities.settings ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
WlrLayershell.keyboardFocus: visibilities.launcher || visibilities.settings || visibilities.sidebar ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
WlrLayershell.layer: (fsTransitionProg > 0 && Config.general.showOverFullscreen) || (hasSpecialWorkspace && hasFullscreenOnNormalWs) ? WlrLayer.Overlay : WlrLayer.Top
color: "transparent"
contentItem.focus: true
mask: visibilities.isDrawing ? null : (hasFullscreen ? emptyRegion : regions)
mask: visibilities.isDrawing ? null : (hasFullscreen && !bar.isHovered ? emptyRegion : regions)
name: "Bar"
Behavior on fsTransitionProg {
Anim {
}
Anim {}
}
Behavior on surfaceColor {
CAnim {
}
CAnim {}
}
contentItem.Keys.onEscapePressed: {
@@ -118,6 +116,12 @@ CustomWindow {
x: root.width - width
y: panels.osdWrapper.y + bar.implicitHeight
}
Region {
height: geometry.horizontal ? 1 : root.screen.height
width: geometry.horizontal ? root.screen.width : 1
y: geometry.position === "bottom" ? root.screen.height - 1 : 0
}
}
Regions {
@@ -219,9 +223,9 @@ CustomWindow {
implicitHeight: panels.dashboard.height * (geometry.horizontal ? 1 + extraExtent : 1)
implicitWidth: panels.dashboard.width * (geometry.horizontal ? 1 : 1 + extraExtent)
panel: panels.dashboardWrapper
radius: Tokens.rounding.normal
radius: Tokens.rounding.extraLarge
x: panels.dashboardWrapper.x + panels.dashboard.x + geometry.insetLeft(root.borderThickness) - (geometry.horizontal ? 0 : panels.dashboard.width * extraExtent)
y: panels.dashboardWrapper.y + panels.dashboard.y + geometry.insetTop(root.borderThickness) - (geometry.horizontal ? panels.dashboard.height * extraExtent : 0)
y: panels.dashboardWrapper.y + panels.dashboard.y + geometry.insetTop(root.borderThickness) - (geometry.horizontal && geometry.position !== "bottom" ? panels.dashboard.height * extraExtent : 0)
}
PanelBg {
@@ -232,7 +236,7 @@ CustomWindow {
deformAmount: 0.06
implicitHeight: panels.launcher.height * (1 + extraHeight)
panel: panels.launcher
radius: Tokens.rounding.smallest + 5
radius: Tokens.rounding.medium + (Tokens.padding.largeIncreased / 4)
y: panels.launcher.y + geometry.insetTop(root.borderThickness)
}
@@ -261,7 +265,7 @@ CustomWindow {
id: notifsBg
panel: panels.notifications
radius: Tokens.rounding.normal
radius: Tokens.rounding.large
}
PanelBg {
@@ -282,13 +286,12 @@ CustomWindow {
implicitHeight: panels.popouts.height * (geometry.horizontal ? 1 + extraExtent : 1)
implicitWidth: panels.popouts.width * (geometry.horizontal ? 1 : 1 + extraExtent)
panel: panels.popoutsWrapper
radius: panels.popouts.current?.panelRadius ?? Tokens.rounding.normal
radius: panels.popouts.current?.panelRadius ?? Tokens.rounding.large
x: panels.popoutsWrapper.x + panels.popouts.x + geometry.insetLeft(root.borderThickness) - (geometry.horizontal ? 0 : panels.popouts.width * extraExtent)
y: panels.popoutsWrapper.y + panels.popouts.y + geometry.insetTop(root.borderThickness) - (geometry.barOnTop ? panels.popouts.height * extraExtent : 0)
Behavior on extraExtent {
Anim {
}
Anim {}
}
}
@@ -299,7 +302,7 @@ CustomWindow {
implicitHeight: panels.resources.height
implicitWidth: panels.resources.width
panel: panels.resourcesWrapper
radius: Tokens.rounding.large
radius: Tokens.rounding.largeIncreased + Tokens.padding.small
x: panels.resourcesWrapper.x + panels.resources.x + geometry.insetLeft(root.borderThickness)
y: panels.resourcesWrapper.y + panels.resources.y + geometry.insetTop(root.borderThickness)
}
@@ -309,7 +312,7 @@ CustomWindow {
deformAmount: 0.03
panel: panels.settings
radius: Tokens.rounding.large + Tokens.padding.normal
radius: Tokens.rounding.largeIncreased + Tokens.padding.small
}
PanelBg {
@@ -317,7 +320,7 @@ CustomWindow {
deformAmount: 0.08
panel: panels.dock
radius: Tokens.rounding.normal
radius: Tokens.rounding.medium
}
PanelBg {
@@ -325,7 +328,7 @@ CustomWindow {
deformAmount: 0.08
panel: panels.drawing
radius: Tokens.rounding.normal
radius: Tokens.rounding.medium
}
PanelBg {
@@ -456,7 +459,7 @@ CustomWindow {
group: blobGroup
implicitHeight: panel.height
implicitWidth: panel.width
radius: Tokens.rounding.smallest
radius: Tokens.rounding.small
x: panel.x + geometry.insetLeft(root.borderThickness)
y: panel.y + geometry.insetTop(root.borderThickness)
}
-33
View File
@@ -1,33 +0,0 @@
import QtQuick
import QtQuick.Effects
Item {
id: root
property real radius
Rectangle {
id: shadowRect
anchors.fill: root
color: "black"
layer.enabled: true
radius: root.radius
visible: false
}
MultiEffect {
id: effects
anchors.fill: shadowRect
autoPaddingEnabled: true
maskEnabled: true
maskInverted: true
maskSource: shadowRect
shadowBlur: 2.0
shadowColor: "black"
shadowEnabled: true
shadowOpacity: 1
source: shadowRect
}
}
+8 -8
View File
@@ -18,7 +18,7 @@ ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: false
Layout.preferredWidth: centerWidth
spacing: Tokens.spacing.large * 2
spacing: Tokens.spacing.largeIncreased * 2
RowLayout {
Layout.alignment: Qt.AlignHCenter
@@ -64,7 +64,7 @@ ColumnLayout {
CustomClippingRect {
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: Tokens.spacing.large * 2
Layout.topMargin: Tokens.spacing.largeIncreased * 2
color: Colors.tPalette.m3surfaceContainer
implicitHeight: root.centerWidth / 2
implicitWidth: root.centerWidth / 2
@@ -99,7 +99,7 @@ ColumnLayout {
Layout.alignment: Qt.AlignHCenter
color: Colors.tPalette.m3surfaceContainer
focus: true
implicitHeight: input.implicitHeight + Tokens.padding.small * 2
implicitHeight: input.implicitHeight + Tokens.padding.extraSmall * 2
implicitWidth: root.centerWidth * 0.8
radius: Tokens.rounding.full
@@ -130,11 +130,11 @@ ColumnLayout {
id: input
anchors.fill: parent
anchors.margins: Tokens.padding.small
spacing: Tokens.spacing.normal
anchors.margins: Tokens.padding.extraSmall
spacing: Tokens.spacing.medium
Item {
implicitHeight: statusIcon.implicitHeight + Tokens.padding.small * 2
implicitHeight: statusIcon.implicitHeight + Tokens.padding.extraSmall * 2
implicitWidth: implicitHeight
MaterialIcon {
@@ -174,7 +174,7 @@ ColumnLayout {
CustomRect {
color: root.greeter.buffer && !root.greeter.launching ? Colors.palette.m3primary : Colors.layer(Colors.palette.m3surfaceContainerHigh, 2)
implicitHeight: enterIcon.implicitHeight + Tokens.padding.small * 2
implicitHeight: enterIcon.implicitHeight + Tokens.padding.extraSmall * 2
implicitWidth: implicitHeight
radius: Tokens.rounding.full
@@ -200,7 +200,7 @@ ColumnLayout {
Item {
Layout.fillWidth: true
Layout.topMargin: -Tokens.spacing.large
Layout.topMargin: -Tokens.spacing.largeIncreased
implicitHeight: Math.max(message.implicitHeight, stateMessage.implicitHeight)
Behavior on implicitHeight {
+11 -11
View File
@@ -30,11 +30,11 @@ NumberAnimation {
if (type === Anim.DefaultSpatial)
return Tokens.anim.durations.expressiveDefaultSpatial;
if (type === Anim.SlowSpatial)
return Tokens.anim.durations.large;
return Tokens.anim.durations.expressiveSlowSpatial;
if (type === Anim.FastEffects)
return Tokens.anim.durations.expressiveFastEffects;
if (type === Anim.DefaultEffects)
return Tokens.anim.durations.expressiveEffects;
return Tokens.anim.durations.expressiveDefaultEffects;
if (type === Anim.SlowEffects)
return Tokens.anim.durations.expressiveSlowEffects;
@@ -42,22 +42,22 @@ NumberAnimation {
const idx = type % 4; // 0-7 are the 4 standard types
return Tokens.anim.durations[types[idx]];
}
easing.bezierCurve: {
easing: {
if (type === Anim.FastSpatial)
return Tokens.anim.curves.expressiveFastSpatial;
return Tokens.anim.expressiveFastSpatial;
if (type === Anim.DefaultSpatial)
return Tokens.anim.curves.expressiveDefaultSpatial;
return Tokens.anim.expressiveDefaultSpatial;
if (type === Anim.SlowSpatial)
return Tokens.anim.curves.expressiveSlowSpatial;
return Tokens.anim.expressiveSlowSpatial;
if (type === Anim.FastEffects)
return Tokens.anim.curves.expressiveFastEffects;
return Tokens.anim.expressiveFastEffects;
if (type === Anim.DefaultEffects)
return Tokens.anim.curves.expressiveDefaultEffects;
return Tokens.anim.expressiveDefaultEffects;
if (type === Anim.SlowEffects)
return Tokens.anim.curves.expressiveSlowEffects;
return Tokens.anim.expressiveSlowEffects;
if (type >= Anim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge)
return Tokens.anim.curves.emphasized;
return Tokens.anim.curves.standard;
return Tokens.anim.emphasized;
return Tokens.anim.standard;
}
}
+2 -58
View File
@@ -2,62 +2,6 @@ import QtQuick
import ZShell.Config
ColorAnimation {
enum Type {
StandardSmall = 0,
Standard,
StandardLarge,
StandardExtraLarge,
EmphasizedSmall,
Emphasized,
EmphasizedLarge,
EmphasizedExtraLarge,
FastSpatial,
DefaultSpatial,
SlowSpatial,
FastEffects,
DefaultEffects,
SlowEffects
}
property int type: CAnim.DefaultSpatial
duration: {
if (type < CAnim.StandardSmall || type > Anim.SlowEffects)
return Tokens.anim.durations.normal;
if (type === CAnim.FastSpatial)
return Tokens.anim.durations.expressiveFastSpatial;
if (type === CAnim.DefaultSpatial)
return Tokens.anim.durations.expressiveDefaultSpatial;
if (type === CAnim.SlowSpatial)
return Tokens.anim.durations.large;
if (type === CAnim.FastEffects)
return Tokens.anim.durations.expressiveFastEffects;
if (type === CAnim.DefaultEffects)
return Tokens.anim.durations.expressiveEffects;
if (type === CAnim.SlowEffects)
return Tokens.anim.durations.expressiveSlowEffects;
const types = ["small", "normal", "large", "extraLarge"];
const idx = type % 4;
return Tokens.anim.durations[types[idx]];
}
easing.bezierCurve: {
if (type === CAnim.FastSpatial)
return Tokens.anim.curves.expressiveFastSpatial;
if (type === CAnim.DefaultSpatial)
return Tokens.anim.curves.expressiveDefaultSpatial;
if (type === CAnim.SlowSpatial)
return Tokens.anim.curves.expressiveSlowSpatial;
if (type === CAnim.FastEffects)
return Tokens.anim.curves.expressiveFastEffects;
if (type === CAnim.DefaultEffects)
return Tokens.anim.curves.expressiveDefaultEffects;
if (type === CAnim.SlowEffects)
return Tokens.anim.curves.expressiveSlowEffects;
if (type >= CAnim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge)
return Tokens.anim.curves.emphasized;
return Tokens.anim.curves.standard;
}
duration: Tokens.anim.durations.expressiveSlowEffects
easing: Tokens.anim.expressiveSlowEffects
}
+1 -1
View File
@@ -23,7 +23,7 @@ BusyIndicator {
property real implicitSize: Tokens.font.size.normal * 3
property real internalStrokeWidth: strokeWidth
readonly property alias progress: manager.progress
property real strokeWidth: Tokens.padding.small * 0.8
property real strokeWidth: Tokens.padding.extraSmall * 0.8
property alias type: manager.indeterminateAnimationType
implicitHeight: implicitSize
+1 -1
View File
@@ -21,7 +21,7 @@ Item {
readonly property real size: Math.min(width, height)
property int spacing: Tokens.spacing.small
property int startAngle: -90
property int strokeWidth: Tokens.padding.small
property int strokeWidth: Tokens.padding.extraSmall
property int sweepAngle: 360
readonly property real thickness: strokeWidth * (1 + waveAmplitude) * 2
property real value
+1 -1
View File
@@ -27,7 +27,7 @@ TextField {
color: Colors.palette.m3primary
implicitWidth: 2
radius: Tokens.rounding.normal
radius: Tokens.rounding.medium
Behavior on opacity {
Anim {
+1 -2
View File
@@ -1,5 +1,4 @@
import QtQuick
import QtQuick.Controls
import ZShell.Config
import qs.Services
@@ -11,6 +10,6 @@ TextInput {
font {
family: Config.appearance?.font.family.sans ?? "sans-serif"
hintingPreference: Font.PreferFullHinting
pixelSize: Config.appearance?.font.size.normal ?? 15
pixelSize: Tokens?.font.size.normal ?? 15
}
}
+1 -1
View File
@@ -81,7 +81,7 @@ MouseArea {
alwaysRunToEnd: true
duration: Tokens.anim.durations.expressiveSlowEffects * 2
easing.bezierCurve: Tokens.anim.curves.standard
easing: Tokens.anim.standard
property: "circleRadius"
target: root
to: root.endRadius
+7 -7
View File
@@ -11,18 +11,18 @@ RowLayout {
required property var greeter
required property real screenHeight
spacing: Tokens.spacing.large * 2
spacing: Tokens.spacing.largeIncreased * 2
ColumnLayout {
Layout.fillWidth: true
spacing: Tokens.spacing.normal
spacing: Tokens.spacing.medium
CustomRect {
Layout.fillWidth: true
color: Colors.tPalette.m3surfaceContainer
implicitHeight: weather.implicitHeight
radius: Tokens.rounding.small
topLeftRadius: Tokens.rounding.large
topLeftRadius: Tokens.rounding.largeIncreased
WeatherInfo {
id: weather
@@ -34,7 +34,7 @@ RowLayout {
CustomClippingRect {
Layout.fillHeight: true
Layout.fillWidth: true
bottomLeftRadius: Tokens.rounding.large
bottomLeftRadius: Tokens.rounding.largeIncreased
color: Colors.tPalette.m3surfaceContainer
radius: Tokens.rounding.small
@@ -51,15 +51,15 @@ RowLayout {
ColumnLayout {
Layout.fillWidth: true
spacing: Tokens.spacing.normal
spacing: Tokens.spacing.medium
CustomRect {
Layout.fillHeight: true
Layout.fillWidth: true
bottomRightRadius: Tokens.rounding.large
bottomRightRadius: Tokens.rounding.largeIncreased
color: Colors.tPalette.m3surfaceContainer
radius: Tokens.rounding.small
topRightRadius: Tokens.rounding.large
topRightRadius: Tokens.rounding.largeIncreased
SessionDock {
greeter: root.greeter
+5 -5
View File
@@ -43,7 +43,7 @@ Scope {
ParallelAnimation {
Anim {
duration: Tokens.anim.durations.expressiveFastSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial
easing: Tokens.anim.expressiveFastSpatial
property: "scale"
target: lockContent
to: 1
@@ -65,7 +65,7 @@ Scope {
Anim {
duration: Tokens.anim.durations.expressiveDefaultSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
easing: Tokens.anim.expressiveDefaultSpatial
property: "scale"
target: content
to: 1
@@ -74,12 +74,12 @@ Scope {
Anim {
property: "radius"
target: lockBg
to: Tokens.rounding.large * 1.5
to: Tokens.rounding.largeIncreased * 1.5
}
Anim {
duration: Tokens.anim.durations.expressiveDefaultSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
easing: Tokens.anim.expressiveDefaultSpatial
property: "implicitWidth"
target: lockContent
to: (win.screen?.height ?? 0) * Config.lock.sizes.heightMult * Config.lock.sizes.ratio
@@ -87,7 +87,7 @@ Scope {
Anim {
duration: Tokens.anim.durations.expressiveDefaultSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
easing: Tokens.anim.expressiveDefaultSpatial
property: "implicitHeight"
target: lockContent
to: (win.screen?.height ?? 0) * Config.lock.sizes.heightMult
+1 -1
View File
@@ -113,7 +113,7 @@ Item {
Behavior on scale {
Anim {
duration: Tokens.anim.durations.expressiveFastSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial
easing: Tokens.anim.expressiveFastSpatial
}
}
+5 -10
View File
@@ -13,21 +13,17 @@ import qs.Paths
Singleton {
id: root
readonly property M3Palette current: M3Palette {
}
readonly property M3Palette current: M3Palette {}
property bool currentLight
property string flavour
readonly property bool light: showPreview ? previewLight : currentLight
readonly property M3Palette palette: showPreview ? preview : current
readonly property M3Palette preview: M3Palette {
}
readonly property M3Palette preview: M3Palette {}
property bool previewLight
property string scheme
property bool showPreview
readonly property M3TPalette tPalette: M3TPalette {
}
readonly property Transparency transparency: Transparency {
}
readonly property M3TPalette tPalette: M3TPalette {}
readonly property Transparency transparency: Transparency {}
readonly property alias wallLuminance: analyser.luminance
function alterColor(c: color, a: real, layer: int): color {
@@ -112,8 +108,7 @@ Singleton {
function setMode(mode: string): void {
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--mode", mode]);
Config.general.color.mode = mode;
Config.save();
Config.colors.mode = mode;
}
function swapRG(c: color): color {
+8 -8
View File
@@ -13,7 +13,7 @@ ColumnLayout {
anchors.fill: parent
anchors.margins: Tokens.padding.large
spacing: Tokens.spacing.smaller
spacing: Tokens.spacing.small
CustomText {
Layout.fillWidth: true
@@ -41,7 +41,7 @@ ColumnLayout {
}
}
sourceComponent: ColumnLayout {
spacing: Tokens.spacing.large
spacing: Tokens.spacing.largeIncreased
MaterialIcon {
Layout.alignment: Qt.AlignHCenter
@@ -79,8 +79,8 @@ ColumnLayout {
anchors.left: parent?.left
anchors.right: parent?.right
implicitHeight: row.implicitHeight + Tokens.padding.normal * 2
radius: Tokens.rounding.normal - Tokens.padding.smaller
implicitHeight: row.implicitHeight + Tokens.padding.small * 2
radius: Tokens.rounding.medium - Tokens.padding.small
StateLayer {
onClicked: {
@@ -92,8 +92,8 @@ ColumnLayout {
id: row
anchors.fill: parent
anchors.margins: Tokens.padding.normal
spacing: Tokens.spacing.normal
anchors.margins: Tokens.padding.small
spacing: Tokens.spacing.medium
MaterialIcon {
color: session.index === sessions.currentIndex ? Colors.palette.m3onPrimary : Colors.palette.m3onSurfaceVariant
@@ -129,13 +129,13 @@ ColumnLayout {
color: Colors.palette.m3primary
implicitHeight: sessions.currentItem?.implicitHeight ?? 0
implicitWidth: sessions.width
radius: Tokens.rounding.normal - Tokens.padding.smaller
radius: Tokens.rounding.medium - Tokens.padding.small
y: sessions.currentItem?.y ?? 0
Behavior on y {
Anim {
duration: Tokens.anim.durations.small
easing.bezierCurve: Tokens.anim.curves.expressiveEffects
easing: Tokens.anim.expressiveDefaultEffects
}
}
}
+9 -9
View File
@@ -14,7 +14,7 @@ ColumnLayout {
anchors.fill: parent
anchors.margins: Tokens.padding.large
spacing: Tokens.spacing.smaller
spacing: Tokens.spacing.small
CustomText {
Layout.fillWidth: true
@@ -42,7 +42,7 @@ ColumnLayout {
}
}
sourceComponent: ColumnLayout {
spacing: Tokens.spacing.large
spacing: Tokens.spacing.largeIncreased
MaterialIcon {
Layout.alignment: Qt.AlignHCenter
@@ -81,8 +81,8 @@ ColumnLayout {
anchors.left: parent?.left
anchors.right: parent?.right
implicitHeight: row.implicitHeight + Tokens.padding.normal * 2
radius: Tokens.rounding.normal - Tokens.padding.smaller
implicitHeight: row.implicitHeight + Tokens.padding.small * 2
radius: Tokens.rounding.medium - Tokens.padding.small
StateLayer {
onClicked: {
@@ -94,8 +94,8 @@ ColumnLayout {
id: row
anchors.fill: parent
anchors.margins: Tokens.padding.normal
spacing: Tokens.spacing.normal
anchors.margins: Tokens.padding.small
spacing: Tokens.spacing.medium
CustomClippingRect {
Layout.preferredHeight: 50
@@ -135,13 +135,13 @@ ColumnLayout {
color: Colors.palette.m3primary
implicitHeight: users.currentItem?.implicitHeight ?? 0
implicitWidth: users.width
radius: Tokens.rounding.normal - Tokens.padding.smaller
radius: Tokens.rounding.medium - Tokens.padding.small
y: users.currentItem?.y ?? 0
Behavior on y {
Anim {
duration: Tokens.anim.durations.small
easing.bezierCurve: Tokens.anim.curves.expressiveEffects
duration: Tokens.anim.durations.expressiveDefaultEffects
easing: Tokens.anim.expressiveDefaultEffects
}
}
}
+4 -4
View File
@@ -34,7 +34,7 @@ ColumnLayout {
RowLayout {
Layout.fillWidth: true
spacing: Tokens.spacing.large
spacing: Tokens.spacing.largeIncreased
MaterialIcon {
animate: true
@@ -67,7 +67,7 @@ ColumnLayout {
}
Loader {
Layout.rightMargin: Tokens.padding.smaller
Layout.rightMargin: Tokens.padding.small
active: root.width > 400
visible: active
@@ -103,12 +103,12 @@ ColumnLayout {
Layout.bottomMargin: Tokens.padding.large * 2
Layout.fillWidth: true
Layout.topMargin: Tokens.spacing.smaller
Layout.topMargin: Tokens.spacing.small
active: root.rootHeight > 820
visible: active
sourceComponent: RowLayout {
spacing: Tokens.spacing.large
spacing: Tokens.spacing.largeIncreased
Repeater {
model: {
+40 -12
View File
@@ -1,35 +1,63 @@
pragma Singleton
import Quickshell
import Quickshell.Io
import Quickshell.Services.UPower
import ZShell.Config
import qs.Services
import qs.Paths
Singleton {
id: root
readonly property var colors: {
if (deviceState === UPowerDeviceState.Charging || deviceState === UPowerDeviceState.FullyCharged)
readonly property list<var> allPeripherals: [...logiDevices, ...upowerDevices.filter(d => !Battery.logiDevices.some(l => l.nativePath === d.nativePath))]
readonly property real currentPerc: UPower.displayDevice.percentage
readonly property var deviceState: UPower.displayDevice.state
readonly property string deviceStateString: UPowerDeviceState.toString(deviceState)
readonly property bool isLaptop: UPower.displayDevice.isLaptopBattery
readonly property alias logiDevices: adapter.devices
readonly property var lowestPeripheral: allPeripherals.reduce((lowest, current) => current.percentage < lowest.percentage ? current : lowest)
readonly property bool onBattery: UPower.onBattery
readonly property bool ready: UPower.displayDevice.ready
readonly property real timeToEmpty: UPower.displayDevice.timeToEmpty
readonly property real timeToFull: UPower.displayDevice.timeToFull
readonly property list<UPowerDevice> upowerDevices: UPower.devices.values.filter(d => d.state !== UPowerDeviceState.Unknown)
function getColors(percentage: real, state: string): var {
if (state === "charging" || state === "full" || state === "recharging")
return {
fg: Colors.swapRG(Colors.palette.m3error),
bg: Colors.swapRG(Colors.palette.m3onError)
};
else if (currentPerc <= 0.2)
else if (percentage <= 0.2)
return {
fg: Colors.palette.m3error,
bg: Colors.palette.m3onError
};
else
return {
fg: Colors.palette.m3onSurface,
bg: Colors.palette.m3surface
fg: Colors.palette.m3tertiary,
bg: Colors.palette.m3onTertiary
};
}
readonly property real currentPerc: UPower.displayDevice.percentage
readonly property var deviceState: UPower.displayDevice.state
readonly property bool isLaptop: UPower.displayDevice.isLaptopBattery
readonly property bool onBattery: UPower.onBattery
readonly property bool ready: UPower.displayDevice.ready
readonly property real timeToEmpty: UPower.displayDevice.timeToEmpty
readonly property real timeToFull: UPower.displayDevice.timeToFull
function startDaemon(): void {
Quickshell.execDetached(["zshell-cli", "battery", "daemon"]);
}
FileView {
id: fileView
path: `${Paths.cache}/battery.json`
watchChanges: true
onFileChanged: reload()
JsonAdapter {
id: adapter
property list<var> devices: []
property real updated: 0.0
}
}
}
-70
View File
@@ -1,70 +0,0 @@
pragma Singleton
import QtQuick
import Quickshell
import Quickshell.Wayland
import qs.Components
import ZShell.Config
Singleton {
id: root
property list<var> apps: {
var map = new Map();
const pinnedApps = Config.dock?.pinnedApps ?? [];
for (const appId of pinnedApps) {
if (!map.has(appId.toLowerCase()))
map.set(appId.toLowerCase(), ({
pinned: true,
toplevels: []
}));
}
if (pinnedApps.length > 0) {
map.set("SEPARATOR", {
pinned: false,
toplevels: []
});
}
var values = [];
for (const [key, value] of map) {
values.push(appEntryComp.createObject(null, {
appId: key,
toplevels: value.toplevels,
pinned: value.pinned
}));
}
return values;
}
function isPinned(appId) {
return Config.dock.pinnedApps.indexOf(appId) !== -1;
}
function togglePin(appId) {
if (root.isPinned(appId)) {
Config.dock.pinnedApps = Config.dock.pinnedApps.filter(id => id !== appId);
} else {
Config.dock.pinnedApps = Config.dock.pinnedApps.concat([appId]);
}
}
Component {
id: appEntryComp
TaskbarAppEntry {
}
}
component TaskbarAppEntry: QtObject {
id: wrapper
required property string appId
required property bool pinned
required property list<var> toplevels
}
}
-63
View File
@@ -1,63 +0,0 @@
// FetchPresets.qml
pragma Singleton
import QtQuick
import Quickshell
import Quickshell.Io
Singleton {
id: root
property var parsedPresets: ({})
readonly property var presets: parsedPresets
property bool ready: false
function accents(presetName, variantName) {
const variant = parsedPresets[presetName]?.variants?.[variantName];
return variant?.accents ?? [];
}
function defaultAccent(presetName, variantName) {
const variant = parsedPresets[presetName]?.variants?.[variantName];
return variant?.default_accent ?? "";
}
function modes(presetName, variantName) {
const variant = parsedPresets[presetName]?.variants?.[variantName];
return variant?.modes ?? [];
}
function presetNames() {
return Object.keys(parsedPresets);
}
function variantNames(presetName) {
const preset = parsedPresets[presetName];
if (!preset || !preset.variants)
return [];
return Object.keys(preset.variants);
}
Process {
command: ["zshell-cli", "scheme", "list-presets", "--json"]
running: true
stdout: StdioCollector {
onStreamFinished: {
try {
const parsed = JSON.parse(text);
root.parsedPresets = parsed.presets ?? {};
root.ready = true;
} catch (e) {
console.error("Failed to parse presets JSON:", e);
}
}
}
}
}
+8 -6
View File
@@ -9,13 +9,13 @@ Singleton {
id: root
readonly property bool enabled: service.enabled
readonly property int end: Config.general.color.scheduleHyprsunsetEnd
readonly property int end: Config.display.nightlight.scheduleEnd
property bool manualToggle: false
readonly property int start: Config.general.color.scheduleHyprsunsetStart
readonly property int temp: Config.general.color.hyprsunsetTemp
readonly property int start: Config.display.nightlight.scheduleStart
readonly property int temp: Config.display.nightlight.temp
function checkStartup(): void {
if (!Config.general.color.scheduleHyprsunset)
if (!Config.display.nightlight.schedule)
return;
service.apply();
@@ -26,12 +26,14 @@ Singleton {
service.toggle();
}
HyprsunsetManager {
NightlightManager {
id: service
activeAuto: Config.general.color.scheduleHyprsunset
activeAuto: Config.display.nightlight.schedule
endTime: root.end
startTime: root.start
temp: root.temp
fadeDuration: Config.display.nightlight.fadeDuration / 1000
useNativeNightlight: Config.display.nightlight.useNative
}
}
+51 -2
View File
@@ -1,9 +1,8 @@
pragma Singleton
import ZShell.Config
import QtQuick
import Quickshell
import Quickshell.Services.Notifications
import QtQuick
Singleton {
id: root
@@ -95,6 +94,15 @@ Singleton {
return Quickshell.iconPath(icon);
}
function getBatteryIcon(percentage: real, charging = false): string {
if (percentage === 1)
return charging ? "battery_charging_full" : "battery_full";
let level = Math.floor(percentage * 7);
if (charging && (level === 4 || level === 1))
level--;
return charging ? `battery_charging_${(level + 3) * 10}` : `battery_${level}_bar`;
}
function getBluetoothIcon(icon: string): string {
if (icon.includes("headset") || icon.includes("headphones"))
return "headphones";
@@ -168,6 +176,32 @@ Singleton {
return "chat";
}
function getSpecialWsIcon(name: string): string {
name = name.toLowerCase().slice("special:".length);
if (name === "special")
return "star";
if (name === "communication")
return "forum";
if (name === "music")
return "music_cast";
if (name === "todo")
return "checklist";
if (name === "sysmon")
return "monitor_heart";
return name[0].toUpperCase();
}
function getTrayIcon(id: string, icon: string): string {
if (icon.includes("?path=")) {
const [name, path] = icon.split("?path=");
const file = name.slice(name.lastIndexOf("/") + 1);
const themed = Quickshell.iconPath(file, true);
icon = themed ? themed : Qt.resolvedUrl(`${path}/${file}`);
}
return icon;
}
function getVolumeIcon(volume: real, isMuted: bool): string {
if (isMuted)
return "no_sound";
@@ -183,4 +217,19 @@ Singleton {
return weatherIcons[code];
return "air";
}
function matchIconConfig(name: string, iconConfig: var): bool {
if (!iconConfig.icon)
return false;
if (iconConfig.regex) {
const re = new RegExp(iconConfig.regex, iconConfig.flags ?? "");
if (re.test(name))
return true;
} else if (iconConfig.name === name) {
return true;
}
return false;
}
}
+6 -6
View File
@@ -11,14 +11,14 @@ import qs.Services
Singleton {
id: root
readonly property int darkEnd: Config.general.color.scheduleDarkEnd
readonly property int darkStart: Config.general.color.scheduleDarkStart
readonly property bool enabled: Config.general.color.scheduleDark && Config.general.color.schemeGeneration
readonly property int darkEnd: Config.colors.scheduleDarkEnd
readonly property int darkStart: Config.colors.scheduleDarkStart
readonly property bool enabled: Config.colors.scheduleDark && Config.colors.schemeGen
function applyDarkMode() {
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--mode", "dark"]);
Config.general.color.mode = "dark";
Config.colors.mode = "dark";
Quickshell.execDetached(["gsettings", "set", "org.gnome.desktop.interface", "color-scheme", "'prefer-dark'"]);
@@ -30,13 +30,13 @@ Singleton {
function applyLightMode() {
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--mode", "light"]);
Config.general.color.mode = "light";
Config.colors.mode = "light";
Quickshell.execDetached(["gsettings", "set", "org.gnome.desktop.interface", "color-scheme", "'prefer-light'"]);
Quickshell.execDetached(["sh", "-c", `sed -i 's/color_scheme_path=\\(.*\\)Dark.colors/color_scheme_path=\\1Light.colors/' ${Paths.home}/.config/qt6ct/qt6ct.conf`]);
if (Config.general.color.neovimColors)
if (Config.colors.neovimColors)
Quickshell.execDetached(["sed", "-i", "'s/\\(vim.cmd.colorscheme \\).*/\\1\"onelight\"/'", "~/.config/nvim/lua/config/load-colorscheme.lua"]);
}
+11 -17
View File
@@ -126,33 +126,29 @@ Item {
focus: true
opacity: 0
Behavior on opacity {
Anim {
duration: 300
}
}
Behavior on rsx {
enabled: !selectArea.pressed && root.mode === "select"
ExAnim {
}
ExAnim {}
}
Behavior on rsy {
enabled: !selectArea.pressed && root.mode === "select"
ExAnim {
}
ExAnim {}
}
Behavior on sh {
enabled: !selectArea.pressed && root.mode === "select"
ExAnim {
}
ExAnim {}
}
Behavior on sw {
enabled: !selectArea.pressed && root.mode === "select"
ExAnim {
ExAnim {}
}
Behavior on opacity {
Anim {
duration: 300
}
}
@@ -352,8 +348,7 @@ Item {
y: selectionRect.y - root.realBorderWidth
Behavior on border.color {
Anim {
}
Anim {}
}
}
@@ -391,7 +386,7 @@ Item {
tool: root.tool
visible: root.mode === "edit"
x: Math.max(8, Math.min(root.rsx + root.sw / 2 - width / 2, root.screen.width - width - 8))
y: (root.rsy + root.sh + height + Tokens.padding.normal <= root.screen.height) ? root.rsy + root.sh + Tokens.padding.normal : (root.rsy - height - Tokens.padding.normal <= 0) ? root.rsy + root.sh - height - Tokens.padding.normal : root.rsy - height - Tokens.padding.normal
y: (root.rsy + root.sh + height + Tokens.padding.small <= root.screen.height) ? root.rsy + root.sh + Tokens.padding.small : (root.rsy - height - Tokens.padding.small <= 0) ? root.rsy + root.sh - height - Tokens.padding.small : root.rsy - height - Tokens.padding.small
onCancelRequested: root.cancel()
onClearRequested: annotations.clearAll()
@@ -402,6 +397,5 @@ Item {
onUndoRequested: annotations.undo()
}
component ExAnim: Anim {
}
component ExAnim: Anim {}
}
+10 -4
View File
@@ -49,9 +49,9 @@ CustomRect {
signal undoRequested
color: Colors.palette.m3surface
height: row.implicitHeight + Tokens.padding.normal * 2
height: row.implicitHeight + Tokens.padding.small * 2
radius: Tokens.rounding.full
width: row.implicitWidth + Tokens.padding.normal * 2
width: row.implicitWidth + Tokens.padding.small * 2
RowLayout {
id: row
@@ -73,6 +73,7 @@ CustomRect {
required property var modelData
color: root.tool === modelData.id ? "#3584e4" : "transparent"
font.pointSize: Tokens.font.size.large
icon: tool.modelData.glyph
inactiveColor: root.tool === modelData.id ? Colors.palette.m3primary : "transparent"
inactiveOnColor: root.tool === modelData.id ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
@@ -98,11 +99,11 @@ CustomRect {
model: root.colorPalette
delegate: IconButton {
readonly property real buttonSize: toolRow.implicitHeight - Tokens.padding.normal
readonly property real buttonSize: toolRow.implicitHeight - Tokens.padding.small
required property color modelData
fillWidth: false
font.pointSize: 0
font.pointSize: Tokens.font.size.large
icon: ""
implicitHeight: buttonSize
implicitWidth: buttonSize
@@ -127,6 +128,7 @@ CustomRect {
spacing: Tokens.spacing.extraSmall
IconButton {
font.pointSize: Tokens.font.size.large
icon: "undo"
inactiveColor: "transparent"
inactiveOnColor: Colors.palette.m3onSurface
@@ -138,6 +140,7 @@ CustomRect {
}
IconButton {
font.pointSize: Tokens.font.size.large
icon: "delete_history"
inactiveColor: "transparent"
inactiveOnColor: Colors.palette.m3onSurface
@@ -149,6 +152,7 @@ CustomRect {
}
IconButton {
font.pointSize: Tokens.font.size.large
icon: "content_copy"
inactiveColor: "transparent"
inactiveOnColor: Colors.palette.m3onSurface
@@ -160,6 +164,7 @@ CustomRect {
}
IconButton {
font.pointSize: Tokens.font.size.large
icon: "delete_forever"
inactiveColor: "transparent"
inactiveOnColor: Colors.palette.m3onSurface
@@ -171,6 +176,7 @@ CustomRect {
}
IconButton {
font.pointSize: Tokens.font.size.large
icon: "check"
inactiveColor: "transparent"
inactiveOnColor: Colors.palette.m3onSurface
-1
View File
@@ -73,7 +73,6 @@ Singleton {
Config.dock.pinnedApps = pinnedApps;
root.unpinnedOrder = visibleUnpinned.concat(root.unpinnedOrder.map(normalizeId).filter(id => !pinnedApps.includes(id) && !visibleUnpinned.includes(id)));
Config.saveNoToast();
}
function isPinned(appId) {
+8 -41
View File
@@ -11,8 +11,8 @@ Singleton {
id: root
property int availableUpdates: 0
property string cmd: ""
property bool commandReady
property bool hasHelper
property bool loaded
property double now: Date.now()
property var updates: ({})
@@ -38,18 +38,12 @@ Singleton {
}
function performPackageUpdate(pkg: string): void {
if (root.cmd === "pacman")
pkgUpdateProc.command = ["pkexec", root.cmd, "--noconfirm", "-Sy", pkg];
else
pkgUpdateProc.command = [root.cmd, "--noconfirm", "--sudo", "pkexec", "-Sy", pkg];
pkgUpdateProc.command = ["pkexec", "pacman", "--noconfirm", "-Sy", pkg];
pkgUpdateProc.running = true;
}
function performSystemUpdate(): void {
if (root.cmd === "pacman")
sysUpdateProc.command = ["pkexec", root.cmd, "--noconfirm", "-Syu"];
else
sysUpdateProc.command = [root.cmd, "--noconfirm", "--sudo", "pkexec", "-Syu"];
sysUpdateProc.command = ["pkexec", "pacman", "--noconfirm", "-Syu"];
sysUpdateProc.running = true;
}
@@ -87,7 +81,7 @@ Singleton {
Process {
id: cmdDetect
command: ["sh", "-c", "command -v checkupdates || command -v yay || command -v paru"]
command: ["sh", "-c", "command -v checkupdates"]
running: true
stdout: StdioCollector {
@@ -96,47 +90,20 @@ Singleton {
let helper;
if (cmd.length > 0) {
helper = cmd.split("/").pop();
helper = true;
} else {
helper = "pacman";
}
if (helper === "checkupdates") {
updatesProc.command = [helper];
} else {
updatesProc.command = [helper, "-Qu"];
helper = false;
}
root.hasHelper = helper;
root.commandReady = true;
}
}
}
Process {
id: updateCmdDetect
command: ["sh", "-c", "command -v yay || command -v paru"]
running: true
stdout: StdioCollector {
onStreamFinished: {
const cmd = this.text.trim();
let helper;
if (cmd.length > 0) {
helper = cmd.split("/").pop();
} else {
helper = "pacman";
}
root.cmd = helper;
}
}
}
Process {
id: updatesProc
command: []
command: root.hasHelper ? ["checkupdates"] : []
running: false
stdout: StdioCollector {
+4 -1
View File
@@ -17,7 +17,10 @@ Singleton {
watchChanges: true
onAdapterUpdated: writeAdapter()
onFileChanged: reload()
onFileChanged: {
reload();
Wallpapers.previewColorLock = false;
}
JsonAdapter {
id: adapter
+30 -8
View File
@@ -6,7 +6,7 @@ import Quickshell.Io
import QtQuick
import ZShell.Models
import ZShell.Config
import qs.Modules
import qs.Services
import qs.Helpers
import qs.Paths
@@ -17,6 +17,8 @@ Searcher {
property alias crops: adapter.monitorCrops
readonly property string current: showPreview ? previewPath : actualCurrent
property alias monitorCrops: monitorCrops
property bool pendingPreviewClear
property bool previewColorLock
property string previewPath
property bool recentlyChanged
property bool showPreview: false
@@ -34,9 +36,10 @@ Searcher {
function preview(path: string): void {
previewPath = path;
if (Config.general.color.schemeGeneration)
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--image-path", `${previewPath}`, "--scheme", `${Config.colors.schemeType}`, "--mode", `${Config.general.color.mode}`]);
showPreview = true;
if (Config.colors.schemeGen)
previewColorsProc.running = true;
}
function setCrop(screen: string, rect: rect, zoom: real): void {
@@ -52,7 +55,6 @@ Searcher {
height: rect.height,
zoom: zoom
};
// root.crops = updated;
}
function setWallpaper(path: string): void {
@@ -60,14 +62,16 @@ Searcher {
WallpaperPath.currentWallpaperPath = path;
Quickshell.screens.forEach(n => setCrop(n.name, Qt.rect(0, 0, 1, 1), 1.0));
Quickshell.execDetached(["zshell-cli", "wallpaper", "lockscreen", "--input-image", `${root.actualCurrent}`, "--output-path", `${Paths.state}/lockscreen_bg.png`, "--blur-amount", `${Config.lock.blurAmount}`]);
if (Config.general.color.schemeGeneration)
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--image-path", `${root.actualCurrent}`, "--scheme", `${Config.colors.schemeType}`, "--mode", `${Config.general.color.mode}`]);
if (Config.colors.schemeGen)
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--image-path", `${root.actualCurrent}`, "--scheme", `${Config.colors.schemeType}`, "--mode", `${Config.colors.mode}`]);
}
function stopPreview(): void {
showPreview = false;
if (Config.general.color.schemeGeneration)
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--image-path", `${root.actualCurrent}`, "--scheme", `${Config.colors.schemeType}`, "--mode", `${Config.general.color.mode}`]);
if (previewColorLock)
pendingPreviewClear = true;
else
Colors.showPreview = false;
}
extraOpts: useFuzzy ? ({}) : ({
@@ -77,6 +81,11 @@ Searcher {
list: wallpapers.entries
useFuzzy: true
onPreviewColorLockChanged: {
if (!previewColorLock && pendingPreviewClear)
Colors.showPreview = false;
}
IpcHandler {
function set(path: string): void {
root.setWallpaper(path);
@@ -118,4 +127,17 @@ Searcher {
path: Config.general.wallpaperPath
recursive: true
}
Process {
id: previewColorsProc
command: ["zshell-cli", "scheme", "generate", "-p", "-i", root.previewPath]
stdout: StdioCollector {
onStreamFinished: {
Colors.load(text, true);
Colors.showPreview = true;
}
}
}
}
+13 -13
View File
@@ -3,17 +3,16 @@ pragma ComponentBehavior: Bound
import Quickshell
import QtQuick
import QtQuick.Layouts
import qs.Modules
import ZShell.Config
import qs.Modules.SysTray
import qs.Modules.Network
import qs.Modules.Updates
import qs.Modules.Bar.Components
import qs.Modules.Bar.Popouts
GridLayout {
id: root
required property bool fullscreen
required property bool horizontal
required property bool isHovered
required property Wrapper popouts
required property ClipWrapper popoutsWrapper
required property ShellScreen screen
@@ -94,7 +93,7 @@ GridLayout {
delegate: EntryWrapper {
HyprsunsetWidget {
horizontal: root.horizontal
visible: !root.fullscreen
visible: !root.fullscreen || root.isHovered
}
}
}
@@ -115,7 +114,7 @@ GridLayout {
Workspaces {
horizontal: root.horizontal
screen: root.screen
visible: !root.fullscreen
visible: !root.fullscreen || root.isHovered
}
}
}
@@ -128,7 +127,7 @@ GridLayout {
horizontal: root.horizontal
loader: root
popouts: root.popouts
visible: !root.fullscreen
visible: !root.fullscreen || root.isHovered
}
}
}
@@ -139,6 +138,7 @@ GridLayout {
delegate: EntryWrapper {
StatusIcons {
horizontal: root.horizontal
visible: !root.fullscreen || root.isHovered
}
}
}
@@ -150,7 +150,7 @@ GridLayout {
Resources {
horizontal: root.horizontal
visibilities: root.visibilities
visible: !root.fullscreen
visible: !root.fullscreen || root.isHovered
}
}
}
@@ -161,7 +161,7 @@ GridLayout {
delegate: EntryWrapper {
UpdatesWidget {
horizontal: root.horizontal
visible: !root.fullscreen
visible: !root.fullscreen || root.isHovered
}
}
}
@@ -174,7 +174,7 @@ GridLayout {
horizontal: root.horizontal
popouts: root.popouts
visibilities: root.visibilities
visible: !root.fullscreen
visible: !root.fullscreen || root.isHovered
}
}
}
@@ -188,7 +188,7 @@ GridLayout {
loader: root
popouts: root.popouts
visibilities: root.visibilities
visible: !root.fullscreen
visible: !root.fullscreen || root.isHovered
}
}
}
@@ -200,7 +200,7 @@ GridLayout {
WindowTitle {
bar: root
horizontal: root.horizontal
visible: !root.fullscreen
visible: !root.fullscreen || root.isHovered
}
}
}
@@ -220,7 +220,7 @@ GridLayout {
delegate: EntryWrapper {
MediaWidget {
horizontal: root.horizontal
visible: !root.fullscreen
visible: !root.fullscreen || root.isHovered
}
}
}
+6 -8
View File
@@ -3,29 +3,25 @@ pragma ComponentBehavior: Bound
import Quickshell
import QtQuick
import ZShell.Config
import qs.Modules.Bar.Popouts
import qs.Components
import qs.Modules
import qs.Helpers
import qs.Modules.SysTray
import qs.Modules.SysTray.Widgets
import qs.Modules.Network
Item {
id: root
readonly property int clampedExtent: Math.max(Config.bar.border, extent)
readonly property int contentThickness: Math.max(Config.bar.height, 30) + padding * 2
readonly property int contentThickness: Math.floor(Math.max(Config.bar.height, Tokens.bar.innerSize * (horizontal ? 1 : 1.5))) + padding * 2
readonly property int exclusiveZone: Config.bar.autoHide ? Config.bar.border : contentThickness
property real extent: fullscreen ? 0 : Config.bar.border
required property bool fullscreen
readonly property bool horizontal: position !== "left"
property bool isHovered
readonly property int padding: Math.max(Tokens.padding.smaller, Config.bar.border)
readonly property int padding: Math.max(Tokens.padding.small, Config.bar.border)
required property Wrapper popouts
required property ClipWrapper popoutsWrapper
required property string position
required property ShellScreen screen
readonly property bool shouldBeVisible: !fullscreen && (!Config.bar.autoHide || visibilities.bar || isHovered)
readonly property bool shouldBeVisible: (!fullscreen && (!Config.bar.autoHide || visibilities.bar)) || isHovered
readonly property int vPadding: 6
required property PersistentProperties visibilities
@@ -83,7 +79,9 @@ Item {
sourceComponent: Bar {
fullscreen: root.fullscreen
height: root.contentThickness
horizontal: root.horizontal
isHovered: root.isHovered
popouts: root.popouts
popoutsWrapper: root.popoutsWrapper
screen: root.screen
+153
View File
@@ -0,0 +1,153 @@
pragma ComponentBehavior: Bound
import Quickshell
import QtQuick
import QtQuick.Layouts
import ZShell.Config
import qs.Modules.Bar.Popouts
import qs.Modules.Bar.Components.Common
import qs.Helpers
import qs.Components
import qs.Services
WidgetBase {
id: root
readonly property color contentColor: visibilities.dashboard ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
readonly property string effectiveFormat: {
let fmt = Config.general.dateFormat;
if (!root.horizontal)
fmt = fmt.replace("dddd", "ddd");
return fmt;
}
readonly property var formatParts: {
const segments = root.effectiveFormat.split(" - ");
let datePart = "";
let timePart = "";
if (segments.length > 1) {
datePart = segments[0];
timePart = segments[1];
} else if (/[hms]/.test(segments[0])) {
timePart = segments[0];
} else {
datePart = segments[0];
}
const dateTokens = datePart.trim().length ? datePart.trim().split(/\s+/) : [];
const timeTokens = timePart.trim().length ? timePart.trim().split(":") : [];
return {
dateTokens: dateTokens,
timeTokens: timeTokens
};
}
required property GridLayout loader
required property Wrapper popouts
readonly property real size: horizontal ? timeText.contentWidth + Tokens.padding.medium * 2 : verticalColumn.implicitHeight + Tokens.padding.medium * 2
required property PersistentProperties visibilities
color: visibilities.dashboard ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer
implicitHeight: horizontal ? baseSize : size
implicitWidth: horizontal ? size : baseSize
radius: Tokens.rounding.full
CustomText {
id: timeText
anchors.centerIn: parent
color: root.contentColor
font.family: Config.appearance.font.family.clock // qmllint disable incompatible-type
height: implicitHeight
text: Time.dateStr
visible: root.horizontal
Behavior on color {
CAnim {}
}
}
ColumnLayout {
id: verticalColumn
anchors.centerIn: parent
spacing: Tokens.padding.extraSmall ?? 2
visible: !root.horizontal
width: root.baseSize
Repeater {
model: root.formatParts.dateTokens
CustomText {
required property string modelData
Layout.alignment: Qt.AlignHCenter
color: root.contentColor
font.family: Config.appearance.font.family.clock // qmllint disable incompatible-type
text: Qt.formatDateTime(Time.date, modelData)
Behavior on color {
CAnim {}
}
}
}
Rectangle {
Layout.alignment: Qt.AlignHCenter
Layout.bottomMargin: Tokens.padding.extraSmall ?? 2
Layout.topMargin: Tokens.padding.extraSmall ?? 2
color: root.contentColor
height: 1
implicitWidth: root.baseSize * 0.5
opacity: 0.4
radius: 1
visible: root.formatParts.dateTokens.length > 0 && root.formatParts.timeTokens.length > 0
}
Repeater {
model: root.formatParts.timeTokens
CustomText {
required property string modelData
Layout.alignment: Qt.AlignHCenter
color: root.contentColor
font.family: Config.appearance.font.family.clock // qmllint disable incompatible-type
text: {
if (modelData.includes("h"))
return Time.hourStr;
if (modelData.includes("m"))
return Time.minuteStr;
if (modelData.includes("s"))
return Time.secondStr;
return "";
}
Behavior on color {
CAnim {}
}
}
}
CustomText {
Layout.alignment: Qt.AlignHCenter
color: root.contentColor
font.family: Config.appearance.font.family.clock // qmllint disable incompatible-type
text: Qt.formatDateTime(Time.date, "AP")
visible: Config.services.useTwelveHourClock && root.formatParts.timeTokens.length > 0
Behavior on color {
CAnim {}
}
}
}
StateLayer {
acceptedButtons: Qt.LeftButton
color: root.contentColor
onClicked: {
root.visibilities.dashboard = !root.visibilities.dashboard;
}
}
}
@@ -0,0 +1,85 @@
import QtQuick
import ZShell.Config
import qs.Services
import qs.Components
import qs.Helpers
Row {
id: root
property real batHeight: Tokens.padding.small * 2
property real batWidth: Tokens.padding.medium * 2
required property string devState
property real nubHeight: Tokens.padding.extraSmall
property real nubWidth: 2
required property real percentage
property real radius: Tokens.rounding.small / 2
spacing: 1
CustomRect {
id: track
anchors.verticalCenter: parent.verticalCenter
color: Battery.getColors(root.percentage, root.devState).bg
height: root.batHeight
radius: root.radius
width: root.batWidth
CustomText {
color: Battery.getColors(root.percentage, root.devState).fg
font.pointSize: Tokens.font.size.larger / 1.5
font.weight: 800
height: track.height
horizontalAlignment: Text.AlignHCenter
text: Math.round(root.percentage * 100)
verticalAlignment: Text.AlignVCenter
width: track.width
}
Item {
clip: true
width: parent.width * root.percentage
anchors {
bottom: parent.bottom
left: parent.left
top: parent.top
}
CustomRect {
id: fill
color: Battery.getColors(root.percentage, root.devState).fg
height: track.height
radius: track.radius
width: track.width
CustomText {
id: batteryLabel
clip: true
color: Battery.getColors(root.percentage, root.devState).bg
font.pointSize: Tokens.font.size.larger / 1.5
font.weight: 800
height: track.height
horizontalAlignment: Text.AlignHCenter
text: Math.round(root.percentage * 100)
verticalAlignment: Text.AlignVCenter
width: track.width
}
}
}
}
CustomRect {
id: nub
anchors.verticalCenter: parent.verticalCenter
bottomRightRadius: 20
color: root.percentage < 0.99 ? track.color : fill.color
height: root.nubHeight
topRightRadius: 20
width: root.nubWidth
}
}
@@ -0,0 +1,16 @@
import QtQuick
import ZShell.Config
import qs.Components
import qs.Services
CustomRect {
id: root
readonly property int baseSize: horizontal ? Math.max(Config.bar.height, Tokens.bar.innerSize) : Math.max(Config.bar.height, Math.floor(Tokens.bar.innerSize * 1.5))
required property bool horizontal
color: Colors.tPalette.m3surfaceContainer
implicitHeight: horizontal ? baseSize : width
implicitWidth: horizontal ? height : baseSize
radius: Tokens.rounding.full
}
@@ -1,18 +1,16 @@
import QtQuick
import ZShell.Config
import qs.Components
import qs.Modules.Bar.Components.Common
import qs.Helpers
import qs.Services
CustomRect {
WidgetBase {
id: root
required property bool horizontal
property bool tempEnabled: Hyprsunset.enabled
color: root.tempEnabled ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer
implicitHeight: horizontal ? Config.bar.height : width
implicitWidth: horizontal ? height : Config.bar.height
radius: Tokens.rounding.full
StateLayer {
@@ -27,7 +25,7 @@ CustomRect {
animate: true
color: root.tempEnabled ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
fill: root.tempEnabled ? 1 : 0
font.pointSize: root.horizontal ? Tokens.font.size.larger : Tokens.font.size.large
font.pointSize: Tokens.font.size.larger
text: root.tempEnabled ? "lightbulb" : "light_off"
Behavior on fill {
@@ -1,24 +1,30 @@
import QtQuick
import QtQuick.Layouts
import qs.Components
import qs.Daemons
import ZShell.Config
import qs.Components
import qs.Modules.Bar.Components.Common
import qs.Helpers
import qs.Services
CustomRect {
WidgetBase {
id: root
readonly property string currentMedia: (Players.active?.trackTitle ?? qsTr("No media")) || qsTr("Unknown title")
required property bool horizontal
readonly property int textWidth: Math.min(metrics.width, 200)
color: Colors.tPalette.m3surfaceContainer
implicitHeight: horizontal ? Config.bar.height : layout.implicitHeight + Tokens.padding.normal * 2
implicitWidth: horizontal ? layout.implicitWidth + Tokens.padding.normal * 2 : Config.bar.height
implicitHeight: horizontal ? baseSize : layout.implicitHeight + Tokens.padding.small * 2
implicitWidth: horizontal ? layout.implicitWidth + Tokens.padding.small * 2 : baseSize
radius: Tokens.rounding.full
Behavior on implicitHeight {
enabled: !root.horizontal
Anim {
}
}
Behavior on implicitWidth {
enabled: root.horizontal
Anim {
}
}
@@ -33,7 +39,11 @@ CustomRect {
GridLayout {
id: layout
anchors.centerIn: parent
anchors.bottomMargin: root.horizontal ? 0 : Tokens.padding.small
anchors.fill: parent
anchors.leftMargin: root.horizontal ? Tokens.padding.small : 0
anchors.rightMargin: root.horizontal ? Tokens.padding.small : 0
anchors.topMargin: root.horizontal ? 0 : Tokens.padding.small
columns: root.horizontal ? -1 : 1
Behavior on implicitWidth {
@@ -53,39 +63,29 @@ CustomRect {
id: mediatext
Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter
Layout.preferredHeight: root.horizontal ? root.height : root.textWidth
animate: true
color: Players.active?.isPlaying ? Colors.palette.m3primary : Colors.palette.m3onSurface
font.pointSize: Tokens.font.size.normal
horizontalAlignment: Text.AlignHCenter
implicitHeight: root.horizontal ? root.implicitHeight : root.textWidth
implicitWidth: root.horizontal ? root.textWidth : root.implicitWidth
marqueeEnabled: false
pauseMs: 4000
text: root.currentMedia
width: root.textWidth
vertical: !root.horizontal
}
}
transform: [
Translate {
x: !root.horizontal ? -root.textWidth + mediatext.implicitHeight : 0
},
Rotation {
angle: root.horizontal ? 0 : 270
origin.x: mediatext.implicitHeight / 2
origin.y: mediatext.implicitHeight / 2
}
]
CustomMouseArea {
anchors.fill: parent
hoverEnabled: true
CustomMouseArea {
anchors.fill: parent
hoverEnabled: true
onContainsMouseChanged: {
if (!containsMouse) {
mediatext.marqueeEnabled = false;
} else {
mediatext.marqueeEnabled = true;
mediatext.anim.start();
}
}
onContainsMouseChanged: {
if (!containsMouse) {
mediatext.marqueeEnabled = false;
} else {
mediatext.marqueeEnabled = true;
mediatext.anim.start();
}
}
}
@@ -1,20 +1,19 @@
import Quickshell
import QtQuick
import ZShell.Config
import qs.Modules.Bar.Components.Common
import qs.Modules.Bar.Popouts
import qs.Daemons
import qs.Components
import qs.Services
CustomRect {
WidgetBase {
id: root
required property bool horizontal
required property Wrapper popouts
required property PersistentProperties visibilities
color: visibilities.sidebar ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer
implicitHeight: horizontal ? Config.bar.height : width
implicitWidth: horizontal ? height : Config.bar.height
radius: Tokens.rounding.full
MaterialIcon {
@@ -23,7 +22,7 @@ CustomRect {
anchors.centerIn: parent
color: root.visibilities.sidebar ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
fill: root.visibilities.sidebar ? 1 : 0
font.pointSize: root.horizontal ? Tokens.font.size.larger : Tokens.font.size.large
font.pointSize: Tokens.font.size.larger
text: NotifServer.list.length ? "\uf4fe" : "\ue7f4"
Behavior on color {
@@ -22,7 +22,7 @@ GridLayout {
property bool warning: percentage * 100 >= warningThreshold
property int warningThreshold: 80
columnSpacing: Tokens.spacing.smaller
columnSpacing: Tokens.spacing.medium
columns: horizontal ? -1 : 1
percentage: 0
@@ -49,7 +49,7 @@ GridLayout {
}
CustomClippingRect {
Layout.preferredHeight: root.horizontal ? icon.implicitHeight : 4
Layout.preferredHeight: root.horizontal ? icon.implicitHeight - Tokens.padding.extraSmall : 4
Layout.preferredWidth: root.horizontal ? 4 : icon.implicitWidth
color: Colors.layer(Colors.palette.m3surfaceContainerHigh, 2)
radius: Tokens.rounding.full
@@ -63,7 +63,7 @@ GridLayout {
anchors.top: root.horizontal ? undefined : parent.top
color: root.mainColor
implicitHeight: root.horizontal ? Math.ceil(root.percentage * parent.height) : 0
implicitWidth: root.horizontal ? 0 : Math.ceil(root.percentage * parent.height)
implicitWidth: root.horizontal ? 0 : Math.ceil(root.percentage * parent.width)
// Behavior on implicitHeight {
// Anim {
@@ -6,19 +6,18 @@ import QtQuick.Layouts
import ZShell.Config
import ZShell.Services
import qs.Services
import qs.Modules
import qs.Modules.Bar.Components.Common
import qs.Components
CustomRect {
WidgetBase {
id: root
required property bool horizontal
required property PersistentProperties visibilities
clip: true
color: visibilities.resources ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer
implicitHeight: horizontal ? Math.max(Config.bar.height, 24) : gridLayout.implicitHeight + Tokens.padding.normal * 2
implicitWidth: horizontal ? gridLayout.implicitWidth + Tokens.padding.larger * 2 : Config.bar.height
implicitHeight: horizontal ? baseSize : gridLayout.implicitHeight + Tokens.padding.medium * 2
implicitWidth: horizontal ? gridLayout.implicitWidth + Tokens.padding.medium * 2 : baseSize
radius: Tokens.rounding.full
StateLayer {
@@ -33,7 +32,7 @@ CustomRect {
anchors.centerIn: parent
anchors.horizontalCenterOffset: root.horizontal ? 0 : 1
anchors.verticalCenterOffset: root.horizontal ? 0 : -3
columnSpacing: Tokens.spacing.smaller
columnSpacing: Tokens.spacing.small
columns: root.horizontal ? -1 : 1
ServiceRef {
@@ -3,13 +3,14 @@ pragma ComponentBehavior: Bound
import Quickshell
import QtQuick
import QtQuick.Layouts
import qs.Helpers
import qs.Modules.SysTray.Widgets
import ZShell.Config
import qs.Helpers
import qs.Modules.Bar.Components.StatusIcons
import qs.Modules.Bar.Components.Common
import qs.Components
import qs.Services
CustomClippingRect {
WidgetBase {
id: root
readonly property int firstPresent: {
@@ -19,7 +20,6 @@ CustomClippingRect {
return i;
return -1;
}
required property bool horizontal
// Index of the first/last entry that isn't collapsed, for edge margin gating
readonly property alias items: grid
@@ -30,9 +30,8 @@ CustomClippingRect {
return i;
return -1;
}
readonly property real shortSize: Config.bar.height
readonly property real size: horizontal ? grid.implicitWidth + Tokens.padding.small * 2 : grid.implicitHeight + Tokens.padding.small * 2
readonly property int spacing: Tokens.spacing.normal / 2
readonly property real size: horizontal ? grid.implicitWidth + grid.anchors.leftMargin + grid.anchors.rightMargin : grid.implicitHeight + grid.anchors.bottomMargin + grid.anchors.topMargin
readonly property int spacing: Tokens.spacing.medium / 2
// Entries that can shrink to nothing, spacing included
function collapsed(entry: var): bool {
@@ -41,13 +40,13 @@ CustomClippingRect {
return false;
}
bottomLeftRadius: horizontal ? Tokens.rounding.smallest / 2 : Tokens.rounding.full
bottomLeftRadius: horizontal ? Tokens.rounding.small / 2 : Tokens.rounding.full
color: Colors.tPalette.m3surfaceContainer
implicitHeight: horizontal ? shortSize : size
implicitWidth: horizontal ? size : shortSize
implicitHeight: horizontal ? baseSize : size
implicitWidth: horizontal ? size : baseSize
radius: Tokens.rounding.full
topLeftRadius: Tokens.rounding.smallest / 2
topRightRadius: horizontal ? Tokens.rounding.full : Tokens.rounding.smallest / 2
topLeftRadius: Tokens.rounding.small / 2
topRightRadius: horizontal ? Tokens.rounding.full : Tokens.rounding.small / 2
Behavior on implicitHeight {
enabled: !root.horizontal
@@ -65,11 +64,11 @@ CustomClippingRect {
GridLayout {
id: grid
anchors.bottomMargin: root.horizontal ? 0 : Tokens.padding.small
anchors.bottomMargin: root.horizontal ? 0 : Tokens.padding.medium
anchors.fill: parent
anchors.leftMargin: root.horizontal ? Tokens.padding.small : 0
anchors.rightMargin: root.horizontal ? Tokens.padding.small : 0
anchors.topMargin: root.horizontal ? 0 : Tokens.padding.small
anchors.leftMargin: root.horizontal ? Tokens.padding.extraSmall : 0
anchors.rightMargin: root.horizontal ? Tokens.padding.extraSmall : 0
anchors.topMargin: root.horizontal ? 0 : Tokens.padding.extraSmall
columns: root.horizontal ? -1 : 1
Repeater {
@@ -113,7 +112,6 @@ CustomClippingRect {
name: "upower"
UPowerWidget {
horizontal: root.horizontal
}
}
}
@@ -13,7 +13,7 @@ MaterialIcon {
animate: true
color: Audio.muted ? Colors.palette.m3error : Colors.palette.m3onSurface
fill: 1
font.pointSize: horizontal ? Tokens.font.size.larger : Tokens.font.size.large
font.pointSize: Tokens.font.size.larger
text: Audio.muted ? "volume_off" : "volume_up"
Behavior on Layout.maximumWidth {
@@ -13,7 +13,7 @@ MaterialIcon {
animate: true
color: (Audio.sourceMuted ?? false) ? Colors.palette.m3error : Colors.palette.m3onSurface
fill: 1
font.pointSize: horizontal ? Tokens.font.size.larger : Tokens.font.size.large
font.pointSize: Tokens.font.size.larger
text: Audio.sourceMuted ? "mic_off" : "mic"
Behavior on Layout.maximumWidth {
@@ -0,0 +1,80 @@
import Quickshell.Services.UPower
import QtQuick
import QtQuick.Layouts
import ZShell.Config
import qs.Modules.Bar.Components.Common
import qs.Components
import qs.Helpers
Item {
id: root
readonly property Item currentItem: batteryIconLoader?.item ?? peripheralIconLoader?.item ?? upowerIconLoader.item
implicitHeight: currentItem?.implicitHeight ?? 0
implicitWidth: currentItem?.implicitWidth ?? 0
Behavior on Layout.preferredHeight {
Anim {
}
}
Behavior on Layout.preferredWidth {
Anim {
}
}
Behavior on opacity {
Anim {
}
}
Behavior on scale {
Anim {
}
}
Component.onCompleted: Battery.startDaemon()
Loader {
id: batteryIconLoader
active: Battery.isLaptop
anchors.centerIn: parent
sourceComponent: BatteryIcon {
devState: Battery.deviceStateString.toLowerCase()
percentage: Battery.currentPerc
}
}
Loader {
id: peripheralIconLoader
active: (Battery.lowestPeripheral?.isPresent ?? false) && !batteryIconLoader.active
anchors.centerIn: parent
sourceComponent: BatteryIcon {
devState: Battery.lowestPeripheral?.state ?? ""
percentage: Battery.lowestPeripheral?.percentage ?? 0
}
}
Loader {
id: upowerIconLoader
active: !batteryIconLoader.active && !peripheralIconLoader.active
anchors.centerIn: parent
sourceComponent: MaterialIcon {
Layout.alignment: Qt.AlignVCenter
animate: true
fill: 1
font.pointSize: Tokens.font.size.larger
text: {
if (PowerProfiles.profile === PowerProfile.PowerSaver)
return "energy_savings_leaf";
if (PowerProfiles.profile === PowerProfile.Performance)
return "bolt";
return "balance";
}
}
}
}
@@ -1,10 +1,9 @@
import QtQuick.Layouts
import QtQuick
import QtQuick.VectorImage
import Quickshell
import Quickshell.Services.SystemTray
import qs.Helpers
import qs.Modules
import qs.Modules.Bar.Popouts
import qs.Components
import ZShell.Config
import qs.Services
@@ -3,35 +3,39 @@ pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Layouts
import Quickshell.Services.SystemTray
import qs.Components
import ZShell.Config
import qs.Modules
import qs.Components
import qs.Modules.Bar.Components.Common
import qs.Modules.Bar.Components.Tray
import qs.Modules.Bar.Popouts
import qs.Services
CustomClippingRect {
WidgetBase {
id: root
required property bool horizontal
readonly property alias items: repeater
readonly property alias layout: sysGrid
required property GridLayout loader
readonly property int padding: Tokens.padding.small
readonly property int padding: Tokens.padding.extraSmall
required property Wrapper popouts
readonly property real shortSize: Config.bar.height
readonly property real size: horizontal ? sysGrid.implicitWidth + Tokens.padding.small : sysGrid.implicitHeight + Tokens.padding.small
readonly property real size: horizontal ? sysGrid.implicitWidth + sysGrid.anchors.leftMargin + sysGrid.anchors.rightMargin : sysGrid.implicitHeight + sysGrid.anchors.topMargin + sysGrid.anchors.bottomMargin
bottomLeftRadius: horizontal ? Tokens.rounding.full : Tokens.rounding.smallest / 2
bottomRightRadius: Tokens.rounding.smallest / 2
bottomLeftRadius: horizontal ? Tokens.rounding.full : Tokens.rounding.small / 2
bottomRightRadius: Tokens.rounding.small / 2
color: Colors.tPalette.m3surfaceContainer
implicitHeight: horizontal ? shortSize : size
implicitWidth: horizontal ? size : shortSize
implicitHeight: horizontal ? baseSize : size
implicitWidth: horizontal ? size : baseSize
radius: Tokens.rounding.full
topRightRadius: horizontal ? Tokens.rounding.smallest / 2 : Tokens.rounding.full
topRightRadius: horizontal ? Tokens.rounding.small / 2 : Tokens.rounding.full
GridLayout {
id: sysGrid
anchors.bottomMargin: root.horizontal ? 0 : Tokens.padding.extraSmall
anchors.centerIn: parent
anchors.leftMargin: root.horizontal ? Tokens.padding.extraSmall : 0
anchors.rightMargin: root.horizontal ? Tokens.padding.extraSmall : 0
anchors.topMargin: root.horizontal ? 0 : Tokens.padding.extraSmall
columns: root.horizontal ? -1 : 1
rowSpacing: -2
@@ -46,6 +50,7 @@ CustomClippingRect {
required property int index
required property SystemTrayItem modelData
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
implicitHeight: 34
implicitWidth: 34
ind: index
@@ -1,21 +1,20 @@
import QtQuick
import QtQuick.Layouts
import qs.Components
import qs.Modules
import qs.Helpers
import ZShell.Config
import qs.Components
import qs.Modules.Bar.Components.Common
import qs.Helpers
import qs.Services
CustomRect {
WidgetBase {
id: root
property int countUpdates: Updates.availableUpdates
required property bool horizontal
property color textColor: Colors.palette.m3onSurface
color: Colors.tPalette.m3surfaceContainer
implicitHeight: horizontal ? Config.bar.height : content.implicitHeight + Tokens.spacing.small * 2
implicitWidth: horizontal ? content.implicitWidth + Tokens.spacing.small * 2 : Config.bar.height
implicitHeight: horizontal ? baseSize : content.implicitHeight + Tokens.spacing.small
implicitWidth: horizontal ? content.implicitWidth + Tokens.spacing.small * 2 : baseSize
radius: Tokens.rounding.full
GridLayout {
@@ -24,6 +23,7 @@ CustomRect {
anchors.centerIn: parent
columnSpacing: Tokens.spacing.small
columns: root.horizontal ? -1 : 1
rowSpacing: -Tokens.spacing.extraSmall / 2
MaterialIcon {
Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter
@@ -34,7 +34,7 @@ CustomRect {
CustomText {
Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter
color: root.textColor
font.pointSize: root.horizontal ? Tokens.font.size.normal : Tokens.font.size.larger
font.pointSize: Tokens.font.size.normal
text: root.countUpdates
}
}
@@ -1,8 +1,8 @@
pragma ComponentBehavior: Bound
import QtQuick
import qs.Components
import ZShell.Config
import qs.Components
import qs.Helpers
import qs.Services
@@ -17,13 +17,12 @@ Item {
readonly property int maxSize: {
const otherModules = bar.children.filter(c => c.enabled && c.entryId && c.item !== this && c.entryId !== "spacer");
const otherSize = otherModules.reduce((acc, curr) => acc + (horizontal ? (curr.item?.nonAnimWidth ?? curr.width ?? 0) : (curr.item.nonAnimHeight ?? curr.height ?? 0)), 0);
return horizontal ? bar.width - otherSize - bar.spacing * (bar.children.length - 1) - bar.vPadding * 2 : bar.height - otherSize - bar.vPadding * (bar.children.length - 1) - bar.vPadding * 4;
return horizontal ? (bar.width - otherSize - bar.columnSpacing * (bar.children.length - 1) - bar.vPadding * 2) : (bar.height - otherSize - bar.rowSpacing * (bar.children.length - 1) - bar.vPadding * 4);
}
anchors.centerIn: parent
clip: true
implicitHeight: horizontal ? current.implicitHeight : current.implicitWidth + current.anchors.topMargin
implicitWidth: horizontal ? Math.min(current.implicitWidth, root.maxSize) : current.implicitHeight + current.anchors.topMargin
implicitWidth: horizontal ? current.implicitWidth + current.anchors.leftMargin : current.implicitHeight + current.anchors.topMargin
Behavior on implicitHeight {
enabled: !root.horizontal
@@ -36,6 +35,7 @@ Item {
enabled: root.horizontal
Anim {
type: Anim.DefaultEffects
}
}
@@ -2,22 +2,22 @@ pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Controls
import QtQuick.Effects
import Quickshell
import Quickshell.Hyprland
import ZShell.Config
import qs.Modules.Bar.Components.Workspaces
import qs.Components
import qs.Services
Item {
id: root
property real activeWorkspaceMargin: Math.ceil(Tokens.padding.small / 2)
property real activeWorkspaceMargin: Math.ceil(Tokens.padding.medium / 4)
readonly property int effectiveActiveWorkspaceId: monitor?.activeWorkspace?.id ?? 1
required property bool horizontal
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(root.screen)
required property ShellScreen screen
readonly property real shortSize: Math.max(Config.bar.height, 24)
readonly property real shortSize: Math.max(Config.bar.height, Tokens.bar.innerSize)
readonly property real size: (workspaceButtonWidth * workspacesShown) + activeWorkspaceMargin * 2
property int workspaceButtonWidth: (horizontal ? bgRect.implicitHeight : bgRect.implicitWidth) - root.activeWorkspaceMargin * 2
property int workspaceIndexInGroup: (effectiveActiveWorkspaceId - 1) % root.workspacesShown
@@ -90,7 +90,7 @@ Item {
color: Colors.palette.m3onSecondaryContainer
elide: Text.ElideRight
horizontalAlignment: Text.AlignHCenter
text: button.modelData.name
text: button.modelData?.name ?? ""
verticalAlignment: Text.AlignVCenter
}
}
@@ -15,12 +15,13 @@ import qs.Services
Item {
id: root
readonly property int rounding: Tokens.rounding.small - Tokens.padding.small
readonly property int panelRadius: Tokens.rounding.largeIncreased + Tokens.padding.smaller
readonly property int rounding: panelRadius - Tokens.padding.smaller
readonly property int topMargin: 0
required property var wrapper
implicitHeight: vol.implicitHeight + Tokens.padding.small * 2
implicitWidth: 500 + Tokens.padding.small * 2
implicitHeight: vol.implicitHeight + Tokens.padding.smaller * 2
implicitWidth: 500 + Tokens.padding.smaller * 2
CustomRect {
anchors.left: parent.left
@@ -28,7 +29,7 @@ Item {
anchors.top: parent.top
color: Colors.tPalette.m3surfaceContainer
implicitHeight: parent.implicitHeight
radius: Tokens.rounding.small
radius: root.rounding
y: parent.y
Behavior on implicitHeight {
@@ -41,7 +42,7 @@ Item {
id: vol
anchors.left: parent.left
anchors.margins: Tokens.padding.small
anchors.margins: Tokens.padding.smaller
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
}
@@ -51,17 +52,17 @@ Item {
CustomRect {
Layout.fillWidth: true
Layout.preferredHeight: 65 + Tokens.spacing.smaller * 2
Layout.preferredHeight: 65 + Tokens.spacing.small * 2
Layout.topMargin: root.topMargin
color: Colors.tPalette.m3surfaceContainer
radius: root.rounding
radius: root.rounding - vol.anchors.margins
ColumnLayout {
anchors.bottomMargin: Tokens.padding.smaller
anchors.bottomMargin: Tokens.padding.small
anchors.fill: parent
anchors.leftMargin: Tokens.padding.larger
anchors.rightMargin: Tokens.padding.larger
anchors.topMargin: Tokens.padding.smaller
anchors.leftMargin: Tokens.padding.small
anchors.rightMargin: Tokens.padding.small
anchors.topMargin: Tokens.padding.small
RowLayout {
Layout.fillHeight: true
@@ -82,12 +83,12 @@ Item {
}
RowLayout {
spacing: Tokens.spacing.large
spacing: Tokens.spacing.largeIncreased
CustomMouseArea {
Layout.bottomMargin: Tokens.padding.normal
Layout.bottomMargin: Tokens.padding.small
Layout.fillWidth: true
Layout.preferredHeight: Tokens.padding.larger * 3
Layout.preferredHeight: Tokens.padding.medium * 3
CustomSlider {
anchors.left: parent.left
@@ -109,7 +110,7 @@ Item {
}
CustomSwitch {
Layout.bottomMargin: Tokens.padding.normal
Layout.bottomMargin: Tokens.padding.small
checked: !Audio.muted
onToggled: {
@@ -124,10 +125,10 @@ Item {
CustomClippingRect {
Layout.fillWidth: true
Layout.preferredHeight: 65 + Tokens.spacing.smaller * 2
Layout.preferredHeight: 65 + Tokens.spacing.small * 2
Layout.topMargin: root.topMargin
color: Colors.tPalette.m3surfaceContainer
radius: root.rounding
radius: root.rounding - vol.anchors.margins
PwNodePeakMonitor {
id: sourcePeak
@@ -151,11 +152,11 @@ Item {
}
ColumnLayout {
anchors.bottomMargin: Tokens.padding.smaller
anchors.bottomMargin: Tokens.padding.small
anchors.fill: parent
anchors.leftMargin: Tokens.padding.larger
anchors.rightMargin: Tokens.padding.larger
anchors.topMargin: Tokens.padding.smaller
anchors.leftMargin: Tokens.padding.small
anchors.rightMargin: Tokens.padding.small
anchors.topMargin: Tokens.padding.small
RowLayout {
Layout.fillHeight: true
@@ -176,12 +177,12 @@ Item {
}
RowLayout {
spacing: Tokens.spacing.large
spacing: Tokens.spacing.largeIncreased
CustomMouseArea {
Layout.bottomMargin: Tokens.padding.normal
Layout.bottomMargin: Tokens.padding.small
Layout.fillWidth: true
Layout.preferredHeight: Tokens.padding.larger * 3
Layout.preferredHeight: Tokens.padding.medium * 3
CustomSlider {
anchors.left: parent.left
@@ -203,7 +204,7 @@ Item {
}
CustomSwitch {
Layout.bottomMargin: Tokens.padding.normal
Layout.bottomMargin: Tokens.padding.small
checked: !Audio.sourceMuted
onToggled: {
@@ -236,10 +237,10 @@ Item {
required property var modelData
Layout.fillWidth: true
Layout.preferredHeight: 65 + Tokens.spacing.smaller * 2
Layout.preferredHeight: 65 + Tokens.spacing.small * 2
Layout.topMargin: root.topMargin
color: Colors.tPalette.m3surfaceContainer
radius: root.rounding
radius: root.rounding - vol.anchors.margins
PwNodePeakMonitor {
id: peak
@@ -271,11 +272,11 @@ Item {
}
ColumnLayout {
anchors.bottomMargin: Tokens.padding.smaller
anchors.bottomMargin: Tokens.padding.small
anchors.fill: parent
anchors.leftMargin: Tokens.padding.larger
anchors.rightMargin: Tokens.padding.larger
anchors.topMargin: Tokens.padding.smaller
anchors.leftMargin: Tokens.padding.small
anchors.rightMargin: Tokens.padding.small
anchors.topMargin: Tokens.padding.small
RowLayout {
Layout.fillHeight: true
@@ -297,12 +298,12 @@ Item {
}
RowLayout {
spacing: Tokens.spacing.large
spacing: Tokens.spacing.largeIncreased
CustomMouseArea {
Layout.bottomMargin: Tokens.padding.normal
Layout.bottomMargin: Tokens.padding.small
Layout.fillWidth: true
Layout.preferredHeight: Tokens.padding.larger * 3
Layout.preferredHeight: Tokens.padding.medium * 3
CustomSlider {
anchors.left: parent.left
@@ -324,7 +325,7 @@ Item {
}
CustomSwitch {
Layout.bottomMargin: Tokens.padding.normal
Layout.bottomMargin: Tokens.padding.small
checked: !appBox.modelData.audio.muted
onToggled: {
@@ -58,7 +58,7 @@ Item {
Anim {
duration: content.animLength
easing.bezierCurve: content.animCurve
easing: content.animCurve
}
}
Behavior on y {
@@ -66,7 +66,7 @@ Item {
Anim {
duration: content.animLength
easing.bezierCurve: content.animCurve
easing: content.animCurve
}
}
@@ -81,6 +81,7 @@ Item {
anchors.top: root.position === "top" ? parent.top : undefined
anchors.topMargin: (-implicitHeight - 5) * root.offsetScale
anchors.verticalCenter: root.horizontal ? undefined : parent.verticalCenter
horizontal: root.horizontal
offsetScale: root.offsetScale
screen: root.screen
}
@@ -5,20 +5,17 @@ import Quickshell.Services.SystemTray
import QtQuick
import ZShell.Config
import qs.Components
import qs.Modules.WSOverview
import qs.Modules.Network
import qs.Modules.SysTray.Popouts
import qs.Modules.Updates
Item {
id: root
readonly property Item current: currentPopout?.item ?? null
readonly property Popout currentPopout: content.children.find(c => c.shouldBeActive) ?? null
required property bool horizontal
required property PopoutState popouts
implicitHeight: (currentPopout?.implicitHeight ?? 0) + Tokens.padding.small * 2
implicitWidth: (currentPopout?.implicitWidth ?? 0) + Tokens.padding.small * 2
implicitHeight: (currentPopout?.implicitHeight ?? 0) + Tokens.padding.smaller * 2
implicitWidth: (currentPopout?.implicitWidth ?? 0) + Tokens.padding.smaller * 2
Item {
id: content
@@ -73,6 +70,7 @@ Item {
name: "upower"
sourceComponent: UPowerPopout {
horizontal: root.horizontal
}
}
@@ -100,10 +98,10 @@ Item {
readonly property bool shouldBeActive: root.popouts.currentName === name
active: false
// anchors.horizontalCenter: parent.horizontalCenter
// anchors.top: parent.top
// anchors.topMargin: 5
anchors.centerIn: parent
anchors.centerIn: opacity === 1 ? undefined : parent
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: opacity === 1 ? parent.top : undefined
anchors.topMargin: Tokens.padding.smaller
opacity: 0
scale: 0.8
@@ -15,7 +15,7 @@ StackView {
id: root
readonly property int itemHeight: 30
readonly property int panelRadius: ((itemHeight / 2) + Tokens.padding.small) * Tokens.rounding.scale
readonly property int panelRadius: ((itemHeight / 2) + Tokens.padding.extraSmall) * Tokens.rounding.scale
required property PopoutState popouts
property int rootWidth: 0
required property QsMenuHandle trayItem
@@ -88,10 +88,10 @@ StackView {
required property QsMenuEntry modelData
Layout.fillWidth: true
Layout.leftMargin: modelData.isSeparator ? Tokens.padding.normal : 0
Layout.rightMargin: modelData.isSeparator ? Tokens.padding.normal : 0
color: modelData.isSeparator ? Colors.palette.m3outlineVariant : "transparent"
implicitHeight: modelData.isSeparator ? (visible ? 1 : 0) : childrenLoader.item.implicitHeight
Layout.leftMargin: modelData?.isSeparator ?? false ? Tokens.padding.small : 0
Layout.rightMargin: modelData?.isSeparator ?? false ? Tokens.padding.small : 0
color: modelData?.isSeparator ?? false ? Colors.palette.m3outlineVariant : "transparent"
implicitHeight: modelData?.isSeparator ?? false ? (visible ? 1 : 0) : childrenLoader.item?.implicitHeight ?? 0
implicitWidth: childrenLoader.item?.implicitWidth ?? 0
radius: Tokens.rounding.full
visible: index !== (menuOpener.children.values.length - 1) ? true : (modelData.isSeparator ? false : true)
@@ -99,18 +99,18 @@ StackView {
Loader {
id: childrenLoader
active: !item.modelData.isSeparator
active: !item.modelData?.isSeparator ?? false
anchors.fill: parent
asynchronous: true
sourceComponent: Item {
property int iconWidth: icon.active ? icon.width + Tokens.spacing.normal + icon.anchors.rightMargin : 0
property int iconWidth: icon.active ? icon.width + Tokens.spacing.medium + icon.anchors.rightMargin : 0
implicitHeight: root.itemHeight
implicitWidth: label.width + label.anchors.leftMargin * 2 + iconWidth + (expand.item?.width ?? 0)
StateLayer {
enabled: item.modelData.enabled
enabled: item.modelData?.enabled ?? false
radius: item.radius
onClicked: {
@@ -130,7 +130,7 @@ StackView {
Loader {
id: icon
active: item.modelData.icon !== ""
active: item.modelData?.icon ?? "" !== ""
anchors.right: parent.right
anchors.rightMargin: 10
anchors.verticalCenter: parent.verticalCenter
@@ -144,7 +144,7 @@ StackView {
id: iconImage
implicitSize: parent.implicitHeight
source: item.modelData.icon
source: item.modelData?.icon ?? Qt.url("")
visible: false
}
@@ -163,20 +163,20 @@ StackView {
anchors.left: parent.left
anchors.leftMargin: 10
anchors.verticalCenter: parent.verticalCenter
color: item.modelData.enabled ? Colors.palette.m3onSurface : Colors.palette.m3outline
text: item.modelData.text
color: item.modelData?.enabled ?? false ? Colors.palette.m3onSurface : Colors.palette.m3outline
text: item.modelData?.text ?? ""
}
Loader {
id: expand
active: item.modelData.hasChildren
active: item.modelData?.hasChildren ?? false
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
asynchronous: true
sourceComponent: MaterialIcon {
color: item.modelData.enabled ? Colors.palette.m3onSurface : Colors.palette.m3outline
color: item.modelData?.enabled ?? false ? Colors.palette.m3onSurface : Colors.palette.m3outline
text: "chevron_right"
}
}
@@ -1,8 +1,10 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Layouts
import Quickshell.Services.UPower
import ZShell.Config
import qs.Modules.Bar.Components.Common
import qs.Helpers
import qs.Components
import qs.Services
@@ -10,9 +12,10 @@ import qs.Services
Column {
id: root
readonly property int panelRadius: ((profiles.height / 2) + Tokens.padding.small) * Tokens.rounding.scale
required property bool horizontal
readonly property int panelRadius: ((profiles.height / 2) + Tokens.padding.extraSmall) * Tokens.rounding.scale
spacing: Tokens.spacing.normal
spacing: Tokens.spacing.medium
Loader {
active: Battery.isLaptop
@@ -22,6 +25,38 @@ Column {
}
}
Item {
id: padding
implicitHeight: root.horizontal ? 0 : Tokens.padding.small
implicitWidth: 1
}
Repeater {
model: Battery.allPeripherals
RowLayout {
id: layout
required property var modelData
anchors.left: parent.left
anchors.leftMargin: Tokens.padding.small
anchors.right: parent.right
anchors.rightMargin: Tokens.padding.small
CustomText {
Layout.fillWidth: true
text: layout.modelData.model
}
BatteryIcon {
devState: layout.modelData.state
percentage: layout.modelData.percentage
}
}
}
CustomText {
function formatSeconds(s: int, fallback: string): string {
const day = Math.floor(s / 86400);
@@ -40,7 +75,7 @@ Column {
}
anchors.left: parent.left
anchors.leftMargin: Tokens.padding.normal
anchors.leftMargin: Tokens.padding.small
text: Battery.isLaptop ? qsTr("Time %1: %2").arg(Battery.onBattery ? "remaining" : "until charged").arg(Battery.onBattery ? formatSeconds(Battery.timeToEmpty, "Calculating...") : formatSeconds(Battery.timeToFull, "Fully charged!")) : qsTr("Power profile: %1").arg(PowerProfile.toString(PowerProfiles.profile))
}
@@ -53,8 +88,8 @@ Column {
sourceComponent: CustomRect {
color: Colors.palette.m3error
implicitHeight: child.implicitHeight + Tokens.padding.large
implicitWidth: child.implicitWidth + Tokens.padding.larger * 2
radius: Tokens.rounding.large
implicitWidth: child.implicitWidth + Tokens.padding.small * 2
radius: Tokens.rounding.largeIncreased
Column {
id: child
@@ -75,7 +110,7 @@ Column {
CustomText {
anchors.verticalCenter: parent.verticalCenter
color: Colors.palette.m3onError
font.family: Appearance.font.family.mono
font.family: Config.appearance.font.family.mono
text: qsTr("Performance Degraded")
}
@@ -111,7 +146,7 @@ Column {
anchors.horizontalCenter: parent.horizontalCenter
color: Colors.tPalette.m3surfaceContainer
implicitHeight: indicator.height + Tokens.padding.extraSmall * 2
implicitWidth: saver.implicitHeight + balance.implicitHeight + perf.implicitHeight + Tokens.padding.larger * 2 + Tokens.spacing.small * 8
implicitWidth: saver.implicitHeight + balance.implicitHeight + perf.implicitHeight + Tokens.padding.small * 2 + Tokens.spacing.small * 8
radius: Tokens.rounding.full
CustomRect {
@@ -192,8 +227,8 @@ Column {
required property string icon
required property int profile
implicitHeight: icon.implicitHeight + Tokens.padding.small
implicitWidth: icon.implicitHeight + Tokens.padding.small
implicitHeight: icon.implicitHeight + Tokens.padding.extraSmall
implicitWidth: icon.implicitHeight + Tokens.padding.extraSmall
StateLayer {
color: profiles.current === parent.icon ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
@@ -13,13 +13,13 @@ CustomClippingRect {
id: root
readonly property bool hasUpdates: Object.keys(Updates.updates)?.length > 0
readonly property int itemHeight: 50 + Tokens.padding.smaller * 2
readonly property int itemHeight: 50 + Tokens.padding.small * 2
required property var wrapper
color: Colors.tPalette.m3surfaceContainer
implicitHeight: hasUpdates ? updatesListLoader.item?.implicitHeight + Tokens.padding.small * 2 : noUpdatesLoader.item.height
implicitWidth: hasUpdates ? updatesListLoader.item?.contentWidth + Tokens.padding.small * 2 : noUpdatesLoader.item.width
radius: Tokens.rounding.small
implicitHeight: hasUpdates ? updatesListLoader.item?.implicitHeight + Tokens.padding.extraSmall * 2 : noUpdatesLoader.item.height
implicitWidth: hasUpdates ? updatesListLoader.item?.contentWidth + Tokens.padding.extraSmall * 2 : noUpdatesLoader.item.width
radius: Tokens.rounding.large - Tokens.padding.smaller
Loader {
id: noUpdatesLoader
@@ -70,7 +70,7 @@ CustomClippingRect {
displayMarginEnd: root.itemHeight
implicitHeight: Math.min(contentHeight, (root.itemHeight + spacing) * 5 - spacing)
implicitWidth: contentWidth
spacing: Tokens.spacing.normal
spacing: Tokens.spacing.medium
delegate: CustomRect {
id: update
@@ -78,17 +78,15 @@ CustomClippingRect {
required property var modelData
readonly property list<string> sections: modelData.update.split(" ")
// anchors.left: parent.left
// anchors.right: parent.right
color: Colors.tPalette.m3surfaceContainer
implicitHeight: root.itemHeight
implicitWidth: 600
radius: Tokens.rounding.small - Tokens.padding.small
radius: root.radius - Tokens.padding.extraSmall
RowLayout {
anchors.fill: parent
anchors.leftMargin: Tokens.padding.smaller
anchors.rightMargin: Tokens.padding.smaller
anchors.leftMargin: Tokens.padding.small
anchors.rightMargin: Tokens.padding.small
MaterialIcon {
font.pointSize: Tokens.font.size.large * 2

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