Compare commits
212 commits
lolcathost
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| f0c7f565c3 | |||
| 540fd9c2a9 | |||
| a03ea35af7 | |||
| 91afb32049 | |||
| 8f7a725fd5 | |||
| 8a14f7e2fc | |||
| 8f222f454a | |||
| ca3fd4093f | |||
| c8d3fe1e6b | |||
| e2f641e553 | |||
| 728f933f39 | |||
| ffb9b35d46 | |||
| 2fb9171d92 | |||
| 11b4c920fc | |||
| 09db1c47e1 | |||
| 17807752e5 | |||
| 46ed077813 | |||
| 596fcd5389 | |||
| fd48d6af9a | |||
| 892a1ae877 | |||
| 1ee0ba1a4c | |||
| 63c1f112d4 | |||
| ce3eb7a6d8 | |||
| 1d54b41347 | |||
| 1600fd2885 | |||
| 8e2aad53be | |||
| a29c66e35d | |||
| f51ac822e0 | |||
| 78c75ea740 | |||
| c46d9665a1 | |||
| d26b8af26f | |||
| 4e615703a6 | |||
| 328c628291 | |||
| 8ec227aa10 | |||
| d094fbb26f | |||
| dc0ec2f3f1 | |||
| 2dde0450c4 | |||
| 2da0075992 | |||
| a04641fc9d | |||
| c05db67974 | |||
| 5c955e5232 | |||
| 70ed4a9a38 | |||
| 120b753882 | |||
| 3e1d106179 | |||
| f9df463872 | |||
| bf22bfbcf4 | |||
| 81c7c25c6f | |||
| cb6f984065 | |||
| 75751e3085 | |||
| c94e75bb02 | |||
| eaea98a362 | |||
| a35cedeecb | |||
| 6fbaf7fe89 | |||
| 364efb25ea | |||
| eb02262ae6 | |||
| 95bf9fe6ad | |||
| a33e8a0147 | |||
| 1f35c727ed | |||
| 99a0adb621 | |||
| db0a34ebbd | |||
| 484a8df77b | |||
| caa5bc0394 | |||
| 0213b82a2f | |||
| 8db3e2693e | |||
| f68a8e6d19 | |||
| 1c0ee94532 | |||
| ec542cc738 | |||
| 940a79292e | |||
| d1cfd55e67 | |||
| 91f1033c9e | |||
| af62453ef7 | |||
| f4b4052c30 | |||
| b2e95eebd7 | |||
| d077f4bfd9 | |||
| 98244e7ecf | |||
| 186c0c741a | |||
| 7ecf75bef5 | |||
| dc12ab717b | |||
| 60a6b07c9d | |||
| 7069840beb | |||
| 63e8a31e7f | |||
| 7ab29bfe07 | |||
| d68132b8fb | |||
| d3a642fafb | |||
| 0129fe2b97 | |||
| ee7e38e7ba | |||
| 0eeb94b65c | |||
| 874852ca07 | |||
| 72d68585bc | |||
| 828203ffe8 | |||
| c5207a5406 | |||
| de67846d56 | |||
| 6d4c43dcbe | |||
| ea63bc85ad | |||
| d2d27a7cf9 | |||
| d59c11a414 | |||
| 6e3221a410 | |||
| c0dda89f83 | |||
| 174061f662 | |||
| 30d49efe57 | |||
| fe8db21616 | |||
| b303ffb3cc | |||
| 7d4e0f3559 | |||
| b5dab67f08 | |||
| 9896d98154 | |||
| e4bfdad61b | |||
| 20bdc7b50c | |||
| af31d0273c | |||
| d0cc0504fa | |||
| fe2a8f6837 | |||
| 8661d198b2 | |||
| f32b784ed7 | |||
| c6ced19dee | |||
| 230af2eca4 | |||
| bad1cbbe8c | |||
| 7c0f73beb8 | |||
| 3eef80123d | |||
| 0a231108eb | |||
| da63d4a2be | |||
| 2d529a46d5 | |||
| 999be39b36 | |||
| 3d136d90f0 | |||
| 733b383a7c | |||
| 8cee3dec34 | |||
| 531122d9b6 | |||
| 0a557e7195 | |||
| 7304fa0f51 | |||
| 83b7f2650a | |||
| 97d6d8919c | |||
| 8613df22fd | |||
| 5b2a7b7d9f | |||
| 490249583a | |||
| 48c4d22632 | |||
| 87c92d308b | |||
| f109744b87 | |||
| 90be1ef9fb | |||
| 65d6c36c3e | |||
| 9fd929ae7b | |||
| e0174e669c | |||
| c9899c797e | |||
| e2c8d980f8 | |||
| 9f4c664250 | |||
| 15a8cb1c55 | |||
| 9f6bf432bc | |||
| db0b1c3883 | |||
| 2cbf2f83a4 | |||
| 30f3b04fb0 | |||
| 759ad1c5b5 | |||
| 9863e6a726 | |||
| a4741a2357 | |||
| a23c48b138 | |||
| fd2857742f | |||
| a0a97c9f42 | |||
| 7e55a46db7 | |||
| f99f6e8c94 | |||
| 8e2335c886 | |||
| 2d59248e1c | |||
| 06c25186b7 | |||
| e70e804c34 | |||
| 856f424393 | |||
| 334845da97 | |||
| 84f0364bef | |||
| 6824eff694 | |||
| a5631ee6f9 | |||
| 1b09aac8fc | |||
| 0762e2fba6 | |||
| 58065c0478 | |||
| 6ccfdadeb5 | |||
| 95a8af3e89 | |||
| 71176846d6 | |||
| abed1dec09 | |||
| 4b03d162c7 | |||
| 142dad8f68 | |||
| 5988687e75 | |||
| dab56acd19 | |||
| ee70819b3f | |||
| 78880c5af2 | |||
| 852d2232b0 | |||
| 832b25183b | |||
| fac296efb8 | |||
| 45ad6da23c | |||
| cd56f7af93 | |||
| f98b3fd945 | |||
| 5cd5ca4987 | |||
| 54ecb45922 | |||
| 2bd0b967cb | |||
| ba3f4f6f7b | |||
| 5a15c239cd | |||
| 3bc320cc6a | |||
| c626227f55 | |||
| 09c38f02ea | |||
| 35b54acb85 | |||
| b3bb2227d1 | |||
| b646675328 | |||
| c3b02c5f7b | |||
| 9636eab7f6 | |||
| 61b4615aee | |||
| 6f3c509510 | |||
| 4175d8e0f6 | |||
| 5aa769343f | |||
| d178606f7d | |||
| 4a19a87761 | |||
| db9479fa96 | |||
| 0f3a016a3d | |||
| 20d938a506 | |||
| 64d5097f1a | |||
| d39ba5da80 | |||
| 79504da0a5 | |||
| 16c4e77524 | |||
| f46de5b1d7 | |||
| 23942b961e | |||
| a448ce3f39 |
6
.gitignore
vendored
Executable file → Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
ISSUES/
|
||||||
|
secrets/
|
||||||
|
nib/
|
||||||
|
|
||||||
|
result
|
||||||
|
rebuild*.log
|
||||||
109
GUIDE.md
Normal file
|
|
@ -0,0 +1,109 @@
|
||||||
|
# The Nix Documentation Situation
|
||||||
|
The Nix documentation situation is notorious bad. It's difficult to find
|
||||||
|
a concise answer with detailed justification/explanation. And most people
|
||||||
|
(myself included) tend resort to the [ArchWiki](https://wiki.archlinux.org).
|
||||||
|
> [!NOTE]
|
||||||
|
> The [Nix documentation team](https://nixos.org/community/teams/documentation) has an incredibly difficult job.
|
||||||
|
|
||||||
|
Unlike the *centralised* [ArchWiki](https://wiki.archlinux.org), the Nix ecosystem
|
||||||
|
is incredibly large:
|
||||||
|
1. **Nix** (the package manager)
|
||||||
|
2. **Nix/NixLang** (the programming language)
|
||||||
|
3. **Nixpkgs** (the package repository)
|
||||||
|
4. **NixOS** (the linux distribution)
|
||||||
|
5. **Home-Manager** (user environment management)
|
||||||
|
6. **NUR** (Nix User Repository, like the AUR but Nix!)
|
||||||
|
7. *and **many** more...*
|
||||||
|
|
||||||
|
Often each project has its own website, wiki, styling, etc. There is tonnes
|
||||||
|
of information available online but its so hard to find it.
|
||||||
|
|
||||||
|
**Notable organisations:**
|
||||||
|
1. NixOS Foundation (*official organisation that maintains Nix/Nixpkgs/NixOS*)
|
||||||
|
2. Nix Community (*unofficial community providing infrastructure/hosting/visibility for projects*)
|
||||||
|
|
||||||
|
## About Me
|
||||||
|
I love and hate Nix simultaneously.
|
||||||
|
|
||||||
|
Originally *(circa 2023)* I used Windows 10/11 exclusively for programming.
|
||||||
|
But this is tedious and my friend started mentioning Arch Linux. So with their
|
||||||
|
help I formatted a spare SSD and began my journey.
|
||||||
|
|
||||||
|
But I **REALLY** like computers... I have servers, routers, 3 computers
|
||||||
|
actively powered in my bedroom, and *I believe* 8 laptops *currently* in my posession.
|
||||||
|
|
||||||
|
Documenting **every** change I make to a system and spending a week
|
||||||
|
setting up a device I don't really care about isn't sustainable.
|
||||||
|
And then *(circa October 2024)* I learnt about NixOS... And now life is "easy".
|
||||||
|
But learning Nix/NixLang/Nixpkgs/NixOS/Home-Manager/blah-blah-blah was exhausting.
|
||||||
|
So now I'll try to simplify this learning curve for other newbies **<3**
|
||||||
|
|
||||||
|
|
||||||
|
## Nix/NixOS How To
|
||||||
|
### NixOS Documentation
|
||||||
|
Using "the" NixOS wiki is surprisingly confusing (at least it was for me).
|
||||||
|
Why? Because there are multiple and you probably won't realise the difference.
|
||||||
|
|
||||||
|
**Main Wikis:**
|
||||||
|
> These are visually and structurally identical... And are both community run.
|
||||||
|
> But they're content does differ. [nixos.wiki] was created
|
||||||
|
> because ""[wiki.nixos.org] was too limiting with regards to wiki features".
|
||||||
|
1. [https://wiki.nixos.org] (the **official** NixOS wiki)
|
||||||
|
2. [https://nixos.wiki] (the **unofficial** user's wiki, community run)
|
||||||
|
|
||||||
|
|
||||||
|
**Other Resources:**
|
||||||
|
> [!TODO]
|
||||||
|
|
||||||
|
|
||||||
|
### Migrate to a Newer Version of Nixpkgs
|
||||||
|
```bash
|
||||||
|
# Determine the channel name you're using
|
||||||
|
nix-channel --list
|
||||||
|
nix-channel --remove <OLD_CHANNEL>
|
||||||
|
nix-channel --add <NEW_CHANNEL> # ie https://nixos.org/channels/nixos-25.05
|
||||||
|
nix-channel --update
|
||||||
|
|
||||||
|
# Now upgrade system profile (log to file in case of failure)
|
||||||
|
nixos-rebuild boot --upgrade | tee rebuild.log
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Security Implications
|
||||||
|
### NixOS Default Home Permissions
|
||||||
|
```bash
|
||||||
|
# Executing from $HOME
|
||||||
|
>>> mkdir example.d && ls -l example.d
|
||||||
|
-rw-r--r-- 1 me users 1 Jul 25 10:13 example.d
|
||||||
|
>>> echo > example.f && ls -l example.f
|
||||||
|
-rw-r--r-- 1 me users 1 Jul 25 10:15 example.f
|
||||||
|
|
||||||
|
## But these ignore facl?
|
||||||
|
>>> getfacl "$HOME"
|
||||||
|
# file: home/me
|
||||||
|
# owner: me
|
||||||
|
# group: users
|
||||||
|
user::rwx
|
||||||
|
group::---
|
||||||
|
other::---
|
||||||
|
```
|
||||||
|
Many commands default to permissions that ignore the file access control listl (file ACLs).
|
||||||
|
This is not a NixOS specific issue. However this isn't ideal from a security perspective.
|
||||||
|
The simplest solution is a recursive `chmod -R 600 ~` but there are plenty of files we
|
||||||
|
intentionally want to be different.
|
||||||
|
> [!TODO]
|
||||||
|
> Solution: Make a Nix/Home-Manager package allowing for control over folder permissions.
|
||||||
|
> SOlution: Also it should warn if any files owned by $USER have a 2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Further Reading
|
||||||
|
### Finding New Things to Do
|
||||||
|
`man 5 configuration.nix` is incredibly useful
|
||||||
|
similar info can be found at https://mynixos.com/options
|
||||||
|
|
||||||
|
### For your curiosity
|
||||||
|
1. https://wiki.nixos.org/wiki/Firejail
|
||||||
|
|
||||||
|
|
||||||
52
README.md
Executable file → Normal file
|
|
@ -1,11 +1,8 @@
|
||||||
|
## My NixOS Flake
|
||||||
### Philosophy
|
### Philosophy
|
||||||
I try to use Home Manager as little as possible. When I first started with NixOS I found
|
> [!TODO] My philosophy has kinda changed since the beginning
|
||||||
it distracting and confusing. NixOS already handles system wide and user packages, so having
|
|
||||||
another user level package management method was baffling. Obviously I understand now how
|
|
||||||
it can be useful (so I do use it). But where possible I will instead use the functionality
|
|
||||||
of Nix rather than Home Manager.
|
|
||||||
|
|
||||||
###### Structuring Modules
|
### Repo Structure
|
||||||
Modules are organised into groups (ie "Core"), from here a module is structured as either:
|
Modules are organised into groups (ie "Core"), from here a module is structured as either:
|
||||||
1. a single `.nix` file (ie bluetooth.nix). I do this when I won't implement an alternative
|
1. a single `.nix` file (ie bluetooth.nix). I do this when I won't implement an alternative
|
||||||
2. a directory (ie `sound`) containing a set of alternative implementations and a `default.nix`
|
2. a directory (ie `sound`) containing a set of alternative implementations and a `default.nix`
|
||||||
|
|
@ -13,15 +10,19 @@ that simply imports one of the implementations. For the `sound` example I curren
|
||||||
to default to `pipewire.nix`. I haven't made alternatives yet but the idea is that it is HIGHLY likely
|
to default to `pipewire.nix`. I haven't made alternatives yet but the idea is that it is HIGHLY likely
|
||||||
I do in future.
|
I do in future.
|
||||||
|
|
||||||
|
### Security Considerations
|
||||||
|
###### Hashing
|
||||||
|
For services where password hashing is done infrequently (ie my forgejo instance with signups disabled)
|
||||||
|
use argon2 (argon2id) with default `argon2$2$65536$8$50` (typically). Otherwise bcrypt is preferred.
|
||||||
|
|
||||||
### TODO
|
### TODO
|
||||||
There are a lot of `TODO` items in this repository. To improve these dotfiles
|
There are a lot of commented `# TODO: ...` items in this repository.
|
||||||
I should run a command to find files containing "TODO" and then implement the
|
All (most) of my commented directives can be found via this pattern:
|
||||||
recommendation I left behind :)
|
```sh
|
||||||
|
grep -rnE '^\s*(//|#)\s*[A-Z]*:\s*.+$' --exclude-dir=.git 2>/dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
### Random Explanation of Fonts
|
||||||
|
|
||||||
##### Small Explanation of Fonts
|
|
||||||
There are four types of fonts (to my knowledge at least):
|
There are four types of fonts (to my knowledge at least):
|
||||||
1. serif (funny squigles / small elegant strokes included)
|
1. serif (funny squigles / small elegant strokes included)
|
||||||
2. sans-serif (meaning "without serifs")
|
2. sans-serif (meaning "without serifs")
|
||||||
|
|
@ -33,19 +34,9 @@ Fun fact: on Android, the emojis you are seeing are part of the noto-emoji font
|
||||||
For finding a font for programming I highly recommend trying https://www.codingfont.com/
|
For finding a font for programming I highly recommend trying https://www.codingfont.com/
|
||||||
|
|
||||||
|
|
||||||
### My config
|
### Links
|
||||||
|
#### Inspiration
|
||||||
Font:
|
##### Explaining my Vision with r/unixporn posts
|
||||||
Iosevka nerd font set as default/prefered font
|
|
||||||
Terminal uses IosevkaTerm nerd font
|
|
||||||
|
|
||||||
Home-Manager:
|
|
||||||
I just to use home-manager standalone and not as a NixOS module, thus allowing
|
|
||||||
my dotfiles to also work on non-NixOS systems.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Explaining my Vision with r/unixporn posts
|
|
||||||
I want the side panel from https://www.reddit.com/r/unixporn/comments/12wpvyf/hyprland_eww_is_all_i_need/
|
I want the side panel from https://www.reddit.com/r/unixporn/comments/12wpvyf/hyprland_eww_is_all_i_need/
|
||||||
but not the colour scheme and I'm 50/50 on the bar being on th eleft side lol. Also I love the volume bar on the right!
|
but not the colour scheme and I'm 50/50 on the bar being on th eleft side lol. Also I love the volume bar on the right!
|
||||||
|
|
||||||
|
|
@ -64,15 +55,22 @@ Their window decorations and bar are great, also being able to hide everything u
|
||||||
https://www.reddit.com/r/unixporn/comments/vkcasz/i3gaps_i_prefer_light_mode/
|
https://www.reddit.com/r/unixporn/comments/vkcasz/i3gaps_i_prefer_light_mode/
|
||||||
If their colour scheme was a little less white I'd love it but overall one of my favourites every
|
If their colour scheme was a little less white I'd love it but overall one of my favourites every
|
||||||
|
|
||||||
|
##### Other Inspiring Shtuff
|
||||||
|
1. https://github.com/sabrehagen/desktop-environment
|
||||||
|
|
||||||
### Wallpaper Sources
|
#### Wallpaper Sources
|
||||||
1. https://www.wallpaperflare.com/
|
1. https://www.wallpaperflare.com/
|
||||||
2. https://alphacoders.com
|
2. https://alphacoders.com
|
||||||
especially this one person: https://alphacoders.com/users/profile/69089/robokoboto
|
especially this one person: https://alphacoders.com/users/profile/69089/robokoboto
|
||||||
and also the lofi category: https://alphacoders.com/lofi
|
and also the lofi category: https://alphacoders.com/lofi
|
||||||
|
|
||||||
|
#### Teach Yourself Nix
|
||||||
|
1. https://github.com/XNM1/linux-nixos-hyprland-config-dotfiles)
|
||||||
|
Really good security oriented NixOS stuff
|
||||||
|
2. https://jade.fyi/blog/flakes-arent-real/
|
||||||
|
Interesting blog post on using flakes
|
||||||
|
|
||||||
### Credits
|
#### Credits
|
||||||
1. https://github.com/XNM1/linux-nixos-hyprland-config-dotfiles
|
1. https://github.com/XNM1/linux-nixos-hyprland-config-dotfiles
|
||||||
The simplicity of their layout is amazing, was really good to pick out small modules and learn how something works / is configured.
|
The simplicity of their layout is amazing, was really good to pick out small modules and learn how something works / is configured.
|
||||||
2. https://github.com/Misterio77/nix-starter-configs
|
2. https://github.com/Misterio77/nix-starter-configs
|
||||||
|
|
|
||||||
11
SCREENSHARING
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
Excellent Resource
|
||||||
|
https://gist.github.com/brunoanc/2dea6ddf6974ba4e5d26c3139ffb7580#install-xdg-desktop-portal-and-friends
|
||||||
|
|
||||||
|
Hyprland official page on screensharing
|
||||||
|
https://wiki.hyprland.org/Useful-Utilities/Screen-Sharing/
|
||||||
|
|
||||||
|
|
||||||
|
Multiple sources seem to think that use xdg-desktop-portal-wlr works (but I can't stream individual applications)
|
||||||
|
but I suppose that's better than nothing?
|
||||||
|
|
||||||
|
Also check out xwaylandvideobridge
|
||||||
32
TODO.md
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
## Next Up
|
||||||
|
1. Rename user "ae" to "cry" or "vps"
|
||||||
|
2. Add 404 page to nginx on hyrule
|
||||||
|
3. Add a user called "mirror" that stores important mirrors (inspiration: https://git.gay/mirror)
|
||||||
|
|
||||||
|
## TODO
|
||||||
|
SOON: fix having to keep specifying new sha256 for home-manager (where I fetchTarball for it)
|
||||||
|
|
||||||
|
Create a command palette accessible with MOD+P (MOD => Windows Key)
|
||||||
|
(ie make fullscreen, send to monitor, etc)
|
||||||
|
|
||||||
|
Boring stuff (ie work and uni should go on a separate user account)
|
||||||
|
on in some separate $HOME atleast
|
||||||
|
|
||||||
|
Is home-manager installed standalone? If so please remove that...
|
||||||
|
|
||||||
|
Rewrite the README.md file its all over the place (add more structure to the `docs` directory instead)
|
||||||
|
|
||||||
|
Add a MAC Changer module like
|
||||||
|
https://github.com/XNM1/linux-nixos-hyprland-config-dotfiles/blob/main/nixos/mac-randomize.nix
|
||||||
|
|
||||||
|
Make each monitor's window styling slightly different (just for fun)
|
||||||
|
|
||||||
|
Research "input methods" ie https://wiki.archlinux.org/title/Input_method
|
||||||
|
|
||||||
|
Bind 5 workspaces per connected monitor.
|
||||||
|
Then use the command palette (discussed prior) to send to
|
||||||
|
a different workspace (ie because I currently use MOD+SHIFT+n
|
||||||
|
but if n>=10 then it doesnt work! hence we need a command palette!)
|
||||||
|
|
||||||
|
Can I run openvpn only for a specific proccess and its children?
|
||||||
|
then ie run qbittorrent (just in case the VPN isnt private)
|
||||||
6
banner
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
.------------.
|
||||||
|
| oh my |
|
||||||
|
'------------'
|
||||||
|
^ (\_(\
|
||||||
|
'----- ( -.-)
|
||||||
|
o_(")(")
|
||||||
373
config.temp/hyprland.conf
Executable file
|
|
@ -0,0 +1,373 @@
|
||||||
|
# All hyprland configuration variables are listed (even niche ones)
|
||||||
|
# to save you the hassle. Reference: https://wiki.hypr.land/Configuring/Variables/
|
||||||
|
#
|
||||||
|
# You can split this configuration into multiple files
|
||||||
|
# Create your files separately and then link them to this file like this:
|
||||||
|
# source = ~/.config/hypr/myColors.conf
|
||||||
|
|
||||||
|
|
||||||
|
################
|
||||||
|
### MONITORS ###
|
||||||
|
################
|
||||||
|
|
||||||
|
# Programming:
|
||||||
|
monitor=eDP-1, highres@highrr, auto, 1.0
|
||||||
|
# Comfy:
|
||||||
|
#monitor=eDP-1, highres@highrr, auto, 1.5
|
||||||
|
|
||||||
|
|
||||||
|
###################
|
||||||
|
### MY PROGRAMS ###
|
||||||
|
###################
|
||||||
|
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Keywords/
|
||||||
|
|
||||||
|
# Set programs that you use
|
||||||
|
$terminal = ghostty #rio
|
||||||
|
$fileManager = thunar
|
||||||
|
# $menu = wofi --show drun
|
||||||
|
# $menu = ags -t "applauncher"
|
||||||
|
$menu = fuzzel
|
||||||
|
$colorpicker = hyprpicker | head -c 7 | wl-copy
|
||||||
|
|
||||||
|
#################
|
||||||
|
### AUTOSTART ###
|
||||||
|
#################
|
||||||
|
|
||||||
|
# Autostart necessary processes (like notifications daemons, status bars, etc.)
|
||||||
|
# Or execute your favorite apps at launch like this:
|
||||||
|
|
||||||
|
# exec-once = $terminal
|
||||||
|
# exec-once = nm-applet &
|
||||||
|
# exec-once = waybar & hyprpaper & firefox
|
||||||
|
exec-once = swww-daemon &
|
||||||
|
exec-once = mako &
|
||||||
|
# TODO: or do I do `swww init` or `swww restore`?
|
||||||
|
|
||||||
|
# █▀▀ █▄░█ █░█ █░█ ▄▀█ █▀█
|
||||||
|
# ██▄ █░▀█ ▀▄▀ ▀▄▀ █▀█ █▀▄
|
||||||
|
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Environment-variables/
|
||||||
|
|
||||||
|
#env = HYPRCURSOR_THEME,Bibata-Modern-Ice
|
||||||
|
env = HYPRCURSOR_SIZE,16
|
||||||
|
#env = XCURSOR_THEME,Bibata-Modern-Ice
|
||||||
|
env = XCURSOR_SIZE,16
|
||||||
|
|
||||||
|
env = QT_QPA_PLATFORM,wayland
|
||||||
|
env = QT_QPA_PLATFORMTHEME,qt5ct
|
||||||
|
env = XDG_MENU_PREFIX,arch-
|
||||||
|
|
||||||
|
# TODO: make this variable (not dependent on helix) in my flake
|
||||||
|
env = EDITOR,hx
|
||||||
|
env = TERMINAL,rio
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# DEBUG: attempting to get screensharing working... (please god help me)
|
||||||
|
# REFERENCE: https://github.com/hyprwm/xdg-desktop-portal-hyprland/issues/251#issuecomment-2345631820
|
||||||
|
env = XDG_CURRENT_DESKTOP,Hyprland
|
||||||
|
exec-once = dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
|
||||||
|
#exec-once = dbus-update-activation-environment --systemd --all
|
||||||
|
#exec-once = systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# .__. .___ __..___. . . .___ .___. ._. __ __.
|
||||||
|
# [__] [__ (__ | |__| [__ | | / ` (__
|
||||||
|
# | | [___ .__) | | | [___ | _|_ \__. .__)
|
||||||
|
|
||||||
|
# Refer to https://wiki.hyprland.org/Configuring/Variables/
|
||||||
|
|
||||||
|
# https://wiki.hyprland.org/Configuring/Variables/#general
|
||||||
|
general {
|
||||||
|
gaps_in = 12 # margin between windows
|
||||||
|
gaps_out = 25 # margin from windows to monitor edge
|
||||||
|
gaps_workspaces = 0 # margin between workspaces (stacks with gaps_out)
|
||||||
|
# float_gaps = 0 # gaps_out but for floating windows
|
||||||
|
|
||||||
|
border_size = 4
|
||||||
|
|
||||||
|
# https://wiki.hyprland.org/Configuring/Variables/#variable-types for info about colors
|
||||||
|
col.active_border = rgba(33ccffee) rgba(00ff99ee) 45deg
|
||||||
|
col.inactive_border = rgba(00000000)
|
||||||
|
|
||||||
|
# Set to true enable resizing windows by clicking and dragging on borders and gaps
|
||||||
|
resize_on_border = true
|
||||||
|
|
||||||
|
# Please see https://wiki.hyprland.org/Configuring/Tearing/ before you turn this on
|
||||||
|
allow_tearing = false
|
||||||
|
|
||||||
|
layout = dwindle
|
||||||
|
|
||||||
|
snap {
|
||||||
|
enabled = false
|
||||||
|
window_gap = 10
|
||||||
|
monitor_gap = 10
|
||||||
|
border_overlap = false
|
||||||
|
# respect_gaps = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# https://wiki.hyprland.org/Configuring/Variables/#decoration
|
||||||
|
decoration {
|
||||||
|
rounding = 20
|
||||||
|
rounding_power = 4.0 # Lp norm
|
||||||
|
border_part_of_window = true # consider border as part of its window
|
||||||
|
screen_shader = # path to custom GLSL fragment shader
|
||||||
|
|
||||||
|
# Window Transparency
|
||||||
|
active_opacity = 1.0
|
||||||
|
inactive_opacity = 0.95
|
||||||
|
fullscreen_opacity = 1.0 # fullscreened windows
|
||||||
|
# Inactive Window Dimming
|
||||||
|
dim_inactive = false
|
||||||
|
dim_strength = 0.5
|
||||||
|
dim_special = 0.2
|
||||||
|
dim_around = 0.4
|
||||||
|
|
||||||
|
# https://wiki.hyprland.org/Configuring/Variables/#blur
|
||||||
|
blur {
|
||||||
|
enabled = true
|
||||||
|
new_optimizations = true
|
||||||
|
xray = false # floating windows xray through tiling windows
|
||||||
|
ignore_opacity = true
|
||||||
|
|
||||||
|
# Blur Parameters
|
||||||
|
size = 8
|
||||||
|
passes = 1
|
||||||
|
noise = 0.0117 # default
|
||||||
|
contrast = 0.8916 # default
|
||||||
|
brightness = 0.8172 # default
|
||||||
|
vibrancy = 0.1696 # default
|
||||||
|
vibrancy_darkness = 0.0 # default
|
||||||
|
|
||||||
|
# Blurring For Specific Window Types
|
||||||
|
special = false # blur special windows
|
||||||
|
popups = false # blur popups
|
||||||
|
popups_ignorealpha = 0.2
|
||||||
|
input_methods = false
|
||||||
|
input_methods_ignorealpha = 0.2
|
||||||
|
}
|
||||||
|
|
||||||
|
shadow {
|
||||||
|
enabled = true
|
||||||
|
ignore_window = true # only render at edges (not behind)
|
||||||
|
|
||||||
|
range = 3
|
||||||
|
render_power = 1 # falloff rate
|
||||||
|
sharp = false # aka infinite shadow.render_power
|
||||||
|
offset = 0 0 # vec2
|
||||||
|
scale = 1.0
|
||||||
|
|
||||||
|
color = rgba(00000000)
|
||||||
|
color_inactive = rgba(000000ff) # defaults to shadow.color if unset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# https://wiki.hyprland.org/Configuring/Variables/#animations
|
||||||
|
animations {
|
||||||
|
enabled = yes, please :)
|
||||||
|
|
||||||
|
# Animation Declaration Format:
|
||||||
|
# "animation = NAME, ENABLE, SPEED, BEZIER [,STYLE]"
|
||||||
|
# SPEED: in ds (where 1ds = 100ms)
|
||||||
|
|
||||||
|
# Default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
|
||||||
|
|
||||||
|
bezier = easeOutQuint,0.23,1,0.32,1
|
||||||
|
bezier = easeInOutCubic,0.65,0.05,0.36,1
|
||||||
|
bezier = linear,0,0,1,1
|
||||||
|
bezier = almostLinear,0.5,0.5,0.75,1.0
|
||||||
|
bezier = quick,0.15,0,0.1,1
|
||||||
|
|
||||||
|
animation = global, 1, 10, default
|
||||||
|
animation = border, 1, 5.39, easeOutQuint
|
||||||
|
|
||||||
|
#animation = windows, 1, 4.79, easeOutQuint
|
||||||
|
#animation = windowsIn, 1, 4.1, easeOutQuint, popin 87%
|
||||||
|
animation = windowsIn, 1, 4, linear, slide bottom
|
||||||
|
# animation = windowsOut, 1, 1.49, linear, popin 87%
|
||||||
|
animation = windowsOut, 1, 10, linear, popin
|
||||||
|
|
||||||
|
animation = fadeIn, 1, 1.73, almostLinear
|
||||||
|
animation = fadeOut, 1, 1.46, almostLinear
|
||||||
|
animation = fade, 1, 3.03, quick
|
||||||
|
|
||||||
|
animation = layers, 1, 3.81, easeOutQuint
|
||||||
|
animation = layersIn, 1, 4, easeOutQuint, fade
|
||||||
|
animation = layersOut, 1, 1.5, linear, fade
|
||||||
|
|
||||||
|
animation = fadeLayersIn, 1, 1.79, almostLinear
|
||||||
|
animation = fadeLayersOut, 1, 1.39, almostLinear
|
||||||
|
|
||||||
|
animation = workspaces, 1, 1.94, almostLinear, fade
|
||||||
|
animation = workspacesIn, 1, 1.21, almostLinear, fade
|
||||||
|
animation = workspacesOut, 1, 1.94, almostLinear, fade
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ref https://wiki.hyprland.org/Configuring/Workspace-Rules/
|
||||||
|
# "Smart gaps" / "No gaps when only"
|
||||||
|
# uncomment all if you wish to use that.
|
||||||
|
# workspace = w[t1], gapsout:0, gapsin:0
|
||||||
|
# workspace = w[tg1], gapsout:0, gapsin:0
|
||||||
|
# workspace = f[1], gapsout:0, gapsin:0
|
||||||
|
# windowrulev2 = bordersize 0, floating:0, onworkspace:w[t1]
|
||||||
|
# windowrulev2 = rounding 0, floating:0, onworkspace:w[t1]
|
||||||
|
# windowrulev2 = bordersize 0, floating:0, onworkspace:w[tg1]
|
||||||
|
# windowrulev2 = rounding 0, floating:0, onworkspace:w[tg1]
|
||||||
|
# windowrulev2 = bordersize 0, floating:0, onworkspace:f[1]
|
||||||
|
# windowrulev2 = rounding 0, floating:0, onworkspace:f[1]
|
||||||
|
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
|
||||||
|
dwindle {
|
||||||
|
pseudotile = true # Master switch for pseudotiling. Enabling is bound to MOD + P in the keybinds section below
|
||||||
|
preserve_split = true # You probably want this
|
||||||
|
}
|
||||||
|
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Master-Layout/ for more
|
||||||
|
master {
|
||||||
|
new_status = master
|
||||||
|
}
|
||||||
|
|
||||||
|
# https://wiki.hyprland.org/Configuring/Variables/#misc
|
||||||
|
misc {
|
||||||
|
#force_default_wallpaper = -1 # Set to 0 or 1 to disable the anime mascot wallpapers
|
||||||
|
disable_hyprland_logo = true # If true disables the random hyprland logo / anime girl background. :(
|
||||||
|
disable_splash_rendering = true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#############
|
||||||
|
### INPUT ###
|
||||||
|
#############
|
||||||
|
|
||||||
|
# https://wiki.hyprland.org/Configuring/Variables/#input
|
||||||
|
input {
|
||||||
|
kb_layout = us
|
||||||
|
kb_variant =
|
||||||
|
kb_model =
|
||||||
|
kb_options =
|
||||||
|
kb_rules =
|
||||||
|
|
||||||
|
follow_mouse = 1
|
||||||
|
|
||||||
|
sensitivity = 0 # -1.0 - 1.0, 0 means no modification.
|
||||||
|
|
||||||
|
touchpad {
|
||||||
|
natural_scroll = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# https://wiki.hyprland.org/Configuring/Variables/#gestures
|
||||||
|
gestures {
|
||||||
|
workspace_swipe = true
|
||||||
|
}
|
||||||
|
|
||||||
|
# Example per-device config
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Keywords/#per-device-input-configs for more
|
||||||
|
#device {
|
||||||
|
# name = epic-mouse-v1
|
||||||
|
# sensitivity = -0.5
|
||||||
|
#}
|
||||||
|
|
||||||
|
|
||||||
|
###################
|
||||||
|
### KEYBINDINGS ###
|
||||||
|
###################
|
||||||
|
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Keywords/
|
||||||
|
$MOD = SUPER # Sets "Windows" key as main modifier
|
||||||
|
|
||||||
|
# Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
|
||||||
|
bind = $MOD, RETURN, exec, $terminal
|
||||||
|
bind = $MOD, E, exec, $fileManager
|
||||||
|
bind = $MOD, R, exec, $menu
|
||||||
|
bind = $MOD, H, exec, $colorpicker
|
||||||
|
|
||||||
|
bind = $MOD, F, fullscreen
|
||||||
|
bind = $MOD, V, togglefloating,
|
||||||
|
bind = $MOD, P, pseudo, # dwindle
|
||||||
|
bind = $MOD, J, togglesplit, # dwindle
|
||||||
|
|
||||||
|
bind = $MOD, C, killactive,
|
||||||
|
#bind = $MOD, M, exit,
|
||||||
|
|
||||||
|
# Move focus with MOD + arrow keys
|
||||||
|
bind = $MOD, left, movefocus, l
|
||||||
|
bind = $MOD, right, movefocus, r
|
||||||
|
bind = $MOD, up, movefocus, u
|
||||||
|
bind = $MOD, down, movefocus, d
|
||||||
|
|
||||||
|
# Switch workspaces with MOD + [0-9]
|
||||||
|
bind = $MOD, 1, workspace, 1
|
||||||
|
bind = $MOD, 2, workspace, 2
|
||||||
|
bind = $MOD, 3, workspace, 3
|
||||||
|
bind = $MOD, 4, workspace, 4
|
||||||
|
bind = $MOD, 5, workspace, 5
|
||||||
|
bind = $MOD, 6, workspace, 6
|
||||||
|
bind = $MOD, 7, workspace, 7
|
||||||
|
bind = $MOD, 8, workspace, 8
|
||||||
|
bind = $MOD, 9, workspace, 9
|
||||||
|
bind = $MOD, 0, workspace, 10
|
||||||
|
|
||||||
|
# Move active window to a workspace with MOD + SHIFT + [0-9]
|
||||||
|
bind = $MOD SHIFT, 1, movetoworkspace, 1
|
||||||
|
bind = $MOD SHIFT, 2, movetoworkspace, 2
|
||||||
|
bind = $MOD SHIFT, 3, movetoworkspace, 3
|
||||||
|
bind = $MOD SHIFT, 4, movetoworkspace, 4
|
||||||
|
bind = $MOD SHIFT, 5, movetoworkspace, 5
|
||||||
|
bind = $MOD SHIFT, 6, movetoworkspace, 6
|
||||||
|
bind = $MOD SHIFT, 7, movetoworkspace, 7
|
||||||
|
bind = $MOD SHIFT, 8, movetoworkspace, 8
|
||||||
|
bind = $MOD SHIFT, 9, movetoworkspace, 9
|
||||||
|
bind = $MOD SHIFT, 0, movetoworkspace, 10
|
||||||
|
|
||||||
|
# Example special workspace (scratchpad)
|
||||||
|
bind = $MOD, S, togglespecialworkspace, magic
|
||||||
|
bind = $MOD SHIFT, S, movetoworkspace, special:magic
|
||||||
|
|
||||||
|
# Scroll through existing workspaces with MOD + scroll
|
||||||
|
bind = $MOD, mouse_up, workspace, e-1
|
||||||
|
bind = $MOD, mouse_down, workspace, e+1
|
||||||
|
# Or with the keyboard
|
||||||
|
bind = $MOD SHIFT, left, workspace, e-1
|
||||||
|
bind = $MOD SHIFT, right, workspace, e+1
|
||||||
|
|
||||||
|
# Move/resize windows with MOD + LMB/RMB and dragging
|
||||||
|
bindm = $MOD, mouse:272, movewindow
|
||||||
|
bindm = $MOD, mouse:273, resizewindow
|
||||||
|
|
||||||
|
# Laptop multimedia keys for volume and LCD brightness
|
||||||
|
bindel = ,XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+
|
||||||
|
bindel = ,XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
|
||||||
|
bindel = ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
|
||||||
|
bindel = ,XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle
|
||||||
|
bindel = ,XF86MonBrightnessUp, exec, brightnessctl s 10%+
|
||||||
|
bindel = ,XF86MonBrightnessDown, exec, brightnessctl s 10%-
|
||||||
|
|
||||||
|
# Requires playerctl
|
||||||
|
bindl = , XF86AudioNext, exec, playerctl next
|
||||||
|
bindl = , XF86AudioPause, exec, playerctl play-pause
|
||||||
|
bindl = , XF86AudioPlay, exec, playerctl play-pause
|
||||||
|
bindl = , XF86AudioPrev, exec, playerctl previous
|
||||||
|
|
||||||
|
##############################
|
||||||
|
### WINDOWS AND WORKSPACES ###
|
||||||
|
##############################
|
||||||
|
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Workspace-Rules/ for workspace rules
|
||||||
|
|
||||||
|
# Example windowrule v1
|
||||||
|
# windowrule = float, ^(kitty)$
|
||||||
|
|
||||||
|
# Example windowrule v2
|
||||||
|
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
|
||||||
|
|
||||||
|
# Ignore maximize requests from apps. You'll probably like this.
|
||||||
|
windowrulev2 = suppressevent maximize, class:.*
|
||||||
|
|
||||||
|
# Fix some dragging issues with XWayland
|
||||||
|
windowrulev2 = nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0
|
||||||
81
deploy
|
|
@ -1,3 +1,82 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
sudo nixos-rebuild switch --flake .
|
set -e
|
||||||
|
|
||||||
|
# TODO: use `nixos-rebuild build-vm`
|
||||||
|
|
||||||
|
usage="Usage: $(basename $0) [OPTIONS]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-f, --fresh Remove old content in the nixstore (good for debugging)
|
||||||
|
-b, --bootloader Reinstall the bootloader
|
||||||
|
-r, --remote Locally build and remotely deploy Colmena hive
|
||||||
|
-h, --help Show this message (^_^)"
|
||||||
|
|
||||||
|
# delete all cached entries
|
||||||
|
# to make the system from scratch
|
||||||
|
collect_garbage () {
|
||||||
|
sudo nix-collect-garbage --delete-old
|
||||||
|
}
|
||||||
|
|
||||||
|
rebuild_flake () {
|
||||||
|
# make sure all changes are visible to nixos
|
||||||
|
git add . --verbose
|
||||||
|
local FLAGS=
|
||||||
|
if [ "$1" = "reinstall-bootloader" ]; then
|
||||||
|
FLAGS="--install-bootloader"
|
||||||
|
# sudo nixos-rebuild switch --flake . --install-bootloader
|
||||||
|
# STC_DISPLAY_ALL_UNITS=1 (verbose, show output of all units)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# LOG="$(mktemp /tmp/rebuild-XXXXXXXX)"
|
||||||
|
LOG="./rebuild.log"
|
||||||
|
echo "[*] Logging to $LOG"
|
||||||
|
sudo nixos-rebuild switch --flake . $FLAGS 2>&1 | tee "$LOG"
|
||||||
#nixos-rebuild build --flake .# --cores 8 -j 1
|
#nixos-rebuild build --flake .# --cores 8 -j 1
|
||||||
|
}
|
||||||
|
|
||||||
|
deploy_hive () {
|
||||||
|
echo "[+] Adding keys to ssh-agent"
|
||||||
|
ssh-add ~/.ssh/id_hyrule
|
||||||
|
printf "\n"
|
||||||
|
|
||||||
|
git add . --verbose
|
||||||
|
# Deploy to all Colmena hives
|
||||||
|
colmena build --experimental-flake-eval
|
||||||
|
colmena apply --experimental-flake-eval
|
||||||
|
# colmena apply --on hyrule --experimental-flake-eval
|
||||||
|
}
|
||||||
|
|
||||||
|
# check which flags were given
|
||||||
|
flag_fresh=false
|
||||||
|
flag_bootloader=false
|
||||||
|
for flag in "$@"; do
|
||||||
|
case "$flag" in
|
||||||
|
-r|--remote)
|
||||||
|
deploy_hive
|
||||||
|
exit 0 ;;
|
||||||
|
-f|--fresh)
|
||||||
|
flag_fresh=true ;;
|
||||||
|
-b|--bootloader)
|
||||||
|
flag_bootloader=true ;;
|
||||||
|
-h|--help)
|
||||||
|
echo "$usage"
|
||||||
|
exit 0 ;;
|
||||||
|
*)
|
||||||
|
echo "[!] Unknown flag \"$flag\""
|
||||||
|
exit 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# delete cached items in nixstore
|
||||||
|
if [ "$flag_fresh" = true ]; then
|
||||||
|
collect_garbage
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# nixos-rebuild switch ...
|
||||||
|
if [ "$flag_bootloader" = true ]; then
|
||||||
|
collect_garbage
|
||||||
|
rebuild_flake "reinstall-bootloader"
|
||||||
|
else
|
||||||
|
rebuild_flake
|
||||||
|
fi
|
||||||
|
|
|
||||||
25
docs/DEVDOC.md
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
## Users
|
||||||
|
|
||||||
|
#### me
|
||||||
|
My main personal account, used on my PC and laptop.
|
||||||
|
Contains a hyprland graphical environment by default.
|
||||||
|
|
||||||
|
#### ae
|
||||||
|
Primary account on my servers. Contains the bare
|
||||||
|
essentials for my work, no graphical environment.
|
||||||
|
|
||||||
|
|
||||||
|
#### friends
|
||||||
|
A simple account I let me friends connect to.
|
||||||
|
Limited functionality, mostly just for letting
|
||||||
|
them test small things or for giving them files.
|
||||||
|
|
||||||
|
|
||||||
|
## Setup Guide
|
||||||
|
##### Adding a New Server
|
||||||
|
Enable an ssh server on the remote host, then on the
|
||||||
|
local machine set `.ssh/config` to have a profile for
|
||||||
|
your desired host and have a key pair that's authorised
|
||||||
|
to your desired user.
|
||||||
|
|
||||||
|
NOTE: these keys must have permission 600 (only readable/writable by you)
|
||||||
67
docs/DEV_ENV.md
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
This file will document what features I believe I need
|
||||||
|
for NixOS to be a good development environment.
|
||||||
|
|
||||||
|
|
||||||
|
Issues I've encountered:
|
||||||
|
- [X] Audio not working
|
||||||
|
- [X] Tesseract is a pain in the ass to setup on Nix
|
||||||
|
- [ ] ags no longer supports `-t` flag, so applauncher won't work, requires switching to Astral
|
||||||
|
- [ ] script to enable/disable passwordless sudo
|
||||||
|
|
||||||
|
- [X] Move Emile.Vault to new vault (I lost the password...)
|
||||||
|
|
||||||
|
- [X] Add a simple and ugly bar
|
||||||
|
|
||||||
|
- [ ] Install powertop (funny name) for monitoring power usage by processes
|
||||||
|
- [ ] Try to make my battery life bettery
|
||||||
|
|
||||||
|
- [ ] Apply for JetBrains student license
|
||||||
|
- [ ] JetBrains Rider and VSCodium for C#
|
||||||
|
2. Imperative development environment behind NixOS (declarative),
|
||||||
|
similar to python's virtualenv but for the entirety of my system.
|
||||||
|
|
||||||
|
- [X] Call my wishlist command "subspace (highway)" (Scott Pilgrim reference)
|
||||||
|
|
||||||
|
- [ ] Create a GitHub profile readme like this persons:
|
||||||
|
https://github.com/yuyudhn
|
||||||
|
- [ ] Set a new GitHub profile picture (like github:@Vendicated)
|
||||||
|
artists credit: https://dotpict.net/users/1598051
|
||||||
|
- [ ] Change GitHub location to /dev/zero, /dev/null, www, World Wide Web, etc
|
||||||
|
- [ ] Clean up my GitHub profile (only have things I'm proud of)
|
||||||
|
|
||||||
|
- [X] Put a template website on my VPS
|
||||||
|
- [ ] Put a neoweb-esque webiste on my VPS
|
||||||
|
- [ ] Host a blog on my VPS
|
||||||
|
|
||||||
|
- [ ] Clean laptop and PC, there's tons of unnecessary files and documents now
|
||||||
|
- [ ] Clean nixdots repo, start modularising it ^_^
|
||||||
|
- [ ] Disable `allowUnfree` in nixdots everywhere, if a program needs it then they
|
||||||
|
can `mkForce` override it
|
||||||
|
|
||||||
|
- [X] Add LSP for Nix in helix
|
||||||
|
- [ ] Make a way for me to put my laptop in a low power state, doing very specific actions like:
|
||||||
|
1. disabling LSP use by default temporarily
|
||||||
|
|
||||||
|
- [ ] Add https://github.com/levnikmyskin/hyprland-virtual-desktops
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
- [X] make btop theming declarative
|
||||||
|
- [X] Merge laptop and PC dotfiles repos
|
||||||
|
- [ ] declaratively install themes for gitkraken using home-manager
|
||||||
|
|
||||||
|
Cool Technologies:
|
||||||
|
- wishlist (by charmbracelet)
|
||||||
|
- Vaultwarden server + Keyguard client
|
||||||
|
- devbox
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Random Idea List:
|
||||||
|
- [ ] powertop is cool but it's outdated and ugly, make a prettier one with charmbracelet's tui library
|
||||||
|
and call it powerbtm lmao
|
||||||
|
- [ ] Blog Post: a modern alternative to the suckless philosphy,
|
||||||
|
why GNU keeps failing cause their programs are amazing but
|
||||||
|
aren't designed for humans. suckless programs are excellent
|
||||||
|
too when writing shell scripts, but they suck in dev environments.
|
||||||
|
The solution is to gamify our code and focus on aesthetics
|
||||||
|
and "ergonomics" (usability) like what CharmBracelet does
|
||||||
5
docs/PROBLEMLOG.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
180GB of disk space were used by my system which seemed absurd. Running the NixOS
|
||||||
|
garbage collector only removed 7GB. The rest was found via:
|
||||||
|
`du -hs ./.local/share/Games/drive_c/Program\ Files\ \(x86\)/Steam/dumps/reports/*`
|
||||||
|
tldr: there were 2714 30MB crash report files generated every minute of May 2nd 2025 (10 days ago)
|
||||||
|
SOLUTION: delete them all and hope it doesn't happen again
|
||||||
15
TODO → docs/TODO.md
Normal file → Executable file
|
|
@ -17,15 +17,20 @@ Get hyprcursor working with Bibata-Modern-Ice
|
||||||
Get a GRUB theme working
|
Get a GRUB theme working
|
||||||
Get SDDM and a theme working
|
Get SDDM and a theme working
|
||||||
|
|
||||||
|
Make a custom hyprlock screen
|
||||||
|
|
||||||
|
Get AGS working
|
||||||
|
Make an applauncher in AGS
|
||||||
Get waybar (or another bar) working
|
Remove hyprland splash screen on init
|
||||||
|
Made lolcathost home modular
|
||||||
|
|
||||||
Overtime just install more programs that I need regularly: ie
|
Overtime just install more programs that I need regularly: ie
|
||||||
- btop/htop/etc
|
- btop/htop/etc
|
||||||
|
|
||||||
|
Get GTK Bibata Cursors to be the same size as my system cursor (NOT SURE WHAT I DID...)
|
||||||
|
|
||||||
|
|
||||||
|
Get waybar (or another bar) working
|
||||||
|
|
||||||
Get a QT theme
|
Get a QT theme
|
||||||
|
|
||||||
|
|
@ -35,12 +40,10 @@ Bind new terminal to SUPER+Enter instead of SUPER+Q
|
||||||
|
|
||||||
Join Rio Terminal's discord and ask if they support nerdfonts or if I'm doing something wrong
|
Join Rio Terminal's discord and ask if they support nerdfonts or if I'm doing something wrong
|
||||||
|
|
||||||
Figure out how to modularise my dotfiles
|
|
||||||
|
|
||||||
|
|
||||||
Change Dell loading screen (Boot Graphics Resource Table, aka BGRT)
|
Change Dell loading screen (Boot Graphics Resource Table, aka BGRT)
|
||||||
|
|
||||||
Get GTK Bibata Cursors to be the same size as my system cursor
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
3
docs/TODO_UI.md
Executable file
|
|
@ -0,0 +1,3 @@
|
||||||
|
1. Create more themes for my applauncher
|
||||||
|
2. Create more themes for hyprlock
|
||||||
|
check out: https://github.com/MrVivekRajan/Hyprlock-Styles
|
||||||
4
INSPIRATION → docs/inspiration.md
Normal file → Executable file
|
|
@ -6,3 +6,7 @@ Gorgeous
|
||||||
|
|
||||||
Very nice
|
Very nice
|
||||||
https://github.com/linuxmobile/hyprland-dots
|
https://github.com/linuxmobile/hyprland-dots
|
||||||
|
|
||||||
|
|
||||||
|
I love their hyprpanel!
|
||||||
|
https://www.reddit.com/r/unixporn/comments/1ha3mjw/hyprlandnixos_is_the_pretty_ucking_solid_i_love/
|
||||||
2
docs/nixos_notes.md
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
Building specific parts of a NixOS system
|
||||||
|
https://nixos.org/manual/nixos/stable/#sec-building-parts
|
||||||
690
flake.lock
generated
Executable file → Normal file
|
|
@ -1,84 +1,36 @@
|
||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"ags": {
|
"colmena": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
|
"flake-compat": "flake-compat",
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nix-github-actions": "nix-github-actions",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"systems": "systems"
|
"stable": "stable"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1728326430,
|
"lastModified": 1734374287,
|
||||||
"narHash": "sha256-tV1ABHuA1HItMdCTuNdA8fMB+qw7LpjvI945VwMSABI=",
|
"narHash": "sha256-rINodqeUuezuCWOnpJgrH7u9vJ86fYT+Dj8Mu8T/IBc=",
|
||||||
"owner": "Aylur",
|
"owner": "zhaofengli",
|
||||||
"repo": "ags",
|
"repo": "colmena",
|
||||||
"rev": "60180a184cfb32b61a1d871c058b31a3b9b0743d",
|
"rev": "47b6414d800c8471e98ca072bc0835345741a56a",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "Aylur",
|
"owner": "zhaofengli",
|
||||||
"repo": "ags",
|
"repo": "colmena",
|
||||||
"type": "github"
|
"rev": "47b6414d800c8471e98ca072bc0835345741a56a",
|
||||||
}
|
|
||||||
},
|
|
||||||
"ags_2": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": "nixpkgs_4",
|
|
||||||
"systems": "systems_3"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1728326430,
|
|
||||||
"narHash": "sha256-tV1ABHuA1HItMdCTuNdA8fMB+qw7LpjvI945VwMSABI=",
|
|
||||||
"owner": "Aylur",
|
|
||||||
"repo": "ags",
|
|
||||||
"rev": "60180a184cfb32b61a1d871c058b31a3b9b0743d",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "Aylur",
|
|
||||||
"repo": "ags",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"aquamarine": {
|
|
||||||
"inputs": {
|
|
||||||
"hyprutils": [
|
|
||||||
"hyprland",
|
|
||||||
"hyprutils"
|
|
||||||
],
|
|
||||||
"hyprwayland-scanner": [
|
|
||||||
"hyprland",
|
|
||||||
"hyprwayland-scanner"
|
|
||||||
],
|
|
||||||
"nixpkgs": [
|
|
||||||
"hyprland",
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"systems": [
|
|
||||||
"hyprland",
|
|
||||||
"systems"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1730968822,
|
|
||||||
"narHash": "sha256-NocDjINsh6ismkhb0Xr6xPRksmhuB2WGf8ZmXMhxu7Y=",
|
|
||||||
"owner": "hyprwm",
|
|
||||||
"repo": "aquamarine",
|
|
||||||
"rev": "a49bc3583ff223f426cb3526fdaa4bcaa247ec14",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "hyprwm",
|
|
||||||
"repo": "aquamarine",
|
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-compat": {
|
"flake-compat": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1696426674,
|
"lastModified": 1650374568,
|
||||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
"narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=",
|
||||||
"owner": "edolstra",
|
"owner": "edolstra",
|
||||||
"repo": "flake-compat",
|
"repo": "flake-compat",
|
||||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
"rev": "b4a34015c698c7793d592d66adbab377907a2be8",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -87,71 +39,18 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-compat_2": {
|
"flake-utils": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1696426674,
|
"lastModified": 1659877975,
|
||||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
|
||||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
"owner": "numtide",
|
||||||
"revCount": 57,
|
"repo": "flake-utils",
|
||||||
"type": "tarball",
|
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
|
||||||
"url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-compat_3": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1696426674,
|
|
||||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "edolstra",
|
"owner": "numtide",
|
||||||
"repo": "flake-compat",
|
"repo": "flake-utils",
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-compat_4": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1696426674,
|
|
||||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"gitignore": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"hyprland",
|
|
||||||
"pre-commit-hooks",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1709087332,
|
|
||||||
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
|
|
||||||
"owner": "hercules-ci",
|
|
||||||
"repo": "gitignore.nix",
|
|
||||||
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "hercules-ci",
|
|
||||||
"repo": "gitignore.nix",
|
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -160,11 +59,11 @@
|
||||||
"nixpkgs": "nixpkgs_2"
|
"nixpkgs": "nixpkgs_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1730004881,
|
"lastModified": 1757136219,
|
||||||
"narHash": "sha256-8xVIqIW25o2uCL0fxAmP4Sj9sdebarQXmd1+64yMe8o=",
|
"narHash": "sha256-tKU+vq34KHu/A2wD7WdgP5A4/RCmSD8hB0TyQAUlixA=",
|
||||||
"owner": "vinceliuice",
|
"owner": "vinceliuice",
|
||||||
"repo": "grub2-themes",
|
"repo": "grub2-themes",
|
||||||
"rev": "42c232dfb46bf93c17506cbc1a574e5e89b5e09f",
|
"rev": "80dd04ddf3ba7b284a7b1a5df2b1e95ee2aad606",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -173,247 +72,34 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"home-manager": {
|
"nix-github-actions": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
|
"colmena",
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1730633670,
|
"lastModified": 1729742964,
|
||||||
"narHash": "sha256-ZFJqIXpvVKvzOVFKWNRDyIyAo+GYdmEPaYi1bZB6uf0=",
|
"narHash": "sha256-B4mzTcQ0FZHdpeWcpDYPERtyjJd/NIuaQ9+BV1h+MpA=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "nix-github-actions",
|
||||||
"rev": "8f6ca7855d409aeebe2a582c6fd6b6a8d0bf5661",
|
"rev": "e04df33f62cdcf93d73e9a04142464753a16db67",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "nix-github-actions",
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"hyprcursor": {
|
|
||||||
"inputs": {
|
|
||||||
"hyprlang": [
|
|
||||||
"hyprland",
|
|
||||||
"hyprlang"
|
|
||||||
],
|
|
||||||
"nixpkgs": [
|
|
||||||
"hyprland",
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"systems": [
|
|
||||||
"hyprland",
|
|
||||||
"systems"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1728669738,
|
|
||||||
"narHash": "sha256-EDNAU9AYcx8OupUzbTbWE1d3HYdeG0wO6Msg3iL1muk=",
|
|
||||||
"owner": "hyprwm",
|
|
||||||
"repo": "hyprcursor",
|
|
||||||
"rev": "0264e698149fcb857a66a53018157b41f8d97bb0",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "hyprwm",
|
|
||||||
"repo": "hyprcursor",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"hyprland": {
|
|
||||||
"inputs": {
|
|
||||||
"aquamarine": "aquamarine",
|
|
||||||
"hyprcursor": "hyprcursor",
|
|
||||||
"hyprland-protocols": "hyprland-protocols",
|
|
||||||
"hyprlang": "hyprlang",
|
|
||||||
"hyprutils": "hyprutils",
|
|
||||||
"hyprwayland-scanner": "hyprwayland-scanner",
|
|
||||||
"nixpkgs": "nixpkgs_3",
|
|
||||||
"pre-commit-hooks": "pre-commit-hooks",
|
|
||||||
"systems": "systems_2",
|
|
||||||
"xdph": "xdph"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1730969692,
|
|
||||||
"narHash": "sha256-4Ly9zkqnRB6qLjMeddfUyd4iRLvq+RDspBWABS8DGN4=",
|
|
||||||
"owner": "hyprwm",
|
|
||||||
"repo": "Hyprland",
|
|
||||||
"rev": "e58e97b0a38b8ccc87a4304c9e4e2b37c9966875",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "hyprwm",
|
|
||||||
"repo": "Hyprland",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"hyprland-protocols": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"hyprland",
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"systems": [
|
|
||||||
"hyprland",
|
|
||||||
"systems"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1728345020,
|
|
||||||
"narHash": "sha256-xGbkc7U/Roe0/Cv3iKlzijIaFBNguasI31ynL2IlEoM=",
|
|
||||||
"owner": "hyprwm",
|
|
||||||
"repo": "hyprland-protocols",
|
|
||||||
"rev": "a7c183800e74f337753de186522b9017a07a8cee",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "hyprwm",
|
|
||||||
"repo": "hyprland-protocols",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"hyprlang": {
|
|
||||||
"inputs": {
|
|
||||||
"hyprutils": [
|
|
||||||
"hyprland",
|
|
||||||
"hyprutils"
|
|
||||||
],
|
|
||||||
"nixpkgs": [
|
|
||||||
"hyprland",
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"systems": [
|
|
||||||
"hyprland",
|
|
||||||
"systems"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1728168612,
|
|
||||||
"narHash": "sha256-AnB1KfiXINmuiW7BALYrKqcjCnsLZPifhb/7BsfPbns=",
|
|
||||||
"owner": "hyprwm",
|
|
||||||
"repo": "hyprlang",
|
|
||||||
"rev": "f054f2e44d6a0b74607a6bc0f52dba337a3db38e",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "hyprwm",
|
|
||||||
"repo": "hyprlang",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"hyprpanel": {
|
|
||||||
"inputs": {
|
|
||||||
"ags": "ags_2",
|
|
||||||
"nixpkgs": "nixpkgs_5"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1731270736,
|
|
||||||
"narHash": "sha256-N0unlLf/7BqkrYx3BO9svv1+oLzKpArgiqLzkmNpD3Q=",
|
|
||||||
"owner": "Jas-SinghFSU",
|
|
||||||
"repo": "HyprPanel",
|
|
||||||
"rev": "a7855baf13c6abdd0b0e988e4390112cd7deda67",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "Jas-SinghFSU",
|
|
||||||
"repo": "HyprPanel",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"hyprutils": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"hyprland",
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"systems": [
|
|
||||||
"hyprland",
|
|
||||||
"systems"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1730968903,
|
|
||||||
"narHash": "sha256-zFvzLXcSm0Ia4XI1SE4FQ9KE63hlGrRWhLtwMolWuR8=",
|
|
||||||
"owner": "hyprwm",
|
|
||||||
"repo": "hyprutils",
|
|
||||||
"rev": "3ce0cde8709cdacbfba471f8e828433b58a561e9",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "hyprwm",
|
|
||||||
"repo": "hyprutils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"hyprwayland-scanner": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"hyprland",
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"systems": [
|
|
||||||
"hyprland",
|
|
||||||
"systems"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1726874836,
|
|
||||||
"narHash": "sha256-VKR0sf0PSNCB0wPHVKSAn41mCNVCnegWmgkrneKDhHM=",
|
|
||||||
"owner": "hyprwm",
|
|
||||||
"repo": "hyprwayland-scanner",
|
|
||||||
"rev": "500c81a9e1a76760371049a8d99e008ea77aa59e",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "hyprwm",
|
|
||||||
"repo": "hyprwayland-scanner",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nix-flatpak": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1711997201,
|
|
||||||
"narHash": "sha256-J71xzQlVYsjagA4AsVwRazhBh2rZrPpKvxTgs6UzL7c=",
|
|
||||||
"owner": "gmodena",
|
|
||||||
"repo": "nix-flatpak",
|
|
||||||
"rev": "b76fa31346db7fc958a9898f3c594696ca71c4fd",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "gmodena",
|
|
||||||
"ref": "v0.4.1",
|
|
||||||
"repo": "nix-flatpak",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixcord": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-compat": "flake-compat_2",
|
|
||||||
"nixpkgs": "nixpkgs_6"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1730720546,
|
|
||||||
"narHash": "sha256-5147A6X0MH6u/YDxLe+Nnva3oxfLQanC716LarG/uoo=",
|
|
||||||
"owner": "kaylorben",
|
|
||||||
"repo": "nixcord",
|
|
||||||
"rev": "e3e27c77316f7526b1a846778ae9c759c9377611",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "kaylorben",
|
|
||||||
"repo": "nixcord",
|
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1725634671,
|
"lastModified": 1734119587,
|
||||||
"narHash": "sha256-v3rIhsJBOMLR8e/RNWxr828tB+WywYIoajrZKFM+0Gg=",
|
"narHash": "sha256-AKU6qqskl0yf2+JdRdD0cfxX4b9x3KKV5RqA6wijmPM=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "574d1eac1c200690e27b8eb4e24887f8df7ac27c",
|
"rev": "3566ab7246670a43abd2ffa913cc62dad9cdf7d5",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -423,29 +109,29 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs-stable": {
|
"nixpkgs-unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1730741070,
|
"lastModified": 1761114652,
|
||||||
"narHash": "sha256-edm8WG19kWozJ/GqyYx2VjW99EdhjKwbY3ZwdlPAAlo=",
|
"narHash": "sha256-f/QCJM/YhrV/lavyCVz8iU3rlZun6d+dAiC3H+CDle4=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "d063c1dd113c91ab27959ba540c0d9753409edf3",
|
"rev": "01f116e4df6a15f4ccdffb1bcd41096869fb385c",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"ref": "nixos-24.05",
|
"ref": "nixos-unstable",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1730808093,
|
"lastModified": 1761269590,
|
||||||
"narHash": "sha256-oOenwoxpzQsBNi7KltgnXqq6e0+CxlfNXKn3k27w6cQ=",
|
"narHash": "sha256-yTr+PCi4wGbOEidrm8XyXBobLxLMqIBsbUyhwsN6wrc=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "c1a390f74b2c93f69a6805142f11a215a689cec1",
|
"rev": "d792a6e0cd4ba35c90ea787b717d72410f56dc40",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -457,295 +143,41 @@
|
||||||
},
|
},
|
||||||
"nixpkgs_3": {
|
"nixpkgs_3": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1730785428,
|
"lastModified": 1761016216,
|
||||||
"narHash": "sha256-Zwl8YgTVJTEum+L+0zVAWvXAGbWAuXHax3KzuejaDyo=",
|
"narHash": "sha256-G/iC4t/9j/52i/nm+0/4ybBmAF4hzR8CNHC75qEhjHo=",
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "4aa36568d413aca0ea84a1684d2d46f55dbabad7",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"ref": "nixos-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs_4": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1725634671,
|
|
||||||
"narHash": "sha256-v3rIhsJBOMLR8e/RNWxr828tB+WywYIoajrZKFM+0Gg=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "574d1eac1c200690e27b8eb4e24887f8df7ac27c",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"ref": "nixos-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs_5": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1729880355,
|
|
||||||
"narHash": "sha256-RP+OQ6koQQLX5nw0NmcDrzvGL8HDLnyXt/jHhL1jwjM=",
|
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "18536bf04cd71abd345f9579158841376fdd0c5a",
|
"rev": "481cf557888e05d3128a76f14c76397b7d7cc869",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"ref": "nixos-unstable",
|
"ref": "nixos-25.05",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_6": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1730768919,
|
|
||||||
"narHash": "sha256-8AKquNnnSaJRXZxc5YmF/WfmxiHX6MMZZasRP6RRQkE=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "a04d33c0c3f1a59a2c1cb0c6e34cd24500e5a1dc",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"ref": "nixpkgs-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs_7": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1730785428,
|
|
||||||
"narHash": "sha256-Zwl8YgTVJTEum+L+0zVAWvXAGbWAuXHax3KzuejaDyo=",
|
|
||||||
"owner": "nixos",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "4aa36568d413aca0ea84a1684d2d46f55dbabad7",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nixos",
|
|
||||||
"ref": "nixos-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs_8": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1730200266,
|
|
||||||
"narHash": "sha256-l253w0XMT8nWHGXuXqyiIC/bMvh1VRszGXgdpQlfhvU=",
|
|
||||||
"owner": "nixos",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "807e9154dcb16384b1b765ebe9cd2bba2ac287fd",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nixos",
|
|
||||||
"ref": "nixos-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pre-commit-hooks": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-compat": "flake-compat",
|
|
||||||
"gitignore": "gitignore",
|
|
||||||
"nixpkgs": [
|
|
||||||
"hyprland",
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"nixpkgs-stable": "nixpkgs-stable"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1730814269,
|
|
||||||
"narHash": "sha256-fWPHyhYE6xvMI1eGY3pwBTq85wcy1YXqdzTZF+06nOg=",
|
|
||||||
"owner": "cachix",
|
|
||||||
"repo": "git-hooks.nix",
|
|
||||||
"rev": "d70155fdc00df4628446352fc58adc640cd705c2",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "cachix",
|
|
||||||
"repo": "git-hooks.nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"ags": "ags",
|
"colmena": "colmena",
|
||||||
"grub2-themes": "grub2-themes",
|
"grub2-themes": "grub2-themes",
|
||||||
"home-manager": "home-manager",
|
"nixpkgs": "nixpkgs_3",
|
||||||
"hyprland": "hyprland",
|
"nixpkgs-unstable": "nixpkgs-unstable"
|
||||||
"hyprpanel": "hyprpanel",
|
|
||||||
"nix-flatpak": "nix-flatpak",
|
|
||||||
"nixcord": "nixcord",
|
|
||||||
"nixpkgs": "nixpkgs_7",
|
|
||||||
"spicetify-nix": "spicetify-nix",
|
|
||||||
"swww": "swww"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"spicetify-nix": {
|
"stable": {
|
||||||
"inputs": {
|
|
||||||
"flake-compat": "flake-compat_3",
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1730780158,
|
"lastModified": 1730883749,
|
||||||
"narHash": "sha256-ZJkCFn4PL49rINz7xrjlBqw9nF8wWJE7fSVqbHlCWSA=",
|
"narHash": "sha256-mwrFF0vElHJP8X3pFCByJR365Q2463ATp2qGIrDUdlE=",
|
||||||
"owner": "Gerg-L",
|
"owner": "NixOS",
|
||||||
"repo": "spicetify-nix",
|
"repo": "nixpkgs",
|
||||||
"rev": "2791c6662002731d3dfc00312307aef547e1c8be",
|
"rev": "dba414932936fde69f0606b4f1d87c5bc0003ede",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "Gerg-L",
|
"owner": "NixOS",
|
||||||
"repo": "spicetify-nix",
|
"ref": "nixos-24.05",
|
||||||
"type": "github"
|
"repo": "nixpkgs",
|
||||||
}
|
|
||||||
},
|
|
||||||
"swww": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-compat": "flake-compat_4",
|
|
||||||
"nixpkgs": "nixpkgs_8",
|
|
||||||
"utils": "utils"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1730424990,
|
|
||||||
"narHash": "sha256-+8YUJsNzvgAeZYLfbHYfYlad/iS+6Eec/LWzL1ZIGfY=",
|
|
||||||
"owner": "LGFae",
|
|
||||||
"repo": "swww",
|
|
||||||
"rev": "0db3f4eb192f1c9bf914efcc1d2aba809da5d78a",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "LGFae",
|
|
||||||
"repo": "swww",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"systems": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1689347949,
|
|
||||||
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default-linux",
|
|
||||||
"rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default-linux",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"systems_2": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1689347949,
|
|
||||||
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default-linux",
|
|
||||||
"rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default-linux",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"systems_3": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1689347949,
|
|
||||||
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default-linux",
|
|
||||||
"rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default-linux",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"systems_4": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1681028828,
|
|
||||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"utils": {
|
|
||||||
"inputs": {
|
|
||||||
"systems": "systems_4"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1726560853,
|
|
||||||
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"xdph": {
|
|
||||||
"inputs": {
|
|
||||||
"hyprland-protocols": [
|
|
||||||
"hyprland",
|
|
||||||
"hyprland-protocols"
|
|
||||||
],
|
|
||||||
"hyprlang": [
|
|
||||||
"hyprland",
|
|
||||||
"hyprlang"
|
|
||||||
],
|
|
||||||
"hyprutils": [
|
|
||||||
"hyprland",
|
|
||||||
"hyprutils"
|
|
||||||
],
|
|
||||||
"hyprwayland-scanner": [
|
|
||||||
"hyprland",
|
|
||||||
"hyprwayland-scanner"
|
|
||||||
],
|
|
||||||
"nixpkgs": [
|
|
||||||
"hyprland",
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"systems": [
|
|
||||||
"hyprland",
|
|
||||||
"systems"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1730743262,
|
|
||||||
"narHash": "sha256-iTLqj3lU8kFehPm5tXpctzkD274t/k1nwSSq3qCWXeg=",
|
|
||||||
"owner": "hyprwm",
|
|
||||||
"repo": "xdg-desktop-portal-hyprland",
|
|
||||||
"rev": "09b23cef06fe248e61cec8862c04b9bcb62f4b6d",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "hyprwm",
|
|
||||||
"repo": "xdg-desktop-portal-hyprland",
|
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
80
flake.nix
Executable file → Normal file
|
|
@ -2,60 +2,55 @@
|
||||||
description = "Emile's Nix Dotfiles";
|
description = "Emile's Nix Dotfiles";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
#nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05";
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05";
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
|
||||||
home-manager = {
|
colmena.url = "github:zhaofengli/colmena/?rev=47b6414d800c8471e98ca072bc0835345741a56a";
|
||||||
url = "github:nix-community/home-manager";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
|
|
||||||
spicetify-nix = {
|
|
||||||
url = "github:Gerg-L/spicetify-nix";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
|
|
||||||
nixcord.url = "github:kaylorben/nixcord";
|
|
||||||
|
|
||||||
grub2-themes.url = "github:vinceliuice/grub2-themes";
|
grub2-themes.url = "github:vinceliuice/grub2-themes";
|
||||||
|
|
||||||
# is this necessary? (aren't I enabling it in `configuration.nix` anyways?)
|
|
||||||
hyprland.url = "github:hyprwm/Hyprland";
|
|
||||||
|
|
||||||
swww.url = "github:LGFae/swww";
|
|
||||||
|
|
||||||
# TODO: declarative flatpak management
|
|
||||||
nix-flatpak.url = "github:gmodena/nix-flatpak/?ref=v0.4.1";
|
|
||||||
|
|
||||||
ags.url = "github:Aylur/ags";
|
|
||||||
|
|
||||||
hyprpanel.url = "github:Jas-SinghFSU/HyprPanel";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = {
|
outputs = {
|
||||||
self,
|
self,
|
||||||
nixpkgs,
|
nixpkgs,
|
||||||
home-manager,
|
nixpkgs-unstable,
|
||||||
hyprland,
|
|
||||||
grub2-themes,
|
grub2-themes,
|
||||||
nixcord,
|
colmena,
|
||||||
...
|
...
|
||||||
} @ inputs: let
|
} @ inputs: let
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
|
|
||||||
pkgs = import nixpkgs {
|
pkgs = import nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
config.allowUnfree = true;
|
config = {
|
||||||
|
allowUnfree = false; # sanity check
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pkgs-unstable = import nixpkgs-unstable {
|
||||||
|
inherit system;
|
||||||
|
config = {
|
||||||
|
allowUnfree = true; # TODO: bandaid solution... (for minecraft-server)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
# TODO: come back to this its really cool
|
||||||
# this is just something I'm experimenting with
|
# this is just something I'm experimenting with
|
||||||
PROJECT_ROOT = builtins.toString ./.;
|
# PROJECT_ROOT = builtins.toString ./.;
|
||||||
in {
|
in {
|
||||||
|
devShells."x86_64-linux".default = pkgs.mkShell {
|
||||||
|
shell = "${pkgs.bash}/bin/bash";
|
||||||
|
|
||||||
|
packages = with pkgs; [
|
||||||
|
# ./script/* dependencies
|
||||||
|
mkpasswd
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
nixosConfigurations = {
|
nixosConfigurations = {
|
||||||
# i be on my puter fr
|
# i be on my puter fr
|
||||||
myputer = nixpkgs.lib.nixosSystem {
|
myputer = nixpkgs.lib.nixosSystem {
|
||||||
# nix passes these to every single module above
|
# nix passes these to every single module
|
||||||
specialArgs = {inherit inputs pkgs;};
|
specialArgs = {inherit inputs pkgs-unstable;};
|
||||||
|
|
||||||
modules = [
|
modules = [
|
||||||
./hosts/myputer
|
./hosts/myputer
|
||||||
|
|
@ -65,7 +60,7 @@
|
||||||
|
|
||||||
# my laptop 0w0
|
# my laptop 0w0
|
||||||
lolcathost = nixpkgs.lib.nixosSystem {
|
lolcathost = nixpkgs.lib.nixosSystem {
|
||||||
specialArgs = {inherit inputs pkgs;};
|
specialArgs = {inherit inputs pkgs-unstable;};
|
||||||
|
|
||||||
modules = [
|
modules = [
|
||||||
./hosts/lolcathost
|
./hosts/lolcathost
|
||||||
|
|
@ -73,5 +68,24 @@
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# remote deployment to my servers!!
|
||||||
|
colmenaHive = colmena.lib.makeHive {
|
||||||
|
meta = {
|
||||||
|
nixpkgs = pkgs;
|
||||||
|
specialArgs = {inherit pkgs-unstable;};
|
||||||
|
|
||||||
|
# set nixpkgs per server
|
||||||
|
nodeNixpkgs = {
|
||||||
|
hyrule = import nixpkgs {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
config.allowUnfree = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# meine vps
|
||||||
|
hyrule = import ./hosts/hyrule;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
28
homes/ae/default.nix
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
inputs,
|
||||||
|
outputs,
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
nixpkgs = {
|
||||||
|
config.allowUnfree = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
../modules/fish.nix
|
||||||
|
../modules/bat.nix
|
||||||
|
../modules/btop.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
home = {
|
||||||
|
username = "ae";
|
||||||
|
homeDirectory = "/home/ae";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Nicely reload system units when changing configs
|
||||||
|
systemd.user.startServices = "sd-switch";
|
||||||
|
|
||||||
|
home.stateVersion = "24.11"; # DO NOT MODIFY
|
||||||
|
}
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
openai-symbolic.svg
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
width="20"
|
|
||||||
height="20"
|
|
||||||
viewBox="0 0 20 20"
|
|
||||||
fill="none"
|
|
||||||
version="1.1"
|
|
||||||
id="svg9"
|
|
||||||
sodipodi:docname="oxygen.svg"
|
|
||||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
|
|
||||||
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="defs9" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview9"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#000000"
|
|
||||||
borderopacity="0.25"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:zoom="7.6782609"
|
|
||||||
inkscape:cx="-11.916761"
|
|
||||||
inkscape:cy="11.786523"
|
|
||||||
inkscape:window-width="1627"
|
|
||||||
inkscape:window-height="1028"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="svg9" />
|
|
||||||
<g
|
|
||||||
id="g9"
|
|
||||||
transform="translate(0.7158741,-0.307456)">
|
|
||||||
<path
|
|
||||||
d="m 12.821126,8.892686 c 0,2.99523 -2.42813,5.42337 -5.4233602,5.42337 -2.99523,0 -5.42334,-2.42814 -5.42334,-5.42337 0,-2.99523 2.42811,-5.42334 5.42334,-5.42334 2.9952302,0 5.4233602,2.42811 5.4233602,5.42334 z"
|
|
||||||
fill="white"
|
|
||||||
id="path7"
|
|
||||||
style="fill:#000000" />
|
|
||||||
<path
|
|
||||||
d="m 16.593826,4.412536 c 0,1.04182 -0.8445,1.88638 -1.8863,1.88638 -1.0419,0 -1.8864,-0.84456 -1.8864,-1.88638 0,-1.041819 0.8445,-1.88638 1.8864,-1.88638 1.0418,0 1.8863,0.844561 1.8863,1.88638 z"
|
|
||||||
fill="white"
|
|
||||||
id="path8"
|
|
||||||
style="fill:#000000" />
|
|
||||||
<path
|
|
||||||
d="m 16.593826,15.495056 c 0,1.4325 -1.1612,2.5937 -2.5937,2.5937 -1.4325,0 -2.5938,-1.1612 -2.5938,-2.5937 0,-1.4325 1.1613,-2.5938 2.5938,-2.5938 1.4325,0 2.5937,1.1613 2.5937,2.5938 z"
|
|
||||||
fill="white"
|
|
||||||
id="path9"
|
|
||||||
style="fill:#000000" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 306 KiB |
|
|
@ -1,113 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
version="1.0"
|
|
||||||
width="20"
|
|
||||||
height="19.999941"
|
|
||||||
id="svg2424"
|
|
||||||
sodipodi:docname="archlinux-logo-black-scalable.f931920e6cdb.svg"
|
|
||||||
viewBox="0 0 166.18749 166.187"
|
|
||||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
|
|
||||||
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="namedview1"
|
|
||||||
pagecolor="#505050"
|
|
||||||
bordercolor="#ffffff"
|
|
||||||
borderopacity="1"
|
|
||||||
inkscape:showpageshadow="0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pagecheckerboard="1"
|
|
||||||
inkscape:deskcolor="#505050"
|
|
||||||
inkscape:zoom="16.650008"
|
|
||||||
inkscape:cx="13.093087"
|
|
||||||
inkscape:cy="16.366359"
|
|
||||||
inkscape:window-width="1340"
|
|
||||||
inkscape:window-height="768"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="g2424" />
|
|
||||||
<defs
|
|
||||||
id="defs2426">
|
|
||||||
<linearGradient
|
|
||||||
x1="112.49854"
|
|
||||||
y1="6.1372099"
|
|
||||||
x2="112.49853"
|
|
||||||
y2="129.3468"
|
|
||||||
id="path1082_2_"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
gradientTransform="translate(287,-83)">
|
|
||||||
<stop
|
|
||||||
id="stop193"
|
|
||||||
style="stop-color:#ffffff;stop-opacity:0"
|
|
||||||
offset="0" />
|
|
||||||
<stop
|
|
||||||
id="stop195"
|
|
||||||
style="stop-color:#ffffff;stop-opacity:0.27450982"
|
|
||||||
offset="1" />
|
|
||||||
<midPointStop
|
|
||||||
offset="0"
|
|
||||||
style="stop-color:#FFFFFF"
|
|
||||||
id="midPointStop197" />
|
|
||||||
<midPointStop
|
|
||||||
offset="0.5"
|
|
||||||
style="stop-color:#FFFFFF"
|
|
||||||
id="midPointStop199" />
|
|
||||||
<midPointStop
|
|
||||||
offset="1"
|
|
||||||
style="stop-color:#000000"
|
|
||||||
id="midPointStop201" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
x1="541.33502"
|
|
||||||
y1="104.50665"
|
|
||||||
x2="606.91248"
|
|
||||||
y2="303.14029"
|
|
||||||
id="linearGradient2544"
|
|
||||||
xlink:href="#path1082_2_"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
gradientTransform="matrix(-0.3937741,0,0,0.393752,357.51969,122.00151)" />
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient3388">
|
|
||||||
<stop
|
|
||||||
id="stop3390"
|
|
||||||
style="stop-color:#000000;stop-opacity:0"
|
|
||||||
offset="0" />
|
|
||||||
<stop
|
|
||||||
id="stop3392"
|
|
||||||
style="stop-color:#000000;stop-opacity:0.37113401"
|
|
||||||
offset="1" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
x1="490.72305"
|
|
||||||
y1="237.72447"
|
|
||||||
x2="490.72305"
|
|
||||||
y2="183.9644"
|
|
||||||
id="linearGradient4416"
|
|
||||||
xlink:href="#linearGradient3388"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
gradientTransform="matrix(0.749107,0,0,0.749107,-35.459862,91.44108)" />
|
|
||||||
</defs>
|
|
||||||
<g
|
|
||||||
transform="translate(-57.527313,-146.42741)"
|
|
||||||
id="layer1">
|
|
||||||
<g
|
|
||||||
transform="matrix(0.8746356,0,0,0.8746356,14.730518,23.408954)"
|
|
||||||
id="g2424"
|
|
||||||
style="fill:#000000">
|
|
||||||
<g
|
|
||||||
transform="matrix(0.6378586,0,0,0.6378586,36.486487,2.17139)"
|
|
||||||
id="g2809"
|
|
||||||
style="fill:#000000;fill-opacity:1" />
|
|
||||||
<path
|
|
||||||
d="m 143.91698,140.65081 c -8.45709,20.73453 -13.55799,34.29734 -22.97385,54.41552 5.7731,6.11948 12.85931,13.24593 24.36729,21.29458 -12.37221,-5.09109 -20.81157,-10.20242 -27.11844,-15.50646 -12.0505,25.14523 -30.930177,60.96349 -69.243121,129.80406 30.112687,-17.38458 53.455511,-28.10236 75.209891,-32.19198 -0.93414,-4.01773 -1.46524,-8.36369 -1.42916,-12.89823 l 0.0357,-0.96469 c 0.47781,-19.2924 10.51371,-34.12825 22.40218,-33.12093 11.88848,1.00732 21.12927,17.4729 20.65146,36.76531 -0.0899,3.63022 -0.49934,7.12245 -1.21479,10.36146 21.51819,4.20934 44.61141,14.89968 74.31666,32.04906 -5.85729,-10.78369 -11.08544,-20.5044 -16.07812,-29.7624 -7.86429,-6.09535 -16.06714,-14.02847 -32.79938,-22.61656 11.50078,2.98839 19.73519,6.43619 26.15375,10.29 -50.76203,-94.51003 -54.87267,-107.06846 -72.2801,-147.91874 z"
|
|
||||||
id="path2518"
|
|
||||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.14333" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 4.1 KiB |
|
|
@ -1,318 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
id="SVGRoot"
|
|
||||||
width="20"
|
|
||||||
height="20"
|
|
||||||
version="1.1"
|
|
||||||
viewBox="0 0 17.921003 17.921002"
|
|
||||||
sodipodi:docname="cachyos-symbolic.svg"
|
|
||||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
|
|
||||||
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="namedview30"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#000000"
|
|
||||||
borderopacity="0.25"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:zoom="32"
|
|
||||||
inkscape:cx="10.671875"
|
|
||||||
inkscape:cy="11.234375"
|
|
||||||
inkscape:window-width="1687"
|
|
||||||
inkscape:window-height="1028"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="SVGRoot" />
|
|
||||||
<defs
|
|
||||||
id="defs6">
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient939"
|
|
||||||
x1="237.19"
|
|
||||||
x2="237.07001"
|
|
||||||
y1="296.20001"
|
|
||||||
y2="304.07999"
|
|
||||||
gradientTransform="matrix(0.04476,0,0,0.044679,-8.5042241,-4.351186)"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
xlink:href="#linearGradient937" />
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient937">
|
|
||||||
<stop
|
|
||||||
stop-color="#001313"
|
|
||||||
offset="0"
|
|
||||||
id="stop1" />
|
|
||||||
<stop
|
|
||||||
stop-color="#001313"
|
|
||||||
stop-opacity="0"
|
|
||||||
offset="1"
|
|
||||||
id="stop2" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient5185"
|
|
||||||
x1="994.81"
|
|
||||||
x2="982.34003"
|
|
||||||
y1="1533.3"
|
|
||||||
y2="1556.8"
|
|
||||||
gradientTransform="matrix(0.084141,0,0,0.083989,-76.242924,-126.39098)"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
xlink:href="#linearGradient4353" />
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient4353">
|
|
||||||
<stop
|
|
||||||
stop-color="#020202"
|
|
||||||
offset="0"
|
|
||||||
id="stop3" />
|
|
||||||
<stop
|
|
||||||
stop-color="#020202"
|
|
||||||
stop-opacity="0"
|
|
||||||
offset="1"
|
|
||||||
id="stop4" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient9102"
|
|
||||||
x1="1022.5"
|
|
||||||
x2="1018.6"
|
|
||||||
y1="1582.4"
|
|
||||||
y2="1575.6"
|
|
||||||
gradientTransform="matrix(0.086381,0,0,0.081808,-79.103924,-124.69099)"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
xlink:href="#linearGradient4353" />
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient11890"
|
|
||||||
x1="940.42999"
|
|
||||||
x2="930.59003"
|
|
||||||
y1="1612.5"
|
|
||||||
y2="1594.5"
|
|
||||||
gradientTransform="matrix(0.084141,0,0,0.083989,-76.242924,-126.39098)"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
xlink:href="#linearGradient4353" />
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient11670"
|
|
||||||
x1="965.59998"
|
|
||||||
x2="951.65997"
|
|
||||||
y1="1571.4"
|
|
||||||
y2="1571.3"
|
|
||||||
gradientTransform="matrix(0.084141,0,0,0.083989,-76.242924,-126.39098)"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
xlink:href="#linearGradient4353" />
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient13770"
|
|
||||||
x1="946.22998"
|
|
||||||
x2="961.37"
|
|
||||||
y1="1655.9"
|
|
||||||
y2="1655.8"
|
|
||||||
gradientTransform="matrix(0.084141,0,0,0.083989,-76.242924,-126.39098)"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
xlink:href="#linearGradient4353" />
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient2816"
|
|
||||||
x1="366.14999"
|
|
||||||
x2="350.92001"
|
|
||||||
y1="427.32001"
|
|
||||||
y2="419.64001"
|
|
||||||
gradientTransform="matrix(0.04476,0,0,0.044679,-10.832924,-4.155886)"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
xlink:href="#linearGradient937" />
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient12421"
|
|
||||||
x1="936.34003"
|
|
||||||
x2="933.38"
|
|
||||||
y1="1628.8"
|
|
||||||
y2="1623"
|
|
||||||
gradientTransform="matrix(0.084141,0,0,0.083989,-76.242924,-126.39098)"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
xlink:href="#linearGradient4353" />
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient13391"
|
|
||||||
x1="950.33002"
|
|
||||||
x2="941.96997"
|
|
||||||
y1="1618.6"
|
|
||||||
y2="1645.8"
|
|
||||||
gradientTransform="matrix(0.084141,0,0,0.083989,-76.242924,-126.39098)"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
xlink:href="#linearGradient4353" />
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient13599"
|
|
||||||
x1="1008.2"
|
|
||||||
x2="1015.7"
|
|
||||||
y1="1681.3"
|
|
||||||
y2="1668.4"
|
|
||||||
gradientTransform="matrix(0.084141,0,0,0.083989,-77.884838,-124.43841)"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
xlink:href="#linearGradient4353" />
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient18175"
|
|
||||||
x1="1148.3"
|
|
||||||
x2="1145.4"
|
|
||||||
y1="1585.5"
|
|
||||||
y2="1630"
|
|
||||||
gradientTransform="matrix(0.34992,0,0,0.34992,-282.87,-491.67)"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
xlink:href="#linearGradient18299" />
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient18299">
|
|
||||||
<stop
|
|
||||||
stop-color="#008066"
|
|
||||||
stop-opacity="0"
|
|
||||||
offset="0"
|
|
||||||
id="stop5" />
|
|
||||||
<stop
|
|
||||||
stop-color="#0fc"
|
|
||||||
offset="1"
|
|
||||||
id="stop6" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient18632"
|
|
||||||
x1="1148.3"
|
|
||||||
x2="1145.4"
|
|
||||||
y1="1585.5"
|
|
||||||
y2="1630"
|
|
||||||
gradientTransform="matrix(0.26565,0,0,0.26565,-211.15,-375.49)"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
xlink:href="#linearGradient18299" />
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient18659"
|
|
||||||
x1="1148.3"
|
|
||||||
x2="1145.4"
|
|
||||||
y1="1585.5"
|
|
||||||
y2="1630"
|
|
||||||
gradientTransform="matrix(0.13679,0,0,0.13679,-53.624,-195.03)"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
xlink:href="#linearGradient18299" />
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient3254"
|
|
||||||
x1="348.04999"
|
|
||||||
x2="361.20999"
|
|
||||||
y1="194.78"
|
|
||||||
y2="187.24001"
|
|
||||||
gradientTransform="matrix(0.04476,0,0,0.044679,-10.832924,-4.155886)"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
xlink:href="#linearGradient937" />
|
|
||||||
</defs>
|
|
||||||
<circle
|
|
||||||
cx="87.449997"
|
|
||||||
cy="87.449997"
|
|
||||||
r="87.449997"
|
|
||||||
opacity="0"
|
|
||||||
stroke-width="0.27971"
|
|
||||||
id="circle6" />
|
|
||||||
<path
|
|
||||||
d="m 4.0610759,2.168314 6.5887001,3.6879 2.1127,-3.6528 z"
|
|
||||||
fill="#00aa88"
|
|
||||||
id="path7"
|
|
||||||
style="fill:#000000" />
|
|
||||||
<path
|
|
||||||
d="m 6.1499759,12.423014 -1.9125,3.7456 h 8.5747001 l 2.1664,-3.7456 z"
|
|
||||||
fill="#00aa88"
|
|
||||||
id="path8"
|
|
||||||
style="fill:#7a7a7a;fill-opacity:0.68506807" />
|
|
||||||
<path
|
|
||||||
d="m 4.0610759,2.168314 6.5887001,3.6879 H 6.1237759 l -1.8859,3.2605 1.9121,3.306 -1.9125,3.7456 -4.13689997,-7.1525 3.96049997,-6.8475"
|
|
||||||
fill="#00ccff"
|
|
||||||
id="path9"
|
|
||||||
style="fill:#7a7a7a;fill-opacity:0.69262218" />
|
|
||||||
<path
|
|
||||||
d="m 6.0909759,5.821714 6.7111001,-3.7832 -2.169,3.5579 z"
|
|
||||||
fill="url(#linearGradient9102)"
|
|
||||||
id="path12"
|
|
||||||
style="fill:url(#linearGradient9102)" />
|
|
||||||
<path
|
|
||||||
d="m 6.1236759,5.856214 6.6388001,-3.6528 -2.1127,3.6528 z"
|
|
||||||
fill="#00aa88"
|
|
||||||
id="path13"
|
|
||||||
style="fill:#000000" />
|
|
||||||
<path
|
|
||||||
d="m 0.10057593,9.015814 6.02309997,-3.1596 -1.8859,3.2605 z"
|
|
||||||
fill="#00aa88"
|
|
||||||
id="path14"
|
|
||||||
style="fill:#1a1a1a" />
|
|
||||||
<path
|
|
||||||
d="m 6.1236759,5.856214 -2.0626,-3.6879 0.17673,6.9484 z"
|
|
||||||
fill="#00aa88"
|
|
||||||
id="path16"
|
|
||||||
style="fill:#1a1a1a" />
|
|
||||||
<path
|
|
||||||
d="m 4.2378759,9.116714 -3.1586,1.5811 3.1583,5.4705 z"
|
|
||||||
fill="#00aa88"
|
|
||||||
id="path19"
|
|
||||||
style="fill:#1a1a1a" />
|
|
||||||
<path
|
|
||||||
d="m 1.0792259,10.698014 5.0708,1.7248 -1.9121,-3.306 z"
|
|
||||||
fill="#00aa88"
|
|
||||||
id="path23"
|
|
||||||
style="fill:#1a1a1a" />
|
|
||||||
<g
|
|
||||||
transform="matrix(0.14699,0,0,0.14672,-0.75949407,-0.14715599)"
|
|
||||||
id="g26"
|
|
||||||
style="fill:#1a1a1a">
|
|
||||||
<circle
|
|
||||||
cx="117.95"
|
|
||||||
cy="75.441002"
|
|
||||||
r="9.6893997"
|
|
||||||
fill="#00ccff"
|
|
||||||
id="circle25"
|
|
||||||
style="fill:#1a1a1a" />
|
|
||||||
<circle
|
|
||||||
cx="118.08"
|
|
||||||
cy="75.341003"
|
|
||||||
r="9.6893997"
|
|
||||||
fill="url(#linearGradient18175)"
|
|
||||||
id="circle26"
|
|
||||||
style="fill:#1a1a1a" />
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
transform="matrix(0.14699,0,0,0.14672,-0.11248407,-0.47061599)"
|
|
||||||
id="g28"
|
|
||||||
style="fill:#1a1a1a">
|
|
||||||
<circle
|
|
||||||
cx="93.138"
|
|
||||||
cy="55.044998"
|
|
||||||
r="7.3558998"
|
|
||||||
fill="#00ccff"
|
|
||||||
id="circle27"
|
|
||||||
style="fill:#1a1a1a" />
|
|
||||||
<circle
|
|
||||||
cx="93.238998"
|
|
||||||
cy="54.969002"
|
|
||||||
r="7.3558998"
|
|
||||||
fill="url(#linearGradient18632)"
|
|
||||||
id="circle28"
|
|
||||||
style="fill:#1a1a1a" />
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
transform="matrix(0.14699,0,0,0.14672,-0.08243407,-0.04714599)"
|
|
||||||
id="g30"
|
|
||||||
style="fill:#000000">
|
|
||||||
<circle
|
|
||||||
cx="103.06"
|
|
||||||
cy="26.657"
|
|
||||||
r="3.7876999"
|
|
||||||
fill="#00ccff"
|
|
||||||
id="circle29"
|
|
||||||
style="fill:#000000" />
|
|
||||||
<circle
|
|
||||||
cx="103.11"
|
|
||||||
cy="26.618"
|
|
||||||
r="3.7876999"
|
|
||||||
fill="url(#linearGradient18659)"
|
|
||||||
id="circle30"
|
|
||||||
style="fill:#000000" />
|
|
||||||
</g>
|
|
||||||
<path
|
|
||||||
d="m 6.1236759,5.856214 -2.0626,-3.6879 0.52544,-0.0074 1.9387,3.4465 z"
|
|
||||||
fill="url(#linearGradient3254)"
|
|
||||||
id="path30"
|
|
||||||
style="fill:url(#linearGradient3254)" />
|
|
||||||
<path
|
|
||||||
d="M 12.808567,16.168211 6.1524738,12.428132 4.2457352,16.165572 Z"
|
|
||||||
fill="#00ccff"
|
|
||||||
id="path17"
|
|
||||||
style="fill:#1a1a1a;fill-opacity:1"
|
|
||||||
sodipodi:nodetypes="cccc" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 9 KiB |
|
|
@ -1,10 +0,0 @@
|
||||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g clip-path="url(#clip0_26_18)">
|
|
||||||
<path d="M3 7.06015V4.74436C4.12 4.69624 4.90412 4.62466 5.35237 4.52962C6.06664 4.37804 6.64769 4.07549 7.09553 3.62195C7.40205 3.31158 7.63448 2.89754 7.7928 2.37985C7.8839 2.06947 7.92946 1.8387 7.92946 1.68752H10.9001V19H7.25588V7.06015H3ZM12.4228 5.65444V4.52962L15.0783 1H16.1879V4.64211H17V5.65444H16.1879V7.05594H15.0084V5.65444H12.4228ZM14.9823 2.53985L13.4031 4.64511H15.0102V2.53985H14.9823Z" fill="black"/>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="clip0_26_18">
|
|
||||||
<rect width="20" height="20" fill="white"/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 660 B |
|
|
@ -1,65 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
fill="#000000"
|
|
||||||
width="20"
|
|
||||||
height="20"
|
|
||||||
viewBox="0 0 380.95238 380.95238"
|
|
||||||
version="1.1"
|
|
||||||
id="svg1"
|
|
||||||
sodipodi:docname="crosshair-symbolic.svg"
|
|
||||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
|
|
||||||
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"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
|
||||||
<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="35"
|
|
||||||
inkscape:cx="10.371429"
|
|
||||||
inkscape:cy="7.9571429"
|
|
||||||
inkscape:window-width="1430"
|
|
||||||
inkscape:window-height="1028"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="svg1" />
|
|
||||||
<title
|
|
||||||
id="title1">ionicons-v5_logos</title>
|
|
||||||
<metadata
|
|
||||||
id="metadata1">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:title>ionicons-v5_logos</dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<rect
|
|
||||||
style="fill:#000000;stroke-width:23.0377"
|
|
||||||
id="rect1"
|
|
||||||
width="380.95239"
|
|
||||||
height="57.142857"
|
|
||||||
x="-3.5527137e-15"
|
|
||||||
y="161.90475" />
|
|
||||||
<rect
|
|
||||||
style="fill:#000000;stroke-width:23.0451;stroke-dasharray:none"
|
|
||||||
id="rect1-5"
|
|
||||||
width="57.142857"
|
|
||||||
height="380.95239"
|
|
||||||
x="161.90475"
|
|
||||||
y="0" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.8 KiB |
|
|
@ -1,91 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
width="20"
|
|
||||||
height="20"
|
|
||||||
viewBox="-30.5 0 317.00242 317.00243"
|
|
||||||
version="1.1"
|
|
||||||
preserveAspectRatio="xMidYMid"
|
|
||||||
id="svg12"
|
|
||||||
sodipodi:docname="debian-symbolic.svg"
|
|
||||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
|
|
||||||
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="defs12" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview12"
|
|
||||||
pagecolor="#505050"
|
|
||||||
bordercolor="#ffffff"
|
|
||||||
borderopacity="1"
|
|
||||||
inkscape:showpageshadow="0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pagecheckerboard="1"
|
|
||||||
inkscape:deskcolor="#505050"
|
|
||||||
inkscape:zoom="17.5"
|
|
||||||
inkscape:cx="13.742857"
|
|
||||||
inkscape:cy="12.628571"
|
|
||||||
inkscape:window-width="1295"
|
|
||||||
inkscape:window-height="867"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="svg12" />
|
|
||||||
<g
|
|
||||||
fill="#A80030"
|
|
||||||
id="g12"
|
|
||||||
style="fill:#1a1a1a"
|
|
||||||
transform="translate(0.05835351,0.0538775)">
|
|
||||||
<path
|
|
||||||
d="m 152.79662,167.42537 c -5.25095,0.0731 0.9935,2.70583 7.84865,3.76069 1.8935,-1.47856 3.61167,-2.97466 5.14283,-4.42984 -4.26913,1.04609 -8.61424,1.06947 -12.99148,0.66915"
|
|
||||||
id="path1"
|
|
||||||
style="fill:#1a1a1a" />
|
|
||||||
<path
|
|
||||||
d="m 180.9799,160.40073 c 3.12661,-4.31588 5.40581,-9.04086 6.20938,-13.92654 -0.70129,3.4831 -2.59187,6.4899 -4.3714,9.66326 -9.81521,6.18016 -0.92337,-3.67011 -0.006,-7.41328 -10.55448,13.2837 -1.44934,7.96554 -1.83213,11.67656"
|
|
||||||
id="path2"
|
|
||||||
style="fill:#1a1a1a" />
|
|
||||||
<path
|
|
||||||
d="m 191.38244,133.33075 c 0.63409,-9.45579 -1.86135,-6.46652 -2.69999,-2.85777 0.9789,0.50844 1.75324,6.66522 2.69999,2.85777"
|
|
||||||
id="path3"
|
|
||||||
style="fill:#1a1a1a" />
|
|
||||||
<path
|
|
||||||
d="m 132.88569,4.0879643 c 2.80225,0.5025946 6.05451,0.8883068 5.59867,1.5574589 3.06524,-0.6720742 3.76069,-1.2915513 -5.59867,-1.5574589"
|
|
||||||
id="path4"
|
|
||||||
style="fill:#1a1a1a" />
|
|
||||||
<path
|
|
||||||
d="m 138.48436,5.6454232 -1.98116,0.4090887 1.84382,-0.1636355 0.13734,-0.2454532"
|
|
||||||
id="path5"
|
|
||||||
style="fill:#1a1a1a" />
|
|
||||||
<path
|
|
||||||
d="m 225.86569,136.91612 c 0.31266,8.49151 -2.48375,12.61162 -5.00549,19.90509 l -4.53796,2.26752 c -3.71394,7.21165 0.35941,4.57887 -2.29967,10.31487 -5.79737,5.15452 -17.59373,16.12979 -21.36903,17.13205 -2.75551,-0.0614 1.86719,-3.25225 2.47206,-4.50289 -7.76099,5.32984 -6.22691,8.0006 -18.09633,11.23824 l -0.34772,-0.77142 c -29.27322,13.77168 -69.93663,-13.52038 -69.40189,-50.75913 -0.31266,2.36394 -0.88831,1.77369 -1.537,2.7292 -1.51071,-19.15996 8.848,-38.40465 26.31901,-46.262078 17.08821,-8.459369 37.12187,-4.987959 49.36238,6.419768 -6.72366,-8.807092 -20.1067,-18.14308 -35.96765,-17.269383 -15.53661,0.245453 -30.07094,10.1191 -34.92156,20.837223 -7.9597,5.01133 -8.88307,19.31775 -12.351558,21.93592 -4.666532,34.29623 8.777878,49.11401 31.520278,66.54411 3.57953,2.41362 1.00811,2.77888 1.49318,4.61685 -7.55646,-3.53861 -14.4759,-8.88014 -20.16515,-15.41972 3.01849,4.41816 6.27659,8.71359 10.48728,12.08857 -7.12399,-2.41362 -16.64115,-17.26354 -19.42003,-17.8684 12.28143,21.98851 49.827,38.56245 69.48663,30.33976 -9.09638,0.33604 -20.65313,0.18702 -30.8745,-3.59121 -4.29251,-2.20908 -10.13079,-6.78503 -9.08761,-7.64119 26.83037,10.02267 54.54612,7.59151 77.7619,-11.0191 5.90549,-4.59932 12.3574,-12.4246 14.22168,-12.53272 -2.8081,4.22238 0.47921,2.03083 -1.67727,5.75938 5.88504,-9.49085 -2.5568,-3.86296 6.08374,-16.38984 l 3.19089,4.39478 c -1.18636,-7.87788 9.78306,-17.44471 8.66975,-29.90438 2.5159,-3.81037 2.80811,4.09965 0.13734,12.86584 3.70517,-9.72462 0.97597,-11.28793 1.92856,-19.31191 1.02857,2.69707 2.37856,5.56361 3.07109,8.4097 -2.41362,-9.39735 2.47791,-15.82589 3.68764,-21.28722 -1.1922,-0.52889 -3.72563,4.15517 -4.3042,-6.94574 0.0847,-4.8214 1.34123,-2.52759 1.82629,-3.71394 -0.94675,-0.54351 -3.4305,-4.23991 -4.9412,-11.328836 1.09577,-1.665575 2.9279,4.318806 4.41815,4.564256 -0.95843,-5.636653 -2.6094,-9.935006 -2.67661,-14.259657 -4.35387,-9.0993 -1.53992,1.212656 -5.07269,-3.906796 -4.63439,-14.45544 3.84543,-3.354527 4.41815,-9.923322 7.02464,10.177541 11.03079,25.950835 12.86876,32.484565 -1.40259,-7.965545 -3.67011,-15.68271 -6.4373,-23.148578 2.13311,0.897073 -3.43634,-16.389844 2.77304,-4.941206 -6.63308,-24.40506 -28.38783,-47.208829 -48.40103,-57.909419 2.44869,2.241221 5.54023,5.055166 4.42984,5.496398 -9.95254,-5.925941 -8.20223,-6.387627 -9.62819,-8.891834 -8.10872,-3.299008 -8.64054,0.265908 -14.01129,0.0058 -15.28238,-8.105755 -18.22782,-7.243747 -32.2917,-12.32229 l 0.63993,2.9892691 c -10.12494,-3.3720592 -11.79636,1.279863 -22.73948,0.011688 -0.66623,-0.520127 3.50647,-1.8818077 6.93989,-2.3814803 -9.7889,1.2915513 -9.33014,-1.9285607 -18.90866,0.3564916 2.36103,-1.656809 4.85647,-2.7525822 7.37529,-4.1610159 -7.98308,0.4850622 -19.05769,4.6460781 -15.63888,0.8620082 C 96.316085,8.9298206 73.190888,17.085295 60.214012,29.25276 L 59.804924,26.526476 C 53.858528,33.665073 33.874548,47.845838 32.282025,57.091242 l -1.589602,0.371102 C 27.59796,62.7016 25.596347,68.63923 23.141816,74.030433 19.09476,80.926499 17.21003,76.683665 17.785676,77.764828 9.8259803,93.903375 5.8724309,107.46466 2.4565407,118.58603 4.8906182,122.224 2.514982,140.48688 3.4354314,155.10304 -0.56194899,227.28965 54.098137,297.37822 113.84553,313.5606 c 8.75742,3.13245 21.78105,3.01264 32.85859,3.33407 -13.07039,-3.73732 -14.75934,-1.98116 -27.49076,-6.41977 -9.18404,-4.32465 -11.19734,-9.26293 -17.70185,-14.90836 l 2.57434,4.54965 c -12.757724,-4.51458 -7.419118,-5.58698 -17.798281,-8.8743 l 2.74966,-3.59121 c -4.134717,-0.31266 -10.951887,-6.96912 -12.816162,-10.65384 l -4.523352,0.17825 C 66.26268,270.46895 63.366917,265.63586 63.577306,261.8927 l -1.461031,2.60356 c -1.656809,-2.84317 -19.995669,-25.15019 -10.481436,-19.95768 -1.767847,-1.6159 -4.117185,-2.62986 -6.665222,-7.2584 l 1.937326,-2.21493 c -4.57887,-5.89087 -8.427226,-13.44148 -8.135019,-15.95737 2.442843,3.299 4.137639,3.91556 5.814902,4.47952 -11.562598,-28.68881 -12.211295,-1.58084 -20.968714,-29.20309 l 1.852587,-0.14902 c -1.420122,-2.13895 -2.28213,-4.46199 -3.424657,-6.7412 l 0.80649,-8.03567 c -8.324954,-9.62527 -2.328884,-40.9264 -1.127916,-58.09351 0.832787,-6.9808 6.948662,-14.41161 11.600585,-26.064789 l -2.8344,-0.487985 c 5.417502,-9.449947 30.932945,-37.951737 42.749763,-36.484862 5.724319,-7.191194 -1.136683,-0.0263 -2.255832,-1.837977 12.573631,-13.011941 16.527181,-9.192806 25.012848,-11.533378 9.1519,-5.432112 -7.854502,2.118495 -3.51524,-2.071741 15.82004,-4.041212 11.21195,-9.186962 31.85047,-11.23825 2.17694,1.238955 -5.05224,1.913951 -6.86684,3.521085 13.18142,-6.448991 41.71243,-4.982116 60.24414,3.579525 21.50346,10.04897 45.66306,39.75465 46.61565,67.704172 l 1.08409,0.2922 c -0.54935,11.10968 1.70064,23.95799 -2.19739,35.76019 l 2.65323,-5.58698"
|
|
||||||
id="path6"
|
|
||||||
style="fill:#1a1a1a" />
|
|
||||||
<path
|
|
||||||
d="m 95.483297,174.6341 -0.736359,3.68179 c 3.450955,4.68699 6.188932,9.76553 10.595392,13.4298 -3.17043,-6.18893 -5.525615,-8.74573 -9.859033,-17.11159"
|
|
||||||
id="path7"
|
|
||||||
style="fill:#1a1a1a" />
|
|
||||||
<path
|
|
||||||
d="m 103.64169,174.31267 c -1.82629,-2.01915 -2.90745,-4.4503 -4.117181,-6.87269 1.157141,4.25744 3.526931,7.91586 5.733081,11.63565 l -1.6159,-4.76296"
|
|
||||||
id="path8"
|
|
||||||
style="fill:#1a1a1a" />
|
|
||||||
<path
|
|
||||||
d="m 248.00323,142.93557 -0.77142,1.9344 c -1.41428,10.04605 -4.46784,19.98691 -9.14898,29.20309 5.17205,-9.72462 8.51781,-20.36093 9.9204,-31.13749"
|
|
||||||
id="path9"
|
|
||||||
style="fill:#1a1a1a" />
|
|
||||||
<path
|
|
||||||
d="M 133.92302,1.5691471 C 137.47332,0.26882968 142.65122,0.85616408 146.41775,0 141.50869,0.4120107 136.623,0.65746388 131.79868,1.279863 l 2.12434,0.2892841"
|
|
||||||
id="path10"
|
|
||||||
style="fill:#1a1a1a" />
|
|
||||||
<path
|
|
||||||
d="m 9.2824769,67.847351 c 0.8181771,7.573984 -5.6980203,10.513578 1.4434981,5.519774 3.827901,-8.623004 -1.4960952,-2.38148 -1.4434981,-5.519774"
|
|
||||||
id="path11"
|
|
||||||
style="fill:#1a1a1a" />
|
|
||||||
<path
|
|
||||||
d="M 0.89031567,102.9004 C 2.5354364,97.85108 2.8334867,94.81798 3.46173,91.895919 -1.084998,97.707899 1.3695338,98.946854 0.89031567,102.9004"
|
|
||||||
id="path12"
|
|
||||||
style="fill:#1a1a1a" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 8.3 KiB |
|
|
@ -1,96 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
width="20mm"
|
|
||||||
height="20mm"
|
|
||||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
|
|
||||||
sodipodi:docname="EndeavourOS Logo.svg"
|
|
||||||
version="1.1"
|
|
||||||
viewBox="0 0 48.231007 48.231007"
|
|
||||||
id="svg8"
|
|
||||||
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"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
|
||||||
<defs
|
|
||||||
id="defs8" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="cvfa"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:current-layer="g3"
|
|
||||||
inkscape:cx="52.728754"
|
|
||||||
inkscape:cy="60.739468"
|
|
||||||
inkscape:document-rotation="0"
|
|
||||||
inkscape:document-units="mm"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:window-height="1028"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:window-width="1316"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:zoom="4.930896"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1" />
|
|
||||||
<title
|
|
||||||
id="title1">EndeavourOS Logo</title>
|
|
||||||
<metadata
|
|
||||||
id="metadata1">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title>EndeavourOS Logo</dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
transform="translate(-66.790568,-123.01834)"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
id="g8">
|
|
||||||
<g
|
|
||||||
transform="translate(76.2,-12.7)"
|
|
||||||
id="g7">
|
|
||||||
<g
|
|
||||||
transform="matrix(1.47,0,0,1.47,-519,105)"
|
|
||||||
id="g6">
|
|
||||||
<g
|
|
||||||
transform="matrix(0.963,0,0,0.983,13.5,0.76)"
|
|
||||||
id="g5">
|
|
||||||
<g
|
|
||||||
transform="matrix(0.678,0,0,0.678,452,49.2)"
|
|
||||||
id="g3">
|
|
||||||
<g
|
|
||||||
id="g9"
|
|
||||||
transform="translate(6.8384014e-4,3.6851185)">
|
|
||||||
<path
|
|
||||||
d="m -127,-42.3 c 4.57,6.45 23.8,31.4 10.7,36.6 -6.12,2.81 -34,-1.65 -33.6,-0.921 -2,3.28 -3.59,5.92 -3.59,5.92 0,0 21.5,0.967 38.1,-1.27 23.7,-3.18 -4.88,-33.5 -11.6,-40.3 z"
|
|
||||||
style="fill:#333333;fill-opacity:0.7;stroke-width:0.585"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path1" />
|
|
||||||
<path
|
|
||||||
d="m -127,-42.3 c -1.52,0.209 -29.4,34.5 -29.4,34.5 0,0 2.01,0.57 6.58,1.23 1.48,-1.15 22.3,-36.2 22.9,-35.7 -0.0107,-0.0141 -0.028,-0.0193 -0.0522,-0.016 z"
|
|
||||||
style="fill:#333333;fill-opacity:0.7;stroke-width:0.585"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path2" />
|
|
||||||
<path
|
|
||||||
d="m -127,-42.3 c -0.96,-0.156 -22.9,35.7 -22.9,35.7 0,0 19.9,2.1 28.1,1.96 23.1,-0.39 0.176,-30.6 -5.16,-37.7 -0.007,-0.007 -0.0151,-0.0108 -0.0248,-0.0124 z"
|
|
||||||
style="fill:#1a1a1a;stroke-width:0.585"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path3" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.3 KiB |
|
|
@ -1,38 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 448.00288 448.00288"
|
|
||||||
version="1.1"
|
|
||||||
id="svg1"
|
|
||||||
sodipodi:docname="Fa-Team-Fontawesome-Brands-FontAwesome-Brands-Fedora.svg"
|
|
||||||
width="19.999744"
|
|
||||||
height="19.999744"
|
|
||||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
|
|
||||||
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="#505050"
|
|
||||||
bordercolor="#ffffff"
|
|
||||||
borderopacity="1"
|
|
||||||
inkscape:showpageshadow="0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pagecheckerboard="1"
|
|
||||||
inkscape:deskcolor="#505050"
|
|
||||||
inkscape:zoom="13.671875"
|
|
||||||
inkscape:cx="19.2"
|
|
||||||
inkscape:cy="17.664"
|
|
||||||
inkscape:window-width="1313"
|
|
||||||
inkscape:window-height="908"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="svg1" />
|
|
||||||
<!--! Font Awesome Free 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. -->
|
|
||||||
<path
|
|
||||||
d="M 0.0413,223.8 C 0.1219,100.2 100.3,0 224,0 347.7,0 448,100.3 448,224 448,347.7 347.8,447.9 224.1,448 H 50.93 C 22.84,448 0.0832,425.3 0.0416,397.2 H 0 V 223.8 Z M 342.6,160.7 c 0,-39.7 -35.6,-68.5 -73.2,-68.5 -34.9,0 -65.8,26.3 -70.1,59.9 -0.2,3.8 -0.4,5 -0.4,8.5 -0.1,21.1 0,42.8 -0.8,64.4 0.9,26.1 1,52.1 0,76.6 0,27.1 -19.4,45.5 -44.7,45.5 -25.3,0 -45.8,-20.2 -45.8,-45.5 0.5,-27.7 22.6,-45.3 48.5,-46.1 h 0.2 l 26.3,-0.2 V 218 l -26.3,0.2 c -47.1,-0.4 -84.58,36.5 -85.94,83.4 0,45.6 37.54,82.9 83.04,82.9 43,0 78.7,-33.6 82.6,-75.6 l 0.2,-53.5 32.6,-0.3 c 25.3,0.2 25,-37.8 -0.2,-37.3 l -32.4,0.3 c 0,-6.4 0.1,-12.8 0.1,-19.2 0.1,-12.7 0.1,-25.4 -0.1,-38.2 0.1,-16.5 15.8,-31.2 33.2,-31.2 17.5,0 35.9,8.7 35.9,31.2 0,3.2 -0.1,5.1 -0.3,6.3 -1.9,10.5 5.2,20.4 15.7,21.9 10.6,1.5 20.2,-6.1 21.2,-16.6 0.6,-4.2 0.7,-7.9 0.7,-11.6 z"
|
|
||||||
id="path1" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.1 KiB |
|
|
@ -1,52 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
role="img"
|
|
||||||
viewBox="0 0 24.000009 24.000009"
|
|
||||||
version="1.1"
|
|
||||||
id="svg1"
|
|
||||||
sodipodi:docname="flatpak_logo_icon_248537.svg"
|
|
||||||
width="20"
|
|
||||||
height="20"
|
|
||||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
|
|
||||||
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"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
|
||||||
<defs
|
|
||||||
id="defs1" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview1"
|
|
||||||
pagecolor="#505050"
|
|
||||||
bordercolor="#ffffff"
|
|
||||||
borderopacity="1"
|
|
||||||
inkscape:showpageshadow="0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pagecheckerboard="1"
|
|
||||||
inkscape:deskcolor="#505050"
|
|
||||||
inkscape:zoom="18.229167"
|
|
||||||
inkscape:cx="11.190857"
|
|
||||||
inkscape:cy="11.766857"
|
|
||||||
inkscape:window-width="1164"
|
|
||||||
inkscape:window-height="648"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="svg1" />
|
|
||||||
<title
|
|
||||||
id="title1">Flatpak</title>
|
|
||||||
<path
|
|
||||||
d="m 12.000004,7.3336774e-5 c -0.556,0 -1.110999,0.143999993226 -1.609999,0.431999993226 L 2.7870046,4.8220733 a 3.217,3.217 0 0 0 -1.61,2.788 v 8.7799997 c 0,1.151 0.612,2.212 1.61,2.788 l 7.6030004,4.39 a 3.217,3.217 0 0 0 3.219999,0 l 7.603,-4.39 a 3.217,3.217 0 0 0 1.61,-2.788 V 7.6100733 a 3.217,3.217 0 0 0 -1.61,-2.788 l -7.603,-4.38999997 a 3.218,3.218 0 0 0 -1.61,-0.431999993226 z m 0,2.357999963226 c 0.15,0 0.299,0.039 0.431,0.115 l 7.604,4.39 c 0.132,0.077 0.24,0.187 0.315,0.316 l -8.35,4.8209997 v 9.642 a 0.863,0.863 0 0 1 -0.431,-0.116 l -7.6039994,-4.39 a 0.866,0.866 0 0 1 -0.431,-0.746 V 7.6100733 c 0,-0.153 0.041,-0.302 0.116,-0.43 l 8.3499994,4.8199997 z"
|
|
||||||
id="path1" />
|
|
||||||
<metadata
|
|
||||||
id="metadata1">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:title>Flatpak</dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.1 KiB |
|
|
@ -1,40 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
width="98"
|
|
||||||
height="96"
|
|
||||||
version="1.1"
|
|
||||||
id="svg1"
|
|
||||||
sodipodi:docname="github-symbolic.svg"
|
|
||||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
|
|
||||||
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="2.4081633"
|
|
||||||
inkscape:cx="32.597458"
|
|
||||||
inkscape:cy="46.716102"
|
|
||||||
inkscape:window-width="1339"
|
|
||||||
inkscape:window-height="1028"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="svg1" />
|
|
||||||
<path
|
|
||||||
fill-rule="evenodd"
|
|
||||||
clip-rule="evenodd"
|
|
||||||
d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z"
|
|
||||||
fill="#fff"
|
|
||||||
id="path1"
|
|
||||||
style="fill:#000000" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.9 KiB |
|
|
@ -1,56 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
fill="#000000"
|
|
||||||
width="20"
|
|
||||||
height="20"
|
|
||||||
viewBox="0 0 380.95238 380.95238"
|
|
||||||
version="1.1"
|
|
||||||
id="svg1"
|
|
||||||
sodipodi:docname="google-gemini-symbolic.svg"
|
|
||||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
|
|
||||||
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"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
|
||||||
<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="17.5"
|
|
||||||
inkscape:cx="10.828571"
|
|
||||||
inkscape:cy="16.971429"
|
|
||||||
inkscape:window-width="1351"
|
|
||||||
inkscape:window-height="981"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="svg1" />
|
|
||||||
<title
|
|
||||||
id="title1">ionicons-v5_logos</title>
|
|
||||||
<path
|
|
||||||
d="m 190.47617,352.20814 v 0 0 C 177.81956,268.68717 112.26524,203.13276 28.744252,190.4762 v 0 0 C 112.26524,177.81957 177.81956,112.26522 190.47617,28.744235 v 0 0 c 12.65659,83.520985 78.2109,149.075335 161.73196,161.731965 v 0 0 c -83.52106,12.65656 -149.07537,78.21097 -161.73196,161.73194 z"
|
|
||||||
fill="#076eff"
|
|
||||||
id="path19"
|
|
||||||
style="fill:#000000;stroke-width:4.44566" />
|
|
||||||
<metadata
|
|
||||||
id="metadata1">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:title>ionicons-v5_logos</dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
|
@ -1,77 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
height="20"
|
|
||||||
width="19.999744"
|
|
||||||
version="1.1"
|
|
||||||
id="svg8"
|
|
||||||
sodipodi:docname="nixos-symbolic.svg"
|
|
||||||
viewBox="0 0 512.00001 512.00656"
|
|
||||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
|
|
||||||
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="defs8" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview8"
|
|
||||||
pagecolor="#505050"
|
|
||||||
bordercolor="#ffffff"
|
|
||||||
borderopacity="1"
|
|
||||||
inkscape:showpageshadow="0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pagecheckerboard="1"
|
|
||||||
inkscape:deskcolor="#505050"
|
|
||||||
inkscape:zoom="27.34375"
|
|
||||||
inkscape:cx="8.832"
|
|
||||||
inkscape:cy="15.817143"
|
|
||||||
inkscape:window-width="1075"
|
|
||||||
inkscape:window-height="1028"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="svg8" />
|
|
||||||
<g
|
|
||||||
fill-rule="evenodd"
|
|
||||||
transform="matrix(1.2756532,0,0,-1.2756532,9.0810546e-6,478.03773)"
|
|
||||||
id="g8"
|
|
||||||
style="fill:#000000">
|
|
||||||
<path
|
|
||||||
d="m 122.453,169.761 97.758,-169.34 -44.926,-0.422 -26.101,45.496 -26.286,-45.25 -22.32,0.008 -11.433,19.75 37.449,64.394 -26.582,46.258 z"
|
|
||||||
fill="#5277c3"
|
|
||||||
id="path1"
|
|
||||||
style="fill:#000000" />
|
|
||||||
<path
|
|
||||||
d="M 157.738,239.515 59.961,70.183 37.133,108.882 63.484,154.229 11.152,154.366 0,173.702 l 11.391,19.777 74.488,-0.234 26.769,46.152 z"
|
|
||||||
fill="#7ebae4"
|
|
||||||
id="path2"
|
|
||||||
style="fill:#000000" />
|
|
||||||
<path
|
|
||||||
d="M 165.238,104.155 360.77,104.143 338.672,65.026 286.223,65.171 312.27,19.784 301.102,0.456 278.277,0.429 241.238,65.058 187.883,65.167 Z"
|
|
||||||
fill="#7ebae4"
|
|
||||||
id="path3"
|
|
||||||
style="fill:#000000" />
|
|
||||||
<path
|
|
||||||
d="m 279.043,178.35 -97.758,169.34 44.926,0.422 26.101,-45.496 26.286,45.254 22.32,-0.008 11.434,-19.754 -37.45,-64.39 26.582,-46.262 z"
|
|
||||||
fill="#7ebae4"
|
|
||||||
id="path4"
|
|
||||||
style="fill:#000000" />
|
|
||||||
<g
|
|
||||||
fill="#5277c3"
|
|
||||||
id="g7"
|
|
||||||
style="fill:#000000">
|
|
||||||
<path
|
|
||||||
d="m 122.453,169.761 97.758,-169.34 -44.926,-0.422 -26.101,45.496 -26.286,-45.25 -22.32,0.008 -11.433,19.75 37.449,64.394 -26.582,46.258 z"
|
|
||||||
id="path5"
|
|
||||||
style="fill:#000000" />
|
|
||||||
<path
|
|
||||||
d="m 236,244.386 -195.535,0.011 22.101,39.118 52.45,-0.149 -26.047,45.391 11.168,19.328 22.82,0.023 37.043,-64.625 53.352,-0.109 z"
|
|
||||||
id="path6"
|
|
||||||
style="fill:#000000" />
|
|
||||||
<path
|
|
||||||
d="m 243.625,108.636 97.777,169.328 22.825,-38.696 -26.348,-45.351 52.332,-0.137 11.152,-19.336 -11.39,-19.777 -74.489,0.238 -26.769,-46.152 z"
|
|
||||||
id="path7"
|
|
||||||
style="fill:#000000" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.7 KiB |
|
|
@ -1,60 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
width="20"
|
|
||||||
height="20.000149"
|
|
||||||
viewBox="0 0 853.78869 853.79504"
|
|
||||||
fill="none"
|
|
||||||
version="1.1"
|
|
||||||
id="svg5"
|
|
||||||
sodipodi:docname="ollama-symbolic.svg"
|
|
||||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
|
|
||||||
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="defs5" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview5"
|
|
||||||
pagecolor="#505050"
|
|
||||||
bordercolor="#eeeeee"
|
|
||||||
borderopacity="1"
|
|
||||||
inkscape:showpageshadow="0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#505050"
|
|
||||||
showguides="false"
|
|
||||||
inkscape:zoom="23.606557"
|
|
||||||
inkscape:cx="13.004861"
|
|
||||||
inkscape:cy="9.8065973"
|
|
||||||
inkscape:window-width="1374"
|
|
||||||
inkscape:window-height="848"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="svg5" />
|
|
||||||
<g
|
|
||||||
id="g5"
|
|
||||||
transform="translate(103.8943,1.5259608e-5)">
|
|
||||||
<path
|
|
||||||
d="M 140.629,0.23994313 C 132.66,1.5272641 123.097,5.6956941 116.354,10.845014 c -20.413,15.5091 -36.2287,48.4278 -42.9105,89.437996 -2.5133,15.509 -4.2297,37.026 -4.2297,53.455 0,19.371 2.2681,44.136 5.5171,61.239 0.7356,3.801 1.1034,7.173 0.7969,7.418 -0.2452,0.245 -3.249,2.697 -6.6206,5.394 -11.5245,9.195 -24.7043,23.356 -33.7768,36.291 -17.4095,24.704 -28.6888898,52.78 -33.4090698,83.185 -1.83902799,12.015 -2.32943599,36.29 -0.85821199,48.305 3.24895199,27.708 11.58588179,51.125 25.86898179,72.581 l 4.6589,6.927 -1.3486,2.268 c -9.563,16.061 -17.716,39.294 -21.5166498,61.607 -3.00375,17.655 -3.37156,22.375 -3.37156,46.037 0,23.847 0.30651,28.567 3.12635,45.057 3.3715598,19.739 10.2372598,40.642 17.8998598,54.558 2.5134,4.536 8.6435,13.976 9.3791,14.467 0.2452,0.122 -0.4904,2.39 -1.6551,5.026 -8.8274,19.31 -16.3674,44.995 -19.4938,66.635 -2.2068,14.834 -2.5133,19.616 -2.5133,35.248 0,19.922 1.1034,29.608 5.2719,45.485 l 0.613,2.329 H 44.019 70.3172 l -1.7165,-3.249 c -10.605,-19.616 -11.5858,-56.029 -2.452,-92.38 4.1685,-16.797 8.8887,-29.118 17.716,-46.099 l 5.2719,-10.298 v -6.314 c 0,-5.885 -0.1226,-6.559 -2.0229,-10.421 -1.4713,-2.943 -3.4329,-5.456 -6.9271,-8.889 -5.9462,-5.762 -10.2372,-11.831 -13.6701,-19.31 -15.08,-32.735 -18.0225,-81.346 -7.4174,-122.786 4.4137,-17.287 11.7085,-32.673 19.3711,-41.071 5.2106,-5.763 7.9078,-12.199 7.9078,-18.881 0,-6.927 -2.452,-12.628 -7.9691,-18.574 -15.8157,-16.919 -25.5625,-37.517 -29.0567,-61.485 -4.9654,-34.145 4.0459,-71.355 24.5204,-100.84 20.0455,-28.935 48.1824,-47.509 79.6304,-52.474 7.049,-1.165 20.229,-0.981 27.585,0.368 8.031,1.41 13.057,0.98 18.207,-1.472 6.375,-3.003 9.563,-6.743 13.302,-15.325 3.31,-7.662 5.885,-11.831 12.812,-20.474 8.337,-10.36 16.367,-17.41 29.24,-25.931 14.713,-9.624 31.448,-16.612 48.122,-19.984 6.068,-1.226 8.888,-1.41 20.229,-1.41 11.341,0 14.161,0.184 20.229,1.41 24.459,4.966 48.735,17.594 68.106,35.493 4.168,3.862 14.16,16.245 17.348,21.395 1.226,2.022 3.372,6.314 4.72,9.501 3.739,8.582 6.927,12.322 13.302,15.325 4.966,2.391 10.176,2.882 17.9,1.594 12.199,-2.084 21.578,-1.9 33.532,0.552 40.704,8.214 76.136,41.746 91.829,86.68 13.67,39.416 9.808,80.672 -10.544,112.18 -3.433,5.334 -6.866,9.625 -11.831,14.897 -10.728,11.463 -10.728,25.685 -0.061,37.455 17.532,19.187 28.505,66.389 25.194,108.012 -2.206,27.463 -9.256,52.045 -18.942,65.96 -1.716,2.452 -5.271,6.62 -7.969,9.195 -3.494,3.433 -5.455,5.946 -6.927,8.889 -1.9,3.862 -2.023,4.536 -2.023,10.421 v 6.314 l 5.272,10.298 c 8.828,16.981 13.548,29.302 17.716,46.099 9.012,35.861 8.215,71.538 -2.084,91.829 -0.858,1.716 -1.594,3.31 -1.594,3.494 0,0.184 11.709,0.306 26.053,0.306 h 25.992 l 0.674,-2.636 c 0.368,-1.409 0.981,-3.555 1.287,-4.781 0.675,-2.697 2.023,-10.666 3.127,-18.329 1.042,-7.724 1.042,-36.168 0,-44.75 -3.923,-31.141 -10.483,-55.845 -21.21,-79.201 -1.165,-2.636 -1.901,-4.904 -1.656,-5.026 0.307,-0.184 2.023,-2.636 3.862,-5.395 13.364,-20.229 21.578,-45.669 25.747,-79.262 1.103,-9.257 1.103,-49.041 0,-57.93 -2.943,-22.926 -6.498,-38.497 -12.383,-54.251 -2.452,-6.559 -8.95,-20.413 -11.708,-24.888 l -1.349,-2.268 4.659,-6.927 c 14.283,-21.456 22.62,-44.873 25.869,-72.581 1.471,-12.015 0.981,-36.29 -0.858,-48.305 -4.782,-30.467 -16,-58.42 -33.409,-83.185 -9.073,-12.935 -22.253,-27.096 -33.777,-36.291 -3.372,-2.697 -6.376,-5.149 -6.621,-5.394 -0.306,-0.245 0.062,-3.617 0.797,-7.418 7.418,-38.681 7.172,-86.924 -0.613,-124.624596 -6.743,-32.8573 -19.003,-58.9716 -34.819,-74.0516 C 523.209,4.2857941 510.336,-0.86349287 494.888,0.11732413 459.456,2.2015541 430.89,42.966714 419.61,107.21001 c -1.839,10.36 -3.432,22.498 -3.432,25.808 0,1.287 -0.246,2.329 -0.552,2.329 -0.307,0 -2.697,-1.226 -5.272,-2.758 -27.34,-16.184 -57.746,-24.827 -87.354,-24.827 -29.608,0 -60.014,8.643 -87.354,24.827 -2.575,1.532 -4.965,2.758 -5.272,2.758 -0.306,0 -0.552,-1.042 -0.552,-2.329 0,-3.433 -1.655,-15.938 -3.432,-25.808 C 216.152,49.525914 192.674,11.335414 161.472,1.7111341 157.181,0.42381313 144.982,-0.43436787 140.629,0.23994313 Z M 151.051,50.139014 c 8.827,6.9883 18.635,26.9724 24.275,49.3473 1.042,4.045696 2.145,8.704696 2.452,10.420696 0.245,1.656 0.919,5.395 1.471,8.276 2.391,12.996 3.494,27.034 3.617,44.137 l 0.061,16.858 -4.23,6.252 -4.229,6.314 h -9.87 c -11.524,0 -22.988,1.472 -33.961,4.414 -3.923,0.981 -7.724,1.962 -8.459,2.146 -1.165,0.245 -1.349,-0.123 -2.023,-5.15 -3.617,-27.279 -3.433,-57.5 0.552,-82.634 4.413,-28.014096 14.712,-53.392696 24.765,-60.871396 2.391,-1.7778 2.82,-1.7165 5.579,0.4904 z m 349.538,-0.4292 c 6.069,4.475 12.751,16.3674 17.716,31.57 9.992,30.405196 12.812,72.151196 7.54,111.874196 -0.674,5.027 -0.858,5.395 -2.023,5.15 -0.735,-0.184 -4.536,-1.165 -8.459,-2.146 -10.973,-2.942 -22.437,-4.414 -33.961,-4.414 h -9.87 l -4.229,-6.314 -4.23,-6.252 0.061,-16.858 c 0.123,-23.785 2.33,-42.359 7.601,-63.017596 5.579,-22.191 15.448,-42.1751 24.214,-49.1634 2.759,-2.2069 3.188,-2.2682 5.64,-0.4292 z"
|
|
||||||
fill="#000000"
|
|
||||||
id="path1" />
|
|
||||||
<path
|
|
||||||
d="m 313.498,358.23701 c -13.303,1.288 -16.919,1.778 -23.295,3.066 -10.36,2.145 -24.214,6.927 -33.838,11.647 -33.47,16.367 -56.519,43.646 -63.569,75.216 -1.41,6.253 -1.594,8.337 -1.594,18.881 0,10.421 0.184,12.689 1.533,18.635 9.379,41.256 47.385,71.723 96.549,77.301 10.666,1.165 56.765,1.165 67.431,0 39.478,-4.475 73.439,-25.869 88.703,-55.907 4.045,-8.03 6.007,-13.241 7.846,-21.394 1.349,-5.946 1.533,-8.214 1.533,-18.635 0,-10.544 -0.184,-12.628 -1.594,-18.881 -10.238,-45.853 -54.742,-81.959 -109.3,-88.825 -7.111,-0.858 -25.746,-1.594 -30.405,-1.104 z m 22.926,33.348 c 18.207,1.962 36.536,8.46 51.248,18.268 7.908,5.272 19.065,16.306 23.846,23.54 5.885,8.949 9.256,18.083 10.789,29.179 0.674,5.088 0.307,8.95 -1.533,17.164 -2.881,12.26 -11.831,25.072 -23.907,34.022 -5.64,4.107 -17.348,10.054 -24.52,12.383 -13.609,4.352 -22.498,5.149 -54.252,4.904 -20.719,-0.184 -24.398,-0.368 -30.344,-1.471 -20.29,-3.801 -36.351,-11.893 -47.998,-24.214 -9.441,-9.931 -13.732,-19.003 -16.061,-33.654 -1.042,-6.805 0.919,-18.084 4.904,-27.586 4.843,-11.586 17.348,-25.991 29.731,-34.267 14.344,-9.563 33.225,-16.367 50.573,-18.206 6.682,-0.736 20.842,-0.736 27.524,-0.062 z"
|
|
||||||
fill="#000000"
|
|
||||||
id="path2" />
|
|
||||||
<path
|
|
||||||
d="m 299.584,436.33601 c -4.659,2.513 -7.908,8.888 -6.927,13.608 1.103,5.088 5.578,10.238 12.566,14.468 3.74,2.268 3.985,2.574 4.169,4.842 0.122,1.349 -0.368,5.211 -1.042,8.644 -0.736,3.371 -1.288,6.927 -1.288,7.908 0.062,2.636 2.514,6.927 5.088,9.011 2.269,1.839 2.698,1.9 9.073,2.084 5.824,0.184 7.05,0.061 9.379,-1.042 6.008,-2.943 7.54,-8.337 5.333,-18.697 -1.839,-8.643 -1.471,-9.992 3.127,-12.628 4.842,-2.82 9.992,-7.785 11.524,-11.157 2.943,-6.436 0.245,-13.731 -6.253,-17.103 -1.593,-0.797 -3.555,-1.164 -6.436,-1.164 -4.475,0 -7.356,1.042 -12.628,4.413 l -3.004,1.901 -1.9,-1.165 c -7.785,-4.598 -9.195,-5.149 -13.916,-5.088 -3.371,0 -5.21,0.306 -6.865,1.165 z"
|
|
||||||
fill="#000000"
|
|
||||||
id="path3" />
|
|
||||||
<path
|
|
||||||
d="m 150.744,365.16501 c -10.85,3.433 -18.942,11.402 -23.11,22.743 -2.023,5.395 -3.004,13.916 -2.146,18.513 2.023,10.973 11.034,20.965 21.272,23.724 12.873,3.371 22.497,1.164 31.018,-7.295 4.965,-4.843 7.663,-9.073 10.36,-15.939 1.961,-4.842 2.084,-5.7 2.084,-12.566 l 0.061,-7.356 -2.574,-5.272 c -4.108,-8.337 -11.525,-14.529 -20.107,-16.797 -4.843,-1.226 -12.628,-1.164 -16.858,0.245 z"
|
|
||||||
fill="#000000"
|
|
||||||
id="path4" />
|
|
||||||
<path
|
|
||||||
d="m 478.153,364.98201 c -8.398,2.268 -15.877,8.52 -19.862,16.735 l -2.574,5.272 0.061,7.356 c 0,6.866 0.123,7.724 2.084,12.566 2.698,6.866 5.395,11.096 10.36,15.939 8.521,8.459 18.145,10.666 31.019,7.295 7.417,-1.962 14.834,-8.215 18.39,-15.51 3.065,-6.191 3.8,-10.666 2.82,-17.716 -2.268,-16.122 -11.709,-27.83 -25.747,-31.937 -4.107,-1.226 -12.076,-1.226 -16.551,0 z"
|
|
||||||
fill="#000000"
|
|
||||||
id="path5" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 8.8 KiB |
|
|
@ -1,38 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 322.58065 322.58064"
|
|
||||||
version="1.1"
|
|
||||||
id="svg1"
|
|
||||||
sodipodi:docname="openai-symbolic.svg"
|
|
||||||
width="20"
|
|
||||||
height="20"
|
|
||||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
|
|
||||||
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="#505050"
|
|
||||||
bordercolor="#ffffff"
|
|
||||||
borderopacity="1"
|
|
||||||
inkscape:showpageshadow="0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pagecheckerboard="1"
|
|
||||||
inkscape:deskcolor="#505050"
|
|
||||||
inkscape:zoom="30.935922"
|
|
||||||
inkscape:cx="9.0348044"
|
|
||||||
inkscape:cy="14.917933"
|
|
||||||
inkscape:window-width="1183"
|
|
||||||
inkscape:window-height="1028"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="svg1" />
|
|
||||||
<path
|
|
||||||
d="m 298.66868,131.77215 c 7.30439,-21.92321 4.7891,-45.939129 -6.89187,-65.880296 C 274.21007,35.30601 238.89549,19.570397 204.40593,26.975391 189.0627,9.6903649 167.01876,-0.13936259 143.90833,0.0014933 108.65412,-0.07899576 77.374064,22.618921 66.528162,56.162739 43.880552,60.800921 24.33177,74.977058 12.892261,95.069141 -4.8052718,125.57449 -0.77075743,164.02814 22.872905,190.18709 c -7.304382,21.92321 -4.789099,45.93913 6.891877,65.8803 17.566738,30.58585 52.881316,46.32146 87.370878,38.91646 15.33316,17.28503 37.38717,27.11476 60.49759,26.96384 35.27433,0.0905 66.56446,-22.62749 77.41036,-56.20149 22.64761,-4.63818 42.19639,-18.81432 53.6359,-38.9064 17.67741,-30.50536 13.63284,-68.92883 -10.00077,-95.08777 z M 177.65337,300.90986 c -14.11577,0.0201 -27.78885,-4.91989 -38.62469,-13.96485 0.493,-0.26159 1.34819,-0.73446 1.90156,-1.07654 l 64.10954,-37.02497 c 3.27993,-1.86131 5.29215,-5.35253 5.27203,-9.12545 v -90.37916 l 27.09463,15.64506 c 0.29178,0.14086 0.48294,0.42257 0.52318,0.74453 v 74.84477 c -0.0402,33.28222 -26.99402,60.26618 -60.27625,60.33661 z M 48.025738,245.54345 c -7.072976,-12.21422 -9.618443,-26.53121 -7.19371,-40.42564 0.472874,0.28171 1.307948,0.79483 1.901554,1.13691 l 64.109538,37.02497 c 3.24974,1.90155 7.2742,1.90155 10.534,0 l 78.26556,-45.19461 v 31.29012 c 0.0201,0.32196 -0.1308,0.63386 -0.38232,0.83508 l -64.80376,37.41735 c -28.86539,16.62099 -65.72938,6.74096 -82.4208,-22.08418 z M 31.153218,105.60314 c 7.042793,-12.234331 18.160346,-21.591185 31.400797,-26.450712 0,0.553362 -0.03018,1.529292 -0.03018,2.213449 v 74.059993 c -0.02012,3.76287 1.992105,7.25408 5.261973,9.11539 l 78.265542,45.18455 -27.09463,15.64506 c -0.27165,0.1811 -0.61373,0.21129 -0.91556,0.0805 L 53.227344,188.00382 C 24.42232,171.32247 14.542287,134.46853 31.143157,105.6132 Z m 222.612632,51.80478 -78.26556,-45.19461 27.09463,-15.634999 c 0.27165,-0.181101 0.61373,-0.211284 0.91557,-0.08049 l 64.81382,37.417349 c 28.85533,16.6713 38.74542,53.5856 22.07412,82.44093 -7.05285,12.21421 -18.16034,21.57107 -31.39073,26.44066 V 166.5233 c 0.0302,-3.76286 -1.97199,-7.24401 -5.23179,-9.11538 z m 26.96383,-40.58661 c -0.47287,-0.29178 -1.30794,-0.79483 -1.90155,-1.13691 L 214.71859,78.659433 c -3.24975,-1.901555 -7.2742,-1.901555 -10.53401,0 L 125.91903,123.85404 V 92.563919 c -0.0201,-0.321957 0.13079,-0.633852 0.38232,-0.835074 l 64.80376,-37.387171 c 28.86539,-16.651176 65.76963,-6.74096 82.41074,22.134493 7.03273,12.194093 9.5782,26.470833 7.19371,40.345143 z M 111.18953,172.59017 84.08484,156.94511 c -0.291773,-0.14086 -0.482934,-0.42257 -0.523179,-0.74453 V 81.355816 c 0.02012,-33.322473 27.054379,-60.326555 60.376859,-60.306432 14.09564,0 27.73854,4.950077 38.57438,13.964853 -0.493,0.261589 -1.33813,0.734462 -1.90155,1.076541 l -64.10954,37.02497 c -3.27993,1.86131 -5.29216,5.342462 -5.27204,9.115387 l -0.0402,90.338915 z m 14.71943,-31.73282 34.86183,-20.13232 34.86183,20.12226 v 40.2546 l -34.86183,20.12226 -34.86183,-20.12226 z"
|
|
||||||
id="path1"
|
|
||||||
style="stroke-width:1.00611" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 4 KiB |
|
|
@ -1,39 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
version="1.1"
|
|
||||||
width="20.000015"
|
|
||||||
height="20"
|
|
||||||
id="svg1"
|
|
||||||
sodipodi:docname="openrouter-symbolic.svg"
|
|
||||||
viewBox="0 0 47.999998 47.999962"
|
|
||||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
|
|
||||||
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="#505050"
|
|
||||||
bordercolor="#eeeeee"
|
|
||||||
borderopacity="1"
|
|
||||||
inkscape:showpageshadow="0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#505050"
|
|
||||||
inkscape:zoom="19.666667"
|
|
||||||
inkscape:cx="6.7118644"
|
|
||||||
inkscape:cy="10.805085"
|
|
||||||
inkscape:window-width="1908"
|
|
||||||
inkscape:window-height="1028"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="svg1" />
|
|
||||||
<path
|
|
||||||
d="m 32.999999,2.9999808 c 3.980422,0.5880984 6.862472,1.8203168 10.3125,3.875 0.883008,0.5130469 1.766016,1.0260937 2.675781,1.5546875 0.663867,0.5182031 1.327735,1.0364062 2.011719,1.5703125 0,0.9900002 0,1.9800002 0,3.0000002 -2.311036,1.335928 -4.623718,2.668844 -6.9375,4 -0.659355,0.381562 -1.318711,0.763125 -1.998047,1.15625 -4.951172,2.84375 -4.951172,2.84375 -6.064453,2.84375 0,-1.65 0,-3.3 0,-5 -6.609294,1.004133 -10.792298,2.789518 -16,7 3.696448,3.823912 6.292078,6.155833 11.6875,6.625 0.808242,0.07477 1.616484,0.149531 2.449219,0.226562 0.614883,0.04898 1.229765,0.09797 1.863281,0.148438 0,-0.99 0,-1.98 0,-3 4.062255,0.578231 6.847624,1.891177 10.3125,4.0625 0.883008,0.547852 1.766016,1.095703 2.675781,1.660156 0.663867,0.421524 1.327735,0.843047 2.011719,1.277344 -1.156668,3.470003 -1.857267,3.847015 -4.875,5.6875 -0.698672,0.436992 -1.397344,0.873984 -2.117188,1.324219 -2.007812,0.988281 -2.007812,0.988281 -5.007812,0.988281 0,0.66 0,1.32 0,2 -0.99,0.33 -1.98,0.66 -3,1 0,-1.32 0,-2.64 0,-4 C 32.359335,40.962601 31.718671,40.925211 31.058593,40.8867 22.287404,40.220037 16.393127,37.373973 9.2226552,32.429668 6.2608222,30.524517 3.2830902,29.257335 -8.4473381e-7,27.999981 c 0,-3.3 0,-6.6 0,-10 C 1.6232682,17.32911 3.2486752,16.663411 4.8749992,15.999981 c 0.904922,-0.37125 1.809844,-0.7425 2.742188,-1.125 2.382812,-0.875 2.382812,-0.875 4.3828118,-0.875 0,-0.66 0,-1.32 0,-2 0.99,0 1.98,0 3,0 0,-0.66 0,-1.32 0,-2.0000002 6.284532,-3.3279791 10.886587,-4.4516452 18,-4 0,-0.99 0,-1.98 0,-3 z"
|
|
||||||
fill="#93a2b8"
|
|
||||||
id="path1"
|
|
||||||
style="fill:#000000" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.6 KiB |
|
|
@ -1,85 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
fill="#000000"
|
|
||||||
height="20.000002"
|
|
||||||
width="20"
|
|
||||||
version="1.1"
|
|
||||||
id="Capa_1"
|
|
||||||
viewBox="0 0 493.42511 493.42516"
|
|
||||||
xml:space="preserve"
|
|
||||||
sodipodi:docname="ubuntu-logo-svgrepo-com.svg"
|
|
||||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
|
|
||||||
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="defs9" /><sodipodi:namedview
|
|
||||||
id="namedview9"
|
|
||||||
pagecolor="#505050"
|
|
||||||
bordercolor="#ffffff"
|
|
||||||
borderopacity="1"
|
|
||||||
inkscape:showpageshadow="0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pagecheckerboard="1"
|
|
||||||
inkscape:deskcolor="#505050"
|
|
||||||
inkscape:zoom="12.374369"
|
|
||||||
inkscape:cx="24.76894"
|
|
||||||
inkscape:cy="15.515943"
|
|
||||||
inkscape:window-width="1415"
|
|
||||||
inkscape:window-height="753"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="Capa_1" />
|
|
||||||
<g
|
|
||||||
id="ubuntu"
|
|
||||||
transform="translate(5.5573583e-4,0.00107926)">
|
|
||||||
<g
|
|
||||||
id="g2">
|
|
||||||
<g
|
|
||||||
id="g1">
|
|
||||||
<path
|
|
||||||
d="m 168.839,241.198 c 0,-38.117 17.894,-72.05 45.685,-93.896 L 171.988,79.22 c -35.648,25.603 -62.472,62.66 -75.127,105.796 19.811,12.751 32.949,35.031 32.949,60.353 0,24.424 -12.143,45.957 -30.783,58.918 13.606,40.86 40.12,75.838 74.706,100.113 l 39.559,-70.358 c -27.105,-21.838 -44.453,-55.318 -44.453,-92.844 z"
|
|
||||||
id="path1" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g3">
|
|
||||||
<path
|
|
||||||
d="m 109.704,245.368 c 0,28.484 -23.132,51.592 -51.609,51.592 -28.491,0 -51.606,-23.107 -51.606,-51.592 0,-28.47 23.115,-51.577 51.606,-51.577 28.477,0 51.609,23.107 51.609,51.577 z"
|
|
||||||
id="path2" />
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g5">
|
|
||||||
<g
|
|
||||||
id="g4">
|
|
||||||
<path
|
|
||||||
d="m 399.494,370.126 c 12.002,0 23.301,2.936 33.23,8.149 30.924,-32.591 50.906,-75.595 54.211,-123.228 l -80.148,-1.551 c -6.171,60.111 -56.954,106.941 -118.677,106.941 -17.084,0 -33.388,-3.594 -48.101,-10.093 l -39.841,69.704 c 26.56,13.069 56.376,20.411 87.941,20.411 13.622,0 26.981,-1.379 39.854,-4.006 2.746,-37.072 33.717,-66.327 71.531,-66.327 z"
|
|
||||||
id="path3" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g6">
|
|
||||||
<path
|
|
||||||
d="m 451.071,441.847 c 0,28.478 -23.084,51.576 -51.577,51.576 -28.493,0 -51.594,-23.098 -51.594,-51.576 0,-28.5 23.101,-51.592 51.594,-51.592 28.493,0 51.577,23.092 51.577,51.592 z"
|
|
||||||
id="path5" />
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g8">
|
|
||||||
<g
|
|
||||||
id="g7">
|
|
||||||
<path
|
|
||||||
d="m 438.211,110.152 c -11.677,8.269 -25.968,13.163 -41.399,13.163 -39.637,0 -71.73,-32.102 -71.73,-71.715 0,-2.104 0.094,-4.139 0.25,-6.181 -12.05,-2.307 -24.503,-3.491 -37.222,-3.491 -31.859,0 -61.988,7.498 -88.689,20.777 l 39.607,69.75 c 14.979,-6.748 31.593,-10.544 49.082,-10.544 61.177,0 111.601,46.074 118.491,105.414 l 80.147,-2.447 C 483.209,181.12 465.487,141.372 438.211,110.152 Z"
|
|
||||||
id="path6" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g9">
|
|
||||||
<path
|
|
||||||
d="m 448.374,51.601 c 0,28.492 -23.038,51.592 -51.561,51.592 -28.491,0 -51.592,-23.1 -51.592,-51.592 C 345.22,23.107 368.321,0 396.812,0 c 28.523,0 51.562,23.107 51.562,51.601 z"
|
|
||||||
id="path8" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.1 KiB |
|
|
@ -1,339 +0,0 @@
|
||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
Version 2, June 1991
|
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The licenses for most software are designed to take away your
|
|
||||||
freedom to share and change it. By contrast, the GNU General Public
|
|
||||||
License is intended to guarantee your freedom to share and change free
|
|
||||||
software--to make sure the software is free for all its users. This
|
|
||||||
General Public License applies to most of the Free Software
|
|
||||||
Foundation's software and to any other program whose authors commit to
|
|
||||||
using it. (Some other Free Software Foundation software is covered by
|
|
||||||
the GNU Lesser General Public License instead.) You can apply it to
|
|
||||||
your programs, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
this service if you wish), that you receive source code or can get it
|
|
||||||
if you want it, that you can change the software or use pieces of it
|
|
||||||
in new free programs; and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
|
||||||
anyone to deny you these rights or to ask you to surrender the rights.
|
|
||||||
These restrictions translate to certain responsibilities for you if you
|
|
||||||
distribute copies of the software, or if you modify it.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must give the recipients all the rights that
|
|
||||||
you have. You must make sure that they, too, receive or can get the
|
|
||||||
source code. And you must show them these terms so they know their
|
|
||||||
rights.
|
|
||||||
|
|
||||||
We protect your rights with two steps: (1) copyright the software, and
|
|
||||||
(2) offer you this license which gives you legal permission to copy,
|
|
||||||
distribute and/or modify the software.
|
|
||||||
|
|
||||||
Also, for each author's protection and ours, we want to make certain
|
|
||||||
that everyone understands that there is no warranty for this free
|
|
||||||
software. If the software is modified by someone else and passed on, we
|
|
||||||
want its recipients to know that what they have is not the original, so
|
|
||||||
that any problems introduced by others will not reflect on the original
|
|
||||||
authors' reputations.
|
|
||||||
|
|
||||||
Finally, any free program is threatened constantly by software
|
|
||||||
patents. We wish to avoid the danger that redistributors of a free
|
|
||||||
program will individually obtain patent licenses, in effect making the
|
|
||||||
program proprietary. To prevent this, we have made it clear that any
|
|
||||||
patent must be licensed for everyone's free use or not licensed at all.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. This License applies to any program or other work which contains
|
|
||||||
a notice placed by the copyright holder saying it may be distributed
|
|
||||||
under the terms of this General Public License. The "Program", below,
|
|
||||||
refers to any such program or work, and a "work based on the Program"
|
|
||||||
means either the Program or any derivative work under copyright law:
|
|
||||||
that is to say, a work containing the Program or a portion of it,
|
|
||||||
either verbatim or with modifications and/or translated into another
|
|
||||||
language. (Hereinafter, translation is included without limitation in
|
|
||||||
the term "modification".) Each licensee is addressed as "you".
|
|
||||||
|
|
||||||
Activities other than copying, distribution and modification are not
|
|
||||||
covered by this License; they are outside its scope. The act of
|
|
||||||
running the Program is not restricted, and the output from the Program
|
|
||||||
is covered only if its contents constitute a work based on the
|
|
||||||
Program (independent of having been made by running the Program).
|
|
||||||
Whether that is true depends on what the Program does.
|
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Program's
|
|
||||||
source code as you receive it, in any medium, provided that you
|
|
||||||
conspicuously and appropriately publish on each copy an appropriate
|
|
||||||
copyright notice and disclaimer of warranty; keep intact all the
|
|
||||||
notices that refer to this License and to the absence of any warranty;
|
|
||||||
and give any other recipients of the Program a copy of this License
|
|
||||||
along with the Program.
|
|
||||||
|
|
||||||
You may charge a fee for the physical act of transferring a copy, and
|
|
||||||
you may at your option offer warranty protection in exchange for a fee.
|
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Program or any portion
|
|
||||||
of it, thus forming a work based on the Program, and copy and
|
|
||||||
distribute such modifications or work under the terms of Section 1
|
|
||||||
above, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) You must cause the modified files to carry prominent notices
|
|
||||||
stating that you changed the files and the date of any change.
|
|
||||||
|
|
||||||
b) You must cause any work that you distribute or publish, that in
|
|
||||||
whole or in part contains or is derived from the Program or any
|
|
||||||
part thereof, to be licensed as a whole at no charge to all third
|
|
||||||
parties under the terms of this License.
|
|
||||||
|
|
||||||
c) If the modified program normally reads commands interactively
|
|
||||||
when run, you must cause it, when started running for such
|
|
||||||
interactive use in the most ordinary way, to print or display an
|
|
||||||
announcement including an appropriate copyright notice and a
|
|
||||||
notice that there is no warranty (or else, saying that you provide
|
|
||||||
a warranty) and that users may redistribute the program under
|
|
||||||
these conditions, and telling the user how to view a copy of this
|
|
||||||
License. (Exception: if the Program itself is interactive but
|
|
||||||
does not normally print such an announcement, your work based on
|
|
||||||
the Program is not required to print an announcement.)
|
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
|
||||||
identifiable sections of that work are not derived from the Program,
|
|
||||||
and can be reasonably considered independent and separate works in
|
|
||||||
themselves, then this License, and its terms, do not apply to those
|
|
||||||
sections when you distribute them as separate works. But when you
|
|
||||||
distribute the same sections as part of a whole which is a work based
|
|
||||||
on the Program, the distribution of the whole must be on the terms of
|
|
||||||
this License, whose permissions for other licensees extend to the
|
|
||||||
entire whole, and thus to each and every part regardless of who wrote it.
|
|
||||||
|
|
||||||
Thus, it is not the intent of this section to claim rights or contest
|
|
||||||
your rights to work written entirely by you; rather, the intent is to
|
|
||||||
exercise the right to control the distribution of derivative or
|
|
||||||
collective works based on the Program.
|
|
||||||
|
|
||||||
In addition, mere aggregation of another work not based on the Program
|
|
||||||
with the Program (or with a work based on the Program) on a volume of
|
|
||||||
a storage or distribution medium does not bring the other work under
|
|
||||||
the scope of this License.
|
|
||||||
|
|
||||||
3. You may copy and distribute the Program (or a work based on it,
|
|
||||||
under Section 2) in object code or executable form under the terms of
|
|
||||||
Sections 1 and 2 above provided that you also do one of the following:
|
|
||||||
|
|
||||||
a) Accompany it with the complete corresponding machine-readable
|
|
||||||
source code, which must be distributed under the terms of Sections
|
|
||||||
1 and 2 above on a medium customarily used for software interchange; or,
|
|
||||||
|
|
||||||
b) Accompany it with a written offer, valid for at least three
|
|
||||||
years, to give any third party, for a charge no more than your
|
|
||||||
cost of physically performing source distribution, a complete
|
|
||||||
machine-readable copy of the corresponding source code, to be
|
|
||||||
distributed under the terms of Sections 1 and 2 above on a medium
|
|
||||||
customarily used for software interchange; or,
|
|
||||||
|
|
||||||
c) Accompany it with the information you received as to the offer
|
|
||||||
to distribute corresponding source code. (This alternative is
|
|
||||||
allowed only for noncommercial distribution and only if you
|
|
||||||
received the program in object code or executable form with such
|
|
||||||
an offer, in accord with Subsection b above.)
|
|
||||||
|
|
||||||
The source code for a work means the preferred form of the work for
|
|
||||||
making modifications to it. For an executable work, complete source
|
|
||||||
code means all the source code for all modules it contains, plus any
|
|
||||||
associated interface definition files, plus the scripts used to
|
|
||||||
control compilation and installation of the executable. However, as a
|
|
||||||
special exception, the source code distributed need not include
|
|
||||||
anything that is normally distributed (in either source or binary
|
|
||||||
form) with the major components (compiler, kernel, and so on) of the
|
|
||||||
operating system on which the executable runs, unless that component
|
|
||||||
itself accompanies the executable.
|
|
||||||
|
|
||||||
If distribution of executable or object code is made by offering
|
|
||||||
access to copy from a designated place, then offering equivalent
|
|
||||||
access to copy the source code from the same place counts as
|
|
||||||
distribution of the source code, even though third parties are not
|
|
||||||
compelled to copy the source along with the object code.
|
|
||||||
|
|
||||||
4. You may not copy, modify, sublicense, or distribute the Program
|
|
||||||
except as expressly provided under this License. Any attempt
|
|
||||||
otherwise to copy, modify, sublicense or distribute the Program is
|
|
||||||
void, and will automatically terminate your rights under this License.
|
|
||||||
However, parties who have received copies, or rights, from you under
|
|
||||||
this License will not have their licenses terminated so long as such
|
|
||||||
parties remain in full compliance.
|
|
||||||
|
|
||||||
5. You are not required to accept this License, since you have not
|
|
||||||
signed it. However, nothing else grants you permission to modify or
|
|
||||||
distribute the Program or its derivative works. These actions are
|
|
||||||
prohibited by law if you do not accept this License. Therefore, by
|
|
||||||
modifying or distributing the Program (or any work based on the
|
|
||||||
Program), you indicate your acceptance of this License to do so, and
|
|
||||||
all its terms and conditions for copying, distributing or modifying
|
|
||||||
the Program or works based on it.
|
|
||||||
|
|
||||||
6. Each time you redistribute the Program (or any work based on the
|
|
||||||
Program), the recipient automatically receives a license from the
|
|
||||||
original licensor to copy, distribute or modify the Program subject to
|
|
||||||
these terms and conditions. You may not impose any further
|
|
||||||
restrictions on the recipients' exercise of the rights granted herein.
|
|
||||||
You are not responsible for enforcing compliance by third parties to
|
|
||||||
this License.
|
|
||||||
|
|
||||||
7. If, as a consequence of a court judgment or allegation of patent
|
|
||||||
infringement or for any other reason (not limited to patent issues),
|
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot
|
|
||||||
distribute so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you
|
|
||||||
may not distribute the Program at all. For example, if a patent
|
|
||||||
license would not permit royalty-free redistribution of the Program by
|
|
||||||
all those who receive copies directly or indirectly through you, then
|
|
||||||
the only way you could satisfy both it and this License would be to
|
|
||||||
refrain entirely from distribution of the Program.
|
|
||||||
|
|
||||||
If any portion of this section is held invalid or unenforceable under
|
|
||||||
any particular circumstance, the balance of the section is intended to
|
|
||||||
apply and the section as a whole is intended to apply in other
|
|
||||||
circumstances.
|
|
||||||
|
|
||||||
It is not the purpose of this section to induce you to infringe any
|
|
||||||
patents or other property right claims or to contest validity of any
|
|
||||||
such claims; this section has the sole purpose of protecting the
|
|
||||||
integrity of the free software distribution system, which is
|
|
||||||
implemented by public license practices. Many people have made
|
|
||||||
generous contributions to the wide range of software distributed
|
|
||||||
through that system in reliance on consistent application of that
|
|
||||||
system; it is up to the author/donor to decide if he or she is willing
|
|
||||||
to distribute software through any other system and a licensee cannot
|
|
||||||
impose that choice.
|
|
||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to
|
|
||||||
be a consequence of the rest of this License.
|
|
||||||
|
|
||||||
8. If the distribution and/or use of the Program is restricted in
|
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
|
||||||
original copyright holder who places the Program under this License
|
|
||||||
may add an explicit geographical distribution limitation excluding
|
|
||||||
those countries, so that distribution is permitted only in or among
|
|
||||||
countries not thus excluded. In such case, this License incorporates
|
|
||||||
the limitation as if written in the body of this License.
|
|
||||||
|
|
||||||
9. The Free Software Foundation may publish revised and/or new versions
|
|
||||||
of the General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Program
|
|
||||||
specifies a version number of this License which applies to it and "any
|
|
||||||
later version", you have the option of following the terms and conditions
|
|
||||||
either of that version or of any later version published by the Free
|
|
||||||
Software Foundation. If the Program does not specify a version number of
|
|
||||||
this License, you may choose any version ever published by the Free Software
|
|
||||||
Foundation.
|
|
||||||
|
|
||||||
10. If you wish to incorporate parts of the Program into other free
|
|
||||||
programs whose distribution conditions are different, write to the author
|
|
||||||
to ask for permission. For software which is copyrighted by the Free
|
|
||||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
|
||||||
make exceptions for this. Our decision will be guided by the two goals
|
|
||||||
of preserving the free status of all derivatives of our free software and
|
|
||||||
of promoting the sharing and reuse of software generally.
|
|
||||||
|
|
||||||
NO WARRANTY
|
|
||||||
|
|
||||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
|
||||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
|
||||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
|
||||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
|
||||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
|
||||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
|
||||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
|
||||||
REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
|
||||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
|
||||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
|
||||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
|
||||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
|
||||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
|
||||||
POSSIBILITY OF SUCH DAMAGES.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
convey the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program is interactive, make it output a short notice like this
|
|
||||||
when it starts in an interactive mode:
|
|
||||||
|
|
||||||
Gnomovision version 69, Copyright (C) year name of author
|
|
||||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, the commands you use may
|
|
||||||
be called something other than `show w' and `show c'; they could even be
|
|
||||||
mouse-clicks or menu items--whatever suits your program.
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or your
|
|
||||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
|
||||||
necessary. Here is a sample; alter the names:
|
|
||||||
|
|
||||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
|
||||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 1 April 1989
|
|
||||||
Ty Coon, President of Vice
|
|
||||||
|
|
||||||
This General Public License does not permit incorporating your program into
|
|
||||||
proprietary programs. If your program is a subroutine library, you may
|
|
||||||
consider it more useful to permit linking proprietary applications with the
|
|
||||||
library. If this is what you want to do, use the GNU Lesser General
|
|
||||||
Public License instead of this License.
|
|
||||||
|
|
@ -1,95 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<style-scheme id="custom-light" _name="Custom" version="1.0">
|
|
||||||
<author>end_4</author>
|
|
||||||
<_description>Catppuccin port but very random</_description>
|
|
||||||
|
|
||||||
<style name="bracket-match" background="#E3E6EB" bold="true"/>
|
|
||||||
<style name="bracket-mismatch" background="#E3E6EB" underline="true"/>
|
|
||||||
<style name="c:preprocessor" foreground="#DF8E1D"/>
|
|
||||||
<style name="css:at-rules" foreground="#8839EF"/>
|
|
||||||
<style name="css:color" foreground="#DF8E1D"/>
|
|
||||||
<style name="css:keyword" foreground="#256BF5"/>
|
|
||||||
<style name="current-line" background="#E3E6EB"/>
|
|
||||||
<style name="cursor" foreground="#DC8A78"/>
|
|
||||||
<style name="def:base-n-integer" foreground="#DF8E1D"/>
|
|
||||||
<style name="def:boolean" foreground="#DF8E1D"/>
|
|
||||||
<style name="def:builtin" foreground="#DF8E1D"/>
|
|
||||||
<style name="def:character" foreground="#DF8E1D"/>
|
|
||||||
<style name="def:comment" foreground="#9DA1B1"/>
|
|
||||||
<style name="def:complex" foreground="#DF8E1D"/>
|
|
||||||
<style name="def:decimal" foreground="#DF8E1D"/>
|
|
||||||
<style name="def:doc-comment" foreground="#9DA1B1"/>
|
|
||||||
<style name="def:doc-comment-element" foreground="#9DA1B1"/>
|
|
||||||
<style name="def:error" foreground="#D53055" background="#EAEDF2"/>
|
|
||||||
<style name="def:floating-point" foreground="#DF8E1D"/>
|
|
||||||
<style name="def:function" foreground="#256BF5"/>
|
|
||||||
<style name="def:identifier" foreground="#000000"/>
|
|
||||||
<style name="def:keyword" foreground="#8839EF"/>
|
|
||||||
<style name="def:note" foreground="#9DA1B1"/>
|
|
||||||
<style name="def:number" foreground="#FE640B"/>
|
|
||||||
<style name="def:operator" foreground="#8839EF"/>
|
|
||||||
<style name="def:preprocessor" foreground="#256BF5"/>
|
|
||||||
<style name="def:reserved" foreground="#8839EF"/>
|
|
||||||
<style name="def:shebang" foreground="#9DA1B1"/>
|
|
||||||
<style name="def:special-char" foreground="#256BF5"/>
|
|
||||||
<style name="def:special-constant" foreground="#DF8E1D"/>
|
|
||||||
<style name="def:statement" foreground="#8839EF"/>
|
|
||||||
<style name="def:string" foreground="#4AA537"/>
|
|
||||||
<style name="def:type" foreground="#256BF5" italic="true"/>
|
|
||||||
<style name="diff:added-line" foreground="#282D32" background="#ACF2BD"/>
|
|
||||||
<style name="diff:changed-line" foreground="#282D32" background="#F1F2C3"/>
|
|
||||||
<style name="diff:location" foreground="#9DA1B1"/>
|
|
||||||
<style name="diff:removed-line" foreground="#282D32" background="#FFEEF0"/>
|
|
||||||
<style name="draw-spaces" foreground="#3b3a32"/>
|
|
||||||
<style name="html:dtd" foreground="#4AA537"/>
|
|
||||||
<style name="html:tag" foreground="#8839EF"/>
|
|
||||||
<style name="js:function" foreground="#256BF5"/>
|
|
||||||
<style name="line-numbers" foreground="#9699AA" background="#EAEDF2"/>
|
|
||||||
<style name="perl:builtin" foreground="#256BF5"/>
|
|
||||||
<style name="perl:include-statement" foreground="#8839EF"/>
|
|
||||||
<style name="perl:special-variable" foreground="#DF8E1D"/>
|
|
||||||
<style name="perl:variable" foreground="#000000"/>
|
|
||||||
<style name="php:string" foreground="#4AA537"/>
|
|
||||||
<style name="python:builtin-constant" foreground="#8839EF"/>
|
|
||||||
<style name="python:builtin-function" foreground="#256BF5"/>
|
|
||||||
<style name="python:module-handler" foreground="#8839EF"/>
|
|
||||||
<style name="python:special-variable" foreground="#8839EF"/>
|
|
||||||
<style name="ruby:attribute-definition" foreground="#8839EF"/>
|
|
||||||
<style name="ruby:builtin" foreground="#000000"/>
|
|
||||||
<style name="ruby:class-variable" foreground="#000000"/>
|
|
||||||
<style name="ruby:constant" foreground="#000000"/>
|
|
||||||
<style name="ruby:global-variable" foreground="#256BF5"/>
|
|
||||||
<style name="ruby:instance-variable" foreground="#000000"/>
|
|
||||||
<style name="ruby:module-handler" foreground="#8839EF"/>
|
|
||||||
<style name="ruby:predefined-variable" foreground="#DF8E1D"/>
|
|
||||||
<style name="ruby:regex" foreground="#f6aa11"/>
|
|
||||||
<style name="ruby:special-variable" foreground="#8839EF"/>
|
|
||||||
<style name="ruby:symbol" foreground="#DF8E1D"/>
|
|
||||||
<style name="rubyonrails:attribute-definition" foreground="#8839EF"/>
|
|
||||||
<style name="rubyonrails:block-parameter" foreground="#fd971f" italic="true"/>
|
|
||||||
<style name="rubyonrails:builtin" foreground="#000000"/>
|
|
||||||
<style name="rubyonrails:class-inherit" foreground="#256BF5" underline="true" italic="true"/>
|
|
||||||
<style name="rubyonrails:class-name" foreground="#256BF5"/>
|
|
||||||
<style name="rubyonrails:class-variable" foreground="#000000"/>
|
|
||||||
<style name="rubyonrails:complex-interpolation" foreground="#DF8E1D"/>
|
|
||||||
<style name="rubyonrails:constant" foreground="#000000"/>
|
|
||||||
<style name="rubyonrails:global-variable" foreground="#256BF5"/>
|
|
||||||
<style name="rubyonrails:instance-variable" foreground="#000000"/>
|
|
||||||
<style name="rubyonrails:module-handler" foreground="#8839EF"/>
|
|
||||||
<style name="rubyonrails:module-name" foreground="#256BF5"/>
|
|
||||||
<style name="rubyonrails:predefined-variable" foreground="#DF8E1D"/>
|
|
||||||
<style name="rubyonrails:rails" foreground="#000000"/>
|
|
||||||
<style name="rubyonrails:regex" foreground="#f6aa11"/>
|
|
||||||
<style name="rubyonrails:simple-interpolation" foreground="#DF8E1D"/>
|
|
||||||
<style name="rubyonrails:special-variable" foreground="#8839EF"/>
|
|
||||||
<style name="rubyonrails:symbol" foreground="#DF8E1D"/>
|
|
||||||
<style name="search-match" background="#E3E6EB" bold="true" underline="true"/>
|
|
||||||
<style name="selection" foreground="#f8f8f2" background="#444444"/>
|
|
||||||
<style name="text" foreground="#f8f8f2" background="#222222"/>
|
|
||||||
<style name="xml:attribute-name" foreground="#256BF5"/>
|
|
||||||
<style name="xml:element-name" foreground="#8839EF"/>
|
|
||||||
<style name="xml:entity" foreground="#c8cecc"/>
|
|
||||||
<style name="xml:namespace" foreground="#8839EF"/>
|
|
||||||
<style name="xml:tag" foreground="#8839EF"/>
|
|
||||||
|
|
||||||
</style-scheme>
|
|
||||||
|
|
@ -1,121 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!--
|
|
||||||
Copyright (C) 2014 Leo Iannacone <info@leoiannacone.com>
|
|
||||||
|
|
||||||
This file was generated from a textmate theme named Monokai Extended
|
|
||||||
with tm2gtksw2 tool. (Alexandre da Silva)
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the
|
|
||||||
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
||||||
Boston, MA 02111-1307, USA.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- MODIFIED -->
|
|
||||||
|
|
||||||
<style-scheme id="custom" _name="Custom" version="1.0">
|
|
||||||
<author>Leo Iannacone</author>
|
|
||||||
<_description>Based on SublimeText Monokai Extended - Generated with tm2gtksw2</_description>
|
|
||||||
|
|
||||||
<style name="bracket-match" background="#333333" bold="true"/>
|
|
||||||
<style name="bracket-mismatch" background="#333333" underline="true"/>
|
|
||||||
<style name="c:preprocessor" foreground="#be84ff"/>
|
|
||||||
<style name="css:at-rules" foreground="#f92672"/>
|
|
||||||
<style name="css:color" foreground="#be84ff"/>
|
|
||||||
<style name="css:keyword" foreground="#66d9ef"/>
|
|
||||||
<style name="current-line" background="#333333"/>
|
|
||||||
<style name="cursor" foreground="#f8f8f0"/>
|
|
||||||
<style name="def:base-n-integer" foreground="#be84ff"/>
|
|
||||||
<style name="def:boolean" foreground="#be84ff"/>
|
|
||||||
<style name="def:builtin" foreground="#be84ff"/>
|
|
||||||
<style name="def:character" foreground="#be84ff"/>
|
|
||||||
<style name="def:comment" foreground="#75715e"/>
|
|
||||||
<style name="def:complex" foreground="#be84ff"/>
|
|
||||||
<style name="def:decimal" foreground="#be84ff"/>
|
|
||||||
<style name="def:doc-comment" foreground="#75715e"/>
|
|
||||||
<style name="def:doc-comment-element" foreground="#75715e"/>
|
|
||||||
<style name="def:error" foreground="#f8f8f0" background="#f92672"/>
|
|
||||||
<style name="def:floating-point" foreground="#be84ff"/>
|
|
||||||
<style name="def:function" foreground="#a6e22e"/>
|
|
||||||
<style name="def:identifier" foreground="#ffffff"/>
|
|
||||||
<style name="def:keyword" foreground="#f92672"/>
|
|
||||||
<style name="def:note" foreground="#75715e"/>
|
|
||||||
<style name="def:number" foreground="#be84ff"/>
|
|
||||||
<style name="def:operator" foreground="#f92672"/>
|
|
||||||
<style name="def:preprocessor" foreground="#66d9ef"/>
|
|
||||||
<style name="def:reserved" foreground="#f92672"/>
|
|
||||||
<style name="def:shebang" foreground="#75715e"/>
|
|
||||||
<style name="def:special-char" foreground="#66d9ef"/>
|
|
||||||
<style name="def:special-constant" foreground="#be84ff"/>
|
|
||||||
<style name="def:statement" foreground="#f92672"/>
|
|
||||||
<style name="def:string" foreground="#e6db74"/>
|
|
||||||
<style name="def:type" foreground="#66d9ef" italic="true"/>
|
|
||||||
<style name="diff:added-line" foreground="#a6e22e"/>
|
|
||||||
<style name="diff:changed-line" foreground="#e6db74"/>
|
|
||||||
<style name="diff:location" foreground="#75715e"/>
|
|
||||||
<style name="diff:removed-line" foreground="#f92672"/>
|
|
||||||
<style name="draw-spaces" foreground="#3b3a32"/>
|
|
||||||
<style name="html:dtd" foreground="#e6db74"/>
|
|
||||||
<style name="html:tag" foreground="#f92672"/>
|
|
||||||
<style name="js:function" foreground="#66d9ef"/>
|
|
||||||
<style name="line-numbers" foreground="#bebeba" background="#333333"/>
|
|
||||||
<style name="perl:builtin" foreground="#a6e22e"/>
|
|
||||||
<style name="perl:include-statement" foreground="#f92672"/>
|
|
||||||
<style name="perl:special-variable" foreground="#be84ff"/>
|
|
||||||
<style name="perl:variable" foreground="#ffffff"/>
|
|
||||||
<style name="php:string" foreground="#e6db74"/>
|
|
||||||
<style name="python:builtin-constant" foreground="#f92672"/>
|
|
||||||
<style name="python:builtin-function" foreground="#a6e22e"/>
|
|
||||||
<style name="python:module-handler" foreground="#f92672"/>
|
|
||||||
<style name="python:special-variable" foreground="#f92672"/>
|
|
||||||
<style name="ruby:attribute-definition" foreground="#f92672"/>
|
|
||||||
<style name="ruby:builtin" foreground="#ffffff"/>
|
|
||||||
<style name="ruby:class-variable" foreground="#ffffff"/>
|
|
||||||
<style name="ruby:constant" foreground="#ffffff"/>
|
|
||||||
<style name="ruby:global-variable" foreground="#a6e22e"/>
|
|
||||||
<style name="ruby:instance-variable" foreground="#ffffff"/>
|
|
||||||
<style name="ruby:module-handler" foreground="#f92672"/>
|
|
||||||
<style name="ruby:predefined-variable" foreground="#be84ff"/>
|
|
||||||
<style name="ruby:regex" foreground="#f6aa11"/>
|
|
||||||
<style name="ruby:special-variable" foreground="#f92672"/>
|
|
||||||
<style name="ruby:symbol" foreground="#be84ff"/>
|
|
||||||
<style name="rubyonrails:attribute-definition" foreground="#f92672"/>
|
|
||||||
<style name="rubyonrails:block-parameter" foreground="#fd971f" italic="true"/>
|
|
||||||
<style name="rubyonrails:builtin" foreground="#ffffff"/>
|
|
||||||
<style name="rubyonrails:class-inherit" foreground="#a6e22e" underline="true" italic="true"/>
|
|
||||||
<style name="rubyonrails:class-name" foreground="#66d9ef"/>
|
|
||||||
<style name="rubyonrails:class-variable" foreground="#ffffff"/>
|
|
||||||
<style name="rubyonrails:complex-interpolation" foreground="#be84ff"/>
|
|
||||||
<style name="rubyonrails:constant" foreground="#ffffff"/>
|
|
||||||
<style name="rubyonrails:global-variable" foreground="#a6e22e"/>
|
|
||||||
<style name="rubyonrails:instance-variable" foreground="#ffffff"/>
|
|
||||||
<style name="rubyonrails:module-handler" foreground="#f92672"/>
|
|
||||||
<style name="rubyonrails:module-name" foreground="#66d9ef"/>
|
|
||||||
<style name="rubyonrails:predefined-variable" foreground="#be84ff"/>
|
|
||||||
<style name="rubyonrails:rails" foreground="#ffffff"/>
|
|
||||||
<style name="rubyonrails:regex" foreground="#f6aa11"/>
|
|
||||||
<style name="rubyonrails:simple-interpolation" foreground="#be84ff"/>
|
|
||||||
<style name="rubyonrails:special-variable" foreground="#f92672"/>
|
|
||||||
<style name="rubyonrails:symbol" foreground="#be84ff"/>
|
|
||||||
<style name="search-match" background="#333333" bold="true" underline="true"/>
|
|
||||||
<style name="selection" foreground="#f8f8f2" background="#444444"/>
|
|
||||||
<style name="text" foreground="#f8f8f2" background="#222222"/>
|
|
||||||
<style name="xml:attribute-name" foreground="#a6e22e"/>
|
|
||||||
<style name="xml:element-name" foreground="#f92672"/>
|
|
||||||
<style name="xml:entity" foreground="#c8cecc"/>
|
|
||||||
<style name="xml:namespace" foreground="#f92672"/>
|
|
||||||
<style name="xml:tag" foreground="#f92672"/>
|
|
||||||
|
|
||||||
|
|
||||||
</style-scheme>
|
|
||||||
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
"use strict";
|
|
||||||
// Import
|
|
||||||
import Gdk from 'gi://Gdk';
|
|
||||||
import GLib from 'gi://GLib';
|
|
||||||
import App from 'resource:///com/github/Aylur/ags/app.js'
|
|
||||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
|
|
||||||
// Stuff
|
|
||||||
import userOptions from './modules/.configuration/user_options.js';
|
|
||||||
import { firstRunWelcome, startBatteryWarningService } from './services/messages.js';
|
|
||||||
import { startAutoDarkModeService } from './services/darkmode.js';
|
|
||||||
// Widgets
|
|
||||||
import { Bar, BarCornerTopleft, BarCornerTopright } from './modules/bar/main.js';
|
|
||||||
import Cheatsheet from './modules/cheatsheet/main.js';
|
|
||||||
// import DesktopBackground from './modules/desktopbackground/main.js';
|
|
||||||
import Dock from './modules/dock/main.js';
|
|
||||||
import Corner from './modules/screencorners/main.js';
|
|
||||||
import Crosshair from './modules/crosshair/main.js';
|
|
||||||
import Indicator from './modules/indicators/main.js';
|
|
||||||
import Osk from './modules/onscreenkeyboard/main.js';
|
|
||||||
import Overview from './modules/overview/main.js';
|
|
||||||
import Session from './modules/session/main.js';
|
|
||||||
import SideLeft from './modules/sideleft/main.js';
|
|
||||||
import SideRight from './modules/sideright/main.js';
|
|
||||||
import { COMPILED_STYLE_DIR } from './init.js';
|
|
||||||
|
|
||||||
const range = (length, start = 1) => Array.from({ length }, (_, i) => i + start);
|
|
||||||
function forMonitors(widget) {
|
|
||||||
const n = Gdk.Display.get_default()?.get_n_monitors() || 1;
|
|
||||||
return range(n, 0).map(widget).flat(1);
|
|
||||||
}
|
|
||||||
function forMonitorsAsync(widget) {
|
|
||||||
const n = Gdk.Display.get_default()?.get_n_monitors() || 1;
|
|
||||||
return range(n, 0).forEach((n) => widget(n).catch(print))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start stuff
|
|
||||||
handleStyles(true);
|
|
||||||
startAutoDarkModeService().catch(print);
|
|
||||||
firstRunWelcome().catch(print);
|
|
||||||
startBatteryWarningService().catch(print)
|
|
||||||
|
|
||||||
const Windows = () => [
|
|
||||||
// forMonitors(DesktopBackground),
|
|
||||||
forMonitors(Crosshair),
|
|
||||||
Overview(),
|
|
||||||
forMonitors(Indicator),
|
|
||||||
forMonitors(Cheatsheet),
|
|
||||||
SideLeft(),
|
|
||||||
SideRight(),
|
|
||||||
forMonitors(Osk),
|
|
||||||
forMonitors(Session),
|
|
||||||
...(userOptions.dock.enabled ? [forMonitors(Dock)] : []),
|
|
||||||
...(userOptions.appearance.fakeScreenRounding !== 0 ? [
|
|
||||||
forMonitors((id) => Corner(id, 'top left', true)),
|
|
||||||
forMonitors((id) => Corner(id, 'top right', true)),
|
|
||||||
forMonitors((id) => Corner(id, 'bottom left', true)),
|
|
||||||
forMonitors((id) => Corner(id, 'bottom right', true)),
|
|
||||||
] : []),
|
|
||||||
...(userOptions.appearance.barRoundCorners ? [
|
|
||||||
forMonitors(BarCornerTopleft),
|
|
||||||
forMonitors(BarCornerTopright),
|
|
||||||
] : []),
|
|
||||||
];
|
|
||||||
|
|
||||||
const CLOSE_ANIM_TIME = 210; // Longer than actual anim time to make sure widgets animate fully
|
|
||||||
const closeWindowDelays = {}; // For animations
|
|
||||||
for (let i = 0; i < (Gdk.Display.get_default()?.get_n_monitors() || 1); i++) {
|
|
||||||
closeWindowDelays[`osk${i}`] = CLOSE_ANIM_TIME;
|
|
||||||
}
|
|
||||||
|
|
||||||
App.config({
|
|
||||||
css: `${COMPILED_STYLE_DIR}/style.css`,
|
|
||||||
stackTraceOnError: true,
|
|
||||||
closeWindowDelay: closeWindowDelays,
|
|
||||||
windows: Windows().flat(1),
|
|
||||||
});
|
|
||||||
|
|
||||||
// Stuff that don't need to be toggled. And they're async so ugh...
|
|
||||||
forMonitorsAsync(Bar);
|
|
||||||
// Bar().catch(print); // Use this to debug the bar. Single monitor only.
|
|
||||||
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
// Want only the overview from my config? this is what you're looking for!
|
|
||||||
// Remember to install: `dart-sass`, `ags`, `material-symbols`, and `xorg-xrandr`
|
|
||||||
// To launch this, run the following
|
|
||||||
// ags -c ~/.config/ags/config_overviewOnly.js
|
|
||||||
// To toggle the overview, run:
|
|
||||||
// ags -t overview
|
|
||||||
// You might wanna add that as a keybind (in hyprland.conf)
|
|
||||||
// bind = Super, Tab, exec, ags -t overview
|
|
||||||
|
|
||||||
// Import
|
|
||||||
import App from 'resource:///com/github/Aylur/ags/app.js'
|
|
||||||
// Widgets
|
|
||||||
import Overview from './modules/overview/main.js';
|
|
||||||
import { COMPILED_STYLE_DIR } from './init.js';
|
|
||||||
|
|
||||||
handleStyles(true);
|
|
||||||
|
|
||||||
App.config({
|
|
||||||
css: `${COMPILED_STYLE_DIR}/style.css`,
|
|
||||||
stackTraceOnError: true,
|
|
||||||
windows: [
|
|
||||||
Overview(),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
const Gio = imports.gi.Gio;
|
|
||||||
const GLib = imports.gi.GLib;
|
|
||||||
import configOptions from "../modules/.configuration/user_options.js";
|
|
||||||
const { langCode, Extra_logs } = configOptions.i18n
|
|
||||||
const translations = {};
|
|
||||||
|
|
||||||
let currentLanguage = langCode || getLanguageCode();
|
|
||||||
|
|
||||||
function getLanguageCode() {
|
|
||||||
let langEnv = GLib.getenv('LANG') || GLib.getenv('LANGUAGE') || 'Default.';
|
|
||||||
let langCode = langEnv.split('.')[0];
|
|
||||||
return langCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load language file
|
|
||||||
function loadLanguage(lang) {
|
|
||||||
if (!translations[lang]) {
|
|
||||||
try {
|
|
||||||
let filePath = `~/.config/ags/i18n/locales/${lang}.json`;
|
|
||||||
filePath = filePath.replace(/^~/, GLib.get_home_dir());
|
|
||||||
let file = Gio.File.new_for_path(filePath);
|
|
||||||
let [success, contents] = file.load_contents(null);
|
|
||||||
if (success) {
|
|
||||||
let decoder = new TextDecoder('utf-8');
|
|
||||||
let jsonString = decoder.decode(contents);
|
|
||||||
translations[lang] = JSON.parse(jsonString);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
if (Extra_logs || lang === "Default")
|
|
||||||
console.warn(`Failed to load language file, language code: ${lang}:\n`, error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
currentLanguage = currentLanguage || lang;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize default language
|
|
||||||
function init() {
|
|
||||||
try {
|
|
||||||
loadLanguage(currentLanguage);
|
|
||||||
if (Extra_logs)
|
|
||||||
console.log(getString("Initialization complete!") || "Initialization complete!");
|
|
||||||
loadLanguage("Default");
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Failed to initialize default language:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get translation, if no corresponding value, return the key
|
|
||||||
function getString(key) {
|
|
||||||
if (key && !translations[currentLanguage]?.[key] && Extra_logs)
|
|
||||||
console.warn(`${translations[currentLanguage]["Not found"] || "Not found"}:::${key}`);
|
|
||||||
return translations[currentLanguage]?.[key] || translations['Default']?.[key] || key;
|
|
||||||
}
|
|
||||||
export { getString, init };
|
|
||||||
|
|
@ -1,241 +0,0 @@
|
||||||
{
|
|
||||||
"No media": "No media",
|
|
||||||
"Powered by Google": "Powered by Google",
|
|
||||||
"Uses gemini-pro.\nNot affiliated, endorsed, or sponsored by Google.\n\nPrivacy: Chat messages aren't linked to your account,\n but will be read by human reviewers to improve the model.": "Uses gemini-pro.\nNot affiliated, endorsed, or sponsored by Google.\n\nPrivacy: Chat messages aren't linked to your account,\n but will be read by human reviewers to improve the model.",
|
|
||||||
"Precise": "Precise",
|
|
||||||
"Balanced": "Balanced",
|
|
||||||
"Creative": "Creative",
|
|
||||||
"Gemini's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "Gemini's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1",
|
|
||||||
"Enhancements": "Enhancements",
|
|
||||||
"Tells Gemini:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "Tells Gemini:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points",
|
|
||||||
"Safety": "Safety",
|
|
||||||
"When turned off, tells the API (not the model) \nto not block harmful/explicit content": "When turned off, tells the API (not the model) \nto not block harmful/explicit content",
|
|
||||||
"History": "History",
|
|
||||||
"Saves chat history\nMessages in previous chats won't show automatically, but they are there": "Saves chat history\nMessages in previous chats won't show automatically, but they are there",
|
|
||||||
"Key stored in:": "Key stored in:",
|
|
||||||
"To update this key, type": "To update this key, type",
|
|
||||||
"Updated API Key at": "Updated API Key at",
|
|
||||||
"Currently using": "Currently using",
|
|
||||||
"Select ChatGPT-compatible API provider": "Select ChatGPT-compatible API provider",
|
|
||||||
"Official OpenAI API.\nPricing: Free for the first $5 or 3 months, whichever is less.": "Official OpenAI API.\nPricing: Free for the first $5 or 3 months, whichever is less.",
|
|
||||||
"Official Ollama API.\nPricing: Free.": "Official Ollama API.\nPricing: Free.",
|
|
||||||
"A unified interface for LLMs": "A unified interface for LLMs",
|
|
||||||
"An API from Tornado Softwares\nPricing: Free: 100/day\nRequires you to join their Discord for a key": "An API from Tornado Softwares\nPricing: Free: 100/day\nRequires you to join their Discord for a key",
|
|
||||||
"An API from @zukixa on GitHub.\nNote: Keys are IP-locked so it's buggy sometimes\nPricing: Free: 10/min, 800/day.\nRequires you to join their Discord for a key": "An API from @zukixa on GitHub.\nNote: Keys are IP-locked so it's buggy sometimes\nPricing: Free: 10/min, 800/day.\nRequires you to join their Discord for a key",
|
|
||||||
"Provider shown above": "Provider shown above",
|
|
||||||
"Uses gpt-3.5-turbo.\nNot affiliated, endorsed, or sponsored by OpenAI.\n\nPrivacy: OpenAI claims they do not use your data\nwhen you use their API. Idk about others.": "Uses gpt-3.5-turbo.\nNot affiliated, endorsed, or sponsored by OpenAI.\n\nPrivacy: OpenAI claims they do not use your data\nwhen you use their API. Idk about others.",
|
|
||||||
"The model's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "The model's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1",
|
|
||||||
"An API key is required\nYou can grab one <u>here</u>, then enter it below": "An API key is required\nYou can grab one <u>here</u>, then enter it below",
|
|
||||||
"Tells the model:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "Tells the model:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points",
|
|
||||||
"Powered by waifu.im + other APIs": "Powered by waifu.im + other APIs",
|
|
||||||
"Type tags for a random pic.\nNSFW content will not be returned unless\nyou explicitly request such a tag.\n\nDisclaimer: Not affiliated with the providers\nnor responsible for any of their content.": "Type tags for a random pic.\nNSFW content will not be returned unless\nyou explicitly request such a tag.\n\nDisclaimer: Not affiliated with the providers\nnor responsible for any of their content.",
|
|
||||||
"Tags →": "Tags →",
|
|
||||||
"Invalid command.": "Invalid command.",
|
|
||||||
"Anime booru": "Anime booru",
|
|
||||||
"Powered by yande.re and konachan": "Powered by yande.re and konachan",
|
|
||||||
"An image booru. May contain NSFW content.\nWatch your back.\n\nDisclaimer: Not affiliated with the provider\nnor responsible for any of its content.": "An image booru. May contain NSFW content.\nWatch your back.\n\nDisclaimer: Not affiliated with the provider\nnor responsible for any of its content.",
|
|
||||||
"Lewds": "Lewds",
|
|
||||||
"Shows naughty stuff when enabled.\nYa like those? Add this to user_options.js:\n\t'sidebar': {\n\t'image': {\n\t\t'allowNsfw': true,\n\t}\n}": "Shows naughty stuff when enabled.\nYa like those? Add this to user_options.js:\n\t'sidebar': {\n\t'image': {\n\t\t'allowNsfw': true,\n\t}\n}",
|
|
||||||
"Save in folder by tags": "Save in folder by tags",
|
|
||||||
"Saves images in folders by their tags": "Saves images in folders by their tags",
|
|
||||||
"Message Gemini...": "Message Gemini...",
|
|
||||||
"Enter Google AI API Key...": "Enter Google AI API Key...",
|
|
||||||
"Message the model...": "Message the model...",
|
|
||||||
"Enter API Key...": "Enter API Key...",
|
|
||||||
"Enter tags": "Enter tags",
|
|
||||||
"Quick scripts": "Quick scripts",
|
|
||||||
"Change screen resolution": "Change screen resolution",
|
|
||||||
"Update packages": "Update packages",
|
|
||||||
"Trim system generations to 5": "Trim system generations to 5",
|
|
||||||
"Trim home manager generations to 5": "Trim home manager generations to 5",
|
|
||||||
"Remove orphan packages": "Remove orphan packages",
|
|
||||||
"Uninstall unused flatpak packages": "Uninstall unused flatpak packages",
|
|
||||||
"<span strikethrough=\"true\">Inaccurate</span> Color picker": "<span strikethrough=\"true\">Inaccurate</span> Color picker",
|
|
||||||
"Result": "Result",
|
|
||||||
"Type to search": "Type to search",
|
|
||||||
"illogical-impulse": "illogical-impulse",
|
|
||||||
"RAM Usage": "RAM Usage",
|
|
||||||
"Swap Usage": "Swap Usage",
|
|
||||||
"CPU Usage": "CPU Usage",
|
|
||||||
"Uptime:": "Uptime:",
|
|
||||||
"Screen snip": "Screen snip",
|
|
||||||
"Color picker": "Color picker",
|
|
||||||
"Toggle on-screen keyboard": "Toggle on-screen keyboard",
|
|
||||||
"Night Light": "Night Light",
|
|
||||||
"Color inversion": "Color inversion",
|
|
||||||
"Keep system awake": "Keep system awake",
|
|
||||||
"Cloudflare WARP": "Cloudflare WARP",
|
|
||||||
"Session": "Session",
|
|
||||||
"Bluetooth | Right-click to configure": "Bluetooth | Right-click to configure",
|
|
||||||
"Wifi | Right-click to configure": "Wifi | Right-click to configure",
|
|
||||||
"Right-click to configure": "Right-click to configure",
|
|
||||||
"Unknown": "Unknown",
|
|
||||||
"Reload Environment config": "Reload Environment config",
|
|
||||||
"Open Settings": "Open Settings",
|
|
||||||
"Notifications": "Notifications",
|
|
||||||
"Audio controls": "Audio controls",
|
|
||||||
"Bluetooth": "Bluetooth",
|
|
||||||
"Wifi networks": "Wifi networks",
|
|
||||||
"Live config": "Live config",
|
|
||||||
"Silence": "Silence",
|
|
||||||
"Clear": "Clear",
|
|
||||||
"No notifications": "No notifications",
|
|
||||||
"notifications": "notifications",
|
|
||||||
"Close": "Close",
|
|
||||||
"Now": "Now",
|
|
||||||
"Yesterday": "Yesterday",
|
|
||||||
"No audio source": "No audio source",
|
|
||||||
"Remove device": "Remove device",
|
|
||||||
"Connected": "Connected",
|
|
||||||
"Paired": "Paired",
|
|
||||||
"More": "More",
|
|
||||||
"Selected": "Selected",
|
|
||||||
"Current network": "Current network",
|
|
||||||
"Authentication": "Authentication",
|
|
||||||
"Effects": "Effects",
|
|
||||||
"Transparency": "Transparency",
|
|
||||||
"[AGS]\nMake shell elements transparent\nBlur is also recommended if you enable this": "[AGS]\nMake shell elements transparent\nBlur is also recommended if you enable this",
|
|
||||||
"Blur": "Blur",
|
|
||||||
"[Hyprland]\nEnable blur on transparent elements\nDoesn't affect performance/power consumption unless you have transparent windows.": "[Hyprland]\nEnable blur on transparent elements\nDoesn't affect performance/power consumption unless you have transparent windows.",
|
|
||||||
"X-ray": "X-ray",
|
|
||||||
"[Hyprland]\nMake everything behind a window/layer except the wallpaper not rendered on its blurred surface\nRecommended to improve performance (if you don't abuse transparency/blur) ": "[Hyprland]\nMake everything behind a window/layer except the wallpaper not rendered on its blurred surface\nRecommended to improve performance (if you don't abuse transparency/blur) ",
|
|
||||||
"Size": "Size",
|
|
||||||
"[Hyprland]\nAdjust the blur radius. Generally doesn't affect performance\nHigher = more color spread": "[Hyprland]\nAdjust the blur radius. Generally doesn't affect performance\nHigher = more color spread",
|
|
||||||
"Passes": "Passes",
|
|
||||||
"[Hyprland] Adjust the number of runs of the blur algorithm\nMore passes = more spread and power consumption\n4 is recommended\n2- would look weird and 6+ would look lame.": "[Hyprland] Adjust the number of runs of the blur algorithm\nMore passes = more spread and power consumption\n4 is recommended\n2- would look weird and 6+ would look lame.",
|
|
||||||
"Animations": "Animations",
|
|
||||||
"[Hyprland] [GTK]\nEnable animations": "[Hyprland] [GTK]\nEnable animations",
|
|
||||||
"Choreography delay": "Choreography delay",
|
|
||||||
"In milliseconds, the delay between animations of a series": "In milliseconds, the delay between animations of a series",
|
|
||||||
"Developer": "Developer",
|
|
||||||
"Show FPS": "Show FPS",
|
|
||||||
"[Hyprland]\nShow FPS overlay on top-left corner": "[Hyprland]\nShow FPS overlay on top-left corner",
|
|
||||||
"Log to stdout": "Log to stdout",
|
|
||||||
"[Hyprland]\nPrint LOG, ERR, WARN, etc. messages to the console": "[Hyprland]\nPrint LOG, ERR, WARN, etc. messages to the console",
|
|
||||||
"Damage tracking": "Damage tracking",
|
|
||||||
"[Hyprland]\nEnable damage tracking\nGenerally, leave it on.\nTurn off only when a shader doesn't work": "[Hyprland]\nEnable damage tracking\nGenerally, leave it on.\nTurn off only when a shader doesn't work",
|
|
||||||
"Damage blink": "Damage blink",
|
|
||||||
"[Hyprland] [Epilepsy warning!]\nShow screen damage flashes": "[Hyprland] [Epilepsy warning!]\nShow screen damage flashes",
|
|
||||||
"Not all changes are saved": "Not all changes are saved",
|
|
||||||
"Mo": "Mo",
|
|
||||||
"Tu": "Tu",
|
|
||||||
"We": "We",
|
|
||||||
"Th": "Th",
|
|
||||||
"Fr": "Fr",
|
|
||||||
"Sa": "Sa",
|
|
||||||
"Su": "Su",
|
|
||||||
"Calendar": "Calendar",
|
|
||||||
"To Do": "To Do",
|
|
||||||
"Unfinished": "Unfinished",
|
|
||||||
"Done": "Done",
|
|
||||||
"Finished tasks will go here": "Finished tasks will go here",
|
|
||||||
"Nothing here!": "Nothing here!",
|
|
||||||
"+ New task": "+ New task",
|
|
||||||
"Add a task...": "Add a task...",
|
|
||||||
"Color scheme": "Color scheme",
|
|
||||||
"Options": "Options",
|
|
||||||
"Dark Mode": "Dark Mode",
|
|
||||||
"Ya should go to sleep!": "Ya should go to sleep!",
|
|
||||||
"Use Gradience": "Use Gradience",
|
|
||||||
"Theme GTK apps using accent color\n(drawback: dark/light mode switching requires restart)": "Theme GTK apps using accent color\n(drawback: dark/light mode switching requires restart)",
|
|
||||||
"Scheme styles": "Scheme styles",
|
|
||||||
"Vibrant": "Vibrant",
|
|
||||||
"Vibrant+": "Vibrant+",
|
|
||||||
"Expressive": "Expressive",
|
|
||||||
"Monochrome": "Monochrome",
|
|
||||||
"Rainbow": "Rainbow",
|
|
||||||
"Fidelity": "Fidelity",
|
|
||||||
"Fruit Salad": "Fruit Salad",
|
|
||||||
"Tonal Spot": "Tonal Spot",
|
|
||||||
"Content": "Content",
|
|
||||||
"Use arrow keys to navigate.\nEnter to select, Esc to cancel.": "Use arrow keys to navigate.\nEnter to select, Esc to cancel.",
|
|
||||||
"Lock": "Lock",
|
|
||||||
"Logout": "Logout",
|
|
||||||
"Sleep": "Sleep",
|
|
||||||
"Hibernate": "Hibernate",
|
|
||||||
"Shutdown": "Shutdown",
|
|
||||||
"Reboot": "Reboot",
|
|
||||||
"Cancel": "Cancel",
|
|
||||||
"Cheat sheet": "Cheat sheet",
|
|
||||||
"Keybinds": "Keybinds",
|
|
||||||
"Periodic table": "Periodic table",
|
|
||||||
"Essentials for beginners": "Essentials for beginners",
|
|
||||||
"Make shell elements transparent": "Make shell elements transparent",
|
|
||||||
"Actions": "Actions",
|
|
||||||
"Window management": "Window management",
|
|
||||||
"Window arrangement": "Window arrangement",
|
|
||||||
"Workspace management": "Workspace management",
|
|
||||||
"Workspace navigation": "Workspace navigation",
|
|
||||||
"Widgets": "Widgets",
|
|
||||||
"Media": "Media",
|
|
||||||
"Apps": "Apps",
|
|
||||||
"Neutral": "Neutral",
|
|
||||||
"Launch foot (terminal)": "Launch foot (terminal)",
|
|
||||||
"Open app launcher": "Open app launcher",
|
|
||||||
"Change wallpaper": "Change wallpaper",
|
|
||||||
"Clipboard history >> clipboard": "Clipboard history >> clipboard",
|
|
||||||
"Pick emoji >> clipboard": "Pick emoji >> clipboard",
|
|
||||||
"Screen snip >> edit": "Screen snip >> edit",
|
|
||||||
"Screen snip to text >> clipboard": "Screen snip to text >> clipboard",
|
|
||||||
"Pick color (Hex) >> clipboard": "Pick color (Hex) >> clipboard",
|
|
||||||
"Screenshot >> clipboard": "Screenshot >> clipboard",
|
|
||||||
"Screenshot >> clipboard & file": "Screenshot >> clipboard & file",
|
|
||||||
"Record region (no sound)": "Record region (no sound)",
|
|
||||||
"Record screen (with sound)": "Record screen (with sound)",
|
|
||||||
"Suspend system": "Suspend system",
|
|
||||||
"Move focus in direction": "Move focus in direction",
|
|
||||||
"Move window": "Move window",
|
|
||||||
"Resize window": "Resize window",
|
|
||||||
"Close window": "Close window",
|
|
||||||
"Pick and kill a window": "Pick and kill a window",
|
|
||||||
"Window: move in direction": "Window: move in direction",
|
|
||||||
"Window: split ratio +/- 0.1": "Window: split ratio +/- 0.1",
|
|
||||||
"Float/unfloat window": "Float/unfloat window",
|
|
||||||
"Toggle fake fullscreen": "Toggle fake fullscreen",
|
|
||||||
"Toggle fullscreen": "Toggle fullscreen",
|
|
||||||
"Toggle maximization": "Toggle maximization",
|
|
||||||
"Focus workspace # (1, 2, 3, 4, ...)": "Focus workspace # (1, 2, 3, 4, ...)",
|
|
||||||
"Workspace: focus left/right": "Workspace: focus left/right",
|
|
||||||
"Workspace: toggle special": "Workspace: toggle special",
|
|
||||||
"Window: move to workspace # (1, 2, 3, 4, ...)": "Window: move to workspace # (1, 2, 3, 4, ...)",
|
|
||||||
"Window: move to workspace left/right": "Window: move to workspace left/right",
|
|
||||||
"Window: move to workspace special": "Window: move to workspace special",
|
|
||||||
"Window: pin (show on all workspaces)": "Window: pin (show on all workspaces)",
|
|
||||||
"Restart widgets": "Restart widgets",
|
|
||||||
"Cycle bar mode (normal, focus)": "Cycle bar mode (normal, focus)",
|
|
||||||
"Toggle overview/launcher": "Toggle overview/launcher",
|
|
||||||
"Show cheatsheet": "Show cheatsheet",
|
|
||||||
"Toggle left sidebar": "Toggle left sidebar",
|
|
||||||
"Toggle right sidebar": "Toggle right sidebar",
|
|
||||||
"Toggle music controls": "Toggle music controls",
|
|
||||||
"View color scheme and options": "View color scheme and options",
|
|
||||||
"Toggle power menu": "Toggle power menu",
|
|
||||||
"Toggle crosshair": "Toggle crosshair",
|
|
||||||
"Next track": "Next track",
|
|
||||||
"Previous track": "Previous track",
|
|
||||||
"Play/pause media": "Play/pause media",
|
|
||||||
"Launch Zed (editor)": "Launch Zed (editor)",
|
|
||||||
"Launch VSCode (editor)": "Launch VSCode (editor)",
|
|
||||||
"Launch Nautilus (file manager)": "Launch Nautilus (file manager)",
|
|
||||||
"Launch Firefox (browser)": "Launch Firefox (browser)",
|
|
||||||
"Launch GNOME Text Editor": "Launch GNOME Text Editor",
|
|
||||||
"Launch WPS Office": "Launch WPS Office",
|
|
||||||
"Launch GNOME Settings": "Launch GNOME Settings",
|
|
||||||
"Launch pavucontrol (volume mixer)": "Launch pavucontrol (volume mixer)",
|
|
||||||
"Launch EasyEffects (equalizer & other audio effects)": "Launch EasyEffects (equalizer & other audio effects)",
|
|
||||||
"Launch GNOME System monitor": "Launch GNOME System monitor",
|
|
||||||
"Toggle fallback launcher: anyrun": "Toggle fallback launcher: anyrun",
|
|
||||||
"Toggle fallback launcher: fuzzel": "Toggle fallback launcher: fuzzel",
|
|
||||||
"Initialization complete!": "Initialization complete!",
|
|
||||||
"Not found": "Not found:",
|
|
||||||
"Calling API": "Calling API",
|
|
||||||
"Downloading image": "Downloading image",
|
|
||||||
"Finished!": "Finished!",
|
|
||||||
"Error": "Error",
|
|
||||||
"Not found!": "Not found!",
|
|
||||||
"Go to file url": "Go to file url",
|
|
||||||
"Save image": "Save image",
|
|
||||||
"Hoard": "Hoard",
|
|
||||||
"Open externally": "Open externally",
|
|
||||||
"You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or don’t have enough information to provide a confident answer, simply say “I don’t know” or “I’m not sure.”. \nThanks!": "You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or don’t have enough information to provide a confident answer, simply say “I don’t know” or “I’m not sure.”. \nThanks!"
|
|
||||||
}
|
|
||||||
|
|
@ -1,241 +0,0 @@
|
||||||
{
|
|
||||||
"No media": "无媒体活动",
|
|
||||||
"Powered by Google": "由 Google 提供技术支持",
|
|
||||||
"Uses gemini-pro.\nNot affiliated, endorsed, or sponsored by Google.\n\nPrivacy: Chat messages aren't linked to your account,\n but will be read by human reviewers to improve the model.": "使用 Gemini Pro\n不隶属于、不受 Google 赞助或支持。\n\n隐私:聊天信息不会与你的账户关联,\n但会被人类审阅者阅读,用于改进模型。",
|
|
||||||
"Precise": "精确",
|
|
||||||
"Balanced": "平衡",
|
|
||||||
"Creative": "创意",
|
|
||||||
"Gemini's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "Gemini 的 temperature 值\n 精确 = 0\n 平衡 = 0.5\n 创意 = 1",
|
|
||||||
"Enhancements": "增强功能",
|
|
||||||
"Tells Gemini:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "告诉 Gemini:\n- 它是一个 Linux 侧边栏助手\n- 保持简洁并使用项目符号",
|
|
||||||
"Safety": "安全",
|
|
||||||
"When turned off, tells the API (not the model) \nto not block harmful/explicit content": "当关闭时,告诉 API(而不是模型)\n不要屏蔽有害/显露的内容",
|
|
||||||
"History": "历史",
|
|
||||||
"Saves chat history\nMessages in previous chats won't show automatically, but they are there": "保存聊天历史\n以前聊天中的消息不会自动显示,但它们仍然存在",
|
|
||||||
"Key stored in:": "密钥值储存在:",
|
|
||||||
"To update this key, type": "要更新此密钥,请输入",
|
|
||||||
"Updated API Key at": "更新了 API 密钥于",
|
|
||||||
"Currently using": "当前使用",
|
|
||||||
"Select ChatGPT-compatible API provider": "选择与 ChatGPT 兼容的 API 提供商",
|
|
||||||
"Official OpenAI API.\nPricing: Free for the first $5 or 3 months, whichever is less.": "官方 OpenAI API。\n定价:前 $5 或前 3 个月免费,取较小者。",
|
|
||||||
"Official Ollama API.\nPricing: Free.": "官方 Ollama API。\n定价:免费。",
|
|
||||||
"A unified interface for LLMs": "LLM 的统一接口",
|
|
||||||
"An API from Tornado Softwares\nPricing: Free: 100/day\nRequires you to join their Discord for a key": "来自 Tornado Softwares 的 API\n定价:免费:每天 100 次请求\n需要加入他们的 Discord 以获取密钥",
|
|
||||||
"An API from @zukixa on GitHub.\nNote: Keys are IP-locked so it's buggy sometimes\nPricing: Free: 10/min, 800/day.\nRequires you to join their Discord for a key": "来自 GitHub 上的 @zukixa 的 API。\n注意:密钥与 IP 绑定,所以有时会出错。\n定价:免费:每分钟 10 次,每天 800 次。\n需要加入他们的 Discord 才能获得密钥。",
|
|
||||||
"Provider shown above": "上述显示的提供商",
|
|
||||||
"Uses gpt-3.5-turbo.\nNot affiliated, endorsed, or sponsored by OpenAI.\n\nPrivacy: OpenAI claims they do not use your data\nwhen you use their API. Idk about others.": "使用 gpt-3.5-turbo。\n与 OpenAI 无关联,未获得其认可或赞助。\n\n隐私:OpenAI 声明,当您使用他们的 API 时,他们不会使用您的数据。\n我不清楚其他人的情况。",
|
|
||||||
"The model's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "模型的 temperature 值。\n 精确 = 0\n 平衡 = 0.5\n 创意 = 1",
|
|
||||||
"An API key is required\nYou can grab one <u>here</u>, then enter it below": "需要 API 密钥\n您可以在<u>这里</u>获取一个,然后在下面输入",
|
|
||||||
"Tells the model:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "告诉模型:\n- 它是一个 Linux 侧边栏助手\n- 保持简洁并使用项目符号",
|
|
||||||
"Powered by waifu.im + other APIs": "由 waifu.im + 其他 API 提供支持",
|
|
||||||
"Type tags for a random pic.\nNSFW content will not be returned unless\nyou explicitly request such a tag.\n\nDisclaimer: Not affiliated with the providers\nnor responsible for any of their content.": "输入标签以获取随机图片。\n除非您明确请求,否则不会返回 NSFW 内容。\n\n免责声明:与提供商无关联\n我也不对他们的任何内容负责。",
|
|
||||||
"Tags →": "标签 →",
|
|
||||||
"Invalid command.": "无效命令。",
|
|
||||||
"Anime booru": "动漫图库",
|
|
||||||
"Powered by yande.re and konachan": "由 yande.re 和 konachan 提供支持",
|
|
||||||
"An image booru. May contain NSFW content.\nWatch your back.\n\nDisclaimer: Not affiliated with the provider\nnor responsible for any of its content.": "一个图片图库。可能包含 NSFW 内容。\n小心。\n\n免责声明:与提供商无关联\n也不对它的任何内容负责。",
|
|
||||||
"Lewds": "不雅内容",
|
|
||||||
"Shows naughty stuff when enabled.\nYa like those? Add this to user_options.js:\n\t'sidebar': {\n\t'image': {\n\t\t'allowNsfw': true,\n\t}\n}": "启用时显示不雅内容。\n你喜欢这些?添加到 user_options.js 中:\n'sidebar': {\n\t'image': {\n\t\t'allowNsfw': true,\n\t}\n}",
|
|
||||||
"Save in folder by tags": "按标签保存到文件夹",
|
|
||||||
"Saves images in folders by their tags": "按标签将图片保存到文件夹中",
|
|
||||||
"Message Gemini...": "向 Gemini 发送消息...",
|
|
||||||
"Enter Google AI API Key...": "输入 Google AI API 密钥...",
|
|
||||||
"Message the model...": "向模型发送消息...",
|
|
||||||
"Enter API Key...": "输入 API 密钥...",
|
|
||||||
"Enter tags": "输入标签",
|
|
||||||
"Quick scripts": "快速脚本",
|
|
||||||
"Change screen resolution": "更改屏幕分辨率",
|
|
||||||
"Update packages": "更新软件包",
|
|
||||||
"Trim system generations to 5": "将系统代数修剪为 5",
|
|
||||||
"Trim home manager generations to 5": "将 home manager 代数修剪为 5",
|
|
||||||
"Remove orphan packages": "移除孤立软件包",
|
|
||||||
"Uninstall unused flatpak packages": "卸载未使用的 Flatpak 软件包",
|
|
||||||
"<span strikethrough=\"true\">Inaccurate</span> Color picker": "<span strikethrough=\"true\">不准确</span> 颜色选择器",
|
|
||||||
"Result": "结果",
|
|
||||||
"Type to search": "输入以搜索",
|
|
||||||
"illogical-impulse": "illogical-impulse",
|
|
||||||
"RAM Usage": "RAM 使用情况",
|
|
||||||
"Swap Usage": "Swap 使用情况",
|
|
||||||
"CPU Usage": "CPU 使用情况",
|
|
||||||
"Uptime:": "运行时间:",
|
|
||||||
"Screen snip": "屏幕截图",
|
|
||||||
"Color picker": "颜色选择器",
|
|
||||||
"Toggle on-screen keyboard": "切换屏幕键盘",
|
|
||||||
"Night Light": "夜灯",
|
|
||||||
"Color inversion": "颜色反转",
|
|
||||||
"Keep system awake": "保持系统唤醒",
|
|
||||||
"Cloudflare WARP": "Cloudflare WARP",
|
|
||||||
"Session": "会话",
|
|
||||||
"Bluetooth | Right-click to configure": "蓝牙 | 右键单击以配置",
|
|
||||||
"Wifi | Right-click to configure": "Wi-Fi | 右键单击以配置",
|
|
||||||
"Right-click to configure": "右键单击以配置",
|
|
||||||
"Unknown": "未知",
|
|
||||||
"Reload Environment config": "重新加载环境配置",
|
|
||||||
"Open Settings": "打开设置",
|
|
||||||
"Notifications": "通知",
|
|
||||||
"Audio controls": "音频控制",
|
|
||||||
"Bluetooth": "蓝牙",
|
|
||||||
"Wifi networks": "Wi-Fi 网络",
|
|
||||||
"Live config": "实时配置",
|
|
||||||
"Silence": "静音",
|
|
||||||
"Clear": "清除",
|
|
||||||
"No notifications": "无通知",
|
|
||||||
"notifications": "条通知",
|
|
||||||
"Close": "关闭",
|
|
||||||
"Now": "现在",
|
|
||||||
"Yesterday": "昨天",
|
|
||||||
"No audio source": "没有音频源",
|
|
||||||
"Remove device": "移除设备",
|
|
||||||
"Connected": "已连接",
|
|
||||||
"Paired": "已配对",
|
|
||||||
"More": "更多",
|
|
||||||
"Selected": "已选中",
|
|
||||||
"Current network": "当前网络",
|
|
||||||
"Authentication": "身份验证",
|
|
||||||
"Effects": "效果",
|
|
||||||
"Transparency": "透明度",
|
|
||||||
"[AGS]\nMake shell elements transparent\nBlur is also recommended if you enable this": "[AGS]\n使外壳元素透明\n如果启用此功能,也建议使用模糊效果",
|
|
||||||
"Blur": "模糊",
|
|
||||||
"[Hyprland]\nEnable blur on transparent elements\nDoesn't affect performance/power consumption unless you have transparent windows.": "[Hyprland]\n在透明元素上启用模糊效果\n除非您有透明窗口,否则不会影响性能/功耗。",
|
|
||||||
"X-ray": "X-ray",
|
|
||||||
"[Hyprland]\nMake everything behind a window/layer except the wallpaper not rendered on its blurred surface\nRecommended to improve performance (if you don't abuse transparency/blur) ": "[Hyprland]\n使窗口/图层后面的所有内容(除了壁纸)在其模糊表面上不渲染\n建议提高性能(如果您不滥用透明度/模糊)",
|
|
||||||
"Size": "大小",
|
|
||||||
"[Hyprland]\nAdjust the blur radius. Generally doesn't affect performance\nHigher = more color spread": "[Hyprland]\n调整模糊半径。通常不会影响性能\n数值越高 = 颜色扩散越大",
|
|
||||||
"Passes": "次数",
|
|
||||||
"[Hyprland] Adjust the number of runs of the blur algorithm\nMore passes = more spread and power consumption\n4 is recommended\n2- would look weird and 6+ would look lame.": "[Hyprland]\n调整模糊算法的运行次数\n次数越多 = 扩散越大,功耗越高\n建议使用 4 次\n2 次看起来很奇怪,6 次以上看起来很糟糕。",
|
|
||||||
"Animations": "动画",
|
|
||||||
"[Hyprland] [GTK]\nEnable animations": "[Hyprland] [GTK]\n启用动画",
|
|
||||||
"Choreography delay": "间隔",
|
|
||||||
"In milliseconds, the delay between animations of a series": "以毫秒为单位,一系列动画之间的延迟",
|
|
||||||
"Developer": "开发者选项",
|
|
||||||
"Show FPS": "显示 FPS",
|
|
||||||
"[Hyprland]\nShow FPS overlay on top-left corner": "[Hyprland]\n在左上角显示 FPS 叠加层",
|
|
||||||
"Log to stdout": "输出日志",
|
|
||||||
"[Hyprland]\nPrint LOG, ERR, WARN, etc. messages to the console": "[Hyprland]\n将 LOG、ERR、WARN 等消息打印到控制台",
|
|
||||||
"Damage tracking": "Damage tracking",
|
|
||||||
"[Hyprland]\nEnable damage tracking\nGenerally, leave it on.\nTurn off only when a shader doesn't work": "[Hyprland]\n启用 Damage tracking \n通常情况下,保持启用状态\n仅当着色器无法正常工作时才禁用",
|
|
||||||
"Damage blink": "显示视图更新",
|
|
||||||
"[Hyprland] [Epilepsy warning!]\nShow screen damage flashes": "[Hyprland] [癫痫警告!]\n屏幕视图更新时闪烁",
|
|
||||||
"Not all changes are saved": "并非所有更改都已保存",
|
|
||||||
"Mo": "一",
|
|
||||||
"Tu": "二",
|
|
||||||
"We": "三",
|
|
||||||
"Th": "四",
|
|
||||||
"Fr": "五",
|
|
||||||
"Sa": "六",
|
|
||||||
"Su": "日",
|
|
||||||
"Calendar": "日历",
|
|
||||||
"To Do": "待办",
|
|
||||||
"Unfinished": "未完成",
|
|
||||||
"Done": "已完成",
|
|
||||||
"Finished tasks will go here": "已完成的任务将显示在此处",
|
|
||||||
"Nothing here!": "这里什么也没有!",
|
|
||||||
"+ New task": "+ 新任务",
|
|
||||||
"Add a task...": "添加任务...",
|
|
||||||
"Color scheme": "配色方案",
|
|
||||||
"Options": "选项",
|
|
||||||
"Dark Mode": "深色模式",
|
|
||||||
"Ya should go to sleep!": "你应该去睡觉!",
|
|
||||||
"Use Gradience": "GTK 主题",
|
|
||||||
"Theme GTK apps using accent color\n(drawback: dark/light mode switching requires restart)": "使用强调色对 GTK 应用程序进行主题化\n(缺点:深色/浅色模式切换需要重启)",
|
|
||||||
"Scheme styles": "样式方案",
|
|
||||||
"Vibrant": "鲜艳",
|
|
||||||
"Vibrant+": "鲜艳+",
|
|
||||||
"Expressive": "表现力",
|
|
||||||
"Monochrome": "黑白",
|
|
||||||
"Rainbow": "彩虹",
|
|
||||||
"Fidelity": "保真度",
|
|
||||||
"Fruit Salad": "水果沙拉",
|
|
||||||
"Tonal Spot": "色调点",
|
|
||||||
"Content": "内容",
|
|
||||||
"Use arrow keys to navigate.\nEnter to select, Esc to cancel.": "使用箭头键导航。\n回车键选择,Esc 键取消。",
|
|
||||||
"Lock": "锁屏",
|
|
||||||
"Logout": "注销",
|
|
||||||
"Sleep": "睡眠",
|
|
||||||
"Hibernate": "休眠",
|
|
||||||
"Shutdown": "关机",
|
|
||||||
"Reboot": "重启",
|
|
||||||
"Cancel": "取消",
|
|
||||||
"Cheat sheet": "备忘单",
|
|
||||||
"Keybinds": "按键绑定",
|
|
||||||
"Periodic table": "元素周期表",
|
|
||||||
"Essentials for beginners": "初学者必备",
|
|
||||||
"Make shell elements transparent": "使外壳元素透明",
|
|
||||||
"Actions": "操作",
|
|
||||||
"Window management": "窗口管理",
|
|
||||||
"Window arrangement": "窗口排列",
|
|
||||||
"Workspace management": "工作区管理",
|
|
||||||
"Workspace navigation": "工作区导航",
|
|
||||||
"Widgets": "小部件",
|
|
||||||
"Media": "媒体",
|
|
||||||
"Apps": "应用程序",
|
|
||||||
"Neutral": "中性",
|
|
||||||
"Launch foot (terminal)": "启动终端(foot)",
|
|
||||||
"Open app launcher": "打开应用程序启动器",
|
|
||||||
"Change wallpaper": "更改壁纸",
|
|
||||||
"Clipboard history >> clipboard": "剪贴板历史 >> 剪贴板",
|
|
||||||
"Pick emoji >> clipboard": "选择表情符号 >> 剪贴板",
|
|
||||||
"Screen snip >> edit": "屏幕截图 >> 编辑",
|
|
||||||
"Screen snip to text >> clipboard": "屏幕截图转文字 >> 剪贴板",
|
|
||||||
"Pick color (Hex) >> clipboard": "选择颜色(十六进制)>> 剪贴板",
|
|
||||||
"Screenshot >> clipboard": "屏幕截图 >> 剪贴板",
|
|
||||||
"Screenshot >> clipboard & file": "屏幕截图 >> 剪贴板和文件",
|
|
||||||
"Record region (no sound)": "录制区域(无声音)",
|
|
||||||
"Record screen (with sound)": "录制屏幕(带声音)",
|
|
||||||
"Suspend system": "挂起系统",
|
|
||||||
"Move focus in direction": "在方向上移动焦点",
|
|
||||||
"Move window": "移动窗口",
|
|
||||||
"Resize window": "调整窗口大小",
|
|
||||||
"Close window": "关闭窗口",
|
|
||||||
"Pick and kill a window": "选择并关闭一个窗口",
|
|
||||||
"Window: move in direction": "窗口:在方向上移动",
|
|
||||||
"Window: split ratio +/- 0.1": "窗口:分割比例 +/- 0.1",
|
|
||||||
"Float/unfloat window": "浮动/取消浮动窗口",
|
|
||||||
"Toggle fake fullscreen": "切换伪全屏",
|
|
||||||
"Toggle fullscreen": "切换全屏",
|
|
||||||
"Toggle maximization": "切换最大化",
|
|
||||||
"Focus workspace # (1, 2, 3, 4, ...)": "聚焦工作区 #(1, 2, 3, 4, ...)",
|
|
||||||
"Workspace: focus left/right": "工作区:聚焦左右",
|
|
||||||
"Workspace: toggle special": "工作区:切换特殊工作区",
|
|
||||||
"Window: move to workspace # (1, 2, 3, 4, ...)": "窗口:移动到工作区 #(1, 2, 3, 4, ...)",
|
|
||||||
"Window: move to workspace left/right": "窗口:移动到左右工作区",
|
|
||||||
"Window: move to workspace special": "窗口:移动到特殊工作区",
|
|
||||||
"Window: pin (show on all workspaces)": "窗口:固定(在所有工作区显示)",
|
|
||||||
"Restart widgets": "重启小部件",
|
|
||||||
"Cycle bar mode (normal, focus)": "循环栏模式(正常,聚焦)",
|
|
||||||
"Toggle overview/launcher": "切换概览/启动器",
|
|
||||||
"Show cheatsheet": "显示快捷键表",
|
|
||||||
"Toggle left sidebar": "切换左侧边栏",
|
|
||||||
"Toggle right sidebar": "切换右侧边栏",
|
|
||||||
"Toggle music controls": "切换音乐控制",
|
|
||||||
"View color scheme and options": "查看配色方案和选项",
|
|
||||||
"Toggle power menu": "切换电源菜单",
|
|
||||||
"Toggle crosshair": "切换准星",
|
|
||||||
"Next track": "下一曲目",
|
|
||||||
"Previous track": "上一曲目",
|
|
||||||
"Play/pause media": "播放/暂停媒体",
|
|
||||||
"Launch Zed (editor)": "启动 Zed(编辑器)",
|
|
||||||
"Launch VSCode (editor)": "启动 VSCode(编辑器)",
|
|
||||||
"Launch Nautilus (file manager)": "启动 Nautilus(文件管理器)",
|
|
||||||
"Launch Firefox (browser)": "启动 Firefox(浏览器)",
|
|
||||||
"Launch GNOME Text Editor": "启动 GNOME 文本编辑器",
|
|
||||||
"Launch WPS Office": "启动 WPS 办公软件",
|
|
||||||
"Launch GNOME Settings": "启动 GNOME 设置",
|
|
||||||
"Launch pavucontrol (volume mixer)": "启动 pavucontrol(音量混合器)",
|
|
||||||
"Launch EasyEffects (equalizer & other audio effects)": "启动 EasyEffects(均衡器和其他音频效果)",
|
|
||||||
"Launch GNOME System monitor": "启动 GNOME 系统监视器",
|
|
||||||
"Toggle fallback launcher: anyrun": "切换备用启动器:anyrun",
|
|
||||||
"Toggle fallback launcher: fuzzel": "切换备用启动器:fuzzel",
|
|
||||||
"Initialization complete!": "初始化完成!",
|
|
||||||
"Not found": "未找到",
|
|
||||||
"Calling API": "调用 API",
|
|
||||||
"Downloading image": "正在下载图片",
|
|
||||||
"Finished!": "完成!",
|
|
||||||
"Error": "错误",
|
|
||||||
"Not found!": "未找到!",
|
|
||||||
"Go to file url": "前往文件链接",
|
|
||||||
"Save image": "保存图片",
|
|
||||||
"Hoard": "保存",
|
|
||||||
"Open externally": "在外部打开",
|
|
||||||
"You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or don’t have enough information to provide a confident answer, simply say “I don’t know” or “I’m not sure.”. \nThanks!": "你是 Wayland Linux 桌面侧边栏上的助手。除非有其他要求或提供建议,否则请始终保持轻松的语气回答问题。这是你回答用户查询的步骤:\n1. 如果是写作或语法相关的问题,或者引号中的句子,请指出错误并在必要时进行更正,使用下划线,并在适当的地方使写作更自然,不要进行太大更改。如果你给出的句子在引号中但语法正确,请简要解释不常见概念。\n2. 如果是关于系统任务的问题,请给出bash命令,并在代码块中简要说明。\n3. 否则,在总结信息或解释概念时,你应该使用项目符号和标题。对于数学表达式,你必须在代码块中使用 LaTeX,并将语言设置为\"latex\"。\n注意:使用轻松的语言,简洁,同时确保回答的事实正确性。如果你不确定或没有足够的信息来提供自信的答案,只需说“我不知道”或“我不确定”。\n谢谢!"
|
|
||||||
}
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
import GLib from 'gi://GLib';
|
|
||||||
import App from 'resource:///com/github/Aylur/ags/app.js'
|
|
||||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
|
|
||||||
import { darkMode } from './modules/.miscutils/system.js';
|
|
||||||
export const COMPILED_STYLE_DIR = `${GLib.get_user_cache_dir()}/ags/user/generated`
|
|
||||||
globalThis['handleStyles'] = (resetMusic) => {
|
|
||||||
// Reset
|
|
||||||
Utils.exec(`mkdir -p "${GLib.get_user_state_dir()}/ags/scss"`);
|
|
||||||
if (resetMusic) {
|
|
||||||
Utils.exec(`bash -c 'echo "" > ${GLib.get_user_state_dir()}/ags/scss/_musicwal.scss'`); // reset music styles
|
|
||||||
Utils.exec(`bash -c 'echo "" > ${GLib.get_user_state_dir()}/ags/scss/_musicmaterial.scss'`); // reset music styles
|
|
||||||
}
|
|
||||||
// Generate overrides
|
|
||||||
let lightdark = darkMode.value ? "dark" : "light";
|
|
||||||
Utils.writeFileSync(
|
|
||||||
`@mixin symbolic-icon {
|
|
||||||
-gtk-icon-theme: '${userOptions.icons.symbolicIconTheme[lightdark]}';
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
`${GLib.get_user_state_dir()}/ags/scss/_lib_mixins_overrides.scss`)
|
|
||||||
// Compile and apply
|
|
||||||
async function applyStyle() {
|
|
||||||
Utils.exec(`mkdir -p ${COMPILED_STYLE_DIR}`);
|
|
||||||
Utils.exec(`sass -I "${GLib.get_user_state_dir()}/ags/scss" -I "${App.configDir}/scss/fallback" "${App.configDir}/scss/main.scss" "${COMPILED_STYLE_DIR}/style.css"`);
|
|
||||||
App.resetCss();
|
|
||||||
App.applyCss(`${COMPILED_STYLE_DIR}/style.css`);
|
|
||||||
console.log('[LOG] Styles loaded')
|
|
||||||
}
|
|
||||||
applyStyle().catch(print);
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
const { Gdk } = imports.gi;
|
|
||||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
|
|
||||||
const { execAsync, exec } = Utils;
|
|
||||||
|
|
||||||
export let monitors;
|
|
||||||
|
|
||||||
// Mixes with Gdk monitor size cuz it reports monitor size scaled
|
|
||||||
async function updateStuff() {
|
|
||||||
monitors = JSON.parse(exec('hyprctl monitors -j'))
|
|
||||||
const display = Gdk.Display.get_default();
|
|
||||||
monitors.forEach((monitor, i) => {
|
|
||||||
const gdkMonitor = display.get_monitor(i);
|
|
||||||
monitor.realWidth = monitor.width;
|
|
||||||
monitor.realHeight = monitor.height;
|
|
||||||
if (userOptions.monitors.scaleMethod.toLowerCase == "gdk") {
|
|
||||||
monitor.width = gdkMonitor.get_geometry().width;
|
|
||||||
monitor.height = gdkMonitor.get_geometry().height;
|
|
||||||
}
|
|
||||||
else { // == "division"
|
|
||||||
monitor.width = Math.ceil(monitor.realWidth / monitor.scale);
|
|
||||||
monitor.height = Math.ceil(monitor.realHeight / monitor.scale);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
updateStuff().catch(print);
|
|
||||||
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
export const quotes = [
|
|
||||||
{
|
|
||||||
quote: 'Nvidia, fuck you',
|
|
||||||
author: 'Linus Torvalds',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
quote: 'reproducible system? cock and vagina?',
|
|
||||||
author: 'vaxry',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
quote: "haha pointers hee hee i love pointe-\\\nProcess Vaxry exited with signal SIGSEGV",
|
|
||||||
author: 'vaxry',
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
@ -1,94 +0,0 @@
|
||||||
export const WWO_CODE = {
|
|
||||||
"113": "Sunny",
|
|
||||||
"116": "PartlyCloudy",
|
|
||||||
"119": "Cloudy",
|
|
||||||
"122": "VeryCloudy",
|
|
||||||
"143": "Fog",
|
|
||||||
"176": "LightShowers",
|
|
||||||
"179": "LightSleetShowers",
|
|
||||||
"182": "LightSleet",
|
|
||||||
"185": "LightSleet",
|
|
||||||
"200": "ThunderyShowers",
|
|
||||||
"227": "LightSnow",
|
|
||||||
"230": "HeavySnow",
|
|
||||||
"248": "Fog",
|
|
||||||
"260": "Fog",
|
|
||||||
"263": "LightShowers",
|
|
||||||
"266": "LightRain",
|
|
||||||
"281": "LightSleet",
|
|
||||||
"284": "LightSleet",
|
|
||||||
"293": "LightRain",
|
|
||||||
"296": "LightRain",
|
|
||||||
"299": "HeavyShowers",
|
|
||||||
"302": "HeavyRain",
|
|
||||||
"305": "HeavyShowers",
|
|
||||||
"308": "HeavyRain",
|
|
||||||
"311": "LightSleet",
|
|
||||||
"314": "LightSleet",
|
|
||||||
"317": "LightSleet",
|
|
||||||
"320": "LightSnow",
|
|
||||||
"323": "LightSnowShowers",
|
|
||||||
"326": "LightSnowShowers",
|
|
||||||
"329": "HeavySnow",
|
|
||||||
"332": "HeavySnow",
|
|
||||||
"335": "HeavySnowShowers",
|
|
||||||
"338": "HeavySnow",
|
|
||||||
"350": "LightSleet",
|
|
||||||
"353": "LightShowers",
|
|
||||||
"356": "HeavyShowers",
|
|
||||||
"359": "HeavyRain",
|
|
||||||
"362": "LightSleetShowers",
|
|
||||||
"365": "LightSleetShowers",
|
|
||||||
"368": "LightSnowShowers",
|
|
||||||
"371": "HeavySnowShowers",
|
|
||||||
"374": "LightSleetShowers",
|
|
||||||
"377": "LightSleet",
|
|
||||||
"386": "ThunderyShowers",
|
|
||||||
"389": "ThunderyHeavyRain",
|
|
||||||
"392": "ThunderySnowShowers",
|
|
||||||
"395": "HeavySnowShowers",
|
|
||||||
}
|
|
||||||
|
|
||||||
export const WEATHER_SYMBOL = {
|
|
||||||
"Unknown": "air",
|
|
||||||
"Cloudy": "cloud",
|
|
||||||
"Fog": "foggy",
|
|
||||||
"HeavyRain": "rainy",
|
|
||||||
"HeavyShowers": "rainy",
|
|
||||||
"HeavySnow": "snowing",
|
|
||||||
"HeavySnowShowers": "snowing",
|
|
||||||
"LightRain": "rainy",
|
|
||||||
"LightShowers": "rainy",
|
|
||||||
"LightSleet": "rainy",
|
|
||||||
"LightSleetShowers": "rainy",
|
|
||||||
"LightSnow": "cloudy_snowing",
|
|
||||||
"LightSnowShowers": "cloudy_snowing",
|
|
||||||
"PartlyCloudy": "partly_cloudy_day",
|
|
||||||
"Sunny": "clear_day",
|
|
||||||
"ThunderyHeavyRain": "thunderstorm",
|
|
||||||
"ThunderyShowers": "thunderstorm",
|
|
||||||
"ThunderySnowShowers": "thunderstorm",
|
|
||||||
"VeryCloudy": "cloud",
|
|
||||||
}
|
|
||||||
|
|
||||||
export const NIGHT_WEATHER_SYMBOL = {
|
|
||||||
"Unknown": "air",
|
|
||||||
"Cloudy": "cloud",
|
|
||||||
"Fog": "foggy",
|
|
||||||
"HeavyRain": "rainy",
|
|
||||||
"HeavyShowers": "rainy",
|
|
||||||
"HeavySnow": "snowing",
|
|
||||||
"HeavySnowShowers": "snowing",
|
|
||||||
"LightRain": "rainy",
|
|
||||||
"LightShowers": "rainy",
|
|
||||||
"LightSleet": "rainy",
|
|
||||||
"LightSleetShowers": "rainy",
|
|
||||||
"LightSnow": "cloudy_snowing",
|
|
||||||
"LightSnowShowers": "cloudy_snowing",
|
|
||||||
"PartlyCloudy": "partly_cloudy_night",
|
|
||||||
"Sunny": "clear_night",
|
|
||||||
"ThunderyHeavyRain": "thunderstorm",
|
|
||||||
"ThunderyShowers": "thunderstorm",
|
|
||||||
"ThunderySnowShowers": "thunderstorm",
|
|
||||||
"VeryCloudy": "cloud",
|
|
||||||
}
|
|
||||||
|
|
@ -1,106 +0,0 @@
|
||||||
const { Gtk } = imports.gi;
|
|
||||||
const Lang = imports.lang;
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js'
|
|
||||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
|
|
||||||
|
|
||||||
// -- Styling --
|
|
||||||
// min-height for diameter
|
|
||||||
// min-width for trough stroke
|
|
||||||
// padding for space between trough and progress
|
|
||||||
// margin for space between widget and parent
|
|
||||||
// background-color for trough color
|
|
||||||
// color for progress color
|
|
||||||
// -- Usage --
|
|
||||||
// font size for progress value (0-100px) (hacky i know, but i want animations)
|
|
||||||
export const AnimatedCircProg = ({
|
|
||||||
initFrom = 0,
|
|
||||||
initTo = 0,
|
|
||||||
initAnimTime = 2900,
|
|
||||||
initAnimPoints = 1,
|
|
||||||
extraSetup = () => { },
|
|
||||||
...rest
|
|
||||||
}) => Widget.DrawingArea({
|
|
||||||
...rest,
|
|
||||||
css: `${initFrom != initTo ? 'font-size: ' + initFrom + 'px; transition: ' + initAnimTime + 'ms linear;' : ''}`,
|
|
||||||
setup: (area) => {
|
|
||||||
const styleContext = area.get_style_context();
|
|
||||||
const width = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
|
|
||||||
const height = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
|
|
||||||
const padding = styleContext.get_padding(Gtk.StateFlags.NORMAL).left;
|
|
||||||
const marginLeft = styleContext.get_margin(Gtk.StateFlags.NORMAL).left;
|
|
||||||
const marginRight = styleContext.get_margin(Gtk.StateFlags.NORMAL).right;
|
|
||||||
const marginTop = styleContext.get_margin(Gtk.StateFlags.NORMAL).top;
|
|
||||||
const marginBottom = styleContext.get_margin(Gtk.StateFlags.NORMAL).bottom;
|
|
||||||
area.set_size_request(width + marginLeft + marginRight, height + marginTop + marginBottom);
|
|
||||||
area.connect('draw', Lang.bind(area, (area, cr) => {
|
|
||||||
const styleContext = area.get_style_context();
|
|
||||||
const width = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
|
|
||||||
const height = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
|
|
||||||
const padding = styleContext.get_padding(Gtk.StateFlags.NORMAL).left;
|
|
||||||
const marginLeft = styleContext.get_margin(Gtk.StateFlags.NORMAL).left;
|
|
||||||
const marginRight = styleContext.get_margin(Gtk.StateFlags.NORMAL).right;
|
|
||||||
const marginTop = styleContext.get_margin(Gtk.StateFlags.NORMAL).top;
|
|
||||||
const marginBottom = styleContext.get_margin(Gtk.StateFlags.NORMAL).bottom;
|
|
||||||
area.set_size_request(width + marginLeft + marginRight, height + marginTop + marginBottom);
|
|
||||||
|
|
||||||
const progressValue = styleContext.get_property('font-size', Gtk.StateFlags.NORMAL) / 100.0;
|
|
||||||
|
|
||||||
const bg_stroke = styleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
|
|
||||||
const fg_stroke = bg_stroke - padding;
|
|
||||||
const radius = Math.min(width, height) / 2.0 - Math.max(bg_stroke, fg_stroke) / 2.0;
|
|
||||||
const center_x = width / 2.0 + marginLeft;
|
|
||||||
const center_y = height / 2.0 + marginTop;
|
|
||||||
const start_angle = -Math.PI / 2.0;
|
|
||||||
const end_angle = start_angle + (2 * Math.PI * progressValue);
|
|
||||||
const start_x = center_x + Math.cos(start_angle) * radius;
|
|
||||||
const start_y = center_y + Math.sin(start_angle) * radius;
|
|
||||||
const end_x = center_x + Math.cos(end_angle) * radius;
|
|
||||||
const end_y = center_y + Math.sin(end_angle) * radius;
|
|
||||||
|
|
||||||
// Draw background
|
|
||||||
const background_color = styleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
|
|
||||||
cr.setSourceRGBA(background_color.red, background_color.green, background_color.blue, background_color.alpha);
|
|
||||||
cr.arc(center_x, center_y, radius, 0, 2 * Math.PI);
|
|
||||||
cr.setLineWidth(bg_stroke);
|
|
||||||
cr.stroke();
|
|
||||||
|
|
||||||
if (progressValue == 0) return;
|
|
||||||
|
|
||||||
// Draw progress
|
|
||||||
const color = styleContext.get_property('color', Gtk.StateFlags.NORMAL);
|
|
||||||
cr.setSourceRGBA(color.red, color.green, color.blue, color.alpha);
|
|
||||||
cr.arc(center_x, center_y, radius, start_angle, end_angle);
|
|
||||||
cr.setLineWidth(fg_stroke);
|
|
||||||
cr.stroke();
|
|
||||||
|
|
||||||
// Draw rounded ends for progress arcs
|
|
||||||
cr.setLineWidth(0);
|
|
||||||
cr.arc(start_x, start_y, fg_stroke / 2, 0, 0 - 0.01);
|
|
||||||
cr.fill();
|
|
||||||
cr.arc(end_x, end_y, fg_stroke / 2, 0, 0 - 0.01);
|
|
||||||
cr.fill();
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Init animation
|
|
||||||
if (initFrom != initTo) {
|
|
||||||
area.css = `font-size: ${initFrom}px; transition: ${initAnimTime}ms linear;`;
|
|
||||||
Utils.timeout(20, () => {
|
|
||||||
area.css = `font-size: ${initTo}px;`;
|
|
||||||
}, area)
|
|
||||||
const transitionDistance = initTo - initFrom;
|
|
||||||
const oneStep = initAnimTime / initAnimPoints;
|
|
||||||
area.css = `
|
|
||||||
font-size: ${initFrom}px;
|
|
||||||
transition: ${oneStep}ms linear;
|
|
||||||
`;
|
|
||||||
for (let i = 0; i < initAnimPoints; i++) {
|
|
||||||
Utils.timeout(Math.max(10, i * oneStep), () => {
|
|
||||||
if(!area) return;
|
|
||||||
area.css = `${initFrom != initTo ? 'font-size: ' + (initFrom + (transitionDistance / initAnimPoints * (i + 1))) + 'px;' : ''}`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else area.css = 'font-size: 0px;';
|
|
||||||
extraSetup(area);
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
const { Gtk } = imports.gi;
|
|
||||||
const Lang = imports.lang;
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
|
|
||||||
// min-height/min-width for height/width
|
|
||||||
// background-color/color for background/indicator color
|
|
||||||
// padding for pad of indicator
|
|
||||||
// font-size for selected index (0-based)
|
|
||||||
export const NavigationIndicator = ({count, vertical, ...props}) => Widget.DrawingArea({
|
|
||||||
...props,
|
|
||||||
setup: (area) => {
|
|
||||||
const styleContext = area.get_style_context();
|
|
||||||
const width = Math.max(styleContext.get_property('min-width', Gtk.StateFlags.NORMAL), area.get_allocated_width());
|
|
||||||
const height = Math.max(styleContext.get_property('min-height', Gtk.StateFlags.NORMAL), area.get_allocated_height());
|
|
||||||
area.set_size_request(width, height);
|
|
||||||
|
|
||||||
area.connect('draw', Lang.bind(area, (area, cr) => {
|
|
||||||
const styleContext = area.get_style_context();
|
|
||||||
const width = Math.max(styleContext.get_property('min-width', Gtk.StateFlags.NORMAL), area.get_allocated_width());
|
|
||||||
const height = Math.max(styleContext.get_property('min-height', Gtk.StateFlags.NORMAL), area.get_allocated_height());
|
|
||||||
// console.log('allocated width/height:', area.get_allocated_width(), '/', area.get_allocated_height())
|
|
||||||
area.set_size_request(width, height);
|
|
||||||
const paddingLeft = styleContext.get_padding(Gtk.StateFlags.NORMAL).left;
|
|
||||||
const paddingRight = styleContext.get_padding(Gtk.StateFlags.NORMAL).right;
|
|
||||||
const paddingTop = styleContext.get_padding(Gtk.StateFlags.NORMAL).top;
|
|
||||||
const paddingBottom = styleContext.get_padding(Gtk.StateFlags.NORMAL).bottom;
|
|
||||||
|
|
||||||
const selectedCell = styleContext.get_property('font-size', Gtk.StateFlags.NORMAL);
|
|
||||||
|
|
||||||
let cellWidth = width;
|
|
||||||
let cellHeight = height;
|
|
||||||
if (vertical) cellHeight /= count;
|
|
||||||
else cellWidth /= count;
|
|
||||||
const indicatorWidth = cellWidth - paddingLeft - paddingRight;
|
|
||||||
const indicatorHeight = cellHeight - paddingTop - paddingBottom;
|
|
||||||
|
|
||||||
const background_color = styleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
|
|
||||||
const color = styleContext.get_property('color', Gtk.StateFlags.NORMAL);
|
|
||||||
cr.setLineWidth(2);
|
|
||||||
// Background
|
|
||||||
cr.setSourceRGBA(background_color.red, background_color.green, background_color.blue, background_color.alpha);
|
|
||||||
cr.rectangle(0, 0, width, height);
|
|
||||||
cr.fill();
|
|
||||||
|
|
||||||
// The indicator line
|
|
||||||
cr.setSourceRGBA(color.red, color.green, color.blue, color.alpha);
|
|
||||||
if (vertical) {
|
|
||||||
cr.rectangle(paddingLeft, paddingTop + cellHeight * selectedCell + indicatorWidth / 2, indicatorWidth, indicatorHeight - indicatorWidth);
|
|
||||||
cr.stroke();
|
|
||||||
cr.rectangle(paddingLeft, paddingTop + cellHeight * selectedCell + indicatorWidth / 2, indicatorWidth, indicatorHeight - indicatorWidth);
|
|
||||||
cr.fill();
|
|
||||||
cr.arc(paddingLeft + indicatorWidth / 2, paddingTop + cellHeight * selectedCell + indicatorWidth / 2, indicatorWidth / 2, Math.PI, 2 * Math.PI);
|
|
||||||
cr.fill();
|
|
||||||
cr.arc(paddingLeft + indicatorWidth / 2, paddingTop + cellHeight * selectedCell + indicatorHeight - indicatorWidth / 2, indicatorWidth / 2, 0, Math.PI);
|
|
||||||
cr.fill();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cr.rectangle(paddingLeft + cellWidth * selectedCell + indicatorHeight / 2, paddingTop, indicatorWidth - indicatorHeight, indicatorHeight);
|
|
||||||
cr.stroke();
|
|
||||||
cr.rectangle(paddingLeft + cellWidth * selectedCell + indicatorHeight / 2, paddingTop, indicatorWidth - indicatorHeight, indicatorHeight);
|
|
||||||
cr.fill();
|
|
||||||
cr.arc(paddingLeft + cellWidth * selectedCell + indicatorHeight / 2, paddingTop + indicatorHeight / 2, indicatorHeight / 2, 0.5 * Math.PI, 1.5 * Math.PI);
|
|
||||||
cr.fill();
|
|
||||||
cr.arc(paddingLeft + cellWidth * selectedCell + indicatorWidth - indicatorHeight / 2, paddingTop + indicatorHeight / 2, indicatorHeight / 2, -0.5 * Math.PI, 0.5 * Math.PI);
|
|
||||||
cr.fill();
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
const { Gtk } = imports.gi;
|
|
||||||
const Lang = imports.lang;
|
|
||||||
|
|
||||||
export const RoundedCorner = (place, props) => Widget.DrawingArea({
|
|
||||||
...props,
|
|
||||||
hpack: place.includes('left') ? 'start' : 'end',
|
|
||||||
vpack: place.includes('top') ? 'start' : 'end',
|
|
||||||
setup: (widget) => Utils.timeout(1, () => {
|
|
||||||
const c = widget.get_style_context().get_property('background-color', Gtk.StateFlags.NORMAL);
|
|
||||||
const r = widget.get_style_context().get_property('border-radius', Gtk.StateFlags.NORMAL);
|
|
||||||
widget.set_size_request(r, r);
|
|
||||||
widget.connect('draw', Lang.bind(widget, (widget, cr) => {
|
|
||||||
const c = widget.get_style_context().get_property('background-color', Gtk.StateFlags.NORMAL);
|
|
||||||
const r = widget.get_style_context().get_property('border-radius', Gtk.StateFlags.NORMAL);
|
|
||||||
// const borderColor = widget.get_style_context().get_property('color', Gtk.StateFlags.NORMAL);
|
|
||||||
// const borderWidth = widget.get_style_context().get_border(Gtk.StateFlags.NORMAL).left; // ur going to write border-width: something anyway
|
|
||||||
widget.set_size_request(r, r);
|
|
||||||
|
|
||||||
switch (place) {
|
|
||||||
case 'topleft':
|
|
||||||
cr.arc(r, r, r, Math.PI, 3 * Math.PI / 2);
|
|
||||||
cr.lineTo(0, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'topright':
|
|
||||||
cr.arc(0, r, r, 3 * Math.PI / 2, 2 * Math.PI);
|
|
||||||
cr.lineTo(r, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'bottomleft':
|
|
||||||
cr.arc(r, 0, r, Math.PI / 2, Math.PI);
|
|
||||||
cr.lineTo(0, r);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'bottomright':
|
|
||||||
cr.arc(0, 0, r, 0, Math.PI / 2);
|
|
||||||
cr.lineTo(r, r);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
cr.closePath();
|
|
||||||
cr.setSourceRGBA(c.red, c.green, c.blue, c.alpha);
|
|
||||||
cr.fill();
|
|
||||||
// cr.setLineWidth(borderWidth);
|
|
||||||
// cr.setSourceRGBA(borderColor.red, borderColor.green, borderColor.blue, borderColor.alpha);
|
|
||||||
// cr.stroke();
|
|
||||||
}));
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
const { Gtk } = imports.gi;
|
|
||||||
const Lang = imports.lang;
|
|
||||||
|
|
||||||
export const AnimatedSlider = ({
|
|
||||||
className,
|
|
||||||
value,
|
|
||||||
...rest
|
|
||||||
}) => {
|
|
||||||
return Widget.DrawingArea({
|
|
||||||
className: `${className}`,
|
|
||||||
setup: (self) => {
|
|
||||||
self.connect('draw', Lang.bind(self, (self, cr) => {
|
|
||||||
const styleContext = self.get_style_context();
|
|
||||||
const allocatedWidth = self.get_allocated_width();
|
|
||||||
const allocatedHeight = self.get_allocated_height();
|
|
||||||
console.log(allocatedHeight, allocatedWidth)
|
|
||||||
const minWidth = styleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
|
|
||||||
const minHeight = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
|
|
||||||
const radius = styleContext.get_property('border-radius', Gtk.StateFlags.NORMAL);
|
|
||||||
const bg = styleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
|
|
||||||
const fg = styleContext.get_property('color', Gtk.StateFlags.NORMAL);
|
|
||||||
const value = styleContext.get_property('font-size', Gtk.StateFlags.NORMAL) / 100;
|
|
||||||
self.set_size_request(-1, minHeight);
|
|
||||||
const width = allocatedHeight;
|
|
||||||
const height = minHeight;
|
|
||||||
|
|
||||||
cr.arc(radius, radius, radius, -1 * Math.PI, -0.5 * Math.PI); // Top-left
|
|
||||||
cr.arc(width - radius, radius, radius, -0.5 * Math.PI, 0); // Top-right
|
|
||||||
cr.arc(width - radius, height - radius, radius, 0, 0.5 * Math.PI); // Bottom-left
|
|
||||||
cr.arc(radius, height - radius, radius, 0.5 * Math.PI, 1 * Math.PI); // Bottom-right
|
|
||||||
cr.setSourceRGBA(bg.red, bg.green, bg.blue, bg.alpha);
|
|
||||||
cr.closePath();
|
|
||||||
cr.fill();
|
|
||||||
|
|
||||||
// const valueWidth = width * value;
|
|
||||||
// cr.arc(radius, radius, radius, -1 * Math.PI, -0.5 * Math.PI); // Top-left
|
|
||||||
// cr.arc(valueWidth - radius, radius, radius, -0.5 * Math.PI, 0); // Top-right
|
|
||||||
// cr.arc(valueWidth - radius, height - radius, radius, 0, 0.5 * Math.PI); // Bottom-left
|
|
||||||
// cr.arc(radius, height - radius, radius, 0.5 * Math.PI, 1 * Math.PI); // Bottom-right
|
|
||||||
// cr.setSourceRGBA(fg.red, fg.green, fg.blue, fg.alpha);
|
|
||||||
// cr.closePath();
|
|
||||||
// cr.fill();
|
|
||||||
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
...rest,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
import App from 'resource:///com/github/Aylur/ags/app.js';
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import { monitors } from '../.commondata/hyprlanddata.js';
|
|
||||||
const { Box, EventBox } = Widget;
|
|
||||||
|
|
||||||
export const clickCloseRegion = ({ name, multimonitor = true, monitor = 0, expand = true, fillMonitor = '' }) => {
|
|
||||||
return EventBox({
|
|
||||||
child: Box({
|
|
||||||
expand: expand,
|
|
||||||
css: `
|
|
||||||
min-width: ${fillMonitor.includes('h') ? monitors[monitor].width : 0}px;
|
|
||||||
min-height: ${fillMonitor.includes('v') ? monitors[monitor].height : 0}px;
|
|
||||||
`,
|
|
||||||
}),
|
|
||||||
setup: (self) => self.on('button-press-event', (self, event) => { // Any mouse button
|
|
||||||
if (multimonitor) closeWindowOnAllMonitors(name);
|
|
||||||
else App.closeWindow(name);
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export default clickCloseRegion;
|
|
||||||
|
|
||||||
|
|
@ -1,219 +0,0 @@
|
||||||
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
|
|
||||||
import { MaterialIcon } from './materialicon.js';
|
|
||||||
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
|
|
||||||
const { Box, Button, Label, Revealer, SpinButton } = Widget;
|
|
||||||
|
|
||||||
export const ConfigToggle = ({
|
|
||||||
icon, name, desc = '', initValue,
|
|
||||||
expandWidget = true,
|
|
||||||
onChange = () => { }, extraSetup = () => { },
|
|
||||||
...rest
|
|
||||||
}) => {
|
|
||||||
const enabled = Variable(initValue);
|
|
||||||
const toggleIcon = Label({
|
|
||||||
className: `icon-material txt-bold ${enabled.value ? '' : 'txt-poof'}`,
|
|
||||||
label: `${enabled.value ? 'check' : ''}`,
|
|
||||||
setup: (self) => self.hook(enabled, (self) => {
|
|
||||||
self.toggleClassName('switch-fg-toggling-false', false);
|
|
||||||
if (!enabled.value) {
|
|
||||||
self.label = '';
|
|
||||||
self.toggleClassName('txt-poof', true);
|
|
||||||
}
|
|
||||||
else Utils.timeout(1, () => {
|
|
||||||
toggleIcon.label = 'check';
|
|
||||||
toggleIcon.toggleClassName('txt-poof', false);
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
const toggleButtonIndicator = Box({
|
|
||||||
className: `switch-fg ${enabled.value ? 'switch-fg-true' : ''}`,
|
|
||||||
vpack: 'center',
|
|
||||||
hpack: 'start',
|
|
||||||
homogeneous: true,
|
|
||||||
children: [toggleIcon,],
|
|
||||||
setup: (self) => self.hook(enabled, (self) => {
|
|
||||||
self.toggleClassName('switch-fg-true', enabled.value);
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
const toggleButton = Box({
|
|
||||||
hpack: 'end',
|
|
||||||
className: `switch-bg ${enabled.value ? 'switch-bg-true' : ''}`,
|
|
||||||
homogeneous: true,
|
|
||||||
children: [toggleButtonIndicator],
|
|
||||||
setup: (self) => self.hook(enabled, (self) => {
|
|
||||||
self.toggleClassName('switch-bg-true', enabled.value);
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
const widgetContent = Box({
|
|
||||||
tooltipText: desc,
|
|
||||||
className: 'txt spacing-h-5 configtoggle-box',
|
|
||||||
children: [
|
|
||||||
...(icon !== undefined ? [MaterialIcon(icon, 'norm')] : []),
|
|
||||||
...(name !== undefined ? [Label({
|
|
||||||
className: 'txt txt-small',
|
|
||||||
label: name,
|
|
||||||
})] : []),
|
|
||||||
...(expandWidget ? [Box({ hexpand: true })] : []),
|
|
||||||
toggleButton,
|
|
||||||
]
|
|
||||||
});
|
|
||||||
const interactionWrapper = Button({
|
|
||||||
attribute: {
|
|
||||||
enabled: enabled,
|
|
||||||
toggle: (newValue) => {
|
|
||||||
enabled.value = !enabled.value;
|
|
||||||
onChange(interactionWrapper, enabled.value);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: widgetContent,
|
|
||||||
onClicked: (self) => self.attribute.toggle(self),
|
|
||||||
setup: (self) => {
|
|
||||||
setupCursorHover(self);
|
|
||||||
self.connect('pressed', () => { // mouse down
|
|
||||||
toggleIcon.toggleClassName('txt-poof', true);
|
|
||||||
toggleIcon.toggleClassName('switch-fg-true', false);
|
|
||||||
if (!enabled.value) toggleIcon.toggleClassName('switch-fg-toggling-false', true);
|
|
||||||
});
|
|
||||||
extraSetup(self)
|
|
||||||
},
|
|
||||||
...rest,
|
|
||||||
});
|
|
||||||
interactionWrapper.enabled = enabled;
|
|
||||||
return interactionWrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ConfigSegmentedSelection = ({
|
|
||||||
icon, name, desc = '',
|
|
||||||
options = [{ name: 'Option 1', value: 0 }, { name: 'Option 2', value: 1 }],
|
|
||||||
initIndex = 0,
|
|
||||||
onChange,
|
|
||||||
...rest
|
|
||||||
}) => {
|
|
||||||
let lastSelected = initIndex;
|
|
||||||
let value = options[initIndex].value;
|
|
||||||
const widget = Box({
|
|
||||||
tooltipText: desc,
|
|
||||||
className: 'segment-container',
|
|
||||||
// homogeneous: true,
|
|
||||||
children: options.map((option, id) => {
|
|
||||||
const selectedIcon = Revealer({
|
|
||||||
revealChild: id == initIndex,
|
|
||||||
transition: 'slide_right',
|
|
||||||
transitionDuration: userOptions.animations.durationSmall,
|
|
||||||
child: MaterialIcon('check', 'norm')
|
|
||||||
});
|
|
||||||
return Button({
|
|
||||||
setup: setupCursorHover,
|
|
||||||
className: `segment-btn ${id == initIndex ? 'segment-btn-enabled' : ''}`,
|
|
||||||
child: Box({
|
|
||||||
hpack: 'center',
|
|
||||||
className: 'spacing-h-5',
|
|
||||||
children: [
|
|
||||||
selectedIcon,
|
|
||||||
Label({
|
|
||||||
label: option.name,
|
|
||||||
})
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
onClicked: (self) => {
|
|
||||||
value = option.value;
|
|
||||||
const kids = widget.get_children();
|
|
||||||
kids[lastSelected].toggleClassName('segment-btn-enabled', false);
|
|
||||||
kids[lastSelected].get_children()[0].get_children()[0].revealChild = false;
|
|
||||||
lastSelected = id;
|
|
||||||
self.toggleClassName('segment-btn-enabled', true);
|
|
||||||
selectedIcon.revealChild = true;
|
|
||||||
onChange(option.value, option.name);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
...rest,
|
|
||||||
});
|
|
||||||
return widget;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ConfigMulipleSelection = ({
|
|
||||||
icon, name, desc = '',
|
|
||||||
optionsArr = [
|
|
||||||
[{ name: 'Option 1', value: 0 }, { name: 'Option 2', value: 1 }],
|
|
||||||
[{ name: 'Option 3', value: 0 }, { name: 'Option 4', value: 1 }],
|
|
||||||
],
|
|
||||||
initIndex = [0, 0],
|
|
||||||
onChange,
|
|
||||||
...rest
|
|
||||||
}) => {
|
|
||||||
let lastSelected = initIndex;
|
|
||||||
const widget = Box({
|
|
||||||
tooltipText: desc,
|
|
||||||
className: 'multipleselection-container spacing-v-3',
|
|
||||||
vertical: true,
|
|
||||||
children: optionsArr.map((options, grp) => Box({
|
|
||||||
className: 'spacing-h-5',
|
|
||||||
hpack: 'center',
|
|
||||||
children: options.map((option, id) => Button({
|
|
||||||
setup: setupCursorHover,
|
|
||||||
className: `multipleselection-btn ${id == initIndex[1] && grp == initIndex[0] ? 'multipleselection-btn-enabled' : ''}`,
|
|
||||||
label: option.name,
|
|
||||||
onClicked: (self) => {
|
|
||||||
const kidsg = widget.get_children();
|
|
||||||
const kids = kidsg.flatMap(widget => widget.get_children());
|
|
||||||
kids.forEach(kid => {
|
|
||||||
kid.toggleClassName('multipleselection-btn-enabled', false);
|
|
||||||
});
|
|
||||||
lastSelected = id;
|
|
||||||
self.toggleClassName('multipleselection-btn-enabled', true);
|
|
||||||
onChange(option.value, option.name);
|
|
||||||
}
|
|
||||||
})),
|
|
||||||
})),
|
|
||||||
...rest,
|
|
||||||
});
|
|
||||||
return widget;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ConfigGap = ({ vertical = true, size = 5, ...rest }) => Box({
|
|
||||||
className: `gap-${vertical ? 'v' : 'h'}-${size}`,
|
|
||||||
...rest,
|
|
||||||
})
|
|
||||||
|
|
||||||
export const ConfigSpinButton = ({
|
|
||||||
icon, name, desc = '', initValue,
|
|
||||||
minValue = 0, maxValue = 100, step = 1,
|
|
||||||
expandWidget = true,
|
|
||||||
onChange = () => { }, extraSetup = () => { },
|
|
||||||
...rest
|
|
||||||
}) => {
|
|
||||||
const value = Variable(initValue);
|
|
||||||
const spinButton = SpinButton({
|
|
||||||
className: 'spinbutton',
|
|
||||||
range: [minValue, maxValue],
|
|
||||||
increments: [step, step],
|
|
||||||
onValueChanged: ({ value: newValue }) => {
|
|
||||||
value.value = newValue;
|
|
||||||
onChange(spinButton, newValue);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
spinButton.value = value.value;
|
|
||||||
const widgetContent = Box({
|
|
||||||
tooltipText: desc,
|
|
||||||
className: 'txt spacing-h-5 configtoggle-box',
|
|
||||||
children: [
|
|
||||||
...(icon !== undefined ? [MaterialIcon(icon, 'norm')] : []),
|
|
||||||
...(name !== undefined ? [Label({
|
|
||||||
className: 'txt txt-small',
|
|
||||||
label: name,
|
|
||||||
})] : []),
|
|
||||||
...(expandWidget ? [Box({ hexpand: true })] : []),
|
|
||||||
spinButton,
|
|
||||||
],
|
|
||||||
setup: (self) => {
|
|
||||||
extraSetup(self);
|
|
||||||
},
|
|
||||||
...rest,
|
|
||||||
});
|
|
||||||
return widgetContent;
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
|
|
||||||
export const MaterialIcon = (icon, size, props = {}) => Widget.Label({
|
|
||||||
className: `icon-material txt-${size}`,
|
|
||||||
label: icon,
|
|
||||||
...props,
|
|
||||||
})
|
|
||||||
|
|
@ -1,462 +0,0 @@
|
||||||
// This file is for the actual widget for each single notification
|
|
||||||
const { GLib, Gdk, Gtk } = imports.gi;
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js'
|
|
||||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
|
|
||||||
const { Box, EventBox, Icon, Overlay, Label, Button, Revealer } = Widget;
|
|
||||||
import { MaterialIcon } from './materialicon.js';
|
|
||||||
import { setupCursorHover } from "../.widgetutils/cursorhover.js";
|
|
||||||
import { AnimatedCircProg } from "./cairo_circularprogress.js";
|
|
||||||
|
|
||||||
function guessMessageType(summary) {
|
|
||||||
const str = summary.toLowerCase();
|
|
||||||
if (str.includes('reboot')) return 'restart_alt';
|
|
||||||
if (str.includes('recording')) return 'screen_record';
|
|
||||||
if (str.includes('battery') || summary.includes('power')) return 'power';
|
|
||||||
if (str.includes('screenshot')) return 'screenshot_monitor';
|
|
||||||
if (str.includes('welcome')) return 'waving_hand';
|
|
||||||
if (str.includes('time')) return 'scheduleb';
|
|
||||||
if (str.includes('installed')) return 'download';
|
|
||||||
if (str.includes('update')) return 'update';
|
|
||||||
if (str.startsWith('file')) return 'folder_copy';
|
|
||||||
return 'chat';
|
|
||||||
}
|
|
||||||
|
|
||||||
function exists(widget) {
|
|
||||||
return widget !== null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const getFriendlyNotifTimeString = (timeObject) => {
|
|
||||||
const messageTime = GLib.DateTime.new_from_unix_local(timeObject);
|
|
||||||
const oneMinuteAgo = GLib.DateTime.new_now_local().add_seconds(-60);
|
|
||||||
if (messageTime.compare(oneMinuteAgo) > 0)
|
|
||||||
return getString('Now');
|
|
||||||
else if (messageTime.get_day_of_year() == GLib.DateTime.new_now_local().get_day_of_year())
|
|
||||||
return messageTime.format(userOptions.time.format);
|
|
||||||
else if (messageTime.get_day_of_year() == GLib.DateTime.new_now_local().get_day_of_year() - 1)
|
|
||||||
return getString('Yesterday');
|
|
||||||
else
|
|
||||||
return messageTime.format(userOptions.time.dateFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
const NotificationIcon = (notifObject) => {
|
|
||||||
// { appEntry, appIcon, image }, urgency = 'normal'
|
|
||||||
if (notifObject.image) {
|
|
||||||
return Box({
|
|
||||||
valign: Gtk.Align.CENTER,
|
|
||||||
hexpand: false,
|
|
||||||
className: 'notif-icon',
|
|
||||||
css: `
|
|
||||||
background-image: url("${notifObject.image}");
|
|
||||||
background-size: auto 100%;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center;
|
|
||||||
`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let icon = 'NO_ICON';
|
|
||||||
if (Utils.lookUpIcon(notifObject.appIcon))
|
|
||||||
icon = notifObject.appIcon;
|
|
||||||
if (Utils.lookUpIcon(notifObject.appEntry))
|
|
||||||
icon = notifObject.appEntry;
|
|
||||||
|
|
||||||
return Box({
|
|
||||||
vpack: 'center',
|
|
||||||
hexpand: false,
|
|
||||||
className: `notif-icon notif-icon-material-${notifObject.urgency}`,
|
|
||||||
homogeneous: true,
|
|
||||||
children: [
|
|
||||||
(icon != 'NO_ICON' ?
|
|
||||||
Icon({
|
|
||||||
vpack: 'center',
|
|
||||||
icon: icon,
|
|
||||||
})
|
|
||||||
:
|
|
||||||
MaterialIcon(`${notifObject.urgency == 'critical' ? 'release_alert' : guessMessageType(notifObject.summary.toLowerCase())}`, 'hugerass', {
|
|
||||||
hexpand: true,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
],
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ({
|
|
||||||
notifObject,
|
|
||||||
isPopup = false,
|
|
||||||
props = {},
|
|
||||||
} = {}) => {
|
|
||||||
const popupTimeout = notifObject.timeout || (notifObject.urgency == 'critical' ? 8000 : 3000);
|
|
||||||
const command = (isPopup ?
|
|
||||||
() => notifObject.dismiss() :
|
|
||||||
() => notifObject.close()
|
|
||||||
)
|
|
||||||
const destroyWithAnims = () => {
|
|
||||||
widget.sensitive = false;
|
|
||||||
notificationBox.setCss(middleClickClose);
|
|
||||||
Utils.timeout(userOptions.animations.durationSmall, () => {
|
|
||||||
if (wholeThing) wholeThing.revealChild = false;
|
|
||||||
}, wholeThing);
|
|
||||||
Utils.timeout(userOptions.animations.durationSmall * 2, () => {
|
|
||||||
command();
|
|
||||||
if (wholeThing) {
|
|
||||||
wholeThing.destroy();
|
|
||||||
wholeThing = null;
|
|
||||||
}
|
|
||||||
}, wholeThing);
|
|
||||||
}
|
|
||||||
const widget = EventBox({
|
|
||||||
onHover: (self) => {
|
|
||||||
self.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grab'));
|
|
||||||
if (!wholeThing.attribute.hovered)
|
|
||||||
wholeThing.attribute.hovered = true;
|
|
||||||
},
|
|
||||||
onHoverLost: (self) => {
|
|
||||||
self.window.set_cursor(null);
|
|
||||||
if (wholeThing.attribute.hovered)
|
|
||||||
wholeThing.attribute.hovered = false;
|
|
||||||
if (isPopup) {
|
|
||||||
command();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onMiddleClick: (self) => {
|
|
||||||
destroyWithAnims();
|
|
||||||
},
|
|
||||||
setup: (self) => {
|
|
||||||
self.on("button-press-event", () => {
|
|
||||||
wholeThing.attribute.held = true;
|
|
||||||
notificationContent.toggleClassName(`${isPopup ? 'popup-' : ''}notif-clicked-${notifObject.urgency}`, true);
|
|
||||||
Utils.timeout(800, () => {
|
|
||||||
if (wholeThing?.attribute.held) {
|
|
||||||
Utils.execAsync(['wl-copy', `${notifObject.body}`]).catch(print);
|
|
||||||
notifTextSummary.label = notifObject.summary + " (copied)";
|
|
||||||
Utils.timeout(3000, () => notifTextSummary.label = notifObject.summary)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}).on("button-release-event", () => {
|
|
||||||
wholeThing.attribute.held = false;
|
|
||||||
notificationContent.toggleClassName(`${isPopup ? 'popup-' : ''}notif-clicked-${notifObject.urgency}`, false);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let wholeThing = Revealer({
|
|
||||||
attribute: {
|
|
||||||
'close': undefined,
|
|
||||||
'destroyWithAnims': destroyWithAnims,
|
|
||||||
'dragging': false,
|
|
||||||
'held': false,
|
|
||||||
'hovered': false,
|
|
||||||
'id': notifObject.id,
|
|
||||||
},
|
|
||||||
revealChild: false,
|
|
||||||
transition: 'slide_down',
|
|
||||||
transitionDuration: userOptions.animations.durationLarge,
|
|
||||||
child: Box({ // Box to make sure css-based spacing works
|
|
||||||
homogeneous: true,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const display = Gdk.Display.get_default();
|
|
||||||
const notifTextPreview = Revealer({
|
|
||||||
transition: 'slide_down',
|
|
||||||
transitionDuration: userOptions.animations.durationSmall,
|
|
||||||
revealChild: true,
|
|
||||||
child: Label({
|
|
||||||
xalign: 0,
|
|
||||||
className: `txt-smallie notif-body-${notifObject.urgency}`,
|
|
||||||
useMarkup: true,
|
|
||||||
xalign: 0,
|
|
||||||
justify: Gtk.Justification.LEFT,
|
|
||||||
maxWidthChars: 1,
|
|
||||||
truncate: 'end',
|
|
||||||
label: notifObject.body.split("\n")[0],
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
const notifTextExpanded = Revealer({
|
|
||||||
transition: 'slide_up',
|
|
||||||
transitionDuration: userOptions.animations.durationSmall,
|
|
||||||
revealChild: false,
|
|
||||||
child: Box({
|
|
||||||
vertical: true,
|
|
||||||
className: 'spacing-v-10',
|
|
||||||
children: [
|
|
||||||
Label({
|
|
||||||
xalign: 0,
|
|
||||||
className: `txt-smallie notif-body-${notifObject.urgency}`,
|
|
||||||
useMarkup: true,
|
|
||||||
xalign: 0,
|
|
||||||
justify: Gtk.Justification.LEFT,
|
|
||||||
maxWidthChars: 1,
|
|
||||||
wrap: true,
|
|
||||||
label: notifObject.body,
|
|
||||||
}),
|
|
||||||
Box({
|
|
||||||
className: 'notif-actions spacing-h-5',
|
|
||||||
children: [
|
|
||||||
Button({
|
|
||||||
hexpand: true,
|
|
||||||
className: `notif-action notif-action-${notifObject.urgency}`,
|
|
||||||
onClicked: () => destroyWithAnims(),
|
|
||||||
setup: setupCursorHover,
|
|
||||||
child: Label({
|
|
||||||
label: getString('Close'),
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
...notifObject.actions.map(action => Widget.Button({
|
|
||||||
hexpand: true,
|
|
||||||
className: `notif-action notif-action-${notifObject.urgency}`,
|
|
||||||
onClicked: () => notifObject.invoke(action.id),
|
|
||||||
setup: setupCursorHover,
|
|
||||||
child: Label({
|
|
||||||
label: action.label,
|
|
||||||
}),
|
|
||||||
}))
|
|
||||||
],
|
|
||||||
})
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
const notifIcon = Box({
|
|
||||||
vpack: 'start',
|
|
||||||
homogeneous: true,
|
|
||||||
children: [
|
|
||||||
Overlay({
|
|
||||||
child: NotificationIcon(notifObject),
|
|
||||||
overlays: isPopup ? [AnimatedCircProg({
|
|
||||||
className: `notif-circprog-${notifObject.urgency}`,
|
|
||||||
vpack: 'center', hpack: 'center',
|
|
||||||
initFrom: (isPopup ? 100 : 0),
|
|
||||||
initTo: 0,
|
|
||||||
initAnimTime: popupTimeout,
|
|
||||||
})] : [],
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
const notifTextSummary = Label({
|
|
||||||
xalign: 0,
|
|
||||||
className: 'txt-small txt-semibold titlefont',
|
|
||||||
justify: Gtk.Justification.LEFT,
|
|
||||||
hexpand: true,
|
|
||||||
maxWidthChars: 1,
|
|
||||||
truncate: 'end',
|
|
||||||
ellipsize: 3,
|
|
||||||
useMarkup: notifObject.summary.startsWith('<'),
|
|
||||||
label: notifObject.summary,
|
|
||||||
});
|
|
||||||
const initTimeString = getFriendlyNotifTimeString(notifObject.time);
|
|
||||||
const notifTextBody = Label({
|
|
||||||
vpack: 'center',
|
|
||||||
justification: 'right',
|
|
||||||
className: 'txt-smaller txt-semibold',
|
|
||||||
label: initTimeString,
|
|
||||||
setup: initTimeString == 'Now' ? (self) => {
|
|
||||||
let id = Utils.timeout(60000, () => {
|
|
||||||
self.label = getFriendlyNotifTimeString(notifObject.time);
|
|
||||||
id = null;
|
|
||||||
});
|
|
||||||
self.connect('destroy', () => { if (id) GLib.source_remove(id) });
|
|
||||||
} : () => { },
|
|
||||||
});
|
|
||||||
const notifText = Box({
|
|
||||||
valign: Gtk.Align.CENTER,
|
|
||||||
vertical: true,
|
|
||||||
hexpand: true,
|
|
||||||
children: [
|
|
||||||
Box({
|
|
||||||
children: [
|
|
||||||
notifTextSummary,
|
|
||||||
notifTextBody,
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
notifTextPreview,
|
|
||||||
notifTextExpanded,
|
|
||||||
]
|
|
||||||
});
|
|
||||||
const notifExpandButton = Button({
|
|
||||||
vpack: 'start',
|
|
||||||
className: 'notif-expand-btn',
|
|
||||||
onClicked: (self) => {
|
|
||||||
if (notifTextPreview.revealChild) { // Expanding...
|
|
||||||
notifTextPreview.revealChild = false;
|
|
||||||
notifTextExpanded.revealChild = true;
|
|
||||||
self.child.label = 'expand_less';
|
|
||||||
expanded = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
notifTextPreview.revealChild = true;
|
|
||||||
notifTextExpanded.revealChild = false;
|
|
||||||
self.child.label = 'expand_more';
|
|
||||||
expanded = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: MaterialIcon('expand_more', 'norm', {
|
|
||||||
vpack: 'center',
|
|
||||||
}),
|
|
||||||
setup: setupCursorHover,
|
|
||||||
});
|
|
||||||
const notificationContent = Box({
|
|
||||||
...props,
|
|
||||||
className: `${isPopup ? 'popup-' : ''}notif-${notifObject.urgency} spacing-h-10`,
|
|
||||||
children: [
|
|
||||||
notifIcon,
|
|
||||||
Box({
|
|
||||||
className: 'spacing-h-5',
|
|
||||||
children: [
|
|
||||||
notifText,
|
|
||||||
notifExpandButton,
|
|
||||||
]
|
|
||||||
})
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
// Gesture stuff
|
|
||||||
const gesture = Gtk.GestureDrag.new(widget);
|
|
||||||
var initDirX = 0;
|
|
||||||
var initDirVertical = -1; // -1: unset, 0: horizontal, 1: vertical
|
|
||||||
var expanded = false;
|
|
||||||
// in px
|
|
||||||
const startMargin = 0;
|
|
||||||
const MOVE_THRESHOLD = 10;
|
|
||||||
const DRAG_CONFIRM_THRESHOLD = 100;
|
|
||||||
// in rem
|
|
||||||
const maxOffset = 10.227;
|
|
||||||
const endMargin = 20.455;
|
|
||||||
const disappearHeight = 6.818;
|
|
||||||
const leftAnim1 = `transition: ${userOptions.animations.durationSmall}ms cubic-bezier(0.05, 0.7, 0.1, 1);
|
|
||||||
margin-left: -${Number(maxOffset + endMargin)}rem;
|
|
||||||
margin-right: ${Number(maxOffset + endMargin)}rem;
|
|
||||||
opacity: 0;`;
|
|
||||||
|
|
||||||
const rightAnim1 = `transition: ${userOptions.animations.durationSmall}ms cubic-bezier(0.05, 0.7, 0.1, 1);
|
|
||||||
margin-left: ${Number(maxOffset + endMargin)}rem;
|
|
||||||
margin-right: -${Number(maxOffset + endMargin)}rem;
|
|
||||||
opacity: 0;`;
|
|
||||||
|
|
||||||
const middleClickClose = `transition: ${userOptions.animations.durationSmall}ms cubic-bezier(0.85, 0, 0.15, 1);
|
|
||||||
margin-left: ${Number(maxOffset + endMargin)}rem;
|
|
||||||
margin-right: -${Number(maxOffset + endMargin)}rem;
|
|
||||||
opacity: 0;`;
|
|
||||||
|
|
||||||
const notificationBox = Box({
|
|
||||||
attribute: {
|
|
||||||
'leftAnim1': leftAnim1,
|
|
||||||
'rightAnim1': rightAnim1,
|
|
||||||
'middleClickClose': middleClickClose,
|
|
||||||
'ready': false,
|
|
||||||
},
|
|
||||||
homogeneous: true,
|
|
||||||
children: [notificationContent],
|
|
||||||
setup: (self) => self
|
|
||||||
.hook(gesture, self => {
|
|
||||||
var offset_x = gesture.get_offset()[1];
|
|
||||||
var offset_y = gesture.get_offset()[2];
|
|
||||||
// Which dir?
|
|
||||||
if (initDirVertical == -1) {
|
|
||||||
if (Math.abs(offset_y) > MOVE_THRESHOLD)
|
|
||||||
initDirVertical = 1;
|
|
||||||
if (initDirX == 0 && Math.abs(offset_x) > MOVE_THRESHOLD) {
|
|
||||||
initDirVertical = 0;
|
|
||||||
initDirX = (offset_x > 0 ? 1 : -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Horizontal drag
|
|
||||||
if (initDirVertical == 0 && offset_x > MOVE_THRESHOLD) {
|
|
||||||
if (initDirX < 0)
|
|
||||||
self.setCss(`margin-left: 0px; margin-right: 0px;`);
|
|
||||||
else
|
|
||||||
self.setCss(`
|
|
||||||
margin-left: ${Number(offset_x + startMargin - MOVE_THRESHOLD)}px;
|
|
||||||
margin-right: -${Number(offset_x + startMargin - MOVE_THRESHOLD)}px;
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
else if (initDirVertical == 0 && offset_x < -MOVE_THRESHOLD) {
|
|
||||||
if (initDirX > 0)
|
|
||||||
self.setCss(`margin-left: 0px; margin-right: 0px;`);
|
|
||||||
else {
|
|
||||||
offset_x = Math.abs(offset_x);
|
|
||||||
self.setCss(`
|
|
||||||
margin-right: ${Number(offset_x + startMargin - MOVE_THRESHOLD)}px;
|
|
||||||
margin-left: -${Number(offset_x + startMargin - MOVE_THRESHOLD)}px;
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Update dragging
|
|
||||||
wholeThing.attribute.dragging = Math.abs(offset_x) > MOVE_THRESHOLD;
|
|
||||||
if (Math.abs(offset_x) > MOVE_THRESHOLD ||
|
|
||||||
Math.abs(offset_y) > MOVE_THRESHOLD) wholeThing.attribute.held = false;
|
|
||||||
widget.window?.set_cursor(Gdk.Cursor.new_from_name(display, 'grabbing'));
|
|
||||||
// Vertical drag
|
|
||||||
if (initDirVertical == 1 && offset_y > MOVE_THRESHOLD && !expanded) {
|
|
||||||
notifTextPreview.revealChild = false;
|
|
||||||
notifTextExpanded.revealChild = true;
|
|
||||||
expanded = true;
|
|
||||||
notifExpandButton.child.label = 'expand_less';
|
|
||||||
}
|
|
||||||
else if (initDirVertical == 1 && offset_y < -MOVE_THRESHOLD && expanded) {
|
|
||||||
notifTextPreview.revealChild = true;
|
|
||||||
notifTextExpanded.revealChild = false;
|
|
||||||
expanded = false;
|
|
||||||
notifExpandButton.child.label = 'expand_more';
|
|
||||||
}
|
|
||||||
|
|
||||||
}, 'drag-update')
|
|
||||||
.hook(gesture, self => {
|
|
||||||
if (!self.attribute.ready) {
|
|
||||||
wholeThing.revealChild = true;
|
|
||||||
self.attribute.ready = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const offset_h = gesture.get_offset()[1];
|
|
||||||
|
|
||||||
if (Math.abs(offset_h) > DRAG_CONFIRM_THRESHOLD && offset_h * initDirX > 0) {
|
|
||||||
if (offset_h > 0) {
|
|
||||||
self.setCss(rightAnim1);
|
|
||||||
widget.sensitive = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.setCss(leftAnim1);
|
|
||||||
widget.sensitive = false;
|
|
||||||
}
|
|
||||||
Utils.timeout(userOptions.animations.durationSmall, () => {
|
|
||||||
if (wholeThing) wholeThing.revealChild = false;
|
|
||||||
}, wholeThing);
|
|
||||||
Utils.timeout(userOptions.animations.durationSmall * 2, () => {
|
|
||||||
command();
|
|
||||||
if (wholeThing) {
|
|
||||||
wholeThing.destroy();
|
|
||||||
wholeThing = null;
|
|
||||||
}
|
|
||||||
}, wholeThing);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.setCss(`transition: margin 200ms cubic-bezier(0.05, 0.7, 0.1, 1), opacity 200ms cubic-bezier(0.05, 0.7, 0.1, 1);
|
|
||||||
margin-left: ${startMargin}px;
|
|
||||||
margin-right: ${startMargin}px;
|
|
||||||
margin-bottom: unset; margin-top: unset;
|
|
||||||
opacity: 1;`);
|
|
||||||
if (widget.window)
|
|
||||||
widget.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grab'));
|
|
||||||
|
|
||||||
wholeThing.attribute.dragging = false;
|
|
||||||
}
|
|
||||||
initDirX = 0;
|
|
||||||
initDirVertical = -1;
|
|
||||||
}, 'drag-end')
|
|
||||||
,
|
|
||||||
})
|
|
||||||
widget.add(notificationBox);
|
|
||||||
wholeThing.child.children = [widget];
|
|
||||||
if (isPopup) Utils.timeout(popupTimeout, () => {
|
|
||||||
if (wholeThing) {
|
|
||||||
wholeThing.revealChild = false;
|
|
||||||
Utils.timeout(userOptions.animations.durationSmall, () => {
|
|
||||||
if (wholeThing) {
|
|
||||||
wholeThing.destroy();
|
|
||||||
wholeThing = null;
|
|
||||||
}
|
|
||||||
command();
|
|
||||||
}, wholeThing);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return wholeThing;
|
|
||||||
}
|
|
||||||
|
|
@ -1,306 +0,0 @@
|
||||||
import App from 'resource:///com/github/Aylur/ags/app.js';
|
|
||||||
import Audio from 'resource:///com/github/Aylur/ags/service/audio.js';
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
|
|
||||||
|
|
||||||
import { MaterialIcon } from './materialicon.js';
|
|
||||||
import Bluetooth from 'resource:///com/github/Aylur/ags/service/bluetooth.js';
|
|
||||||
import Network from 'resource:///com/github/Aylur/ags/service/network.js';
|
|
||||||
import Notifications from 'resource:///com/github/Aylur/ags/service/notifications.js';
|
|
||||||
import { languages } from './statusicons_languages.js';
|
|
||||||
|
|
||||||
// A guessing func to try to support langs not listed in data/languages.js
|
|
||||||
function isLanguageMatch(abbreviation, word) {
|
|
||||||
const lowerAbbreviation = abbreviation.toLowerCase();
|
|
||||||
const lowerWord = word.toLowerCase();
|
|
||||||
let j = 0;
|
|
||||||
for (let i = 0; i < lowerWord.length; i++) {
|
|
||||||
if (lowerWord[i] === lowerAbbreviation[j]) {
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
if (j === lowerAbbreviation.length) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const MicMuteIndicator = () => Widget.Revealer({
|
|
||||||
transition: 'slide_left',
|
|
||||||
transitionDuration: userOptions.animations.durationSmall,
|
|
||||||
revealChild: false,
|
|
||||||
setup: (self) => self.hook(Audio, (self) => {
|
|
||||||
self.revealChild = Audio.microphone?.stream?.isMuted;
|
|
||||||
}),
|
|
||||||
child: MaterialIcon('mic_off', 'norm'),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const NotificationIndicator = (notifCenterName = 'sideright') => {
|
|
||||||
const widget = Widget.Revealer({
|
|
||||||
transition: 'slide_left',
|
|
||||||
transitionDuration: userOptions.animations.durationSmall,
|
|
||||||
revealChild: false,
|
|
||||||
setup: (self) => self
|
|
||||||
.hook(Notifications, (self, id) => {
|
|
||||||
if (!id || Notifications.dnd) return;
|
|
||||||
if (!Notifications.getNotification(id)) return;
|
|
||||||
self.revealChild = true;
|
|
||||||
}, 'notified')
|
|
||||||
.hook(App, (self, currentName, visible) => {
|
|
||||||
if (visible && currentName === notifCenterName) {
|
|
||||||
self.revealChild = false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
,
|
|
||||||
child: Widget.Box({
|
|
||||||
children: [
|
|
||||||
MaterialIcon('notifications', 'norm'),
|
|
||||||
Widget.Label({
|
|
||||||
className: 'txt-small titlefont',
|
|
||||||
attribute: {
|
|
||||||
unreadCount: 0,
|
|
||||||
update: (self) => self.label = `${self.attribute.unreadCount}`,
|
|
||||||
},
|
|
||||||
setup: (self) => self
|
|
||||||
.hook(Notifications, (self, id) => {
|
|
||||||
if (!id || Notifications.dnd) return;
|
|
||||||
if (!Notifications.getNotification(id)) return;
|
|
||||||
self.attribute.unreadCount++;
|
|
||||||
self.attribute.update(self);
|
|
||||||
}, 'notified')
|
|
||||||
.hook(App, (self, currentName, visible) => {
|
|
||||||
if (visible && currentName === notifCenterName) {
|
|
||||||
self.attribute.unreadCount = 0;
|
|
||||||
self.attribute.update(self);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
,
|
|
||||||
})
|
|
||||||
]
|
|
||||||
})
|
|
||||||
});
|
|
||||||
return widget;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const BluetoothIndicator = () => Widget.Stack({
|
|
||||||
transition: 'slide_up_down',
|
|
||||||
transitionDuration: userOptions.animations.durationSmall,
|
|
||||||
children: {
|
|
||||||
'false': Widget.Label({ className: 'txt-norm icon-material', label: 'bluetooth_disabled' }),
|
|
||||||
'true': Widget.Label({ className: 'txt-norm icon-material', label: 'bluetooth' }),
|
|
||||||
},
|
|
||||||
setup: (self) => self
|
|
||||||
.hook(Bluetooth, stack => {
|
|
||||||
stack.shown = String(Bluetooth.enabled);
|
|
||||||
})
|
|
||||||
,
|
|
||||||
});
|
|
||||||
|
|
||||||
const BluetoothDevices = () => Widget.Box({
|
|
||||||
className: 'spacing-h-5',
|
|
||||||
setup: self => self.hook(Bluetooth, self => {
|
|
||||||
self.children = Bluetooth.connected_devices.map((device) => {
|
|
||||||
return Widget.Box({
|
|
||||||
className: 'bar-bluetooth-device spacing-h-5',
|
|
||||||
vpack: 'center',
|
|
||||||
tooltipText: device.name,
|
|
||||||
children: [
|
|
||||||
Widget.Icon(`${device.iconName}-symbolic`),
|
|
||||||
...(device.batteryPercentage ? [Widget.Label({
|
|
||||||
className: 'txt-smallie',
|
|
||||||
label: `${device.batteryPercentage}`,
|
|
||||||
setup: (self) => {
|
|
||||||
self.hook(device, (self) => {
|
|
||||||
self.label = `${device.batteryPercentage}`;
|
|
||||||
}, 'notify::batteryPercentage')
|
|
||||||
}
|
|
||||||
})] : []),
|
|
||||||
]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
self.visible = Bluetooth.connected_devices.length > 0;
|
|
||||||
}, 'notify::connected-devices'),
|
|
||||||
})
|
|
||||||
|
|
||||||
const NetworkWiredIndicator = () => Widget.Stack({
|
|
||||||
transition: 'slide_up_down',
|
|
||||||
transitionDuration: userOptions.animations.durationSmall,
|
|
||||||
children: {
|
|
||||||
'fallback': SimpleNetworkIndicator(),
|
|
||||||
'unknown': Widget.Label({ className: 'txt-norm icon-material', label: 'wifi_off' }),
|
|
||||||
'disconnected': Widget.Label({ className: 'txt-norm icon-material', label: 'signal_wifi_off' }),
|
|
||||||
'connected': Widget.Label({ className: 'txt-norm icon-material', label: 'lan' }),
|
|
||||||
'connecting': Widget.Label({ className: 'txt-norm icon-material', label: 'settings_ethernet' }),
|
|
||||||
},
|
|
||||||
setup: (self) => self.hook(Network, stack => {
|
|
||||||
if (!Network.wired)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const { internet } = Network.wired;
|
|
||||||
if (['connecting', 'connected'].includes(internet))
|
|
||||||
stack.shown = internet;
|
|
||||||
else if (Network.connectivity !== 'full')
|
|
||||||
stack.shown = 'disconnected';
|
|
||||||
else
|
|
||||||
stack.shown = 'fallback';
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const SimpleNetworkIndicator = () => Widget.Icon({
|
|
||||||
setup: (self) => self.hook(Network, self => {
|
|
||||||
const icon = Network[Network.primary || 'wifi']?.iconName;
|
|
||||||
self.icon = icon || '';
|
|
||||||
self.visible = icon;
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const NetworkWifiIndicator = () => Widget.Stack({
|
|
||||||
transition: 'slide_up_down',
|
|
||||||
transitionDuration: userOptions.animations.durationSmall,
|
|
||||||
children: {
|
|
||||||
'disabled': Widget.Label({ className: 'txt-norm icon-material', label: 'wifi_off' }),
|
|
||||||
'disconnected': Widget.Label({ className: 'txt-norm icon-material', label: 'signal_wifi_off' }),
|
|
||||||
'connecting': Widget.Label({ className: 'txt-norm icon-material', label: 'settings_ethernet' }),
|
|
||||||
'0': Widget.Label({ className: 'txt-norm icon-material', label: 'signal_wifi_0_bar' }),
|
|
||||||
'1': Widget.Label({ className: 'txt-norm icon-material', label: 'network_wifi_1_bar' }),
|
|
||||||
'2': Widget.Label({ className: 'txt-norm icon-material', label: 'network_wifi_2_bar' }),
|
|
||||||
'3': Widget.Label({ className: 'txt-norm icon-material', label: 'network_wifi_3_bar' }),
|
|
||||||
'4': Widget.Label({ className: 'txt-norm icon-material', label: 'signal_wifi_4_bar' }),
|
|
||||||
},
|
|
||||||
setup: (self) => self.hook(Network, (stack) => {
|
|
||||||
if (!Network.wifi) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (Network.wifi.internet == 'connected') {
|
|
||||||
stack.shown = String(Math.ceil(Network.wifi.strength / 25));
|
|
||||||
}
|
|
||||||
else if (["disconnected", "connecting"].includes(Network.wifi.internet)) {
|
|
||||||
stack.shown = Network.wifi.internet;
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const NetworkIndicator = () => Widget.Stack({
|
|
||||||
transition: 'slide_up_down',
|
|
||||||
transitionDuration: userOptions.animations.durationSmall,
|
|
||||||
children: {
|
|
||||||
'fallback': SimpleNetworkIndicator(),
|
|
||||||
'wifi': NetworkWifiIndicator(),
|
|
||||||
'wired': NetworkWiredIndicator(),
|
|
||||||
},
|
|
||||||
setup: (self) => self.hook(Network, stack => {
|
|
||||||
if (!Network.primary) {
|
|
||||||
stack.shown = 'wifi';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const primary = Network.primary || 'fallback';
|
|
||||||
if (['wifi', 'wired'].includes(primary))
|
|
||||||
stack.shown = primary;
|
|
||||||
else
|
|
||||||
stack.shown = 'fallback';
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const HyprlandXkbKeyboardLayout = async ({ useFlag } = {}) => {
|
|
||||||
try {
|
|
||||||
const Hyprland = (await import('resource:///com/github/Aylur/ags/service/hyprland.js')).default;
|
|
||||||
var languageStackArray = [];
|
|
||||||
|
|
||||||
const updateCurrentKeyboards = () => {
|
|
||||||
var initLangs = [];
|
|
||||||
JSON.parse(Utils.exec('hyprctl -j devices')).keyboards
|
|
||||||
.forEach(keyboard => {
|
|
||||||
initLangs.push(...keyboard.layout.split(',').map(lang => lang.trim()));
|
|
||||||
});
|
|
||||||
initLangs = [...new Set(initLangs)];
|
|
||||||
languageStackArray = Array.from({ length: initLangs.length }, (_, i) => {
|
|
||||||
const lang = languages.find(lang => lang.layout == initLangs[i]);
|
|
||||||
// if (!lang) return [
|
|
||||||
// initLangs[i],
|
|
||||||
// Widget.Label({ label: initLangs[i] })
|
|
||||||
// ];
|
|
||||||
// return [
|
|
||||||
// lang.layout,
|
|
||||||
// Widget.Label({ label: (useFlag ? lang.flag : lang.layout) })
|
|
||||||
// ];
|
|
||||||
// Object
|
|
||||||
if (!lang) return {
|
|
||||||
[initLangs[i]]: Widget.Label({ label: initLangs[i] })
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
[lang.layout]: Widget.Label({ label: (useFlag ? lang.flag : lang.layout) })
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
updateCurrentKeyboards();
|
|
||||||
const widgetRevealer = Widget.Revealer({
|
|
||||||
transition: 'slide_left',
|
|
||||||
transitionDuration: userOptions.animations.durationSmall,
|
|
||||||
revealChild: languageStackArray.length > 1,
|
|
||||||
});
|
|
||||||
const widgetKids = {
|
|
||||||
...languageStackArray.reduce((obj, lang) => {
|
|
||||||
return { ...obj, ...lang };
|
|
||||||
}, {}),
|
|
||||||
'undef': Widget.Label({ label: '?' }),
|
|
||||||
}
|
|
||||||
const widgetContent = Widget.Stack({
|
|
||||||
transition: 'slide_up_down',
|
|
||||||
transitionDuration: userOptions.animations.durationSmall,
|
|
||||||
children: widgetKids,
|
|
||||||
setup: (self) => self.hook(Hyprland, (stack, kbName, layoutName) => {
|
|
||||||
if (!kbName) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var lang = languages.find(lang => layoutName.includes(lang.name));
|
|
||||||
if (lang) {
|
|
||||||
widgetContent.shown = lang.layout;
|
|
||||||
}
|
|
||||||
else { // Attempt to support langs not listed
|
|
||||||
lang = languageStackArray.find(lang => isLanguageMatch(lang[0], layoutName));
|
|
||||||
if (!lang) stack.shown = 'undef';
|
|
||||||
else stack.shown = lang[0];
|
|
||||||
}
|
|
||||||
}, 'keyboard-layout'),
|
|
||||||
});
|
|
||||||
widgetRevealer.child = widgetContent;
|
|
||||||
return widgetRevealer;
|
|
||||||
} catch {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const OptionalKeyboardLayout = async () => {
|
|
||||||
try {
|
|
||||||
return await HyprlandXkbKeyboardLayout({ useFlag: userOptions.appearance.keyboardUseFlag });
|
|
||||||
} catch {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const createKeyboardLayoutInstances = async () => {
|
|
||||||
const Hyprland = (await import('resource:///com/github/Aylur/ags/service/hyprland.js')).default;
|
|
||||||
const monitorsCount = Hyprland.monitors.length
|
|
||||||
const instances = await Promise.all(
|
|
||||||
Array.from({ length: monitorsCount }, () => OptionalKeyboardLayout())
|
|
||||||
);
|
|
||||||
|
|
||||||
return instances;
|
|
||||||
};
|
|
||||||
const optionalKeyboardLayoutInstances = await createKeyboardLayoutInstances()
|
|
||||||
|
|
||||||
export const StatusIcons = (props = {}, monitor = 0) => Widget.Box({
|
|
||||||
...props,
|
|
||||||
child: Widget.Box({
|
|
||||||
className: 'spacing-h-15',
|
|
||||||
children: [
|
|
||||||
MicMuteIndicator(),
|
|
||||||
optionalKeyboardLayoutInstances[monitor],
|
|
||||||
NotificationIndicator(),
|
|
||||||
NetworkIndicator(),
|
|
||||||
Widget.Box({
|
|
||||||
className: 'spacing-h-5',
|
|
||||||
children: [BluetoothIndicator(), BluetoothDevices()]
|
|
||||||
})
|
|
||||||
]
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
// For keyboard layout in statusicons.js
|
|
||||||
// This list is not exhaustive. It just includes known/possible languages of users of my dotfiles
|
|
||||||
// Add your language here if you use multi-lang xkb input. Else, ignore
|
|
||||||
// Note that something like "French (Canada)" should go before "French"
|
|
||||||
// and "English (US)" should go before "English"
|
|
||||||
export const languages = [
|
|
||||||
{
|
|
||||||
layout: 'us',
|
|
||||||
name: 'English (US)',
|
|
||||||
flag: '🇺🇸'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
layout: 'ru',
|
|
||||||
name: 'Russian',
|
|
||||||
flag: '🇷🇺',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
layout: 'pl',
|
|
||||||
name: 'Polish',
|
|
||||||
flag: '🇷🇵🇵🇱',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
layout: 'ro',
|
|
||||||
name: 'Romanian',
|
|
||||||
flag: '🇷🇴',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
layout: 'ca',
|
|
||||||
name: 'French (Canada)',
|
|
||||||
flag: '🇫🇷',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
layout: 'fr',
|
|
||||||
name: 'French',
|
|
||||||
flag: '🇫🇷',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
layout: 'tr',
|
|
||||||
name: 'Turkish',
|
|
||||||
flag: '🇹🇷',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
layout: 'jp',
|
|
||||||
name: 'Japanese',
|
|
||||||
flag: '🇯🇵',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
layout: 'cn',
|
|
||||||
name: 'Chinese',
|
|
||||||
flag: '🇨🇳',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
layout: 'vn',
|
|
||||||
name: 'Vietnamese',
|
|
||||||
flag: '🇻🇳',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
layout: 'undef',
|
|
||||||
name: 'Undefined',
|
|
||||||
flag: '🧐',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
@ -1,279 +0,0 @@
|
||||||
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
const { Box, Button, EventBox, Label, Overlay, Stack } = Widget;
|
|
||||||
import { MaterialIcon } from './materialicon.js';
|
|
||||||
import { NavigationIndicator } from './cairo_navigationindicator.js';
|
|
||||||
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
|
|
||||||
import { DoubleRevealer } from '../.widgethacks/advancedrevealers.js';
|
|
||||||
|
|
||||||
export const TabContainer = ({ icons, names, children, className = '', setup = () => { }, ...rest }) => {
|
|
||||||
const shownIndex = Variable(0);
|
|
||||||
let previousShownIndex = 0;
|
|
||||||
const count = Math.min(icons.length, names.length, children.length);
|
|
||||||
const tabs = Box({
|
|
||||||
homogeneous: true,
|
|
||||||
children: Array.from({ length: count }, (_, i) => Button({ // Tab button
|
|
||||||
className: 'tab-btn',
|
|
||||||
onClicked: () => shownIndex.value = i,
|
|
||||||
setup: setupCursorHover,
|
|
||||||
child: Box({
|
|
||||||
hpack: 'center',
|
|
||||||
vpack: 'center',
|
|
||||||
className: 'spacing-h-5 txt-small',
|
|
||||||
children: [
|
|
||||||
MaterialIcon(icons[i], 'norm'),
|
|
||||||
Label({
|
|
||||||
label: names[i],
|
|
||||||
})
|
|
||||||
]
|
|
||||||
})
|
|
||||||
})),
|
|
||||||
setup: (self) => self.hook(shownIndex, (self) => {
|
|
||||||
self.children[previousShownIndex].toggleClassName('tab-btn-active', false);
|
|
||||||
self.children[shownIndex.value].toggleClassName('tab-btn-active', true);
|
|
||||||
previousShownIndex = shownIndex.value;
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
const tabIndicatorLine = Box({
|
|
||||||
vertical: true,
|
|
||||||
homogeneous: true,
|
|
||||||
setup: (self) => self.hook(shownIndex, (self) => {
|
|
||||||
self.children[0].css = `font-size: ${shownIndex.value}px;`;
|
|
||||||
}),
|
|
||||||
children: [NavigationIndicator({
|
|
||||||
className: 'tab-indicator',
|
|
||||||
count: count,
|
|
||||||
css: `font-size: ${shownIndex.value}px;`,
|
|
||||||
})],
|
|
||||||
});
|
|
||||||
const tabSection = Box({
|
|
||||||
homogeneous: true,
|
|
||||||
children: [EventBox({
|
|
||||||
onScrollUp: () => mainBox.prevTab(),
|
|
||||||
onScrollDown: () => mainBox.nextTab(),
|
|
||||||
child: Box({
|
|
||||||
vertical: true,
|
|
||||||
children: [
|
|
||||||
tabs,
|
|
||||||
tabIndicatorLine
|
|
||||||
]
|
|
||||||
})
|
|
||||||
})]
|
|
||||||
});
|
|
||||||
const contentStack = Stack({
|
|
||||||
transition: 'slide_left_right',
|
|
||||||
children: children.reduce((acc, currentValue, index) => {
|
|
||||||
acc[index] = currentValue;
|
|
||||||
return acc;
|
|
||||||
}, {}),
|
|
||||||
setup: (self) => self.hook(shownIndex, (self) => {
|
|
||||||
self.shown = `${shownIndex.value}`;
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
const mainBox = Box({
|
|
||||||
attribute: {
|
|
||||||
children: children,
|
|
||||||
shown: shownIndex,
|
|
||||||
names: names,
|
|
||||||
},
|
|
||||||
vertical: true,
|
|
||||||
className: `spacing-v-5 ${className}`,
|
|
||||||
setup: (self) => {
|
|
||||||
self.pack_start(tabSection, false, false, 0);
|
|
||||||
self.pack_end(contentStack, true, true, 0);
|
|
||||||
setup(self);
|
|
||||||
},
|
|
||||||
...rest,
|
|
||||||
});
|
|
||||||
mainBox.nextTab = () => shownIndex.value = Math.min(shownIndex.value + 1, count - 1);
|
|
||||||
mainBox.prevTab = () => shownIndex.value = Math.max(shownIndex.value - 1, 0);
|
|
||||||
mainBox.cycleTab = () => shownIndex.value = (shownIndex.value + 1) % count;
|
|
||||||
|
|
||||||
return mainBox;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export const IconTabContainer = ({
|
|
||||||
iconWidgets, names, children, className = '',
|
|
||||||
setup = () => { }, onChange = () => { },
|
|
||||||
tabsHpack = 'center', tabSwitcherClassName = '',
|
|
||||||
...rest
|
|
||||||
}) => {
|
|
||||||
const shownIndex = Variable(0);
|
|
||||||
let previousShownIndex = 0;
|
|
||||||
const count = Math.min(iconWidgets.length, names.length, children.length);
|
|
||||||
const tabs = Box({
|
|
||||||
hpack: tabsHpack,
|
|
||||||
className: `spacing-h-5 ${tabSwitcherClassName}`,
|
|
||||||
children: iconWidgets.map((icon, i) => Button({
|
|
||||||
className: 'tab-icon',
|
|
||||||
tooltipText: names[i],
|
|
||||||
child: icon,
|
|
||||||
setup: setupCursorHover,
|
|
||||||
onClicked: () => shownIndex.value = i,
|
|
||||||
})),
|
|
||||||
setup: (self) => self.hook(shownIndex, (self) => {
|
|
||||||
self.children[previousShownIndex].toggleClassName('tab-icon-active', false);
|
|
||||||
self.children[shownIndex.value].toggleClassName('tab-icon-active', true);
|
|
||||||
previousShownIndex = shownIndex.value;
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
const tabSection = Box({
|
|
||||||
homogeneous: true,
|
|
||||||
children: [EventBox({
|
|
||||||
onScrollUp: () => mainBox.prevTab(),
|
|
||||||
onScrollDown: () => mainBox.nextTab(),
|
|
||||||
child: Box({
|
|
||||||
vertical: true,
|
|
||||||
hexpand: true,
|
|
||||||
children: [
|
|
||||||
tabs,
|
|
||||||
]
|
|
||||||
})
|
|
||||||
})]
|
|
||||||
});
|
|
||||||
const contentStack = Stack({
|
|
||||||
transition: 'slide_left_right',
|
|
||||||
children: children.reduce((acc, currentValue, index) => {
|
|
||||||
acc[index] = currentValue;
|
|
||||||
return acc;
|
|
||||||
}, {}),
|
|
||||||
setup: (self) => self.hook(shownIndex, (self) => {
|
|
||||||
self.shown = `${shownIndex.value}`;
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
const mainBox = Box({
|
|
||||||
attribute: {
|
|
||||||
children: children,
|
|
||||||
shown: shownIndex,
|
|
||||||
names: names,
|
|
||||||
},
|
|
||||||
vertical: true,
|
|
||||||
className: `spacing-v-5 ${className}`,
|
|
||||||
setup: (self) => {
|
|
||||||
self.pack_start(tabSection, false, false, 0);
|
|
||||||
self.pack_end(contentStack, true, true, 0);
|
|
||||||
setup(self);
|
|
||||||
self.hook(shownIndex, (self) => onChange(self, shownIndex.value));
|
|
||||||
},
|
|
||||||
...rest,
|
|
||||||
});
|
|
||||||
mainBox.nextTab = () => shownIndex.value = Math.min(shownIndex.value + 1, count - 1);
|
|
||||||
mainBox.prevTab = () => shownIndex.value = Math.max(shownIndex.value - 1, 0);
|
|
||||||
mainBox.cycleTab = () => shownIndex.value = (shownIndex.value + 1) % count;
|
|
||||||
mainBox.shown = shownIndex;
|
|
||||||
|
|
||||||
return mainBox;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ExpandingIconTabContainer = ({
|
|
||||||
icons, names, children, className = '',
|
|
||||||
setup = () => { }, onChange = () => { },
|
|
||||||
tabsHpack = 'center', tabSwitcherClassName = '',
|
|
||||||
transitionDuration = userOptions.animations.durationLarge,
|
|
||||||
...rest
|
|
||||||
}) => {
|
|
||||||
const shownIndex = Variable(0);
|
|
||||||
let previousShownIndex = 0;
|
|
||||||
const count = Math.min(icons.length, names.length, children.length);
|
|
||||||
const tabs = Box({
|
|
||||||
hpack: tabsHpack,
|
|
||||||
className: `spacing-h-5 ${tabSwitcherClassName}`,
|
|
||||||
children: icons.map((icon, i) => {
|
|
||||||
const tabIcon = MaterialIcon(icon, 'norm', { hexpand: true });
|
|
||||||
const tabName = DoubleRevealer({
|
|
||||||
transition1: 'slide_right',
|
|
||||||
transition2: 'crossfade',
|
|
||||||
duration1: 0,
|
|
||||||
duration2: 0,
|
|
||||||
// duration1: userOptions.animations.durationSmall,
|
|
||||||
// duration2: userOptions.animations.durationSmall,
|
|
||||||
child: Label({
|
|
||||||
className: 'margin-left-5 txt-small',
|
|
||||||
label: names[i],
|
|
||||||
}),
|
|
||||||
revealChild: i === shownIndex.value,
|
|
||||||
})
|
|
||||||
const button = Button({
|
|
||||||
className: 'tab-icon-expandable',
|
|
||||||
tooltipText: names[i],
|
|
||||||
child: Box({
|
|
||||||
homogeneous: true,
|
|
||||||
children: [Box({
|
|
||||||
hpack: 'center',
|
|
||||||
children: [
|
|
||||||
tabIcon,
|
|
||||||
tabName,
|
|
||||||
]
|
|
||||||
})],
|
|
||||||
}),
|
|
||||||
setup: setupCursorHover,
|
|
||||||
onClicked: () => shownIndex.value = i,
|
|
||||||
});
|
|
||||||
button.toggleFocus = (value) => {
|
|
||||||
tabIcon.hexpand = !value;
|
|
||||||
button.toggleClassName('tab-icon-expandable-active', value);
|
|
||||||
tabName.toggleRevealChild(value);
|
|
||||||
}
|
|
||||||
return button;
|
|
||||||
}),
|
|
||||||
setup: (self) => self.hook(shownIndex, (self) => {
|
|
||||||
self.children[previousShownIndex].toggleFocus(false);
|
|
||||||
self.children[shownIndex.value].toggleFocus(true);
|
|
||||||
previousShownIndex = shownIndex.value;
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
const tabSection = Box({
|
|
||||||
homogeneous: true,
|
|
||||||
children: [EventBox({
|
|
||||||
onScrollUp: () => mainBox.prevTab(),
|
|
||||||
onScrollDown: () => mainBox.nextTab(),
|
|
||||||
child: Box({
|
|
||||||
vertical: true,
|
|
||||||
hexpand: true,
|
|
||||||
children: [
|
|
||||||
tabs,
|
|
||||||
]
|
|
||||||
})
|
|
||||||
})]
|
|
||||||
});
|
|
||||||
const contentStack = Stack({
|
|
||||||
transition: 'slide_left_right',
|
|
||||||
transitionDuration: transitionDuration,
|
|
||||||
children: children.reduce((acc, currentValue, index) => {
|
|
||||||
acc[index] = currentValue;
|
|
||||||
return acc;
|
|
||||||
}, {}),
|
|
||||||
setup: (self) => self.hook(shownIndex, (self) => {
|
|
||||||
self.shown = `${shownIndex.value}`;
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
const mainBox = Box({
|
|
||||||
attribute: {
|
|
||||||
children: children,
|
|
||||||
shown: shownIndex,
|
|
||||||
names: names,
|
|
||||||
},
|
|
||||||
vertical: true,
|
|
||||||
className: `spacing-v-5 ${className}`,
|
|
||||||
setup: (self) => {
|
|
||||||
self.pack_start(tabSection, false, false, 0);
|
|
||||||
self.pack_end(contentStack, true, true, 0);
|
|
||||||
setup(self);
|
|
||||||
self.hook(shownIndex, (self) => onChange(self, shownIndex.value));
|
|
||||||
},
|
|
||||||
...rest,
|
|
||||||
});
|
|
||||||
mainBox.nextTab = () => shownIndex.value = Math.min(shownIndex.value + 1, count - 1);
|
|
||||||
mainBox.prevTab = () => shownIndex.value = Math.max(shownIndex.value - 1, 0);
|
|
||||||
mainBox.cycleTab = () => shownIndex.value = (shownIndex.value + 1) % count;
|
|
||||||
mainBox.focusName = (name) => {
|
|
||||||
const focusIndex = names.indexOf(name);
|
|
||||||
if (focusIndex !== -1) {
|
|
||||||
shownIndex.value = focusIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mainBox.shown = shownIndex;
|
|
||||||
|
|
||||||
return mainBox;
|
|
||||||
}
|
|
||||||
|
|
@ -1,262 +0,0 @@
|
||||||
import GLib from 'gi://GLib';
|
|
||||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
|
|
||||||
import userOverrides from '../../user_options.js';
|
|
||||||
|
|
||||||
// Default options.
|
|
||||||
// Add overrides in ~/.config/ags/user_options.js
|
|
||||||
let configOptions = {
|
|
||||||
// General stuff
|
|
||||||
'ai': {
|
|
||||||
'defaultGPTProvider': "openai",
|
|
||||||
'defaultTemperature': 0.9,
|
|
||||||
'enhancements': true,
|
|
||||||
'useHistory': true,
|
|
||||||
'safety': true,
|
|
||||||
'writingCursor': " ...", // Warning: Using weird characters can mess up Markdown rendering
|
|
||||||
'proxyUrl': null, // Can be "socks5://127.0.0.1:9050" or "http://127.0.0.1:8080" for example. Leave it blank if you don't need it.
|
|
||||||
},
|
|
||||||
'animations': {
|
|
||||||
'choreographyDelay': 35,
|
|
||||||
'durationSmall': 110,
|
|
||||||
'durationLarge': 180,
|
|
||||||
},
|
|
||||||
'appearance': {
|
|
||||||
'autoDarkMode': { // Turns on dark mode in certain hours. Time in 24h format
|
|
||||||
'enabled': false,
|
|
||||||
'from': "18:10",
|
|
||||||
'to': "6:10",
|
|
||||||
},
|
|
||||||
'keyboardUseFlag': false, // Use flag emoji instead of abbreviation letters
|
|
||||||
'layerSmoke': false,
|
|
||||||
'layerSmokeStrength': 0.2,
|
|
||||||
'barRoundCorners': 1, // 0: No, 1: Yes
|
|
||||||
'fakeScreenRounding': 1, // 0: None | 1: Always | 2: When not fullscreen
|
|
||||||
},
|
|
||||||
'apps': {
|
|
||||||
'bluetooth': "blueberry",
|
|
||||||
'imageViewer': "loupe",
|
|
||||||
'network': "XDG_CURRENT_DESKTOP=\"gnome\" gnome-control-center wifi",
|
|
||||||
'settings': "XDG_CURRENT_DESKTOP=\"gnome\" gnome-control-center",
|
|
||||||
'taskManager': "gnome-usage",
|
|
||||||
'terminal': "foot", // This is only for shell actions
|
|
||||||
},
|
|
||||||
'battery': {
|
|
||||||
'low': 20,
|
|
||||||
'critical': 10,
|
|
||||||
'warnLevels': [20, 15, 5],
|
|
||||||
'warnTitles': ["Low battery", "Very low battery", 'Critical Battery'],
|
|
||||||
'warnMessages': ["Plug in the charger", "You there?", 'PLUG THE CHARGER ALREADY'],
|
|
||||||
'suspendThreshold': 3,
|
|
||||||
},
|
|
||||||
'brightness': {
|
|
||||||
// Object of controller names for each monitor, either "brightnessctl" or "ddcutil" or "auto"
|
|
||||||
// 'default' one will be used if unspecified
|
|
||||||
// Examples
|
|
||||||
// 'eDP-1': "brightnessctl",
|
|
||||||
// 'DP-1': "ddcutil",
|
|
||||||
'controllers': {
|
|
||||||
'default': "auto",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'cheatsheet': {
|
|
||||||
'keybinds': {
|
|
||||||
'configPath': "" // Path to hyprland keybind config file. Leave empty for default (~/.config/hypr/hyprland/keybinds.conf)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'gaming': {
|
|
||||||
'crosshair': {
|
|
||||||
'size': 20,
|
|
||||||
'color': 'rgba(113,227,32,0.9)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'i18n': {
|
|
||||||
'langCode': "",//Customize the locale, such as zh_CN,Optional value references "~/.config/ags/i18n/locales/"
|
|
||||||
'extraLogs': false
|
|
||||||
},
|
|
||||||
'monitors': {
|
|
||||||
'scaleMethod': "division", // Either "division" [default] or "gdk"
|
|
||||||
},
|
|
||||||
'music': {
|
|
||||||
'preferredPlayer': "plasma-browser-integration",
|
|
||||||
},
|
|
||||||
'onScreenKeyboard': {
|
|
||||||
'layout': "qwerty_full", // See modules/onscreenkeyboard/onscreenkeyboard.js for available layouts
|
|
||||||
},
|
|
||||||
'overview': {
|
|
||||||
'scale': 0.18, // Relative to screen size
|
|
||||||
'numOfRows': 2,
|
|
||||||
'numOfCols': 5,
|
|
||||||
'wsNumScale': 0.09,
|
|
||||||
'wsNumMarginScale': 0.07,
|
|
||||||
},
|
|
||||||
'sidebar': {
|
|
||||||
'ai': {
|
|
||||||
'extraGptModels': {
|
|
||||||
'oxygen3': {
|
|
||||||
'name': 'Oxygen (GPT-3.5)',
|
|
||||||
'logo_name': 'ai-oxygen-symbolic',
|
|
||||||
'description': 'An API from Tornado Softwares\nPricing: Free: 100/day\nRequires you to join their Discord for a key',
|
|
||||||
'base_url': 'https://app.oxyapi.uk/v1/chat/completions',
|
|
||||||
'key_get_url': 'https://discord.com/invite/kM6MaCqGKA',
|
|
||||||
'key_file': 'oxygen_key.txt',
|
|
||||||
'model': 'gpt-3.5-turbo',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'image': {
|
|
||||||
'columns': 2,
|
|
||||||
'batchCount': 20,
|
|
||||||
'allowNsfw': false,
|
|
||||||
'saveInFolderByTags': false,
|
|
||||||
},
|
|
||||||
'pages': {
|
|
||||||
'order': ["apis", "tools"],
|
|
||||||
'apis': {
|
|
||||||
'order': ["gemini", "gpt", "waifu", "booru"],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'search': {
|
|
||||||
'enableFeatures': {
|
|
||||||
'actions': true,
|
|
||||||
'commands': true,
|
|
||||||
'mathResults': true,
|
|
||||||
'directorySearch': true,
|
|
||||||
'aiSearch': true,
|
|
||||||
'webSearch': true,
|
|
||||||
},
|
|
||||||
'engineBaseUrl': "https://www.google.com/search?q=",
|
|
||||||
'excludedSites': ["quora.com"],
|
|
||||||
},
|
|
||||||
'time': {
|
|
||||||
// See https://docs.gtk.org/glib/method.DateTime.format.html
|
|
||||||
// Here's the 12h format: "%I:%M%P"
|
|
||||||
// For seconds, add "%S" and set interval to 1000
|
|
||||||
'format': "%H:%M",
|
|
||||||
'interval': 5000,
|
|
||||||
'dateFormatLong': "%A, %d/%m", // On bar
|
|
||||||
'dateInterval': 5000,
|
|
||||||
'dateFormat': "%d/%m", // On notif time
|
|
||||||
},
|
|
||||||
'weather': {
|
|
||||||
'city': "",
|
|
||||||
'preferredUnit': "C", // Either C or F
|
|
||||||
},
|
|
||||||
'workspaces': {
|
|
||||||
'shown': 10,
|
|
||||||
},
|
|
||||||
'dock': {
|
|
||||||
'enabled': false,
|
|
||||||
'hiddenThickness': 5,
|
|
||||||
'pinnedApps': ['firefox', 'org.gnome.Nautilus'],
|
|
||||||
'layer': 'top',
|
|
||||||
'monitorExclusivity': true, // Dock will move to other monitor along with focus if enabled
|
|
||||||
'searchPinnedAppIcons': false, // Try to search for the correct icon if the app class isn't an icon name
|
|
||||||
'trigger': ['client-added', 'client-removed'], // client_added, client_move, workspace_active, client_active
|
|
||||||
// Automatically hide dock after `interval` ms since trigger
|
|
||||||
'autoHide': [
|
|
||||||
{
|
|
||||||
'trigger': 'client-added',
|
|
||||||
'interval': 500,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'trigger': 'client-removed',
|
|
||||||
'interval': 500,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
// Longer stuff
|
|
||||||
'icons': {
|
|
||||||
// Find the window's icon by its class with levenshteinDistance
|
|
||||||
// The file names are processed at startup, so if there
|
|
||||||
// are too many files in the search path it'll affect performance
|
|
||||||
// Example: ['/usr/share/icons/Tela-nord/scalable/apps']
|
|
||||||
'searchPaths': [''],
|
|
||||||
'symbolicIconTheme': {
|
|
||||||
"dark": "Adwaita",
|
|
||||||
"light": "Adwaita",
|
|
||||||
},
|
|
||||||
substitutions: {
|
|
||||||
'code-url-handler': "visual-studio-code",
|
|
||||||
'Code': "visual-studio-code",
|
|
||||||
'GitHub Desktop': "github-desktop",
|
|
||||||
'Minecraft* 1.20.1': "minecraft",
|
|
||||||
'gnome-tweaks': "org.gnome.tweaks",
|
|
||||||
'pavucontrol-qt': "pavucontrol",
|
|
||||||
'wps': "wps-office2019-kprometheus",
|
|
||||||
'wpsoffice': "wps-office2019-kprometheus",
|
|
||||||
'': "image-missing",
|
|
||||||
},
|
|
||||||
regexSubstitutions: [
|
|
||||||
{
|
|
||||||
regex: /^steam_app_(\d+)$/,
|
|
||||||
replace: "steam_icon_$1",
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
'keybinds': {
|
|
||||||
// Format: Mod1+Mod2+key. CaSe SeNsItIvE!
|
|
||||||
// Modifiers: Shift Ctrl Alt Hyper Meta
|
|
||||||
// See https://docs.gtk.org/gdk3/index.html#constants for the other keys (they are listed as KEY_key)
|
|
||||||
'overview': {
|
|
||||||
'altMoveLeft': "Ctrl+b",
|
|
||||||
'altMoveRight': "Ctrl+f",
|
|
||||||
'deleteToEnd': "Ctrl+k",
|
|
||||||
},
|
|
||||||
'sidebar': {
|
|
||||||
'apis': {
|
|
||||||
'nextTab': "Page_Down",
|
|
||||||
'prevTab': "Page_Up",
|
|
||||||
},
|
|
||||||
'options': { // Right sidebar
|
|
||||||
'nextTab': "Page_Down",
|
|
||||||
'prevTab': "Page_Up",
|
|
||||||
},
|
|
||||||
'pin': "Ctrl+p",
|
|
||||||
'cycleTab': "Ctrl+Tab",
|
|
||||||
'nextTab': "Ctrl+Page_Down",
|
|
||||||
'prevTab': "Ctrl+Page_Up",
|
|
||||||
},
|
|
||||||
'cheatsheet': {
|
|
||||||
'keybinds': {
|
|
||||||
'nextTab': "Page_Down",
|
|
||||||
'prevTab': "Page_Up",
|
|
||||||
},
|
|
||||||
'nextTab': "Ctrl+Page_Down",
|
|
||||||
'prevTab': "Ctrl+Page_Up",
|
|
||||||
'cycleTab': "Ctrl+Tab",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'bar': {
|
|
||||||
// Array of bar modes for each monitor. Hit Ctrl+Alt+Slash to cycle.
|
|
||||||
// Modes: "normal", "focus" (workspace indicator only), "nothing"
|
|
||||||
// Example for four monitors: ["normal", "focus", "normal", "nothing"]
|
|
||||||
'modes': ["normal"]
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Override defaults with user's options
|
|
||||||
let optionsOkay = true;
|
|
||||||
function overrideConfigRecursive(userOverrides, configOptions = {}, check = true) {
|
|
||||||
for (const [key, value] of Object.entries(userOverrides)) {
|
|
||||||
if (configOptions[key] === undefined && check) {
|
|
||||||
optionsOkay = false;
|
|
||||||
}
|
|
||||||
else if (typeof value === 'object' && !(value instanceof Array)) {
|
|
||||||
if (key === "substitutions" || key === "regexSubstitutions" || key === "extraGptModels") {
|
|
||||||
overrideConfigRecursive(value, configOptions[key], false);
|
|
||||||
} else overrideConfigRecursive(value, configOptions[key]);
|
|
||||||
} else {
|
|
||||||
configOptions[key] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
overrideConfigRecursive(userOverrides, configOptions);
|
|
||||||
if (!optionsOkay) Utils.timeout(2000, () => Utils.execAsync(['notify-send',
|
|
||||||
'Update your user options',
|
|
||||||
'One or more config options don\'t exist',
|
|
||||||
'-a', 'ags',
|
|
||||||
]).catch(print))
|
|
||||||
|
|
||||||
globalThis['userOptions'] = configOptions;
|
|
||||||
export default configOptions;
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
const { Gio, GLib, Gtk } = imports.gi;
|
|
||||||
|
|
||||||
export function fileExists(filePath) {
|
|
||||||
let file = Gio.File.new_for_path(filePath);
|
|
||||||
return file.query_exists(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function expandTilde(path) {
|
|
||||||
if (path.startsWith('~')) {
|
|
||||||
return GLib.get_home_dir() + path.slice(1);
|
|
||||||
} else {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
const { Gtk } = imports.gi;
|
|
||||||
|
|
||||||
export function iconExists(iconName) {
|
|
||||||
let iconTheme = Gtk.IconTheme.get_default();
|
|
||||||
return iconTheme.has_icon(iconName);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function substitute(str) {
|
|
||||||
// Normal substitutions
|
|
||||||
if (userOptions.icons.substitutions[str])
|
|
||||||
return userOptions.icons.substitutions[str];
|
|
||||||
|
|
||||||
// Regex substitutions
|
|
||||||
for (let i = 0; i < userOptions.icons.regexSubstitutions.length; i++) {
|
|
||||||
const substitution = userOptions.icons.regexSubstitutions[i];
|
|
||||||
const replacedName = str.replace(
|
|
||||||
substitution.regex,
|
|
||||||
substitution.replace,
|
|
||||||
);
|
|
||||||
if (replacedName != str) return replacedName;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Guess: convert to kebab case
|
|
||||||
if (!iconExists(str)) str = str.toLowerCase().replace(/\s+/g, "-");
|
|
||||||
|
|
||||||
// Original string
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
|
|
||||||
export function clamp(x, min, max) {
|
|
||||||
return Math.min(Math.max(x, min), max);
|
|
||||||
}
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
||||||
// Converts from Markdown to Pango. This does not support code blocks.
|
|
||||||
// For illogical-impulse, code blocks are treated separately, in their own GtkSourceView widgets.
|
|
||||||
// Partly inherited from https://github.com/ubunatic/md2pango
|
|
||||||
|
|
||||||
const monospaceFonts = 'JetBrains Mono NF, JetBrains Mono Nerd Font, JetBrains Mono NL, SpaceMono NF, SpaceMono Nerd Font, monospace';
|
|
||||||
|
|
||||||
const replacements = {
|
|
||||||
'indents': [
|
|
||||||
{ name: 'BULLET', re: /^(\s*)([\*\-]\s)(.*)(\s*)$/, sub: ' $1- $3' },
|
|
||||||
{ name: 'NUMBERING', re: /^(\s*[0-9]+\.\s)(.*)(\s*)$/, sub: ' $1 $2' },
|
|
||||||
],
|
|
||||||
'escapes': [
|
|
||||||
{ name: 'COMMENT', re: /<!--[\s\S]*?-->/, sub: '' },
|
|
||||||
{ name: 'AMPERSTAND', re: /&/g, sub: '&' },
|
|
||||||
{ name: 'LESSTHAN', re: /</g, sub: '<' },
|
|
||||||
{ name: 'GREATERTHAN', re: />/g, sub: '>' },
|
|
||||||
],
|
|
||||||
'sections': [
|
|
||||||
{ name: 'H1', re: /^(#\s+)(.*)(\s*)$/, sub: '<span font_weight="bold" size="170%">$2</span>' },
|
|
||||||
{ name: 'H2', re: /^(##\s+)(.*)(\s*)$/, sub: '<span font_weight="bold" size="150%">$2</span>' },
|
|
||||||
{ name: 'H3', re: /^(###\s+)(.*)(\s*)$/, sub: '<span font_weight="bold" size="125%">$2</span>' },
|
|
||||||
{ name: 'H4', re: /^(####\s+)(.*)(\s*)$/, sub: '<span font_weight="bold" size="100%">$2</span>' },
|
|
||||||
{ name: 'H5', re: /^(#####\s+)(.*)(\s*)$/, sub: '<span font_weight="bold" size="90%">$2</span>' },
|
|
||||||
],
|
|
||||||
'styles': [
|
|
||||||
{ name: 'BOLD', re: /(\*\*)(\S[\s\S]*?\S)(\*\*)/g, sub: "<b>$2</b>" },
|
|
||||||
{ name: 'UND', re: /(__)(\S[\s\S]*?\S)(__)/g, sub: "<u>$2</u>" },
|
|
||||||
{ name: 'EMPH', re: /\*(\S.*?\S)\*/g, sub: "<i>$1</i>" },
|
|
||||||
// { name: 'EMPH', re: /_(\S.*?\S)_/g, sub: "<i>$1</i>" },
|
|
||||||
{ name: 'HEXCOLOR', re: /#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/g, sub: '<span bgcolor="#$1" fgcolor="#000000" font_family="' + monospaceFonts + '">#$1</span>' },
|
|
||||||
{ name: 'INLCODE', re: /(`)([^`]*)(`)/g, sub: '<span font_weight="bold" font_family="' + monospaceFonts + '">$2</span>' },
|
|
||||||
// { name: 'UND', re: /(__|\*\*)(\S[\s\S]*?\S)(__|\*\*)/g, sub: "<u>$2</u>" },
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
const replaceCategory = (text, replaces) => {
|
|
||||||
for (const type of replaces) {
|
|
||||||
text = text.replace(type.re, type.sub);
|
|
||||||
}
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main function
|
|
||||||
|
|
||||||
export default (text) => {
|
|
||||||
let lines = text.split('\n')
|
|
||||||
let output = [];
|
|
||||||
// Replace
|
|
||||||
for (const line of lines) {
|
|
||||||
let result = line;
|
|
||||||
result = replaceCategory(result, replacements.indents);
|
|
||||||
result = replaceCategory(result, replacements.escapes);
|
|
||||||
result = replaceCategory(result, replacements.sections);
|
|
||||||
result = replaceCategory(result, replacements.styles);
|
|
||||||
output.push(result)
|
|
||||||
}
|
|
||||||
// Remove trailing whitespaces
|
|
||||||
output = output.map(line => line.replace(/ +$/, ''))
|
|
||||||
return output.join('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
export const markdownTest = `## Inline formatting
|
|
||||||
- **Bold** *Italics* __Underline__
|
|
||||||
- \`Monospace text\` 🤓
|
|
||||||
- Colors
|
|
||||||
- Nvidia green #7ABB08
|
|
||||||
- Soundcloud orange #FF5500
|
|
||||||
## Code block
|
|
||||||
\`\`\`cpp
|
|
||||||
#include <bits/stdc++.h>
|
|
||||||
const std::string GREETING="UwU";
|
|
||||||
int main() { std::cout << GREETING; }
|
|
||||||
\`\`\`
|
|
||||||
## LaTeX
|
|
||||||
\`\`\`latex
|
|
||||||
\\frac{d}{dx} \\left( \\frac{x-438}{x^2+23x-7} \\right) = \\frac{-x^2 + 869}{(x^2+23x-7)^2} \\\\ → \\\\ cos(2x) = 2cos^2(x) - 1 = 1 - 2sin^2(x) = cos^2(x) - sin^2(x)
|
|
||||||
\`\`\`
|
|
||||||
`;
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
const { GLib } = imports.gi;
|
|
||||||
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
|
|
||||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
|
|
||||||
const { execAsync, exec } = Utils;
|
|
||||||
|
|
||||||
export const distroID = exec(`bash -c 'cat /etc/os-release | grep "^ID=" | cut -d "=" -f 2 | sed "s/\\"//g"'`).trim();
|
|
||||||
export const isDebianDistro = (distroID == 'linuxmint' || distroID == 'ubuntu' || distroID == 'debian' || distroID == 'zorin' || distroID == 'popos' || distroID == 'raspbian' || distroID == 'kali');
|
|
||||||
export const isArchDistro = (distroID == 'arch' || distroID == 'endeavouros' || distroID == 'cachyos');
|
|
||||||
export const hasFlatpak = !!exec(`bash -c 'command -v flatpak'`);
|
|
||||||
|
|
||||||
const LIGHTDARK_FILE_LOCATION = `${GLib.get_user_state_dir()}/ags/user/colormode.txt`;
|
|
||||||
export const darkMode = Variable(!(Utils.readFile(LIGHTDARK_FILE_LOCATION).split('\n')[0].trim() == 'light'));
|
|
||||||
darkMode.connect('changed', ({ value }) => {
|
|
||||||
let lightdark = value ? "dark" : "light";
|
|
||||||
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_state_dir()}/ags/user && sed -i "1s/.*/${lightdark}/" ${GLib.get_user_state_dir()}/ags/user/colormode.txt`])
|
|
||||||
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchcolor.sh`]))
|
|
||||||
.then(execAsync(['bash', '-c', `command -v darkman && darkman set ${lightdark}`])) // Optional darkman integration
|
|
||||||
.catch(print);
|
|
||||||
});
|
|
||||||
globalThis['darkMode'] = darkMode;
|
|
||||||
export const hasPlasmaIntegration = !!Utils.exec('bash -c "command -v plasma-browser-integration-host"');
|
|
||||||
|
|
||||||
export const getDistroIcon = () => {
|
|
||||||
// Arches
|
|
||||||
if(distroID == 'arch') return 'arch-symbolic';
|
|
||||||
if(distroID == 'endeavouros') return 'endeavouros-symbolic';
|
|
||||||
if(distroID == 'cachyos') return 'cachyos-symbolic';
|
|
||||||
// Funny flake
|
|
||||||
if(distroID == 'nixos') return 'nixos-symbolic';
|
|
||||||
// Cool thing
|
|
||||||
if(distroID == 'fedora') return 'fedora-symbolic';
|
|
||||||
// Debians
|
|
||||||
if(distroID == 'linuxmint') return 'ubuntu-symbolic';
|
|
||||||
if(distroID == 'ubuntu') return 'ubuntu-symbolic';
|
|
||||||
if(distroID == 'debian') return 'debian-symbolic';
|
|
||||||
if(distroID == 'zorin') return 'ubuntu-symbolic';
|
|
||||||
if(distroID == 'popos') return 'ubuntu-symbolic';
|
|
||||||
if(distroID == 'raspbian') return 'debian-symbolic';
|
|
||||||
if(distroID == 'kali') return 'debian-symbolic';
|
|
||||||
return 'linux-symbolic';
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getDistroName = () => {
|
|
||||||
// Arches
|
|
||||||
if(distroID == 'arch') return 'Arch Linux';
|
|
||||||
if(distroID == 'endeavouros') return 'EndeavourOS';
|
|
||||||
if(distroID == 'cachyos') return 'CachyOS';
|
|
||||||
// Funny flake
|
|
||||||
if(distroID == 'nixos') return 'NixOS';
|
|
||||||
// Cool thing
|
|
||||||
if(distroID == 'fedora') return 'Fedora';
|
|
||||||
// Debians
|
|
||||||
if(distroID == 'linuxmint') return 'Linux Mint';
|
|
||||||
if(distroID == 'ubuntu') return 'Ubuntu';
|
|
||||||
if(distroID == 'debian') return 'Debian';
|
|
||||||
if(distroID == 'zorin') return 'Zorin';
|
|
||||||
if(distroID == 'popos') return 'Pop!_OS';
|
|
||||||
if(distroID == 'raspbian') return 'Raspbian';
|
|
||||||
if(distroID == 'kali') return 'Kali Linux';
|
|
||||||
return 'Linux';
|
|
||||||
}
|
|
||||||
|
|
@ -1,86 +0,0 @@
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
|
|
||||||
const { Revealer, Scrollable } = Widget;
|
|
||||||
|
|
||||||
export const MarginRevealer = ({
|
|
||||||
transition = 'slide_down',
|
|
||||||
child,
|
|
||||||
revealChild,
|
|
||||||
showClass = 'element-show', // These are for animation curve, they don't really hide
|
|
||||||
hideClass = 'element-hide', // Don't put margins in these classes!
|
|
||||||
extraSetup = () => { },
|
|
||||||
...rest
|
|
||||||
}) => {
|
|
||||||
const widget = Scrollable({
|
|
||||||
...rest,
|
|
||||||
attribute: {
|
|
||||||
'revealChild': true, // It'll be set to false after init if it's supposed to hide
|
|
||||||
'transition': transition,
|
|
||||||
'show': () => {
|
|
||||||
if (widget.attribute.revealChild) return;
|
|
||||||
widget.hscroll = 'never';
|
|
||||||
widget.vscroll = 'never';
|
|
||||||
child.toggleClassName(hideClass, false);
|
|
||||||
child.toggleClassName(showClass, true);
|
|
||||||
widget.attribute.revealChild = true;
|
|
||||||
child.css = 'margin: 0px;';
|
|
||||||
},
|
|
||||||
'hide': () => {
|
|
||||||
if (!widget.attribute.revealChild) return;
|
|
||||||
child.toggleClassName(hideClass, true);
|
|
||||||
child.toggleClassName(showClass, false);
|
|
||||||
widget.attribute.revealChild = false;
|
|
||||||
if (widget.attribute.transition == 'slide_left')
|
|
||||||
child.css = `margin-right: -${child.get_allocated_width()}px;`;
|
|
||||||
else if (widget.attribute.transition == 'slide_right')
|
|
||||||
child.css = `margin-left: -${child.get_allocated_width()}px;`;
|
|
||||||
else if (widget.attribute.transition == 'slide_up')
|
|
||||||
child.css = `margin-bottom: -${child.get_allocated_height()}px;`;
|
|
||||||
else if (widget.attribute.transition == 'slide_down')
|
|
||||||
child.css = `margin-top: -${child.get_allocated_height()}px;`;
|
|
||||||
},
|
|
||||||
'toggle': () => {
|
|
||||||
if (widget.attribute.revealChild) widget.attribute.hide();
|
|
||||||
else widget.attribute.show();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
child: child,
|
|
||||||
hscroll: `${revealChild ? 'never' : 'always'}`,
|
|
||||||
vscroll: `${revealChild ? 'never' : 'always'}`,
|
|
||||||
setup: (self) => {
|
|
||||||
extraSetup(self);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
child.toggleClassName(`${revealChild ? showClass : hideClass}`, true);
|
|
||||||
return widget;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Allow reveal update. Currently this just helps at declaration
|
|
||||||
export const DoubleRevealer = ({
|
|
||||||
transition1 = 'slide_right',
|
|
||||||
transition2 = 'slide_left',
|
|
||||||
duration1 = 150,
|
|
||||||
duration2 = 150,
|
|
||||||
child,
|
|
||||||
revealChild,
|
|
||||||
...rest
|
|
||||||
}) => {
|
|
||||||
const r2 = Revealer({
|
|
||||||
transition: transition2,
|
|
||||||
transitionDuration: duration2,
|
|
||||||
revealChild: revealChild,
|
|
||||||
child: child,
|
|
||||||
});
|
|
||||||
const r1 = Revealer({
|
|
||||||
transition: transition1,
|
|
||||||
transitionDuration: duration1,
|
|
||||||
revealChild: revealChild,
|
|
||||||
child: r2,
|
|
||||||
...rest,
|
|
||||||
})
|
|
||||||
r1.toggleRevealChild = (value) => {
|
|
||||||
r1.revealChild = value;
|
|
||||||
r2.revealChild = value;
|
|
||||||
}
|
|
||||||
return r1;
|
|
||||||
}
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
import App from 'resource:///com/github/Aylur/ags/app.js';
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
const { Box, Window } = Widget;
|
|
||||||
|
|
||||||
|
|
||||||
export default ({
|
|
||||||
name,
|
|
||||||
child,
|
|
||||||
showClassName = "",
|
|
||||||
hideClassName = "",
|
|
||||||
...props
|
|
||||||
}) => {
|
|
||||||
return Window({
|
|
||||||
name,
|
|
||||||
visible: false,
|
|
||||||
layer: 'top',
|
|
||||||
...props,
|
|
||||||
|
|
||||||
child: Box({
|
|
||||||
setup: (self) => {
|
|
||||||
self.keybind("Escape", () => closeEverything());
|
|
||||||
if (showClassName != "" && hideClassName !== "") {
|
|
||||||
self.hook(App, (self, currentName, visible) => {
|
|
||||||
if (currentName === name) {
|
|
||||||
self.toggleClassName(hideClassName, !visible);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (showClassName !== "" && hideClassName !== "")
|
|
||||||
self.className = `${showClassName} ${hideClassName}`;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: child,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
import Cairo from 'gi://cairo?version=1.0';
|
|
||||||
|
|
||||||
export const dummyRegion = new Cairo.Region();
|
|
||||||
export const enableClickthrough = (self) => self.input_shape_combine_region(dummyRegion);
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
const { Gdk } = imports.gi;
|
|
||||||
|
|
||||||
export function setupCursorHover(button) { // Hand pointing cursor on hover
|
|
||||||
const display = Gdk.Display.get_default();
|
|
||||||
button.connect('enter-notify-event', () => {
|
|
||||||
const cursor = Gdk.Cursor.new_from_name(display, 'pointer');
|
|
||||||
button.get_window().set_cursor(cursor);
|
|
||||||
});
|
|
||||||
|
|
||||||
button.connect('leave-notify-event', () => {
|
|
||||||
const cursor = Gdk.Cursor.new_from_name(display, 'default');
|
|
||||||
button.get_window().set_cursor(cursor);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setupCursorHoverAim(button) { // Crosshair cursor on hover
|
|
||||||
button.connect('enter-notify-event', () => {
|
|
||||||
const display = Gdk.Display.get_default();
|
|
||||||
const cursor = Gdk.Cursor.new_from_name(display, 'crosshair');
|
|
||||||
button.get_window().set_cursor(cursor);
|
|
||||||
});
|
|
||||||
|
|
||||||
button.connect('leave-notify-event', () => {
|
|
||||||
const display = Gdk.Display.get_default();
|
|
||||||
const cursor = Gdk.Cursor.new_from_name(display, 'default');
|
|
||||||
button.get_window().set_cursor(cursor);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setupCursorHoverGrab(button) { // Hand ready to grab on hover
|
|
||||||
button.connect('enter-notify-event', () => {
|
|
||||||
const display = Gdk.Display.get_default();
|
|
||||||
const cursor = Gdk.Cursor.new_from_name(display, 'grab');
|
|
||||||
button.get_window().set_cursor(cursor);
|
|
||||||
});
|
|
||||||
|
|
||||||
button.connect('leave-notify-event', () => {
|
|
||||||
const display = Gdk.Display.get_default();
|
|
||||||
const cursor = Gdk.Cursor.new_from_name(display, 'default');
|
|
||||||
button.get_window().set_cursor(cursor);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setupCursorHoverInfo(button) { // "?" mark cursor on hover
|
|
||||||
const display = Gdk.Display.get_default();
|
|
||||||
button.connect('enter-notify-event', () => {
|
|
||||||
const cursor = Gdk.Cursor.new_from_name(display, 'help');
|
|
||||||
button.get_window().set_cursor(cursor);
|
|
||||||
});
|
|
||||||
|
|
||||||
button.connect('leave-notify-event', () => {
|
|
||||||
const cursor = Gdk.Cursor.new_from_name(display, 'default');
|
|
||||||
button.get_window().set_cursor(cursor);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
const { Gdk } = imports.gi;
|
|
||||||
|
|
||||||
const MODS = {
|
|
||||||
'Shift': Gdk.ModifierType.SHIFT_MASK,
|
|
||||||
'Ctrl': Gdk.ModifierType.CONTROL_MASK,
|
|
||||||
'Alt': Gdk.ModifierType.ALT_MASK,
|
|
||||||
'Hyper': Gdk.ModifierType.HYPER_MASK,
|
|
||||||
'Meta': Gdk.ModifierType.META_MASK
|
|
||||||
}
|
|
||||||
|
|
||||||
export const checkKeybind = (event, keybind) => {
|
|
||||||
const pressedModMask = event.get_state()[1];
|
|
||||||
const pressedKey = event.get_keyval()[1];
|
|
||||||
const keys = keybind.split('+');
|
|
||||||
for (let i = 0; i < keys.length; i++) {
|
|
||||||
if (keys[i] in MODS) {
|
|
||||||
if (!(pressedModMask & MODS[keys[i]])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (pressedKey !== Gdk[`KEY_${keys[i]}`]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
@ -1,213 +0,0 @@
|
||||||
const { GLib, Gdk, Gtk } = imports.gi;
|
|
||||||
const Lang = imports.lang;
|
|
||||||
const Cairo = imports.cairo;
|
|
||||||
const Pango = imports.gi.Pango;
|
|
||||||
const PangoCairo = imports.gi.PangoCairo;
|
|
||||||
import App from 'resource:///com/github/Aylur/ags/app.js';
|
|
||||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
const { Box, DrawingArea, EventBox } = Widget;
|
|
||||||
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
|
|
||||||
|
|
||||||
const dummyWs = Box({ className: 'bar-ws-focus' }); // Not shown. Only for getting size props
|
|
||||||
const dummyActiveWs = Box({ className: 'bar-ws-focus bar-ws-focus-active' }); // Not shown. Only for getting size props
|
|
||||||
const dummyOccupiedWs = Box({ className: 'bar-ws-focus bar-ws-focus-occupied' }); // Not shown. Only for getting size props
|
|
||||||
|
|
||||||
const WS_TAKEN_WIDTH_MULTIPLIER = 1.4;
|
|
||||||
const floor = Math.floor;
|
|
||||||
const ceil = Math.ceil;
|
|
||||||
|
|
||||||
// Font size = workspace id
|
|
||||||
const WorkspaceContents = (count = 10) => {
|
|
||||||
return DrawingArea({
|
|
||||||
className: 'menu-decel',
|
|
||||||
attribute: {
|
|
||||||
lastImmediateActiveWs: 0,
|
|
||||||
immediateActiveWs: 0,
|
|
||||||
initialized: false,
|
|
||||||
workspaceMask: 0,
|
|
||||||
workspaceGroup: 0,
|
|
||||||
updateMask: (self) => {
|
|
||||||
const offset = Math.floor((Hyprland.active.workspace.id - 1) / count) * userOptions.workspaces.shown;
|
|
||||||
// if (self.attribute.initialized) return; // We only need this to run once
|
|
||||||
const workspaces = Hyprland.workspaces;
|
|
||||||
let workspaceMask = 0;
|
|
||||||
for (let i = 0; i < workspaces.length; i++) {
|
|
||||||
const ws = workspaces[i];
|
|
||||||
if (ws.id <= offset || ws.id > offset + count) continue; // Out of range, ignore
|
|
||||||
if (workspaces[i].windows > 0)
|
|
||||||
workspaceMask |= (1 << (ws.id - offset));
|
|
||||||
}
|
|
||||||
// console.log('Mask:', workspaceMask.toString(2));
|
|
||||||
self.attribute.workspaceMask = workspaceMask;
|
|
||||||
// self.attribute.initialized = true;
|
|
||||||
self.queue_draw();
|
|
||||||
},
|
|
||||||
toggleMask: (self, occupied, name) => {
|
|
||||||
if (occupied) self.attribute.workspaceMask |= (1 << parseInt(name));
|
|
||||||
else self.attribute.workspaceMask &= ~(1 << parseInt(name));
|
|
||||||
self.queue_draw();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
setup: (area) => area
|
|
||||||
.hook(Hyprland.active.workspace, (self) => {
|
|
||||||
const newActiveWs = (Hyprland.active.workspace.id - 1) % count + 1;
|
|
||||||
self.setCss(`font-size: ${newActiveWs}px;`);
|
|
||||||
self.attribute.lastImmediateActiveWs = self.attribute.immediateActiveWs;
|
|
||||||
self.attribute.immediateActiveWs = newActiveWs;
|
|
||||||
const previousGroup = self.attribute.workspaceGroup;
|
|
||||||
const currentGroup = Math.floor((Hyprland.active.workspace.id - 1) / count);
|
|
||||||
if (currentGroup !== previousGroup) {
|
|
||||||
self.attribute.updateMask(self);
|
|
||||||
self.attribute.workspaceGroup = currentGroup;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.hook(Hyprland, (self) => self.attribute.updateMask(self), 'notify::workspaces')
|
|
||||||
.on('draw', Lang.bind(area, (area, cr) => {
|
|
||||||
const offset = Math.floor((Hyprland.active.workspace.id - 1) / count) * userOptions.workspaces.shown;
|
|
||||||
|
|
||||||
const allocation = area.get_allocation();
|
|
||||||
const { width, height } = allocation;
|
|
||||||
|
|
||||||
const workspaceStyleContext = dummyWs.get_style_context();
|
|
||||||
const workspaceDiameter = workspaceStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
|
|
||||||
const workspaceRadius = workspaceDiameter / 2;
|
|
||||||
const wsbg = workspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
|
|
||||||
|
|
||||||
const occupiedWorkspaceStyleContext = dummyOccupiedWs.get_style_context();
|
|
||||||
const occupiedbg = occupiedWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
|
|
||||||
|
|
||||||
const activeWorkspaceStyleContext = dummyActiveWs.get_style_context();
|
|
||||||
const activeWorkspaceWidth = activeWorkspaceStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
|
|
||||||
// const activeWorkspaceWidth = 100;
|
|
||||||
const activebg = activeWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
|
|
||||||
|
|
||||||
const widgetStyleContext = area.get_style_context();
|
|
||||||
const activeWs = widgetStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL);
|
|
||||||
const lastImmediateActiveWs = area.attribute.lastImmediateActiveWs;
|
|
||||||
const immediateActiveWs = area.attribute.immediateActiveWs;
|
|
||||||
|
|
||||||
// Draw
|
|
||||||
area.set_size_request(workspaceDiameter * WS_TAKEN_WIDTH_MULTIPLIER * (count - 1) + activeWorkspaceWidth, -1);
|
|
||||||
for (let i = 1; i <= count; i++) {
|
|
||||||
if (i == immediateActiveWs) continue;
|
|
||||||
let colors = {};
|
|
||||||
if (area.attribute.workspaceMask & (1 << i)) colors = occupiedbg;
|
|
||||||
else colors = wsbg;
|
|
||||||
|
|
||||||
// if ((i == immediateActiveWs + 1 && immediateActiveWs < activeWs) ||
|
|
||||||
// (i == immediateActiveWs + 1 && immediateActiveWs < activeWs)) {
|
|
||||||
// const widthPercentage = (i == immediateActiveWs - 1) ?
|
|
||||||
// 1 - (immediateActiveWs - activeWs) :
|
|
||||||
// activeWs - immediateActiveWs;
|
|
||||||
// cr.setSourceRGBA(colors.red * widthPercentage + activebg.red * (1 - widthPercentage),
|
|
||||||
// colors.green * widthPercentage + activebg.green * (1 - widthPercentage),
|
|
||||||
// colors.blue * widthPercentage + activebg.blue * (1 - widthPercentage),
|
|
||||||
// colors.alpha);
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
cr.setSourceRGBA(colors.red, colors.green, colors.blue, colors.alpha)
|
|
||||||
|
|
||||||
const centerX = (i <= activeWs) ?
|
|
||||||
(-workspaceRadius + (workspaceDiameter * WS_TAKEN_WIDTH_MULTIPLIER * i))
|
|
||||||
: -workspaceRadius + workspaceDiameter * WS_TAKEN_WIDTH_MULTIPLIER * (count - 1) + activeWorkspaceWidth - ((count - i) * workspaceDiameter * WS_TAKEN_WIDTH_MULTIPLIER);
|
|
||||||
cr.arc(centerX, height / 2, workspaceRadius, 0, 2 * Math.PI);
|
|
||||||
cr.fill();
|
|
||||||
// What if shrinking
|
|
||||||
if (i == floor(activeWs) && immediateActiveWs > activeWs) { // To right
|
|
||||||
const widthPercentage = 1 - (ceil(activeWs) - activeWs);
|
|
||||||
const leftX = centerX;
|
|
||||||
const wsWidth = (activeWorkspaceWidth - (workspaceDiameter * 1.5)) * (1 - widthPercentage);
|
|
||||||
cr.rectangle(leftX, height / 2 - workspaceRadius, wsWidth, workspaceDiameter);
|
|
||||||
cr.fill();
|
|
||||||
cr.arc(leftX + wsWidth, height / 2, workspaceRadius, 0, Math.PI * 2);
|
|
||||||
cr.fill();
|
|
||||||
}
|
|
||||||
else if (i == ceil(activeWs) && immediateActiveWs < activeWs) { // To left
|
|
||||||
const widthPercentage = activeWs - floor(activeWs);
|
|
||||||
const rightX = centerX;
|
|
||||||
const wsWidth = (activeWorkspaceWidth - (workspaceDiameter * 1.5)) * widthPercentage;
|
|
||||||
const leftX = rightX - wsWidth;
|
|
||||||
cr.rectangle(leftX, height / 2 - workspaceRadius, wsWidth, workspaceDiameter);
|
|
||||||
cr.fill();
|
|
||||||
cr.arc(leftX, height / 2, workspaceRadius, 0, Math.PI * 2);
|
|
||||||
cr.fill();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let widthPercentage, leftX, rightX, activeWsWidth;
|
|
||||||
cr.setSourceRGBA(activebg.red, activebg.green, activebg.blue, activebg.alpha);
|
|
||||||
if (immediateActiveWs > activeWs) { // To right
|
|
||||||
const immediateActiveWs = ceil(activeWs);
|
|
||||||
widthPercentage = immediateActiveWs - activeWs;
|
|
||||||
rightX = -workspaceRadius + workspaceDiameter * WS_TAKEN_WIDTH_MULTIPLIER * (count - 1) + activeWorkspaceWidth - ((count - immediateActiveWs) * workspaceDiameter * WS_TAKEN_WIDTH_MULTIPLIER);
|
|
||||||
activeWsWidth = (activeWorkspaceWidth - (workspaceDiameter * 1.5)) * (1 - widthPercentage);
|
|
||||||
leftX = rightX - activeWsWidth;
|
|
||||||
|
|
||||||
cr.arc(leftX, height / 2, workspaceRadius, 0, Math.PI * 2); // Should be 0.5 * Math.PI, 1.5 * Math.PI in theory but it leaves a weird 1px gap
|
|
||||||
cr.fill();
|
|
||||||
cr.rectangle(leftX, height / 2 - workspaceRadius, activeWsWidth, workspaceDiameter);
|
|
||||||
cr.fill();
|
|
||||||
cr.arc(leftX + activeWsWidth, height / 2, workspaceRadius, 0, Math.PI * 2);
|
|
||||||
cr.fill();
|
|
||||||
}
|
|
||||||
else { // To left
|
|
||||||
const immediateActiveWs = floor(activeWs);
|
|
||||||
widthPercentage = 1 - (activeWs - immediateActiveWs);
|
|
||||||
leftX = -workspaceRadius + (workspaceDiameter * WS_TAKEN_WIDTH_MULTIPLIER * immediateActiveWs);
|
|
||||||
activeWsWidth = (activeWorkspaceWidth - (workspaceDiameter * 1.5)) * widthPercentage
|
|
||||||
|
|
||||||
cr.arc(leftX, height / 2, workspaceRadius, 0, Math.PI * 2); // Should be 0.5 * Math.PI, 1.5 * Math.PI in theory but it leaves a weird 1px gap
|
|
||||||
cr.fill();
|
|
||||||
cr.rectangle(leftX, height / 2 - workspaceRadius, activeWsWidth, workspaceDiameter);
|
|
||||||
cr.fill();
|
|
||||||
cr.arc(leftX + activeWsWidth, height / 2, workspaceRadius, 0, Math.PI * 2);
|
|
||||||
cr.fill();
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export default () => EventBox({
|
|
||||||
onScrollUp: () => Hyprland.messageAsync(`dispatch workspace -1`).catch(print),
|
|
||||||
onScrollDown: () => Hyprland.messageAsync(`dispatch workspace +1`).catch(print),
|
|
||||||
onMiddleClick: () => toggleWindowOnAllMonitors('osk'),
|
|
||||||
onSecondaryClick: () => App.toggleWindow('overview'),
|
|
||||||
attribute: {
|
|
||||||
clicked: false,
|
|
||||||
ws_group: 0,
|
|
||||||
},
|
|
||||||
child: Box({
|
|
||||||
homogeneous: true,
|
|
||||||
// className: 'bar-group-margin',
|
|
||||||
children: [Box({
|
|
||||||
// className: 'bar-group bar-group-standalone bar-group-pad',
|
|
||||||
css: 'min-width: 2px;',
|
|
||||||
children: [WorkspaceContents(userOptions.workspaces.shown)],
|
|
||||||
})]
|
|
||||||
}),
|
|
||||||
setup: (self) => {
|
|
||||||
self.add_events(Gdk.EventMask.POINTER_MOTION_MASK);
|
|
||||||
self.on('motion-notify-event', (self, event) => {
|
|
||||||
if (!self.attribute.clicked) return;
|
|
||||||
const [_, cursorX, cursorY] = event.get_coords();
|
|
||||||
const widgetWidth = self.get_allocation().width;
|
|
||||||
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
|
|
||||||
Utils.execAsync([`${App.configDir}/scripts/hyprland/workspace_action.sh`, 'workspace', `${wsId}`])
|
|
||||||
.catch(print);
|
|
||||||
})
|
|
||||||
self.on('button-press-event', (self, event) => {
|
|
||||||
if (!(event.get_button()[1] === 1)) return; // We're only interested in left-click here
|
|
||||||
self.attribute.clicked = true;
|
|
||||||
const [_, cursorX, cursorY] = event.get_coords();
|
|
||||||
const widgetWidth = self.get_allocation().width;
|
|
||||||
// const wsId = Math.ceil(cursorX * NUM_OF_WORKSPACES_PER_GROUP / widgetWidth) + self.attribute.ws_group * NUM_OF_WORKSPACES_PER_GROUP;
|
|
||||||
// Hyprland.messageAsync(`dispatch workspace ${wsId}`).catch(print);
|
|
||||||
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
|
|
||||||
Utils.execAsync([`${App.configDir}/scripts/hyprland/workspace_action.sh`, 'workspace', `${wsId}`])
|
|
||||||
.catch(print);
|
|
||||||
})
|
|
||||||
self.on('button-release-event', (self) => self.attribute.clicked = false);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
@ -1,183 +0,0 @@
|
||||||
const { GLib, Gdk, Gtk } = imports.gi;
|
|
||||||
const Lang = imports.lang;
|
|
||||||
const Cairo = imports.cairo;
|
|
||||||
const Pango = imports.gi.Pango;
|
|
||||||
const PangoCairo = imports.gi.PangoCairo;
|
|
||||||
import Widget from "resource:///com/github/Aylur/ags/widget.js";
|
|
||||||
import Sway from "../../../services/sway.js";
|
|
||||||
import * as Utils from "resource:///com/github/Aylur/ags/utils.js";
|
|
||||||
const { execAsync, exec } = Utils;
|
|
||||||
const { Box, DrawingArea, EventBox } = Widget;
|
|
||||||
|
|
||||||
const dummyWs = Box({ className: 'bar-ws' }); // Not shown. Only for getting size props
|
|
||||||
const dummyActiveWs = Box({ className: 'bar-ws bar-ws-active' }); // Not shown. Only for getting size props
|
|
||||||
const dummyOccupiedWs = Box({ className: 'bar-ws bar-ws-occupied' }); // Not shown. Only for getting size props
|
|
||||||
|
|
||||||
const switchToWorkspace = (arg) => Utils.execAsync(`swaymsg workspace ${arg}`).catch(print);
|
|
||||||
const switchToRelativeWorkspace = (self, num) =>
|
|
||||||
execAsync([`${App.configDir}/scripts/sway/swayToRelativeWs.sh`, `${num}`]).catch(print);
|
|
||||||
|
|
||||||
const WorkspaceContents = (count = 10) => {
|
|
||||||
return DrawingArea({
|
|
||||||
css: `transition: 90ms cubic-bezier(0.1, 1, 0, 1);`,
|
|
||||||
attribute: {
|
|
||||||
initialized: false,
|
|
||||||
workspaceMask: 0,
|
|
||||||
updateMask: (self) => {
|
|
||||||
if (self.attribute.initialized) return; // We only need this to run once
|
|
||||||
const workspaces = Sway.workspaces;
|
|
||||||
let workspaceMask = 0;
|
|
||||||
// console.log('----------------')
|
|
||||||
for (let i = 0; i < workspaces.length; i++) {
|
|
||||||
const ws = workspaces[i];
|
|
||||||
// console.log(ws.name, ',', ws.num);
|
|
||||||
if (!Number(ws.name)) return;
|
|
||||||
const id = Number(ws.name);
|
|
||||||
if (id <= 0) continue; // Ignore scratchpads
|
|
||||||
if (id > count) return; // Not rendered
|
|
||||||
if (workspaces[i].windows > 0) {
|
|
||||||
workspaceMask |= (1 << id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.attribute.workspaceMask = workspaceMask;
|
|
||||||
self.attribute.initialized = true;
|
|
||||||
},
|
|
||||||
toggleMask: (self, occupied, name) => {
|
|
||||||
if (occupied) self.attribute.workspaceMask |= (1 << parseInt(name));
|
|
||||||
else self.attribute.workspaceMask &= ~(1 << parseInt(name));
|
|
||||||
},
|
|
||||||
},
|
|
||||||
setup: (area) => area
|
|
||||||
.hook(Sway.active.workspace, (area) => {
|
|
||||||
area.setCss(`font-size: ${Sway.active.workspace.name}px;`)
|
|
||||||
})
|
|
||||||
.hook(Sway, (self) => self.attribute.updateMask(self), 'notify::workspaces')
|
|
||||||
// .hook(Hyprland, (self, name) => self.attribute.toggleMask(self, true, name), 'workspace-added')
|
|
||||||
// .hook(Hyprland, (self, name) => self.attribute.toggleMask(self, false, name), 'workspace-removed')
|
|
||||||
.on('draw', Lang.bind(area, (area, cr) => {
|
|
||||||
const allocation = area.get_allocation();
|
|
||||||
const { width, height } = allocation;
|
|
||||||
|
|
||||||
const workspaceStyleContext = dummyWs.get_style_context();
|
|
||||||
const workspaceDiameter = workspaceStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
|
|
||||||
const workspaceRadius = workspaceDiameter / 2;
|
|
||||||
const workspaceFontSize = workspaceStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL) / 4 * 3;
|
|
||||||
const workspaceFontFamily = workspaceStyleContext.get_property('font-family', Gtk.StateFlags.NORMAL);
|
|
||||||
const wsbg = workspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
|
|
||||||
const wsfg = workspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
|
|
||||||
|
|
||||||
const occupiedWorkspaceStyleContext = dummyOccupiedWs.get_style_context();
|
|
||||||
const occupiedbg = occupiedWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
|
|
||||||
const occupiedfg = occupiedWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
|
|
||||||
|
|
||||||
const activeWorkspaceStyleContext = dummyActiveWs.get_style_context();
|
|
||||||
const activebg = activeWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
|
|
||||||
const activefg = activeWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
|
|
||||||
area.set_size_request(workspaceDiameter * count, -1);
|
|
||||||
const widgetStyleContext = area.get_style_context();
|
|
||||||
const activeWs = widgetStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL);
|
|
||||||
|
|
||||||
const activeWsCenterX = -(workspaceDiameter / 2) + (workspaceDiameter * activeWs);
|
|
||||||
const activeWsCenterY = height / 2;
|
|
||||||
|
|
||||||
// Font
|
|
||||||
const layout = PangoCairo.create_layout(cr);
|
|
||||||
const fontDesc = Pango.font_description_from_string(`${workspaceFontFamily[0]} ${workspaceFontSize}`);
|
|
||||||
layout.set_font_description(fontDesc);
|
|
||||||
cr.setAntialias(Cairo.Antialias.BEST);
|
|
||||||
// Get kinda min radius for number indicators
|
|
||||||
layout.set_text("0".repeat(count.toString().length), -1);
|
|
||||||
const [layoutWidth, layoutHeight] = layout.get_pixel_size();
|
|
||||||
const indicatorRadius = Math.max(layoutWidth, layoutHeight) / 2 * 1.2; // a bit smaller than sqrt(2)*radius
|
|
||||||
const indicatorGap = workspaceRadius - indicatorRadius;
|
|
||||||
|
|
||||||
// Draw workspace numbers
|
|
||||||
for (let i = 1; i <= count; i++) {
|
|
||||||
if (area.attribute.workspaceMask & (1 << i)) {
|
|
||||||
// Draw bg highlight
|
|
||||||
cr.setSourceRGBA(occupiedbg.red, occupiedbg.green, occupiedbg.blue, occupiedbg.alpha);
|
|
||||||
const wsCenterX = -(workspaceRadius) + (workspaceDiameter * i);
|
|
||||||
const wsCenterY = height / 2;
|
|
||||||
if (!(area.attribute.workspaceMask & (1 << (i - 1)))) { // Left
|
|
||||||
cr.arc(wsCenterX, wsCenterY, workspaceRadius, 0.5 * Math.PI, 1.5 * Math.PI);
|
|
||||||
cr.fill();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cr.rectangle(wsCenterX - workspaceRadius, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2)
|
|
||||||
cr.fill();
|
|
||||||
}
|
|
||||||
if (!(area.attribute.workspaceMask & (1 << (i + 1)))) { // Right
|
|
||||||
cr.arc(wsCenterX, wsCenterY, workspaceRadius, -0.5 * Math.PI, 0.5 * Math.PI);
|
|
||||||
cr.fill();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cr.rectangle(wsCenterX, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2)
|
|
||||||
cr.fill();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set color for text
|
|
||||||
cr.setSourceRGBA(occupiedfg.red, occupiedfg.green, occupiedfg.blue, occupiedfg.alpha);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
cr.setSourceRGBA(wsfg.red, wsfg.green, wsfg.blue, wsfg.alpha);
|
|
||||||
layout.set_text(`${i}`, -1);
|
|
||||||
const [layoutWidth, layoutHeight] = layout.get_pixel_size();
|
|
||||||
const x = -workspaceRadius + (workspaceDiameter * i) - (layoutWidth / 2);
|
|
||||||
const y = (height - layoutHeight) / 2;
|
|
||||||
cr.moveTo(x, y);
|
|
||||||
// cr.showText(text);
|
|
||||||
PangoCairo.show_layout(cr, layout);
|
|
||||||
cr.stroke();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw active ws
|
|
||||||
// base
|
|
||||||
cr.setSourceRGBA(activebg.red, activebg.green, activebg.blue, activebg.alpha);
|
|
||||||
cr.arc(activeWsCenterX, activeWsCenterY, indicatorRadius, 0, 2 * Math.PI);
|
|
||||||
cr.fill();
|
|
||||||
// inner decor
|
|
||||||
cr.setSourceRGBA(activefg.red, activefg.green, activefg.blue, activefg.alpha);
|
|
||||||
cr.arc(activeWsCenterX, activeWsCenterY, indicatorRadius * 0.2, 0, 2 * Math.PI);
|
|
||||||
cr.fill();
|
|
||||||
}))
|
|
||||||
,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export default () => EventBox({
|
|
||||||
onScrollUp: (self) => switchToRelativeWorkspace(self, -1),
|
|
||||||
onScrollDown: (self) => switchToRelativeWorkspace(self, +1),
|
|
||||||
onMiddleClick: () => toggleWindowOnAllMonitors('osk'),
|
|
||||||
onSecondaryClick: () => App.toggleWindow('overview'),
|
|
||||||
attribute: { clicked: false },
|
|
||||||
child: Box({
|
|
||||||
homogeneous: true,
|
|
||||||
className: 'bar-group-margin',
|
|
||||||
children: [Box({
|
|
||||||
className: 'bar-group bar-group-standalone bar-group-pad',
|
|
||||||
css: 'min-width: 2px;',
|
|
||||||
children: [
|
|
||||||
WorkspaceContents(10),
|
|
||||||
]
|
|
||||||
})]
|
|
||||||
}),
|
|
||||||
setup: (self) => {
|
|
||||||
self.add_events(Gdk.EventMask.POINTER_MOTION_MASK);
|
|
||||||
self.on('motion-notify-event', (self, event) => {
|
|
||||||
if (!self.attribute.clicked) return;
|
|
||||||
const [_, cursorX, cursorY] = event.get_coords();
|
|
||||||
const widgetWidth = self.get_allocation().width;
|
|
||||||
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
|
|
||||||
switchToWorkspace(wsId);
|
|
||||||
})
|
|
||||||
self.on('button-press-event', (self, event) => {
|
|
||||||
if (!(event.get_button()[1] === 1)) return; // We're only interested in left-click here
|
|
||||||
self.attribute.clicked = true;
|
|
||||||
const [_, cursorX, cursorY] = event.get_coords();
|
|
||||||
const widgetWidth = self.get_allocation().width;
|
|
||||||
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
|
|
||||||
switchToWorkspace(wsId);
|
|
||||||
})
|
|
||||||
self.on('button-release-event', (self) => self.attribute.clicked = false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,129 +0,0 @@
|
||||||
const { Gtk } = imports.gi;
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import Battery from 'resource:///com/github/Aylur/ags/service/battery.js';
|
|
||||||
|
|
||||||
import WindowTitle from "./normal/spaceleft.js";
|
|
||||||
import Indicators from "./normal/spaceright.js";
|
|
||||||
import Music from "./normal/music.js";
|
|
||||||
import System from "./normal/system.js";
|
|
||||||
import { enableClickthrough } from "../.widgetutils/clickthrough.js";
|
|
||||||
import { RoundedCorner } from "../.commonwidgets/cairo_roundedcorner.js";
|
|
||||||
import { currentShellMode } from '../../variables.js';
|
|
||||||
|
|
||||||
const NormalOptionalWorkspaces = async () => {
|
|
||||||
try {
|
|
||||||
return (await import('./normal/workspaces_hyprland.js')).default();
|
|
||||||
} catch {
|
|
||||||
try {
|
|
||||||
return (await import('./normal/workspaces_sway.js')).default();
|
|
||||||
} catch {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const FocusOptionalWorkspaces = async () => {
|
|
||||||
try {
|
|
||||||
return (await import('./focus/workspaces_hyprland.js')).default();
|
|
||||||
} catch {
|
|
||||||
try {
|
|
||||||
return (await import('./focus/workspaces_sway.js')).default();
|
|
||||||
} catch {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Bar = async (monitor = 0) => {
|
|
||||||
const SideModule = (children) => Widget.Box({
|
|
||||||
className: 'bar-sidemodule',
|
|
||||||
children: children,
|
|
||||||
});
|
|
||||||
const normalBarContent = Widget.CenterBox({
|
|
||||||
className: 'bar-bg',
|
|
||||||
setup: (self) => {
|
|
||||||
const styleContext = self.get_style_context();
|
|
||||||
const minHeight = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
|
|
||||||
// execAsync(['bash', '-c', `hyprctl keyword monitor ,addreserved,${minHeight},0,0,0`]).catch(print);
|
|
||||||
},
|
|
||||||
startWidget: (await WindowTitle(monitor)),
|
|
||||||
centerWidget: Widget.Box({
|
|
||||||
className: 'spacing-h-4',
|
|
||||||
children: [
|
|
||||||
SideModule([Music()]),
|
|
||||||
Widget.Box({
|
|
||||||
homogeneous: true,
|
|
||||||
children: [await NormalOptionalWorkspaces()],
|
|
||||||
}),
|
|
||||||
SideModule([System()]),
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
endWidget: Indicators(monitor),
|
|
||||||
});
|
|
||||||
const focusedBarContent = Widget.CenterBox({
|
|
||||||
className: 'bar-bg-focus',
|
|
||||||
startWidget: Widget.Box({}),
|
|
||||||
centerWidget: Widget.Box({
|
|
||||||
className: 'spacing-h-4',
|
|
||||||
children: [
|
|
||||||
SideModule([]),
|
|
||||||
Widget.Box({
|
|
||||||
homogeneous: true,
|
|
||||||
children: [await FocusOptionalWorkspaces()],
|
|
||||||
}),
|
|
||||||
SideModule([]),
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
endWidget: Widget.Box({}),
|
|
||||||
setup: (self) => {
|
|
||||||
self.hook(Battery, (self) => {
|
|
||||||
if (!Battery.available) return;
|
|
||||||
self.toggleClassName('bar-bg-focus-batterylow', Battery.percent <= userOptions.battery.low);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const nothingContent = Widget.Box({
|
|
||||||
className: 'bar-bg-nothing',
|
|
||||||
})
|
|
||||||
return Widget.Window({
|
|
||||||
monitor,
|
|
||||||
name: `bar${monitor}`,
|
|
||||||
anchor: ['top', 'left', 'right'],
|
|
||||||
exclusivity: 'exclusive',
|
|
||||||
visible: true,
|
|
||||||
child: Widget.Stack({
|
|
||||||
homogeneous: false,
|
|
||||||
transition: 'slide_up_down',
|
|
||||||
transitionDuration: userOptions.animations.durationLarge,
|
|
||||||
children: {
|
|
||||||
'normal': normalBarContent,
|
|
||||||
'focus': focusedBarContent,
|
|
||||||
'nothing': nothingContent,
|
|
||||||
},
|
|
||||||
setup: (self) => self.hook(currentShellMode, (self) => {
|
|
||||||
self.shown = currentShellMode.value[monitor];
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export const BarCornerTopleft = (monitor = 0) => Widget.Window({
|
|
||||||
monitor,
|
|
||||||
name: `barcornertl${monitor}`,
|
|
||||||
layer: 'top',
|
|
||||||
anchor: ['top', 'left'],
|
|
||||||
exclusivity: 'normal',
|
|
||||||
visible: true,
|
|
||||||
child: RoundedCorner('topleft', { className: 'corner', }),
|
|
||||||
setup: enableClickthrough,
|
|
||||||
});
|
|
||||||
export const BarCornerTopright = (monitor = 0) => Widget.Window({
|
|
||||||
monitor,
|
|
||||||
name: `barcornertr${monitor}`,
|
|
||||||
layer: 'top',
|
|
||||||
anchor: ['top', 'right'],
|
|
||||||
exclusivity: 'normal',
|
|
||||||
visible: true,
|
|
||||||
child: RoundedCorner('topright', { className: 'corner', }),
|
|
||||||
setup: enableClickthrough,
|
|
||||||
});
|
|
||||||
|
|
@ -1,230 +0,0 @@
|
||||||
const { GLib } = imports.gi;
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
|
|
||||||
import Mpris from 'resource:///com/github/Aylur/ags/service/mpris.js';
|
|
||||||
const { Box, Button, EventBox, Label, Overlay, Revealer, Scrollable } = Widget;
|
|
||||||
const { execAsync, exec } = Utils;
|
|
||||||
import { AnimatedCircProg } from "../../.commonwidgets/cairo_circularprogress.js";
|
|
||||||
import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
|
|
||||||
import { showMusicControls } from '../../../variables.js';
|
|
||||||
|
|
||||||
const CUSTOM_MODULE_CONTENT_INTERVAL_FILE = `${GLib.get_user_cache_dir()}/ags/user/scripts/custom-module-interval.txt`;
|
|
||||||
const CUSTOM_MODULE_CONTENT_SCRIPT = `${GLib.get_user_cache_dir()}/ags/user/scripts/custom-module-poll.sh`;
|
|
||||||
const CUSTOM_MODULE_LEFTCLICK_SCRIPT = `${GLib.get_user_cache_dir()}/ags/user/scripts/custom-module-leftclick.sh`;
|
|
||||||
const CUSTOM_MODULE_RIGHTCLICK_SCRIPT = `${GLib.get_user_cache_dir()}/ags/user/scripts/custom-module-rightclick.sh`;
|
|
||||||
const CUSTOM_MODULE_MIDDLECLICK_SCRIPT = `${GLib.get_user_cache_dir()}/ags/user/scripts/custom-module-middleclick.sh`;
|
|
||||||
const CUSTOM_MODULE_SCROLLUP_SCRIPT = `${GLib.get_user_cache_dir()}/ags/user/scripts/custom-module-scrollup.sh`;
|
|
||||||
const CUSTOM_MODULE_SCROLLDOWN_SCRIPT = `${GLib.get_user_cache_dir()}/ags/user/scripts/custom-module-scrolldown.sh`;
|
|
||||||
|
|
||||||
function trimTrackTitle(title) {
|
|
||||||
if (!title) return '';
|
|
||||||
const cleanPatterns = [
|
|
||||||
/【[^】]*】/, // Touhou n weeb stuff
|
|
||||||
" [FREE DOWNLOAD]", // F-777
|
|
||||||
];
|
|
||||||
cleanPatterns.forEach((expr) => title = title.replace(expr, ''));
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
const BarGroup = ({ child }) => Box({
|
|
||||||
className: 'bar-group-margin bar-sides',
|
|
||||||
children: [
|
|
||||||
Box({
|
|
||||||
className: 'bar-group bar-group-standalone bar-group-pad-system',
|
|
||||||
children: [child],
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
const BarResource = (name, icon, command, circprogClassName = 'bar-batt-circprog', textClassName = 'txt-onSurfaceVariant', iconClassName = 'bar-batt') => {
|
|
||||||
const resourceCircProg = AnimatedCircProg({
|
|
||||||
className: `${circprogClassName}`,
|
|
||||||
vpack: 'center',
|
|
||||||
hpack: 'center',
|
|
||||||
});
|
|
||||||
const resourceProgress = Box({
|
|
||||||
homogeneous: true,
|
|
||||||
children: [Overlay({
|
|
||||||
child: Box({
|
|
||||||
vpack: 'center',
|
|
||||||
className: `${iconClassName}`,
|
|
||||||
homogeneous: true,
|
|
||||||
children: [
|
|
||||||
MaterialIcon(icon, 'small'),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
overlays: [resourceCircProg]
|
|
||||||
})]
|
|
||||||
});
|
|
||||||
const resourceLabel = Label({
|
|
||||||
className: `txt-smallie ${textClassName}`,
|
|
||||||
});
|
|
||||||
const widget = Button({
|
|
||||||
onClicked: () => Utils.execAsync(['bash', '-c', `${userOptions.apps.taskManager}`]).catch(print),
|
|
||||||
child: Box({
|
|
||||||
className: `spacing-h-4 ${textClassName}`,
|
|
||||||
children: [
|
|
||||||
resourceProgress,
|
|
||||||
resourceLabel,
|
|
||||||
],
|
|
||||||
setup: (self) => self.poll(5000, () => execAsync(['bash', '-c', command])
|
|
||||||
.then((output) => {
|
|
||||||
resourceCircProg.css = `font-size: ${Number(output)}px;`;
|
|
||||||
resourceLabel.label = `${Math.round(Number(output))}%`;
|
|
||||||
widget.tooltipText = `${name}: ${Math.round(Number(output))}%`;
|
|
||||||
}).catch(print))
|
|
||||||
,
|
|
||||||
})
|
|
||||||
});
|
|
||||||
return widget;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TrackProgress = () => {
|
|
||||||
const _updateProgress = (circprog) => {
|
|
||||||
const mpris = Mpris.getPlayer('');
|
|
||||||
if (!mpris) return;
|
|
||||||
// Set circular progress value
|
|
||||||
circprog.css = `font-size: ${Math.max(mpris.position / mpris.length * 100, 0)}px;`
|
|
||||||
}
|
|
||||||
return AnimatedCircProg({
|
|
||||||
className: 'bar-music-circprog',
|
|
||||||
vpack: 'center', hpack: 'center',
|
|
||||||
extraSetup: (self) => self
|
|
||||||
.hook(Mpris, _updateProgress)
|
|
||||||
.poll(3000, _updateProgress)
|
|
||||||
,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const switchToRelativeWorkspace = async (self, num) => {
|
|
||||||
try {
|
|
||||||
const Hyprland = (await import('resource:///com/github/Aylur/ags/service/hyprland.js')).default;
|
|
||||||
Hyprland.messageAsync(`dispatch workspace ${num > 0 ? '+' : ''}${num}`).catch(print);
|
|
||||||
} catch {
|
|
||||||
execAsync([`${App.configDir}/scripts/sway/swayToRelativeWs.sh`, `${num}`]).catch(print);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
// TODO: use cairo to make button bounce smaller on click, if that's possible
|
|
||||||
const playingState = Box({ // Wrap a box cuz overlay can't have margins itself
|
|
||||||
homogeneous: true,
|
|
||||||
children: [Overlay({
|
|
||||||
child: Box({
|
|
||||||
vpack: 'center',
|
|
||||||
className: 'bar-music-playstate',
|
|
||||||
homogeneous: true,
|
|
||||||
children: [Label({
|
|
||||||
vpack: 'center',
|
|
||||||
className: 'bar-music-playstate-txt',
|
|
||||||
justification: 'center',
|
|
||||||
setup: (self) => self.hook(Mpris, label => {
|
|
||||||
const mpris = Mpris.getPlayer('');
|
|
||||||
label.label = `${mpris !== null && mpris.playBackStatus == 'Playing' ? 'pause' : 'play_arrow'}`;
|
|
||||||
}),
|
|
||||||
})],
|
|
||||||
setup: (self) => self.hook(Mpris, label => {
|
|
||||||
const mpris = Mpris.getPlayer('');
|
|
||||||
if (!mpris) return;
|
|
||||||
label.toggleClassName('bar-music-playstate-playing', mpris !== null && mpris.playBackStatus == 'Playing');
|
|
||||||
label.toggleClassName('bar-music-playstate', mpris !== null || mpris.playBackStatus == 'Paused');
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
overlays: [
|
|
||||||
TrackProgress(),
|
|
||||||
]
|
|
||||||
})]
|
|
||||||
});
|
|
||||||
const trackTitle = Label({
|
|
||||||
hexpand: true,
|
|
||||||
className: 'txt-smallie bar-music-txt',
|
|
||||||
truncate: 'end',
|
|
||||||
maxWidthChars: 1, // Doesn't matter, just needs to be non negative
|
|
||||||
setup: (self) => self.hook(Mpris, label => {
|
|
||||||
const mpris = Mpris.getPlayer('');
|
|
||||||
if (mpris)
|
|
||||||
label.label = `${trimTrackTitle(mpris.trackTitle)} • ${mpris.trackArtists.join(', ')}`;
|
|
||||||
else
|
|
||||||
label.label = getString('No media');
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
const musicStuff = Box({
|
|
||||||
className: 'spacing-h-10',
|
|
||||||
hexpand: true,
|
|
||||||
children: [
|
|
||||||
playingState,
|
|
||||||
trackTitle,
|
|
||||||
]
|
|
||||||
})
|
|
||||||
const SystemResourcesOrCustomModule = () => {
|
|
||||||
// Check if $XDG_CACHE_HOME/ags/user/scripts/custom-module-poll.sh exists
|
|
||||||
if (GLib.file_test(CUSTOM_MODULE_CONTENT_SCRIPT, GLib.FileTest.EXISTS)) {
|
|
||||||
const interval = Number(Utils.readFile(CUSTOM_MODULE_CONTENT_INTERVAL_FILE)) || 5000;
|
|
||||||
return BarGroup({
|
|
||||||
child: Button({
|
|
||||||
child: Label({
|
|
||||||
className: 'txt-smallie txt-onSurfaceVariant',
|
|
||||||
useMarkup: true,
|
|
||||||
setup: (self) => Utils.timeout(1, () => {
|
|
||||||
self.label = exec(CUSTOM_MODULE_CONTENT_SCRIPT);
|
|
||||||
self.poll(interval, (self) => {
|
|
||||||
const content = exec(CUSTOM_MODULE_CONTENT_SCRIPT);
|
|
||||||
self.label = content;
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
onPrimaryClickRelease: () => execAsync(CUSTOM_MODULE_LEFTCLICK_SCRIPT).catch(print),
|
|
||||||
onSecondaryClickRelease: () => execAsync(CUSTOM_MODULE_RIGHTCLICK_SCRIPT).catch(print),
|
|
||||||
onMiddleClickRelease: () => execAsync(CUSTOM_MODULE_MIDDLECLICK_SCRIPT).catch(print),
|
|
||||||
onScrollUp: () => execAsync(CUSTOM_MODULE_SCROLLUP_SCRIPT).catch(print),
|
|
||||||
onScrollDown: () => execAsync(CUSTOM_MODULE_SCROLLDOWN_SCRIPT).catch(print),
|
|
||||||
})
|
|
||||||
});
|
|
||||||
} else return BarGroup({
|
|
||||||
child: Box({
|
|
||||||
children: [
|
|
||||||
BarResource(getString('RAM Usage'), 'memory', `LANG=C free | awk '/^Mem/ {printf("%.2f\\n", ($3/$2) * 100)}'`,
|
|
||||||
'bar-ram-circprog', 'bar-ram-txt', 'bar-ram-icon'),
|
|
||||||
Revealer({
|
|
||||||
revealChild: true,
|
|
||||||
transition: 'slide_left',
|
|
||||||
transitionDuration: userOptions.animations.durationLarge,
|
|
||||||
child: Box({
|
|
||||||
className: 'spacing-h-10 margin-left-10',
|
|
||||||
children: [
|
|
||||||
BarResource(getString('Swap Usage'), 'swap_horiz', `LANG=C free | awk '/^Swap/ {if ($2 > 0) printf("%.2f\\n", ($3/$2) * 100); else print "0";}'`,
|
|
||||||
'bar-swap-circprog', 'bar-swap-txt', 'bar-swap-icon'),
|
|
||||||
BarResource(getString('CPU Usage'), 'settings_motion_mode', `LANG=C top -bn1 | grep Cpu | sed 's/\\,/\\./g' | awk '{print $2}'`,
|
|
||||||
'bar-cpu-circprog', 'bar-cpu-txt', 'bar-cpu-icon'),
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
setup: (self) => self.hook(Mpris, label => {
|
|
||||||
const mpris = Mpris.getPlayer('');
|
|
||||||
self.revealChild = (!mpris);
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
],
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return EventBox({
|
|
||||||
onScrollUp: (self) => switchToRelativeWorkspace(self, -1),
|
|
||||||
onScrollDown: (self) => switchToRelativeWorkspace(self, +1),
|
|
||||||
child: Box({
|
|
||||||
className: 'spacing-h-4',
|
|
||||||
children: [
|
|
||||||
SystemResourcesOrCustomModule(),
|
|
||||||
EventBox({
|
|
||||||
child: BarGroup({ child: musicStuff }),
|
|
||||||
onPrimaryClick: () => showMusicControls.setValue(!showMusicControls.value),
|
|
||||||
onSecondaryClick: () => execAsync(['bash', '-c', 'playerctl next || playerctl position `bc <<< "100 * $(playerctl metadata mpris:length) / 1000000 / 100"` &']).catch(print),
|
|
||||||
onMiddleClick: () => execAsync('playerctl play-pause').catch(print),
|
|
||||||
setup: (self) => self.on('button-press-event', (self, event) => {
|
|
||||||
if (event.get_button()[1] === 8) // Side button
|
|
||||||
execAsync('playerctl previous').catch(print)
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
]
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
||||||
import App from 'resource:///com/github/Aylur/ags/app.js';
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import Brightness from '../../../services/brightness.js';
|
|
||||||
import Indicator from '../../../services/indicator.js';
|
|
||||||
|
|
||||||
const WindowTitle = async () => {
|
|
||||||
try {
|
|
||||||
const Hyprland = (await import('resource:///com/github/Aylur/ags/service/hyprland.js')).default;
|
|
||||||
return Widget.Scrollable({
|
|
||||||
hexpand: true, vexpand: true,
|
|
||||||
hscroll: 'automatic', vscroll: 'never',
|
|
||||||
child: Widget.Box({
|
|
||||||
vertical: true,
|
|
||||||
children: [
|
|
||||||
Widget.Label({
|
|
||||||
xalign: 0,
|
|
||||||
truncate: 'end',
|
|
||||||
maxWidthChars: 1, // Doesn't matter, just needs to be non negative
|
|
||||||
className: 'txt-smaller bar-wintitle-topdesc txt',
|
|
||||||
setup: (self) => self.hook(Hyprland.active.client, label => { // Hyprland.active.client
|
|
||||||
label.label = Hyprland.active.client.class.length === 0 ? 'Desktop' : Hyprland.active.client.class;
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
Widget.Label({
|
|
||||||
xalign: 0,
|
|
||||||
truncate: 'end',
|
|
||||||
maxWidthChars: 1, // Doesn't matter, just needs to be non negative
|
|
||||||
className: 'txt-smallie bar-wintitle-txt',
|
|
||||||
setup: (self) => self.hook(Hyprland.active.client, label => { // Hyprland.active.client
|
|
||||||
label.label = Hyprland.active.client.title.length === 0 ? `Workspace ${Hyprland.active.workspace.id}` : Hyprland.active.client.title;
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
]
|
|
||||||
})
|
|
||||||
});
|
|
||||||
} catch {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default async (monitor = 0) => {
|
|
||||||
const optionalWindowTitleInstance = await WindowTitle();
|
|
||||||
return Widget.EventBox({
|
|
||||||
onScrollUp: () => {
|
|
||||||
Indicator.popup(1); // Since the brightness and speaker are both on the same window
|
|
||||||
Brightness[monitor].screen_value += 0.05;
|
|
||||||
},
|
|
||||||
onScrollDown: () => {
|
|
||||||
Indicator.popup(1); // Since the brightness and speaker are both on the same window
|
|
||||||
Brightness[monitor].screen_value -= 0.05;
|
|
||||||
},
|
|
||||||
onPrimaryClick: () => {
|
|
||||||
App.toggleWindow('sideleft');
|
|
||||||
},
|
|
||||||
child: Widget.Box({
|
|
||||||
homogeneous: false,
|
|
||||||
children: [
|
|
||||||
Widget.Box({ className: 'bar-corner-spacing' }),
|
|
||||||
Widget.Overlay({
|
|
||||||
overlays: [
|
|
||||||
Widget.Box({ hexpand: true }),
|
|
||||||
Widget.Box({
|
|
||||||
className: 'bar-sidemodule', hexpand: true,
|
|
||||||
children: [Widget.Box({
|
|
||||||
vertical: true,
|
|
||||||
className: 'bar-space-button',
|
|
||||||
children: [
|
|
||||||
optionalWindowTitleInstance,
|
|
||||||
]
|
|
||||||
})]
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
})
|
|
||||||
]
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
import App from 'resource:///com/github/Aylur/ags/app.js';
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
|
|
||||||
|
|
||||||
import Audio from 'resource:///com/github/Aylur/ags/service/audio.js';
|
|
||||||
import SystemTray from 'resource:///com/github/Aylur/ags/service/systemtray.js';
|
|
||||||
const { execAsync } = Utils;
|
|
||||||
import Indicator from '../../../services/indicator.js';
|
|
||||||
import { StatusIcons } from '../../.commonwidgets/statusicons.js';
|
|
||||||
import { Tray } from "./tray.js";
|
|
||||||
|
|
||||||
const SeparatorDot = () => Widget.Revealer({
|
|
||||||
transition: 'slide_left',
|
|
||||||
revealChild: false,
|
|
||||||
attribute: {
|
|
||||||
'count': SystemTray.items.length,
|
|
||||||
'update': (self, diff) => {
|
|
||||||
self.attribute.count += diff;
|
|
||||||
self.revealChild = (self.attribute.count > 0);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: Widget.Box({
|
|
||||||
vpack: 'center',
|
|
||||||
className: 'separator-circle',
|
|
||||||
}),
|
|
||||||
setup: (self) => self
|
|
||||||
.hook(SystemTray, (self) => self.attribute.update(self, 1), 'added')
|
|
||||||
.hook(SystemTray, (self) => self.attribute.update(self, -1), 'removed')
|
|
||||||
,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default (monitor = 0) => {
|
|
||||||
const barTray = Tray();
|
|
||||||
const barStatusIcons = StatusIcons({
|
|
||||||
className: 'bar-statusicons',
|
|
||||||
setup: (self) => self.hook(App, (self, currentName, visible) => {
|
|
||||||
if (currentName === 'sideright') {
|
|
||||||
self.toggleClassName('bar-statusicons-active', visible);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
}, monitor);
|
|
||||||
const SpaceRightDefaultClicks = (child) => Widget.EventBox({
|
|
||||||
onHover: () => { barStatusIcons.toggleClassName('bar-statusicons-hover', true) },
|
|
||||||
onHoverLost: () => { barStatusIcons.toggleClassName('bar-statusicons-hover', false) },
|
|
||||||
onPrimaryClick: () => App.toggleWindow('sideright'),
|
|
||||||
onSecondaryClick: () => execAsync(['bash', '-c', 'playerctl next || playerctl position `bc <<< "100 * $(playerctl metadata mpris:length) / 1000000 / 100"` &']).catch(print),
|
|
||||||
onMiddleClick: () => execAsync('playerctl play-pause').catch(print),
|
|
||||||
setup: (self) => self.on('button-press-event', (self, event) => {
|
|
||||||
if (event.get_button()[1] === 8)
|
|
||||||
execAsync('playerctl previous').catch(print)
|
|
||||||
}),
|
|
||||||
child: child,
|
|
||||||
});
|
|
||||||
const emptyArea = SpaceRightDefaultClicks(Widget.Box({ hexpand: true, }));
|
|
||||||
const indicatorArea = SpaceRightDefaultClicks(Widget.Box({
|
|
||||||
children: [
|
|
||||||
SeparatorDot(),
|
|
||||||
barStatusIcons
|
|
||||||
],
|
|
||||||
}));
|
|
||||||
const actualContent = Widget.Box({
|
|
||||||
hexpand: true,
|
|
||||||
className: 'spacing-h-5 bar-spaceright',
|
|
||||||
children: [
|
|
||||||
emptyArea,
|
|
||||||
barTray,
|
|
||||||
indicatorArea
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
return Widget.EventBox({
|
|
||||||
onScrollUp: () => {
|
|
||||||
if (!Audio.speaker) return;
|
|
||||||
if (Audio.speaker.volume <= 0.09) Audio.speaker.volume += 0.01;
|
|
||||||
else Audio.speaker.volume += 0.03;
|
|
||||||
Indicator.popup(1);
|
|
||||||
},
|
|
||||||
onScrollDown: () => {
|
|
||||||
if (!Audio.speaker) return;
|
|
||||||
if (Audio.speaker.volume <= 0.09) Audio.speaker.volume -= 0.01;
|
|
||||||
else Audio.speaker.volume -= 0.03;
|
|
||||||
Indicator.popup(1);
|
|
||||||
},
|
|
||||||
child: Widget.Box({
|
|
||||||
children: [
|
|
||||||
actualContent,
|
|
||||||
SpaceRightDefaultClicks(Widget.Box({ className: 'bar-corner-spacing' })),
|
|
||||||
]
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
@ -1,236 +0,0 @@
|
||||||
// This is for the right pills of the bar.
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
|
|
||||||
const { Box, Label, Button, Overlay, Revealer, Scrollable, Stack, EventBox } = Widget;
|
|
||||||
const { exec, execAsync } = Utils;
|
|
||||||
const { GLib } = imports.gi;
|
|
||||||
import Battery from 'resource:///com/github/Aylur/ags/service/battery.js';
|
|
||||||
import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
|
|
||||||
import { AnimatedCircProg } from "../../.commonwidgets/cairo_circularprogress.js";
|
|
||||||
import { WWO_CODE, WEATHER_SYMBOL, NIGHT_WEATHER_SYMBOL } from '../../.commondata/weather.js';
|
|
||||||
|
|
||||||
const WEATHER_CACHE_FOLDER = `${GLib.get_user_cache_dir()}/ags/weather`;
|
|
||||||
Utils.exec(`mkdir -p ${WEATHER_CACHE_FOLDER}`);
|
|
||||||
|
|
||||||
const BarBatteryProgress = () => {
|
|
||||||
const _updateProgress = (circprog) => { // Set circular progress value
|
|
||||||
circprog.css = `font-size: ${Math.abs(Battery.percent)}px;`
|
|
||||||
|
|
||||||
circprog.toggleClassName('bar-batt-circprog-low', Battery.percent <= userOptions.battery.low);
|
|
||||||
circprog.toggleClassName('bar-batt-circprog-full', Battery.charged);
|
|
||||||
}
|
|
||||||
return AnimatedCircProg({
|
|
||||||
className: 'bar-batt-circprog',
|
|
||||||
vpack: 'center', hpack: 'center',
|
|
||||||
extraSetup: (self) => self
|
|
||||||
.hook(Battery, _updateProgress)
|
|
||||||
,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const time = Variable('', {
|
|
||||||
poll: [
|
|
||||||
userOptions.time.interval,
|
|
||||||
() => GLib.DateTime.new_now_local().format(userOptions.time.format),
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
const date = Variable('', {
|
|
||||||
poll: [
|
|
||||||
userOptions.time.dateInterval,
|
|
||||||
() => GLib.DateTime.new_now_local().format(userOptions.time.dateFormatLong),
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
const BarClock = () => Widget.Box({
|
|
||||||
vpack: 'center',
|
|
||||||
className: 'spacing-h-4 bar-clock-box',
|
|
||||||
children: [
|
|
||||||
Widget.Label({
|
|
||||||
className: 'bar-time',
|
|
||||||
label: time.bind(),
|
|
||||||
}),
|
|
||||||
Widget.Label({
|
|
||||||
className: 'txt-norm txt-onLayer1',
|
|
||||||
label: '•',
|
|
||||||
}),
|
|
||||||
Widget.Label({
|
|
||||||
className: 'txt-smallie bar-date',
|
|
||||||
label: date.bind(),
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
const UtilButton = ({ name, icon, onClicked }) => Button({
|
|
||||||
vpack: 'center',
|
|
||||||
tooltipText: name,
|
|
||||||
onClicked: onClicked,
|
|
||||||
className: 'bar-util-btn icon-material txt-norm',
|
|
||||||
label: `${icon}`,
|
|
||||||
})
|
|
||||||
|
|
||||||
const Utilities = () => Box({
|
|
||||||
hpack: 'center',
|
|
||||||
className: 'spacing-h-4',
|
|
||||||
children: [
|
|
||||||
UtilButton({
|
|
||||||
name: getString('Screen snip'), icon: 'screenshot_region', onClicked: () => {
|
|
||||||
Utils.execAsync(`${App.configDir}/scripts/grimblast.sh copy area`)
|
|
||||||
.catch(print)
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
UtilButton({
|
|
||||||
name: getString('Color picker'), icon: 'colorize', onClicked: () => {
|
|
||||||
Utils.execAsync(['hyprpicker', '-a']).catch(print)
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
UtilButton({
|
|
||||||
name: getString('Toggle on-screen keyboard'), icon: 'keyboard', onClicked: () => {
|
|
||||||
toggleWindowOnAllMonitors('osk');
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
const BarBattery = () => Box({
|
|
||||||
className: 'spacing-h-4 bar-batt-txt',
|
|
||||||
children: [
|
|
||||||
Revealer({
|
|
||||||
transitionDuration: userOptions.animations.durationSmall,
|
|
||||||
revealChild: false,
|
|
||||||
transition: 'slide_right',
|
|
||||||
child: MaterialIcon('bolt', 'norm', { tooltipText: "Charging" }),
|
|
||||||
setup: (self) => self.hook(Battery, revealer => {
|
|
||||||
self.revealChild = Battery.charging;
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
Label({
|
|
||||||
className: 'txt-smallie',
|
|
||||||
setup: (self) => self.hook(Battery, label => {
|
|
||||||
label.label = `${Number.parseFloat(Battery.percent.toFixed(1))}%`;
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
Overlay({
|
|
||||||
child: Widget.Box({
|
|
||||||
vpack: 'center',
|
|
||||||
className: 'bar-batt',
|
|
||||||
homogeneous: true,
|
|
||||||
children: [
|
|
||||||
MaterialIcon('battery_full', 'small'),
|
|
||||||
],
|
|
||||||
setup: (self) => self.hook(Battery, box => {
|
|
||||||
box.toggleClassName('bar-batt-low', Battery.percent <= userOptions.battery.low);
|
|
||||||
box.toggleClassName('bar-batt-full', Battery.charged);
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
overlays: [
|
|
||||||
BarBatteryProgress(),
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
const BarGroup = ({ child }) => Widget.Box({
|
|
||||||
className: 'bar-group-margin bar-sides',
|
|
||||||
children: [
|
|
||||||
Widget.Box({
|
|
||||||
className: 'bar-group bar-group-standalone bar-group-pad-system',
|
|
||||||
children: [child],
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
});
|
|
||||||
const BatteryModule = () => Stack({
|
|
||||||
transition: 'slide_up_down',
|
|
||||||
transitionDuration: userOptions.animations.durationLarge,
|
|
||||||
children: {
|
|
||||||
'laptop': Box({
|
|
||||||
className: 'spacing-h-4', children: [
|
|
||||||
BarGroup({ child: Utilities() }),
|
|
||||||
BarGroup({ child: BarBattery() }),
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
'desktop': BarGroup({
|
|
||||||
child: Box({
|
|
||||||
hexpand: true,
|
|
||||||
hpack: 'center',
|
|
||||||
className: 'spacing-h-4 txt-onSurfaceVariant',
|
|
||||||
children: [
|
|
||||||
MaterialIcon('device_thermostat', 'small'),
|
|
||||||
Label({
|
|
||||||
label: 'Weather',
|
|
||||||
})
|
|
||||||
],
|
|
||||||
setup: (self) => self.poll(900000, async (self) => {
|
|
||||||
const WEATHER_CACHE_PATH = WEATHER_CACHE_FOLDER + '/wttr.in.txt';
|
|
||||||
const updateWeatherForCity = (city) => execAsync(`curl https://wttr.in/${city.replace(/ /g, '%20')}?format=j1`)
|
|
||||||
.then(output => {
|
|
||||||
const weather = JSON.parse(output);
|
|
||||||
Utils.writeFile(JSON.stringify(weather), WEATHER_CACHE_PATH)
|
|
||||||
.catch(print);
|
|
||||||
const weatherCode = weather.current_condition[0].weatherCode;
|
|
||||||
const weatherDesc = weather.current_condition[0].weatherDesc[0].value;
|
|
||||||
const temperature = weather.current_condition[0][`temp_${userOptions.weather.preferredUnit}`];
|
|
||||||
const feelsLike = weather.current_condition[0][`FeelsLike${userOptions.weather.preferredUnit}`];
|
|
||||||
const weatherSymbol = WEATHER_SYMBOL[WWO_CODE[weatherCode]];
|
|
||||||
self.children[0].label = weatherSymbol;
|
|
||||||
self.children[1].label = `${temperature}°${userOptions.weather.preferredUnit} • Feels like ${feelsLike}°${userOptions.weather.preferredUnit}`;
|
|
||||||
self.tooltipText = weatherDesc;
|
|
||||||
}).catch((err) => {
|
|
||||||
try { // Read from cache
|
|
||||||
const weather = JSON.parse(
|
|
||||||
Utils.readFile(WEATHER_CACHE_PATH)
|
|
||||||
);
|
|
||||||
const weatherCode = weather.current_condition[0].weatherCode;
|
|
||||||
const weatherDesc = weather.current_condition[0].weatherDesc[0].value;
|
|
||||||
const temperature = weather.current_condition[0][`temp_${userOptions.weather.preferredUnit}`];
|
|
||||||
const feelsLike = weather.current_condition[0][`FeelsLike${userOptions.weather.preferredUnit}`];
|
|
||||||
const weatherSymbol = WEATHER_SYMBOL[WWO_CODE[weatherCode]];
|
|
||||||
self.children[0].label = weatherSymbol;
|
|
||||||
self.children[1].label = `${temperature}°${userOptions.weather.preferredUnit} • Feels like ${feelsLike}°${userOptions.weather.preferredUnit}`;
|
|
||||||
self.tooltipText = weatherDesc;
|
|
||||||
} catch (err) {
|
|
||||||
print(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (userOptions.weather.city != '' && userOptions.weather.city != null) {
|
|
||||||
updateWeatherForCity(userOptions.weather.city.replace(/ /g, '%20'));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Utils.execAsync('curl ipinfo.io')
|
|
||||||
.then(output => {
|
|
||||||
return JSON.parse(output)['city'].toLowerCase();
|
|
||||||
})
|
|
||||||
.then(updateWeatherForCity)
|
|
||||||
.catch(print)
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
setup: (stack) => Utils.timeout(10, () => {
|
|
||||||
if (!Battery.available) stack.shown = 'desktop';
|
|
||||||
else stack.shown = 'laptop';
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
const switchToRelativeWorkspace = async (self, num) => {
|
|
||||||
try {
|
|
||||||
const Hyprland = (await import('resource:///com/github/Aylur/ags/service/hyprland.js')).default;
|
|
||||||
Hyprland.messageAsync(`dispatch workspace ${num > 0 ? '+' : ''}${num}`).catch(print);
|
|
||||||
} catch {
|
|
||||||
execAsync([`${App.configDir}/scripts/sway/swayToRelativeWs.sh`, `${num}`]).catch(print);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default () => Widget.EventBox({
|
|
||||||
onScrollUp: (self) => switchToRelativeWorkspace(self, -1),
|
|
||||||
onScrollDown: (self) => switchToRelativeWorkspace(self, +1),
|
|
||||||
onPrimaryClick: () => App.toggleWindow('sideright'),
|
|
||||||
child: Widget.Box({
|
|
||||||
className: 'spacing-h-4',
|
|
||||||
children: [
|
|
||||||
BarGroup({ child: BarClock() }),
|
|
||||||
BatteryModule(),
|
|
||||||
]
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import SystemTray from 'resource:///com/github/Aylur/ags/service/systemtray.js';
|
|
||||||
const { Box, Icon, Button, Revealer } = Widget;
|
|
||||||
const { Gravity } = imports.gi.Gdk;
|
|
||||||
|
|
||||||
const SysTrayItem = (item) => item.id !== null ? Button({
|
|
||||||
className: 'bar-systray-item',
|
|
||||||
child: Icon({ hpack: 'center' }).bind('icon', item, 'icon'),
|
|
||||||
setup: (self) => self
|
|
||||||
.hook(item, (self) => self.tooltipMarkup = item['tooltip-markup'])
|
|
||||||
,
|
|
||||||
onPrimaryClick: (_, event) => item.activate(event),
|
|
||||||
onSecondaryClick: (btn, event) => item.menu.popup_at_widget(btn, Gravity.SOUTH, Gravity.NORTH, null),
|
|
||||||
}) : null;
|
|
||||||
|
|
||||||
export const Tray = (props = {}) => {
|
|
||||||
const trayContent = Box({
|
|
||||||
className: 'margin-right-5 spacing-h-15',
|
|
||||||
setup: (self) => self
|
|
||||||
.hook(SystemTray, (self) => {
|
|
||||||
self.children = SystemTray.items.map(SysTrayItem);
|
|
||||||
self.show_all();
|
|
||||||
})
|
|
||||||
,
|
|
||||||
});
|
|
||||||
const trayRevealer = Widget.Revealer({
|
|
||||||
revealChild: true,
|
|
||||||
transition: 'slide_left',
|
|
||||||
transitionDuration: userOptions.animations.durationLarge,
|
|
||||||
child: trayContent,
|
|
||||||
});
|
|
||||||
return Box({
|
|
||||||
...props,
|
|
||||||
children: [trayRevealer],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
@ -1,224 +0,0 @@
|
||||||
const { GLib, Gdk, Gtk } = imports.gi;
|
|
||||||
const Lang = imports.lang;
|
|
||||||
const Cairo = imports.cairo;
|
|
||||||
const Pango = imports.gi.Pango;
|
|
||||||
const PangoCairo = imports.gi.PangoCairo;
|
|
||||||
import App from 'resource:///com/github/Aylur/ags/app.js';
|
|
||||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
const { Box, DrawingArea, EventBox } = Widget;
|
|
||||||
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
|
|
||||||
|
|
||||||
const dummyWs = Box({ className: 'bar-ws' }); // Not shown. Only for getting size props
|
|
||||||
const dummyActiveWs = Box({ className: 'bar-ws bar-ws-active' }); // Not shown. Only for getting size props
|
|
||||||
const dummyOccupiedWs = Box({ className: 'bar-ws bar-ws-occupied' }); // Not shown. Only for getting size props
|
|
||||||
|
|
||||||
const mix = (value1, value2, perc) => {
|
|
||||||
return value1 * perc + value2 * (1 - perc);
|
|
||||||
}
|
|
||||||
|
|
||||||
const getFontWeightName = (weight) => {
|
|
||||||
switch (weight) {
|
|
||||||
case Pango.Weight.ULTRA_LIGHT:
|
|
||||||
return 'UltraLight';
|
|
||||||
case Pango.Weight.LIGHT:
|
|
||||||
return 'Light';
|
|
||||||
case Pango.Weight.NORMAL:
|
|
||||||
return 'Normal';
|
|
||||||
case Pango.Weight.BOLD:
|
|
||||||
return 'Bold';
|
|
||||||
case Pango.Weight.ULTRA_BOLD:
|
|
||||||
return 'UltraBold';
|
|
||||||
case Pango.Weight.HEAVY:
|
|
||||||
return 'Heavy';
|
|
||||||
default:
|
|
||||||
return 'Normal';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Font size = workspace id
|
|
||||||
const WorkspaceContents = (count = 10) => {
|
|
||||||
return DrawingArea({
|
|
||||||
className: 'bar-ws-container',
|
|
||||||
attribute: {
|
|
||||||
initialized: false,
|
|
||||||
workspaceMask: 0,
|
|
||||||
workspaceGroup: 0,
|
|
||||||
updateMask: (self) => {
|
|
||||||
const offset = Math.floor((Hyprland.active.workspace.id - 1) / count) * userOptions.workspaces.shown;
|
|
||||||
// if (self.attribute.initialized) return; // We only need this to run once
|
|
||||||
const workspaces = Hyprland.workspaces;
|
|
||||||
let workspaceMask = 0;
|
|
||||||
for (let i = 0; i < workspaces.length; i++) {
|
|
||||||
const ws = workspaces[i];
|
|
||||||
if (ws.id <= offset || ws.id > offset + count) continue; // Out of range, ignore
|
|
||||||
if (workspaces[i].windows > 0)
|
|
||||||
workspaceMask |= (1 << (ws.id - offset));
|
|
||||||
}
|
|
||||||
// console.log('Mask:', workspaceMask.toString(2));
|
|
||||||
self.attribute.workspaceMask = workspaceMask;
|
|
||||||
// self.attribute.initialized = true;
|
|
||||||
self.queue_draw();
|
|
||||||
},
|
|
||||||
toggleMask: (self, occupied, name) => {
|
|
||||||
if (occupied) self.attribute.workspaceMask |= (1 << parseInt(name));
|
|
||||||
else self.attribute.workspaceMask &= ~(1 << parseInt(name));
|
|
||||||
self.queue_draw();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
setup: (area) => area
|
|
||||||
.hook(Hyprland.active.workspace, (self) => {
|
|
||||||
self.setCss(`font-size: ${(Hyprland.active.workspace.id - 1) % count + 1}px;`);
|
|
||||||
const previousGroup = self.attribute.workspaceGroup;
|
|
||||||
const currentGroup = Math.floor((Hyprland.active.workspace.id - 1) / count);
|
|
||||||
if (currentGroup !== previousGroup) {
|
|
||||||
self.attribute.updateMask(self);
|
|
||||||
self.attribute.workspaceGroup = currentGroup;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.hook(Hyprland, (self) => self.attribute.updateMask(self), 'notify::workspaces')
|
|
||||||
.on('draw', Lang.bind(area, (area, cr) => {
|
|
||||||
const offset = Math.floor((Hyprland.active.workspace.id - 1) / count) * userOptions.workspaces.shown;
|
|
||||||
|
|
||||||
const allocation = area.get_allocation();
|
|
||||||
const { width, height } = allocation;
|
|
||||||
|
|
||||||
const workspaceStyleContext = dummyWs.get_style_context();
|
|
||||||
const workspaceDiameter = workspaceStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
|
|
||||||
const workspaceRadius = workspaceDiameter / 2;
|
|
||||||
const workspaceFontSize = workspaceStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL) / 4 * 3;
|
|
||||||
const workspaceFontFamily = workspaceStyleContext.get_property('font-family', Gtk.StateFlags.NORMAL);
|
|
||||||
const workspaceFontWeight = workspaceStyleContext.get_property('font-weight', Gtk.StateFlags.NORMAL);
|
|
||||||
const wsbg = workspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
|
|
||||||
const wsfg = workspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
|
|
||||||
|
|
||||||
const occupiedWorkspaceStyleContext = dummyOccupiedWs.get_style_context();
|
|
||||||
const occupiedbg = occupiedWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
|
|
||||||
const occupiedfg = occupiedWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
|
|
||||||
|
|
||||||
const activeWorkspaceStyleContext = dummyActiveWs.get_style_context();
|
|
||||||
const activebg = activeWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
|
|
||||||
const activefg = activeWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
|
|
||||||
area.set_size_request(workspaceDiameter * count, -1);
|
|
||||||
const widgetStyleContext = area.get_style_context();
|
|
||||||
const activeWs = widgetStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL);
|
|
||||||
|
|
||||||
const activeWsCenterX = -(workspaceDiameter / 2) + (workspaceDiameter * activeWs);
|
|
||||||
const activeWsCenterY = height / 2;
|
|
||||||
|
|
||||||
// Font
|
|
||||||
const layout = PangoCairo.create_layout(cr);
|
|
||||||
const fontDesc = Pango.font_description_from_string(`${workspaceFontFamily[0]} ${getFontWeightName(workspaceFontWeight)} ${workspaceFontSize}`);
|
|
||||||
layout.set_font_description(fontDesc);
|
|
||||||
cr.setAntialias(Cairo.Antialias.BEST);
|
|
||||||
// Get kinda min radius for number indicators
|
|
||||||
layout.set_text("0".repeat(count.toString().length), -1);
|
|
||||||
const [layoutWidth, layoutHeight] = layout.get_pixel_size();
|
|
||||||
const indicatorRadius = Math.max(layoutWidth, layoutHeight) / 2 * 1.15; // smaller than sqrt(2)*radius
|
|
||||||
const indicatorGap = workspaceRadius - indicatorRadius;
|
|
||||||
|
|
||||||
for (let i = 1; i <= count; i++) {
|
|
||||||
if (area.attribute.workspaceMask & (1 << i)) {
|
|
||||||
// Draw bg highlight
|
|
||||||
cr.setSourceRGBA(occupiedbg.red, occupiedbg.green, occupiedbg.blue, occupiedbg.alpha);
|
|
||||||
const wsCenterX = -(workspaceRadius) + (workspaceDiameter * i);
|
|
||||||
const wsCenterY = height / 2;
|
|
||||||
if (!(area.attribute.workspaceMask & (1 << (i - 1)))) { // Left
|
|
||||||
cr.arc(wsCenterX, wsCenterY, workspaceRadius, 0.5 * Math.PI, 1.5 * Math.PI);
|
|
||||||
cr.fill();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cr.rectangle(wsCenterX - workspaceRadius, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2)
|
|
||||||
cr.fill();
|
|
||||||
}
|
|
||||||
if (!(area.attribute.workspaceMask & (1 << (i + 1)))) { // Right
|
|
||||||
cr.arc(wsCenterX, wsCenterY, workspaceRadius, -0.5 * Math.PI, 0.5 * Math.PI);
|
|
||||||
cr.fill();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cr.rectangle(wsCenterX, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2)
|
|
||||||
cr.fill();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw active ws
|
|
||||||
cr.setSourceRGBA(activebg.red, activebg.green, activebg.blue, activebg.alpha);
|
|
||||||
cr.arc(activeWsCenterX, activeWsCenterY, indicatorRadius, 0, 2 * Math.PI);
|
|
||||||
cr.fill();
|
|
||||||
|
|
||||||
// Draw workspace numbers
|
|
||||||
for (let i = 1; i <= count; i++) {
|
|
||||||
const inactivecolors = area.attribute.workspaceMask & (1 << i) ? occupiedfg : wsfg;
|
|
||||||
if (i == activeWs) {
|
|
||||||
cr.setSourceRGBA(activefg.red, activefg.green, activefg.blue, activefg.alpha);
|
|
||||||
}
|
|
||||||
// Moving to
|
|
||||||
else if ((i == Math.floor(activeWs) && Hyprland.active.workspace.id < activeWs) || (i == Math.ceil(activeWs) && Hyprland.active.workspace.id > activeWs)) {
|
|
||||||
cr.setSourceRGBA(mix(activefg.red, inactivecolors.red, 1 - Math.abs(activeWs - i)), mix(activefg.green, inactivecolors.green, 1 - Math.abs(activeWs - i)), mix(activefg.blue, inactivecolors.blue, 1 - Math.abs(activeWs - i)), activefg.alpha);
|
|
||||||
}
|
|
||||||
// Moving from
|
|
||||||
else if ((i == Math.floor(activeWs) && Hyprland.active.workspace.id > activeWs) || (i == Math.ceil(activeWs) && Hyprland.active.workspace.id < activeWs)) {
|
|
||||||
cr.setSourceRGBA(mix(activefg.red, inactivecolors.red, 1 - Math.abs(activeWs - i)), mix(activefg.green, inactivecolors.green, 1 - Math.abs(activeWs - i)), mix(activefg.blue, inactivecolors.blue, 1 - Math.abs(activeWs - i)), activefg.alpha);
|
|
||||||
}
|
|
||||||
// Inactive
|
|
||||||
else
|
|
||||||
cr.setSourceRGBA(inactivecolors.red, inactivecolors.green, inactivecolors.blue, inactivecolors.alpha);
|
|
||||||
|
|
||||||
layout.set_text(`${i + offset}`, -1);
|
|
||||||
const [layoutWidth, layoutHeight] = layout.get_pixel_size();
|
|
||||||
const x = -workspaceRadius + (workspaceDiameter * i) - (layoutWidth / 2);
|
|
||||||
const y = (height - layoutHeight) / 2;
|
|
||||||
cr.moveTo(x, y);
|
|
||||||
PangoCairo.show_layout(cr, layout);
|
|
||||||
cr.stroke();
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export default () => EventBox({
|
|
||||||
onScrollUp: () => Hyprland.messageAsync(`dispatch workspace -1`).catch(print),
|
|
||||||
onScrollDown: () => Hyprland.messageAsync(`dispatch workspace +1`).catch(print),
|
|
||||||
onMiddleClick: () => toggleWindowOnAllMonitors('osk'),
|
|
||||||
onSecondaryClick: () => App.toggleWindow('overview'),
|
|
||||||
attribute: {
|
|
||||||
clicked: false,
|
|
||||||
ws_group: 0,
|
|
||||||
},
|
|
||||||
child: Box({
|
|
||||||
homogeneous: true,
|
|
||||||
className: 'bar-group-margin',
|
|
||||||
children: [Box({
|
|
||||||
className: 'bar-group bar-group-standalone bar-group-pad',
|
|
||||||
css: 'min-width: 2px;',
|
|
||||||
children: [WorkspaceContents(userOptions.workspaces.shown)],
|
|
||||||
})]
|
|
||||||
}),
|
|
||||||
setup: (self) => {
|
|
||||||
self.add_events(Gdk.EventMask.POINTER_MOTION_MASK);
|
|
||||||
self.on('motion-notify-event', (self, event) => {
|
|
||||||
if (!self.attribute.clicked) return;
|
|
||||||
const [_, cursorX, cursorY] = event.get_coords();
|
|
||||||
const widgetWidth = self.get_allocation().width;
|
|
||||||
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
|
|
||||||
Utils.execAsync([`${App.configDir}/scripts/hyprland/workspace_action.sh`, 'workspace', `${wsId}`])
|
|
||||||
.catch(print);
|
|
||||||
})
|
|
||||||
self.on('button-press-event', (self, event) => {
|
|
||||||
if (event.get_button()[1] === 1) {
|
|
||||||
self.attribute.clicked = true;
|
|
||||||
const [_, cursorX, cursorY] = event.get_coords();
|
|
||||||
const widgetWidth = self.get_allocation().width;
|
|
||||||
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
|
|
||||||
Utils.execAsync([`${App.configDir}/scripts/hyprland/workspace_action.sh`, 'workspace', `${wsId}`])
|
|
||||||
.catch(print);
|
|
||||||
}
|
|
||||||
else if (event.get_button()[1] === 8) {
|
|
||||||
Hyprland.messageAsync(`dispatch togglespecialworkspace`).catch(print);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
self.on('button-release-event', (self) => self.attribute.clicked = false);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
@ -1,183 +0,0 @@
|
||||||
const { GLib, Gdk, Gtk } = imports.gi;
|
|
||||||
const Lang = imports.lang;
|
|
||||||
const Cairo = imports.cairo;
|
|
||||||
const Pango = imports.gi.Pango;
|
|
||||||
const PangoCairo = imports.gi.PangoCairo;
|
|
||||||
import Widget from "resource:///com/github/Aylur/ags/widget.js";
|
|
||||||
import Sway from "../../../services/sway.js";
|
|
||||||
import * as Utils from "resource:///com/github/Aylur/ags/utils.js";
|
|
||||||
const { execAsync, exec } = Utils;
|
|
||||||
const { Box, DrawingArea, EventBox } = Widget;
|
|
||||||
|
|
||||||
const dummyWs = Box({ className: 'bar-ws' }); // Not shown. Only for getting size props
|
|
||||||
const dummyActiveWs = Box({ className: 'bar-ws bar-ws-active' }); // Not shown. Only for getting size props
|
|
||||||
const dummyOccupiedWs = Box({ className: 'bar-ws bar-ws-occupied' }); // Not shown. Only for getting size props
|
|
||||||
|
|
||||||
const switchToWorkspace = (arg) => Utils.execAsync(`swaymsg workspace ${arg}`).catch(print);
|
|
||||||
const switchToRelativeWorkspace = (self, num) =>
|
|
||||||
execAsync([`${App.configDir}/scripts/sway/swayToRelativeWs.sh`, `${num}`]).catch(print);
|
|
||||||
|
|
||||||
const WorkspaceContents = (count = 10) => {
|
|
||||||
return DrawingArea({
|
|
||||||
css: `transition: 90ms cubic-bezier(0.1, 1, 0, 1);`,
|
|
||||||
attribute: {
|
|
||||||
initialized: false,
|
|
||||||
workspaceMask: 0,
|
|
||||||
updateMask: (self) => {
|
|
||||||
if (self.attribute.initialized) return; // We only need this to run once
|
|
||||||
const workspaces = Sway.workspaces;
|
|
||||||
let workspaceMask = 0;
|
|
||||||
// console.log('----------------')
|
|
||||||
for (let i = 0; i < workspaces.length; i++) {
|
|
||||||
const ws = workspaces[i];
|
|
||||||
// console.log(ws.name, ',', ws.num);
|
|
||||||
if (!Number(ws.name)) return;
|
|
||||||
const id = Number(ws.name);
|
|
||||||
if (id <= 0) continue; // Ignore scratchpads
|
|
||||||
if (id > count) return; // Not rendered
|
|
||||||
if (workspaces[i].windows > 0) {
|
|
||||||
workspaceMask |= (1 << id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.attribute.workspaceMask = workspaceMask;
|
|
||||||
self.attribute.initialized = true;
|
|
||||||
},
|
|
||||||
toggleMask: (self, occupied, name) => {
|
|
||||||
if (occupied) self.attribute.workspaceMask |= (1 << parseInt(name));
|
|
||||||
else self.attribute.workspaceMask &= ~(1 << parseInt(name));
|
|
||||||
},
|
|
||||||
},
|
|
||||||
setup: (area) => area
|
|
||||||
.hook(Sway.active.workspace, (area) => {
|
|
||||||
area.setCss(`font-size: ${Sway.active.workspace.name}px;`)
|
|
||||||
})
|
|
||||||
.hook(Sway, (self) => self.attribute.updateMask(self), 'notify::workspaces')
|
|
||||||
// .hook(Hyprland, (self, name) => self.attribute.toggleMask(self, true, name), 'workspace-added')
|
|
||||||
// .hook(Hyprland, (self, name) => self.attribute.toggleMask(self, false, name), 'workspace-removed')
|
|
||||||
.on('draw', Lang.bind(area, (area, cr) => {
|
|
||||||
const allocation = area.get_allocation();
|
|
||||||
const { width, height } = allocation;
|
|
||||||
|
|
||||||
const workspaceStyleContext = dummyWs.get_style_context();
|
|
||||||
const workspaceDiameter = workspaceStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
|
|
||||||
const workspaceRadius = workspaceDiameter / 2;
|
|
||||||
const workspaceFontSize = workspaceStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL) / 4 * 3;
|
|
||||||
const workspaceFontFamily = workspaceStyleContext.get_property('font-family', Gtk.StateFlags.NORMAL);
|
|
||||||
const wsbg = workspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
|
|
||||||
const wsfg = workspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
|
|
||||||
|
|
||||||
const occupiedWorkspaceStyleContext = dummyOccupiedWs.get_style_context();
|
|
||||||
const occupiedbg = occupiedWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
|
|
||||||
const occupiedfg = occupiedWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
|
|
||||||
|
|
||||||
const activeWorkspaceStyleContext = dummyActiveWs.get_style_context();
|
|
||||||
const activebg = activeWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
|
|
||||||
const activefg = activeWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
|
|
||||||
area.set_size_request(workspaceDiameter * count, -1);
|
|
||||||
const widgetStyleContext = area.get_style_context();
|
|
||||||
const activeWs = widgetStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL);
|
|
||||||
|
|
||||||
const activeWsCenterX = -(workspaceDiameter / 2) + (workspaceDiameter * activeWs);
|
|
||||||
const activeWsCenterY = height / 2;
|
|
||||||
|
|
||||||
// Font
|
|
||||||
const layout = PangoCairo.create_layout(cr);
|
|
||||||
const fontDesc = Pango.font_description_from_string(`${workspaceFontFamily[0]} ${workspaceFontSize}`);
|
|
||||||
layout.set_font_description(fontDesc);
|
|
||||||
cr.setAntialias(Cairo.Antialias.BEST);
|
|
||||||
// Get kinda min radius for number indicators
|
|
||||||
layout.set_text("0".repeat(count.toString().length), -1);
|
|
||||||
const [layoutWidth, layoutHeight] = layout.get_pixel_size();
|
|
||||||
const indicatorRadius = Math.max(layoutWidth, layoutHeight) / 2 * 1.2; // a bit smaller than sqrt(2)*radius
|
|
||||||
const indicatorGap = workspaceRadius - indicatorRadius;
|
|
||||||
|
|
||||||
// Draw workspace numbers
|
|
||||||
for (let i = 1; i <= count; i++) {
|
|
||||||
if (area.attribute.workspaceMask & (1 << i)) {
|
|
||||||
// Draw bg highlight
|
|
||||||
cr.setSourceRGBA(occupiedbg.red, occupiedbg.green, occupiedbg.blue, occupiedbg.alpha);
|
|
||||||
const wsCenterX = -(workspaceRadius) + (workspaceDiameter * i);
|
|
||||||
const wsCenterY = height / 2;
|
|
||||||
if (!(area.attribute.workspaceMask & (1 << (i - 1)))) { // Left
|
|
||||||
cr.arc(wsCenterX, wsCenterY, workspaceRadius, 0.5 * Math.PI, 1.5 * Math.PI);
|
|
||||||
cr.fill();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cr.rectangle(wsCenterX - workspaceRadius, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2)
|
|
||||||
cr.fill();
|
|
||||||
}
|
|
||||||
if (!(area.attribute.workspaceMask & (1 << (i + 1)))) { // Right
|
|
||||||
cr.arc(wsCenterX, wsCenterY, workspaceRadius, -0.5 * Math.PI, 0.5 * Math.PI);
|
|
||||||
cr.fill();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cr.rectangle(wsCenterX, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2)
|
|
||||||
cr.fill();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set color for text
|
|
||||||
cr.setSourceRGBA(occupiedfg.red, occupiedfg.green, occupiedfg.blue, occupiedfg.alpha);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
cr.setSourceRGBA(wsfg.red, wsfg.green, wsfg.blue, wsfg.alpha);
|
|
||||||
layout.set_text(`${i}`, -1);
|
|
||||||
const [layoutWidth, layoutHeight] = layout.get_pixel_size();
|
|
||||||
const x = -workspaceRadius + (workspaceDiameter * i) - (layoutWidth / 2);
|
|
||||||
const y = (height - layoutHeight) / 2;
|
|
||||||
cr.moveTo(x, y);
|
|
||||||
// cr.showText(text);
|
|
||||||
PangoCairo.show_layout(cr, layout);
|
|
||||||
cr.stroke();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw active ws
|
|
||||||
// base
|
|
||||||
cr.setSourceRGBA(activebg.red, activebg.green, activebg.blue, activebg.alpha);
|
|
||||||
cr.arc(activeWsCenterX, activeWsCenterY, indicatorRadius, 0, 2 * Math.PI);
|
|
||||||
cr.fill();
|
|
||||||
// inner decor
|
|
||||||
cr.setSourceRGBA(activefg.red, activefg.green, activefg.blue, activefg.alpha);
|
|
||||||
cr.arc(activeWsCenterX, activeWsCenterY, indicatorRadius * 0.2, 0, 2 * Math.PI);
|
|
||||||
cr.fill();
|
|
||||||
}))
|
|
||||||
,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export default () => EventBox({
|
|
||||||
onScrollUp: (self) => switchToRelativeWorkspace(self, -1),
|
|
||||||
onScrollDown: (self) => switchToRelativeWorkspace(self, +1),
|
|
||||||
onMiddleClick: () => toggleWindowOnAllMonitors('osk'),
|
|
||||||
onSecondaryClick: () => App.toggleWindow('overview'),
|
|
||||||
attribute: { clicked: false },
|
|
||||||
child: Box({
|
|
||||||
homogeneous: true,
|
|
||||||
className: 'bar-group-margin',
|
|
||||||
children: [Box({
|
|
||||||
className: 'bar-group bar-group-standalone bar-group-pad',
|
|
||||||
css: 'min-width: 2px;',
|
|
||||||
children: [
|
|
||||||
WorkspaceContents(10),
|
|
||||||
]
|
|
||||||
})]
|
|
||||||
}),
|
|
||||||
setup: (self) => {
|
|
||||||
self.add_events(Gdk.EventMask.POINTER_MOTION_MASK);
|
|
||||||
self.on('motion-notify-event', (self, event) => {
|
|
||||||
if (!self.attribute.clicked) return;
|
|
||||||
const [_, cursorX, cursorY] = event.get_coords();
|
|
||||||
const widgetWidth = self.get_allocation().width;
|
|
||||||
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
|
|
||||||
switchToWorkspace(wsId);
|
|
||||||
})
|
|
||||||
self.on('button-press-event', (self, event) => {
|
|
||||||
if (!(event.get_button()[1] === 1)) return; // We're only interested in left-click here
|
|
||||||
self.attribute.clicked = true;
|
|
||||||
const [_, cursorX, cursorY] = event.get_coords();
|
|
||||||
const widgetWidth = self.get_allocation().width;
|
|
||||||
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
|
|
||||||
switchToWorkspace(wsId);
|
|
||||||
})
|
|
||||||
self.on('button-release-event', (self) => self.attribute.clicked = false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,122 +0,0 @@
|
||||||
export const keybindList = [[
|
|
||||||
{
|
|
||||||
"icon": "pin_drop",
|
|
||||||
"name": "Workspaces: navigation",
|
|
||||||
"binds": [
|
|
||||||
{ "keys": ["", "+", "#"], "action": "Go to workspace #" },
|
|
||||||
{ "keys": ["", "+", "S"], "action": "Toggle special workspace" },
|
|
||||||
{ "keys": ["", "+", "(Scroll ↑↓)"], "action": "Go to workspace -1/+1" },
|
|
||||||
{ "keys": ["Ctrl", "", "+", "←"], "action": "Go to workspace on the left" },
|
|
||||||
{ "keys": ["Ctrl", "", "+", "→"], "action": "Go to workspace on the right" },
|
|
||||||
{ "keys": ["", "+", "PageUp"], "action": "Go to workspace on the left" },
|
|
||||||
{ "keys": ["", "+", "PageDown"], "action": "Go to workspace on the right" }
|
|
||||||
],
|
|
||||||
"id": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon": "overview_key",
|
|
||||||
"name": "Workspaces: management",
|
|
||||||
"binds": [
|
|
||||||
{ "keys": ["", "Alt", "+", "#"], "action": "Move window to workspace #" },
|
|
||||||
{ "keys": ["", "Alt", "+", "S"], "action": "Move window to special workspace" },
|
|
||||||
{ "keys": ["", "Alt", "+", "PageUp"], "action": "Move window to workspace on the left" },
|
|
||||||
{ "keys": ["", "Alt", "+", "PageDown"], "action": "Move window to workspace on the right" }
|
|
||||||
],
|
|
||||||
"id": 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon": "move_group",
|
|
||||||
"name": "Windows",
|
|
||||||
"binds": [
|
|
||||||
{ "keys": ["", "+", "←↑→↓"], "action": "Focus window in direction" },
|
|
||||||
{ "keys": ["", "Shift", "+", "←↑→↓"], "action": "Swap window in direction" },
|
|
||||||
{ "keys": ["", "+", ";"], "action": "Split ratio -" },
|
|
||||||
{ "keys": ["", "+", "'"], "action": "Split ratio +" },
|
|
||||||
{ "keys": ["", "+", "Lmb"], "action": "Move window" },
|
|
||||||
{ "keys": ["", "+", "Rmb"], "action": "Resize window" },
|
|
||||||
{ "keys": ["", "Alt", "+", "Space"], "action": "Float window" },
|
|
||||||
{ "keys": ["", "+", "F"], "action": "Fullscreen" },
|
|
||||||
{ "keys": ["", "Alt", "+", "F"], "action": "Fake fullscreen" }
|
|
||||||
],
|
|
||||||
"id": 3
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"icon": "widgets",
|
|
||||||
"name": "Widgets (AGS)",
|
|
||||||
"binds": [
|
|
||||||
{ "keys": ["", "OR", "", "+", "Tab"], "action": "Toggle overview/launcher" },
|
|
||||||
{ "keys": ["Ctrl", "", "+", "R"], "action": "Restart AGS" },
|
|
||||||
{ "keys": ["", "+", "/"], "action": "Toggle this cheatsheet" },
|
|
||||||
{ "keys": ["", "+", "N"], "action": "Toggle system sidebar" },
|
|
||||||
{ "keys": ["", "+", "B", "OR", "", "+", "O"], "action": "Toggle utilities sidebar" },
|
|
||||||
{ "keys": ["", "+", "K"], "action": "Toggle virtual keyboard" },
|
|
||||||
{ "keys": ["Ctrl", "Alt", "+", "Del"], "action": "Power/Session menu" },
|
|
||||||
|
|
||||||
{ "keys": ["Esc"], "action": "Exit a window" },
|
|
||||||
{ "keys": ["rightCtrl"], "action": "Dismiss/close sidebar" },
|
|
||||||
|
|
||||||
{ "keys": ["Ctrl", "", "+", "T"], "action": "Change wallpaper+colorscheme" },
|
|
||||||
|
|
||||||
// { "keys": ["", "+", "B"], "action": "Toggle left sidebar" },
|
|
||||||
// { "keys": ["", "+", "N"], "action": "Toggle right sidebar" },
|
|
||||||
// { "keys": ["", "+", "G"], "action": "Toggle volume mixer" },
|
|
||||||
// { "keys": ["", "+", "M"], "action": "Toggle useless audio visualizer" },
|
|
||||||
// { "keys": ["(right)Ctrl"], "action": "Dismiss notification & close menus" }
|
|
||||||
],
|
|
||||||
"id": 4
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon": "construction",
|
|
||||||
"name": "Utilities",
|
|
||||||
"binds": [
|
|
||||||
{ "keys": ["PrtSc"], "action": "Screenshot >> clipboard" },
|
|
||||||
{ "keys": ["Ctrl", "PrtSc"], "action": "Screenshot >> file + clipboard" },
|
|
||||||
{ "keys": ["", "Shift", "+", "S"], "action": "Screen snip >> clipboard" },
|
|
||||||
{ "keys": ["", "Shift", "+", "T"], "action": "Image to text >> clipboard" },
|
|
||||||
{ "keys": ["", "Shift", "+", "C"], "action": "Color picker" },
|
|
||||||
{ "keys": ["", "Alt", "+", "R"], "action": "Record region" },
|
|
||||||
{ "keys": ["Ctrl", "Alt", "+", "R"], "action": "Record region with sound" },
|
|
||||||
{ "keys": ["", "Shift", "Alt", "+", "R"], "action": "Record screen with sound" }
|
|
||||||
],
|
|
||||||
"id": 5
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"icon": "apps",
|
|
||||||
"name": "Apps",
|
|
||||||
"binds": [
|
|
||||||
{ "keys": ["", "+", "T"], "action": "Launch terminal: foot" },
|
|
||||||
{ "keys": ["", "+", "W"], "action": "Launch browser: Firefox" },
|
|
||||||
{ "keys": ["", "+", "C"], "action": "Launch editor: vscode" },
|
|
||||||
{ "keys": ["", "+", "X"], "action": "Launch editor: GNOME Text Editor" },
|
|
||||||
{ "keys": ["", "+", "I"], "action": "Launch settings: GNOME Control center" }
|
|
||||||
],
|
|
||||||
"id": 6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon": "keyboard",
|
|
||||||
"name": "Typing",
|
|
||||||
"binds": [
|
|
||||||
{ "keys": ["", "+", "V"], "action": "Clipboard history >> clipboard" },
|
|
||||||
{ "keys": ["", "+", "."], "action": "Emoji picker >> clipboard" },
|
|
||||||
],
|
|
||||||
"id": 7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon": "terminal",
|
|
||||||
"name": "Launcher actions",
|
|
||||||
"binds": [
|
|
||||||
{ "keys": [">raw"], "action": "Toggle mouse acceleration" },
|
|
||||||
{ "keys": [">img"], "action": "Select wallpaper and generate colorscheme" },
|
|
||||||
{ "keys": [">light"], "action": "Switch to light theme" },
|
|
||||||
{ "keys": [">dark"], "action": "Switch to dark theme" },
|
|
||||||
{ "keys": [">badapple"], "action": "Apply black n' white colorscheme" },
|
|
||||||
{ "keys": [">color"], "action": "Pick acccent color" },
|
|
||||||
{ "keys": [">todo"], "action": "Type something after that to add a To-do item" },
|
|
||||||
],
|
|
||||||
"id": 8
|
|
||||||
}
|
|
||||||
]];
|
|
||||||
|
|
@ -1,195 +0,0 @@
|
||||||
export const periodicTable = [
|
|
||||||
[
|
|
||||||
{ name: 'Hydrogen', symbol: 'H', number: 1, weight: 1.01, type: 'nonmetal' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: 'Helium', symbol: 'He', number: 2, weight: 4.00, type: 'noblegas' },
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{ name: 'Lithium', symbol: 'Li', number: 3, weight: 6.94, type: 'metal' },
|
|
||||||
{ name: 'Beryllium', symbol: 'Be', number: 4, weight: 9.01, type: 'metal' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: 'Boron', symbol: 'B', number: 5, weight: 10.81, type: 'nonmetal' },
|
|
||||||
{ name: 'Carbon', symbol: 'C', number: 6, weight: 12.01, type: 'nonmetal' },
|
|
||||||
{ name: 'Nitrogen', symbol: 'N', number: 7, weight: 14.01, type: 'nonmetal' },
|
|
||||||
{ name: 'Oxygen', symbol: 'O', number: 8, weight: 16, type: 'nonmetal' },
|
|
||||||
{ name: 'Fluorine', symbol: 'F', number: 9, weight: 19, type: 'nonmetal' },
|
|
||||||
{ name: 'Neon', symbol: 'Ne', number: 10, weight: 20.18, type: 'noblegas' },
|
|
||||||
|
|
||||||
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{ name: 'Sodium', symbol: 'Na', number: 11, weight: 22.99, type: 'metal' },
|
|
||||||
{ name: 'Magnesium', symbol: 'Mg', number: 12, weight: 24.31, type: 'metal' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: 'Aluminum', symbol: 'Al', number: 13, weight: 26.98, type: 'metal' },
|
|
||||||
{ name: 'Silicon', symbol: 'Si', number: 14, weight: 28.09, type: 'nonmetal' },
|
|
||||||
{ name: 'Phosphorus', symbol: 'P', number: 15, weight: 30.97, type: 'nonmetal' },
|
|
||||||
{ name: 'Sulfur', symbol: 'S', number: 16, weight: 32.07, type: 'nonmetal' },
|
|
||||||
{ name: 'Chlorine', symbol: 'Cl', number: 17, weight: 35.45, type: 'nonmetal' },
|
|
||||||
{ name: 'Argon', symbol: 'Ar', number: 18, weight: 39.95, type: 'noblegas' },
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{ name: 'Kalium', symbol: 'K', number: 19, weight: 39.098, type: 'metal' },
|
|
||||||
{ name: 'Calcium', symbol: 'Ca', number: 20, weight: 40.078, type: 'metal' },
|
|
||||||
{ name: 'Scandium', symbol: 'Sc', number: 21, weight: 44.956, type: 'metal' },
|
|
||||||
{ name: 'Titanium', symbol: 'Ti', number: 22, weight: 47.87, type: 'metal' },
|
|
||||||
{ name: 'Vanadium', symbol: 'V', number: 23, weight: 50.94, type: 'metal' },
|
|
||||||
{ name: 'Chromium', symbol: 'Cr', number: 24, weight: 52, type: 'metal', icon: 'chromium-browser' },
|
|
||||||
{ name: 'Manganese', symbol: 'Mn', number: 25, weight: 54.94, type: 'metal' },
|
|
||||||
{ name: 'Iron', symbol: 'Fe', number: 26, weight: 55.85, type: 'metal' },
|
|
||||||
{ name: 'Cobalt', symbol: 'Co', number: 27, weight: 58.93, type: 'metal' },
|
|
||||||
{ name: 'Nickel', symbol: 'Ni', number: 28, weight: 58.69, type: 'metal' },
|
|
||||||
{ name: 'Copper', symbol: 'Cu', number: 29, weight: 63.55, type: 'metal' },
|
|
||||||
{ name: 'Zinc', symbol: 'Zn', number: 30, weight: 65.38, type: 'metal' },
|
|
||||||
{ name: 'Gallium', symbol: 'Ga', number: 31, weight: 69.72, type: 'metal' },
|
|
||||||
{ name: 'Germanium', symbol: 'Ge', number: 32, weight: 72.63, type: 'metal' },
|
|
||||||
{ name: 'Arsenic', symbol: 'As', number: 33, weight: 74.92, type: 'nonmetal' },
|
|
||||||
{ name: 'Selenium', symbol: 'Se', number: 34, weight: 78.96, type: 'nonmetal' },
|
|
||||||
{ name: 'Bromine', symbol: 'Br', number: 35, weight: 79.904, type: 'nonmetal' },
|
|
||||||
{ name: 'Krypton', symbol: 'Kr', number: 36, weight: 83.8, type: 'noblegas' },
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{ name: 'Rubidium', symbol: 'Rb', number: 37, weight: 85.47, type: 'metal' },
|
|
||||||
{ name: 'Strontium', symbol: 'Sr', number: 38, weight: 87.62, type: 'metal' },
|
|
||||||
{ name: 'Yttrium', symbol: 'Y', number: 39, weight: 88.91, type: 'metal' },
|
|
||||||
{ name: 'Zirconium', symbol: 'Zr', number: 40, weight: 91.22, type: 'metal' },
|
|
||||||
{ name: 'Niobium', symbol: 'Nb', number: 41, weight: 92.91, type: 'metal' },
|
|
||||||
{ name: 'Molybdenum', symbol: 'Mo', number: 42, weight: 95.94, type: 'metal' },
|
|
||||||
{ name: 'Technetium', symbol: 'Tc', number: 43, weight: 98, type: 'metal' },
|
|
||||||
{ name: 'Ruthenium', symbol: 'Ru', number: 44, weight: 101.07, type: 'metal' },
|
|
||||||
{ name: 'Rhodium', symbol: 'Rh', number: 45, weight: 102.91, type: 'metal' },
|
|
||||||
{ name: 'Palladium', symbol: 'Pd', number: 46, weight: 106.42, type: 'metal' },
|
|
||||||
{ name: 'Silver', symbol: 'Ag', number: 47, weight: 107.87, type: 'metal' },
|
|
||||||
{ name: 'Cadmium', symbol: 'Cd', number: 48, weight: 112.41, type: 'metal' },
|
|
||||||
{ name: 'Indium', symbol: 'In', number: 49, weight: 114.82, type: 'metal' },
|
|
||||||
{ name: 'Tin', symbol: 'Sn', number: 50, weight: 118.71, type: 'metal' },
|
|
||||||
{ name: 'Antimony', symbol: 'Sb', number: 51, weight: 121.76, type: 'metal' },
|
|
||||||
{ name: 'Tellurium', symbol: 'Te', number: 52, weight: 127.6, type: 'nonmetal' },
|
|
||||||
{ name: 'Iodine', symbol: 'I', number: 53, weight: 126.9, type: 'nonmetal' },
|
|
||||||
{ name: 'Xenon', symbol: 'Xe', number: 54, weight: 131.29, type: 'noblegas' },
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{ name: 'Cesium', symbol: 'Cs', number: 55, weight: 132.91, type: 'metal' },
|
|
||||||
{ name: 'Barium', symbol: 'Ba', number: 56, weight: 137.33, type: 'metal' },
|
|
||||||
{ name: 'Lanthanum', symbol: 'La', number: 57, weight: 138.91, type: 'lanthanum' },
|
|
||||||
{ name: 'Hafnium', symbol: 'Hf', number: 72, weight: 178.49, type: 'metal' },
|
|
||||||
{ name: 'Tantalum', symbol: 'Ta', number: 73, weight: 180.95, type: 'metal' },
|
|
||||||
{ name: 'Tungsten', symbol: 'W', number: 74, weight: 183.84, type: 'metal' },
|
|
||||||
{ name: 'Rhenium', symbol: 'Re', number: 75, weight: 186.21, type: 'metal' },
|
|
||||||
{ name: 'Osmium', symbol: 'Os', number: 76, weight: 190.23, type: 'metal' },
|
|
||||||
{ name: 'Iridium', symbol: 'Ir', number: 77, weight: 192.22, type: 'metal' },
|
|
||||||
{ name: 'Platinum', symbol: 'Pt', number: 78, weight: 195.09, type: 'metal' },
|
|
||||||
{ name: 'Gold', symbol: 'Au', number: 79, weight: 196.97, type: 'metal' },
|
|
||||||
{ name: 'Mercury', symbol: 'Hg', number: 80, weight: 200.59, type: 'metal' },
|
|
||||||
{ name: 'Thallium', symbol: 'Tl', number: 81, weight: 204.38, type: 'metal' },
|
|
||||||
{ name: 'Lead', symbol: 'Pb', number: 82, weight: 207.2, type: 'metal' },
|
|
||||||
{ name: 'Bismuth', symbol: 'Bi', number: 83, weight: 208.98, type: 'metal' },
|
|
||||||
{ name: 'Polonium', symbol: 'Po', number: 84, weight: 209, type: 'metal' },
|
|
||||||
{ name: 'Astatine', symbol: 'At', number: 85, weight: 210, type: 'nonmetal' },
|
|
||||||
{ name: 'Radon', symbol: 'Rn', number: 86, weight: 222, type: 'noblegas' },
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{ name: 'Francium', symbol: 'Fr', number: 87, weight: 223, type: 'metal' },
|
|
||||||
{ name: 'Radium', symbol: 'Ra', number: 88, weight: 226, type: 'metal' },
|
|
||||||
{ name: 'Actinium', symbol: 'Ac', number: 89, weight: 227, type: 'actinium' },
|
|
||||||
{ name: 'Rutherfordium', symbol: 'Rf', number: 104, weight: 267, type: 'metal' },
|
|
||||||
{ name: 'Dubnium', symbol: 'Db', number: 105, weight: 268, type: 'metal' },
|
|
||||||
{ name: 'Seaborgium', symbol: 'Sg', number: 106, weight: 271, type: 'metal' },
|
|
||||||
{ name: 'Bohrium', symbol: 'Bh', number: 107, weight: 272, type: 'metal' },
|
|
||||||
{ name: 'Hassium', symbol: 'Hs', number: 108, weight: 277, type: 'metal' },
|
|
||||||
{ name: 'Meitnerium', symbol: 'Mt', number: 109, weight: 278, type: 'metal' },
|
|
||||||
{ name: 'Darmstadtium', symbol: 'Ds', number: 110, weight: 281, type: 'metal' },
|
|
||||||
{ name: 'Roentgenium', symbol: 'Rg', number: 111, weight: 280, type: 'metal' },
|
|
||||||
{ name: 'Copernicium', symbol: 'Cn', number: 112, weight: 285, type: 'metal' },
|
|
||||||
{ name: 'Nihonium', symbol: 'Nh', number: 113, weight: 286, type: 'metal' },
|
|
||||||
{ name: 'Flerovium', symbol: 'Fl', number: 114, weight: 289, type: 'metal' },
|
|
||||||
{ name: 'Moscovium', symbol: 'Mc', number: 115, weight: 290, type: 'metal' },
|
|
||||||
{ name: 'Livermorium', symbol: 'Lv', number: 116, weight: 293, type: 'metal' },
|
|
||||||
{ name: 'Tennessine', symbol: 'Ts', number: 117, weight: 294, type: 'metal' },
|
|
||||||
{ name: 'Oganesson', symbol: 'Og', number: 118, weight: 294, type: 'noblegas' },
|
|
||||||
],
|
|
||||||
]
|
|
||||||
|
|
||||||
export const series = [
|
|
||||||
[
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: 'Cerium', symbol: 'Ce', number: 58, weight: 140.12, type: 'lanthanum' },
|
|
||||||
{ name: 'Praseodymium', symbol: 'Pr', number: 59, weight: 140.91, type: 'lanthanum' },
|
|
||||||
{ name: 'Neodymium', symbol: 'Nd', number: 60, weight: 144.24, type: 'lanthanum' },
|
|
||||||
{ name: 'Promethium', symbol: 'Pm', number: 61, weight: 145, type: 'lanthanum' },
|
|
||||||
{ name: 'Samarium', symbol: 'Sm', number: 62, weight: 150.36, type: 'lanthanum' },
|
|
||||||
{ name: 'Europium', symbol: 'Eu', number: 63, weight: 151.96, type: 'lanthanum' },
|
|
||||||
{ name: 'Gadolinium', symbol: 'Gd', number: 64, weight: 157.25, type: 'lanthanum' },
|
|
||||||
{ name: 'Terbium', symbol: 'Tb', number: 65, weight: 158.93, type: 'lanthanum' },
|
|
||||||
{ name: 'Dysprosium', symbol: 'Dy', number: 66, weight: 162.5, type: 'lanthanum' },
|
|
||||||
{ name: 'Holmium', symbol: 'Ho', number: 67, weight: 164.93, type: 'lanthanum' },
|
|
||||||
{ name: 'Erbium', symbol: 'Er', number: 68, weight: 167.26, type: 'lanthanum' },
|
|
||||||
{ name: 'Thulium', symbol: 'Tm', number: 69, weight: 168.93, type: 'lanthanum' },
|
|
||||||
{ name: 'Ytterbium', symbol: 'Yb', number: 70, weight: 173.04, type: 'lanthanum' },
|
|
||||||
{ name: 'Lutetium', symbol: 'Lu', number: 71, weight: 174.97, type: 'lanthanum' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
{ name: 'Thorium', symbol: 'Th', number: 90, weight: 232.04, type: 'actinium' },
|
|
||||||
{ name: 'Protactinium', symbol: 'Pa', number: 91, weight: 231.04, type: 'actinium' },
|
|
||||||
{ name: 'Uranium', symbol: 'U', number: 92, weight: 238.03, type: 'actinium' },
|
|
||||||
{ name: 'Neptunium', symbol: 'Np', number: 93, weight: 237, type: 'actinium' },
|
|
||||||
{ name: 'Plutonium', symbol: 'Pu', number: 94, weight: 244, type: 'actinium' },
|
|
||||||
{ name: 'Americium', symbol: 'Am', number: 95, weight: 243, type: 'actinium' },
|
|
||||||
{ name: 'Curium', symbol: 'Cm', number: 96, weight: 247, type: 'actinium' },
|
|
||||||
{ name: 'Berkelium', symbol: 'Bk', number: 97, weight: 247, type: 'actinium' },
|
|
||||||
{ name: 'Californium', symbol: 'Cf', number: 98, weight: 251, type: 'actinium' },
|
|
||||||
{ name: 'Einsteinium', symbol: 'Es', number: 99, weight: 252, type: 'actinium' },
|
|
||||||
{ name: 'Fermium', symbol: 'Fm', number: 100, weight: 257, type: 'actinium' },
|
|
||||||
{ name: 'Mendelevium', symbol: 'Md', number: 101, weight: 258, type: 'actinium' },
|
|
||||||
{ name: 'Nobelium', symbol: 'No', number: 102, weight: 259, type: 'actinium' },
|
|
||||||
{ name: 'Lawrencium', symbol: 'Lr', number: 103, weight: 262, type: 'actinium' },
|
|
||||||
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
export const niceTypes = {
|
|
||||||
'metal': "Metal",
|
|
||||||
'nonmetal': "Nonmetal",
|
|
||||||
'noblegas': "Noble gas",
|
|
||||||
'lanthanum': "Lanthanum",
|
|
||||||
'actinium': "Actinium"
|
|
||||||
}
|
|
||||||
|
|
@ -1,126 +0,0 @@
|
||||||
const { GLib, Gtk } = imports.gi;
|
|
||||||
import App from "resource:///com/github/Aylur/ags/app.js";
|
|
||||||
import * as Utils from "resource:///com/github/Aylur/ags/utils.js";
|
|
||||||
import Widget from "resource:///com/github/Aylur/ags/widget.js";
|
|
||||||
import { IconTabContainer } from "../.commonwidgets/tabcontainer.js";
|
|
||||||
const { Box, Label, Scrollable } = Widget;
|
|
||||||
|
|
||||||
const HYPRLAND_KEYBIND_CONFIG_FILE = userOptions.cheatsheet.keybinds.configPath ?
|
|
||||||
userOptions.cheatsheet.keybinds.configPath : `${GLib.get_user_config_dir()}/hypr/hyprland/keybinds.conf`;
|
|
||||||
const KEYBIND_SECTIONS_PER_PAGE = 3;
|
|
||||||
const getKeybindList = () => {
|
|
||||||
let data = Utils.exec(`${App.configDir}/scripts/hyprland/get_keybinds.py --path ${HYPRLAND_KEYBIND_CONFIG_FILE}`);
|
|
||||||
if (data == "\"error\"") {
|
|
||||||
Utils.timeout(2000, () => Utils.execAsync(['notify-send',
|
|
||||||
'Update path to keybinds',
|
|
||||||
'Keybinds hyprland config file not found. Check your user options.',
|
|
||||||
'-a', 'ags',
|
|
||||||
]).catch(print))
|
|
||||||
return { children: [] };
|
|
||||||
}
|
|
||||||
return JSON.parse(data);
|
|
||||||
};
|
|
||||||
const keybindList = getKeybindList();
|
|
||||||
|
|
||||||
const keySubstitutions = {
|
|
||||||
"Super": "",
|
|
||||||
"mouse_up": "Scroll ↓", // ikr, weird
|
|
||||||
"mouse_down": "Scroll ↑", // trust me bro
|
|
||||||
"mouse:272": "LMB",
|
|
||||||
"mouse:273": "RMB",
|
|
||||||
"mouse:275": "MouseBack",
|
|
||||||
"Slash": "/",
|
|
||||||
"Hash": "#"
|
|
||||||
}
|
|
||||||
|
|
||||||
const substituteKey = (key) => {
|
|
||||||
return keySubstitutions[key] || key;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Keybind = (keybindData, type) => { // type: either "keys" or "actions"
|
|
||||||
const Key = (key) => Label({ // Specific keys
|
|
||||||
vpack: 'center',
|
|
||||||
className: `${['OR', '+'].includes(key) ? 'cheatsheet-key-notkey' : 'cheatsheet-key'} txt-small`,
|
|
||||||
label: substituteKey(key),
|
|
||||||
});
|
|
||||||
const Action = (text) => Label({ // Binds
|
|
||||||
xalign: 0,
|
|
||||||
label: getString(text),
|
|
||||||
className: "txt txt-small cheatsheet-action",
|
|
||||||
})
|
|
||||||
return Widget.Box({
|
|
||||||
className: "spacing-h-10 cheatsheet-bind-lineheight",
|
|
||||||
children: type == "keys" ? [
|
|
||||||
...(keybindData.mods.length > 0 ? [
|
|
||||||
...keybindData.mods.map(Key),
|
|
||||||
Key("+"),
|
|
||||||
] : []),
|
|
||||||
Key(keybindData.key),
|
|
||||||
] : [Action(keybindData.comment)],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const Section = (sectionData, scope) => {
|
|
||||||
const keys = Box({
|
|
||||||
vertical: true,
|
|
||||||
className: 'spacing-v-5',
|
|
||||||
children: sectionData.keybinds.map((data) => Keybind(data, "keys"))
|
|
||||||
})
|
|
||||||
const actions = Box({
|
|
||||||
vertical: true,
|
|
||||||
className: 'spacing-v-5',
|
|
||||||
children: sectionData.keybinds.map((data) => Keybind(data, "actions"))
|
|
||||||
})
|
|
||||||
const name = Label({
|
|
||||||
xalign: 0,
|
|
||||||
className: "cheatsheet-category-title txt margin-bottom-10",
|
|
||||||
label: getString(sectionData.name),
|
|
||||||
})
|
|
||||||
const binds = Box({
|
|
||||||
className: 'spacing-h-10',
|
|
||||||
children: [
|
|
||||||
keys,
|
|
||||||
actions,
|
|
||||||
]
|
|
||||||
})
|
|
||||||
const childrenSections = Box({
|
|
||||||
vertical: true,
|
|
||||||
className: 'spacing-v-15',
|
|
||||||
children: sectionData.children.map((data) => Section(data, scope + 1))
|
|
||||||
})
|
|
||||||
return Box({
|
|
||||||
vertical: true,
|
|
||||||
children: [
|
|
||||||
...((sectionData.name && sectionData.name.length > 0) ? [name] : []),
|
|
||||||
Box({
|
|
||||||
className: 'spacing-v-10',
|
|
||||||
children: [
|
|
||||||
binds,
|
|
||||||
childrenSections,
|
|
||||||
]
|
|
||||||
})
|
|
||||||
]
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
const numOfTabs = Math.ceil(keybindList.children.length / KEYBIND_SECTIONS_PER_PAGE);
|
|
||||||
const keybindPages = Array.from({ length: numOfTabs }, (_, i) => ({
|
|
||||||
iconWidget: Label({
|
|
||||||
className: "txt txt-small",
|
|
||||||
label: `${i + 1}`,
|
|
||||||
}),
|
|
||||||
name: `${i + 1}`,
|
|
||||||
child: Box({
|
|
||||||
className: 'spacing-h-30',
|
|
||||||
children: keybindList.children.slice(
|
|
||||||
KEYBIND_SECTIONS_PER_PAGE * i, 0 + KEYBIND_SECTIONS_PER_PAGE * (i + 1),
|
|
||||||
).map(data => Section(data, 1)),
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
return IconTabContainer({
|
|
||||||
iconWidgets: keybindPages.map((kbp) => kbp.iconWidget),
|
|
||||||
names: keybindPages.map((kbp) => kbp.name),
|
|
||||||
children: keybindPages.map((kbp) => kbp.child),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
@ -1,146 +0,0 @@
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import { setupCursorHover } from "../.widgetutils/cursorhover.js";
|
|
||||||
import PopupWindow from '../.widgethacks/popupwindow.js';
|
|
||||||
import Keybinds from "./keybinds.js";
|
|
||||||
import PeriodicTable from "./periodictable.js";
|
|
||||||
import { ExpandingIconTabContainer } from '../.commonwidgets/tabcontainer.js';
|
|
||||||
import { checkKeybind } from '../.widgetutils/keybind.js';
|
|
||||||
import clickCloseRegion from '../.commonwidgets/clickcloseregion.js';
|
|
||||||
|
|
||||||
const cheatsheets = [
|
|
||||||
{
|
|
||||||
name: getString('Keybinds'),
|
|
||||||
materialIcon: 'keyboard',
|
|
||||||
contentWidget: Keybinds,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: getString('Periodic table'),
|
|
||||||
materialIcon: 'experiment',
|
|
||||||
contentWidget: PeriodicTable,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const CheatsheetHeader = () => Widget.CenterBox({
|
|
||||||
vertical: false,
|
|
||||||
startWidget: Widget.Box({}),
|
|
||||||
centerWidget: Widget.Box({
|
|
||||||
vertical: true,
|
|
||||||
className: "spacing-h-15",
|
|
||||||
children: [
|
|
||||||
Widget.Box({
|
|
||||||
hpack: 'center',
|
|
||||||
className: 'spacing-h-5 cheatsheet-title',
|
|
||||||
children: [
|
|
||||||
Widget.Label({
|
|
||||||
hpack: 'center',
|
|
||||||
css: 'margin-right: 0.682rem;',
|
|
||||||
className: 'txt-title',
|
|
||||||
label: getString('Cheat sheet'),
|
|
||||||
}),
|
|
||||||
Widget.Label({
|
|
||||||
vpack: 'center',
|
|
||||||
className: "cheatsheet-key txt-small",
|
|
||||||
label: "",
|
|
||||||
}),
|
|
||||||
Widget.Label({
|
|
||||||
vpack: 'center',
|
|
||||||
className: "cheatsheet-key-notkey txt-small",
|
|
||||||
label: "+",
|
|
||||||
}),
|
|
||||||
Widget.Label({
|
|
||||||
vpack: 'center',
|
|
||||||
className: "cheatsheet-key txt-small",
|
|
||||||
label: "/",
|
|
||||||
})
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
endWidget: Widget.Button({
|
|
||||||
vpack: 'start',
|
|
||||||
hpack: 'end',
|
|
||||||
className: "cheatsheet-closebtn icon-material txt txt-hugeass",
|
|
||||||
onClicked: () => {
|
|
||||||
closeWindowOnAllMonitors('cheatsheet');
|
|
||||||
},
|
|
||||||
child: Widget.Label({
|
|
||||||
className: 'icon-material txt txt-hugeass',
|
|
||||||
label: 'close'
|
|
||||||
}),
|
|
||||||
setup: setupCursorHover,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const sheetContents = [];
|
|
||||||
const SheetContent = (id) => {
|
|
||||||
sheetContents[id] = ExpandingIconTabContainer({
|
|
||||||
tabsHpack: 'center',
|
|
||||||
tabSwitcherClassName: 'sidebar-icontabswitcher',
|
|
||||||
transitionDuration: userOptions.animations.durationLarge * 1.4,
|
|
||||||
icons: cheatsheets.map((api) => api.materialIcon),
|
|
||||||
names: cheatsheets.map((api) => api.name),
|
|
||||||
children: cheatsheets.map((api) => api.contentWidget()),
|
|
||||||
onChange: (self, id) => {
|
|
||||||
self.shown = cheatsheets[id].name;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return sheetContents[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
export default (id) => {
|
|
||||||
const sheets = SheetContent(id);
|
|
||||||
const widgetContent = Widget.Box({
|
|
||||||
vertical: true,
|
|
||||||
className: "cheatsheet-bg spacing-v-5",
|
|
||||||
children: [
|
|
||||||
CheatsheetHeader(),
|
|
||||||
sheets,
|
|
||||||
]
|
|
||||||
});
|
|
||||||
return PopupWindow({
|
|
||||||
monitor: id,
|
|
||||||
name: `cheatsheet${id}`,
|
|
||||||
layer: 'top',
|
|
||||||
keymode: 'on-demand',
|
|
||||||
visible: false,
|
|
||||||
anchor: ['top', 'bottom', 'left', 'right'],
|
|
||||||
child: Widget.Box({
|
|
||||||
vertical: true,
|
|
||||||
children: [
|
|
||||||
clickCloseRegion({ name: 'cheatsheet' }),
|
|
||||||
Widget.Box({
|
|
||||||
children: [
|
|
||||||
clickCloseRegion({ name: 'cheatsheet' }),
|
|
||||||
widgetContent,
|
|
||||||
clickCloseRegion({ name: 'cheatsheet' }),
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
clickCloseRegion({ name: 'cheatsheet' }),
|
|
||||||
],
|
|
||||||
setup: (self) => self.on('key-press-event', (widget, event) => { // Typing
|
|
||||||
// Whole sheet
|
|
||||||
if (checkKeybind(event, userOptions.keybinds.cheatsheet.nextTab))
|
|
||||||
sheetContents.forEach(tab => tab.nextTab())
|
|
||||||
else if (checkKeybind(event, userOptions.keybinds.cheatsheet.prevTab))
|
|
||||||
sheetContents.forEach(tab => tab.prevTab())
|
|
||||||
else if (checkKeybind(event, userOptions.keybinds.cheatsheet.cycleTab))
|
|
||||||
sheetContents.forEach(tab => tab.cycleTab())
|
|
||||||
// Keybinds
|
|
||||||
if (sheets.attribute.names[sheets.attribute.shown.value] == 'Keybinds') { // If Keybinds tab is focused
|
|
||||||
if (checkKeybind(event, userOptions.keybinds.cheatsheet.keybinds.nextTab)) {
|
|
||||||
sheetContents.forEach((sheet) => {
|
|
||||||
const toSwitchTab = sheet.attribute.children[sheet.attribute.shown.value];
|
|
||||||
toSwitchTab.nextTab();
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else if (checkKeybind(event, userOptions.keybinds.cheatsheet.keybinds.prevTab)) {
|
|
||||||
sheetContents.forEach((sheet) => {
|
|
||||||
const toSwitchTab = sheet.attribute.children[sheet.attribute.shown.value];
|
|
||||||
toSwitchTab.prevTab();
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
@ -1,94 +0,0 @@
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import { niceTypes, periodicTable, series } from "./data_periodictable.js";
|
|
||||||
const { Box, Button, Icon, Label, Revealer } = Widget;
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
const ElementTile = (element) => {
|
|
||||||
return Box({
|
|
||||||
vertical: true,
|
|
||||||
tooltipText: element.electronConfig ? `${element.electronConfig}` : null,
|
|
||||||
className: `cheatsheet-periodictable-${element.type}`,
|
|
||||||
children: element.name == '' ? null : [
|
|
||||||
Box({
|
|
||||||
className: 'padding-left-8 padding-right-8 padding-top-8',
|
|
||||||
children: [
|
|
||||||
Label({
|
|
||||||
label: `${element.number}`,
|
|
||||||
className: "cheatsheet-periodictable-elementnum txt-tiny txt-bold",
|
|
||||||
}),
|
|
||||||
Box({ hexpand: true }),
|
|
||||||
Label({
|
|
||||||
label: `${element.weight}`,
|
|
||||||
className: "txt-smaller",
|
|
||||||
})
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
element.icon ? Icon({
|
|
||||||
icon: element.icon,
|
|
||||||
className: "txt-hugerass txt-bold",
|
|
||||||
}) : Label({
|
|
||||||
label: `${element.symbol}`,
|
|
||||||
className: "cheatsheet-periodictable-elementsymbol",
|
|
||||||
}),
|
|
||||||
Label({
|
|
||||||
label: `${element.name}`,
|
|
||||||
className: "txt-tiny",
|
|
||||||
})
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const BoardColor = (type) => Box({
|
|
||||||
className: 'spacing-h-5',
|
|
||||||
children: [
|
|
||||||
Box({
|
|
||||||
homogeneous: true,
|
|
||||||
className: `cheatsheet-periodictable-legend-color-wrapper`,
|
|
||||||
children: [Box({
|
|
||||||
className: `cheatsheet-periodictable-legend-color-${type}`,
|
|
||||||
})]
|
|
||||||
}),
|
|
||||||
Label({
|
|
||||||
label: `${niceTypes[type]}`,
|
|
||||||
className: "txt txt-small",
|
|
||||||
})
|
|
||||||
]
|
|
||||||
})
|
|
||||||
const mainBoard = Box({
|
|
||||||
hpack: 'center',
|
|
||||||
vertical: true,
|
|
||||||
className: "spacing-v-3",
|
|
||||||
children: periodicTable.map((row, _) => Box({ // Rows
|
|
||||||
className: "spacing-h-5",
|
|
||||||
children: row.map((element, _) => ElementTile(element))
|
|
||||||
})),
|
|
||||||
});
|
|
||||||
const seriesBoard = Box({
|
|
||||||
hpack: 'center',
|
|
||||||
vertical: true,
|
|
||||||
className: "spacing-v-3",
|
|
||||||
children: series.map((row, _) => Box({ // Rows
|
|
||||||
className: "spacing-h-5",
|
|
||||||
children: row.map((element, _) => ElementTile(element))
|
|
||||||
})),
|
|
||||||
});
|
|
||||||
const legend = Box({
|
|
||||||
hpack: 'center',
|
|
||||||
className: 'spacing-h-20',
|
|
||||||
children: [
|
|
||||||
BoardColor('metal'),
|
|
||||||
BoardColor('nonmetal'),
|
|
||||||
BoardColor('noblegas'),
|
|
||||||
BoardColor('lanthanum'),
|
|
||||||
BoardColor('actinium'),
|
|
||||||
]
|
|
||||||
})
|
|
||||||
return Box({
|
|
||||||
vertical: true,
|
|
||||||
className: 'spacing-v-20',
|
|
||||||
children: [
|
|
||||||
mainBoard,
|
|
||||||
seriesBoard,
|
|
||||||
legend
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import { enableClickthrough } from "../.widgetutils/clickthrough.js";
|
|
||||||
|
|
||||||
export default (monitor = 0, ) => {
|
|
||||||
return Widget.Window({
|
|
||||||
monitor,
|
|
||||||
name: `crosshair${monitor}`,
|
|
||||||
layer: 'overlay',
|
|
||||||
exclusivity: 'ignore',
|
|
||||||
visible: false,
|
|
||||||
child: Widget.Icon({
|
|
||||||
icon: 'crosshair-symbolic',
|
|
||||||
css: `
|
|
||||||
font-size: ${userOptions.gaming.crosshair.size}px;
|
|
||||||
color: ${userOptions.gaming.crosshair.color};
|
|
||||||
`,
|
|
||||||
}),
|
|
||||||
setup: enableClickthrough,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
export const quickLaunchItems = [
|
|
||||||
{
|
|
||||||
"name": "GitHub + Files×2",
|
|
||||||
"command": "github-desktop & nautilus --new-window & nautilus --new-window &"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Terminal×2",
|
|
||||||
"command": "foot & foot &"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Discord + Youtube + Github",
|
|
||||||
"command": "xdg-open 'https://discord.com/app' && xdg-open 'https://youtube.com/' && xdg-open 'https://github.com/' &"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
|
|
||||||
import WallpaperImage from './wallpaper.js';
|
|
||||||
import TimeAndLaunchesWidget from './timeandlaunches.js'
|
|
||||||
import SystemWidget from './system.js'
|
|
||||||
|
|
||||||
export default (monitor) => Widget.Window({
|
|
||||||
name: `desktopbackground${monitor}`,
|
|
||||||
// anchor: ['top', 'bottom', 'left', 'right'],
|
|
||||||
layer: 'background',
|
|
||||||
exclusivity: 'ignore',
|
|
||||||
visible: true,
|
|
||||||
child: Widget.Overlay({
|
|
||||||
child: WallpaperImage(monitor),
|
|
||||||
// child: Widget.Box({}),
|
|
||||||
overlays: [
|
|
||||||
TimeAndLaunchesWidget(),
|
|
||||||
SystemWidget(),
|
|
||||||
],
|
|
||||||
setup: (self) => {
|
|
||||||
self.set_overlay_pass_through(self.get_children()[1], true);
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
@ -1,161 +0,0 @@
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
|
|
||||||
const { execAsync, exec } = Utils;
|
|
||||||
const { Box, EventBox, Label, Revealer, Overlay } = Widget;
|
|
||||||
import { AnimatedCircProg } from "../.commonwidgets/cairo_circularprogress.js";
|
|
||||||
import { MaterialIcon } from '../.commonwidgets/materialicon.js';
|
|
||||||
|
|
||||||
const ResourceValue = (name, icon, interval, valueUpdateCmd, displayFunc, props = {}) => Box({
|
|
||||||
...props,
|
|
||||||
className: 'bg-system-bg txt',
|
|
||||||
children: [
|
|
||||||
Revealer({
|
|
||||||
transition: 'slide_left',
|
|
||||||
transitionDuration: userOptions.animations.durationLarge,
|
|
||||||
child: Box({
|
|
||||||
vpack: 'center',
|
|
||||||
vertical: true,
|
|
||||||
className: 'margin-right-15',
|
|
||||||
children: [
|
|
||||||
Label({
|
|
||||||
xalign: 1,
|
|
||||||
className: 'txt-small txt',
|
|
||||||
label: `${name}`,
|
|
||||||
}),
|
|
||||||
Label({
|
|
||||||
xalign: 1,
|
|
||||||
className: 'titlefont txt-norm txt-onSecondaryContainer',
|
|
||||||
setup: (self) => self
|
|
||||||
.poll(interval, (label) => displayFunc(label))
|
|
||||||
,
|
|
||||||
})
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
Overlay({
|
|
||||||
child: AnimatedCircProg({
|
|
||||||
className: 'bg-system-circprog',
|
|
||||||
extraSetup: (self) => self
|
|
||||||
.poll(interval, (self) => {
|
|
||||||
execAsync(['bash', '-c', `${valueUpdateCmd}`]).then((newValue) => {
|
|
||||||
self.css = `font-size: ${Math.round(newValue)}px;`
|
|
||||||
}).catch(print);
|
|
||||||
})
|
|
||||||
,
|
|
||||||
}),
|
|
||||||
overlays: [
|
|
||||||
MaterialIcon(`${icon}`, 'hugeass'),
|
|
||||||
],
|
|
||||||
setup: self => self.set_overlay_pass_through(self.get_children()[1], true),
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
const resources = Box({
|
|
||||||
vpack: 'fill',
|
|
||||||
vertical: true,
|
|
||||||
className: 'spacing-v-15',
|
|
||||||
children: [
|
|
||||||
ResourceValue('Memory', 'memory', 10000, `free | awk '/^Mem/ {printf("%.2f\\n", ($3/$2) * 100)}'`,
|
|
||||||
(label) => {
|
|
||||||
execAsync(['bash', '-c', `free -h | awk '/^Mem/ {print $3 " / " $2}' | sed 's/Gi/Gib/g'`])
|
|
||||||
.then((output) => {
|
|
||||||
label.label = `${output}`
|
|
||||||
}).catch(print);
|
|
||||||
}, { hpack: 'end' }),
|
|
||||||
ResourceValue('Swap', 'swap_horiz', 10000, `free | awk '/^Swap/ {if ($2 > 0) printf("%.2f\\n", ($3/$2) * 100); else print "0";}'`,
|
|
||||||
(label) => {
|
|
||||||
execAsync(['bash', '-c', `free -h | awk '/^Swap/ {if ($2 != "0") print $3 " / " $2; else print "No swap"}' | sed 's/Gi/Gib/g'`])
|
|
||||||
.then((output) => {
|
|
||||||
label.label = `${output}`
|
|
||||||
}).catch(print);
|
|
||||||
}, { hpack: 'end' }),
|
|
||||||
ResourceValue('Disk space', 'hard_drive_2', 3600000, `echo $(df --output=pcent / | tr -dc '0-9')`,
|
|
||||||
(label) => {
|
|
||||||
execAsync(['bash', '-c', `df -h --output=avail / | awk 'NR==2{print $1}'`])
|
|
||||||
.then((output) => {
|
|
||||||
label.label = `${output} available`
|
|
||||||
}).catch(print);
|
|
||||||
}, { hpack: 'end' }),
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
const distroAndVersion = Box({
|
|
||||||
vertical: true,
|
|
||||||
children: [
|
|
||||||
Box({
|
|
||||||
hpack: 'end',
|
|
||||||
children: [
|
|
||||||
Label({
|
|
||||||
className: 'bg-distro-txt',
|
|
||||||
xalign: 0,
|
|
||||||
label: 'Hyping on ',
|
|
||||||
}),
|
|
||||||
Label({
|
|
||||||
className: 'bg-distro-name',
|
|
||||||
xalign: 0,
|
|
||||||
label: '<distro>',
|
|
||||||
setup: (label) => {
|
|
||||||
execAsync([`grep`, `-oP`, `PRETTY_NAME="\\K[^"]+`, `/etc/os-release`]).then(distro => {
|
|
||||||
label.label = distro;
|
|
||||||
}).catch(print);
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
Box({
|
|
||||||
hpack: 'end',
|
|
||||||
children: [
|
|
||||||
Label({
|
|
||||||
className: 'bg-distro-txt',
|
|
||||||
xalign: 0,
|
|
||||||
label: 'with ',
|
|
||||||
}),
|
|
||||||
Label({
|
|
||||||
className: 'bg-distro-name',
|
|
||||||
xalign: 0,
|
|
||||||
label: 'An environment idk',
|
|
||||||
setup: (label) => {
|
|
||||||
// hyprctl will return unsuccessfully if Hyprland isn't running
|
|
||||||
execAsync([`bash`, `-c`, `hyprctl version | grep -oP "Tag: v\\K\\d+\\.\\d+\\.\\d+"`]).then(version => {
|
|
||||||
label.label = `Hyprland ${version}`;
|
|
||||||
}).catch(() => execAsync([`bash`, `-c`, `sway -v | cut -d'-' -f1 | sed 's/sway version /v/'`]).then(version => {
|
|
||||||
label.label = `Sway ${version}`;
|
|
||||||
}).catch(print));
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
})
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
export default () => Box({
|
|
||||||
hpack: 'end',
|
|
||||||
vpack: 'end',
|
|
||||||
children: [
|
|
||||||
EventBox({
|
|
||||||
child: Box({
|
|
||||||
hpack: 'end',
|
|
||||||
vpack: 'end',
|
|
||||||
className: 'bg-distro-box spacing-v-20',
|
|
||||||
vertical: true,
|
|
||||||
children: [
|
|
||||||
resources,
|
|
||||||
distroAndVersion,
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
onPrimaryClickRelease: () => {
|
|
||||||
const kids = resources.get_children();
|
|
||||||
for (let i = 0; i < kids.length; i++) {
|
|
||||||
const child = kids[i];
|
|
||||||
const firstChild = child.get_children()[0];
|
|
||||||
firstChild.revealChild = !firstChild.revealChild;
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
})
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
||||||
const { GLib } = imports.gi;
|
|
||||||
import App from 'resource:///com/github/Aylur/ags/app.js';
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import Service from 'resource:///com/github/Aylur/ags/service.js';
|
|
||||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
|
|
||||||
|
|
||||||
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
|
|
||||||
const { execAsync, exec } = Utils;
|
|
||||||
const { Box, Label, Button, Revealer, EventBox } = Widget;
|
|
||||||
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
|
|
||||||
import { quickLaunchItems } from './data_quicklaunches.js'
|
|
||||||
|
|
||||||
const TimeAndDate = () => Box({
|
|
||||||
vertical: true,
|
|
||||||
className: 'spacing-v--5',
|
|
||||||
children: [
|
|
||||||
Label({
|
|
||||||
className: 'bg-time-clock',
|
|
||||||
xalign: 0,
|
|
||||||
label: GLib.DateTime.new_now_local().format(userOptions.time.format),
|
|
||||||
setup: (self) => self.poll(userOptions.time.interval, label => {
|
|
||||||
label.label = GLib.DateTime.new_now_local().format(userOptions.time.format);
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
Label({
|
|
||||||
className: 'bg-time-date',
|
|
||||||
xalign: 0,
|
|
||||||
label: GLib.DateTime.new_now_local().format(userOptions.time.dateFormatLong),
|
|
||||||
setup: (self) => self.poll(userOptions.time.dateInterval, (label) => {
|
|
||||||
label.label = GLib.DateTime.new_now_local().format(userOptions.time.dateFormatLong);
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
const QuickLaunches = () => Box({
|
|
||||||
vertical: true,
|
|
||||||
className: 'spacing-v-10',
|
|
||||||
children: [
|
|
||||||
Label({
|
|
||||||
xalign: 0,
|
|
||||||
className: 'bg-quicklaunch-title',
|
|
||||||
label: 'Quick Launches',
|
|
||||||
}),
|
|
||||||
Box({
|
|
||||||
hpack: 'start',
|
|
||||||
className: 'spacing-h-5',
|
|
||||||
children: quickLaunchItems.map((item, i) => Button({
|
|
||||||
onClicked: () => {
|
|
||||||
execAsync(['bash', '-c', `${item["command"]}`]).catch(print);
|
|
||||||
},
|
|
||||||
className: 'bg-quicklaunch-btn',
|
|
||||||
child: Label({
|
|
||||||
label: `${item["name"]}`,
|
|
||||||
}),
|
|
||||||
setup: (self) => {
|
|
||||||
setupCursorHover(self);
|
|
||||||
}
|
|
||||||
})),
|
|
||||||
})
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
export default () => Box({
|
|
||||||
hpack: 'start',
|
|
||||||
vpack: 'end',
|
|
||||||
vertical: true,
|
|
||||||
className: 'bg-time-box spacing-h--10',
|
|
||||||
children: [
|
|
||||||
TimeAndDate(),
|
|
||||||
// QuickLaunches(),
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
@ -1,119 +0,0 @@
|
||||||
const { Gdk, GdkPixbuf, Gio, GLib, Gtk } = imports.gi;
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
|
|
||||||
const { exec, execAsync } = Utils;
|
|
||||||
const { Box, Button, Label, Stack } = Widget;
|
|
||||||
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
|
|
||||||
|
|
||||||
import Wallpaper from '../../services/wallpaper.js';
|
|
||||||
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
|
|
||||||
import { clamp } from '../.miscutils/mathfuncs.js';
|
|
||||||
import { monitors } from '../.commondata/hyprlanddata.js';
|
|
||||||
|
|
||||||
const DISABLE_AGS_WALLPAPER = true;
|
|
||||||
|
|
||||||
const SWITCHWALL_SCRIPT_PATH = `${App.configDir}/scripts/color_generation/switchwall.sh`;
|
|
||||||
const WALLPAPER_ZOOM_SCALE = 1.25; // For scrolling when we switch workspace
|
|
||||||
const MAX_WORKSPACES = 10;
|
|
||||||
|
|
||||||
export default (monitor = 0) => {
|
|
||||||
const WALLPAPER_OFFSCREEN_X = (WALLPAPER_ZOOM_SCALE - 1) * monitors[monitor].width;
|
|
||||||
const WALLPAPER_OFFSCREEN_Y = (WALLPAPER_ZOOM_SCALE - 1) * monitors[monitor].height;
|
|
||||||
const wallpaperImage = Widget.DrawingArea({
|
|
||||||
attribute: {
|
|
||||||
pixbuf: undefined,
|
|
||||||
workspace: 1,
|
|
||||||
sideleft: 0,
|
|
||||||
sideright: 0,
|
|
||||||
updatePos: (self) => {
|
|
||||||
self.setCss(`font-size: ${self.attribute.workspace - self.attribute.sideleft + self.attribute.sideright}px;`)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
className: 'bg-wallpaper-transition',
|
|
||||||
setup: (self) => {
|
|
||||||
self.set_size_request(monitors[monitor].width, monitors[monitor].height);
|
|
||||||
self
|
|
||||||
// TODO: reduced updates using timeouts to reduce lag
|
|
||||||
// .hook(Hyprland.active.workspace, (self) => {
|
|
||||||
// self.attribute.workspace = Hyprland.active.workspace.id
|
|
||||||
// self.attribute.updatePos(self);
|
|
||||||
// })
|
|
||||||
// .hook(App, (box, name, visible) => { // Update on open
|
|
||||||
// if (self.attribute[name] === undefined) return;
|
|
||||||
// self.attribute[name] = (visible ? 1 : 0);
|
|
||||||
// self.attribute.updatePos(self);
|
|
||||||
// })
|
|
||||||
.on('draw', (self, cr) => {
|
|
||||||
if (!self.attribute.pixbuf) return;
|
|
||||||
const styleContext = self.get_style_context();
|
|
||||||
const workspace = styleContext.get_property('font-size', Gtk.StateFlags.NORMAL);
|
|
||||||
// Draw
|
|
||||||
Gdk.cairo_set_source_pixbuf(cr, self.attribute.pixbuf,
|
|
||||||
-(WALLPAPER_OFFSCREEN_X / (MAX_WORKSPACES + 1) * (clamp(workspace, 0, MAX_WORKSPACES + 1))),
|
|
||||||
-WALLPAPER_OFFSCREEN_Y / 2);
|
|
||||||
cr.paint();
|
|
||||||
})
|
|
||||||
.hook(Wallpaper, (self) => {
|
|
||||||
if (DISABLE_AGS_WALLPAPER) return;
|
|
||||||
const wallPath = Wallpaper.get(monitor);
|
|
||||||
if (!wallPath || wallPath === "") return;
|
|
||||||
self.attribute.pixbuf = GdkPixbuf.Pixbuf.new_from_file(wallPath);
|
|
||||||
|
|
||||||
const scale_x = monitors[monitor].width * WALLPAPER_ZOOM_SCALE / self.attribute.pixbuf.get_width();
|
|
||||||
const scale_y = monitors[monitor].height * WALLPAPER_ZOOM_SCALE / self.attribute.pixbuf.get_height();
|
|
||||||
const scale_factor = Math.max(scale_x, scale_y);
|
|
||||||
|
|
||||||
self.attribute.pixbuf = self.attribute.pixbuf.scale_simple(
|
|
||||||
Math.round(self.attribute.pixbuf.get_width() * scale_factor),
|
|
||||||
Math.round(self.attribute.pixbuf.get_height() * scale_factor),
|
|
||||||
GdkPixbuf.InterpType.BILINEAR
|
|
||||||
);
|
|
||||||
self.queue_draw();
|
|
||||||
}, 'updated');
|
|
||||||
;
|
|
||||||
}
|
|
||||||
,
|
|
||||||
});
|
|
||||||
const wallpaperPrompt = Box({
|
|
||||||
hpack: 'center',
|
|
||||||
vpack: 'center',
|
|
||||||
vertical: true,
|
|
||||||
className: 'spacing-v-10',
|
|
||||||
children: [
|
|
||||||
Label({
|
|
||||||
hpack: 'center',
|
|
||||||
justification: 'center',
|
|
||||||
className: 'txt-large',
|
|
||||||
label: `No wallpaper loaded.\nAn image ≥ ${monitors[monitor].width * WALLPAPER_ZOOM_SCALE} × ${monitors[monitor].height * WALLPAPER_ZOOM_SCALE} is recommended.`,
|
|
||||||
}),
|
|
||||||
Button({
|
|
||||||
hpack: 'center',
|
|
||||||
className: 'btn-primary',
|
|
||||||
label: `Select one`,
|
|
||||||
setup: setupCursorHover,
|
|
||||||
onClicked: (self) => Utils.execAsync([SWITCHWALL_SCRIPT_PATH]).catch(print),
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
});
|
|
||||||
const stack = Stack({
|
|
||||||
transition: 'crossfade',
|
|
||||||
transitionDuration: userOptions.animations.durationLarge,
|
|
||||||
children: {
|
|
||||||
'disabled': Box({}),
|
|
||||||
'image': wallpaperImage,
|
|
||||||
'prompt': wallpaperPrompt,
|
|
||||||
},
|
|
||||||
setup: (self) => self
|
|
||||||
.hook(Wallpaper, (self) => {
|
|
||||||
if (DISABLE_AGS_WALLPAPER) {
|
|
||||||
self.shown = 'disabled';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const wallPath = Wallpaper.get(monitor);
|
|
||||||
self.shown = ((wallPath && wallPath != "") ? 'image' : 'prompt');
|
|
||||||
}, 'updated')
|
|
||||||
,
|
|
||||||
})
|
|
||||||
return stack;
|
|
||||||
// return wallpaperImage;
|
|
||||||
}
|
|
||||||
|
|
@ -1,300 +0,0 @@
|
||||||
const { Gtk, GLib } = imports.gi;
|
|
||||||
import App from 'resource:///com/github/Aylur/ags/app.js';
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
|
|
||||||
const { EventBox, Button } = Widget;
|
|
||||||
|
|
||||||
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
|
|
||||||
import Applications from 'resource:///com/github/Aylur/ags/service/applications.js';
|
|
||||||
const { execAsync, exec } = Utils;
|
|
||||||
const { Box, Revealer } = Widget;
|
|
||||||
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
|
|
||||||
import { getAllFiles, searchIcons } from './icons.js'
|
|
||||||
import { MaterialIcon } from '../.commonwidgets/materialicon.js';
|
|
||||||
import { substitute } from '../.miscutils/icons.js';
|
|
||||||
|
|
||||||
const icon_files = userOptions.icons.searchPaths.map(e => getAllFiles(e)).flat(1)
|
|
||||||
|
|
||||||
let isPinned = false
|
|
||||||
let cachePath = new Map()
|
|
||||||
|
|
||||||
let timers = []
|
|
||||||
|
|
||||||
function clearTimes() {
|
|
||||||
timers.forEach(e => GLib.source_remove(e))
|
|
||||||
timers = []
|
|
||||||
}
|
|
||||||
|
|
||||||
function ExclusiveWindow(client) {
|
|
||||||
const fn = [
|
|
||||||
(client) => !(client !== null && client !== undefined),
|
|
||||||
// Jetbrains
|
|
||||||
(client) => client.title.includes("win"),
|
|
||||||
// Vscode
|
|
||||||
(client) => client.title === '' && client.class === ''
|
|
||||||
]
|
|
||||||
|
|
||||||
for (const item of fn) { if (item(client)) { return true } }
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
const focus = ({ address }) => Utils.execAsync(`hyprctl dispatch focuswindow address:${address}`).catch(print);
|
|
||||||
|
|
||||||
const DockSeparator = (props = {}) => Box({
|
|
||||||
...props,
|
|
||||||
className: 'dock-separator',
|
|
||||||
})
|
|
||||||
|
|
||||||
const PinButton = () => Widget.Button({
|
|
||||||
className: 'dock-app-btn dock-app-btn-animate',
|
|
||||||
tooltipText: 'Pin Dock',
|
|
||||||
child: Widget.Box({
|
|
||||||
homogeneous: true,
|
|
||||||
className: 'dock-app-icon txt',
|
|
||||||
child: MaterialIcon('push_pin', 'hugeass')
|
|
||||||
}),
|
|
||||||
onClicked: (self) => {
|
|
||||||
isPinned = !isPinned
|
|
||||||
self.className = `${isPinned ? "pinned-dock-app-btn" : "dock-app-btn animate"} dock-app-btn-animate`
|
|
||||||
},
|
|
||||||
setup: setupCursorHover,
|
|
||||||
})
|
|
||||||
|
|
||||||
const LauncherButton = () => Widget.Button({
|
|
||||||
className: 'dock-app-btn dock-app-btn-animate',
|
|
||||||
tooltipText: 'Open launcher',
|
|
||||||
child: Widget.Box({
|
|
||||||
homogeneous: true,
|
|
||||||
className: 'dock-app-icon txt',
|
|
||||||
child: MaterialIcon('apps', 'hugerass')
|
|
||||||
}),
|
|
||||||
onClicked: (self) => {
|
|
||||||
App.toggleWindow('overview');
|
|
||||||
},
|
|
||||||
setup: setupCursorHover,
|
|
||||||
})
|
|
||||||
|
|
||||||
const AppButton = ({ icon, ...rest }) => Widget.Revealer({
|
|
||||||
attribute: {
|
|
||||||
'workspace': 0
|
|
||||||
},
|
|
||||||
revealChild: false,
|
|
||||||
transition: 'slide_right',
|
|
||||||
transitionDuration: userOptions.animations.durationLarge,
|
|
||||||
child: Widget.Button({
|
|
||||||
...rest,
|
|
||||||
className: 'dock-app-btn dock-app-btn-animate',
|
|
||||||
child: Widget.Box({
|
|
||||||
child: Widget.Overlay({
|
|
||||||
child: Widget.Box({
|
|
||||||
homogeneous: true,
|
|
||||||
className: 'dock-app-icon',
|
|
||||||
child: Widget.Icon({
|
|
||||||
icon: icon,
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
overlays: [Widget.Box({
|
|
||||||
class_name: 'indicator',
|
|
||||||
vpack: 'end',
|
|
||||||
hpack: 'center',
|
|
||||||
})],
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
setup: (button) => {
|
|
||||||
setupCursorHover(button);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
const Taskbar = (monitor) => Widget.Box({
|
|
||||||
className: 'dock-apps',
|
|
||||||
attribute: {
|
|
||||||
monitor: monitor,
|
|
||||||
'map': new Map(),
|
|
||||||
'clientSortFunc': (a, b) => {
|
|
||||||
return a.attribute.workspace > b.attribute.workspace;
|
|
||||||
},
|
|
||||||
'update': (box, monitor) => {
|
|
||||||
for (let i = 0; i < Hyprland.clients.length; i++) {
|
|
||||||
const client = Hyprland.clients[i];
|
|
||||||
if (client["pid"] == -1) return;
|
|
||||||
const appClass = substitute(client.class);
|
|
||||||
// for (const appName of userOptions.dock.pinnedApps) {
|
|
||||||
// if (appClass.includes(appName.toLowerCase()))
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
let appClassLower = appClass.toLowerCase()
|
|
||||||
let path = ''
|
|
||||||
if (cachePath[appClassLower]) { path = cachePath[appClassLower] }
|
|
||||||
else {
|
|
||||||
path = searchIcons(appClass.toLowerCase(), icon_files)
|
|
||||||
cachePath[appClassLower] = path
|
|
||||||
}
|
|
||||||
if (path === '') { path = substitute(appClass) }
|
|
||||||
const newButton = AppButton({
|
|
||||||
icon: path,
|
|
||||||
tooltipText: `${client.title} (${appClass})`,
|
|
||||||
onClicked: () => focus(client),
|
|
||||||
});
|
|
||||||
newButton.attribute.workspace = client.workspace.id;
|
|
||||||
newButton.revealChild = true;
|
|
||||||
box.attribute.map.set(client.address, newButton);
|
|
||||||
}
|
|
||||||
box.children = Array.from(box.attribute.map.values());
|
|
||||||
},
|
|
||||||
'add': (box, address, monitor) => {
|
|
||||||
if (!address) { // First active emit is undefined
|
|
||||||
box.attribute.update(box);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const newClient = Hyprland.clients.find(client => {
|
|
||||||
return client.address == address;
|
|
||||||
});
|
|
||||||
if (ExclusiveWindow(newClient)) { return }
|
|
||||||
let appClass = newClient.class
|
|
||||||
let appClassLower = appClass.toLowerCase()
|
|
||||||
let path = ''
|
|
||||||
if (cachePath[appClassLower]) { path = cachePath[appClassLower] }
|
|
||||||
else {
|
|
||||||
path = searchIcons(appClassLower, icon_files)
|
|
||||||
cachePath[appClassLower] = path
|
|
||||||
}
|
|
||||||
if (path === '') { path = substitute(appClass) }
|
|
||||||
const newButton = AppButton({
|
|
||||||
icon: path,
|
|
||||||
tooltipText: `${newClient.title} (${appClass})`,
|
|
||||||
onClicked: () => focus(newClient),
|
|
||||||
})
|
|
||||||
newButton.attribute.workspace = newClient.workspace.id;
|
|
||||||
box.attribute.map.set(address, newButton);
|
|
||||||
box.children = Array.from(box.attribute.map.values());
|
|
||||||
newButton.revealChild = true;
|
|
||||||
},
|
|
||||||
'remove': (box, address) => {
|
|
||||||
if (!address) return;
|
|
||||||
|
|
||||||
const removedButton = box.attribute.map.get(address);
|
|
||||||
if (!removedButton) return;
|
|
||||||
removedButton.revealChild = false;
|
|
||||||
|
|
||||||
Utils.timeout(userOptions.animations.durationLarge, () => {
|
|
||||||
removedButton.destroy();
|
|
||||||
box.attribute.map.delete(address);
|
|
||||||
box.children = Array.from(box.attribute.map.values());
|
|
||||||
})
|
|
||||||
},
|
|
||||||
},
|
|
||||||
setup: (self) => {
|
|
||||||
self.hook(Hyprland, (box, address) => box.attribute.add(box, address, self.monitor), 'client-added')
|
|
||||||
.hook(Hyprland, (box, address) => box.attribute.remove(box, address, self.monitor), 'client-removed')
|
|
||||||
Utils.timeout(100, () => self.attribute.update(self));
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const PinnedApps = () => Widget.Box({
|
|
||||||
class_name: 'dock-apps',
|
|
||||||
homogeneous: true,
|
|
||||||
children: userOptions.dock.pinnedApps
|
|
||||||
.map(term => ({ app: Applications.query(term)?.[0], term }))
|
|
||||||
.filter(({ app }) => app)
|
|
||||||
.map(({ app, term = true }) => {
|
|
||||||
const newButton = AppButton({
|
|
||||||
// different icon, emm...
|
|
||||||
icon: userOptions.dock.searchPinnedAppIcons ?
|
|
||||||
searchIcons(app.name, icon_files) :
|
|
||||||
app.icon_name,
|
|
||||||
onClicked: () => {
|
|
||||||
for (const client of Hyprland.clients) {
|
|
||||||
if (client.class.toLowerCase().includes(term))
|
|
||||||
return focus(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
app.launch();
|
|
||||||
},
|
|
||||||
onMiddleClick: () => app.launch(),
|
|
||||||
tooltipText: app.name,
|
|
||||||
setup: (self) => {
|
|
||||||
self.revealChild = true;
|
|
||||||
self.hook(Hyprland, button => {
|
|
||||||
const running = Hyprland.clients
|
|
||||||
.find(client => client.class.toLowerCase().includes(term)) || false;
|
|
||||||
|
|
||||||
button.toggleClassName('notrunning', !running);
|
|
||||||
button.toggleClassName('focused', Hyprland.active.client.address == running.address);
|
|
||||||
button.set_tooltip_text(running ? running.title : app.name);
|
|
||||||
}, 'notify::clients')
|
|
||||||
},
|
|
||||||
})
|
|
||||||
newButton.revealChild = true;
|
|
||||||
return newButton;
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
export default (monitor = 0) => {
|
|
||||||
const dockContent = Box({
|
|
||||||
className: 'dock-bg spacing-h-5',
|
|
||||||
children: [
|
|
||||||
PinButton(),
|
|
||||||
PinnedApps(),
|
|
||||||
DockSeparator(),
|
|
||||||
Taskbar(),
|
|
||||||
LauncherButton(),
|
|
||||||
]
|
|
||||||
})
|
|
||||||
const dockRevealer = Revealer({
|
|
||||||
attribute: {
|
|
||||||
'updateShow': self => { // I only use mouse to resize. I don't care about keyboard resize if that's a thing
|
|
||||||
if (userOptions.dock.monitorExclusivity)
|
|
||||||
self.revealChild = Hyprland.active.monitor.id === monitor;
|
|
||||||
else
|
|
||||||
self.revealChild = true;
|
|
||||||
|
|
||||||
return self.revealChild
|
|
||||||
}
|
|
||||||
},
|
|
||||||
revealChild: false,
|
|
||||||
transition: 'slide_up',
|
|
||||||
transitionDuration: userOptions.animations.durationLarge,
|
|
||||||
child: dockContent,
|
|
||||||
setup: (self) => {
|
|
||||||
const callback = (self, trigger) => {
|
|
||||||
if (!userOptions.dock.trigger.includes(trigger)) return
|
|
||||||
const flag = self.attribute.updateShow(self)
|
|
||||||
|
|
||||||
if (flag) clearTimes();
|
|
||||||
|
|
||||||
const hidden = userOptions.dock.autoHide.find(e => e["trigger"] === trigger)
|
|
||||||
|
|
||||||
if (hidden) {
|
|
||||||
let id = Utils.timeout(hidden.interval, () => {
|
|
||||||
if (!isPinned) { self.revealChild = false }
|
|
||||||
timers = timers.filter(e => e !== id)
|
|
||||||
})
|
|
||||||
timers.push(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self
|
|
||||||
// .hook(Hyprland, (self) => self.attribute.updateShow(self))
|
|
||||||
.hook(Hyprland.active.workspace, self => callback(self, "workspace-active"))
|
|
||||||
.hook(Hyprland.active.client, self => callback(self, "client-active"))
|
|
||||||
.hook(Hyprland, self => callback(self, "client-added"), "client-added")
|
|
||||||
.hook(Hyprland, self => callback(self, "client-removed"), "client-removed")
|
|
||||||
},
|
|
||||||
})
|
|
||||||
return EventBox({
|
|
||||||
onHover: () => {
|
|
||||||
dockRevealer.revealChild = true;
|
|
||||||
clearTimes()
|
|
||||||
},
|
|
||||||
child: Box({
|
|
||||||
homogeneous: true,
|
|
||||||
css: `min-height: ${userOptions.dock.hiddenThickness}px;`,
|
|
||||||
children: [dockRevealer],
|
|
||||||
}),
|
|
||||||
setup: self => self.on("leave-notify-event", () => {
|
|
||||||
if (!isPinned) dockRevealer.revealChild = false;
|
|
||||||
clearTimes()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
const { Gio, GLib } = imports.gi
|
|
||||||
|
|
||||||
const exists = (path) => Gio.File.new_for_path(path).query_exists(null);
|
|
||||||
|
|
||||||
export const levenshteinDistance = (a, b) => {
|
|
||||||
if (!a.length) { return b.length }
|
|
||||||
if (!b.length) { return a.length }
|
|
||||||
|
|
||||||
let f = Array.from(new Array(a.length + 1),
|
|
||||||
() => new Array(b.length + 1).fill(0))
|
|
||||||
|
|
||||||
for (let i = 0; i <= b.length; i++) { f[0][i] = i; }
|
|
||||||
for (let i = 0; i <= a.length; i++) { f[i][0] = i; }
|
|
||||||
|
|
||||||
for (let i = 1; i <= a.length; i++) {
|
|
||||||
for (let j = 1; j <= b.length; j++) {
|
|
||||||
if (a.charAt(i - 1) === b.charAt(j - 1)) {
|
|
||||||
f[i][j] = f[i-1][j-1]
|
|
||||||
} else {
|
|
||||||
f[i][j] = Math.min(f[i-1][j-1], Math.min(f[i][j-1], f[i-1][j])) + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return f[a.length][b.length]
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getAllFiles = (dir, files = []) => {
|
|
||||||
if (!exists(dir)) { return [] }
|
|
||||||
const file = Gio.File.new_for_path(dir);
|
|
||||||
const enumerator = file.enumerate_children('standard::name,standard::type',
|
|
||||||
Gio.FileQueryInfoFlags.NONE, null);
|
|
||||||
|
|
||||||
for (const info of enumerator) {
|
|
||||||
if (info.get_file_type() === Gio.FileType.DIRECTORY) {
|
|
||||||
files.push(getAllFiles(`${dir}/${info.get_name()}`))
|
|
||||||
} else {
|
|
||||||
files.push(`${dir}/${info.get_name()}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return files.flat(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const searchIcons = (appClass, files) => {
|
|
||||||
appClass = appClass.toLowerCase()
|
|
||||||
|
|
||||||
if (!files.length) { return "" }
|
|
||||||
|
|
||||||
let appro = 0x3f3f3f3f
|
|
||||||
let path = ""
|
|
||||||
|
|
||||||
for (const item of files) {
|
|
||||||
let score = levenshteinDistance(item.split("/").pop().toLowerCase().split(".")[0], appClass)
|
|
||||||
|
|
||||||
if (score < appro) {
|
|
||||||
appro = score
|
|
||||||
path = item
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return path
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import Dock from './dock.js';
|
|
||||||
|
|
||||||
export default (monitor = 0) => Widget.Window({
|
|
||||||
monitor,
|
|
||||||
name: `dock${monitor}`,
|
|
||||||
layer: userOptions.dock.layer,
|
|
||||||
anchor: ['bottom'],
|
|
||||||
exclusivity: 'normal',
|
|
||||||
visible: true,
|
|
||||||
child: Dock(monitor),
|
|
||||||
});
|
|
||||||
|
|
@ -1,264 +0,0 @@
|
||||||
const { Gio, GLib } = imports.gi;
|
|
||||||
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import { ConfigToggle, ConfigMulipleSelection } from '../.commonwidgets/configwidgets.js';
|
|
||||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
|
|
||||||
const { execAsync } = Utils;
|
|
||||||
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
|
|
||||||
import { showColorScheme } from '../../variables.js';
|
|
||||||
import { MaterialIcon } from '../.commonwidgets/materialicon.js';
|
|
||||||
import { darkMode } from '../.miscutils/system.js';
|
|
||||||
|
|
||||||
const ColorBox = ({
|
|
||||||
name = 'Color',
|
|
||||||
...rest
|
|
||||||
}) => Widget.Box({
|
|
||||||
...rest,
|
|
||||||
homogeneous: true,
|
|
||||||
children: [
|
|
||||||
Widget.Label({
|
|
||||||
label: `${name}`,
|
|
||||||
})
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
const ColorSchemeSettingsRevealer = () => {
|
|
||||||
const headerButtonIcon = MaterialIcon('expand_more', 'norm');
|
|
||||||
const header = Widget.Button({
|
|
||||||
className: 'osd-settings-btn-arrow',
|
|
||||||
onClicked: () => {
|
|
||||||
content.revealChild = !content.revealChild;
|
|
||||||
headerButtonIcon.label = content.revealChild ? 'expand_less' : 'expand_more';
|
|
||||||
},
|
|
||||||
setup: setupCursorHover,
|
|
||||||
hpack: 'end',
|
|
||||||
child: headerButtonIcon,
|
|
||||||
});
|
|
||||||
const content = Widget.Revealer({
|
|
||||||
revealChild: false,
|
|
||||||
transition: 'slide_down',
|
|
||||||
transitionDuration: 200,
|
|
||||||
child: ColorSchemeSettings(),
|
|
||||||
setup: (self) => self.hook(isHoveredColorschemeSettings, (revealer) => {
|
|
||||||
if (isHoveredColorschemeSettings.value == false) {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (isHoveredColorschemeSettings.value == false)
|
|
||||||
revealer.revealChild = false;
|
|
||||||
headerButtonIcon.label = 'expand_more';
|
|
||||||
}, 1500);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
return Widget.EventBox({
|
|
||||||
onHover: (self) => {
|
|
||||||
isHoveredColorschemeSettings.setValue(true);
|
|
||||||
},
|
|
||||||
onHoverLost: (self) => {
|
|
||||||
isHoveredColorschemeSettings.setValue(false);
|
|
||||||
},
|
|
||||||
child: Widget.Box({
|
|
||||||
vertical: true,
|
|
||||||
children: [
|
|
||||||
header,
|
|
||||||
content,
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateSchemeInitIndex(optionsArr, searchValue = 'vibrant') {
|
|
||||||
if (searchValue == '')
|
|
||||||
searchValue = 'vibrant';
|
|
||||||
const flatArray = optionsArr.flatMap(subArray => subArray);
|
|
||||||
const result = flatArray.findIndex(element => element.value === searchValue);
|
|
||||||
const rowIndex = Math.floor(result / optionsArr[0].length);
|
|
||||||
const columnIndex = result % optionsArr[0].length;
|
|
||||||
return [rowIndex, columnIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
const schemeOptionsArr = [
|
|
||||||
[
|
|
||||||
{ name: getString('Tonal Spot'), value: 'tonalspot' },
|
|
||||||
{ name: getString('Fruit Salad'), value: 'fruitsalad' },
|
|
||||||
{ name: getString('Fidelity'), value: 'fidelity' },
|
|
||||||
{ name: getString('Rainbow'), value: 'rainbow' },
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{ name: getString('Neutral'), value: 'neutral' },
|
|
||||||
{ name: getString('Monochrome'), value: 'monochrome' },
|
|
||||||
{ name: getString('Expressive'), value: 'expressive' },
|
|
||||||
{ name: getString('Vibrant'), value: 'vibrant' },
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{ name: getString('Vibrant+'), value: 'morevibrant' },
|
|
||||||
],
|
|
||||||
//[
|
|
||||||
// { name: getString('Content'), value: 'content' },
|
|
||||||
//]
|
|
||||||
];
|
|
||||||
|
|
||||||
const LIGHTDARK_FILE_LOCATION = `${GLib.get_user_state_dir()}/ags/user/colormode.txt`;
|
|
||||||
const initTransparency = Utils.exec(`bash -c "sed -n \'2p\' ${LIGHTDARK_FILE_LOCATION}"`);
|
|
||||||
const initTransparencyVal = (initTransparency == "transparent") ? 1 : 0;
|
|
||||||
const initScheme = Utils.exec(`bash -c "sed -n \'3p\' ${LIGHTDARK_FILE_LOCATION}"`);
|
|
||||||
const initSchemeIndex = calculateSchemeInitIndex(schemeOptionsArr, initScheme);
|
|
||||||
|
|
||||||
const ColorSchemeSettings = () => Widget.Box({
|
|
||||||
className: 'osd-colorscheme-settings spacing-v-5 margin-20',
|
|
||||||
vertical: true,
|
|
||||||
vpack: 'center',
|
|
||||||
children: [
|
|
||||||
Widget.Box({
|
|
||||||
vertical: true,
|
|
||||||
children: [
|
|
||||||
Widget.Label({
|
|
||||||
xalign: 0,
|
|
||||||
className: 'txt-norm titlefont txt',
|
|
||||||
label: getString('Options'),
|
|
||||||
hpack: 'center',
|
|
||||||
}),
|
|
||||||
//////////////////
|
|
||||||
ConfigToggle({
|
|
||||||
icon: 'dark_mode',
|
|
||||||
name: getString('Dark Mode'),
|
|
||||||
desc: getString('Ya should go to sleep!'),
|
|
||||||
initValue: darkMode.value,
|
|
||||||
onChange: (_, newValue) => {
|
|
||||||
darkMode.value = !!newValue;
|
|
||||||
},
|
|
||||||
extraSetup: (self) => self.hook(darkMode, (self) => {
|
|
||||||
self.enabled.value = darkMode.value;
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
ConfigToggle({
|
|
||||||
icon: 'border_clear',
|
|
||||||
name: getString('Transparency'),
|
|
||||||
desc: getString('Make shell elements transparent'),
|
|
||||||
initValue: initTransparencyVal,
|
|
||||||
onChange: (self, newValue) => {
|
|
||||||
let transparency = newValue == 0 ? "opaque" : "transparent";
|
|
||||||
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_state_dir()}/ags/user && sed -i "2s/.*/${transparency}/" ${GLib.get_user_state_dir()}/ags/user/colormode.txt`])
|
|
||||||
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchcolor.sh`]))
|
|
||||||
.catch(print);
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
Widget.Box({
|
|
||||||
tooltipText: getString('Theme GTK apps using accent color\n(drawback: dark/light mode switching requires restart)'),
|
|
||||||
className: 'txt spacing-h-5 configtoggle-box',
|
|
||||||
children: [
|
|
||||||
MaterialIcon('imagesearch_roller', 'norm'),
|
|
||||||
Widget.Label({
|
|
||||||
className: 'txt txt-small',
|
|
||||||
label: getString('Use Gradience'),
|
|
||||||
}),
|
|
||||||
Widget.Box({ hexpand: true }),
|
|
||||||
ConfigMulipleSelection({
|
|
||||||
hpack: 'center',
|
|
||||||
vpack: 'center',
|
|
||||||
optionsArr: [
|
|
||||||
[{ name: 'Off', value: 0 }, { name: 'On', value: 1 }],
|
|
||||||
],
|
|
||||||
initIndex: [-1, -1],
|
|
||||||
onChange: (value, name) => {
|
|
||||||
const ADWAITA_BLUE = "#3584E4";
|
|
||||||
if (value) execAsync([`bash`, `-c`, `${App.configDir}/scripts/color_generation/switchcolor.sh - --yes-gradience`, `&`])
|
|
||||||
.catch(print);
|
|
||||||
else execAsync([`bash`, `-c`, `${App.configDir}/scripts/color_generation/switchcolor.sh "${ADWAITA_BLUE}" --no-gradience`, `&`])
|
|
||||||
.catch(print);
|
|
||||||
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
Widget.Box({
|
|
||||||
vertical: true,
|
|
||||||
className: 'spacing-v-5',
|
|
||||||
children: [
|
|
||||||
Widget.Label({
|
|
||||||
xalign: 0,
|
|
||||||
className: 'txt-norm titlefont txt margin-top-5',
|
|
||||||
label: getString('Scheme styles'),
|
|
||||||
hpack: 'center',
|
|
||||||
}),
|
|
||||||
//////////////////
|
|
||||||
ConfigMulipleSelection({
|
|
||||||
hpack: 'center',
|
|
||||||
vpack: 'center',
|
|
||||||
optionsArr: schemeOptionsArr,
|
|
||||||
initIndex: initSchemeIndex,
|
|
||||||
onChange: (value, name) => {
|
|
||||||
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_state_dir()}/ags/user && sed -i "3s/.*/${value}/" ${GLib.get_user_state_dir()}/ags/user/colormode.txt`])
|
|
||||||
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchcolor.sh`]))
|
|
||||||
.catch(print);
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
})
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
const ColorschemeContent = () => Widget.Box({
|
|
||||||
className: 'osd-colorscheme spacing-v-5',
|
|
||||||
vertical: true,
|
|
||||||
hpack: 'center',
|
|
||||||
children: [
|
|
||||||
Widget.Label({
|
|
||||||
xalign: 0,
|
|
||||||
className: 'txt-norm titlefont txt',
|
|
||||||
label: getString('Color scheme'),
|
|
||||||
hpack: 'center',
|
|
||||||
}),
|
|
||||||
Widget.Box({
|
|
||||||
className: 'spacing-h-5',
|
|
||||||
hpack: 'center',
|
|
||||||
children: [
|
|
||||||
ColorBox({ name: 'P', className: 'osd-color osd-color-primary' }),
|
|
||||||
ColorBox({ name: 'S', className: 'osd-color osd-color-secondary' }),
|
|
||||||
ColorBox({ name: 'T', className: 'osd-color osd-color-tertiary' }),
|
|
||||||
ColorBox({ name: 'Sf', className: 'osd-color osd-color-surface' }),
|
|
||||||
ColorBox({ name: 'Sf-i', className: 'osd-color osd-color-inverseSurface' }),
|
|
||||||
ColorBox({ name: 'E', className: 'osd-color osd-color-error' }),
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
Widget.Box({
|
|
||||||
className: 'spacing-h-5',
|
|
||||||
hpack: 'center',
|
|
||||||
children: [
|
|
||||||
ColorBox({ name: 'P-c', className: 'osd-color osd-color-primaryContainer' }),
|
|
||||||
ColorBox({ name: 'S-c', className: 'osd-color osd-color-secondaryContainer' }),
|
|
||||||
ColorBox({ name: 'T-c', className: 'osd-color osd-color-tertiaryContainer' }),
|
|
||||||
ColorBox({ name: 'Sf-c', className: 'osd-color osd-color-surfaceContainer' }),
|
|
||||||
ColorBox({ name: 'Sf-v', className: 'osd-color osd-color-surfaceVariant' }),
|
|
||||||
ColorBox({ name: 'E-c', className: 'osd-color osd-color-errorContainer' }),
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
ColorSchemeSettingsRevealer(),
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
const isHoveredColorschemeSettings = Variable(false);
|
|
||||||
|
|
||||||
export default () => Widget.Revealer({
|
|
||||||
transition: 'slide_down',
|
|
||||||
transitionDuration: userOptions.animations.durationLarge,
|
|
||||||
child: ColorschemeContent(),
|
|
||||||
setup: (self) => {
|
|
||||||
self
|
|
||||||
.hook(showColorScheme, (revealer) => {
|
|
||||||
if (showColorScheme.value == true)
|
|
||||||
revealer.revealChild = true;
|
|
||||||
else
|
|
||||||
revealer.revealChild = isHoveredColorschemeSettings.value;
|
|
||||||
})
|
|
||||||
.hook(isHoveredColorschemeSettings, (revealer) => {
|
|
||||||
if (isHoveredColorschemeSettings.value == false) {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (isHoveredColorschemeSettings.value == false)
|
|
||||||
revealer.revealChild = showColorScheme.value;
|
|
||||||
}, 2000);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
@ -1,124 +0,0 @@
|
||||||
// This file is for brightness/volume indicators
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import Audio from 'resource:///com/github/Aylur/ags/service/audio.js';
|
|
||||||
const { Box, Label, ProgressBar } = Widget;
|
|
||||||
import { MarginRevealer } from '../.widgethacks/advancedrevealers.js';
|
|
||||||
import Brightness from '../../services/brightness.js';
|
|
||||||
import Indicator from '../../services/indicator.js';
|
|
||||||
|
|
||||||
const OsdValue = ({
|
|
||||||
name, nameSetup = undefined, labelSetup, progressSetup,
|
|
||||||
extraClassName = '', extraProgressClassName = '',
|
|
||||||
...rest
|
|
||||||
}) => {
|
|
||||||
const valueName = Label({
|
|
||||||
xalign: 0, yalign: 0, hexpand: true,
|
|
||||||
className: 'osd-label',
|
|
||||||
label: `${name}`,
|
|
||||||
setup: nameSetup,
|
|
||||||
});
|
|
||||||
const valueNumber = Label({
|
|
||||||
hexpand: false, className: 'osd-value-txt',
|
|
||||||
setup: labelSetup,
|
|
||||||
});
|
|
||||||
return Box({ // Volume
|
|
||||||
vertical: true,
|
|
||||||
hexpand: true,
|
|
||||||
className: `osd-bg osd-value ${extraClassName}`,
|
|
||||||
attribute: {
|
|
||||||
'disable': () => {
|
|
||||||
valueNumber.label = '';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
Box({
|
|
||||||
vexpand: true,
|
|
||||||
children: [
|
|
||||||
valueName,
|
|
||||||
valueNumber,
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
ProgressBar({
|
|
||||||
className: `osd-progress ${extraProgressClassName}`,
|
|
||||||
hexpand: true,
|
|
||||||
vertical: false,
|
|
||||||
setup: progressSetup,
|
|
||||||
})
|
|
||||||
],
|
|
||||||
...rest,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export default (monitor = 0) => {
|
|
||||||
const brightnessIndicator = OsdValue({
|
|
||||||
name: 'Brightness',
|
|
||||||
extraClassName: 'osd-brightness',
|
|
||||||
extraProgressClassName: 'osd-brightness-progress',
|
|
||||||
labelSetup: (self) => self.hook(Brightness[monitor], self => {
|
|
||||||
self.label = `${Math.round(Brightness[monitor].screen_value * 100)}`;
|
|
||||||
}, 'notify::screen-value'),
|
|
||||||
progressSetup: (self) => self.hook(Brightness[monitor], (progress) => {
|
|
||||||
const updateValue = Brightness[monitor].screen_value;
|
|
||||||
if (updateValue !== progress.value) Indicator.popup(1);
|
|
||||||
progress.value = updateValue;
|
|
||||||
}, 'notify::screen-value'),
|
|
||||||
});
|
|
||||||
|
|
||||||
const volumeIndicator = OsdValue({
|
|
||||||
name: 'Volume',
|
|
||||||
extraClassName: 'osd-volume',
|
|
||||||
extraProgressClassName: 'osd-volume-progress',
|
|
||||||
attribute: { headphones: undefined , device: undefined},
|
|
||||||
nameSetup: (self) => Utils.timeout(1, () => {
|
|
||||||
const updateAudioDevice = (self) => {
|
|
||||||
const usingHeadphones = (Audio.speaker?.stream?.port)?.toLowerCase().includes('headphone');
|
|
||||||
if (volumeIndicator.attribute.headphones === undefined ||
|
|
||||||
volumeIndicator.attribute.headphones !== usingHeadphones) {
|
|
||||||
volumeIndicator.attribute.headphones = usingHeadphones;
|
|
||||||
self.label = usingHeadphones ? 'Headphones' : 'Speakers';
|
|
||||||
// Indicator.popup(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.hook(Audio, updateAudioDevice);
|
|
||||||
Utils.timeout(1000, updateAudioDevice);
|
|
||||||
}),
|
|
||||||
labelSetup: (self) => self.hook(Audio, (label) => {
|
|
||||||
const newDevice = (Audio.speaker?.name);
|
|
||||||
const updateValue = Math.round(Audio.speaker?.volume * 100);
|
|
||||||
if (!isNaN(updateValue)) {
|
|
||||||
if (newDevice === volumeIndicator.attribute.device && updateValue != label.label) {
|
|
||||||
Indicator.popup(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
volumeIndicator.attribute.device = newDevice;
|
|
||||||
label.label = `${updateValue}`;
|
|
||||||
}),
|
|
||||||
progressSetup: (self) => self.hook(Audio, (progress) => {
|
|
||||||
const updateValue = Audio.speaker?.volume;
|
|
||||||
if (!isNaN(updateValue)) {
|
|
||||||
if (updateValue > 1) progress.value = 1;
|
|
||||||
else progress.value = updateValue;
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
return MarginRevealer({
|
|
||||||
transition: 'slide_down',
|
|
||||||
showClass: 'osd-show',
|
|
||||||
hideClass: 'osd-hide',
|
|
||||||
extraSetup: (self) => self
|
|
||||||
.hook(Indicator, (revealer, value) => {
|
|
||||||
if (value > -1) revealer.attribute.show();
|
|
||||||
else revealer.attribute.hide();
|
|
||||||
}, 'popup')
|
|
||||||
,
|
|
||||||
child: Box({
|
|
||||||
hpack: 'center',
|
|
||||||
vertical: false,
|
|
||||||
className: 'spacing-h--10',
|
|
||||||
children: [
|
|
||||||
brightnessIndicator,
|
|
||||||
volumeIndicator,
|
|
||||||
]
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import Indicator from '../../services/indicator.js';
|
|
||||||
import IndicatorValues from './indicatorvalues.js';
|
|
||||||
import MusicControls from './musiccontrols.js';
|
|
||||||
import ColorScheme from './colorscheme.js';
|
|
||||||
import NotificationPopups from './notificationpopups.js';
|
|
||||||
|
|
||||||
export default (monitor = 0) => Widget.Window({
|
|
||||||
name: `indicator${monitor}`,
|
|
||||||
monitor,
|
|
||||||
className: 'indicator',
|
|
||||||
layer: 'overlay',
|
|
||||||
// exclusivity: 'ignore',
|
|
||||||
visible: true,
|
|
||||||
anchor: ['top'],
|
|
||||||
child: Widget.EventBox({
|
|
||||||
onHover: () => { //make the widget hide when hovering
|
|
||||||
Indicator.popup(-1);
|
|
||||||
},
|
|
||||||
child: Widget.Box({
|
|
||||||
vertical: true,
|
|
||||||
className: 'osd-window',
|
|
||||||
css: 'min-height: 2px;',
|
|
||||||
children: [
|
|
||||||
IndicatorValues(monitor),
|
|
||||||
MusicControls(),
|
|
||||||
NotificationPopups(),
|
|
||||||
ColorScheme(),
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
@ -1,408 +0,0 @@
|
||||||
const { GLib } = imports.gi;
|
|
||||||
import App from 'resource:///com/github/Aylur/ags/app.js';
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
|
|
||||||
import Mpris from 'resource:///com/github/Aylur/ags/service/mpris.js';
|
|
||||||
const { exec, execAsync } = Utils;
|
|
||||||
const { Box, EventBox, Icon, Scrollable, Label, Button, Revealer } = Widget;
|
|
||||||
|
|
||||||
import { fileExists } from '../.miscutils/files.js';
|
|
||||||
import { AnimatedCircProg } from "../.commonwidgets/cairo_circularprogress.js";
|
|
||||||
import { showMusicControls } from '../../variables.js';
|
|
||||||
import { darkMode, hasPlasmaIntegration } from '../.miscutils/system.js';
|
|
||||||
|
|
||||||
const COMPILED_STYLE_DIR = `${GLib.get_user_cache_dir()}/ags/user/generated`
|
|
||||||
const LIGHTDARK_FILE_LOCATION = `${GLib.get_user_state_dir()}/ags/user/colormode.txt`;
|
|
||||||
const colorMode = Utils.exec(`bash -c "sed -n \'1p\' '${LIGHTDARK_FILE_LOCATION}'"`);
|
|
||||||
const lightDark = (colorMode == "light") ? '-l' : '';
|
|
||||||
const COVER_COLORSCHEME_SUFFIX = '_colorscheme.css';
|
|
||||||
var lastCoverPath = '';
|
|
||||||
|
|
||||||
function isRealPlayer(player) {
|
|
||||||
return (
|
|
||||||
// Remove unecessary native buses from browsers if there's plasma integration
|
|
||||||
!(hasPlasmaIntegration && player.busName.startsWith('org.mpris.MediaPlayer2.firefox')) &&
|
|
||||||
!(hasPlasmaIntegration && player.busName.startsWith('org.mpris.MediaPlayer2.chromium')) &&
|
|
||||||
// playerctld just copies other buses and we don't need duplicates
|
|
||||||
!player.busName.startsWith('org.mpris.MediaPlayer2.playerctld') &&
|
|
||||||
// Non-instance mpd bus
|
|
||||||
!(player.busName.endsWith('.mpd') && !player.busName.endsWith('MediaPlayer2.mpd'))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getPlayer = (name = userOptions.music.preferredPlayer) => Mpris.getPlayer(name) || Mpris.players[0] || null;
|
|
||||||
function lengthStr(length) {
|
|
||||||
const min = Math.floor(length / 60);
|
|
||||||
const sec = Math.floor(length % 60);
|
|
||||||
const sec0 = sec < 10 ? '0' : '';
|
|
||||||
return `${min}:${sec0}${sec}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function detectMediaSource(link) {
|
|
||||||
if (link.startsWith("file://")) {
|
|
||||||
if (link.includes('firefox-mpris'))
|
|
||||||
return ' Firefox'
|
|
||||||
return " File";
|
|
||||||
}
|
|
||||||
let url = link.replace(/(^\w+:|^)\/\//, '');
|
|
||||||
let domain = url.match(/(?:[a-z]+\.)?([a-z]+\.[a-z]+)/i)[1];
|
|
||||||
if (domain == 'ytimg.com') return ' Youtube';
|
|
||||||
if (domain == 'discordapp.net') return ' Discord';
|
|
||||||
if (domain == 'sndcdn.com') return ' SoundCloud';
|
|
||||||
return domain;
|
|
||||||
}
|
|
||||||
|
|
||||||
const DEFAULT_MUSIC_FONT = 'Gabarito, sans-serif';
|
|
||||||
function getTrackfont(player) {
|
|
||||||
const title = player.trackTitle;
|
|
||||||
const artists = player.trackArtists.join(' ');
|
|
||||||
if (artists.includes('TANO*C') || artists.includes('USAO') || artists.includes('Kobaryo'))
|
|
||||||
return 'Chakra Petch'; // Rigid square replacement
|
|
||||||
if (title.includes('東方'))
|
|
||||||
return 'Crimson Text, serif'; // Serif for Touhou stuff
|
|
||||||
return DEFAULT_MUSIC_FONT;
|
|
||||||
}
|
|
||||||
function trimTrackTitle(title) {
|
|
||||||
if (!title) return '';
|
|
||||||
const cleanPatterns = [
|
|
||||||
/【[^】]*】/, // Touhou n weeb stuff
|
|
||||||
" [FREE DOWNLOAD]", // F-777
|
|
||||||
];
|
|
||||||
cleanPatterns.forEach((expr) => title = title.replace(expr, ''));
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TrackProgress = ({ player, ...rest }) => {
|
|
||||||
const _updateProgress = (circprog) => {
|
|
||||||
// const player = Mpris.getPlayer();
|
|
||||||
if (!player) return;
|
|
||||||
// Set circular progress (see definition of AnimatedCircProg for explanation)
|
|
||||||
circprog.css = `font-size: ${Math.max(player.position / player.length * 100, 0)}px;`
|
|
||||||
}
|
|
||||||
return AnimatedCircProg({
|
|
||||||
...rest,
|
|
||||||
className: 'osd-music-circprog',
|
|
||||||
vpack: 'center',
|
|
||||||
extraSetup: (self) => self
|
|
||||||
.hook(Mpris, _updateProgress)
|
|
||||||
.poll(3000, _updateProgress)
|
|
||||||
,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const TrackTitle = ({ player, ...rest }) => Label({
|
|
||||||
...rest,
|
|
||||||
label: 'No music playing',
|
|
||||||
xalign: 0,
|
|
||||||
truncate: 'end',
|
|
||||||
// wrap: true,
|
|
||||||
className: 'osd-music-title',
|
|
||||||
setup: (self) => self.hook(player, (self) => {
|
|
||||||
// Player name
|
|
||||||
self.label = player.trackTitle.length > 0 ? trimTrackTitle(player.trackTitle) : 'No media';
|
|
||||||
// Font based on track/artist
|
|
||||||
const fontForThisTrack = getTrackfont(player);
|
|
||||||
self.css = `font-family: ${fontForThisTrack}, ${DEFAULT_MUSIC_FONT};`;
|
|
||||||
}, 'notify::track-title'),
|
|
||||||
});
|
|
||||||
|
|
||||||
const TrackArtists = ({ player, ...rest }) => Label({
|
|
||||||
...rest,
|
|
||||||
xalign: 0,
|
|
||||||
className: 'osd-music-artists',
|
|
||||||
truncate: 'end',
|
|
||||||
setup: (self) => self.hook(player, (self) => {
|
|
||||||
self.label = player.trackArtists.length > 0 ? player.trackArtists.join(', ') : '';
|
|
||||||
}, 'notify::track-artists'),
|
|
||||||
})
|
|
||||||
|
|
||||||
const CoverArt = ({ player, ...rest }) => {
|
|
||||||
const fallbackCoverArt = Box({ // Fallback
|
|
||||||
className: 'osd-music-cover-fallback',
|
|
||||||
homogeneous: true,
|
|
||||||
children: [Label({
|
|
||||||
className: 'icon-material txt-gigantic txt-thin',
|
|
||||||
label: 'music_note',
|
|
||||||
})]
|
|
||||||
});
|
|
||||||
// const coverArtDrawingArea = Widget.DrawingArea({ className: 'osd-music-cover-art' });
|
|
||||||
// const coverArtDrawingAreaStyleContext = coverArtDrawingArea.get_style_context();
|
|
||||||
const realCoverArt = Box({
|
|
||||||
className: 'osd-music-cover-art',
|
|
||||||
homogeneous: true,
|
|
||||||
// children: [coverArtDrawingArea],
|
|
||||||
attribute: {
|
|
||||||
'pixbuf': null,
|
|
||||||
// 'showImage': (self, imagePath) => {
|
|
||||||
// const borderRadius = coverArtDrawingAreaStyleContext.get_property('border-radius', Gtk.StateFlags.NORMAL);
|
|
||||||
// const frameHeight = coverArtDrawingAreaStyleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
|
|
||||||
// const frameWidth = coverArtDrawingAreaStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
|
|
||||||
// let imageHeight = frameHeight;
|
|
||||||
// let imageWidth = frameWidth;
|
|
||||||
// // Get image dimensions
|
|
||||||
// execAsync(['identify', '-format', '{"w":%w,"h":%h}', imagePath])
|
|
||||||
// .then((output) => {
|
|
||||||
// const imageDimensions = JSON.parse(output);
|
|
||||||
// const imageAspectRatio = imageDimensions.w / imageDimensions.h;
|
|
||||||
// const displayedAspectRatio = imageWidth / imageHeight;
|
|
||||||
// if (imageAspectRatio >= displayedAspectRatio) {
|
|
||||||
// imageWidth = imageHeight * imageAspectRatio;
|
|
||||||
// } else {
|
|
||||||
// imageHeight = imageWidth / imageAspectRatio;
|
|
||||||
// }
|
|
||||||
// // Real stuff
|
|
||||||
// // TODO: fix memory leak(?)
|
|
||||||
// // if (self.attribute.pixbuf) {
|
|
||||||
// // self.attribute.pixbuf.unref();
|
|
||||||
// // self.attribute.pixbuf = null;
|
|
||||||
// // }
|
|
||||||
// self.attribute.pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(imagePath, imageWidth, imageHeight);
|
|
||||||
|
|
||||||
// coverArtDrawingArea.set_size_request(frameWidth, frameHeight);
|
|
||||||
// coverArtDrawingArea.connect("draw", (widget, cr) => {
|
|
||||||
// // Clip a rounded rectangle area
|
|
||||||
// cr.arc(borderRadius, borderRadius, borderRadius, Math.PI, 1.5 * Math.PI);
|
|
||||||
// cr.arc(frameWidth - borderRadius, borderRadius, borderRadius, 1.5 * Math.PI, 2 * Math.PI);
|
|
||||||
// cr.arc(frameWidth - borderRadius, frameHeight - borderRadius, borderRadius, 0, 0.5 * Math.PI);
|
|
||||||
// cr.arc(borderRadius, frameHeight - borderRadius, borderRadius, 0.5 * Math.PI, Math.PI);
|
|
||||||
// cr.closePath();
|
|
||||||
// cr.clip();
|
|
||||||
// // Paint image as bg, centered
|
|
||||||
// Gdk.cairo_set_source_pixbuf(cr, self.attribute.pixbuf,
|
|
||||||
// frameWidth / 2 - imageWidth / 2,
|
|
||||||
// frameHeight / 2 - imageHeight / 2
|
|
||||||
// );
|
|
||||||
// cr.paint();
|
|
||||||
// });
|
|
||||||
// }).catch(print)
|
|
||||||
// },
|
|
||||||
'updateCover': (self) => {
|
|
||||||
// const player = Mpris.getPlayer(); // Maybe no need to re-get player.. can't remember why I had this
|
|
||||||
// Player closed
|
|
||||||
// Note that cover path still remains, so we're checking title
|
|
||||||
if (!player || player.trackTitle == "" || !player.coverPath) {
|
|
||||||
self.css = `background-image: none;`; // CSS image
|
|
||||||
App.applyCss(`${COMPILED_STYLE_DIR}/style.css`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const coverPath = player.coverPath;
|
|
||||||
const stylePath = `${player.coverPath}${darkMode.value ? '' : '-l'}${COVER_COLORSCHEME_SUFFIX}`;
|
|
||||||
if (player.coverPath == lastCoverPath) { // Since 'notify::cover-path' emits on cover download complete
|
|
||||||
Utils.timeout(200, () => {
|
|
||||||
// self.attribute.showImage(self, coverPath);
|
|
||||||
self.css = `background-image: url('${coverPath}');`; // CSS image
|
|
||||||
});
|
|
||||||
}
|
|
||||||
lastCoverPath = player.coverPath;
|
|
||||||
|
|
||||||
// If a colorscheme has already been generated, skip generation
|
|
||||||
if (fileExists(stylePath)) {
|
|
||||||
// self.attribute.showImage(self, coverPath)
|
|
||||||
self.css = `background-image: url('${coverPath}');`; // CSS image
|
|
||||||
App.applyCss(stylePath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate colors
|
|
||||||
execAsync(['bash', '-c',
|
|
||||||
`${App.configDir}/scripts/color_generation/generate_colors_material.py --path '${coverPath}' --mode ${darkMode.value ? 'dark' : 'light'} > ${GLib.get_user_state_dir()}/ags/scss/_musicmaterial.scss`])
|
|
||||||
.then(() => {
|
|
||||||
exec(`wal -i "${player.coverPath}" -n -t -s -e -q ${darkMode.value ? '' : '-l'}`)
|
|
||||||
exec(`cp ${GLib.get_user_cache_dir()}/wal/colors.scss ${GLib.get_user_state_dir()}/ags/scss/_musicwal.scss`);
|
|
||||||
exec(`sass -I "${GLib.get_user_state_dir()}/ags/scss" -I "${App.configDir}/scss/fallback" "${App.configDir}/scss/_music.scss" "${stylePath}"`);
|
|
||||||
Utils.timeout(200, () => {
|
|
||||||
// self.attribute.showImage(self, coverPath)
|
|
||||||
self.css = `background-image: url('${coverPath}');`; // CSS image
|
|
||||||
});
|
|
||||||
App.applyCss(`${stylePath}`);
|
|
||||||
})
|
|
||||||
.catch(print);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
setup: (self) => self
|
|
||||||
.hook(player, (self) => {
|
|
||||||
self.attribute.updateCover(self);
|
|
||||||
}, 'notify::cover-path')
|
|
||||||
,
|
|
||||||
});
|
|
||||||
return Box({
|
|
||||||
...rest,
|
|
||||||
className: 'osd-music-cover',
|
|
||||||
children: [
|
|
||||||
Widget.Overlay({
|
|
||||||
child: fallbackCoverArt,
|
|
||||||
overlays: [realCoverArt],
|
|
||||||
})
|
|
||||||
],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const TrackControls = ({ player, ...rest }) => Widget.Revealer({
|
|
||||||
revealChild: false,
|
|
||||||
transition: 'slide_right',
|
|
||||||
transitionDuration: userOptions.animations.durationLarge,
|
|
||||||
child: Widget.Box({
|
|
||||||
...rest,
|
|
||||||
vpack: 'center',
|
|
||||||
className: 'osd-music-controls spacing-h-3',
|
|
||||||
children: [
|
|
||||||
Button({
|
|
||||||
className: 'osd-music-controlbtn',
|
|
||||||
onClicked: () => player.previous(),
|
|
||||||
child: Label({
|
|
||||||
className: 'icon-material osd-music-controlbtn-txt',
|
|
||||||
label: 'skip_previous',
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
Button({
|
|
||||||
className: 'osd-music-controlbtn',
|
|
||||||
onClicked: () => player.next(),
|
|
||||||
child: Label({
|
|
||||||
className: 'icon-material osd-music-controlbtn-txt',
|
|
||||||
label: 'skip_next',
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
setup: (self) => self.hook(Mpris, (self) => {
|
|
||||||
// const player = Mpris.getPlayer();
|
|
||||||
if (!player)
|
|
||||||
self.revealChild = false;
|
|
||||||
else
|
|
||||||
self.revealChild = true;
|
|
||||||
}, 'notify::play-back-status'),
|
|
||||||
});
|
|
||||||
|
|
||||||
const TrackSource = ({ player, ...rest }) => Widget.Revealer({
|
|
||||||
revealChild: false,
|
|
||||||
transition: 'slide_left',
|
|
||||||
transitionDuration: userOptions.animations.durationLarge,
|
|
||||||
child: Widget.Box({
|
|
||||||
...rest,
|
|
||||||
className: 'osd-music-pill spacing-h-5',
|
|
||||||
homogeneous: true,
|
|
||||||
children: [
|
|
||||||
Label({
|
|
||||||
hpack: 'fill',
|
|
||||||
justification: 'center',
|
|
||||||
className: 'icon-nerd',
|
|
||||||
setup: (self) => self.hook(player, (self) => {
|
|
||||||
self.label = detectMediaSource(player.trackCoverUrl);
|
|
||||||
}, 'notify::cover-path'),
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
setup: (self) => self.hook(Mpris, (self) => {
|
|
||||||
const mpris = Mpris.getPlayer('');
|
|
||||||
if (!mpris)
|
|
||||||
self.revealChild = false;
|
|
||||||
else
|
|
||||||
self.revealChild = true;
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const TrackTime = ({ player, ...rest }) => {
|
|
||||||
return Widget.Revealer({
|
|
||||||
revealChild: false,
|
|
||||||
transition: 'slide_left',
|
|
||||||
transitionDuration: userOptions.animations.durationLarge,
|
|
||||||
child: Widget.Box({
|
|
||||||
...rest,
|
|
||||||
vpack: 'center',
|
|
||||||
className: 'osd-music-pill spacing-h-5',
|
|
||||||
children: [
|
|
||||||
Label({
|
|
||||||
setup: (self) => self.poll(1000, (self) => {
|
|
||||||
// const player = Mpris.getPlayer();
|
|
||||||
if (!player) return;
|
|
||||||
self.label = lengthStr(player.position);
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
Label({ label: '/' }),
|
|
||||||
Label({
|
|
||||||
setup: (self) => self.hook(Mpris, (self) => {
|
|
||||||
// const player = Mpris.getPlayer();
|
|
||||||
if (!player) return;
|
|
||||||
self.label = lengthStr(player.length);
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
setup: (self) => self.hook(Mpris, (self) => {
|
|
||||||
if (!player) self.revealChild = false;
|
|
||||||
else self.revealChild = true;
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const PlayState = ({ player }) => {
|
|
||||||
var position = 0;
|
|
||||||
const trackCircProg = TrackProgress({ player: player });
|
|
||||||
return Widget.Button({
|
|
||||||
className: 'osd-music-playstate',
|
|
||||||
child: Widget.Overlay({
|
|
||||||
child: trackCircProg,
|
|
||||||
overlays: [
|
|
||||||
Widget.Button({
|
|
||||||
className: 'osd-music-playstate-btn',
|
|
||||||
onClicked: () => player.playPause(),
|
|
||||||
child: Widget.Label({
|
|
||||||
justification: 'center',
|
|
||||||
hpack: 'fill',
|
|
||||||
vpack: 'center',
|
|
||||||
setup: (self) => self.hook(player, (label) => {
|
|
||||||
label.label = `${player.playBackStatus == 'Playing' ? 'pause' : 'play_arrow'}`;
|
|
||||||
}, 'notify::play-back-status'),
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
passThrough: true,
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const MusicControlsWidget = (player) => Box({
|
|
||||||
className: 'osd-music spacing-h-20 test',
|
|
||||||
children: [
|
|
||||||
CoverArt({ player: player, vpack: 'center' }),
|
|
||||||
Box({
|
|
||||||
vertical: true,
|
|
||||||
className: 'spacing-v-5 osd-music-info',
|
|
||||||
children: [
|
|
||||||
Box({
|
|
||||||
vertical: true,
|
|
||||||
vpack: 'center',
|
|
||||||
hexpand: true,
|
|
||||||
children: [
|
|
||||||
TrackTitle({ player: player }),
|
|
||||||
TrackArtists({ player: player }),
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
Box({ vexpand: true }),
|
|
||||||
Box({
|
|
||||||
className: 'spacing-h-10',
|
|
||||||
setup: (box) => {
|
|
||||||
box.pack_start(TrackControls({ player: player }), false, false, 0);
|
|
||||||
box.pack_end(PlayState({ player: player }), false, false, 0);
|
|
||||||
if(hasPlasmaIntegration || player.busName.startsWith('org.mpris.MediaPlayer2.chromium')) box.pack_end(TrackTime({ player: player }), false, false, 0)
|
|
||||||
// box.pack_end(TrackSource({ vpack: 'center', player: player }), false, false, 0);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
]
|
|
||||||
})
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
export default () => Revealer({
|
|
||||||
transition: 'slide_down',
|
|
||||||
transitionDuration: userOptions.animations.durationLarge,
|
|
||||||
revealChild: false,
|
|
||||||
child: Box({
|
|
||||||
children: Mpris.bind("players")
|
|
||||||
.as(players => players.map((player) => (isRealPlayer(player) ? MusicControlsWidget(player) : null)))
|
|
||||||
}),
|
|
||||||
setup: (self) => self.hook(showMusicControls, (revealer) => {
|
|
||||||
revealer.revealChild = showMusicControls.value;
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
// This file is for popup notifications
|
|
||||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
||||||
import Notifications from 'resource:///com/github/Aylur/ags/service/notifications.js';
|
|
||||||
const { Box } = Widget;
|
|
||||||
import Notification from '../.commonwidgets/notification.js';
|
|
||||||
|
|
||||||
export default () => Box({
|
|
||||||
vertical: true,
|
|
||||||
hpack: 'center',
|
|
||||||
className: 'osd-notifs spacing-v-5-revealer',
|
|
||||||
attribute: {
|
|
||||||
'map': new Map(),
|
|
||||||
'dismiss': (box, id, force = false) => {
|
|
||||||
if (!id || !box.attribute.map.has(id))
|
|
||||||
return;
|
|
||||||
const notifWidget = box.attribute.map.get(id);
|
|
||||||
if (notifWidget == null || notifWidget.attribute.hovered && !force)
|
|
||||||
return; // cuz already destroyed
|
|
||||||
|
|
||||||
notifWidget.revealChild = false;
|
|
||||||
notifWidget.attribute.destroyWithAnims();
|
|
||||||
box.attribute.map.delete(id);
|
|
||||||
},
|
|
||||||
'notify': (box, id) => {
|
|
||||||
if (!id || Notifications.dnd) return;
|
|
||||||
if (!Notifications.getNotification(id)) return;
|
|
||||||
|
|
||||||
box.attribute.map.delete(id);
|
|
||||||
|
|
||||||
const notif = Notifications.getNotification(id);
|
|
||||||
const newNotif = Notification({
|
|
||||||
notifObject: notif,
|
|
||||||
isPopup: true,
|
|
||||||
});
|
|
||||||
box.attribute.map.set(id, newNotif);
|
|
||||||
box.pack_end(box.attribute.map.get(id), false, false, 0);
|
|
||||||
box.show_all();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
setup: (self) => self
|
|
||||||
.hook(Notifications, (box, id) => box.attribute.notify(box, id), 'notified')
|
|
||||||
.hook(Notifications, (box, id) => box.attribute.dismiss(box, id), 'dismissed')
|
|
||||||
.hook(Notifications, (box, id) => box.attribute.dismiss(box, id, true), 'closed')
|
|
||||||
,
|
|
||||||
});
|
|
||||||