Merge branch 'end-4:main' into fix/workflow-run-on-forks
@@ -2,22 +2,33 @@
|
|||||||
|
|
||||||
- Please, please, please, make multiple PRs if you have many features/fixes, and don't shove your personal changes along with the PR, including changed defaults
|
- Please, please, please, make multiple PRs if you have many features/fixes, and don't shove your personal changes along with the PR, including changed defaults
|
||||||
- We can accept features that we do not personally want, but in that case we will ask you to make it configurable/optionally loaded.
|
- We can accept features that we do not personally want, but in that case we will ask you to make it configurable/optionally loaded.
|
||||||
- If you want to start working on something big to contribute, it might be a good idea to ask first to not waste your effort (but if you've already done it for yourself, it doesn't hurt to submit).
|
- If you want to start working on something _big_ to contribute, it might be a good idea to ask first to not waste your effort (but if you've already done it for yourself, it doesn't hurt to submit).
|
||||||
|
|
||||||
# Code details
|
# Translations
|
||||||
|
|
||||||
## Contributing to i18n
|
See `dots/.config/quickshell/ii/translations/tools`
|
||||||
|
|
||||||
For contributing in translation (i18n) for Quickshell, see also `dots/.config/quickshell/ii/translations/tools`.
|
# Code
|
||||||
|
|
||||||
## Dynamic loading
|
## Dynamic loading
|
||||||
|
|
||||||
- If something's not always necessary, especially when guarded by a config option to enable/disable, put it in a `Loader`. One tip with `Loader`s is sometimes you will need to declare positioning properties (like `anchors`) in the `Loader`, not the `sourceComponent`.
|
- If something's not always necessary, especially when guarded by a config option to enable/disable, put it in a `Loader`
|
||||||
|
- Note that you will need to declare positioning properties (like `anchors`) in the `Loader`, not the `sourceComponent`
|
||||||
|
- When something that's to be dynamically loaded doesn't affect its parent layout, you can have a fading animation by using FadeLoader and set the `shown` prop instead of `active` and `visible`
|
||||||
|
|
||||||
## Practical concerns
|
## Practical concerns
|
||||||
|
|
||||||
- Make sure what you add does not require significant resources for a minor purpose or harm usability just for the sake of looking nice. The dotfiles must remain practical for daily driving.
|
- Make sure what you add does not require significant resources for a minor purpose or harm usability just for the sake of looking nice. The dotfiles must remain practical for daily driving.
|
||||||
- If there is something really fancy and impractical anyway, add a config option for it and make sure it's disabled by default.
|
- If there is something really fancy and impractical anyway, add a config option for it and make sure it's disabled by default (example: constantly rotating background clock)
|
||||||
|
|
||||||
|
## Style
|
||||||
|
|
||||||
|
- Spaces
|
||||||
|
- Space properties and children data into meaningful groups. (but of course, don't use 2+ blanks in a row)
|
||||||
|
- Put spaces between text and operators: `if (condition) { ... } else { ... }` instead of `if(condition){ ... }else{ ... }`
|
||||||
|
- As you can see, it's pretty easy to use lots of nesting. There's no hard limit, end-4 himself nests a lot too, but avoid/mitigate that:
|
||||||
|
- Prefer early return: Use something like `if (!condition) return; doStuff();` instead of `if (condition) { doStuff() }`
|
||||||
|
- If you feel it's a bother to refractor something into a new file, remember there's `component` to declare reusable components in the same file.
|
||||||
|
|
||||||
# Setting up
|
# Setting up
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ Widget system: Quickshell | Support: Yes
|
|||||||
|:---|:---------------|
|
|:---|:---------------|
|
||||||
| <img width="1920" height="1080" alt="image" src="https://github.com/user-attachments/assets/ea0154a1-e984-4bb6-a424-23247cefe3c6" /> | <img width="1920" height="1080" alt="image" src="https://github.com/user-attachments/assets/6eba0d57-2606-4cea-8993-e6f169e82e70" /> |
|
| <img width="1920" height="1080" alt="image" src="https://github.com/user-attachments/assets/ea0154a1-e984-4bb6-a424-23247cefe3c6" /> | <img width="1920" height="1080" alt="image" src="https://github.com/user-attachments/assets/6eba0d57-2606-4cea-8993-e6f169e82e70" /> |
|
||||||
| Window management | Weeb power |
|
| Window management | Weeb power |
|
||||||
| <img width="1920" height="1080" alt="image" src="https://github.com/user-attachments/assets/e77a7c96-1905-4126-a2a0-434f818825a2" /> | <img width="1920" height="1080" alt="image" src="https://github.com/user-attachments/assets/c8544e99-8881-477f-b83a-d6e35c0184a1" /> |
|
| <img width="1920" height="1080" alt="image" src="https://github.com/user-attachments/assets/a7e6d29c-e82c-4934-98db-36c810ec999b" /> | <img width="1920" height="1080" alt="image" src="https://github.com/user-attachments/assets/c8544e99-8881-477f-b83a-d6e35c0184a1" /> |
|
||||||
|
|
||||||
### Other styles: Available at the end of the readme.
|
### Other styles: Available at the end of the readme.
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
/diagnose.result
|
/diagnose.result
|
||||||
/cache
|
/cache
|
||||||
|
|
||||||
# Ignore Python cache files
|
# Ignore Python cache files
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
dots/.config/quickshell/ii/.qmlls.ini
|
|
||||||
.update-lock
|
/dots/.config/quickshell/ii/.qmlls.ini
|
||||||
|
|
||||||
|
# exp-update
|
||||||
|
/.update-lock
|
||||||
|
|
||||||
|
# custom os-release
|
||||||
/os-release
|
/os-release
|
||||||
#emacs backup
|
|
||||||
|
# Emacs auto backup file
|
||||||
*~
|
*~
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ x git submodule status --recursive
|
|||||||
|
|
||||||
e "Checking distro"
|
e "Checking distro"
|
||||||
x _check_distro_id
|
x _check_distro_id
|
||||||
|
x cat os-release
|
||||||
#x _check_distro
|
#x _check_distro
|
||||||
|
|
||||||
e "Checking variables"
|
e "Checking variables"
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ exec-once = sleep 1 && dbus-update-activation-environment --systemd WAYLAND_DISP
|
|||||||
exec-once = hyprpm reload
|
exec-once = hyprpm reload
|
||||||
|
|
||||||
# Audio
|
# Audio
|
||||||
exec-once = easyeffects --gapplication-service
|
exec-once = easyeffects --hide-window --service-mode
|
||||||
|
|
||||||
# Clipboard: history
|
# Clipboard: history
|
||||||
# exec-once = wl-paste --watch cliphist store &
|
# exec-once = wl-paste --watch cliphist store &
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ bindit = ,Super_L, global, quickshell:workspaceNumber # [hidden]
|
|||||||
bindit = ,Super_R, global, quickshell:workspaceNumber # [hidden]
|
bindit = ,Super_R, global, quickshell:workspaceNumber # [hidden]
|
||||||
bindd = Super, V, Clipboard history >> clipboard, global, quickshell:overviewClipboardToggle # Clipboard history >> clipboard
|
bindd = Super, V, Clipboard history >> clipboard, global, quickshell:overviewClipboardToggle # Clipboard history >> clipboard
|
||||||
bindd = Super, Period, Emoji >> clipboard, global, quickshell:overviewEmojiToggle # Emoji >> clipboard
|
bindd = Super, Period, Emoji >> clipboard, global, quickshell:overviewEmojiToggle # Emoji >> clipboard
|
||||||
bindd = Super, Tab, Toggle overview, global, quickshell:overviewToggle # [hidden] Toggle overview/launcher (alt)
|
bind = Super, Tab, global, quickshell:overviewWorkspacesToggle # [hidden] Toggle overview/launcher (alt)
|
||||||
bindd = Super, A, Toggle left sidebar, global, quickshell:sidebarLeftToggle # Toggle left sidebar
|
bind = Super, A, global, quickshell:sidebarLeftToggle # Toggle left sidebar
|
||||||
bind = Super+Alt, A, global, quickshell:sidebarLeftToggleDetach # [hidden]
|
bind = Super+Alt, A, global, quickshell:sidebarLeftToggleDetach # [hidden]
|
||||||
bind = Super, B, global, quickshell:sidebarLeftToggle # [hidden]
|
bind = Super, B, global, quickshell:sidebarLeftToggle # [hidden]
|
||||||
bind = Super, O, global, quickshell:sidebarLeftToggle # [hidden]
|
bind = Super, O, global, quickshell:sidebarLeftToggle # [hidden]
|
||||||
|
|||||||
@@ -133,12 +133,14 @@ layerrule = blurpopups, quickshell:.*
|
|||||||
layerrule = blur, quickshell:.*
|
layerrule = blur, quickshell:.*
|
||||||
layerrule = ignorealpha 0.79, quickshell:.*
|
layerrule = ignorealpha 0.79, quickshell:.*
|
||||||
layerrule = animation slide, quickshell:bar
|
layerrule = animation slide, quickshell:bar
|
||||||
|
layerrule = noanim, quickshell:actionCenter
|
||||||
layerrule = animation slide bottom, quickshell:cheatsheet
|
layerrule = animation slide bottom, quickshell:cheatsheet
|
||||||
layerrule = animation slide bottom, quickshell:dock
|
layerrule = animation slide bottom, quickshell:dock
|
||||||
layerrule = animation popin 120%, quickshell:screenCorners
|
layerrule = animation popin 120%, quickshell:screenCorners
|
||||||
layerrule = noanim, quickshell:lockWindowPusher
|
layerrule = noanim, quickshell:lockWindowPusher
|
||||||
layerrule = animation fade, quickshell:notificationPopup
|
layerrule = animation fade, quickshell:notificationPopup
|
||||||
layerrule = noanim, quickshell:overlay
|
layerrule = noanim, quickshell:overlay
|
||||||
|
layerrule = ignorealpha 1, quickshell:overlay
|
||||||
layerrule = noanim, quickshell:overview
|
layerrule = noanim, quickshell:overview
|
||||||
layerrule = animation slide bottom, quickshell:osk
|
layerrule = animation slide bottom, quickshell:osk
|
||||||
layerrule = noanim, quickshell:polkit
|
layerrule = noanim, quickshell:polkit
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
The "search" and "task view" icons are from here, with modifications
|
The "start-here", "search" and "task view" icons are from here, with modifications
|
||||||
|
|
||||||
https://www.figma.com/community/file/1123040825921884189/windows-11
|
[Windows 11 by Joshua Oghenekaro Okwe - Figma](https://www.figma.com/community/file/1123040825921884189/windows-11)
|
||||||
|
|
||||||
License: CC BY 4.0
|
License: [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/deed.en)
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
sodipodi:docname="arrow-sync.svg"
|
||||||
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs1" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:zoom="25.868323"
|
||||||
|
inkscape:cx="14.245222"
|
||||||
|
inkscape:cy="12.447657"
|
||||||
|
inkscape:window-width="1498"
|
||||||
|
inkscape:window-height="1020"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg1" />
|
||||||
|
<path
|
||||||
|
d="m 19.947024,13.17933 a 0.75,0.75 0 0 0 -0.907212,0.549312 7.251,7.251 0 0 1 -13.334866,1.873667 l 0.8908023,0.350894 a 0.75,0.75 0 0 0 0.6494514,-1.347747 l -0.100442,-0.04793 -2.6316174,-1.036623 a 0.75,0.75 0 0 0 -0.9241627,0.322228 l -0.047921,0.100457 -1.0366214,2.631619 a 0.75,0.75 0 0 0 1.3468323,0.649854 l 0.048321,-0.09951 0.3887326,-0.986859 A 8.75,8.75 0 0 0 20.494492,14.087329 0.75,0.75 0 0 0 19.946102,13.179722 Z M 21.068469,6.4543893 A 0.75,0.75 0 0 0 20.096388,6.8770607 L 19.707652,7.863919 A 8.75,8.75 0 0 0 3.5868012,9.5848274 0.75043107,0.75043107 0 1 0 5.0290446,10.000183 7.251,7.251 0 0 1 18.290631,8.3993655 l -0.8904,-0.3499798 a 0.75,0.75 0 1 0 -0.549014,1.3956769 l 2.631617,1.0366214 a 0.75,0.75 0 0 0 0.972088,-0.422667 L 21.491544,7.4273949 A 0.75,0.75 0 0 0 21.068874,6.455308 Z"
|
||||||
|
fill="#212121"
|
||||||
|
id="path1" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M4.293 8.293a1 1 0 0 1 1.414 0L12 14.586l6.293-6.293a1 1 0 1 1 1.414 1.414l-7 7a1 1 0 0 1-1.414 0l-7-7a1 1 0 0 1 0-1.414Z" fill="#212121"/></svg>
|
||||||
|
After Width: | Height: | Size: 249 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M3.28 2.22a.75.75 0 0 0-1.06 1.06l5.905 5.905L4.81 10.33a1.25 1.25 0 0 0-.476 2.065L7.439 15.5 3 19.94V21h1.06l4.44-4.44 3.105 3.105a1.25 1.25 0 0 0 2.065-.476l1.145-3.313 5.905 5.904a.75.75 0 0 0 1.06-1.06L3.28 2.22Zm10.355 12.476-1.252 3.626-6.705-6.705 3.626-1.252 4.331 4.331Zm6.048-3.876-3.787 1.894 1.118 1.118 3.34-1.67a2.75 2.75 0 0 0 .714-4.404l-4.825-4.826a2.75 2.75 0 0 0-4.405.715l-1.67 3.34 1.118 1.117 1.894-3.787a1.25 1.25 0 0 1 2.002-.325l4.826 4.826a1.25 1.25 0 0 1-.325 2.002Z" fill="#212121"/></svg>
|
||||||
|
After Width: | Height: | Size: 622 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m16.242 2.932 4.826 4.826a2.75 2.75 0 0 1-.715 4.404l-4.87 2.435a.75.75 0 0 0-.374.426l-1.44 4.166a1.25 1.25 0 0 1-2.065.476L8.5 16.561 4.06 21H3v-1.06l4.44-4.44-3.105-3.104a1.25 1.25 0 0 1 .476-2.066l4.166-1.44a.75.75 0 0 0 .426-.373l2.435-4.87a2.75 2.75 0 0 1 4.405-.715Zm3.766 5.886-4.826-4.826a1.25 1.25 0 0 0-2.002.325l-2.435 4.871a2.25 2.25 0 0 1-1.278 1.12l-3.789 1.31 6.705 6.704 1.308-3.789a2.25 2.25 0 0 1 1.12-1.277l4.872-2.436a1.25 1.25 0 0 0 .325-2.002Z" fill="#212121"/></svg>
|
||||||
|
After Width: | Height: | Size: 594 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12.012 2.25c.734.008 1.465.093 2.182.253a.75.75 0 0 1 .582.649l.17 1.527a1.384 1.384 0 0 0 1.927 1.116l1.401-.615a.75.75 0 0 1 .85.174 9.792 9.792 0 0 1 2.204 3.792.75.75 0 0 1-.271.825l-1.242.916a1.381 1.381 0 0 0 0 2.226l1.243.915a.75.75 0 0 1 .272.826 9.797 9.797 0 0 1-2.204 3.792.75.75 0 0 1-.848.175l-1.407-.617a1.38 1.38 0 0 0-1.926 1.114l-.169 1.526a.75.75 0 0 1-.572.647 9.518 9.518 0 0 1-4.406 0 .75.75 0 0 1-.572-.647l-.168-1.524a1.382 1.382 0 0 0-1.926-1.11l-1.406.616a.75.75 0 0 1-.849-.175 9.798 9.798 0 0 1-2.204-3.796.75.75 0 0 1 .272-.826l1.243-.916a1.38 1.38 0 0 0 0-2.226l-1.243-.914a.75.75 0 0 1-.271-.826 9.793 9.793 0 0 1 2.204-3.792.75.75 0 0 1 .85-.174l1.4.615a1.387 1.387 0 0 0 1.93-1.118l.17-1.526a.75.75 0 0 1 .583-.65c.717-.159 1.45-.243 2.201-.252Zm0 1.5a9.135 9.135 0 0 0-1.354.117l-.109.977A2.886 2.886 0 0 1 6.525 7.17l-.898-.394a8.293 8.293 0 0 0-1.348 2.317l.798.587a2.881 2.881 0 0 1 0 4.643l-.799.588c.32.842.776 1.626 1.348 2.322l.905-.397a2.882 2.882 0 0 1 4.017 2.318l.11.984c.889.15 1.798.15 2.687 0l.11-.984a2.881 2.881 0 0 1 4.018-2.322l.905.396a8.296 8.296 0 0 0 1.347-2.318l-.798-.588a2.881 2.881 0 0 1 0-4.643l.796-.587a8.293 8.293 0 0 0-1.348-2.317l-.896.393a2.884 2.884 0 0 1-4.023-2.324l-.11-.976a8.988 8.988 0 0 0-1.333-.117ZM12 8.25a3.75 3.75 0 1 1 0 7.5 3.75 3.75 0 0 1 0-7.5Zm0 1.5a2.25 2.25 0 1 0 0 4.5 2.25 2.25 0 0 0 0-4.5Z" fill="#212121"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,24 @@
|
|||||||
|
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M4 6.2C4 4.98497 4.98497 4 6.2 4H28.2C29.415 4 30.4 4.98497 30.4 6.2V28.2C30.4 29.415 29.415 30.4 28.2 30.4H6.2C4.98497 30.4 4 29.415 4 28.2V6.2Z" fill="url(#paint0_radial_520_19)"/>
|
||||||
|
<path d="M32.6 6.2C32.6 4.98497 33.585 4 34.8 4H56.8C58.015 4 59 4.98497 59 6.2V28.2C59 29.415 58.015 30.4 56.8 30.4H34.8C33.585 30.4 32.6 29.415 32.6 28.2V6.2Z" fill="url(#paint1_radial_520_19)"/>
|
||||||
|
<path d="M32.6 34.8C32.6 33.585 33.585 32.6 34.8 32.6H56.8C58.015 32.6 59 33.585 59 34.8V56.8C59 58.015 58.015 59 56.8 59H34.8C33.585 59 32.6 58.015 32.6 56.8V34.8Z" fill="url(#paint2_radial_520_19)"/>
|
||||||
|
<path d="M4 34.8C4 33.585 4.98497 32.6 6.2 32.6H28.2C29.415 32.6 30.4 33.585 30.4 34.8V56.8C30.4 58.015 29.415 59 28.2 59H6.2C4.98497 59 4 58.015 4 56.8V34.8Z" fill="url(#paint3_radial_520_19)"/>
|
||||||
|
<defs>
|
||||||
|
<radialGradient id="paint0_radial_520_19" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(4 4) rotate(45) scale(77.7817)">
|
||||||
|
<stop stop-color="#0B9BFE"/>
|
||||||
|
<stop offset="1" stop-color="#0B9BFE"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint1_radial_520_19" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(4 4) rotate(45) scale(77.7817)">
|
||||||
|
<stop stop-color="#0B9BFE"/>
|
||||||
|
<stop offset="1" stop-color="#0B9BFE"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint2_radial_520_19" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(4 4) rotate(45) scale(77.7817)">
|
||||||
|
<stop stop-color="#0B9BFE"/>
|
||||||
|
<stop offset="1" stop-color="#0B9BFE"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint3_radial_520_19" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(4 4) rotate(45) scale(77.7817)">
|
||||||
|
<stop stop-color="#0B9BFE"/>
|
||||||
|
<stop offset="1" stop-color="#0B9BFE"/>
|
||||||
|
</radialGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1,24 @@
|
|||||||
|
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M4 6.2C4 4.98497 4.98497 4 6.2 4H28.2C29.415 4 30.4 4.98497 30.4 6.2V28.2C30.4 29.415 29.415 30.4 28.2 30.4H6.2C4.98497 30.4 4 29.415 4 28.2V6.2Z" fill="url(#paint0_radial_519_6)"/>
|
||||||
|
<path d="M32.6 6.2C32.6 4.98497 33.585 4 34.8 4H56.8C58.015 4 59 4.98497 59 6.2V28.2C59 29.415 58.015 30.4 56.8 30.4H34.8C33.585 30.4 32.6 29.415 32.6 28.2V6.2Z" fill="url(#paint1_radial_519_6)"/>
|
||||||
|
<path d="M32.6 34.8C32.6 33.585 33.585 32.6 34.8 32.6H56.8C58.015 32.6 59 33.585 59 34.8V56.8C59 58.015 58.015 59 56.8 59H34.8C33.585 59 32.6 58.015 32.6 56.8V34.8Z" fill="url(#paint2_radial_519_6)"/>
|
||||||
|
<path d="M4 34.8C4 33.585 4.98497 32.6 6.2 32.6H28.2C29.415 32.6 30.4 33.585 30.4 34.8V56.8C30.4 58.015 29.415 59 28.2 59H6.2C4.98497 59 4 58.015 4 56.8V34.8Z" fill="url(#paint3_radial_519_6)"/>
|
||||||
|
<defs>
|
||||||
|
<radialGradient id="paint0_radial_519_6" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(4 4) rotate(45) scale(77.7817)">
|
||||||
|
<stop stop-color="#81DFFF"/>
|
||||||
|
<stop offset="1" stop-color="#0A99F9"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint1_radial_519_6" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(4 4) rotate(45) scale(77.7817)">
|
||||||
|
<stop stop-color="#81DFFF"/>
|
||||||
|
<stop offset="1" stop-color="#0A99F9"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint2_radial_519_6" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(4 4) rotate(45) scale(77.7817)">
|
||||||
|
<stop stop-color="#81DFFF"/>
|
||||||
|
<stop offset="1" stop-color="#0A99F9"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint3_radial_519_6" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(4 4) rotate(45) scale(77.7817)">
|
||||||
|
<stop stop-color="#81DFFF"/>
|
||||||
|
<stop offset="1" stop-color="#0A99F9"/>
|
||||||
|
</radialGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1,105 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="64"
|
||||||
|
height="64"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 16.933 16.933"
|
||||||
|
id="svg2"
|
||||||
|
sodipodi:docname="system-search-checked-dark.svg"
|
||||||
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview2"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:zoom="4.65625"
|
||||||
|
inkscape:cx="32"
|
||||||
|
inkscape:cy="32"
|
||||||
|
inkscape:window-width="1197"
|
||||||
|
inkscape:window-height="1020"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="g2" />
|
||||||
|
<defs
|
||||||
|
id="defs2">
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient1"
|
||||||
|
inkscape:collect="always">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#565757;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop3" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#4c4f52;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient919"
|
||||||
|
x1="4.3106"
|
||||||
|
x2="14.36"
|
||||||
|
y1="8.4665"
|
||||||
|
y2="8.4665"
|
||||||
|
gradientTransform="matrix(1.226575,0,0,1.226575,-0.82407803,-6.4497629)"
|
||||||
|
gradientUnits="userSpaceOnUse">
|
||||||
|
<stop
|
||||||
|
stop-color="#3c8cff"
|
||||||
|
offset="0"
|
||||||
|
id="stop1"
|
||||||
|
style="stop-color:#5fe277;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
stop-color="#55b4ff"
|
||||||
|
offset="1"
|
||||||
|
id="stop2"
|
||||||
|
style="stop-color:#0078d3;stop-opacity:1;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient1"
|
||||||
|
id="linearGradient4"
|
||||||
|
x1="-7.2925777"
|
||||||
|
y1="11.283"
|
||||||
|
x2="5.189723"
|
||||||
|
y2="11.283"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(11.677839,-7.3471437)" />
|
||||||
|
</defs>
|
||||||
|
<g
|
||||||
|
transform="translate(16.148 .19097)"
|
||||||
|
id="g2">
|
||||||
|
<rect
|
||||||
|
transform="rotate(45)"
|
||||||
|
x="2.891"
|
||||||
|
y="10.492"
|
||||||
|
width="7.4901"
|
||||||
|
height="1.583"
|
||||||
|
ry=".79147"
|
||||||
|
fill="#1955b9"
|
||||||
|
stroke-width="1.1651"
|
||||||
|
id="rect2"
|
||||||
|
style="stroke-width:1.16520206;stroke-dasharray:none;fill:#0175d1;fill-opacity:1" />
|
||||||
|
<circle
|
||||||
|
transform="rotate(120)"
|
||||||
|
cx="10.62641"
|
||||||
|
cy="3.9358561"
|
||||||
|
r="5.3520403"
|
||||||
|
fill="none"
|
||||||
|
stroke="url(#linearGradient919)"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-width="1.77822"
|
||||||
|
id="circle2"
|
||||||
|
style="fill:url(#linearGradient4);stroke:url(#linearGradient919);stroke-width:1.77822958;stroke-dasharray:none" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.0 KiB |
@@ -0,0 +1,81 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="64"
|
||||||
|
height="64"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 16.933 16.933"
|
||||||
|
id="svg2"
|
||||||
|
sodipodi:docname="system-search-checked-light.svg"
|
||||||
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview2"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:zoom="6.5849319"
|
||||||
|
inkscape:cx="26.95548"
|
||||||
|
inkscape:cy="26.423963"
|
||||||
|
inkscape:window-width="1257"
|
||||||
|
inkscape:window-height="1020"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg2" />
|
||||||
|
<defs
|
||||||
|
id="defs2">
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient919"
|
||||||
|
x1="4.3106"
|
||||||
|
x2="14.36"
|
||||||
|
y1="8.4665"
|
||||||
|
y2="8.4665"
|
||||||
|
gradientTransform="matrix(1.226575,0,0,1.226575,-0.82407803,-6.4497629)"
|
||||||
|
gradientUnits="userSpaceOnUse">
|
||||||
|
<stop
|
||||||
|
stop-color="#3c8cff"
|
||||||
|
offset="0"
|
||||||
|
id="stop1"
|
||||||
|
style="stop-color:#5fe277;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
stop-color="#55b4ff"
|
||||||
|
offset="1"
|
||||||
|
id="stop2"
|
||||||
|
style="stop-color:#0078d3;stop-opacity:1;" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<rect
|
||||||
|
transform="rotate(45,7.8434785,19.587845)"
|
||||||
|
x="3.4592254"
|
||||||
|
y="10.492"
|
||||||
|
width="6.921874"
|
||||||
|
height="1.5830002"
|
||||||
|
ry="0.71336967"
|
||||||
|
fill="#1955b9"
|
||||||
|
stroke-width="1.1651"
|
||||||
|
id="rect2-5"
|
||||||
|
style="fill:#0077d4;fill-opacity:1;stroke-width:1.1652;stroke-dasharray:none" />
|
||||||
|
<circle
|
||||||
|
transform="rotate(120,8.0188717,4.757011)"
|
||||||
|
cx="10.62641"
|
||||||
|
cy="3.9358561"
|
||||||
|
r="5.3520403"
|
||||||
|
fill="none"
|
||||||
|
stroke="url(#linearGradient919)"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-width="1.77822"
|
||||||
|
id="circle2"
|
||||||
|
style="fill:none;stroke:url(#linearGradient919);stroke-width:1.77822958;stroke-dasharray:none" />
|
||||||
|
<g
|
||||||
|
transform="translate(16.148 .19097)"
|
||||||
|
id="g2" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -7,10 +7,11 @@
|
|||||||
version="1.1"
|
version="1.1"
|
||||||
viewBox="0 0 16.933 16.933"
|
viewBox="0 0 16.933 16.933"
|
||||||
id="svg2"
|
id="svg2"
|
||||||
sodipodi:docname="system-search.svg"
|
sodipodi:docname="system-search-dark.svg"
|
||||||
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
<sodipodi:namedview
|
<sodipodi:namedview
|
||||||
@@ -24,15 +25,27 @@
|
|||||||
inkscape:deskcolor="#d1d1d1"
|
inkscape:deskcolor="#d1d1d1"
|
||||||
inkscape:zoom="4.65625"
|
inkscape:zoom="4.65625"
|
||||||
inkscape:cx="32"
|
inkscape:cx="32"
|
||||||
inkscape:cy="32"
|
inkscape:cy="31.892617"
|
||||||
inkscape:window-width="1061"
|
inkscape:window-width="1061"
|
||||||
inkscape:window-height="1020"
|
inkscape:window-height="835"
|
||||||
inkscape:window-x="0"
|
inkscape:window-x="0"
|
||||||
inkscape:window-y="0"
|
inkscape:window-y="0"
|
||||||
inkscape:window-maximized="1"
|
inkscape:window-maximized="1"
|
||||||
inkscape:current-layer="g2" />
|
inkscape:current-layer="g2" />
|
||||||
<defs
|
<defs
|
||||||
id="defs2">
|
id="defs2">
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient1"
|
||||||
|
inkscape:collect="always">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#565757;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop3" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#4c4f52;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4" />
|
||||||
|
</linearGradient>
|
||||||
<linearGradient
|
<linearGradient
|
||||||
id="linearGradient919"
|
id="linearGradient919"
|
||||||
x1="4.3106"
|
x1="4.3106"
|
||||||
@@ -52,6 +65,15 @@
|
|||||||
id="stop2"
|
id="stop2"
|
||||||
style="stop-color:#d7dcdf;stop-opacity:1;" />
|
style="stop-color:#d7dcdf;stop-opacity:1;" />
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient1"
|
||||||
|
id="linearGradient4"
|
||||||
|
x1="-7.2925777"
|
||||||
|
y1="11.283"
|
||||||
|
x2="5.189723"
|
||||||
|
y2="11.283"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
</defs>
|
</defs>
|
||||||
<g
|
<g
|
||||||
transform="translate(16.148 .19097)"
|
transform="translate(16.148 .19097)"
|
||||||
@@ -77,6 +99,6 @@
|
|||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-width="1.77822"
|
stroke-width="1.77822"
|
||||||
id="circle2"
|
id="circle2"
|
||||||
style="fill:#4f4f4f;fill-opacity:1;stroke:url(#linearGradient919)" />
|
style="fill:url(#linearGradient4);fill-opacity:1;stroke:url(#linearGradient919)" />
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1,132 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="63.999989"
|
||||||
|
height="61.62962"
|
||||||
|
viewBox="0 0 26.999999 26"
|
||||||
|
fill="none"
|
||||||
|
version="1.1"
|
||||||
|
id="svg3"
|
||||||
|
sodipodi:docname="task-view-dark-pressed.svg"
|
||||||
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview3"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:zoom="6.0349946"
|
||||||
|
inkscape:cx="32.228695"
|
||||||
|
inkscape:cy="33.305746"
|
||||||
|
inkscape:window-width="1331"
|
||||||
|
inkscape:window-height="1020"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="g3" />
|
||||||
|
<g
|
||||||
|
id="g3"
|
||||||
|
transform="translate(0.03879728,0.03736111)">
|
||||||
|
<g
|
||||||
|
id="g4"
|
||||||
|
transform="translate(-1.6875003,2.5312505)">
|
||||||
|
<rect
|
||||||
|
opacity="0.9"
|
||||||
|
x="9.4441719"
|
||||||
|
width="17.938911"
|
||||||
|
height="15.248073"
|
||||||
|
rx="0.89694548"
|
||||||
|
fill="#ffffff"
|
||||||
|
id="rect1"
|
||||||
|
y="0.8962484"
|
||||||
|
style="fill:url(#linearGradient4);fill-opacity:1;stroke:#e2e2e2;stroke-width:0.179719;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
transform="translate(-2.3652457,0.93944352)" />
|
||||||
|
<rect
|
||||||
|
y="3.8563478"
|
||||||
|
width="17.953642"
|
||||||
|
height="15.260596"
|
||||||
|
rx="0.89768213"
|
||||||
|
fill="url(#paint0_linear_505_17)"
|
||||||
|
id="rect2"
|
||||||
|
x="5.1897082"
|
||||||
|
style="mix-blend-mode:exclusion;fill:url(#paint0_linear_505_17-3);stroke-width:0.89775;stroke-dasharray:none" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g1"
|
||||||
|
transform="translate(-2.3652457,0.93944351)">
|
||||||
|
<g
|
||||||
|
style="mix-blend-mode:exclusion;stroke-width:1.00007574;stroke-dasharray:none"
|
||||||
|
id="g2"
|
||||||
|
transform="matrix(0.89768215,0,0,0.89768215,4.1799533,-0.09973431)" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<defs
|
||||||
|
id="defs3">
|
||||||
|
<linearGradient
|
||||||
|
id="paint0_linear_505_17"
|
||||||
|
x1="-2.75374e-08"
|
||||||
|
y1="9.2399397"
|
||||||
|
x2="18.808399"
|
||||||
|
y2="26.838499"
|
||||||
|
gradientUnits="userSpaceOnUse">
|
||||||
|
<stop
|
||||||
|
stop-color="#717171"
|
||||||
|
id="stop2"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#717171;stop-opacity:0.73333335;" />
|
||||||
|
<stop
|
||||||
|
offset="1"
|
||||||
|
stop-color="#4F4F4F"
|
||||||
|
id="stop3"
|
||||||
|
style="stop-color:#4f4f4f;stop-opacity:0.73333335;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="paint0_linear_505_17-3"
|
||||||
|
x1="-2.75374e-08"
|
||||||
|
y1="9.2399397"
|
||||||
|
x2="18.808399"
|
||||||
|
y2="26.838499"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.89768213,0,0,0.89768213,5.189708,-4.2227915)">
|
||||||
|
<stop
|
||||||
|
stop-color="#717171"
|
||||||
|
id="stop2-6"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#717171;stop-opacity:0.60000002;" />
|
||||||
|
<stop
|
||||||
|
offset="1"
|
||||||
|
stop-color="#4F4F4F"
|
||||||
|
id="stop3-7"
|
||||||
|
style="stop-color:#565656;stop-opacity:0.60000002;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient1"
|
||||||
|
id="linearGradient4"
|
||||||
|
x1="7.1907158"
|
||||||
|
y1="8.3216944"
|
||||||
|
x2="24.995911"
|
||||||
|
y2="10.507897"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(2.3203156,-0.89451377)" />
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient1"
|
||||||
|
inkscape:collect="always">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop1" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#e6e6e6;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.9 KiB |
@@ -0,0 +1,108 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="63.999989"
|
||||||
|
height="61.62962"
|
||||||
|
viewBox="0 0 26.999999 26"
|
||||||
|
fill="none"
|
||||||
|
version="1.1"
|
||||||
|
id="svg3"
|
||||||
|
sodipodi:docname="task-view-checked-light.svg"
|
||||||
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview3"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:zoom="4.7640337"
|
||||||
|
inkscape:cx="21.200522"
|
||||||
|
inkscape:cy="37.573202"
|
||||||
|
inkscape:window-width="1238"
|
||||||
|
inkscape:window-height="612"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="g3" />
|
||||||
|
<g
|
||||||
|
id="g3"
|
||||||
|
transform="translate(0.03879728,0.03736111)">
|
||||||
|
<g
|
||||||
|
id="g1"
|
||||||
|
transform="translate(-1.7324301,2.5761801)">
|
||||||
|
<g
|
||||||
|
style="mix-blend-mode:exclusion;stroke-width:0.999982;stroke-dasharray:none"
|
||||||
|
id="g2"
|
||||||
|
transform="matrix(0.89768215,0,0,0.89768215,5.2346381,-4.2677212)">
|
||||||
|
<rect
|
||||||
|
y="9"
|
||||||
|
width="20"
|
||||||
|
height="17"
|
||||||
|
rx="1"
|
||||||
|
fill="url(#paint0_linear_505_17)"
|
||||||
|
id="rect2"
|
||||||
|
x="0"
|
||||||
|
style="fill:url(#paint0_linear_505_17);stroke-width:0.999982;stroke-dasharray:none" />
|
||||||
|
</g>
|
||||||
|
<rect
|
||||||
|
opacity="0.9"
|
||||||
|
x="7.1238561"
|
||||||
|
width="17.938911"
|
||||||
|
height="15.248073"
|
||||||
|
rx="0.89694548"
|
||||||
|
fill="#ffffff"
|
||||||
|
id="rect1"
|
||||||
|
y="1.7907622"
|
||||||
|
style="fill:url(#linearGradient4);fill-opacity:1;stroke:#d4d4d4;stroke-width:0.179719;stroke-dasharray:none;stroke-opacity:1" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<defs
|
||||||
|
id="defs3">
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient1"
|
||||||
|
inkscape:collect="always">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:0.80000001;"
|
||||||
|
offset="0"
|
||||||
|
id="stop1" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#e6e6e6;stop-opacity:0.80000001;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="paint0_linear_505_17"
|
||||||
|
x1="-2.75374e-08"
|
||||||
|
y1="9.2399397"
|
||||||
|
x2="18.808399"
|
||||||
|
y2="26.838499"
|
||||||
|
gradientUnits="userSpaceOnUse">
|
||||||
|
<stop
|
||||||
|
stop-color="#717171"
|
||||||
|
id="stop2"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#464543;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
offset="1"
|
||||||
|
stop-color="#4F4F4F"
|
||||||
|
id="stop3"
|
||||||
|
style="stop-color:#1f1f1f;stop-opacity:1;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient1"
|
||||||
|
id="linearGradient4"
|
||||||
|
x1="7.1729918"
|
||||||
|
y1="8.4772339"
|
||||||
|
x2="25.013634"
|
||||||
|
y2="10.352362"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.1 KiB |
@@ -3,6 +3,7 @@ pragma ComponentBehavior: Bound
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
|
import qs.modules.common.functions
|
||||||
|
|
||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
@@ -147,6 +148,7 @@ Singleton {
|
|||||||
property string networkEthernet: "kcmshell6 kcm_networkmanagement"
|
property string networkEthernet: "kcmshell6 kcm_networkmanagement"
|
||||||
property string taskManager: "plasma-systemmonitor --page-name Processes"
|
property string taskManager: "plasma-systemmonitor --page-name Processes"
|
||||||
property string terminal: "kitty -1" // This is only for shell actions
|
property string terminal: "kitty -1" // This is only for shell actions
|
||||||
|
property string update: "kitty -1 --hold=yes fish -i -c 'sudo pacman -Syu'"
|
||||||
property string volumeMixer: `~/.config/hypr/hyprland/scripts/launch_first_available.sh "pavucontrol-qt" "pavucontrol"`
|
property string volumeMixer: `~/.config/hypr/hyprland/scripts/launch_first_available.sh "pavucontrol-qt" "pavucontrol"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +160,8 @@ Singleton {
|
|||||||
property string placementStrategy: "leastBusy" // "free", "leastBusy", "mostBusy"
|
property string placementStrategy: "leastBusy" // "free", "leastBusy", "mostBusy"
|
||||||
property real x: 100
|
property real x: 100
|
||||||
property real y: 100
|
property real y: 100
|
||||||
property string style: "cookie" // Options: "cookie", "digital"
|
property string style: "cookie" // Options: "cookie", "digital"
|
||||||
|
property string styleLocked: "cookie" // Options: "cookie", "digital"
|
||||||
property JsonObject cookie: JsonObject {
|
property JsonObject cookie: JsonObject {
|
||||||
property bool aiStyling: false
|
property bool aiStyling: false
|
||||||
property int sides: 14
|
property int sides: 14
|
||||||
@@ -236,13 +239,6 @@ Singleton {
|
|||||||
property bool showPerformanceProfileToggle: false
|
property bool showPerformanceProfileToggle: false
|
||||||
property bool showScreenRecord: false
|
property bool showScreenRecord: false
|
||||||
}
|
}
|
||||||
property JsonObject tray: JsonObject {
|
|
||||||
property bool monochromeIcons: true
|
|
||||||
property bool showItemId: false
|
|
||||||
property bool invertPinnedItems: true // Makes the below a whitelist for the tray and blacklist for the pinned area
|
|
||||||
property list<string> pinnedItems: [ ]
|
|
||||||
property bool filterPassive: true
|
|
||||||
}
|
|
||||||
property JsonObject workspaces: JsonObject {
|
property JsonObject workspaces: JsonObject {
|
||||||
property bool monochromeIcons: true
|
property bool monochromeIcons: true
|
||||||
property int shown: 10
|
property int shown: 10
|
||||||
@@ -264,6 +260,9 @@ Singleton {
|
|||||||
property bool showUnreadCount: false
|
property bool showUnreadCount: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
property JsonObject tooltips: JsonObject {
|
||||||
|
property bool clickToShow: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
property JsonObject battery: JsonObject {
|
property JsonObject battery: JsonObject {
|
||||||
@@ -426,6 +425,14 @@ Singleton {
|
|||||||
property int historyLength: 60
|
property int historyLength: 60
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property JsonObject tray: JsonObject {
|
||||||
|
property bool monochromeIcons: true
|
||||||
|
property bool showItemId: false
|
||||||
|
property bool invertPinnedItems: true // Makes the below a whitelist for the tray and blacklist for the pinned area
|
||||||
|
property list<var> pinnedItems: [ "Fcitx" ]
|
||||||
|
property bool filterPassive: true
|
||||||
|
}
|
||||||
|
|
||||||
property JsonObject musicRecognition: JsonObject {
|
property JsonObject musicRecognition: JsonObject {
|
||||||
property int timeout: 16
|
property int timeout: 16
|
||||||
property int interval: 4
|
property int interval: 4
|
||||||
@@ -532,6 +539,12 @@ Singleton {
|
|||||||
}
|
}
|
||||||
property bool secondPrecision: false
|
property bool secondPrecision: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property JsonObject updates: JsonObject {
|
||||||
|
property int checkInterval: 120 // minutes
|
||||||
|
property int adviseUpdateThreshold: 75 // packages
|
||||||
|
property int stronglyAdviseUpdateThreshold: 200 // packages
|
||||||
|
}
|
||||||
|
|
||||||
property JsonObject wallpaperSelector: JsonObject {
|
property JsonObject wallpaperSelector: JsonObject {
|
||||||
property bool useSystemFileDialog: false
|
property bool useSystemFileDialog: false
|
||||||
@@ -559,6 +572,10 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
property JsonObject waffles: JsonObject {
|
property JsonObject waffles: JsonObject {
|
||||||
|
// Animations on Windoes are kinda janky. Set the following to
|
||||||
|
// false will make (some) stuff also be like that for accuracy.
|
||||||
|
// Example: the right-click menu of the Start button
|
||||||
|
property bool smootherAnimations: true
|
||||||
property JsonObject bar: JsonObject {
|
property JsonObject bar: JsonObject {
|
||||||
property bool bottom: true
|
property bool bottom: true
|
||||||
property bool leftAlignApps: false
|
property bool leftAlignApps: false
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ Singleton {
|
|||||||
property string shellConfig: FileUtils.trimFileProtocol(`${Directories.config}/illogical-impulse`)
|
property string shellConfig: FileUtils.trimFileProtocol(`${Directories.config}/illogical-impulse`)
|
||||||
property string shellConfigName: "config.json"
|
property string shellConfigName: "config.json"
|
||||||
property string shellConfigPath: `${Directories.shellConfig}/${Directories.shellConfigName}`
|
property string shellConfigPath: `${Directories.shellConfig}/${Directories.shellConfigName}`
|
||||||
property string todoPath: FileUtils.trimFileProtocol(`${Directories.state}/user/todo.json`)
|
property string todoPath: FileUtils.trimFileProtocol(`${Directories.state}/user/todo.json`)
|
||||||
|
property string notesPath: FileUtils.trimFileProtocol(`${Directories.state}/user/notes.txt`)
|
||||||
|
property string conflictCachePath: FileUtils.trimFileProtocol(`${Directories.cache}/conflict-killer`)
|
||||||
property string notificationsPath: FileUtils.trimFileProtocol(`${Directories.cache}/notifications/notifications.json`)
|
property string notificationsPath: FileUtils.trimFileProtocol(`${Directories.cache}/notifications/notifications.json`)
|
||||||
property string generatedMaterialThemePath: FileUtils.trimFileProtocol(`${Directories.state}/user/generated/colors.json`)
|
property string generatedMaterialThemePath: FileUtils.trimFileProtocol(`${Directories.state}/user/generated/colors.json`)
|
||||||
property string generatedWallpaperCategoryPath: FileUtils.trimFileProtocol(`${Directories.state}/user/generated/wallpaper/category.txt`)
|
property string generatedWallpaperCategoryPath: FileUtils.trimFileProtocol(`${Directories.state}/user/generated/wallpaper/category.txt`)
|
||||||
|
|||||||
@@ -131,6 +131,14 @@ Singleton {
|
|||||||
property real height: 600
|
property real height: 600
|
||||||
property int tabIndex: 0
|
property int tabIndex: 0
|
||||||
}
|
}
|
||||||
|
property JsonObject notes: JsonObject {
|
||||||
|
property bool pinned: false
|
||||||
|
property bool clickthrough: true
|
||||||
|
property real x: 1400
|
||||||
|
property real y: 42
|
||||||
|
property real width: 460
|
||||||
|
property real height: 330
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
property JsonObject timer: JsonObject {
|
property JsonObject timer: JsonObject {
|
||||||
|
|||||||
@@ -285,4 +285,14 @@ Singleton {
|
|||||||
}
|
}
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toTitleCase(str) {
|
||||||
|
// Replace "-" and "_" with space, then capitalize each word
|
||||||
|
return str.replace(/[-_]/g, " ").replace(
|
||||||
|
/\w\S*/g,
|
||||||
|
function(txt) {
|
||||||
|
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,13 @@ import qs.modules.common.widgets
|
|||||||
Loader {
|
Loader {
|
||||||
id: root
|
id: root
|
||||||
property bool shown: true
|
property bool shown: true
|
||||||
|
property alias fade: opacityBehavior.enabled
|
||||||
opacity: shown ? 1 : 0
|
opacity: shown ? 1 : 0
|
||||||
visible: opacity > 0
|
visible: opacity > 0
|
||||||
active: opacity > 0
|
active: opacity > 0
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
|
id: opacityBehavior
|
||||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,10 +18,9 @@ StyledListView { // Scrollable window
|
|||||||
required property int index
|
required property int index
|
||||||
required property var modelData
|
required property var modelData
|
||||||
popup: root.popup
|
popup: root.popup
|
||||||
anchors.left: parent?.left
|
width: ListView.view.width // https://doc.qt.io/qt-6/qml-qtquick-listview.html
|
||||||
anchors.right: parent?.right
|
|
||||||
notificationGroup: popup ?
|
notificationGroup: popup ?
|
||||||
Notifications.popupGroupsByAppName[modelData] :
|
Notifications.popupGroupsByAppName[modelData] :
|
||||||
Notifications.groupsByAppName[modelData]
|
Notifications.groupsByAppName[modelData]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ Item {
|
|||||||
property real horizontalPadding: 10
|
property real horizontalPadding: 10
|
||||||
property real verticalPadding: 5
|
property real verticalPadding: 5
|
||||||
|
|
||||||
|
function updateAnchor() {
|
||||||
|
tooltipLoader.item?.anchor.updateAnchor();
|
||||||
|
}
|
||||||
|
|
||||||
readonly property bool internalVisibleCondition: (extraVisibleCondition && (parent.hovered === undefined || parent?.hovered)) || alternativeVisibleCondition
|
readonly property bool internalVisibleCondition: (extraVisibleCondition && (parent.hovered === undefined || parent?.hovered)) || alternativeVisibleCondition
|
||||||
property var anchorEdges: Edges.Top
|
property var anchorEdges: Edges.Top
|
||||||
property var anchorGravity: anchorEdges
|
property var anchorGravity: anchorEdges
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ TextArea {
|
|||||||
selectedTextColor: Appearance.m3colors.m3onSecondaryContainer
|
selectedTextColor: Appearance.m3colors.m3onSecondaryContainer
|
||||||
selectionColor: Appearance.colors.colSecondaryContainer
|
selectionColor: Appearance.colors.colSecondaryContainer
|
||||||
placeholderTextColor: Appearance.m3colors.m3outline
|
placeholderTextColor: Appearance.m3colors.m3outline
|
||||||
|
color: Appearance.colors.colOnLayer0
|
||||||
font {
|
font {
|
||||||
family: Appearance.font.family.main
|
family: Appearance.font.family.main
|
||||||
pixelSize: Appearance?.font.pixelSize.small ?? 15
|
pixelSize: Appearance?.font.pixelSize.small ?? 15
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import qs.services
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import Qt.labs.synchronizer
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ AbstractBackgroundWidget {
|
|||||||
implicitHeight: contentColumn.implicitHeight
|
implicitHeight: contentColumn.implicitHeight
|
||||||
implicitWidth: contentColumn.implicitWidth
|
implicitWidth: contentColumn.implicitWidth
|
||||||
|
|
||||||
readonly property string clockStyle: Config.options.background.widgets.clock.style
|
readonly property string clockStyle: GlobalStates.screenLocked ? Config.options.background.widgets.clock.styleLocked : Config.options.background.widgets.clock.style
|
||||||
readonly property bool forceCenter: (GlobalStates.screenLocked && Config.options.lock.centerClock)
|
readonly property bool forceCenter: (GlobalStates.screenLocked && Config.options.lock.centerClock)
|
||||||
readonly property bool shouldShow: (!Config.options.background.widgets.clock.showOnlyWhenLocked || GlobalStates.screenLocked)
|
readonly property bool shouldShow: (!Config.options.background.widgets.clock.showOnlyWhenLocked || GlobalStates.screenLocked)
|
||||||
property bool wallpaperSafetyTriggered: false
|
property bool wallpaperSafetyTriggered: false
|
||||||
@@ -44,6 +44,7 @@ AbstractBackgroundWidget {
|
|||||||
id: cookieClockLoader
|
id: cookieClockLoader
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
shown: root.clockStyle === "cookie" && (root.shouldShow)
|
shown: root.clockStyle === "cookie" && (root.shouldShow)
|
||||||
|
fade: false
|
||||||
sourceComponent: Column {
|
sourceComponent: Column {
|
||||||
spacing: 10
|
spacing: 10
|
||||||
CookieClock {
|
CookieClock {
|
||||||
@@ -61,6 +62,7 @@ AbstractBackgroundWidget {
|
|||||||
id: digitalClockLoader
|
id: digitalClockLoader
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
shown: root.clockStyle === "digital" && (root.shouldShow)
|
shown: root.clockStyle === "digital" && (root.shouldShow)
|
||||||
|
fade: false
|
||||||
sourceComponent: ColumnLayout {
|
sourceComponent: ColumnLayout {
|
||||||
id: clockColumn
|
id: clockColumn
|
||||||
spacing: 6
|
spacing: 6
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ MouseArea {
|
|||||||
implicitWidth: batteryProgress.implicitWidth
|
implicitWidth: batteryProgress.implicitWidth
|
||||||
implicitHeight: Appearance.sizes.barHeight
|
implicitHeight: Appearance.sizes.barHeight
|
||||||
|
|
||||||
hoverEnabled: true
|
hoverEnabled: !Config.options.bar.tooltips.clickToShow
|
||||||
|
|
||||||
ClippedProgressBar {
|
ClippedProgressBar {
|
||||||
id: batteryProgress
|
id: batteryProgress
|
||||||
|
|||||||
@@ -40,8 +40,7 @@ Item {
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: !Config.options.bar.tooltips.clickToShow
|
||||||
acceptedButtons: Qt.NoButton
|
|
||||||
|
|
||||||
ClockWidgetPopup {
|
ClockWidgetPopup {
|
||||||
hoverTarget: mouseArea
|
hoverTarget: mouseArea
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ MouseArea {
|
|||||||
property bool alwaysShowAllResources: false
|
property bool alwaysShowAllResources: false
|
||||||
implicitWidth: rowLayout.implicitWidth + rowLayout.anchors.leftMargin + rowLayout.anchors.rightMargin
|
implicitWidth: rowLayout.implicitWidth + rowLayout.anchors.leftMargin + rowLayout.anchors.rightMargin
|
||||||
implicitHeight: Appearance.sizes.barHeight
|
implicitHeight: Appearance.sizes.barHeight
|
||||||
hoverEnabled: true
|
hoverEnabled: !Config.options.bar.tooltips.clickToShow
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: rowLayout
|
id: rowLayout
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import qs.modules.common
|
|
||||||
import qs.modules.common.widgets
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
import Quickshell.Services.SystemTray
|
import Quickshell.Services.SystemTray
|
||||||
|
import qs.services
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.widgets
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
@@ -17,13 +18,8 @@ Item {
|
|||||||
property bool showOverflowMenu: true
|
property bool showOverflowMenu: true
|
||||||
property var activeMenu: null
|
property var activeMenu: null
|
||||||
|
|
||||||
property bool smartTray: Config.options.bar.tray.filterPassive
|
property list<var> pinnedItems: TrayService.pinnedItems
|
||||||
property list<var> itemsInUserList: SystemTray.items.values.filter(i => (Config.options.bar.tray.pinnedItems.includes(i.id) && (!smartTray || i.status !== Status.Passive)))
|
property list<var> unpinnedItems: TrayService.unpinnedItems
|
||||||
property list<var> itemsNotInUserList: SystemTray.items.values.filter(i => (!Config.options.bar.tray.pinnedItems.includes(i.id) && (!smartTray || i.status !== Status.Passive)))
|
|
||||||
|
|
||||||
property bool invertPins: Config.options.bar.tray.invertPinnedItems
|
|
||||||
property list<var> pinnedItems: invertPins ? itemsNotInUserList : itemsInUserList
|
|
||||||
property list<var> unpinnedItems: invertPins ? itemsInUserList : itemsNotInUserList
|
|
||||||
onUnpinnedItemsChanged: {
|
onUnpinnedItemsChanged: {
|
||||||
if (unpinnedItems.length == 0) root.closeOverflowMenu();
|
if (unpinnedItems.length == 0) root.closeOverflowMenu();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import qs.modules.common
|
|
||||||
import qs.modules.common.widgets
|
|
||||||
import qs.modules.common.functions
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Services.SystemTray
|
import Quickshell.Services.SystemTray
|
||||||
import Quickshell.Widgets
|
import Quickshell.Widgets
|
||||||
import Qt5Compat.GraphicalEffects
|
import Qt5Compat.GraphicalEffects
|
||||||
|
import qs.services
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.widgets
|
||||||
|
import qs.modules.common.functions
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: root
|
id: root
|
||||||
@@ -31,10 +32,7 @@ MouseArea {
|
|||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
}
|
}
|
||||||
onEntered: {
|
onEntered: {
|
||||||
tooltip.text = item.tooltipTitle.length > 0 ? item.tooltipTitle
|
tooltip.text = TrayService.getTooltipForItem(root.item);
|
||||||
: (item.title.length > 0 ? item.title : item.id);
|
|
||||||
if (item.tooltipDescription.length > 0) tooltip.text += " • " + item.tooltipDescription;
|
|
||||||
if (Config.options.bar.tray.showItemId) tooltip.text += "\n[" + item.id + "]";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
@@ -65,7 +63,7 @@ MouseArea {
|
|||||||
|
|
||||||
IconImage {
|
IconImage {
|
||||||
id: trayIcon
|
id: trayIcon
|
||||||
visible: !Config.options.bar.tray.monochromeIcons
|
visible: !Config.options.tray.monochromeIcons
|
||||||
source: root.item.icon
|
source: root.item.icon
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -73,7 +71,7 @@ MouseArea {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
active: Config.options.bar.tray.monochromeIcons
|
active: Config.options.tray.monochromeIcons
|
||||||
anchors.fill: trayIcon
|
anchors.fill: trayIcon
|
||||||
sourceComponent: Item {
|
sourceComponent: Item {
|
||||||
Desaturate {
|
Desaturate {
|
||||||
|
|||||||
@@ -13,15 +13,19 @@ MouseArea {
|
|||||||
implicitWidth: rowLayout.implicitWidth + 10 * 2
|
implicitWidth: rowLayout.implicitWidth + 10 * 2
|
||||||
implicitHeight: Appearance.sizes.barHeight
|
implicitHeight: Appearance.sizes.barHeight
|
||||||
|
|
||||||
hoverEnabled: true
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
hoverEnabled: !Config.options.bar.tooltips.clickToShow
|
||||||
|
|
||||||
onPressed: {
|
onPressed: {
|
||||||
Weather.getData();
|
if (mouse.button === Qt.RightButton) {
|
||||||
Quickshell.execDetached(["notify-send",
|
Weather.getData();
|
||||||
Translation.tr("Weather"),
|
Quickshell.execDetached(["notify-send",
|
||||||
Translation.tr("Refreshing (manually triggered)")
|
Translation.tr("Weather"),
|
||||||
, "-a", "Shell"
|
Translation.tr("Refreshing (manually triggered)")
|
||||||
])
|
, "-a", "Shell"
|
||||||
|
])
|
||||||
|
mouse.accepted = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import QtQuick
|
|||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import Qt5Compat.GraphicalEffects
|
import Qt5Compat.GraphicalEffects
|
||||||
import Qt.labs.synchronizer
|
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
|
|||||||
@@ -67,11 +67,7 @@ DockButton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
altAction: () => {
|
altAction: () => {
|
||||||
if (Config.options.dock.pinnedApps.indexOf(appToplevel.appId) !== -1) {
|
TaskbarApps.togglePin(appToplevel.appId);
|
||||||
Config.options.dock.pinnedApps = Config.options.dock.pinnedApps.filter(id => id !== appToplevel.appId)
|
|
||||||
} else {
|
|
||||||
Config.options.dock.pinnedApps = Config.options.dock.pinnedApps.concat([appToplevel.appId])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
contentItem: Loader {
|
contentItem: Loader {
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ Scope {
|
|||||||
exclusionMode: ExclusionMode.Ignore
|
exclusionMode: ExclusionMode.Ignore
|
||||||
WlrLayershell.namespace: "quickshell:overlay"
|
WlrLayershell.namespace: "quickshell:overlay"
|
||||||
WlrLayershell.layer: WlrLayer.Overlay
|
WlrLayershell.layer: WlrLayer.Overlay
|
||||||
WlrLayershell.keyboardFocus: GlobalStates.overlayOpen ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
|
// Use OnDemand for pinned widgets to allow focus switching with mouse clicks
|
||||||
|
WlrLayershell.keyboardFocus: GlobalStates.overlayOpen ? WlrKeyboardFocus.Exclusive : (OverlayContext.clickableWidgets.length > 0 ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None)
|
||||||
visible: true
|
visible: true
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ Singleton {
|
|||||||
{ identifier: "floatingImage", materialSymbol: "imagesmode" },
|
{ identifier: "floatingImage", materialSymbol: "imagesmode" },
|
||||||
{ identifier: "recorder", materialSymbol: "screen_record" },
|
{ identifier: "recorder", materialSymbol: "screen_record" },
|
||||||
{ identifier: "resources", materialSymbol: "browse_activity" },
|
{ identifier: "resources", materialSymbol: "browse_activity" },
|
||||||
|
{ identifier: "notes", materialSymbol: "note_stack" },
|
||||||
{ identifier: "volumeMixer", materialSymbol: "volume_up" },
|
{ identifier: "volumeMixer", materialSymbol: "volume_up" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,11 @@ import Quickshell
|
|||||||
import Quickshell.Bluetooth
|
import Quickshell.Bluetooth
|
||||||
import qs.modules.ii.overlay.crosshair
|
import qs.modules.ii.overlay.crosshair
|
||||||
import qs.modules.ii.overlay.volumeMixer
|
import qs.modules.ii.overlay.volumeMixer
|
||||||
|
import qs.modules.ii.overlay.floatingImage
|
||||||
import qs.modules.ii.overlay.fpsLimiter
|
import qs.modules.ii.overlay.fpsLimiter
|
||||||
import qs.modules.ii.overlay.recorder
|
import qs.modules.ii.overlay.recorder
|
||||||
import qs.modules.ii.overlay.resources
|
import qs.modules.ii.overlay.resources
|
||||||
import qs.modules.ii.overlay.floatingImage
|
import qs.modules.ii.overlay.notes
|
||||||
|
|
||||||
DelegateChooser {
|
DelegateChooser {
|
||||||
id: root
|
id: root
|
||||||
@@ -22,5 +23,6 @@ DelegateChooser {
|
|||||||
DelegateChoice { roleValue: "fpsLimiter"; FpsLimiter {} }
|
DelegateChoice { roleValue: "fpsLimiter"; FpsLimiter {} }
|
||||||
DelegateChoice { roleValue: "recorder"; Recorder {} }
|
DelegateChoice { roleValue: "recorder"; Recorder {} }
|
||||||
DelegateChoice { roleValue: "resources"; Resources {} }
|
DelegateChoice { roleValue: "resources"; Resources {} }
|
||||||
|
DelegateChoice { roleValue: "notes"; Notes {} }
|
||||||
DelegateChoice { roleValue: "volumeMixer"; VolumeMixer {} }
|
DelegateChoice { roleValue: "volumeMixer"; VolumeMixer {} }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import qs.services
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.ii.overlay
|
||||||
|
|
||||||
|
StyledOverlayWidget {
|
||||||
|
id: root
|
||||||
|
title: Translation.tr("Notes")
|
||||||
|
showCenterButton: true
|
||||||
|
|
||||||
|
contentItem: NotesContent {
|
||||||
|
radius: root.contentRadius
|
||||||
|
isClickthrough: root.clickthrough
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,292 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import qs
|
||||||
|
import qs.services
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.widgets
|
||||||
|
import qs.modules.ii.overlay
|
||||||
|
|
||||||
|
OverlayBackground {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property alias content: textInput.text
|
||||||
|
property bool pendingReload: false
|
||||||
|
property var copyListEntries: []
|
||||||
|
property string lastParsedCopylistText: ""
|
||||||
|
property var parsedCopylistLines: []
|
||||||
|
property bool isClickthrough: false
|
||||||
|
property real maxCopyButtonSize: 20
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
noteFile.reload();
|
||||||
|
updateCopyListEntries();
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveContent() {
|
||||||
|
if (!textInput)
|
||||||
|
return;
|
||||||
|
noteFile.setText(root.content);
|
||||||
|
}
|
||||||
|
|
||||||
|
function focusAtEnd() {
|
||||||
|
if (!textInput)
|
||||||
|
return;
|
||||||
|
textInput.forceActiveFocus();
|
||||||
|
const endPos = root.content.length;
|
||||||
|
applySelection(endPos, endPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
function applySelection(cursorPos, anchorPos) {
|
||||||
|
if (!textInput)
|
||||||
|
return;
|
||||||
|
const textLength = root.content.length;
|
||||||
|
const cursor = Math.max(0, Math.min(cursorPos, textLength));
|
||||||
|
const anchor = Math.max(0, Math.min(anchorPos, textLength));
|
||||||
|
textInput.select(anchor, cursor);
|
||||||
|
if (cursor === anchor)
|
||||||
|
textInput.deselect();
|
||||||
|
}
|
||||||
|
|
||||||
|
function scheduleCopylistUpdate(immediate = false) {
|
||||||
|
if (!textInput)
|
||||||
|
return;
|
||||||
|
if (immediate) {
|
||||||
|
copyListDebounce?.stop();
|
||||||
|
updateCopyListEntries();
|
||||||
|
} else {
|
||||||
|
copyListDebounce.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCopyListEntries() {
|
||||||
|
if (!textInput)
|
||||||
|
return;
|
||||||
|
const textValue = root.content;
|
||||||
|
if (!textValue || textValue.length === 0) {
|
||||||
|
lastParsedCopylistText = "";
|
||||||
|
parsedCopylistLines = [];
|
||||||
|
root.copyListEntries = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (textValue !== lastParsedCopylistText) {
|
||||||
|
const lineRegex = /(.*?)(\r?\n|$)/g;
|
||||||
|
let match = null;
|
||||||
|
const parsed = [];
|
||||||
|
while ((match = lineRegex.exec(textValue)) !== null) {
|
||||||
|
const lineText = match[1];
|
||||||
|
const newlineText = match[2];
|
||||||
|
const lineStart = match.index;
|
||||||
|
const lineEnd = lineStart + lineText.length;
|
||||||
|
const bulletMatch = lineText.match(/^\s*-\s+(.*\S)\s*$/);
|
||||||
|
if (bulletMatch) {
|
||||||
|
parsed.push({
|
||||||
|
content: bulletMatch[1].trim(),
|
||||||
|
start: lineStart,
|
||||||
|
end: lineEnd
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (newlineText === "")
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lastParsedCopylistText = textValue;
|
||||||
|
parsedCopylistLines = parsed;
|
||||||
|
if (parsed.length === 0) {
|
||||||
|
root.copyListEntries = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCopylistPositions();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCopylistPositions() {
|
||||||
|
if (!textInput || parsedCopylistLines.length === 0)
|
||||||
|
return;
|
||||||
|
const rawSelectionStart = textInput.selectionStart;
|
||||||
|
const rawSelectionEnd = textInput.selectionEnd;
|
||||||
|
const selectionStart = rawSelectionStart === -1 ? textInput.cursorPosition : rawSelectionStart;
|
||||||
|
const selectionEnd = rawSelectionEnd === -1 ? textInput.cursorPosition : rawSelectionEnd;
|
||||||
|
const rangeStart = Math.min(selectionStart, selectionEnd);
|
||||||
|
const rangeEnd = Math.max(selectionStart, selectionEnd);
|
||||||
|
|
||||||
|
const entries = parsedCopylistLines.map(line => {
|
||||||
|
// Don't show copy button if line is (partially) selected
|
||||||
|
const caretIntersects = rangeEnd > line.start && rangeStart <= line.end;
|
||||||
|
if (caretIntersects)
|
||||||
|
return null;
|
||||||
|
const startRect = textInput.positionToRectangle(line.start);
|
||||||
|
let endRect = textInput.positionToRectangle(line.end);
|
||||||
|
if (!isFinite(startRect.y))
|
||||||
|
return null;
|
||||||
|
if (!isFinite(endRect.y))
|
||||||
|
endRect = startRect;
|
||||||
|
const lineBottom = endRect.y + endRect.height;
|
||||||
|
const rectHeight = Math.max(lineBottom - startRect.y, textInput.font.pixelSize + 8);
|
||||||
|
return {
|
||||||
|
content: line.content,
|
||||||
|
y: startRect.y,
|
||||||
|
height: rectHeight
|
||||||
|
};
|
||||||
|
}).filter(entry => entry !== null);
|
||||||
|
|
||||||
|
root.copyListEntries = entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
implicitWidth: 300
|
||||||
|
implicitHeight: 200
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: contentItem
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: -16
|
||||||
|
|
||||||
|
ScrollView {
|
||||||
|
id: editorScrollView
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
clip: true
|
||||||
|
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
||||||
|
onWidthChanged: root.scheduleCopylistUpdate(true)
|
||||||
|
|
||||||
|
StyledTextArea { // This has to be a direct child of ScrollView for proper scrolling
|
||||||
|
id: textInput
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
wrapMode: TextEdit.Wrap
|
||||||
|
placeholderText: Translation.tr("Write something here...\nUse '-' to create copyable bullet points, like this:\n\nSheep fricker\n- 4x Slab\n- 1x Boat\n- 4x Redstone Dust\n- 1x Sticky Piston\n- 1x End Rod\n- 4x Redstone Repeater\n- 1x Redstone Torch\n- 1x Sheep")
|
||||||
|
selectByMouse: true
|
||||||
|
persistentSelection: true
|
||||||
|
textFormat: TextEdit.PlainText
|
||||||
|
background: null
|
||||||
|
padding: 24
|
||||||
|
|
||||||
|
onTextChanged: {
|
||||||
|
if (textInput.activeFocus) {
|
||||||
|
saveDebounce.restart();
|
||||||
|
}
|
||||||
|
root.scheduleCopylistUpdate(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
onHeightChanged: root.scheduleCopylistUpdate(true)
|
||||||
|
onContentHeightChanged: root.scheduleCopylistUpdate(true)
|
||||||
|
onCursorPositionChanged: root.scheduleCopylistUpdate()
|
||||||
|
onSelectionStartChanged: root.scheduleCopylistUpdate()
|
||||||
|
onSelectionEndChanged: root.scheduleCopylistUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: root.copyListEntries.length > 0
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: ScriptModel {
|
||||||
|
values: root.copyListEntries
|
||||||
|
}
|
||||||
|
delegate: RippleButton {
|
||||||
|
id: copyButton
|
||||||
|
required property var modelData
|
||||||
|
readonly property real lineHeight: Math.min(Math.max(modelData.height, Appearance.font.pixelSize.normal + 6), root.maxCopyButtonSize)
|
||||||
|
readonly property real iconSizeLocal: Appearance.font.pixelSize.normal
|
||||||
|
readonly property real hitPadding: 6
|
||||||
|
property bool justCopied: false
|
||||||
|
|
||||||
|
implicitHeight: lineHeight
|
||||||
|
implicitWidth: lineHeight
|
||||||
|
buttonRadius: height / 2
|
||||||
|
y: modelData.y
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 10
|
||||||
|
z: 5
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: resetState
|
||||||
|
interval: 700
|
||||||
|
onTriggered: {
|
||||||
|
copyButton.justCopied = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
Quickshell.clipboardText = copyButton.modelData.content;
|
||||||
|
justCopied = true;
|
||||||
|
resetState.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Item {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
MaterialSymbol {
|
||||||
|
id: iconItem
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: copyButton.justCopied ? "check" : "content_copy"
|
||||||
|
iconSize: copyButton.iconSizeLocal
|
||||||
|
color: Appearance.colors.colOnLayer1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: statusLabel
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.margins: 16
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
|
text: saveDebounce.running ? Translation.tr("Saving...") : Translation.tr("Saved ")
|
||||||
|
color: Appearance.colors.colSubtext
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: saveDebounce
|
||||||
|
interval: 500
|
||||||
|
repeat: false
|
||||||
|
onTriggered: saveContent()
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: copyListDebounce
|
||||||
|
interval: 100
|
||||||
|
repeat: false
|
||||||
|
onTriggered: updateCopylistPositions()
|
||||||
|
}
|
||||||
|
|
||||||
|
FileView {
|
||||||
|
id: noteFile
|
||||||
|
path: Qt.resolvedUrl(Directories.notesPath)
|
||||||
|
onLoaded: {
|
||||||
|
root.content = noteFile.text();
|
||||||
|
if (root.content !== root.content) {
|
||||||
|
const previousCursor = textInput.cursorPosition;
|
||||||
|
const previousAnchor = textInput.selectionStart;
|
||||||
|
root.content = root.content;
|
||||||
|
applySelection(previousCursor, previousAnchor);
|
||||||
|
}
|
||||||
|
if (pendingReload) {
|
||||||
|
pendingReload = false;
|
||||||
|
Qt.callLater(root.focusAtEnd);
|
||||||
|
}
|
||||||
|
Qt.callLater(root.updateCopyListEntries);
|
||||||
|
}
|
||||||
|
onLoadFailed: error => {
|
||||||
|
if (error === FileViewError.FileNotFound) {
|
||||||
|
root.content = "";
|
||||||
|
noteFile.setText(root.content);
|
||||||
|
if (pendingReload) {
|
||||||
|
pendingReload = false;
|
||||||
|
Qt.callLater(root.focusAtEnd);
|
||||||
|
}
|
||||||
|
Qt.callLater(root.updateCopyListEntries);
|
||||||
|
} else {
|
||||||
|
console.log("[Overlay Notes] Error loading file: " + error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,6 @@ import QtQuick.Layouts
|
|||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
import Qt5Compat.GraphicalEffects
|
import Qt5Compat.GraphicalEffects
|
||||||
import Qt.labs.synchronizer
|
|
||||||
import qs
|
import qs
|
||||||
import qs.services
|
import qs.services
|
||||||
import qs.modules.common
|
import qs.modules.common
|
||||||
|
|||||||
@@ -167,6 +167,9 @@ Scope {
|
|||||||
function toggle() {
|
function toggle() {
|
||||||
GlobalStates.overviewOpen = !GlobalStates.overviewOpen;
|
GlobalStates.overviewOpen = !GlobalStates.overviewOpen;
|
||||||
}
|
}
|
||||||
|
function workspacesToggle() {
|
||||||
|
GlobalStates.overviewOpen = !GlobalStates.overviewOpen;
|
||||||
|
}
|
||||||
function close() {
|
function close() {
|
||||||
GlobalStates.overviewOpen = false;
|
GlobalStates.overviewOpen = false;
|
||||||
}
|
}
|
||||||
@@ -189,6 +192,14 @@ Scope {
|
|||||||
GlobalStates.overviewOpen = !GlobalStates.overviewOpen;
|
GlobalStates.overviewOpen = !GlobalStates.overviewOpen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
GlobalShortcut {
|
||||||
|
name: "overviewWorkspacesToggle"
|
||||||
|
description: "Toggles overview on press"
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
GlobalStates.overviewOpen = !GlobalStates.overviewOpen;
|
||||||
|
}
|
||||||
|
}
|
||||||
GlobalShortcut {
|
GlobalShortcut {
|
||||||
name: "overviewClose"
|
name: "overviewClose"
|
||||||
description: "Closes overview"
|
description: "Closes overview"
|
||||||
|
|||||||
@@ -285,48 +285,36 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: ScriptModel {
|
model: ScriptModel {
|
||||||
values: Array.from({ length: root.messageBlocks.length }, (msg, i) => {
|
values: root.messageBlocks
|
||||||
return ({
|
|
||||||
type: root.messageBlocks[i].type
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: DelegateChooser {
|
delegate: DelegateChooser {
|
||||||
id: messageDelegate
|
id: messageDelegate
|
||||||
role: "type"
|
role: "type"
|
||||||
|
|
||||||
DelegateChoice { roleValue: "code"; MessageCodeBlock {
|
DelegateChoice { roleValue: "code"; MessageCodeBlock {
|
||||||
required property int index
|
|
||||||
property var thisBlock: root.messageBlocks[index]
|
|
||||||
editing: root.editing
|
editing: root.editing
|
||||||
renderMarkdown: root.renderMarkdown
|
renderMarkdown: root.renderMarkdown
|
||||||
enableMouseSelection: root.enableMouseSelection
|
enableMouseSelection: root.enableMouseSelection
|
||||||
segmentContent: thisBlock.content
|
segmentContent: modelData.content
|
||||||
segmentLang: thisBlock.lang
|
segmentLang: modelData.lang
|
||||||
messageData: root.messageData
|
messageData: root.messageData
|
||||||
} }
|
} }
|
||||||
DelegateChoice { roleValue: "think"; MessageThinkBlock {
|
DelegateChoice { roleValue: "think"; MessageThinkBlock {
|
||||||
required property int index
|
|
||||||
property var thisBlock: root.messageBlocks[index]
|
|
||||||
editing: root.editing
|
editing: root.editing
|
||||||
renderMarkdown: root.renderMarkdown
|
renderMarkdown: root.renderMarkdown
|
||||||
enableMouseSelection: root.enableMouseSelection
|
enableMouseSelection: root.enableMouseSelection
|
||||||
segmentContent: thisBlock.content
|
segmentContent: modelData.content
|
||||||
messageData: root.messageData
|
messageData: root.messageData
|
||||||
done: root.messageData?.done ?? false
|
done: root.messageData?.done ?? false
|
||||||
completed: thisBlock.completed ?? false
|
completed: modelData.completed ?? false
|
||||||
} }
|
} }
|
||||||
DelegateChoice { roleValue: "text"; MessageTextBlock {
|
DelegateChoice { roleValue: "text"; MessageTextBlock {
|
||||||
required property int index
|
|
||||||
property var thisBlock: root.messageBlocks[index]
|
|
||||||
editing: root.editing
|
editing: root.editing
|
||||||
renderMarkdown: root.renderMarkdown
|
renderMarkdown: root.renderMarkdown
|
||||||
enableMouseSelection: root.enableMouseSelection
|
enableMouseSelection: root.enableMouseSelection
|
||||||
segmentContent: thisBlock.content
|
segmentContent: modelData.content
|
||||||
messageData: root.messageData
|
messageData: root.messageData
|
||||||
done: root.messageData?.done ?? false
|
done: root.messageData?.done ?? false
|
||||||
forceDisableChunkSplitting: root.messageData?.content.includes("```") ?? true
|
forceDisableChunkSplitting: root.messageData?.content.includes("```") ?? true
|
||||||
|
|||||||
@@ -156,7 +156,6 @@ Item {
|
|||||||
property bool editing: root.editing
|
property bool editing: root.editing
|
||||||
property bool renderMarkdown: root.renderMarkdown
|
property bool renderMarkdown: root.renderMarkdown
|
||||||
property bool enableMouseSelection: root.enableMouseSelection
|
property bool enableMouseSelection: root.enableMouseSelection
|
||||||
property string segmentContent: root.segmentContent
|
|
||||||
property var messageData: root.messageData
|
property var messageData: root.messageData
|
||||||
property bool done: root.done
|
property bool done: root.done
|
||||||
|
|
||||||
@@ -165,8 +164,9 @@ Item {
|
|||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
segmentContent: root.segmentContent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ AndroidQuickToggleButton {
|
|||||||
name: Translation.tr("Bluetooth")
|
name: Translation.tr("Bluetooth")
|
||||||
statusText: BluetoothStatus.firstActiveDevice?.name ?? Translation.tr("No device")
|
statusText: BluetoothStatus.firstActiveDevice?.name ?? Translation.tr("No device")
|
||||||
|
|
||||||
|
available: BluetoothStatus.available
|
||||||
toggled: BluetoothStatus.enabled
|
toggled: BluetoothStatus.enabled
|
||||||
buttonIcon: BluetoothStatus.connected ? "bluetooth_connected" : BluetoothStatus.enabled ? "bluetooth" : "bluetooth_disabled"
|
buttonIcon: BluetoothStatus.connected ? "bluetooth_connected" : BluetoothStatus.enabled ? "bluetooth" : "bluetooth_disabled"
|
||||||
mainAction: () => {
|
mainAction: () => {
|
||||||
@@ -27,4 +28,3 @@ AndroidQuickToggleButton {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ AndroidQuickToggleButton {
|
|||||||
|
|
||||||
name: Translation.tr("EasyEffects")
|
name: Translation.tr("EasyEffects")
|
||||||
|
|
||||||
|
available: EasyEffects.available
|
||||||
toggled: EasyEffects.active
|
toggled: EasyEffects.active
|
||||||
buttonIcon: "graphic_eq"
|
buttonIcon: "graphic_eq"
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ GroupButton {
|
|||||||
required property string name
|
required property string name
|
||||||
required property var mainAction
|
required property var mainAction
|
||||||
property string statusText: toggled ? Translation.tr("Active") : Translation.tr("Inactive")
|
property string statusText: toggled ? Translation.tr("Active") : Translation.tr("Inactive")
|
||||||
|
property bool available: true
|
||||||
|
|
||||||
required property real baseCellWidth
|
required property real baseCellWidth
|
||||||
required property real baseCellHeight
|
required property real baseCellHeight
|
||||||
@@ -42,6 +43,7 @@ GroupButton {
|
|||||||
|
|
||||||
signal openMenu()
|
signal openMenu()
|
||||||
|
|
||||||
|
enabled: available || editMode
|
||||||
padding: 6
|
padding: 6
|
||||||
horizontalPadding: padding
|
horizontalPadding: padding
|
||||||
verticalPadding: padding
|
verticalPadding: padding
|
||||||
@@ -52,8 +54,8 @@ GroupButton {
|
|||||||
colBackgroundToggledActive: (altAction && expandedSize) ? Appearance.colors.colLayer2Active : Appearance.colors.colPrimaryActive
|
colBackgroundToggledActive: (altAction && expandedSize) ? Appearance.colors.colLayer2Active : Appearance.colors.colPrimaryActive
|
||||||
buttonRadius: toggled ? Appearance.rounding.large : height / 2
|
buttonRadius: toggled ? Appearance.rounding.large : height / 2
|
||||||
buttonRadiusPressed: Appearance.rounding.normal
|
buttonRadiusPressed: Appearance.rounding.normal
|
||||||
property color colText: (toggled && !(altAction && expandedSize)) ? Appearance.colors.colOnPrimary : Appearance.colors.colOnLayer2
|
property color colText: (toggled && !(altAction && expandedSize) && enabled) ? Appearance.colors.colOnPrimary : ColorUtils.transparentize(Appearance.colors.colOnLayer2, enabled ? 0 : 0.7)
|
||||||
property color colIcon: expandedSize ? (root.toggled ? Appearance.colors.colOnPrimary : Appearance.colors.colOnLayer3) : colText
|
property color colIcon: expandedSize ? ((root.toggled) ? Appearance.colors.colOnPrimary : Appearance.colors.colOnLayer3) : colText
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (root.expandedSize && root.altAction) root.altAction();
|
if (root.expandedSize && root.altAction) root.altAction();
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ MouseArea {
|
|||||||
readonly property bool isLow: percentage <= Config.options.battery.low / 100
|
readonly property bool isLow: percentage <= Config.options.battery.low / 100
|
||||||
|
|
||||||
implicitHeight: batteryProgress.implicitHeight
|
implicitHeight: batteryProgress.implicitHeight
|
||||||
hoverEnabled: true
|
hoverEnabled: !Config.options.bar.tooltips.clickToShow
|
||||||
|
|
||||||
ClippedProgressBar {
|
ClippedProgressBar {
|
||||||
id: batteryProgress
|
id: batteryProgress
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ MouseArea {
|
|||||||
property bool alwaysShowAllResources: false
|
property bool alwaysShowAllResources: false
|
||||||
implicitHeight: columnLayout.implicitHeight
|
implicitHeight: columnLayout.implicitHeight
|
||||||
implicitWidth: columnLayout.implicitWidth
|
implicitWidth: columnLayout.implicitWidth
|
||||||
hoverEnabled: true
|
hoverEnabled: !Config.options.bar.tooltips.clickToShow
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: columnLayout
|
id: columnLayout
|
||||||
|
|||||||
@@ -33,8 +33,7 @@ Item {
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: !Config.options.bar.tooltips.clickToShow
|
||||||
acceptedButtons: Qt.NoButton
|
|
||||||
|
|
||||||
Bar.ClockWidgetPopup {
|
Bar.ClockWidgetPopup {
|
||||||
hoverTarget: mouseArea
|
hoverTarget: mouseArea
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ MouseArea {
|
|||||||
}
|
}
|
||||||
|
|
||||||
acceptedButtons: Qt.MiddleButton | Qt.BackButton | Qt.ForwardButton | Qt.RightButton | Qt.LeftButton
|
acceptedButtons: Qt.MiddleButton | Qt.BackButton | Qt.ForwardButton | Qt.RightButton | Qt.LeftButton
|
||||||
hoverEnabled: true
|
hoverEnabled: !Config.options.bar.tooltips.clickToShow
|
||||||
onPressed: (event) => {
|
onPressed: (event) => {
|
||||||
if (event.button === Qt.MiddleButton) {
|
if (event.button === Qt.MiddleButton) {
|
||||||
activePlayer.togglePlaying();
|
activePlayer.togglePlaying();
|
||||||
|
|||||||
@@ -55,6 +55,20 @@ ContentPage {
|
|||||||
ContentSection {
|
ContentSection {
|
||||||
icon: "clock_loader_40"
|
icon: "clock_loader_40"
|
||||||
title: Translation.tr("Widget: Clock")
|
title: Translation.tr("Widget: Clock")
|
||||||
|
id: settingsClock
|
||||||
|
|
||||||
|
function stylePresent(styleName) {
|
||||||
|
if (!Config.options.background.widgets.clock.showOnlyWhenLocked && Config.options.background.widgets.clock.style === styleName) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (Config.options.background.widgets.clock.styleLocked === styleName) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property bool digitalPresent: stylePresent("digital")
|
||||||
|
readonly property bool cookiePresent: stylePresent("cookie")
|
||||||
|
|
||||||
ConfigRow {
|
ConfigRow {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -107,6 +121,7 @@ ContentPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ContentSubsection {
|
ContentSubsection {
|
||||||
|
visible: !Config.options.background.widgets.clock.showOnlyWhenLocked
|
||||||
title: Translation.tr("Clock style")
|
title: Translation.tr("Clock style")
|
||||||
ConfigSelectionArray {
|
ConfigSelectionArray {
|
||||||
currentValue: Config.options.background.widgets.clock.style
|
currentValue: Config.options.background.widgets.clock.style
|
||||||
@@ -129,7 +144,29 @@ ContentPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ContentSubsection {
|
ContentSubsection {
|
||||||
visible: Config.options.background.widgets.clock.style === "digital"
|
title: Translation.tr("Clock style (locked)")
|
||||||
|
ConfigSelectionArray {
|
||||||
|
currentValue: Config.options.background.widgets.clock.styleLocked
|
||||||
|
onSelected: newValue => {
|
||||||
|
Config.options.background.widgets.clock.styleLocked = newValue;
|
||||||
|
}
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: Translation.tr("Digital"),
|
||||||
|
icon: "timer_10",
|
||||||
|
value: "digital"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: Translation.tr("Cookie"),
|
||||||
|
icon: "cookie",
|
||||||
|
value: "cookie"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentSubsection {
|
||||||
|
visible: settingsClock.digitalPresent
|
||||||
title: Translation.tr("Digital clock settings")
|
title: Translation.tr("Digital clock settings")
|
||||||
|
|
||||||
ConfigSwitch {
|
ConfigSwitch {
|
||||||
@@ -143,7 +180,7 @@ ContentPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ContentSubsection {
|
ContentSubsection {
|
||||||
visible: Config.options.background.widgets.clock.style === "cookie"
|
visible: settingsClock.cookiePresent
|
||||||
title: Translation.tr("Cookie clock settings")
|
title: Translation.tr("Cookie clock settings")
|
||||||
|
|
||||||
ConfigSwitch {
|
ConfigSwitch {
|
||||||
@@ -197,7 +234,7 @@ ContentPage {
|
|||||||
ConfigRow {
|
ConfigRow {
|
||||||
|
|
||||||
ConfigSwitch {
|
ConfigSwitch {
|
||||||
enabled: Config.options.background.widgets.clock.style === "cookie" && Config.options.background.widgets.clock.cookie.dialNumberStyle === "dots" || Config.options.background.widgets.clock.cookie.dialNumberStyle === "full"
|
enabled: Config.options.background.widgets.clock.cookie.dialNumberStyle === "dots" || Config.options.background.widgets.clock.cookie.dialNumberStyle === "full"
|
||||||
buttonIcon: "brightness_7"
|
buttonIcon: "brightness_7"
|
||||||
text: Translation.tr("Hour marks")
|
text: Translation.tr("Hour marks")
|
||||||
checked: Config.options.background.widgets.clock.cookie.hourMarks
|
checked: Config.options.background.widgets.clock.cookie.hourMarks
|
||||||
@@ -213,7 +250,7 @@ ContentPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ConfigSwitch {
|
ConfigSwitch {
|
||||||
enabled: Config.options.background.widgets.clock.style === "cookie" && Config.options.background.widgets.clock.cookie.dialNumberStyle !== "numbers"
|
enabled: Config.options.background.widgets.clock.cookie.dialNumberStyle !== "numbers"
|
||||||
buttonIcon: "timer_10"
|
buttonIcon: "timer_10"
|
||||||
text: Translation.tr("Digits in the middle")
|
text: Translation.tr("Digits in the middle")
|
||||||
checked: Config.options.background.widgets.clock.cookie.timeIndicators
|
checked: Config.options.background.widgets.clock.cookie.timeIndicators
|
||||||
@@ -231,7 +268,7 @@ ContentPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ContentSubsection {
|
ContentSubsection {
|
||||||
visible: Config.options.background.widgets.clock.style === "cookie"
|
visible: settingsClock.cookiePresent
|
||||||
title: Translation.tr("Dial style")
|
title: Translation.tr("Dial style")
|
||||||
ConfigSelectionArray {
|
ConfigSelectionArray {
|
||||||
currentValue: Config.options.background.widgets.clock.cookie.dialNumberStyle
|
currentValue: Config.options.background.widgets.clock.cookie.dialNumberStyle
|
||||||
@@ -270,7 +307,7 @@ ContentPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ContentSubsection {
|
ContentSubsection {
|
||||||
visible: Config.options.background.widgets.clock.style === "cookie"
|
visible: settingsClock.cookiePresent
|
||||||
title: Translation.tr("Hour hand")
|
title: Translation.tr("Hour hand")
|
||||||
ConfigSelectionArray {
|
ConfigSelectionArray {
|
||||||
currentValue: Config.options.background.widgets.clock.cookie.hourHandStyle
|
currentValue: Config.options.background.widgets.clock.cookie.hourHandStyle
|
||||||
@@ -303,7 +340,7 @@ ContentPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ContentSubsection {
|
ContentSubsection {
|
||||||
visible: Config.options.background.widgets.clock.style === "cookie"
|
visible: settingsClock.cookiePresent
|
||||||
title: Translation.tr("Minute hand")
|
title: Translation.tr("Minute hand")
|
||||||
|
|
||||||
ConfigSelectionArray {
|
ConfigSelectionArray {
|
||||||
@@ -342,7 +379,7 @@ ContentPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ContentSubsection {
|
ContentSubsection {
|
||||||
visible: Config.options.background.widgets.clock.style === "cookie"
|
visible: settingsClock.cookiePresent
|
||||||
title: Translation.tr("Second hand")
|
title: Translation.tr("Second hand")
|
||||||
|
|
||||||
ConfigSelectionArray {
|
ConfigSelectionArray {
|
||||||
@@ -376,7 +413,7 @@ ContentPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ContentSubsection {
|
ContentSubsection {
|
||||||
visible: Config.options.background.widgets.clock.style === "cookie"
|
visible: settingsClock.cookiePresent
|
||||||
title: Translation.tr("Date style")
|
title: Translation.tr("Date style")
|
||||||
|
|
||||||
ConfigSelectionArray {
|
ConfigSelectionArray {
|
||||||
|
|||||||
@@ -148,18 +148,18 @@ ContentPage {
|
|||||||
ConfigSwitch {
|
ConfigSwitch {
|
||||||
buttonIcon: "keep"
|
buttonIcon: "keep"
|
||||||
text: Translation.tr('Make icons pinned by default')
|
text: Translation.tr('Make icons pinned by default')
|
||||||
checked: Config.options.bar.tray.invertPinnedItems
|
checked: Config.options.tray.invertPinnedItems
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
Config.options.bar.tray.invertPinnedItems = checked;
|
Config.options.tray.invertPinnedItems = checked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigSwitch {
|
ConfigSwitch {
|
||||||
buttonIcon: "colors"
|
buttonIcon: "colors"
|
||||||
text: Translation.tr('Tint icons')
|
text: Translation.tr('Tint icons')
|
||||||
checked: Config.options.bar.tray.monochromeIcons
|
checked: Config.options.tray.monochromeIcons
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
Config.options.bar.tray.monochromeIcons = checked;
|
Config.options.tray.monochromeIcons = checked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -334,4 +334,17 @@ ContentPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ContentSection {
|
||||||
|
icon: "tooltip"
|
||||||
|
title: Translation.tr("Tooltips")
|
||||||
|
ConfigSwitch {
|
||||||
|
buttonIcon: "ads_click"
|
||||||
|
text: Translation.tr("Click to show")
|
||||||
|
checked: Config.options.bar.tooltips.clickToShow
|
||||||
|
onCheckedChanged: {
|
||||||
|
Config.options.bar.tooltips.clickToShow = checked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ ContentPage {
|
|||||||
// Use a nerdfont to see the icons
|
// Use a nerdfont to see the icons
|
||||||
options: ([
|
options: ([
|
||||||
"", "", "", "", "", "", "", "", "",
|
"", "", "", "", "", "", "", "", "",
|
||||||
"", "", "", "", "", "⌘", "", "", ""
|
"", "", "", "", "", "", "⌘", "", "", ""
|
||||||
]).map(icon => { return {
|
]).map(icon => { return {
|
||||||
displayName: icon,
|
displayName: icon,
|
||||||
value: icon
|
value: icon
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
## Waffle
|
||||||
|
|
||||||
|
A recreation of Windoes. It's WIP!
|
||||||
|
|
||||||
|
- If you install illogical-impulse fully, you can press Super+Alt+W to switch to this style.
|
||||||
|
- If you're just copying the Quickshell config, run the config as usual (`qs -c ii`) then run `qs -c ii ipc call panelFamily cycle`
|
||||||
|
|
||||||
|
## From EWW version to Quickshell
|
||||||
|
|
||||||
|
Just a reflection, in case anyone's interested. My blog is probably a better place for this, but it does not exist. Besides, this is going to change as I do more stuff. Currently there's just the bar.
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
|
||||||
|
- QtQuick's `Button` has the `{top/bottom/left/right}Inset` properties, so we can have clickable regions expanding beyond the button background for free. With EWW it was annoying to wrap the button content with an `eventbox` that has some padding, then somehow use CSS selectors to make sure hovering effects work. I have to admit, (a large) part of that annoyance was with how bad my copy-pasting coding practice was at the time, but still...
|
||||||
|
|
||||||
|
- Fancy effects: Gtk3 CSS does not support transformations. In QtQuick we can smack `rotation` and `scale` almost everywhere, so it's simple to make bouncy icons and rotating chevrons
|
||||||
|
|
||||||
|
- Quickshell provides a system tray service (EWW does now but didn't at the time I created the EWW Windoes version), so now there's no Waybar needed for the tray.
|
||||||
|
|
||||||
|
- QtQuick has `Loader`s, so we can have this live-switchable from the main style without killing the widget system, moving styles to the correct folder, and relaunching.
|
||||||
|
|
||||||
|
- This time my computer is powerful enough to run a VM, so I don't have to occasionally reboot to take quick screenshots for reference. I try to make everything pixel-perfect so this is necessary. Speaking about pixel-perfectness, in the EWW version I hardcoded sizes, but this time I'm still doing that (lol), BUT that's normal and not a problem because Qt has the `QT_SCALE_FACTOR` env var for scaling. (Please feel free to prove me wrong in saying Gtk3 doesn't have that magic)
|
||||||
|
|
||||||
|
### Challenges
|
||||||
|
|
||||||
|
- Qt is not Gtk and definitely not React
|
||||||
|
- We don't get directional border on QtQuick `Rectangle`s like in CSS. I was able to get around this with manual drawing, but it was a bit more work
|
||||||
|
|
||||||
|
- Fluent Icons is difficult to use, compared to Material Symbols
|
||||||
|
- No React, so no clean use via a library.
|
||||||
|
- If we use the font, there's no proper, searchable **codepoint** cheatsheet like Nerd Fonts, and there's no ligatures
|
||||||
|
- I resorted to downloading individual SVGs. Not that nice, but it's better than scanning the whole table of icons every time I want one. For this we have fluenticon.com and fluenticons.co, but icons are awkwardly named and there's no alias. Why is the reload/refresh icon called "arrow-sync"? Well, the name is not misleading, but arguably reload/refresh are more common actions. From Fluent Design's [page on Iconography](https://fluent2.microsoft.design/iconography):
|
||||||
|
|
||||||
|
> Fluent system icons are literal metaphors and are named for the shape or object they represent, not the functionality they provide
|
||||||
|
|
||||||
|
"sync" is functionality.
|
||||||
|
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import qs
|
||||||
|
import qs.services
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.functions
|
||||||
|
import qs.modules.waffle.looks
|
||||||
|
|
||||||
|
WBarAttachedPanelContent {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
contentItem: ColumnLayout {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
topLeftRadius: root.border.radius - root.border.border.width
|
||||||
|
topRightRadius: topLeftRadius
|
||||||
|
color: Looks.colors.bgPanelBody
|
||||||
|
|
||||||
|
implicitWidth: 360
|
||||||
|
implicitHeight: 380
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillHeight: false
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: Looks.colors.bgPanelSeparator
|
||||||
|
implicitHeight: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillHeight: false
|
||||||
|
Layout.fillWidth: true
|
||||||
|
bottomLeftRadius: root.border.radius - root.border.border.width
|
||||||
|
bottomRightRadius: bottomLeftRadius
|
||||||
|
color: Looks.colors.bgPanelFooter
|
||||||
|
|
||||||
|
implicitWidth: 360
|
||||||
|
implicitHeight: 47
|
||||||
|
|
||||||
|
// Battery button
|
||||||
|
WPanelFooterButton {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 12
|
||||||
|
|
||||||
|
contentItem: Row {
|
||||||
|
spacing: 4
|
||||||
|
|
||||||
|
FluentIcon {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
icon: WIcons.batteryIcon
|
||||||
|
}
|
||||||
|
WText {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: `${Math.round(Battery.percentage * 100) || 0}%`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Settings button
|
||||||
|
WPanelFooterButton {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 12
|
||||||
|
|
||||||
|
contentItem: FluentIcon {
|
||||||
|
icon: "settings"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
import qs
|
||||||
|
import qs.services
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.widgets
|
||||||
|
|
||||||
|
Scope {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: GlobalStates
|
||||||
|
|
||||||
|
function onSidebarLeftOpenChanged() {
|
||||||
|
if (GlobalStates.sidebarLeftOpen) barLoader.active = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: barLoader
|
||||||
|
active: GlobalStates.sidebarLeftOpen
|
||||||
|
sourceComponent: PanelWindow {
|
||||||
|
id: panelWindow
|
||||||
|
exclusiveZone: 0
|
||||||
|
WlrLayershell.namespace: "quickshell:actionCenter"
|
||||||
|
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
bottom: Config.options.waffles.bar.bottom
|
||||||
|
top: !Config.options.waffles.bar.bottom
|
||||||
|
right: true
|
||||||
|
}
|
||||||
|
|
||||||
|
implicitWidth: content.implicitWidth + content.visualMargin * 2
|
||||||
|
implicitHeight: content.implicitHeight + content.visualMargin * 2
|
||||||
|
|
||||||
|
HyprlandFocusGrab {
|
||||||
|
id: focusGrab
|
||||||
|
active: true
|
||||||
|
windows: [panelWindow]
|
||||||
|
onCleared: content.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: GlobalStates
|
||||||
|
function onSidebarLeftOpenChanged() {
|
||||||
|
if (!GlobalStates.sidebarLeftOpen) content.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ActionCenterContent {
|
||||||
|
id: content
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
barLoader.active = false;
|
||||||
|
GlobalStates.sidebarLeftOpen = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleOpen() {
|
||||||
|
GlobalStates.sidebarLeftOpen = !GlobalStates.sidebarLeftOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
IpcHandler {
|
||||||
|
target: "sidebarLeft"
|
||||||
|
|
||||||
|
function toggle() {
|
||||||
|
root.toggleOpen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalShortcut {
|
||||||
|
name: "sidebarLeftToggle"
|
||||||
|
description: "Toggles left sidebar on press"
|
||||||
|
|
||||||
|
onPressed: root.toggleOpen();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,10 +17,12 @@ BarButton {
|
|||||||
rightInset: 2
|
rightInset: 2
|
||||||
implicitWidth: height - topInset - bottomInset + leftInset + rightInset
|
implicitWidth: height - topInset - bottomInset + leftInset + rightInset
|
||||||
|
|
||||||
|
property real pressedScale: 5/6
|
||||||
|
|
||||||
onDownChanged: {
|
onDownChanged: {
|
||||||
scaleAnim.duration = root.down ? 150 : 200
|
scaleAnim.duration = root.down ? 150 : 200
|
||||||
scaleAnim.easing.bezierCurve = root.down ? Looks.transition.easing.bezierCurve.easeIn : Looks.transition.easing.bezierCurve.easeOut
|
scaleAnim.easing.bezierCurve = root.down ? Looks.transition.easing.bezierCurve.easeIn : Looks.transition.easing.bezierCurve.easeOut
|
||||||
contentItem.scale = root.down ? 5/6 : 1 // If/When we do dragging, the scale is 1.25
|
contentItem.scale = root.down ? root.pressedScale : 1 // If/When we do dragging, the scale is 1.25
|
||||||
}
|
}
|
||||||
|
|
||||||
background: Item {
|
background: Item {
|
||||||
@@ -45,9 +47,7 @@ BarButton {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.rightMargin: 5
|
anchors.rightMargin: 5
|
||||||
active: root.multiple
|
active: root.multiple
|
||||||
sourceComponent: BackgroundAcrylicRectangle {
|
sourceComponent: BackgroundAcrylicRectangle {}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ BarButton {
|
|||||||
|
|
||||||
component BackgroundAcrylicRectangle: AcrylicRectangle {
|
component BackgroundAcrylicRectangle: AcrylicRectangle {
|
||||||
shiny: ((root.hovered && !root.down) || root.checked)
|
shiny: ((root.hovered && !root.down) || root.checked)
|
||||||
color: root.colBackground
|
color: root.color
|
||||||
border.width: 1
|
border.width: 1
|
||||||
border.color: root.colBackgroundBorder
|
border.color: root.colBackgroundBorder
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ Kirigami.Icon {
|
|||||||
property real implicitSize: 26
|
property real implicitSize: 26
|
||||||
implicitWidth: implicitSize
|
implicitWidth: implicitSize
|
||||||
implicitHeight: implicitSize
|
implicitHeight: implicitSize
|
||||||
|
|
||||||
|
animated: true
|
||||||
roundToIconSize: false
|
roundToIconSize: false
|
||||||
fallback: root.iconName
|
fallback: root.iconName
|
||||||
source: tryCustomIcon ? `${Looks.iconsPath}/${root.iconName}${!root.separateLightDark ? "" : Looks.dark ? "-dark" : "-light"}.svg` : fallback
|
source: tryCustomIcon ? `${Looks.iconsPath}/${root.iconName}${!root.separateLightDark ? "" : Looks.dark ? "-dark" : "-light"}.svg` : fallback
|
||||||
|
|||||||
@@ -8,11 +8,14 @@ import qs.modules.waffle.looks
|
|||||||
Button {
|
Button {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
signal altAction()
|
property var altAction: () => {}
|
||||||
signal middleClickAction()
|
property var middleClickAction: () => {}
|
||||||
|
|
||||||
property color colBackground
|
property color colBackground: ColorUtils.transparentize(Looks.colors.bg1)
|
||||||
|
property color colBackgroundHover: Looks.colors.bg1Hover
|
||||||
|
property color colBackgroundActive: Looks.colors.bg1Active
|
||||||
property color colBackgroundBorder
|
property color colBackgroundBorder
|
||||||
|
property color color
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
topInset: 4
|
topInset: 4
|
||||||
bottomInset: 4
|
bottomInset: 4
|
||||||
@@ -37,16 +40,16 @@ Button {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
colBackground: {
|
colBackgroundBorder: ColorUtils.transparentize(Looks.colors.bg1Border, (root.checked || root.hovered) ? Looks.contentTransparency : 1)
|
||||||
|
color: {
|
||||||
if (root.down) {
|
if (root.down) {
|
||||||
return Looks.colors.bg1Active
|
return root.colBackgroundActive
|
||||||
} else if ((root.hovered && !root.down) || root.checked) {
|
} else if ((root.hovered && !root.down) || root.checked) {
|
||||||
return Looks.colors.bg1Hover
|
return root.colBackgroundHover
|
||||||
} else {
|
} else {
|
||||||
return ColorUtils.transparentize(Looks.colors.bg1)
|
return root.colBackground
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
colBackgroundBorder: ColorUtils.transparentize(Looks.colors.bg1Border, root.checked ? Looks.contentTransparency : 1)
|
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -66,7 +69,8 @@ Button {
|
|||||||
|
|
||||||
background: AcrylicRectangle {
|
background: AcrylicRectangle {
|
||||||
shiny: ((root.hovered && !root.down) || root.checked)
|
shiny: ((root.hovered && !root.down) || root.checked)
|
||||||
color: root.colBackground
|
color: root.color
|
||||||
|
radius: Looks.radius.medium
|
||||||
border.width: 1
|
border.width: 1
|
||||||
border.color: root.colBackgroundBorder
|
border.color: root.colBackgroundBorder
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import qs
|
||||||
|
import qs.services
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.waffle.looks
|
||||||
|
import qs.modules.waffle.bar
|
||||||
|
|
||||||
|
BarButton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property alias iconName: iconContent.icon
|
||||||
|
property alias iconSource: iconContent.source
|
||||||
|
property alias iconSize: iconContent.implicitSize
|
||||||
|
property alias iconRotation: iconContent.rotation
|
||||||
|
property alias iconMonochrome: iconContent.monochrome
|
||||||
|
property alias iconScale: iconContent.scale
|
||||||
|
property alias tooltipText: tooltip.text
|
||||||
|
property alias overlayingItems: iconContent.data
|
||||||
|
|
||||||
|
implicitWidth: 32
|
||||||
|
|
||||||
|
contentItem: Item {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
implicitWidth: iconContent.implicitWidth
|
||||||
|
implicitHeight: iconContent.implicitHeight
|
||||||
|
|
||||||
|
FluentIcon {
|
||||||
|
id: iconContent
|
||||||
|
anchors.centerIn: parent
|
||||||
|
implicitSize: 16
|
||||||
|
icon: root.iconName
|
||||||
|
monochrome: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BarToolTip {
|
||||||
|
id: tooltip
|
||||||
|
extraVisibleCondition: root.shouldShowTooltip && text !== ""
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.functions
|
||||||
|
import qs.modules.waffle.looks
|
||||||
|
|
||||||
|
BarPopup {
|
||||||
|
id: root
|
||||||
|
default property var menuData
|
||||||
|
property var model: [
|
||||||
|
{ iconName: "start-here", text: "Start", action: () => {print("hello")} },
|
||||||
|
{ type : "separator" },
|
||||||
|
]
|
||||||
|
readonly property bool hasIcons: model.some(item => item.iconName !== undefined && item.iconName !== "")
|
||||||
|
padding: 2
|
||||||
|
|
||||||
|
contentItem: ColumnLayout {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: root.model
|
||||||
|
delegate: DelegateChooser {
|
||||||
|
role: "type"
|
||||||
|
DelegateChoice {
|
||||||
|
roleValue: "separator"
|
||||||
|
Rectangle {
|
||||||
|
Layout.topMargin: 2
|
||||||
|
Layout.bottomMargin: 2
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: 1
|
||||||
|
color: Looks.colors.bg0Border
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DelegateChoice {
|
||||||
|
roleValue: undefined
|
||||||
|
WButton {
|
||||||
|
id: btn
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
required property var modelData
|
||||||
|
forceShowIcon: root.hasIcons
|
||||||
|
icon.name: modelData.iconName ? modelData.iconName : ""
|
||||||
|
monochromeIcon: modelData.monochromeIcon ?? true
|
||||||
|
text: modelData.text ? modelData.text : ""
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (modelData.action) modelData.action();
|
||||||
|
root.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.functions
|
||||||
|
import qs.modules.waffle.looks
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property var contentItem
|
||||||
|
property real padding: Looks.radius.large - Looks.radius.medium
|
||||||
|
property bool noSmoothClosing: !Config.options.waffles.smootherAnimations
|
||||||
|
property bool closeOnFocusLost: true
|
||||||
|
signal focusCleared()
|
||||||
|
|
||||||
|
property Item anchorItem: parent
|
||||||
|
property real visualMargin: 12
|
||||||
|
readonly property bool barAtBottom: Config.options.waffles.bar.bottom
|
||||||
|
property real ambientShadowWidth: 1
|
||||||
|
|
||||||
|
onFocusCleared: {
|
||||||
|
if (!root.closeOnFocusLost) return;
|
||||||
|
root.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
function grabFocus() { // Doesn't work
|
||||||
|
item.grabFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
item.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateAnchor() {
|
||||||
|
item?.anchor.updateAnchor();
|
||||||
|
}
|
||||||
|
|
||||||
|
active: false
|
||||||
|
visible: active
|
||||||
|
sourceComponent: PopupWindow {
|
||||||
|
id: popupWindow
|
||||||
|
visible: true
|
||||||
|
Component.onCompleted: {
|
||||||
|
openAnim.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
anchor {
|
||||||
|
adjustment: PopupAdjustment.ResizeY | PopupAdjustment.SlideX
|
||||||
|
item: root.anchorItem
|
||||||
|
gravity: root.barAtBottom ? Edges.Top : Edges.Bottom
|
||||||
|
edges: root.barAtBottom ? Edges.Top : Edges.Bottom
|
||||||
|
}
|
||||||
|
|
||||||
|
HyprlandFocusGrab {
|
||||||
|
id: focusGrab
|
||||||
|
active: true
|
||||||
|
windows: [popupWindow]
|
||||||
|
onCleared: root.focusCleared();
|
||||||
|
}
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
if (root.noSmoothClosing) root.active = false;
|
||||||
|
else closeAnim.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
function grabFocus() {
|
||||||
|
focusGrab.active = true; // Doesn't work
|
||||||
|
}
|
||||||
|
|
||||||
|
implicitWidth: realContent.implicitWidth + (root.ambientShadowWidth * 2) + (root.visualMargin * 2)
|
||||||
|
implicitHeight: realContent.implicitHeight + (root.ambientShadowWidth * 2) + (root.visualMargin * 2)
|
||||||
|
|
||||||
|
property real sourceEdgeMargin: -implicitHeight
|
||||||
|
PropertyAnimation {
|
||||||
|
id: openAnim
|
||||||
|
target: popupWindow
|
||||||
|
property: "sourceEdgeMargin"
|
||||||
|
to: (root.ambientShadowWidth + root.visualMargin)
|
||||||
|
duration: 200
|
||||||
|
easing.type: Easing.BezierSpline
|
||||||
|
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeIn
|
||||||
|
}
|
||||||
|
SequentialAnimation {
|
||||||
|
id: closeAnim
|
||||||
|
PropertyAnimation {
|
||||||
|
target: popupWindow
|
||||||
|
property: "sourceEdgeMargin"
|
||||||
|
to: -implicitHeight
|
||||||
|
duration: 150
|
||||||
|
easing.type: Easing.BezierSpline
|
||||||
|
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeOut
|
||||||
|
}
|
||||||
|
ScriptAction {
|
||||||
|
script: {
|
||||||
|
root.active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
WAmbientShadow {
|
||||||
|
target: realContent
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: realContent
|
||||||
|
z: 1
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
top: root.barAtBottom ? undefined : parent.top
|
||||||
|
bottom: root.barAtBottom ? parent.bottom : undefined
|
||||||
|
margins: root.ambientShadowWidth + root.visualMargin
|
||||||
|
// Opening anim
|
||||||
|
bottomMargin: root.barAtBottom ? popupWindow.sourceEdgeMargin : (root.ambientShadowWidth + root.visualMargin)
|
||||||
|
topMargin: root.barAtBottom ? (root.ambientShadowWidth + root.visualMargin) : popupWindow.sourceEdgeMargin
|
||||||
|
}
|
||||||
|
color: Looks.colors.bg1
|
||||||
|
radius: Looks.radius.large
|
||||||
|
|
||||||
|
// test
|
||||||
|
implicitWidth: root.contentItem.implicitWidth + (root.padding * 2)
|
||||||
|
implicitHeight: root.contentItem.implicitHeight + (root.padding * 2)
|
||||||
|
|
||||||
|
children: [root.contentItem]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,9 +9,10 @@ import qs.modules.waffle.looks
|
|||||||
AppButton {
|
AppButton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
iconName: "system-search"
|
iconName: checked ? "system-search-checked" : "system-search"
|
||||||
separateLightDark: true
|
separateLightDark: true
|
||||||
|
|
||||||
|
checked: GlobalStates.overviewOpen
|
||||||
onClicked: {
|
onClicked: {
|
||||||
GlobalStates.overviewOpen = !GlobalStates.overviewOpen; // For now...
|
GlobalStates.overviewOpen = !GlobalStates.overviewOpen; // For now...
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import org.kde.kirigami as Kirigami
|
import Quickshell
|
||||||
import qs
|
import qs
|
||||||
import qs.services
|
import qs.services
|
||||||
import qs.modules.common
|
import qs.modules.common
|
||||||
@@ -10,7 +11,7 @@ AppButton {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
leftInset: Config.options.waffles.bar.leftAlignApps ? 12 : 0
|
leftInset: Config.options.waffles.bar.leftAlignApps ? 12 : 0
|
||||||
iconName: "start-here"
|
iconName: down ? "start-here-pressed" : "start-here"
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
GlobalStates.overviewOpen = !GlobalStates.overviewOpen; // For now...
|
GlobalStates.overviewOpen = !GlobalStates.overviewOpen; // For now...
|
||||||
@@ -21,4 +22,45 @@ AppButton {
|
|||||||
text: Translation.tr("Start")
|
text: Translation.tr("Start")
|
||||||
extraVisibleCondition: root.shouldShowTooltip
|
extraVisibleCondition: root.shouldShowTooltip
|
||||||
}
|
}
|
||||||
|
|
||||||
|
altAction: () => {
|
||||||
|
contextMenu.active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
BarMenu {
|
||||||
|
id: contextMenu
|
||||||
|
|
||||||
|
model: [
|
||||||
|
{
|
||||||
|
text: Translation.tr("Terminal"),
|
||||||
|
action: () => {
|
||||||
|
Quickshell.execDetached(["bash", "-c", Config.options.apps.terminal]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: Translation.tr("Task Manager"),
|
||||||
|
action: () => {
|
||||||
|
Quickshell.execDetached(["bash", "-c", Config.options.apps.taskManager]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: Translation.tr("Settings"),
|
||||||
|
action: () => {
|
||||||
|
Quickshell.execDetached(["qs", "-p", Quickshell.shellPath("settings.qml")]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: Translation.tr("File Explorer"),
|
||||||
|
action: () => {
|
||||||
|
Qt.openUrlExternally(Directories.home);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: Translation.tr("Search"),
|
||||||
|
action: () => {
|
||||||
|
Quickshell.execDetached(["qs", "-p", Quickshell.shellPath(""), "ipc", "call", "overview", "toggle"]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import qs.modules.waffle.looks
|
|||||||
BarButton {
|
BarButton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
checked: GlobalStates.sidebarRightOpen
|
checked: GlobalStates.sidebarLeftOpen
|
||||||
onClicked: {
|
onClicked: {
|
||||||
GlobalStates.sidebarRightOpen = !GlobalStates.sidebarRightOpen; // For now...
|
GlobalStates.sidebarLeftOpen = !GlobalStates.sidebarLeftOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
contentItem: Item {
|
contentItem: Item {
|
||||||
@@ -85,11 +85,13 @@ BarButton {
|
|||||||
BarToolTip {
|
BarToolTip {
|
||||||
extraVisibleCondition: root.shouldShowTooltip && volumeHoverArea.containsMouse
|
extraVisibleCondition: root.shouldShowTooltip && volumeHoverArea.containsMouse
|
||||||
text: Translation.tr("Speakers (%1): %2") //
|
text: Translation.tr("Speakers (%1): %2") //
|
||||||
.arg(Audio.sink?.nickname || Audio.sink?.description || Translation.tr("Unknown")) //
|
.arg(Audio.sink?.nickname || Audio.sink?.description || Translation.tr("Unknown")) //
|
||||||
.arg(`${Math.round(Audio.sink?.audio.volume * 100) || 0}%`) //
|
.arg(Audio.sink?.audio.muted ? Translation.tr("Muted") : `${Math.round(Audio.sink?.audio.volume * 100) || 0}%`) //
|
||||||
}
|
}
|
||||||
BarToolTip {
|
BarToolTip {
|
||||||
extraVisibleCondition: root.shouldShowTooltip && batteryHoverArea.containsMouse
|
extraVisibleCondition: root.shouldShowTooltip && batteryHoverArea.containsMouse
|
||||||
text: Translation.tr("Battery: %1").arg(`${Math.round(Battery.percentage * 100) || 0}%`)
|
text: Translation.tr("Battery: %1%2") //
|
||||||
|
.arg(`${Math.round(Battery.percentage * 100) || 0}%`) //
|
||||||
|
.arg(Battery.isPluggedIn ? (" " + Translation.tr("(Plugged in)")) : "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ import qs.modules.waffle.looks
|
|||||||
AppButton {
|
AppButton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
iconName: "task-view"
|
iconName: (down && !checked) ? "task-view-pressed" : "task-view"
|
||||||
|
pressedScale: checked ? 5/6 : 1
|
||||||
separateLightDark: true
|
separateLightDark: true
|
||||||
|
|
||||||
checked: GlobalStates.overviewOpen
|
checked: GlobalStates.overviewOpen
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import qs
|
||||||
|
import qs.services
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.waffle.looks
|
||||||
|
import qs.modules.waffle.bar.tray
|
||||||
|
|
||||||
|
BarIconButton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
visible: Updates.updateAdvised || Updates.updateStronglyAdvised
|
||||||
|
padding: 4
|
||||||
|
iconName: "arrow-sync"
|
||||||
|
iconSize: 20 // Needed because the icon appears to have some padding
|
||||||
|
tooltipText: Translation.tr("Get the latest features and security improvements with\nthe newest feature update.\n\n%1 packages").arg(Updates.count)
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
Quickshell.execDetached(["bash", "-c", Config.options.apps.update]);
|
||||||
|
}
|
||||||
|
|
||||||
|
overlayingItems: Rectangle {
|
||||||
|
anchors {
|
||||||
|
right: parent.right
|
||||||
|
bottom: parent.bottom
|
||||||
|
margins: 1
|
||||||
|
}
|
||||||
|
implicitWidth: 8
|
||||||
|
implicitHeight: implicitWidth
|
||||||
|
radius: height / 2
|
||||||
|
color: Updates.updateStronglyAdvised ? Looks.colors.warning : Looks.colors.accent
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,9 +9,8 @@ import qs.modules.common
|
|||||||
import qs.modules.common.widgets
|
import qs.modules.common.widgets
|
||||||
|
|
||||||
Scope {
|
Scope {
|
||||||
id: bar
|
id: root
|
||||||
property bool showBarBackground: Config.options.bar.showBackground
|
|
||||||
|
|
||||||
LazyLoader {
|
LazyLoader {
|
||||||
id: barLoader
|
id: barLoader
|
||||||
active: GlobalStates.barOpen && !GlobalStates.screenLocked
|
active: GlobalStates.barOpen && !GlobalStates.screenLocked
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import qs.modules.common
|
|||||||
import qs.modules.common.widgets
|
import qs.modules.common.widgets
|
||||||
import qs.modules.waffle.looks
|
import qs.modules.waffle.looks
|
||||||
import qs.modules.waffle.bar.tasks
|
import qs.modules.waffle.bar.tasks
|
||||||
|
import qs.modules.waffle.bar.tray
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: root
|
id: root
|
||||||
@@ -68,6 +69,8 @@ Rectangle {
|
|||||||
shown: Config.options.waffles.bar.leftAlignApps
|
shown: Config.options.waffles.bar.leftAlignApps
|
||||||
sourceComponent: WidgetsButton {}
|
sourceComponent: WidgetsButton {}
|
||||||
}
|
}
|
||||||
|
Tray {}
|
||||||
|
UpdatesButton {}
|
||||||
SystemButton {}
|
SystemButton {}
|
||||||
TimeButton {}
|
TimeButton {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ AppButton {
|
|||||||
onClicked: {
|
onClicked: {
|
||||||
GlobalStates.sidebarLeftOpen = !GlobalStates.sidebarLeftOpen
|
GlobalStates.sidebarLeftOpen = !GlobalStates.sidebarLeftOpen
|
||||||
}
|
}
|
||||||
|
onDownChanged: {
|
||||||
|
scaleAnim.duration = root.down ? 150 : 200
|
||||||
|
scaleAnim.easing.bezierCurve = root.down ? Looks.transition.easing.bezierCurve.easeIn : Looks.transition.easing.bezierCurve.easeOut
|
||||||
|
iconWidget.scale = root.down ? 5/6 : 1 // If/When we do dragging, the scale is 1.25
|
||||||
|
}
|
||||||
|
|
||||||
contentItem: Item {
|
contentItem: Item {
|
||||||
anchors {
|
anchors {
|
||||||
@@ -41,6 +46,13 @@ AppButton {
|
|||||||
id: iconWidget
|
id: iconWidget
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
iconName: root.iconName
|
iconName: root.iconName
|
||||||
|
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation {
|
||||||
|
id: scaleAnim
|
||||||
|
easing.type: Easing.BezierSpline
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import QtQuick
|
|||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import qs.services
|
import qs.services
|
||||||
import qs.modules.common
|
import qs.modules.common
|
||||||
|
import qs.modules.common.functions
|
||||||
import qs.modules.waffle.looks
|
import qs.modules.waffle.looks
|
||||||
import qs.modules.waffle.bar
|
import qs.modules.waffle.bar
|
||||||
import Quickshell
|
import Quickshell
|
||||||
@@ -16,6 +17,7 @@ AppButton {
|
|||||||
property bool hasWindows: appEntry.toplevels.length > 0
|
property bool hasWindows: appEntry.toplevels.length > 0
|
||||||
|
|
||||||
signal hoverPreviewRequested()
|
signal hoverPreviewRequested()
|
||||||
|
signal hoverPreviewDismissed()
|
||||||
|
|
||||||
multiple: appEntry.toplevels.length > 1
|
multiple: appEntry.toplevels.length > 1
|
||||||
checked: active
|
checked: active
|
||||||
@@ -37,12 +39,18 @@ AppButton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMiddleClickAction: {
|
middleClickAction: () => {
|
||||||
if (root.desktopEntry) {
|
if (root.desktopEntry) {
|
||||||
desktopEntry.execute()
|
desktopEntry.execute()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
altAction: () => {
|
||||||
|
root.hoverPreviewDismissed()
|
||||||
|
root.hoverTimer.stop()
|
||||||
|
contextMenu.active = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Active indicator
|
// Active indicator
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: activeIndicator
|
id: activeIndicator
|
||||||
@@ -74,4 +82,44 @@ AppButton {
|
|||||||
extraVisibleCondition: root.shouldShowTooltip && !root.hasWindows
|
extraVisibleCondition: root.shouldShowTooltip && !root.hasWindows
|
||||||
text: desktopEntry ? desktopEntry.name : appEntry.appId
|
text: desktopEntry ? desktopEntry.name : appEntry.appId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BarMenu {
|
||||||
|
id: contextMenu
|
||||||
|
|
||||||
|
model: [
|
||||||
|
...((root.desktopEntry?.actions.length > 0) ? root.desktopEntry.actions.map(action =>({
|
||||||
|
iconName: action.icon,
|
||||||
|
text: action.name,
|
||||||
|
action: () => {
|
||||||
|
action.execute()
|
||||||
|
}
|
||||||
|
})).concat({ type: "separator" }) : []),
|
||||||
|
{
|
||||||
|
iconName: root.iconName,
|
||||||
|
text: root.desktopEntry ? root.desktopEntry.name : StringUtils.toTitleCase(appEntry.appId),
|
||||||
|
monochromeIcon: false,
|
||||||
|
action: () => {
|
||||||
|
if (root.desktopEntry) {
|
||||||
|
root.desktopEntry.execute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
iconName: root.appEntry.pinned ? "pin-off" : "pin",
|
||||||
|
text: root.appEntry.pinned ? qsTr("Unpin from taskbar") : qsTr("Pin to taskbar"),
|
||||||
|
action: () => {
|
||||||
|
TaskbarApps.togglePin(root.appEntry.appId);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
...(root.appEntry.toplevels.length > 0 ? [{
|
||||||
|
iconName: "dismiss",
|
||||||
|
text: root.multiple ? qsTr("Close all windows") : qsTr("Close window"),
|
||||||
|
action: () => {
|
||||||
|
for (let toplevel of root.appEntry.toplevels) {
|
||||||
|
toplevel.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}] : []),
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ PopupWindow {
|
|||||||
property Item anchorItem
|
property Item anchorItem
|
||||||
|
|
||||||
//////////////////// Functions ////////////////////
|
//////////////////// Functions ////////////////////
|
||||||
function close() {
|
function close() { // Closing doesn't animate, not sure if they're just lazy or it's intentional
|
||||||
marginBehavior.enabled = false;
|
marginBehavior.enabled = false;
|
||||||
root.visible = false;
|
root.visible = false;
|
||||||
}
|
}
|
||||||
@@ -36,7 +36,7 @@ PopupWindow {
|
|||||||
///////////////////// Internals /////////////////////
|
///////////////////// Internals /////////////////////
|
||||||
readonly property bool bottom: Config.options.waffles.bar.bottom
|
readonly property bool bottom: Config.options.waffles.bar.bottom
|
||||||
property real visualMargin: 12
|
property real visualMargin: 12
|
||||||
property alias ambientShadowWidth: ambientShadow.border.width
|
property real ambientShadowWidth: 1
|
||||||
|
|
||||||
visible: false
|
visible: false
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
@@ -64,16 +64,8 @@ PopupWindow {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
|
||||||
// Shadow
|
// Shadow
|
||||||
Rectangle {
|
WAmbientShadow {
|
||||||
id: ambientShadow
|
target: contentItem
|
||||||
anchors {
|
|
||||||
fill: contentItem
|
|
||||||
margins: -border.width
|
|
||||||
}
|
|
||||||
border.color: ColorUtils.transparentize(Looks.colors.bg0Border, Looks.shadowTransparency)
|
|
||||||
border.width: 1
|
|
||||||
color: "transparent"
|
|
||||||
radius: Looks.radius.large + border.width
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|||||||
@@ -17,10 +17,17 @@ MouseArea {
|
|||||||
previewPopup.show(appEntry, button);
|
previewPopup.show(appEntry, button);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on implicitWidth {
|
||||||
|
animation: Looks.transition.move.createObject(this)
|
||||||
|
}
|
||||||
|
|
||||||
// Apps row
|
// Apps row
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: row
|
id: row
|
||||||
anchors.fill: parent
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
}
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
@@ -36,6 +43,9 @@ MouseArea {
|
|||||||
onHoverPreviewRequested: {
|
onHoverPreviewRequested: {
|
||||||
root.showPreviewPopup(appEntry, this)
|
root.showPreviewPopup(appEntry, this)
|
||||||
}
|
}
|
||||||
|
onHoverPreviewDismissed: {
|
||||||
|
previewPopup.close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,4 +56,5 @@ MouseArea {
|
|||||||
tasksHovered: root.containsMouse
|
tasksHovered: root.containsMouse
|
||||||
anchor.window: root.QsWindow.window
|
anchor.window: root.QsWindow.window
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Qt.labs.synchronizer
|
||||||
|
import Quickshell
|
||||||
|
import qs.services
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.widgets
|
||||||
|
import qs.modules.waffle.looks
|
||||||
|
import qs.modules.waffle.bar
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool overflowOpen: false
|
||||||
|
property bool dragging: false
|
||||||
|
|
||||||
|
Layout.fillHeight: true
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
BarIconButton {
|
||||||
|
id: overflowButton
|
||||||
|
|
||||||
|
visible: (TrayService.unpinnedItems.length > 0 || root.dragging)
|
||||||
|
checked: root.overflowOpen
|
||||||
|
|
||||||
|
iconName: "chevron-down"
|
||||||
|
iconMonochrome: true
|
||||||
|
iconRotation: (Config.options.waffles.bar.bottom ? 180 : 0) + (root.overflowOpen ? 180 : 0)
|
||||||
|
Behavior on iconRotation {
|
||||||
|
animation: Looks.transition.rotate.createObject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
root.overflowOpen = !root.overflowOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
TrayOverflowMenu {
|
||||||
|
id: trayOverflowLayout
|
||||||
|
Synchronizer on active {
|
||||||
|
property alias source: root.overflowOpen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BarToolTip {
|
||||||
|
extraVisibleCondition: overflowButton.shouldShowTooltip
|
||||||
|
text: qsTr("Show hidden icons")
|
||||||
|
}
|
||||||
|
|
||||||
|
DropArea {
|
||||||
|
id: pinDropArea
|
||||||
|
anchors.fill: parent
|
||||||
|
property bool willPin: false
|
||||||
|
onEntered: willPin = true
|
||||||
|
onExited: willPin = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: ScriptModel {
|
||||||
|
values: TrayService.pinnedItems
|
||||||
|
}
|
||||||
|
delegate: TrayButton {
|
||||||
|
id: trayButton
|
||||||
|
required property var modelData
|
||||||
|
item: modelData
|
||||||
|
|
||||||
|
property real initialX
|
||||||
|
property real initialY
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: dragArea
|
||||||
|
anchors.fill: parent
|
||||||
|
drag.target: parent
|
||||||
|
drag.axis: Drag.XAxis
|
||||||
|
drag.threshold: 2
|
||||||
|
|
||||||
|
onPressed: event => {
|
||||||
|
trayButton.Drag.hotSpot.x = event.x;
|
||||||
|
trayButton.initialX = trayButton.x;
|
||||||
|
root.dragging = true;
|
||||||
|
trayButton.Drag.active = true;
|
||||||
|
}
|
||||||
|
onPositionChanged: {
|
||||||
|
pinTooltip.updateAnchor();
|
||||||
|
}
|
||||||
|
onReleased: {
|
||||||
|
if (!dragArea.drag.active) {
|
||||||
|
trayButton.click();
|
||||||
|
} else {
|
||||||
|
if (pinDropArea.containsDrag && pinDropArea.willPin) {
|
||||||
|
// Quickshell would crash if we don't hide this item first. Took me fucking 3 hours to figure out...
|
||||||
|
trayButton.visible = false;
|
||||||
|
TrayService.togglePin(trayButton.item.id);
|
||||||
|
pinDropArea.willPin = false;
|
||||||
|
} else {
|
||||||
|
trayButton.x = trayButton.initialX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
trayButton.Drag.active = false;
|
||||||
|
root.dragging = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BarToolTip {
|
||||||
|
id: pinTooltip
|
||||||
|
extraVisibleCondition: trayButton.Drag.active && pinDropArea.containsDrag && pinDropArea.willPin
|
||||||
|
realContentHorizontalPadding: 6
|
||||||
|
realContentVerticalPadding: 6
|
||||||
|
realContentItem: FluentIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
icon: "pin-off"
|
||||||
|
implicitSize: 18
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Services.SystemTray
|
||||||
|
import qs.services
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.widgets
|
||||||
|
import qs.modules.waffle.looks
|
||||||
|
import qs.modules.waffle.bar
|
||||||
|
|
||||||
|
BarIconButton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property SystemTrayItem item
|
||||||
|
property alias menuOpen: menu.visible
|
||||||
|
readonly property bool barAtBottom: Config.options.waffles.bar.bottom
|
||||||
|
iconSource: item.icon
|
||||||
|
iconScale: 0
|
||||||
|
Component.onCompleted: {
|
||||||
|
root.iconScale = 1
|
||||||
|
}
|
||||||
|
Behavior on iconScale {
|
||||||
|
animation: Looks.transition.enter.createObject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
item.activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
altAction: () => {
|
||||||
|
if (item.hasMenu) menu.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is lazy, but it's not like tray menus on Windoes are consistent...
|
||||||
|
// TODO: Figure out how to do cascading menus then use a custom menu
|
||||||
|
QsMenuAnchor {
|
||||||
|
id: menu
|
||||||
|
menu: root.item.menu
|
||||||
|
anchor {
|
||||||
|
adjustment: PopupAdjustment.ResizeY | PopupAdjustment.SlideX
|
||||||
|
item: root
|
||||||
|
gravity: root.barAtBottom ? Edges.Top : Edges.Bottom
|
||||||
|
edges: root.barAtBottom ? Edges.Top : Edges.Bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BarToolTip {
|
||||||
|
extraVisibleCondition: root.shouldShowTooltip && !root.Drag.active
|
||||||
|
text: TrayService.getTooltipForItem(root.item)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
import qs.services
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.functions
|
||||||
|
import qs.modules.waffle.looks
|
||||||
|
import qs.modules.waffle.bar
|
||||||
|
|
||||||
|
BarPopup {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
closeOnFocusLost: false
|
||||||
|
onFocusCleared: {
|
||||||
|
const hasMenuOpen = contentItem.children.some(c => (c.menuOpen));
|
||||||
|
if (!hasMenuOpen)
|
||||||
|
root.close();
|
||||||
|
else
|
||||||
|
root.grabFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Item {
|
||||||
|
id: contentItem
|
||||||
|
anchors.centerIn: parent
|
||||||
|
implicitWidth: contentGrid.implicitWidth
|
||||||
|
implicitHeight: contentGrid.implicitHeight
|
||||||
|
GridLayout {
|
||||||
|
id: contentGrid
|
||||||
|
anchors.centerIn: parent
|
||||||
|
rows: Math.floor(Math.sqrt(TrayService.unpinnedItems.length))
|
||||||
|
columns: Math.ceil(TrayService.unpinnedItems.length / rows)
|
||||||
|
columnSpacing: 0
|
||||||
|
rowSpacing: 0
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: ScriptModel {
|
||||||
|
values: TrayService.unpinnedItems
|
||||||
|
onValuesChanged: {
|
||||||
|
root.updateAnchor();
|
||||||
|
if (values.length === 0) {
|
||||||
|
root.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delegate: TrayButton {
|
||||||
|
id: trayButton
|
||||||
|
required property var modelData
|
||||||
|
item: modelData
|
||||||
|
|
||||||
|
topInset: 0
|
||||||
|
bottomInset: 0
|
||||||
|
implicitWidth: 40
|
||||||
|
implicitHeight: 40
|
||||||
|
|
||||||
|
colBackground: ColorUtils.transparentize(Looks.colors.bg2)
|
||||||
|
colBackgroundHover: Looks.colors.bg2Hover
|
||||||
|
colBackgroundActive: Looks.colors.bg2Active
|
||||||
|
|
||||||
|
onMenuOpenChanged: {
|
||||||
|
// The overflow menu should only be closed when the user clicks outside
|
||||||
|
// However the focus grab refuses to reactivate, so we can't have that
|
||||||
|
// But most of the time the user dismisses the menu by clicking outside anyway,
|
||||||
|
// so this is acceptable.
|
||||||
|
if (!menuOpen) {
|
||||||
|
root.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
property real initialX
|
||||||
|
property real initialY
|
||||||
|
|
||||||
|
Behavior on x {
|
||||||
|
animation: Looks.transition.move.createObject(this)
|
||||||
|
}
|
||||||
|
Behavior on y {
|
||||||
|
animation: Looks.transition.move.createObject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: dragArea
|
||||||
|
anchors.fill: parent
|
||||||
|
drag.target: parent
|
||||||
|
drag.threshold: 2
|
||||||
|
|
||||||
|
onPressed: event => {
|
||||||
|
trayButton.Drag.hotSpot.x = event.x;
|
||||||
|
trayButton.Drag.hotSpot.y = event.y;
|
||||||
|
trayButton.initialX = trayButton.x;
|
||||||
|
trayButton.initialY = trayButton.y;
|
||||||
|
trayButton.Drag.active = true;
|
||||||
|
}
|
||||||
|
onReleased: {
|
||||||
|
if (!dragArea.drag.active) {
|
||||||
|
trayButton.click();
|
||||||
|
} else {
|
||||||
|
if (!unpinDropArea.containsDrag && unpinDropArea.willUnpin) {
|
||||||
|
// Quickshell would crash if we don't hide this item first. Took me fucking 3 hours to figure out...
|
||||||
|
trayButton.visible = false;
|
||||||
|
TrayService.togglePin(trayButton.item.id);
|
||||||
|
unpinDropArea.willUnpin = false;
|
||||||
|
} else {
|
||||||
|
trayButton.x = trayButton.initialX;
|
||||||
|
trayButton.y = trayButton.initialY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
trayButton.Drag.active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DropArea {
|
||||||
|
id: unpinDropArea
|
||||||
|
anchors.fill: parent
|
||||||
|
property bool willUnpin: false
|
||||||
|
onEntered: willUnpin = false
|
||||||
|
onExited: willUnpin = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import qs.modules.waffle.looks
|
|||||||
Kirigami.Icon {
|
Kirigami.Icon {
|
||||||
id: root
|
id: root
|
||||||
required property string icon
|
required property string icon
|
||||||
|
property alias monochrome: root.isMask
|
||||||
// Should be 16, but it appears the icons have some padding,
|
// Should be 16, but it appears the icons have some padding,
|
||||||
// Unlike the Windows-only Segoe UI icons, the open source FluentUI ones are hella small
|
// Unlike the Windows-only Segoe UI icons, the open source FluentUI ones are hella small
|
||||||
property int implicitSize: 20
|
property int implicitSize: 20
|
||||||
|
|||||||
@@ -17,9 +17,12 @@ Singleton {
|
|||||||
|
|
||||||
property real backgroundTransparency: 0.17
|
property real backgroundTransparency: 0.17
|
||||||
property real contentTransparency: 0.25
|
property real contentTransparency: 0.25
|
||||||
property real shadowTransparency: 0.6
|
|
||||||
colors: QtObject {
|
colors: QtObject {
|
||||||
id: colors
|
id: colors
|
||||||
|
property color ambientShadow: ColorUtils.transparentize("#000000", 0.75)
|
||||||
|
property color bgPanelFooter: root.dark ? "#1C1C1C" : "#EEEEEE"
|
||||||
|
property color bgPanelBody: root.dark ? "#242424" : "#F2F2F2"
|
||||||
|
property color bgPanelSeparator: root.dark ? "#191919" : "#E0E0E0"
|
||||||
property color bg0: root.dark ? "#1C1C1C" : "#EEEEEE"
|
property color bg0: root.dark ? "#1C1C1C" : "#EEEEEE"
|
||||||
property color bg0Border: root.dark ? "#404040" : "#BEBEBE"
|
property color bg0Border: root.dark ? "#404040" : "#BEBEBE"
|
||||||
property color bg1: root.dark ? "#2C2C2C" : "#F7F7F7"
|
property color bg1: root.dark ? "#2C2C2C" : "#F7F7F7"
|
||||||
@@ -34,6 +37,7 @@ Singleton {
|
|||||||
property color fg1: root.dark ? "#D1D1D1" : "#626262"
|
property color fg1: root.dark ? "#D1D1D1" : "#626262"
|
||||||
property color danger: "#C42B1C"
|
property color danger: "#C42B1C"
|
||||||
property color dangerActive: "#B62D1F"
|
property color dangerActive: "#B62D1F"
|
||||||
|
property color warning: "#FF9900"
|
||||||
// property color accent: root.dark ? "#A5C6D8" : "#5377A3"
|
// property color accent: root.dark ? "#A5C6D8" : "#5377A3"
|
||||||
property color accent: Appearance.m3colors.m3primary
|
property color accent: Appearance.m3colors.m3primary
|
||||||
property color accentUnfocused: root.dark ? "#989898" : "#848484"
|
property color accentUnfocused: root.dark ? "#989898" : "#848484"
|
||||||
@@ -61,7 +65,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
property QtObject pixelSize: QtObject {
|
property QtObject pixelSize: QtObject {
|
||||||
property real normal: 11
|
property real normal: 11
|
||||||
property real large: 15
|
property real large: 14
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,6 +119,14 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property Component rotate: Component {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 170
|
||||||
|
easing.type: Easing.BezierSpline
|
||||||
|
easing.bezierCurve: transition.easing.bezierCurve.easeInOut
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
property Component anchor: Component {
|
property Component anchor: Component {
|
||||||
AnchorAnimation {
|
AnchorAnimation {
|
||||||
duration: 160
|
duration: 160
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.functions
|
||||||
|
import qs.modules.waffle.looks
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property var target
|
||||||
|
z: 0
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
fill: target
|
||||||
|
margins: -border.width
|
||||||
|
}
|
||||||
|
|
||||||
|
border.color: Looks.colors.ambientShadow
|
||||||
|
border.width: 1
|
||||||
|
color: "transparent"
|
||||||
|
radius: target.radius + border.width
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import qs
|
||||||
|
import qs.services
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.waffle.looks
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
signal closed()
|
||||||
|
|
||||||
|
property alias border: borderRect
|
||||||
|
required default property Item contentItem
|
||||||
|
property real visualMargin: 12
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
closeAnim.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property bool barAtBottom: Config.options.waffles.bar.bottom
|
||||||
|
|
||||||
|
implicitHeight: borderRect.implicitHeight
|
||||||
|
implicitWidth: borderRect.implicitWidth
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: borderRect
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
radius: Looks.radius.large
|
||||||
|
border.color: Looks.colors.bg2Border
|
||||||
|
border.width: 1
|
||||||
|
implicitWidth: contentItem.implicitWidth + border.width * 2
|
||||||
|
implicitHeight: contentItem.implicitHeight + border.width * 2
|
||||||
|
children: [root.contentItem]
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
top: root.barAtBottom ? undefined : parent.top
|
||||||
|
bottom: root.barAtBottom ? parent.bottom : undefined
|
||||||
|
// Opening anim
|
||||||
|
bottomMargin: root.barAtBottom ? sourceEdgeMargin : 0
|
||||||
|
topMargin: root.barAtBottom ? 0 : sourceEdgeMargin
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
openAnim.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
property real sourceEdgeMargin: -(implicitHeight + root.visualMargin)
|
||||||
|
PropertyAnimation {
|
||||||
|
id: openAnim
|
||||||
|
target: borderRect
|
||||||
|
property: "sourceEdgeMargin"
|
||||||
|
to: 0
|
||||||
|
duration: 200
|
||||||
|
easing.type: Easing.BezierSpline
|
||||||
|
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeIn
|
||||||
|
}
|
||||||
|
SequentialAnimation {
|
||||||
|
id: closeAnim
|
||||||
|
PropertyAnimation {
|
||||||
|
target: borderRect
|
||||||
|
property: "sourceEdgeMargin"
|
||||||
|
to: -(implicitHeight + root.visualMargin)
|
||||||
|
duration: 150
|
||||||
|
easing.type: Easing.BezierSpline
|
||||||
|
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeOut
|
||||||
|
}
|
||||||
|
ScriptAction {
|
||||||
|
script: {
|
||||||
|
root.closed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.functions
|
||||||
|
import qs.modules.waffle.looks
|
||||||
|
|
||||||
|
// Generic button with background
|
||||||
|
Button {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property color colBackgroundHover: Looks.colors.bg2Hover
|
||||||
|
property color colBackgroundActive: Looks.colors.bg2Active
|
||||||
|
property color colBackground: ColorUtils.transparentize(Looks.colors.bg1)
|
||||||
|
|
||||||
|
property alias monochromeIcon: buttonIcon.monochrome
|
||||||
|
property bool forceShowIcon: false
|
||||||
|
|
||||||
|
property var altAction: () => {}
|
||||||
|
property var middleClickAction: () => {}
|
||||||
|
|
||||||
|
property real inset: 2
|
||||||
|
topInset: inset
|
||||||
|
bottomInset: inset
|
||||||
|
leftInset: inset
|
||||||
|
rightInset: inset
|
||||||
|
horizontalPadding: 10
|
||||||
|
verticalPadding: 6
|
||||||
|
implicitHeight: contentItem.implicitHeight + verticalPadding * 2
|
||||||
|
implicitWidth: contentItem.implicitWidth + horizontalPadding * 2
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
radius: Looks.radius.medium
|
||||||
|
color: {
|
||||||
|
if (root.down) {
|
||||||
|
return root.colBackgroundActive;
|
||||||
|
} else if ((root.hovered && !root.down) || root.checked) {
|
||||||
|
return root.colBackgroundHover;
|
||||||
|
} else {
|
||||||
|
return root.colBackground;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Behavior on color {
|
||||||
|
animation: Looks.transition.color.createObject(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.RightButton | Qt.MiddleButton
|
||||||
|
onClicked: (event) => {
|
||||||
|
if (event.button === Qt.LeftButton) root.clicked();
|
||||||
|
if (event.button === Qt.RightButton) root.altAction();
|
||||||
|
if (event.button === Qt.MiddleButton) root.middleClickAction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Item {
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
margins: root.inset
|
||||||
|
}
|
||||||
|
implicitWidth: contentLayout.implicitWidth
|
||||||
|
implicitHeight: contentLayout.implicitHeight
|
||||||
|
RowLayout {
|
||||||
|
id: contentLayout
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
leftMargin: root.horizontalPadding
|
||||||
|
rightMargin: root.horizontalPadding
|
||||||
|
}
|
||||||
|
spacing: 12
|
||||||
|
FluentIcon {
|
||||||
|
id: buttonIcon
|
||||||
|
visible: root.icon.name !== "" || root.forceShowIcon
|
||||||
|
monochrome: true
|
||||||
|
implicitSize: 16
|
||||||
|
Layout.leftMargin: 6
|
||||||
|
Layout.fillWidth: false
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
icon: root.icon.name
|
||||||
|
}
|
||||||
|
WText {
|
||||||
|
Layout.rightMargin: 12
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
|
||||||
|
text: root.text
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
font {
|
||||||
|
pixelSize: Looks.font.pixelSize.large
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import Quickshell
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.functions
|
||||||
|
import qs.modules.waffle.looks
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
implicitHeight: 36
|
||||||
|
|
||||||
|
property color colBackground: ColorUtils.transparentize(Looks.colors.bg1)
|
||||||
|
property color colBackgroundHover: Looks.colors.bg1Hover
|
||||||
|
property color colBackgroundActive: Looks.colors.bg1Active
|
||||||
|
property color color
|
||||||
|
property color colForeground: Looks.colors.fg
|
||||||
|
color: {
|
||||||
|
if (root.down) {
|
||||||
|
return root.colBackgroundActive
|
||||||
|
} else if ((root.hovered && !root.down) || root.checked) {
|
||||||
|
return root.colBackgroundHover
|
||||||
|
} else {
|
||||||
|
return root.colBackground
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
radius: Looks.radius.medium
|
||||||
|
color: root.color
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,42 +10,37 @@ import qs.modules.waffle.looks
|
|||||||
PopupToolTip {
|
PopupToolTip {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property real padding: 2
|
property Item realContentItem
|
||||||
verticalPadding: padding
|
realContentItem: WText {
|
||||||
horizontalPadding: padding
|
text: root.text
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
property real visualMargin: 11
|
||||||
|
verticalPadding: visualMargin
|
||||||
|
horizontalPadding: visualMargin
|
||||||
|
property real realContentVerticalPadding: 8
|
||||||
|
property real realContentHorizontalPadding: 10
|
||||||
|
|
||||||
contentItem: Item {
|
contentItem: Item {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
implicitWidth: realContent.implicitWidth + root.verticalPadding * 2
|
implicitWidth: realContent.implicitWidth + 2 * 2
|
||||||
implicitHeight: realContent.implicitHeight + root.horizontalPadding * 2
|
implicitHeight: realContent.implicitHeight + 2 * 2
|
||||||
|
|
||||||
Rectangle {
|
WAmbientShadow {
|
||||||
id: ambientShadow
|
target: realContent
|
||||||
z: 0
|
|
||||||
anchors {
|
|
||||||
fill: realContent
|
|
||||||
margins: -border.width
|
|
||||||
}
|
|
||||||
border.color: ColorUtils.transparentize(Looks.colors.bg0Border, Looks.shadowTransparency)
|
|
||||||
border.width: 1
|
|
||||||
color: "transparent"
|
|
||||||
radius: realContent.radius + border.width
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: realContent
|
id: realContent
|
||||||
z: 1
|
z: 1
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
implicitWidth: tooltipText.implicitWidth + 10 * 2
|
implicitWidth: root.realContentItem.implicitWidth + root.realContentHorizontalPadding * 2
|
||||||
implicitHeight: tooltipText.implicitHeight + 8 * 2
|
implicitHeight: root.realContentItem.implicitHeight + root.realContentVerticalPadding * 2
|
||||||
color: Looks.colors.bg1
|
color: Looks.colors.bg1
|
||||||
radius: Looks.radius.medium
|
radius: Looks.radius.medium
|
||||||
|
|
||||||
WText {
|
children: [root.realContentItem]
|
||||||
id: tooltipText
|
|
||||||
text: root.text
|
|
||||||
anchors.centerIn: parent
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,10 +135,18 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function syncBrightness() {
|
function syncBrightness() {
|
||||||
const brightnessValue = Math.max(monitor.multipliedBrightness, 0)
|
const brightnessValue = Math.max(monitor.multipliedBrightness, 0);
|
||||||
const rawValueRounded = Math.max(Math.floor(brightnessValue * monitor.rawMaxBrightness), 1);
|
if (isDdc) {
|
||||||
setProc.command = isDdc ? ["ddcutil", "-b", busNum, "setvcp", "10", rawValueRounded] : ["brightnessctl", "--class", "backlight", "s", rawValueRounded, "--quiet"];
|
const rawValueRounded = Math.max(Math.floor(brightnessValue * monitor.rawMaxBrightness), 1);
|
||||||
setProc.startDetached();
|
setProc.command = ["ddcutil", "-b", busNum, "setvcp", "10", rawValueRounded];
|
||||||
|
setProc.startDetached();
|
||||||
|
} else {
|
||||||
|
const valuePercentNumber = Math.floor(brightnessValue * 100);
|
||||||
|
let valuePercent = `${valuePercentNumber}%`;
|
||||||
|
if (valuePercentNumber == 0) valuePercent = "1"; // Prevent fully black
|
||||||
|
setProc.command = ["brightnessctl", "--class", "backlight", "s", valuePercent, "--quiet"];
|
||||||
|
setProc.startDetached();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setBrightness(value: real): void {
|
function setBrightness(value: real): void {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ Singleton {
|
|||||||
|
|
||||||
function enable() {
|
function enable() {
|
||||||
root.active = true
|
root.active = true
|
||||||
Quickshell.execDetached(["bash", "-c", "easyeffects --gapplication-service || flatpak run com.github.wwmm.easyeffects --gapplication-service"])
|
Quickshell.execDetached(["bash", "-c", "easyeffects --hide-window --service-mode || flatpak run com.github.wwmm.easyeffects --hide-window --service-mode"])
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggle() {
|
function toggle() {
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ Singleton {
|
|||||||
|
|
||||||
// Update the distroIcon property based on distroId
|
// Update the distroIcon property based on distroId
|
||||||
switch (distroId) {
|
switch (distroId) {
|
||||||
|
case "artix":
|
||||||
case "arch": distroIcon = "arch-symbolic"; break;
|
case "arch": distroIcon = "arch-symbolic"; break;
|
||||||
case "endeavouros": distroIcon = "endeavouros-symbolic"; break;
|
case "endeavouros": distroIcon = "endeavouros-symbolic"; break;
|
||||||
case "cachyos": distroIcon = "cachyos-symbolic"; break;
|
case "cachyos": distroIcon = "cachyos-symbolic"; break;
|
||||||
|
|||||||
@@ -8,6 +8,14 @@ import Quickshell.Wayland
|
|||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
function togglePin(appId) {
|
||||||
|
if (Config.options.dock.pinnedApps.indexOf(appId) !== -1) {
|
||||||
|
Config.options.dock.pinnedApps = Config.options.dock.pinnedApps.filter(id => id !== appId)
|
||||||
|
} else {
|
||||||
|
Config.options.dock.pinnedApps = Config.options.dock.pinnedApps.concat([appId])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
property list<var> apps: {
|
property list<var> apps: {
|
||||||
var map = new Map();
|
var map = new Map();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import qs.modules.common
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Services.SystemTray
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool smartTray: Config.options.tray.filterPassive
|
||||||
|
property list<var> itemsInUserList: SystemTray.items.values.filter(i => (Config.options.tray.pinnedItems.includes(i.id) && (!smartTray || i.status !== Status.Passive)))
|
||||||
|
property list<var> itemsNotInUserList: SystemTray.items.values.filter(i => (!Config.options.tray.pinnedItems.includes(i.id) && (!smartTray || i.status !== Status.Passive)))
|
||||||
|
|
||||||
|
property bool invertPins: Config.options.tray.invertPinnedItems
|
||||||
|
property list<var> pinnedItems: invertPins ? itemsNotInUserList : itemsInUserList
|
||||||
|
property list<var> unpinnedItems: invertPins ? itemsInUserList : itemsNotInUserList
|
||||||
|
|
||||||
|
function getTooltipForItem(item) {
|
||||||
|
var result = item.tooltipTitle.length > 0 ? item.tooltipTitle
|
||||||
|
: (item.title.length > 0 ? item.title : item.id);
|
||||||
|
if (item.tooltipDescription.length > 0) result += " • " + item.tooltipDescription;
|
||||||
|
if (Config.options.tray.showItemId) result += "\n[" + item.id + "]";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pinning
|
||||||
|
function pin(itemId) {
|
||||||
|
var pins = Config.options.tray.pinnedItems;
|
||||||
|
if (pins.includes(itemId)) return;
|
||||||
|
Config.options.tray.pinnedItems.push(itemId);
|
||||||
|
}
|
||||||
|
function unpin(itemId) {
|
||||||
|
Config.options.tray.pinnedItems = Config.options.tray.pinnedItems.filter(id => id !== itemId);
|
||||||
|
}
|
||||||
|
function togglePin(itemId) {
|
||||||
|
var pins = Config.options.tray.pinnedItems;
|
||||||
|
if (pins.includes(itemId)) {
|
||||||
|
unpin(itemId)
|
||||||
|
} else {
|
||||||
|
pin(itemId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.functions
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
|
||||||
|
/*
|
||||||
|
* System updates service. Currently only supports Arch.
|
||||||
|
*/
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool available: false
|
||||||
|
property int count: 0
|
||||||
|
|
||||||
|
readonly property bool updateAdvised: available && count > Config.options.updates.adviseUpdateThreshold
|
||||||
|
readonly property bool updateStronglyAdvised: available && count > Config.options.updates.stronglyAdviseUpdateThreshold
|
||||||
|
|
||||||
|
function load() {}
|
||||||
|
function refresh() {
|
||||||
|
if (!available) return;
|
||||||
|
print("[Updates] Checking for system updates")
|
||||||
|
checkUpdatesProc.running = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
interval: Config.options.updates.checkInterval * 60 * 1000
|
||||||
|
repeat: true
|
||||||
|
running: Config.ready
|
||||||
|
onTriggered: {
|
||||||
|
print("[Updates] Periodic update check due")
|
||||||
|
root.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: checkAvailabilityProc
|
||||||
|
running: true
|
||||||
|
command: ["which", "checkupdates"]
|
||||||
|
onExited: (exitCode, exitStatus) => {
|
||||||
|
root.available = (exitCode === 0);
|
||||||
|
root.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: checkUpdatesProc
|
||||||
|
command: ["bash", "-c", "checkupdates | wc -l"]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
root.count = parseInt(text.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,6 +28,7 @@ import qs.modules.ii.overlay
|
|||||||
import qs.modules.ii.verticalBar
|
import qs.modules.ii.verticalBar
|
||||||
import qs.modules.ii.wallpaperSelector
|
import qs.modules.ii.wallpaperSelector
|
||||||
|
|
||||||
|
import qs.modules.waffle.actionCenter
|
||||||
import qs.modules.waffle.background
|
import qs.modules.waffle.background
|
||||||
import qs.modules.waffle.bar
|
import qs.modules.waffle.bar
|
||||||
|
|
||||||
@@ -49,6 +50,7 @@ ShellRoot {
|
|||||||
ConflictKiller.load()
|
ConflictKiller.load()
|
||||||
Cliphist.refresh()
|
Cliphist.refresh()
|
||||||
Wallpapers.load()
|
Wallpapers.load()
|
||||||
|
Updates.load()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load enabled stuff
|
// Load enabled stuff
|
||||||
@@ -74,6 +76,7 @@ ShellRoot {
|
|||||||
PanelLoader { identifier: "iiSidebarRight"; component: SidebarRight {} }
|
PanelLoader { identifier: "iiSidebarRight"; component: SidebarRight {} }
|
||||||
PanelLoader { identifier: "iiVerticalBar"; extraCondition: Config.options.bar.vertical; component: VerticalBar {} }
|
PanelLoader { identifier: "iiVerticalBar"; extraCondition: Config.options.bar.vertical; component: VerticalBar {} }
|
||||||
PanelLoader { identifier: "iiWallpaperSelector"; component: WallpaperSelector {} }
|
PanelLoader { identifier: "iiWallpaperSelector"; component: WallpaperSelector {} }
|
||||||
|
PanelLoader { identifier: "wActionCenter"; component: WaffleActionCenter {} }
|
||||||
PanelLoader { identifier: "wBar"; component: WaffleBar {} }
|
PanelLoader { identifier: "wBar"; component: WaffleBar {} }
|
||||||
PanelLoader { identifier: "wBackground"; component: WaffleBackground {} }
|
PanelLoader { identifier: "wBackground"; component: WaffleBackground {} }
|
||||||
|
|
||||||
@@ -87,7 +90,7 @@ ShellRoot {
|
|||||||
property list<string> families: ["ii", "waffle"]
|
property list<string> families: ["ii", "waffle"]
|
||||||
property var panelFamilies: ({
|
property var panelFamilies: ({
|
||||||
"ii": ["iiBar", "iiBackground", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiReloadPopup", "iiScreenCorners", "iiSessionScreen", "iiSidebarLeft", "iiSidebarRight", "iiVerticalBar", "iiWallpaperSelector"],
|
"ii": ["iiBar", "iiBackground", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiReloadPopup", "iiScreenCorners", "iiSessionScreen", "iiSidebarLeft", "iiSidebarRight", "iiVerticalBar", "iiWallpaperSelector"],
|
||||||
"waffle": ["wBar", "wBackground", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiReloadPopup", "iiSessionScreen", "iiSidebarLeft", "iiSidebarRight", "iiWallpaperSelector"],
|
"waffle": ["wBar", "wBackground", "wActionCenter", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiReloadPopup", "iiSessionScreen", "iiSidebarRight", "iiWallpaperSelector"],
|
||||||
})
|
})
|
||||||
function cyclePanelFamily() {
|
function cyclePanelFamily() {
|
||||||
const currentIndex = families.indexOf(Config.options.panelFamily)
|
const currentIndex = families.indexOf(Config.options.panelFamily)
|
||||||
|
|||||||
@@ -211,6 +211,7 @@ Extra dependencies.
|
|||||||
- `qt6-translations`
|
- `qt6-translations`
|
||||||
- `qt6-virtualkeyboard`
|
- `qt6-virtualkeyboard`
|
||||||
- `qt6-wayland`
|
- `qt6-wayland`
|
||||||
|
- `kirigami`
|
||||||
- `kdialog`
|
- `kdialog`
|
||||||
- `syntax-highlighting`
|
- `syntax-highlighting`
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ conflicts=("quickshell-git")
|
|||||||
_pkgname=quickshell
|
_pkgname=quickshell
|
||||||
pkgname="$_prefix-$_pkgname-git"
|
pkgname="$_prefix-$_pkgname-git"
|
||||||
pkgver=0.1.0.r1
|
pkgver=0.1.0.r1
|
||||||
pkgrel=5
|
pkgrel=6
|
||||||
pkgdesc="$_pkgname-git pinned commit and extra deps for $_prefix"
|
pkgdesc="$_pkgname-git pinned commit and extra deps for $_prefix"
|
||||||
arch=(x86_64 aarch64)
|
arch=(x86_64 aarch64)
|
||||||
url='https://git.outfoxxed.me/quickshell/quickshell'
|
url='https://git.outfoxxed.me/quickshell/quickshell'
|
||||||
@@ -39,6 +39,7 @@ depends=(
|
|||||||
qt6-translations
|
qt6-translations
|
||||||
qt6-virtualkeyboard
|
qt6-virtualkeyboard
|
||||||
qt6-wayland
|
qt6-wayland
|
||||||
|
kirigami
|
||||||
kdialog
|
kdialog
|
||||||
syntax-highlighting
|
syntax-highlighting
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
Name: Bibata-Modern-Classic
|
|
||||||
Version: 2.0.7
|
|
||||||
Release: %autorelease
|
|
||||||
Summary: Open source, compact, and material designed cursor set.
|
|
||||||
|
|
||||||
License: GPL-3.0
|
|
||||||
URL: https://github.com/ful1e5/Bibata_Cursor
|
|
||||||
Source0: %{name}.tar.xz
|
|
||||||
|
|
||||||
BuildArch: noarch
|
|
||||||
|
|
||||||
%description
|
|
||||||
Open source, compact, and material designed cursor set.
|
|
||||||
|
|
||||||
%prep
|
|
||||||
wget --content-disposition -q -N -P %{_sourcedir} %{url}/releases/download/v%{version}/Bibata-Modern-Classic.tar.xz
|
|
||||||
wget -q -O %{_buildrootdir}/LICENSE %{url}/raw/refs/heads/main/LICENSE
|
|
||||||
%setup -q -n %{name}
|
|
||||||
|
|
||||||
%build
|
|
||||||
:
|
|
||||||
|
|
||||||
%install
|
|
||||||
install -d -m 0755 %{buildroot}%{_iconsdir}/Bibata-Modern-Classic
|
|
||||||
cp -r * %{buildroot}%{_iconsdir}/Bibata-Modern-Classic
|
|
||||||
|
|
||||||
install -d -m 0755 %{buildroot}%{_licensedir}/%{name}
|
|
||||||
install -m 0644 %{_buildrootdir}/LICENSE %{buildroot}%{_licensedir}/%{name}/
|
|
||||||
|
|
||||||
%files
|
|
||||||
%{_iconsdir}/Bibata-Modern-Classic
|
|
||||||
%license %{_licensedir}/%{name}/LICENSE
|
|
||||||
|
|
||||||
%changelog
|
|
||||||
%autochangelog
|
|
||||||
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
Name: JetBrainsMonoNerdFont-Regular
|
|
||||||
Version: 1.2
|
|
||||||
Release: %autorelease
|
|
||||||
Summary: JetBrainsMonoNerdFonts (TrueType Outlines) (Regulear)
|
|
||||||
|
|
||||||
License: MIT
|
|
||||||
URL: https://github.com/Zhaopudark/JetBrainsMonoNerdFonts
|
|
||||||
Source0: %{name}
|
|
||||||
|
|
||||||
BuildRequires: fonts-rpm-macros
|
|
||||||
BuildArch: noarch
|
|
||||||
|
|
||||||
%description
|
|
||||||
An auto-updated compiling version of JetBrains Mono that has been patched with Nerd Fonts.
|
|
||||||
|
|
||||||
%prep
|
|
||||||
wget --content-disposition -q -N -P %{_sourcedir} %{url}/releases/download/v%{version}/JetBrainsMonoNerdFont-Regular-v%{version}.ttf
|
|
||||||
wget -q -P %{_sourcedir} %{url}/raw/refs/heads/main/LICENSE
|
|
||||||
|
|
||||||
%build
|
|
||||||
:
|
|
||||||
|
|
||||||
%install
|
|
||||||
install -d -m 0755 %{buildroot}%{_fontdir}
|
|
||||||
install -m 0644 %{_sourcedir}/JetBrainsMonoNerdFont*ttf %{buildroot}%{_fontdir}
|
|
||||||
|
|
||||||
install -d -m 0755 %{buildroot}%{_licensedir}/%{name}
|
|
||||||
install -m 0644 %{_sourcedir}/LICENSE %{buildroot}%{_licensedir}/%{name}/
|
|
||||||
|
|
||||||
%post
|
|
||||||
/usr/bin/fc-cache -fv >/dev/null 2>&1 || :
|
|
||||||
|
|
||||||
%postun
|
|
||||||
/usr/bin/fc-cache -fv >/dev/null 2>&1 || :
|
|
||||||
|
|
||||||
%files
|
|
||||||
%{_fontdir}/JetBrainsMonoNerdFont*ttf
|
|
||||||
%license %{_licensedir}/%{name}/LICENSE
|
|
||||||
|
|
||||||
%changelog
|
|
||||||
%autochangelog
|
|
||||||
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
%global commit0 0e3707f6dafebb121d98b53c64364d16fefe481d
|
|
||||||
%global shortcommit0 %(c=%{commit0}; echo ${c:0:7})
|
|
||||||
%global bumpver 100
|
|
||||||
|
|
||||||
Name: MicroTeX
|
|
||||||
Version: 0.0.1%{?bumpver:^%{bumpver}.git%{shortcommit0}}
|
|
||||||
Release: %autorelease
|
|
||||||
Summary: A dynamic, cross-platform, and embeddable LaTeX rendering library
|
|
||||||
|
|
||||||
License: MIT
|
|
||||||
URL: https://github.com/NanoMichael/MicroTeX
|
|
||||||
Source0: %{name}-%{shortcommit0}.tar.gz
|
|
||||||
|
|
||||||
BuildRequires: gcc-c++ cmake
|
|
||||||
BuildRequires: pkgconfig(tinyxml2)
|
|
||||||
BuildRequires: gtkmm3.0-devel gtksourceviewmm3-devel cairomm-devel
|
|
||||||
|
|
||||||
%description
|
|
||||||
MicroTeX is a library for rendering LaTeX mathematical formulas, supporting multiple backends
|
|
||||||
such as GTK+, Qt, and Skia. It provides both library components and demo applications for
|
|
||||||
testing LaTeX rendering.
|
|
||||||
|
|
||||||
%prep
|
|
||||||
curl -fsSL --retry 3 \
|
|
||||||
https://codeload.github.com/NanoMichael/MicroTeX/tar.gz/%{shortcommit0} \
|
|
||||||
-o %{_sourcedir}/%{name}-%{shortcommit0}.tar.gz
|
|
||||||
%setup -q -n %{name}-%{shortcommit0}
|
|
||||||
|
|
||||||
%build
|
|
||||||
mkdir -p build
|
|
||||||
cd build
|
|
||||||
cmake ..
|
|
||||||
make -j$(nproc)
|
|
||||||
|
|
||||||
%install
|
|
||||||
mkdir -p %{buildroot}/opt/MicroTeX
|
|
||||||
cp build/LaTeX %{buildroot}/opt/MicroTeX/
|
|
||||||
cp -r build/res %{buildroot}/opt/MicroTeX/
|
|
||||||
|
|
||||||
install -Dpm 0644 LICENSE %{buildroot}%{_licensedir}/%{name}/LICENSE
|
|
||||||
install -Dpm 0644 res/greek/LICENSE %{buildroot}%{_licensedir}/%{name}/LICENSE-greek
|
|
||||||
install -Dpm 0644 res/cyrillic/LICENSE %{buildroot}%{_licensedir}/%{name}/LICENSE-cyrillic
|
|
||||||
|
|
||||||
%files
|
|
||||||
/opt/MicroTeX/
|
|
||||||
%license %{_licensedir}/%{name}/
|
|
||||||
|
|
||||||
%changelog
|
|
||||||
%autochangelog
|
|
||||||
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
Name: breeze-plus
|
|
||||||
Version: 6.19.0
|
|
||||||
Release: %autorelease
|
|
||||||
Summary: Breeze theme with additional icons
|
|
||||||
|
|
||||||
License: LGPL-2.1
|
|
||||||
URL: https://github.com/mjkim0727/breeze-plus
|
|
||||||
Source0: %{name}-%{version}.tar.gz
|
|
||||||
|
|
||||||
BuildArch: noarch
|
|
||||||
|
|
||||||
%description
|
|
||||||
Breeze icon theme with additional icons for applications not covered by the
|
|
||||||
official Breeze theme. Includes icons for Wine, third-party apps, and more.
|
|
||||||
|
|
||||||
%prep
|
|
||||||
wget --content-disposition -q -N -P %{_sourcedir} %{url}/archive/refs/tags/%{version}.tar.gz
|
|
||||||
%setup -q
|
|
||||||
|
|
||||||
%build
|
|
||||||
:
|
|
||||||
|
|
||||||
%install
|
|
||||||
install -d -m 0755 %{buildroot}%{_iconsdir}/breeze-plus
|
|
||||||
cp -r src/breeze-plus %{buildroot}%{_iconsdir}/
|
|
||||||
cp -r src/breeze-plus-dark %{buildroot}%{_iconsdir}/
|
|
||||||
|
|
||||||
install -d -m 0755 %{buildroot}%{_licensedir}/%{name}
|
|
||||||
install -m 0644 LICENSE %{buildroot}%{_licensedir}/%{name}/
|
|
||||||
|
|
||||||
%files
|
|
||||||
%{_iconsdir}/breeze-plus/
|
|
||||||
%{_iconsdir}/breeze-plus-dark/
|
|
||||||
%license %{_licensedir}/%{name}/LICENSE
|
|
||||||
|
|
||||||
%changelog
|
|
||||||
%autochangelog
|
|
||||||
|
|
||||||