Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99517bbb6c | ||
|
|
1ac77c4045 | ||
|
|
61e0ab126f | ||
|
|
b6b079b8f0 | ||
|
|
f9b35addae | ||
|
|
8425ceb709 | ||
|
|
fa77bc2514 | ||
|
|
84e96f175c | ||
|
|
09c1e312cb | ||
|
|
b14133bbec | ||
|
|
3d1011e17c | ||
|
|
34e978e84c | ||
|
|
1e99a15f6c | ||
|
|
26a29b3182 | ||
|
|
75b1383edf | ||
|
|
d215693df4 | ||
|
|
6423eaa29d | ||
|
|
6f4c331dd4 | ||
|
|
37f4a0391f | ||
|
|
829b0de65e | ||
|
|
2c5365343e | ||
|
|
39c2dc2ac4 | ||
|
|
4c90a40ab5 | ||
|
|
c98d949ea7 | ||
|
|
dd964df37b | ||
|
|
55ca1573e5 | ||
|
|
a75a04c814 | ||
|
|
d37d12e5d8 | ||
|
|
e7729693df | ||
|
|
bed14dac95 | ||
|
|
1e02f21072 | ||
|
|
bf71fa6174 | ||
|
|
e78076944a | ||
|
|
34989c95ae | ||
|
|
4264022a87 | ||
|
|
2796c820d3 | ||
|
|
46d240e5cd | ||
|
|
435a761d22 | ||
|
|
6d5b84db51 | ||
|
|
592e4a838c | ||
|
|
19bc0e3212 | ||
|
|
1b0a6e6d42 | ||
|
|
467c2ebf07 | ||
|
|
cb026ebe5d | ||
|
|
fe5c70240e | ||
|
|
2cee5ce877 | ||
|
|
f62b2b1e4a | ||
|
|
8f2ece4fb7 | ||
|
|
5830509c0d | ||
|
|
6ff9cb4351 | ||
|
|
ea6ea60025 | ||
|
|
7d6f26a6d5 | ||
|
|
10a6a8862f | ||
|
|
76a0ab7891 | ||
|
|
82c4edd500 | ||
|
|
b046ddb942 | ||
|
|
678fb8eb63 | ||
|
|
d3cddc9414 | ||
|
|
560e978a34 | ||
|
|
47f0e4018f | ||
|
|
126a6333a7 | ||
|
|
c1f1cc13eb | ||
|
|
576e20682e | ||
|
|
356ad9d74b | ||
|
|
31465ed3f6 | ||
|
|
09e22050e5 | ||
|
|
1ca097ce6d | ||
|
|
a57e66e31f | ||
|
|
a943f7893e | ||
|
|
93f8712adf | ||
|
|
f2b980d1df | ||
|
|
dec5f076be | ||
|
|
05244511c2 | ||
|
|
aa85f4ff43 |
No files matched your search
@@ -1,29 +1,55 @@
|
||||
# My personal dotfiles
|
||||
# Personal dotfiles
|
||||
|
||||
## Requirement
|
||||
|
||||
- **GNU** `stow`
|
||||
These are my config files for macOS and KDE, managed with GNU Stow. You need `stow` and `zsh` installed.
|
||||
|
||||
## Installation
|
||||
|
||||
1. clone this repo to your `$HOME` and switch to cloned dir:
|
||||
|
||||
```
|
||||
git -C $HOME clone https://github.com/vokhactri/.dotfiles.git && cd "$(basename "$_" .git)"
|
||||
```sh
|
||||
git clone https://git.trivk.dev/tri/.dotfiles.git "$HOME/.dotfiles"
|
||||
cd "$HOME/.dotfiles"
|
||||
```
|
||||
|
||||
2. use `stow` to symlink configs to `$HOME/.config`:
|
||||
The packages are split into three groups:
|
||||
|
||||
- to symlink all config dirs
|
||||
```
|
||||
stow */
|
||||
```
|
||||
- to symlink only one config dir, for example `zsh`
|
||||
```
|
||||
stow zsh
|
||||
- [common/](common/README.md) has Fastfetch, Git, Micro, mpv, npm, Starship and Zsh.
|
||||
- [mac/](mac/README.md) has Ghostty.
|
||||
- [kde/](kde/README.md) has the Darwin Breeze theme, Helium, Spectacle and tray icons.
|
||||
|
||||
Install all of `common`, then the group for your platform:
|
||||
|
||||
```sh
|
||||
(cd common && stow -t "$HOME" */)
|
||||
(cd mac && stow -t "$HOME" */) # macOS
|
||||
(cd kde && stow -t "$HOME" */) # KDE
|
||||
```
|
||||
|
||||
## Credit
|
||||
`*/` matches every package in the group. Each line runs in a subshell, so you stay in the repo root and can run them one after another. KDE needs a few more steps after this. They're in [`kde/README.md`](kde/README.md).
|
||||
|
||||
### Picking packages
|
||||
|
||||
You don't have to install everything. List only the packages you want:
|
||||
|
||||
```sh
|
||||
stow -d common -t "$HOME" git zsh starship
|
||||
stow -d mac -t "$HOME" ghostty
|
||||
stow -d kde -t "$HOME" spectacle
|
||||
```
|
||||
|
||||
`-d` tells Stow which group to read from. `-t` puts the symlinks in your home directory. You can mix packages from different groups.
|
||||
|
||||
### Previewing and removing
|
||||
|
||||
`-n -v` prints what Stow would do and changes nothing. `-D` removes the symlinks. Pass the same `-d` and `-t` you used to install:
|
||||
|
||||
```sh
|
||||
stow -n -v -d kde -t "$HOME" spectacle
|
||||
stow -D -d kde -t "$HOME" spectacle
|
||||
```
|
||||
|
||||
Once the Zsh config is linked, run `exec zsh` to reload the shell.
|
||||
|
||||
## Credits
|
||||
|
||||
- [Machfiles](https://github.com/ChristianChiarulli/Machfiles/)
|
||||
- [zsh_unplugged](https://github.com/mattmc3/zsh_unplugged)
|
||||
- [ayanrajpoot10/dotfiles](https://github.com/ayanrajpoot10/dotfiles)
|
||||
@@ -0,0 +1,18 @@
|
||||
# Common packages
|
||||
|
||||
Shared configuration for Fastfetch, Git, Micro, mpv, npm, Starship, and Zsh.
|
||||
From the repository root, install all shared packages:
|
||||
|
||||
```sh
|
||||
(cd common && stow -t "$HOME" */)
|
||||
```
|
||||
|
||||
Or choose individual packages:
|
||||
|
||||
```sh
|
||||
stow -d common -t "$HOME" git
|
||||
stow -d common -t "$HOME" zsh starship
|
||||
```
|
||||
|
||||
Choose any of `fastfetch`, `git`, `micro`, `mpv`, `npm`, `starship`, and `zsh`.
|
||||
Reload Zsh with `exec zsh` after installing its configuration.
|
||||
@@ -0,0 +1 @@
|
||||
_Ga=T,f=100,t=d,c=20,r=10,q=2,m=1;iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAACXBIWXMAAFxGAABcRgEUlENBAAAgAElEQVR4nOxdB3gU1fc1pPeQ0CFAIAkJCRASWkhCICGFDoKC0hWk6N/eFcvP3it2pIoCFnqTXqQICNJ77wiIAkqZ+//ue/Nm38zOhmR3NkXu+b737aZsm92dc9695957yy0EAsEyKIpyCwDIy0NRFE8AKIc/49+l/8HfVQaAFgDQFwCeA4CvAWAOAPwGAIcA4JyiKNeA4woAnFUU5RQAHACALQCwHAB+UBTlY0VRngSAXoqipOD9KoriYXxMRVHwMT3F38TCvxMIBAKBQCgCDITPSB9JViV/jWABIBAAmgHAfQAwHgDWA8B5KBwUKBrOAcCv+DiKotwLAM0BIMggQLTnaXwNBAKBQCAQCk/8bKdviALUAYABADAJAPY5Infc5SuKchUAcOGO/7q6FIn8FWmJv19Tb3NFuq2pWFAUZZ+iKN8pioLPJ8oQAWCRATkiQEKAQCAQCAQVhnA6LraLNuyskfTvB4CFAHDRZCcvEz0jdIQJ0RcG2m1kGMTBVZP7w+f1MwAMBYAaJkKGogIEAoFAIJjs9nU7ZgAIAICeADADAC4ZyFaQsNjRM7Y2ELjVMN6/EAVX1UiDjAtqhKKdwRtgJwTIK0AgEAiEmwKGnb0gfmboUxeG0l8GgP069lUUJFpth+9msi8sNPGhChARIZCxCQDQMxBWkBAgEAgEAuE/C+OOX3Xzi58bAcBoQ4hfEKqz4fzigmIWGVCfP/+lohwBgGcVRYkwCAEyCxIIBALhvwejCU5yyovfNcZwuRTCR+BuXzbslUbSdwTjc9aiAvgSseRQUZSnsYJAOgYkBAgEAoHw34HB3Gckuhi1dI8RowrZXFfWiN8InRFRFTRyeuAgAAw2SwtQxQCBQCAQyiyMeX7JDIe58LcA4F/Bkg6I/78E+TVdV0sMBVYDQLqjtACBQCAQCGW1c5+XdL0fAByVyE8jfkPZ3n8VRiEgRwQ+AYAQKVKiNT0iIUAgEAiEMlXWJxFYvFojz1lQUa7cZMQvw/h60e8gjgW2Ku5E0QACgUAglAkY69oVRWG7flUAPKEoigj3C3OfXDp3M5G/DNkfoBjSAp8BgJ9JBIWiAQQCgUAoHTDp2S9q+qMBYJlEanK4+2YlfTsYjILXpNLBHQDQVOqVQH0DCAQCgVAqd/6yeQ174/+tEpno2Mc4jsjfoQ6QTZAiGoDHbbiDY1zSbz+BQCAQbjYY6vrlMDVejirJXb/gUfkS1/Xr1+HatWvaunr1qrbk3+P/4TLeXt+mwH1PXzpO8rHDkcaeZikBAoFAIBBKyuznpYqBOuo4XpCm77nd5GdG1DLB43VngCJAvg8hCowCoxgrBXAUcXUSAQQCgUAoETjI9+PQGxyAgzA6/K1nSInsxe6+ILK/fPkyHDlyBLZu3Qq//PILzJkzB3744QeYNGkSTJ48GaZPnw5LliyB3377Dfbt2wfnz583vR8hLGQx4K7ogFlKQFGUEwDQTPQLMJZcEggEAoFQHGY/kQq4T+ItsVt1y65f3n0L0sdLGf/88w9s2LABxo4dCw888AC0bdsW4uPjoUKFCuDh4YEsWeAKCgqCqKgoSE1NhQEDBsBHH30Ey5cvh3PnzukeR358N0YF5ON4RTrGXYQngHoFEAgEAqG4cv6svl/9+U2JrK65g/yNYXexC5dx8OBBRvi9e/eGOnXqFEj05cp5gqenWF7q4j97eJRzeLuqVatCp06dYOTIkbBr1y7d44vogzEd4U5fgKIoQ036LdC3gEAgEAjWwNjcR9r5j3Nnvt9I/Mbd/unTp2HUqFGQn58PgYGBdoTt5cWJvTC7fkcLb4/3YxQGPj4+kJWVBZ9//jmcOnVKe07CSOgGISAfV3nC4FMiIkMigEAgEAiWwoz8AWCaSkBaFzt3Er9MoqtWrYJ77rkHKlasaEr4RhL38faD4MDyUDGiBtSsHgcxdRpD/dgW0CA+HRrWz4CG8RmQUK8l1ItuAlE1E6FqpSgIDakIfr6BDgSBt+53mFq47777YMuWLdpzlP0I7hABajMloYaECKASQQKBQCC4lfxnqSRkudnPGOqXd/wzZ86E3NzcG5J+gH8wVK0cBQn1UiG1SUfITu8FHdreDZ1zh0DnvCHQJX8odMkfBl0NC3/XJW8o+5+OOYMhN7MPpDfvCo0SWkFktVgICixvGh2Qf77jjjuYkVBAjlpYLAQQmghQFKWPPG0RrxMIBAKB4BTMDH8A8KNKPlek/vUus5pMjsJcJ4AO/ZYtW2pE63GLh90uPCQoHKJrJ0HLJh0hv01/RuRI9ILM22ffpa6BbLXDlWVY6t/E/3ZsO4iJBn5fw9jfURDE1k2B0OAI3eN7G54Pmgf37NmjvQb59VgpAtTOgQhstZxoFGsEAoFAIBQJDob6fKiSjbbzdzXsbxbuF8ByvezsbNsOm5n3vHShfQzpI+kjYeMuHgm7Q9tBGtHLhO784uIAowidcu9hj4PXWzbtBDWr1wMvLx8pImETAn5+fvDcc8+xqgQ3RQOMxsBfTHo00CefQCAQCIWHyTS6PirJXLMq5y+ToBzuP378ONx1110OiT8oMIyF93Mye2sheyRk3MXLxI2/E5fOLuN94RKPw6ID+UMhO+MOiK2TDD4+/raIgLdNCMTGxsLcuXO11y1EjgUiwK46QFGUe4w9AggEAoFAKBSkiX7CWV5FUZQ/TEr9nGcuadd/5YptCN5XX30F4eHhuhy/uI5GvkYJmYyAMSTfMWeQXdheJmyrl6PIAKYY8PnkZPZhBkMvT07+WH0gC4Fhw4axhkQIfM0WVQoYKwP2SFMESQAQCAQCwaXd/xcqUV2xkvzlXP+BAwegXbt2pjtof78g5tZH0kWiNdvtu5P4bywEeFQABQk+v6z0XlCjWoxkDvTSShHr1asHa9assYt6WCQCRCqgn2wIJBAIBAKhUDDk/eNNuvs5xVQyycm5/vHjx0NISIjmpC9XjtfcY+19TFQS5LXpZyN+dbdvDM+XxDJLN3AhMJilJlqktGdRCzNR8+GHwk7BhYDx+DgpANgdKYrys/reMfMmgUAgEAiFgmH3/75KLrIIcIr8BUTIH0XA4MGDTQkSa/YzU7urxD9I2/GXBuIvjFcAhUrnvKHset3aDU1TGv369dPI3wJfgCzMLgFAbblBEIFAIBAIBcJQ9hekKMpBlVSuu0r+cr4fB+6kpKSorXnLabt+bNObGNcSOuUMZo770k78NxIBeB1FTPPkdlpjIXytondBixYt4OTJkzph5KIIEFGAXrKQIxAIBAKhQBjqyHNUMhHO/yKzklmJ38KFCyEsLMxuR1whvBrLn3drf6+OUG01+tY6/ItNCKBpMW8oayxUqUKkXcQjMjISNm/ebIUIUKRIzbvy2GACgUAgEAojAEQJ2asqGV11hviNXf0QOLDHLBxerUpdyErvCW1b3ck69+Vm9oV2WQPUuvvhbBfNm/oM0nbXwv1vlo8vDUt+LsIbgK8nOirJTgTgBMKlS5eyY+RopHEhId6r6ep7yLwcBAKBQCAUOgKgKMpciVSKtB01K3F74403NOITIX+bGPDRBu5gGsDXxx+Cg7B/f3WoWSMOEuu1hJZNOkFOq96MRIUg4ESrLwUsTdEBsz4C2EgoKSHTTghhpQBGR4QIcDICINTDGul9pE89gUAgEApdAuinKMoWqd2sU+F/QWIjRoywtfJVS+LwUuTD+aXtuoeH+XQ+FAaYKqhXN4V1AMQoARcDQ/lO20QIlAYxYEwJoAhITemgdREUkQCcMOiKABCtgRVFwZyCD/UCIBAIBEKhgM1/VNKoCAAnnDUAymH/t99+W2f2K/qIXuz976VLGdgG/4RArRrxzGQnxABGCGxpgtIjBMxEQFqzLuBZztYnAGcesAN+/bpTRkBpNsBGRVG8SQAQCAQCoVCQKgBqAMCfglecICKNwNDkxnr3+9h65uPCjn9YCdClSxfo378/KwnEFsC33347mwEQFxenmQWNy2wKYGBACCu5y2jRjacJRFTApJKgfduSEQNGrwIOLsJG\_Gm=1;R+I1tGnTxpUIALupermOJgMSCAQCocgRAEVRUABcUMncKQEgIgA4GU8z+1WrBo888gjLdf/xh+gubA7cBZ8+fRpWr14No0ePhnvvvReSk5PB39/Wc1902jOKAUwTNG7QRosKsLbBpaSkUJs2mDOYVT14e/tqEYBOnTq5JACkCMByagdMIBAIBGciAJUA4KQrPQAEgV26dIl1vhs5ciScPXvWlOiR8LBMEC9vRH67du2CMWPGsEhBpUqVDJEBb53BMDAgFOJjmrESvNIkBPAxMUqRmdqDmR/Fc8YIiIsmQFEFME/u6UAgEAgEQmEFQAAAbBcc7UoVgBFI9GI0rkgVOFpGcWC8P4wQfPvtt3DrrbeyUjpblYEneEkTBNE8iBP7cGCPo7bCxSsAsFPgEDZSWK4EePrpp7Vj5GQKQEwFnCJXdBAIBAKBUJROgD+rZHK1qGkAYx8AmfTlv9/obo3lhEIUCEEg49ChQ/DOO+9Aw4YN7aIC4jqO7MWIAEsNqK16izsaICYJ4uMnJbbWPccvvvjCFQGgSAObvlD7AFAjIAKBQCAUeQ7A2yqZFLkRkBmRuzDtzu6+xKWZGMDfz5o1Czp27OhQCGBqIKVhtq65UHFGAjD6gJEIjErIfRHmzp1rNyypaIdGa9r0P2oFTCAQCARnBUBHlUxEHwBrGNwiGKMM8nhhARy927NnT10PAjk1gB0Ic1v3ZYa84hIBokSxS/5QqFa5jvZc/Pz8YNu2ba6UAcqNgIaRACAQCASCsymA8gBw3NVhQMUBo3fAGBVYv3498wnIZYTCeY8dB9EkKEcC3C0AhA8gJChce05YLnn58mXt9ThxDGQB0E54AOjjTyAQCARLine truncated
|
||||
|
After Width: | Height: | Size: 138 KiB |
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/master/doc/json_schema.json",
|
||||
"display": {
|
||||
"key": {
|
||||
"width": 10
|
||||
},
|
||||
"size": {
|
||||
"binaryPrefix": "jedec"
|
||||
},
|
||||
"separator": ""
|
||||
},
|
||||
"logo": {
|
||||
"type": "raw",
|
||||
"source": "~/.config/fastfetch/albedo.kitty",
|
||||
"width": 20,
|
||||
"height": 10
|
||||
},
|
||||
"modules": [
|
||||
"break",
|
||||
{
|
||||
"type": "os",
|
||||
"key": "os",
|
||||
"keyColor": "yellow",
|
||||
"format": "{name}"
|
||||
},
|
||||
{
|
||||
"type": "kernel",
|
||||
"key": "ker",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "packages",
|
||||
"key": "pkgs",
|
||||
"keyColor": "cyan"
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"key": "sh",
|
||||
"keyColor": "blue",
|
||||
"format": "{pretty-name}"
|
||||
},
|
||||
{
|
||||
"type": "wm",
|
||||
"key": "wm",
|
||||
"keyColor": "red",
|
||||
"format": "{pretty-name}"
|
||||
},
|
||||
{
|
||||
"type": "uptime",
|
||||
"key": "up",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"key": "cpu",
|
||||
"keyColor": "red",
|
||||
"format": "{name}"
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"key": "ram",
|
||||
"keyColor": "yellow",
|
||||
"format": "{used} / {total}"
|
||||
},
|
||||
{
|
||||
"type": "disk",
|
||||
"key": "disk",
|
||||
"keyColor": "cyan",
|
||||
"folders": [
|
||||
"/"
|
||||
],
|
||||
"format": "{size-used} / {size-total}"
|
||||
},
|
||||
"break",
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "\u001b[33m \u001b[32m \u001b[34m \u001b[31m \u001b[36m \u001b[35m \u001b[37m \u001b[97m"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
^/README.*
|
||||
^/build\.py
|
||||
__pycache__
|
||||
@@ -0,0 +1,17 @@
|
||||
# Fastfetch
|
||||
|
||||
```sh
|
||||
stow -d common -t "$HOME" fastfetch
|
||||
```
|
||||
|
||||
The logo is `albedo.png`, sent inline through the kitty graphics protocol from
|
||||
the pre-encoded `albedo.kitty`. This works in Ghostty and Kwi. The
|
||||
`kitty-direct` logo type is not used because Kwi ignores images passed as a
|
||||
file path.
|
||||
|
||||
After changing `albedo.png` or the logo size in `config.jsonc`, regenerate the
|
||||
logo from the repository root:
|
||||
|
||||
```sh
|
||||
python3 common/fastfetch/build.py
|
||||
```
|
||||
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Encode albedo.png as kitty graphics escapes for fastfetch's "raw" logo.
|
||||
|
||||
fastfetch's "kitty-direct" logo sends the terminal a file path (t=f), which
|
||||
Kwi ignores. This file carries the PNG inline (t=d) instead, so it works in
|
||||
any terminal with the kitty graphics protocol, Ghostty and Kwi included. q=2
|
||||
keeps the terminal from answering. Rerun after changing the image or the
|
||||
logo size.
|
||||
"""
|
||||
|
||||
import base64
|
||||
from pathlib import Path
|
||||
|
||||
DIR = Path(__file__).resolve().parent / ".config/fastfetch"
|
||||
# Logo size in cells; keep in sync with "width" and "height" in config.jsonc.
|
||||
COLS, ROWS = 20, 10
|
||||
|
||||
|
||||
def encode(png: bytes) -> bytes:
|
||||
data = base64.b64encode(png)
|
||||
chunks = [data[i : i + 4096] for i in range(0, len(data), 4096)]
|
||||
out = bytearray()
|
||||
for n, chunk in enumerate(chunks):
|
||||
more = int(n < len(chunks) - 1)
|
||||
if n == 0:
|
||||
keys = b"a=T,f=100,t=d,c=%d,r=%d,q=2,m=%d" % (COLS, ROWS, more)
|
||||
else:
|
||||
keys = b"m=%d" % more
|
||||
out += b"\x1b_G" + keys + b";" + chunk + b"\x1b\\"
|
||||
return bytes(out)
|
||||
|
||||
|
||||
(DIR / "albedo.kitty").write_bytes(encode((DIR / "albedo.png").read_bytes()))
|
||||
@@ -0,0 +1,22 @@
|
||||
[init]
|
||||
defaultBranch = main
|
||||
|
||||
[user]
|
||||
name = Tri Vo Khac
|
||||
email = git@trivk.dev
|
||||
|
||||
[core]
|
||||
compression = 9
|
||||
whitespace = error
|
||||
preloadindex = true
|
||||
|
||||
[advice]
|
||||
addEmptyPathspec = false
|
||||
pushNonFastForward = false
|
||||
statusHints = false
|
||||
|
||||
[push]
|
||||
autoSetupRemote = true
|
||||
|
||||
[url "git@github.com:"]
|
||||
insteadOf = "gh:"
|
||||
@@ -0,0 +1 @@
|
||||
**/.claude/settings.local.json
|
||||
@@ -0,0 +1,2 @@
|
||||
min-release-age=1 ; 1 day for npm
|
||||
minimum-release-age=1440 ; 1 day in minutes for pnpm
|
||||
@@ -10,9 +10,18 @@ symbol = " "
|
||||
[buf]
|
||||
symbol = " "
|
||||
|
||||
[bun]
|
||||
symbol = " "
|
||||
|
||||
[c]
|
||||
symbol = " "
|
||||
|
||||
[cpp]
|
||||
symbol = " "
|
||||
|
||||
[cmake]
|
||||
symbol = " "
|
||||
|
||||
[conda]
|
||||
symbol = " "
|
||||
|
||||
@@ -22,6 +31,9 @@ symbol = " "
|
||||
[dart]
|
||||
symbol = " "
|
||||
|
||||
[deno]
|
||||
symbol = " "
|
||||
|
||||
[directory]
|
||||
read_only = " "
|
||||
|
||||
@@ -37,15 +49,27 @@ symbol = " "
|
||||
[fennel]
|
||||
symbol = " "
|
||||
|
||||
[fortran]
|
||||
symbol = " "
|
||||
|
||||
[fossil_branch]
|
||||
symbol = " "
|
||||
|
||||
[gcloud]
|
||||
symbol = " "
|
||||
|
||||
[git_branch]
|
||||
symbol = " "
|
||||
|
||||
[git_commit]
|
||||
tag_symbol = ' '
|
||||
|
||||
[golang]
|
||||
symbol = " "
|
||||
|
||||
[gradle]
|
||||
symbol = " "
|
||||
|
||||
[guix_shell]
|
||||
symbol = " "
|
||||
|
||||
@@ -94,13 +118,17 @@ symbol = " "
|
||||
[os.symbols]
|
||||
Alpaquita = " "
|
||||
Alpine = " "
|
||||
AlmaLinux = " "
|
||||
Amazon = " "
|
||||
Android = " "
|
||||
AOSC = " "
|
||||
Arch = " "
|
||||
Artix = " "
|
||||
CachyOS = " "
|
||||
CentOS = " "
|
||||
Debian = " "
|
||||
DragonFly = " "
|
||||
Elementary = " "
|
||||
Emscripten = " "
|
||||
EndeavourOS = " "
|
||||
Fedora = " "
|
||||
@@ -109,6 +137,8 @@ Garuda = " "
|
||||
Gentoo = " "
|
||||
HardenedBSD = " "
|
||||
Illumos = " "
|
||||
Ios = " "
|
||||
Kali = " "
|
||||
Linux = " "
|
||||
Mabox = " "
|
||||
Macos = " "
|
||||
@@ -118,6 +148,7 @@ MidnightBSD = " "
|
||||
Mint = " "
|
||||
NetBSD = " "
|
||||
NixOS = " "
|
||||
Nobara = " "
|
||||
OpenBSD = " "
|
||||
openSUSE = " "
|
||||
OracleLinux = " "
|
||||
@@ -125,12 +156,15 @@ Pop = " "
|
||||
Raspbian = " "
|
||||
Redhat = " "
|
||||
RedHatEnterprise = " "
|
||||
RockyLinux = " "
|
||||
Redox = " "
|
||||
Solus = " "
|
||||
SUSE = " "
|
||||
Ubuntu = " "
|
||||
Unknown = " "
|
||||
Void = " "
|
||||
Windows = " "
|
||||
Zorin = " "
|
||||
|
||||
[package]
|
||||
symbol = " "
|
||||
@@ -144,6 +178,9 @@ symbol = " "
|
||||
[pijul_channel]
|
||||
symbol = " "
|
||||
|
||||
[pixi]
|
||||
symbol = " "
|
||||
|
||||
[python]
|
||||
symbol = " "
|
||||
|
||||
@@ -154,13 +191,19 @@ symbol = " "
|
||||
symbol = " "
|
||||
|
||||
[rust]
|
||||
symbol = " "
|
||||
symbol = " "
|
||||
|
||||
[scala]
|
||||
symbol = " "
|
||||
|
||||
[status]
|
||||
symbol = " "
|
||||
|
||||
[swift]
|
||||
symbol = " "
|
||||
|
||||
[xmake]
|
||||
symbol = " "
|
||||
|
||||
[zig]
|
||||
symbol = " "
|
||||
@@ -2,3 +2,4 @@
|
||||
.zsh_history
|
||||
.zcompcache/
|
||||
.zsh_sessions/
|
||||
config/secrets.zsh
|
||||
@@ -0,0 +1,75 @@
|
||||
# install zinit
|
||||
if ! source "$ZDOTDIR/zinit.zsh"; then
|
||||
print -u2 "zinit: failed to initialize; skipping plugin configuration"
|
||||
return 1
|
||||
fi
|
||||
|
||||
zinit light zdharma-continuum/zinit-annex-bin-gem-node
|
||||
zinit light zdharma-continuum/zinit-annex-binary-symlink
|
||||
|
||||
zinit wait lucid light-mode id-as depth'1' for \
|
||||
wintermi/zsh-brew \
|
||||
hlissner/zsh-autopair \
|
||||
Aloxaf/fzf-tab \
|
||||
atinit'zicompinit; zicdreplay -q' \
|
||||
zdharma-continuum/fast-syntax-highlighting \
|
||||
atload'_zsh_autosuggest_start' \
|
||||
zsh-users/zsh-autosuggestions
|
||||
|
||||
zinit id-as from'gh-r' lbin'!' completions for \
|
||||
lsd-rs/lsd \
|
||||
micro-editor/micro \
|
||||
mv'**/bat.zsh -> _bat' \
|
||||
@sharkdp/bat
|
||||
|
||||
zinit for \
|
||||
id-as \
|
||||
as'completion' \
|
||||
from'gh-r' \
|
||||
mv'**/_fastfetch -> _fastfetch' \
|
||||
atpull'%atclone' \
|
||||
lbin'!**bin/fastfetch -> fastfetch' \
|
||||
@fastfetch-cli/fastfetch
|
||||
|
||||
zinit for \
|
||||
id-as \
|
||||
from'gh-r' \
|
||||
atclone'./zoxide init zsh > init.zsh' \
|
||||
atpull'%atclone' \
|
||||
lbin'!' \
|
||||
@ajeetdsouza/zoxide
|
||||
|
||||
zinit for \
|
||||
id-as \
|
||||
from'gh-r' \
|
||||
atclone'
|
||||
VP_SELF_SETUP_NO_MODIFY_PATH=1 ./vp env setup --refresh > /dev/null; \
|
||||
./vp env on > /dev/null; \
|
||||
VP_COMPLETE=zsh "$XDG_DATA_HOME/vite-plus/bin/vp" > init.zsh;
|
||||
' \
|
||||
atpull'%atclone' \
|
||||
atload'source "$XDG_CONFIG_HOME/vite-plus/env"' \
|
||||
@voidzero-dev/vite-plus
|
||||
|
||||
zinit for \
|
||||
id-as \
|
||||
from'gh-r' \
|
||||
atclone'
|
||||
./starship init zsh > init.zsh; \
|
||||
./starship completions zsh > _starship;
|
||||
' \
|
||||
atpull'%atclone' \
|
||||
sbin'starship' \
|
||||
@starship/starship
|
||||
|
||||
zinit for \
|
||||
id-as \
|
||||
from'gh-r' \
|
||||
atclone'./fzf --zsh > init.zsh' \
|
||||
atpull'%atclone' \
|
||||
lbin'!fzf' \
|
||||
@junegunn/fzf
|
||||
|
||||
for script in $ZDOTDIR/config/*.zsh; do
|
||||
source "$script"
|
||||
done
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
# Modern alternatives to traditional commands
|
||||
alias cat='bat'
|
||||
alias ls='lsd -A'
|
||||
alias la='lsd -lA'
|
||||
alias tree='lsd --tree'
|
||||
alias nano='micro'
|
||||
alias fetch='fastfetch'
|
||||
|
||||
# Global alias
|
||||
alias \-g -- --help="--help | bat -plhelp"
|
||||
|
||||
docker() {
|
||||
if command -v podman >/dev/null 2>&1; then
|
||||
podman "$@"
|
||||
else
|
||||
command docker "$@"
|
||||
fi
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
local brew_prefix="${HOMEBREW_PREFIX:-}"
|
||||
# `brew --prefix` costs ~12 ms because it runs Ruby. Check the standard
|
||||
# Apple Silicon location first, then fall back for anything else.
|
||||
if [[ -z "$brew_prefix" ]]; then
|
||||
[[ -x /opt/homebrew/bin/brew ]] && brew_prefix=/opt/homebrew
|
||||
fi
|
||||
if [[ -z "$brew_prefix" ]] && command -v brew >/dev/null 2>&1; then
|
||||
brew_prefix="$(brew --prefix 2>/dev/null)"
|
||||
fi
|
||||
|
||||
if [[ -n "$brew_prefix" ]]; then
|
||||
gnu_tools=(
|
||||
"coreutils"
|
||||
"findutils"
|
||||
"gnu-tar"
|
||||
"gnu-sed"
|
||||
"gawk"
|
||||
"gnu-indent"
|
||||
"grep"
|
||||
)
|
||||
|
||||
if [[ -n "$XDG_BIN_HOME" ]] && mkdir -p "$XDG_BIN_HOME"; then
|
||||
for tool in $gnu_tools; do
|
||||
gnubin="$brew_prefix/opt/$tool/libexec/gnubin"
|
||||
if [[ -d "$gnubin" ]]; then
|
||||
for bin in "$gnubin"/*(N); do
|
||||
target="$XDG_BIN_HOME/${bin:t}"
|
||||
[[ "$target" -ef "$bin" ]] || ln -sf "$bin" "$target"
|
||||
done
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
local bin_paths=(
|
||||
"$XDG_BIN_HOME"
|
||||
"${brew_prefix:+$brew_prefix/opt/gnu-getopt/bin}"
|
||||
)
|
||||
for bin_path in "${bin_paths[@]}"; do
|
||||
if [[ -d "$bin_path" ]]; then
|
||||
case ":$PATH:" in
|
||||
*":$bin_path:"*) ;;
|
||||
*) path=("$bin_path" $path) ;;
|
||||
esac
|
||||
fi
|
||||
done
|
||||
@@ -1,13 +1,11 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
HISTSIZE=1000000
|
||||
SAVEHIST=1000000
|
||||
|
||||
export MANWIDTH=999
|
||||
|
||||
export EDITOR="micro"
|
||||
export PAGE="bat"
|
||||
export PAGER="bat"
|
||||
export VISUAL="micro"
|
||||
export SUDO_EDITOR="micro"
|
||||
|
||||
export STARSHIP_CONFIG="$XDG_CONFIG_HOME"/starship/starship.toml
|
||||
export HOMEBREW_NO_UPGRADE_AUTO_UPDATES_CASKS=1
|
||||
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
# NetBird is installed from the official signed .pkg, not Homebrew: the brew
|
||||
# cask removed the launchd plist in uninstall_preflight and then ran the app's
|
||||
# installer.sh against the missing service, leaving the daemon crash-looping.
|
||||
# The pkg's preinstall aborts if the brew formula is present, so keep it out.
|
||||
nbup() {
|
||||
local pkg tmp
|
||||
tmp="$(mktemp -d)" || return 1
|
||||
pkg="$tmp/netbird.pkg"
|
||||
|
||||
print "netbird: downloading arm64 pkg"
|
||||
curl -fL --progress-bar -o "$pkg" "https://pkgs.netbird.io/macos/arm64" || { rm -rf "${tmp:?}"; return 1; }
|
||||
|
||||
if ! pkgutil --check-signature "$pkg" | grep -q "NetBird GmbH"; then
|
||||
print -u2 "netbird: unexpected pkg signature, refusing to install"
|
||||
rm -rf "${tmp:?}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
sudo installer -pkg "$pkg" -target / || { rm -rf "${tmp:?}"; return 1; }
|
||||
rm -rf "${tmp:?}"
|
||||
|
||||
local i
|
||||
for i in {1..30}; do
|
||||
[[ -S /var/run/netbird.sock ]] && break
|
||||
sleep 1
|
||||
done
|
||||
/usr/local/bin/netbird status 2>/dev/null |
|
||||
grep -E '^(Daemon version|CLI version|Management|Signal|NetBird IP):'
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
unsetopt BEEP
|
||||
setopt AUTO_CD
|
||||
setopt GLOB_DOTS
|
||||
setopt NOMATCH
|
||||
setopt MENU_COMPLETE
|
||||
setopt EXTENDED_GLOB
|
||||
setopt INTERACTIVE_COMMENTS
|
||||
setopt APPEND_HISTORY
|
||||
setopt PUSHD_IGNORE_DUPS
|
||||
|
||||
setopt BANG_HIST # Treat the '!' character specially during expansion.
|
||||
setopt EXTENDED_HISTORY # Write the history file in the ":start:elapsed;command" format.
|
||||
setopt INC_APPEND_HISTORY # Write to the history file immediately, not when the shell exits.
|
||||
setopt SHARE_HISTORY # Share history between all sessions.
|
||||
setopt HIST_EXPIRE_DUPS_FIRST # Expire duplicate entries first when trimming history.
|
||||
setopt HIST_IGNORE_DUPS # Don't record an entry that was just recorded again.
|
||||
setopt HIST_IGNORE_ALL_DUPS # Delete old recorded entry if new entry is a duplicate.
|
||||
setopt HIST_FIND_NO_DUPS # Do not display a line previously found.
|
||||
setopt HIST_IGNORE_SPACE # Don't record an entry starting with a space.
|
||||
setopt HIST_SAVE_NO_DUPS # Don't write duplicate entries in the history file.
|
||||
setopt HIST_REDUCE_BLANKS # Remove superfluous blanks before recording entry.
|
||||
setopt HIST_VERIFY # Don't execute immediately upon history expansion.
|
||||
|
||||
HISTFILE="${ZDOTDIR:-$HOME}/.zsh_history"
|
||||
HISTSIZE=5000000
|
||||
SAVEHIST=5000000
|
||||
|
||||
zstyle ':fzf-tab:complete:cd:*' fzf-preview 'lsd -1 --color=always --icon=always $realpath'
|
||||
|
||||
# Starship counts every entry in jobstates, including completed jobs that zsh
|
||||
# hasn't reaped yet. Run jobs before Starship's precmd hook so parallel Zinit
|
||||
# updates don't leave a stale job badge in the prompt.
|
||||
autoload -Uz add-zsh-hook
|
||||
|
||||
_zinit_reap_done_jobs() {
|
||||
jobs -p >/dev/null 2>&1
|
||||
}
|
||||
|
||||
add-zsh-hook -d precmd _zinit_reap_done_jobs 2>/dev/null || true
|
||||
precmd_functions=( _zinit_reap_done_jobs ${precmd_functions:#_zinit_reap_done_jobs} )
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
ZINIT_HOME="${XDG_DATA_HOME:-${HOME}/.local/share}/zinit/zinit.git"
|
||||
if [[ ! -d "$ZINIT_HOME/.git" ]]; then
|
||||
mkdir -p "$(dirname "$ZINIT_HOME")" || return 1
|
||||
git clone --depth 1 https://github.com/zdharma-continuum/zinit.git "$ZINIT_HOME" || return 1
|
||||
fi
|
||||
|
||||
if [[ ! -r "$ZINIT_HOME/zinit.zsh" ]]; then
|
||||
print -u2 "zinit: bootstrap is incomplete at $ZINIT_HOME"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# not to use aliases: zi or zini
|
||||
typeset -A ZINIT
|
||||
ZINIT[NO_ALIASES]=1
|
||||
ZINIT[LIST_COMMAND]='lsd --tree'
|
||||
|
||||
source "${ZINIT_HOME}/zinit.zsh"
|
||||
@@ -0,0 +1,10 @@
|
||||
export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
|
||||
export XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
|
||||
export XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}"
|
||||
export XDG_STATE_HOME="${XDG_STATE_HOME:-$HOME/.local/state}"
|
||||
|
||||
XDG_BIN_HOME="${XDG_BIN_HOME:-$HOME/.local/bin}"
|
||||
ZDOTDIR="$XDG_CONFIG_HOME/zsh"
|
||||
|
||||
# Per-machine settings that stay out of the repo, like PATH entries for a VPS.
|
||||
[ -r "$XDG_CONFIG_HOME/zshenv.local" ] && . "$XDG_CONFIG_HOME/zshenv.local"
|
||||
@@ -1,42 +0,0 @@
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
"type": "builtin",
|
||||
"source": "arch"
|
||||
},
|
||||
"modules": [
|
||||
"title",
|
||||
"separator",
|
||||
{
|
||||
"type": "os",
|
||||
"format": "Arch Linux ({12})"
|
||||
},
|
||||
"host",
|
||||
"kernel",
|
||||
"uptime",
|
||||
{
|
||||
"type": "packages",
|
||||
"format": "{} (pacman)"
|
||||
},
|
||||
"shell",
|
||||
"display",
|
||||
"de",
|
||||
"wm",
|
||||
"wmtheme",
|
||||
"theme",
|
||||
"icons",
|
||||
"font",
|
||||
"cursor",
|
||||
"terminal",
|
||||
"terminalfont",
|
||||
"cpu",
|
||||
"gpu",
|
||||
"memory",
|
||||
"disk",
|
||||
"battery",
|
||||
"poweradapter",
|
||||
"locale",
|
||||
"break",
|
||||
"colors"
|
||||
]
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
<?xml version='1.0'?>
|
||||
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
|
||||
<fontconfig>
|
||||
<alias>
|
||||
<family>sans-serif</family>
|
||||
<prefer>
|
||||
<family>Arial</family>
|
||||
<family>JoyPixels</family>
|
||||
# <family>Noto Color Emoji</family>
|
||||
# <family>Noto Emoji</family>
|
||||
</prefer>
|
||||
</alias>
|
||||
<alias>
|
||||
<family>serif</family>
|
||||
<prefer>
|
||||
<family>Times New Roman</family>
|
||||
<family>JoyPixels</family>
|
||||
# <family>Noto Color Emoji</family>
|
||||
# <family>Noto Emoji</family>
|
||||
</prefer>
|
||||
</alias>
|
||||
<alias>
|
||||
<family>monospace</family>
|
||||
<prefer>
|
||||
<family>Consolas</family>
|
||||
<family>JoyPixels</family>
|
||||
# <family>Noto Color Emoji</family>
|
||||
# <family>Noto Emoji</family>
|
||||
</prefer>
|
||||
</alias>
|
||||
<match target="font">
|
||||
<edit name="hinting" mode="assign">
|
||||
<bool>true</bool>
|
||||
</edit>
|
||||
</match>
|
||||
<match target="font">
|
||||
<edit name="hintstyle" mode="assign">
|
||||
<const>hintslight</const>
|
||||
</edit>
|
||||
</match>
|
||||
<dir>~/.fonts</dir>
|
||||
<selectfont>
|
||||
<rejectfont>
|
||||
<patelt name="family">
|
||||
<string>Segoe UI Emoji</string>
|
||||
</patelt>
|
||||
</rejectfont>
|
||||
</selectfont>
|
||||
</fontconfig>
|
||||
@@ -1,69 +0,0 @@
|
||||
acknowledge_abuse=false
|
||||
apps_script_format=desktop
|
||||
apps_script_icon=
|
||||
async_upload_queue=false
|
||||
async_upload_queue_max_length=0
|
||||
async_upload_threads=10
|
||||
autodetect_mime=true
|
||||
background_folder_fetching=false
|
||||
cache_directory=
|
||||
client_id=
|
||||
client_secret=
|
||||
connect_timeout_ms=5000
|
||||
curl_debug_off=false
|
||||
data_directory=
|
||||
debug_buffers=false
|
||||
delete_forever_in_trash_folder=false
|
||||
desktop_entry_as_html=false
|
||||
desktop_entry_exec=
|
||||
disable_trash=false
|
||||
docs_file_extension=true
|
||||
document_format=desktop
|
||||
document_icon=
|
||||
download_docs=true
|
||||
drawing_format=desktop
|
||||
drawing_icon=
|
||||
form_format=desktop
|
||||
form_icon=
|
||||
fusion_table_format=desktop
|
||||
fusion_table_icon=
|
||||
keep_duplicates=false
|
||||
large_file_read_only=true
|
||||
large_file_threshold_mb=16
|
||||
log_directory=
|
||||
log_to=
|
||||
lost_and_found=false
|
||||
low_speed_limit=0
|
||||
low_speed_time=0
|
||||
map_format=desktop
|
||||
map_icon=
|
||||
max_cache_size_mb=512000
|
||||
max_download_speed=0
|
||||
max_memory_cache_size=10737418240
|
||||
max_retries=8
|
||||
max_upload_chunk_size=1099511627776
|
||||
max_upload_speed=0
|
||||
memory_buffer_size=8388608
|
||||
metadata_cache_time=60
|
||||
metadata_memory_cache=true
|
||||
metadata_memory_cache_saving_interval=30
|
||||
mv_keep_target=false
|
||||
oauth2_loopback=false
|
||||
oauth2_loopback_port=8080
|
||||
presentation_format=desktop
|
||||
presentation_icon=
|
||||
read_ahead_buffers=5
|
||||
read_only=false
|
||||
redirect_uri=
|
||||
root_folder=
|
||||
scope=
|
||||
service_account_credentials_path=
|
||||
service_account_user_to_impersonate=
|
||||
spreadsheet_format=desktop
|
||||
spreadsheet_icon=
|
||||
sqlite3_busy_timeout=5000
|
||||
stream_large_files=true
|
||||
team_drive_id=
|
||||
umask=0o022
|
||||
verification_code=
|
||||
write_buffers=false
|
||||
@@ -1,69 +0,0 @@
|
||||
acknowledge_abuse=false
|
||||
apps_script_format=desktop
|
||||
apps_script_icon=
|
||||
async_upload_queue=false
|
||||
async_upload_queue_max_length=0
|
||||
async_upload_threads=10
|
||||
autodetect_mime=true
|
||||
background_folder_fetching=true
|
||||
cache_directory=
|
||||
client_id=
|
||||
client_secret=
|
||||
connect_timeout_ms=5000
|
||||
curl_debug_off=false
|
||||
data_directory=
|
||||
debug_buffers=false
|
||||
delete_forever_in_trash_folder=false
|
||||
desktop_entry_as_html=false
|
||||
desktop_entry_exec=
|
||||
disable_trash=false
|
||||
docs_file_extension=true
|
||||
document_format=desktop
|
||||
document_icon=
|
||||
download_docs=true
|
||||
drawing_format=desktop
|
||||
drawing_icon=
|
||||
form_format=desktop
|
||||
form_icon=
|
||||
fusion_table_format=desktop
|
||||
fusion_table_icon=
|
||||
keep_duplicates=false
|
||||
large_file_read_only=true
|
||||
large_file_threshold_mb=16
|
||||
log_directory=
|
||||
log_to=
|
||||
lost_and_found=false
|
||||
low_speed_limit=0
|
||||
low_speed_time=0
|
||||
map_format=desktop
|
||||
map_icon=
|
||||
max_cache_size_mb=512000
|
||||
max_download_speed=0
|
||||
max_memory_cache_size=5368709120
|
||||
max_retries=8
|
||||
max_upload_chunk_size=1099511627776
|
||||
max_upload_speed=0
|
||||
memory_buffer_size=8388608
|
||||
metadata_cache_time=60
|
||||
metadata_memory_cache=true
|
||||
metadata_memory_cache_saving_interval=30
|
||||
mv_keep_target=false
|
||||
oauth2_loopback=false
|
||||
oauth2_loopback_port=8080
|
||||
presentation_format=desktop
|
||||
presentation_icon=
|
||||
read_ahead_buffers=5
|
||||
read_only=false
|
||||
redirect_uri=
|
||||
root_folder=
|
||||
scope=
|
||||
service_account_credentials_path=
|
||||
service_account_user_to_impersonate=
|
||||
spreadsheet_format=desktop
|
||||
spreadsheet_icon=
|
||||
sqlite3_busy_timeout=5000
|
||||
stream_large_files=true
|
||||
team_drive_id=0AH4Ykx7cpiF6Uk9PVA
|
||||
umask=0o022
|
||||
verification_code=
|
||||
write_buffers=false
|
||||
@@ -1,69 +0,0 @@
|
||||
acknowledge_abuse=false
|
||||
apps_script_format=desktop
|
||||
apps_script_icon=
|
||||
async_upload_queue=false
|
||||
async_upload_queue_max_length=0
|
||||
async_upload_threads=10
|
||||
autodetect_mime=true
|
||||
background_folder_fetching=true
|
||||
cache_directory=
|
||||
client_id=
|
||||
client_secret=
|
||||
connect_timeout_ms=5000
|
||||
curl_debug_off=false
|
||||
data_directory=
|
||||
debug_buffers=false
|
||||
delete_forever_in_trash_folder=false
|
||||
desktop_entry_as_html=false
|
||||
desktop_entry_exec=
|
||||
disable_trash=false
|
||||
docs_file_extension=true
|
||||
document_format=desktop
|
||||
document_icon=
|
||||
download_docs=true
|
||||
drawing_format=desktop
|
||||
drawing_icon=
|
||||
form_format=desktop
|
||||
form_icon=
|
||||
fusion_table_format=desktop
|
||||
fusion_table_icon=
|
||||
keep_duplicates=false
|
||||
large_file_read_only=true
|
||||
large_file_threshold_mb=16
|
||||
log_directory=
|
||||
log_to=
|
||||
lost_and_found=false
|
||||
low_speed_limit=0
|
||||
low_speed_time=0
|
||||
map_format=desktop
|
||||
map_icon=
|
||||
max_cache_size_mb=512000
|
||||
max_download_speed=0
|
||||
max_memory_cache_size=10737418240
|
||||
max_retries=8
|
||||
max_upload_chunk_size=1099511627776
|
||||
max_upload_speed=0
|
||||
memory_buffer_size=8388608
|
||||
metadata_cache_time=60
|
||||
metadata_memory_cache=true
|
||||
metadata_memory_cache_saving_interval=30
|
||||
mv_keep_target=false
|
||||
oauth2_loopback=false
|
||||
oauth2_loopback_port=8080
|
||||
presentation_format=desktop
|
||||
presentation_icon=
|
||||
read_ahead_buffers=5
|
||||
read_only=false
|
||||
redirect_uri=
|
||||
root_folder=
|
||||
scope=
|
||||
service_account_credentials_path=
|
||||
service_account_user_to_impersonate=
|
||||
spreadsheet_format=desktop
|
||||
spreadsheet_icon=
|
||||
sqlite3_busy_timeout=5000
|
||||
stream_large_files=true
|
||||
team_drive_id=0AIwrATJm5KEtUk9PVA
|
||||
umask=0o022
|
||||
verification_code=
|
||||
write_buffers=false
|
||||
@@ -1,5 +0,0 @@
|
||||
[init]
|
||||
defaultBranch = main
|
||||
[user]
|
||||
name = Tri Vo Khac
|
||||
email = 33442340+vokhactri@users.noreply.github.com
|
||||
@@ -0,0 +1,35 @@
|
||||
# KDE Plasma packages
|
||||
|
||||
From the repository root, install all KDE packages:
|
||||
|
||||
```sh
|
||||
(cd kde && stow -t "$HOME" */)
|
||||
```
|
||||
|
||||
Or choose individual packages:
|
||||
|
||||
```sh
|
||||
stow -d kde -t "$HOME" spectacle helium
|
||||
```
|
||||
|
||||
| Package | Details |
|
||||
| ---------------------------------- | -------------------------------------------------------- |
|
||||
| [theme](theme/README.md) | Darwin Breeze KDE colors and generated app themes |
|
||||
| [helium](helium/README.md) | Browser flags; colors come from GTK |
|
||||
| [spectacle](spectacle/README.md) | Screenshots to clipboard with a notification, no preview |
|
||||
| [tray-icons](tray-icons/README.md) | Ngó Sen, NetBird and qBittorrent tray icons |
|
||||
|
||||
Theme and Spectacle need an additional apply step after stowing their package:
|
||||
|
||||
```sh
|
||||
# If you selected theme:
|
||||
./kde/theme/apply.sh
|
||||
# If you selected spectacle:
|
||||
./kde/spectacle/apply.py
|
||||
```
|
||||
|
||||
The apply scripts require a running KDE Plasma 6 session. Ngó Sen and NetBird
|
||||
icons need an additional install step described in the tray-icons README.
|
||||
|
||||
Packages can be selected independently; Helium follows the Darwin Breeze
|
||||
colors only when the theme is applied.
|
||||
@@ -0,0 +1,8 @@
|
||||
# Hardware video acceleration (VA-API, AMD radeonsi) on Wayland
|
||||
--ozone-platform-hint=auto
|
||||
--enable-features=AcceleratedVideoDecodeLinuxGL,AcceleratedVideoDecodeLinuxZeroCopyGL,AcceleratedVideoEncoder
|
||||
|
||||
# Don't tag surfaces as sRGB. KWin shows tagged sRGB through a gamma 2.2
|
||||
# curve, which lifts dark grays (40 -> 44), so the tab strip would come out
|
||||
# lighter than KDE title bars.
|
||||
--disable-features=WaylandWpColorManagerV1
|
||||
@@ -0,0 +1,14 @@
|
||||
# Helium
|
||||
|
||||
Browser flags for hardware video decoding on Wayland and for colors that
|
||||
match KDE apps. From the repository root:
|
||||
|
||||
```sh
|
||||
stow -d kde -t "$HOME" helium
|
||||
```
|
||||
|
||||
Helium takes its colors and window buttons from GTK. In Settings →
|
||||
Appearance, set Theme to GTK and turn off "Use system title bar and borders".
|
||||
With the KDE `theme` package applied, GTK follows the Darwin Breeze colors and
|
||||
the window buttons match KWin's; see
|
||||
[Darwin Breeze → Helium notes](../theme/README.md#helium-notes).
|
||||
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env xdg-open
|
||||
[Desktop Entry]
|
||||
GenericName=Screenshot Capture Utility
|
||||
Name=Spectacle
|
||||
Comment=Take screenshots and screen recordings
|
||||
Categories=Qt;KDE;Utility;
|
||||
Keywords=snapshot;capture;print;screenshot;snipping;snipping tool;snip;
|
||||
Exec=/usr/bin/spectacle --background --region --copy-image
|
||||
Icon=spectacle
|
||||
Type=Application
|
||||
StartupNotify=false
|
||||
Actions=FullScreenScreenShot;CurrentMonitorScreenShot;ActiveWindowScreenShot;RectangularRegionScreenShot;WindowUnderCursorScreenShot;RecordRegion;RecordScreen;RecordWindow;OpenWithoutScreenshot;
|
||||
DBusActivatable=false
|
||||
X-DBUS-StartupType=Unique
|
||||
X-DBUS-ServiceName=org.kde.Spectacle
|
||||
X-KDE-Shortcuts=Print,Meta+Shift+S
|
||||
X-KDE-DBUS-Restricted-Interfaces=org.kde.KWin.ScreenShot2
|
||||
X-KDE-Wayland-Interfaces=org_kde_plasma_window_management,zkde_screencast_unstable_v1
|
||||
|
||||
[Desktop Action FullScreenScreenShot]
|
||||
Name=Capture Entire Desktop
|
||||
Exec=/usr/bin/spectacle --background --copy-image -f
|
||||
X-KDE-Shortcuts=Shift+Print
|
||||
|
||||
[Desktop Action CurrentMonitorScreenShot]
|
||||
Name=Capture Current Monitor
|
||||
Exec=/usr/bin/spectacle --background --copy-image -m
|
||||
|
||||
|
||||
[Desktop Action ActiveWindowScreenShot]
|
||||
Name=Capture Active Window
|
||||
Exec=/usr/bin/spectacle --background --copy-image -a
|
||||
X-KDE-Shortcuts=Meta+Print
|
||||
|
||||
[Desktop Action RectangularRegionScreenShot]
|
||||
Name=Capture Rectangular Region
|
||||
Exec=/usr/bin/spectacle --background --copy-image -r
|
||||
X-KDE-Shortcuts=Meta+Shift+Print
|
||||
|
||||
[Desktop Action WindowUnderCursorScreenShot]
|
||||
Name=Capture Window Under Cursor
|
||||
Exec=/usr/bin/spectacle --background --copy-image -u
|
||||
X-KDE-Shortcuts=Meta+Ctrl+Print
|
||||
|
||||
[Desktop Action RecordRegion]
|
||||
Name=Start/Stop Region Recording
|
||||
Exec=/usr/bin/spectacle -R region
|
||||
X-KDE-Shortcuts=Meta+Shift+R,Meta+R
|
||||
|
||||
[Desktop Action RecordScreen]
|
||||
Name=Start/Stop Screen Recording
|
||||
Exec=/usr/bin/spectacle -R screen
|
||||
X-KDE-Shortcuts=Meta+Alt+R
|
||||
|
||||
[Desktop Action RecordWindow]
|
||||
Name=Start/Stop Window Recording
|
||||
Exec=/usr/bin/spectacle -R window
|
||||
X-KDE-Shortcuts=Meta+Ctrl+R
|
||||
|
||||
[Desktop Action OpenWithoutScreenshot]
|
||||
Name=Launch without taking a screenshot
|
||||
Exec=/usr/bin/spectacle -l
|
||||
@@ -0,0 +1 @@
|
||||
../applications/org.kde.spectacle.desktop
|
||||
@@ -0,0 +1,4 @@
|
||||
^/README.*
|
||||
^/apply\.py
|
||||
^/settings
|
||||
__pycache__
|
||||
@@ -0,0 +1,28 @@
|
||||
# Spectacle
|
||||
|
||||
Capture screenshots in the background, copy the image to the clipboard, and
|
||||
show a completion notification. Screenshots are not automatically saved.
|
||||
|
||||
```sh
|
||||
stow -d kde -t "$HOME" spectacle
|
||||
./kde/spectacle/apply.py
|
||||
```
|
||||
|
||||
Requires Spectacle, KDE Plasma 6, GNU Stow, Python 3, `kwriteconfig6`,
|
||||
`kbuildsycoca6`, `qdbus6`, and `gdbus`. Run the apply script in your KDE session.
|
||||
Move any existing files reported as conflicts by Stow out of the way first.
|
||||
|
||||
- **Print** / **Meta+Shift+S**: select a rectangular region.
|
||||
- **Shift+Print**: entire desktop.
|
||||
- **Meta+Print**: active window.
|
||||
- **Meta+Shift+Print**: select a rectangular region.
|
||||
- **Meta+Ctrl+Print**: window under the cursor.
|
||||
|
||||
The desktop launcher and shortcut entry are managed by Stow. The files in
|
||||
`settings/` are merged into `~/.config/spectaclerc` and `~/.config/klipperrc`
|
||||
by `apply.py`, preserving unrelated preferences and window state. Klipper's
|
||||
`SaveImages=true` keeps captured images available after Spectacle exits.
|
||||
|
||||
After editing settings or launcher commands, run `apply.py` again. It rebuilds
|
||||
the cache using the KDE session's environment and reloads only Spectacle's
|
||||
shortcut component, preserving custom key bindings.
|
||||
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Apply screenshot preferences and reload Spectacle's KDE shortcuts."""
|
||||
|
||||
import ast
|
||||
import configparser
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import subprocess
|
||||
from typing import Any
|
||||
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
COMPONENT = "org.kde.spectacle.desktop"
|
||||
ACCEL = "/component/org_kde_spectacle_desktop"
|
||||
|
||||
|
||||
def run(*args: str, **kwargs: Any) -> subprocess.CompletedProcess[str]:
|
||||
return subprocess.run(args, check=True, text=True, **kwargs)
|
||||
|
||||
|
||||
def accel(path: str, method: str, *args: str) -> str:
|
||||
return run(
|
||||
"gdbus", "call", "--session", "--dest", "org.kde.kglobalaccel",
|
||||
"--object-path", path, "--method", method, *args,
|
||||
capture_output=True,
|
||||
).stdout
|
||||
|
||||
|
||||
def main() -> None:
|
||||
for name in ("spectaclerc", "klipperrc"):
|
||||
config = configparser.ConfigParser(interpolation=None)
|
||||
config.optionxform = str # type: ignore[method-assign,assignment]
|
||||
config.read(HERE / "settings" / name)
|
||||
for group in config.sections():
|
||||
for key, value in config[group].items():
|
||||
run("kwriteconfig6", "--file", name, "--group", group,
|
||||
"--key", key, value)
|
||||
|
||||
# T3's locale and XDG_DATA_DIRS can differ from the running KDE session.
|
||||
# Build the cache KDE actually reads, rather than an app-specific cache.
|
||||
session: dict[str, str] = dict(
|
||||
line.split("=", 1) for line in
|
||||
run("systemctl", "--user", "show-environment", capture_output=True)
|
||||
.stdout.splitlines() if "=" in line
|
||||
)
|
||||
env = os.environ.copy()
|
||||
for key in ("LANG", "LANGUAGE", "XDG_DATA_DIRS", "XDG_DATA_HOME",
|
||||
"XDG_CACHE_HOME", "XDG_CONFIG_HOME"):
|
||||
env.pop(key, None)
|
||||
if key in session:
|
||||
env[key] = session[key]
|
||||
for key in set(env) | set(session):
|
||||
if key.startswith("LC_"):
|
||||
env.pop(key, None)
|
||||
if key in session:
|
||||
env[key] = session[key]
|
||||
run("kbuildsycoca6", "--noincremental", env=env)
|
||||
|
||||
# Existing shortcut components retain their old Exec commands. Recreate
|
||||
# only Spectacle's component, preserving any customized key bindings.
|
||||
try:
|
||||
output = accel(ACCEL, "org.kde.kglobalaccel.Component.allShortcutInfos")
|
||||
except subprocess.CalledProcessError:
|
||||
shortcuts: list[Any] = [] # Component has not been registered yet.
|
||||
else:
|
||||
shortcuts = ast.literal_eval(re.sub(r"@a[is] ", "", output))[0]
|
||||
accel(ACCEL, "org.kde.kglobalaccel.Component.cleanUp")
|
||||
|
||||
action = [COMPONENT, "_reload_config", "Spectacle", "Reload configuration"]
|
||||
accel("/kglobalaccel", "org.kde.KGlobalAccel.doRegister", repr(action))
|
||||
accel("/kglobalaccel", "org.kde.KGlobalAccel.unregister",
|
||||
COMPONENT, "_reload_config")
|
||||
for name, label, component, friendly, context, _, keys, defaults in shortcuts:
|
||||
if keys != defaults:
|
||||
identity = component if context == "default" else f"{component}|{context}"
|
||||
accel("/kglobalaccel", "org.kde.KGlobalAccel.setForeignShortcut",
|
||||
repr([identity, name, friendly, label]), repr(keys))
|
||||
|
||||
run("qdbus6", "org.kde.klipper", "/klipper",
|
||||
"org.kde.klipper.klipper.reloadConfig")
|
||||
print("Applied Spectacle: copy to clipboard with a notification, no preview.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,2 @@
|
||||
[General]
|
||||
SaveImages=true
|
||||
@@ -0,0 +1,3 @@
|
||||
[General]
|
||||
autoSaveImage=false
|
||||
clipboardGroup=PostScreenshotCopyImage
|
||||
@@ -0,0 +1,12 @@
|
||||
/* Helium (Chromium) with its GTK theme. Chromium adds a "chromium" class to
|
||||
every node of the GTK style contexts it reads colors from, so these rules
|
||||
reach Helium and no other GTK app.
|
||||
|
||||
In the compact layout, the address bar takes the text field color and the
|
||||
segment with the extension and window buttons takes the window color,
|
||||
which Chromium resolves to the darker view color. Both get the title bar
|
||||
color, so the strip reads as one bar like a KDE title bar. */
|
||||
window.background.chromium,
|
||||
textview.view.chromium {
|
||||
background-color: @theme_bg_color_breeze;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
__pycache__/
|
||||
# Binary packages built by build.py.
|
||||
*.vsix
|
||||
*.tdesktop-theme
|
||||
@@ -0,0 +1,165 @@
|
||||
# macOS-inspired colors for Breeze (dark variant).
|
||||
# Header and Window share one color so the title bar merges into the toolbar.
|
||||
|
||||
[ColorEffects:Disabled]
|
||||
Color=56,56,56
|
||||
ColorAmount=0
|
||||
ColorEffect=0
|
||||
ContrastAmount=0.65
|
||||
ContrastEffect=1
|
||||
IntensityAmount=0.1
|
||||
IntensityEffect=2
|
||||
|
||||
[ColorEffects:Inactive]
|
||||
ChangeSelectionColor=true
|
||||
Color=112,111,110
|
||||
ColorAmount=0.025
|
||||
ColorEffect=2
|
||||
ContrastAmount=0.1
|
||||
ContrastEffect=2
|
||||
Enable=false
|
||||
IntensityAmount=0
|
||||
IntensityEffect=0
|
||||
|
||||
[Colors:Button]
|
||||
BackgroundAlternate=109,109,109
|
||||
BackgroundNormal=93,93,93
|
||||
DecorationFocus=0,122,255
|
||||
DecorationHover=0,122,255
|
||||
ForegroundActive=65,156,255
|
||||
ForegroundInactive=154,154,154
|
||||
ForegroundLink=65,156,255
|
||||
ForegroundNegative=255,74,76
|
||||
ForegroundNeutral=255,146,48
|
||||
ForegroundNormal=230,230,230
|
||||
ForegroundPositive=48,209,88
|
||||
ForegroundVisited=191,90,242
|
||||
|
||||
[Colors:Complementary]
|
||||
BackgroundAlternate=40,40,40
|
||||
BackgroundNormal=30,30,30
|
||||
DecorationFocus=0,122,255
|
||||
DecorationHover=0,122,255
|
||||
ForegroundActive=65,156,255
|
||||
ForegroundInactive=154,154,154
|
||||
ForegroundLink=65,156,255
|
||||
ForegroundNegative=255,74,76
|
||||
ForegroundNeutral=255,146,48
|
||||
ForegroundNormal=221,221,221
|
||||
ForegroundPositive=48,209,88
|
||||
ForegroundVisited=191,90,242
|
||||
|
||||
[Colors:Header]
|
||||
BackgroundAlternate=40,40,40
|
||||
BackgroundNormal=40,40,40
|
||||
DecorationFocus=0,122,255
|
||||
DecorationHover=0,122,255
|
||||
ForegroundActive=65,156,255
|
||||
ForegroundInactive=154,154,154
|
||||
ForegroundLink=65,156,255
|
||||
ForegroundNegative=255,74,76
|
||||
ForegroundNeutral=255,146,48
|
||||
ForegroundNormal=222,222,222
|
||||
ForegroundPositive=48,209,88
|
||||
ForegroundVisited=191,90,242
|
||||
|
||||
[Colors:Header][Inactive]
|
||||
BackgroundAlternate=36,36,36
|
||||
BackgroundNormal=36,36,36
|
||||
DecorationFocus=0,122,255
|
||||
DecorationHover=0,122,255
|
||||
ForegroundActive=65,156,255
|
||||
ForegroundInactive=128,128,128
|
||||
ForegroundLink=65,156,255
|
||||
ForegroundNegative=255,74,76
|
||||
ForegroundNeutral=255,146,48
|
||||
ForegroundNormal=154,154,154
|
||||
ForegroundPositive=48,209,88
|
||||
ForegroundVisited=191,90,242
|
||||
|
||||
[Colors:Selection]
|
||||
BackgroundAlternate=25,135,255
|
||||
BackgroundNormal=0,122,255
|
||||
DecorationFocus=0,122,255
|
||||
DecorationHover=0,122,255
|
||||
ForegroundActive=255,255,255
|
||||
ForegroundInactive=222,222,222
|
||||
ForegroundLink=255,255,255
|
||||
ForegroundNegative=255,200,200
|
||||
ForegroundNeutral=255,220,180
|
||||
ForegroundNormal=255,255,255
|
||||
ForegroundPositive=200,255,210
|
||||
ForegroundVisited=230,210,255
|
||||
|
||||
# macOS turns the selection gray when the window loses focus.
|
||||
[Colors:Selection][Inactive]
|
||||
BackgroundAlternate=70,70,70
|
||||
BackgroundNormal=70,70,70
|
||||
DecorationFocus=0,122,255
|
||||
DecorationHover=0,122,255
|
||||
ForegroundActive=255,255,255
|
||||
ForegroundInactive=222,222,222
|
||||
ForegroundLink=255,255,255
|
||||
ForegroundNegative=255,74,76
|
||||
ForegroundNeutral=255,146,48
|
||||
ForegroundNormal=255,255,255
|
||||
ForegroundPositive=48,209,88
|
||||
ForegroundVisited=191,90,242
|
||||
|
||||
[Colors:Tooltip]
|
||||
BackgroundAlternate=46,46,46
|
||||
BackgroundNormal=40,40,40
|
||||
DecorationFocus=0,122,255
|
||||
DecorationHover=0,122,255
|
||||
ForegroundActive=65,156,255
|
||||
ForegroundInactive=154,154,154
|
||||
ForegroundLink=65,156,255
|
||||
ForegroundNegative=255,74,76
|
||||
ForegroundNeutral=255,146,48
|
||||
ForegroundNormal=222,222,222
|
||||
ForegroundPositive=48,209,88
|
||||
ForegroundVisited=191,90,242
|
||||
|
||||
[Colors:View]
|
||||
BackgroundAlternate=37,37,37
|
||||
BackgroundNormal=30,30,30
|
||||
DecorationFocus=0,122,255
|
||||
DecorationHover=0,122,255
|
||||
ForegroundActive=65,156,255
|
||||
ForegroundInactive=154,154,154
|
||||
ForegroundLink=65,156,255
|
||||
ForegroundNegative=255,74,76
|
||||
ForegroundNeutral=255,146,48
|
||||
ForegroundNormal=221,221,221
|
||||
ForegroundPositive=48,209,88
|
||||
ForegroundVisited=191,90,242
|
||||
|
||||
[Colors:Window]
|
||||
BackgroundAlternate=46,46,46
|
||||
BackgroundNormal=40,40,40
|
||||
DecorationFocus=0,122,255
|
||||
DecorationHover=0,122,255
|
||||
ForegroundActive=65,156,255
|
||||
ForegroundInactive=154,154,154
|
||||
ForegroundLink=65,156,255
|
||||
ForegroundNegative=255,74,76
|
||||
ForegroundNeutral=255,146,48
|
||||
ForegroundNormal=222,222,222
|
||||
ForegroundPositive=48,209,88
|
||||
ForegroundVisited=191,90,242
|
||||
|
||||
[General]
|
||||
ColorScheme=DarwinBreezeDark
|
||||
Name=Darwin Breeze Dark
|
||||
shadeSortColumn=true
|
||||
|
||||
[KDE]
|
||||
contrast=4
|
||||
|
||||
[WM]
|
||||
activeBackground=40,40,40
|
||||
activeBlend=40,40,40
|
||||
activeForeground=222,222,222
|
||||
inactiveBackground=36,36,36
|
||||
inactiveBlend=36,36,36
|
||||
inactiveForeground=154,154,154
|
||||
@@ -0,0 +1,24 @@
|
||||
[kdeglobals][KDE]
|
||||
widgetStyle=Breeze
|
||||
|
||||
[kdeglobals][General]
|
||||
ColorScheme=DarwinBreezeDark
|
||||
|
||||
[kdeglobals][Icons]
|
||||
Theme=breeze-dark
|
||||
|
||||
[plasmarc][Theme]
|
||||
name=default
|
||||
|
||||
[kcminputrc][Mouse]
|
||||
cursorTheme=breeze_cursors
|
||||
|
||||
[kwinrc][WindowSwitcher]
|
||||
LayoutName=org.kde.breeze.desktop
|
||||
|
||||
[kwinrc][DesktopSwitcher]
|
||||
LayoutName=org.kde.breeze.desktop
|
||||
|
||||
[kwinrc][org.kde.kdecoration2]
|
||||
library=org.kde.breeze
|
||||
theme=Breeze
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"KPackageStructure": "Plasma/LookAndFeel",
|
||||
"KPlugin": {
|
||||
"Authors": [
|
||||
{
|
||||
"Name": "trivk"
|
||||
}
|
||||
],
|
||||
"Category": "",
|
||||
"Description": "Breeze in macOS-inspired colors (dark)",
|
||||
"Id": "dev.trivk.darwinbreeze.dark",
|
||||
"License": "GPL-2.0-or-later",
|
||||
"Name": "Darwin Breeze Dark",
|
||||
"Version": "1.0"
|
||||
},
|
||||
"X-Plasma-APIVersion": "2"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
^/README.*
|
||||
^/\.gitignore
|
||||
^/apply\.sh
|
||||
^/build\.py
|
||||
^/t3
|
||||
^/telegram
|
||||
^/vscode
|
||||
__pycache__
|
||||
@@ -0,0 +1,133 @@
|
||||
# Darwin Breeze
|
||||
|
||||
Breeze for KDE Plasma 6 in the macOS dark system colors, with Helium, T3 Code,
|
||||
VS Code and Telegram themed from the same colors.
|
||||
|
||||
Only the colors change. Breeze still draws the widgets and the title bar, and
|
||||
the window buttons stay on the right.
|
||||
|
||||
- Selection and focus rings use the macOS blue, `#007AFF`.
|
||||
- The title bar has the same color as the toolbar below it, so the two read as
|
||||
one strip.
|
||||
- When a window loses focus, its selection turns gray, as on macOS.
|
||||
- Errors, warnings, success text and links use Apple's system red, orange,
|
||||
green, blue and purple.
|
||||
|
||||
## Install
|
||||
|
||||
From `~/.dotfiles`:
|
||||
|
||||
```sh
|
||||
stow -d kde -t "$HOME" theme
|
||||
./kde/theme/apply.sh
|
||||
```
|
||||
|
||||
`apply.sh` regenerates the app themes, applies the global theme, hides the
|
||||
line under the title bar, turns off the wallpaper accent color, gives Helium
|
||||
the KWin title buttons and an even tab strip, publishes the T3 Code theme and
|
||||
installs the VS Code extension. Restart Helium afterwards; T3 Code switches on its own. In VS
|
||||
Code, pick "Darwin Breeze Dark" once under Preferences → Color Theme; after
|
||||
later color changes, run Developer: Reload Window.
|
||||
|
||||
Telegram has to import its theme by hand: Settings → Chat Settings → Chat
|
||||
background → Choose from file, then pick
|
||||
`kde/theme/telegram/DarwinBreezeDark.tdesktop-theme` and Apply. Import it
|
||||
again after the colors change.
|
||||
|
||||
## Changing colors
|
||||
|
||||
The color scheme is the only place colors are defined:
|
||||
|
||||
```
|
||||
kde/theme/.local/share/color-schemes/DarwinBreezeDark.colors
|
||||
```
|
||||
|
||||
Edit it, then run `./kde/theme/apply.sh` again. Everything else follows:
|
||||
|
||||
| App | How it gets the colors |
|
||||
| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Qt / KDE apps | the color scheme itself |
|
||||
| GTK apps | Breeze GTK, which `kde-gtk-config` syncs from the scheme |
|
||||
| Tray icons in `kde/tray-icons/` | `ColorScheme-Text`, recolored by Plasma |
|
||||
| Helium | Breeze GTK, through Helium's GTK theme (see [Helium notes](#helium-notes)) |
|
||||
| T3 Code | `t3/darwin-breeze.json`, generated by `build.py` and published with `t3 theme set` |
|
||||
| VS Code | `vscode/package.json` and `vscode/themes/`, generated by `build.py`, packed into `darwin-breeze.vsix` and installed by `apply.sh` |
|
||||
| Telegram | `telegram/DarwinBreezeDark.tdesktop-theme`, built by `build.py` and imported by hand |
|
||||
|
||||
The generated text files are committed so that `stow` alone gives a working
|
||||
setup; the binary packages (Telegram's `.tdesktop-theme`, VS Code's `.vsix`)
|
||||
are built by `build.py` instead. Don't edit generated files by hand.
|
||||
|
||||
## T3 Code notes
|
||||
|
||||
- T3 Code ignores symlinked theme files, so the theme isn't stowed;
|
||||
`apply.sh` publishes a copy into `~/.t3/userdata/themes/`.
|
||||
- Every slot of the T3 theme maps to a role in the color scheme (see `t3()` in
|
||||
`build.py`), so a new slot or a different mapping is a change there, not a
|
||||
hand-edited color.
|
||||
|
||||
## VS Code notes
|
||||
|
||||
- The workbench colors start from VS Code's own default dark theme, Dark 2026
|
||||
(vendored in `vscode/base/` with the themes it includes). It already lays
|
||||
out its grays as the scheme does: the editor darkest, the chrome around it
|
||||
lighter, widgets lighter still. Each of those becomes the matching scheme
|
||||
gray and the grays between them are interpolated. Other colors take the
|
||||
hue of the matching Apple color and keep their lightness and saturation.
|
||||
Keys with an exact role, such as buttons, badges, the active tab's top
|
||||
border and the git colors, are set directly (`vscode()` in `build.py`).
|
||||
- Syntax colors are Pierre Dark's, the theme T3 Code highlights code with
|
||||
(`vscode/base/pierre-dark.json`, taken from T3 Code). They are used as they
|
||||
are, without gamma compensation, so code looks the same in both apps.
|
||||
- The terminal palette is generated from the color scheme.
|
||||
- VS Code is Electron, so its workbench colors get the same gamma
|
||||
compensation as T3 Code.
|
||||
- The `.vsix` isn't committed; `build.py` packs it from `vscode/`.
|
||||
|
||||
## Telegram notes
|
||||
|
||||
- Telegram has some 600 color keys and the scheme has roles for only a few
|
||||
dozen of them (`telegram()` in `build.py`). The rest start from Telegram's
|
||||
own night theme, vendored as `telegram/night.tdesktop-palette`: its
|
||||
blue-tinted grays become scheme grays of the same brightness and its blues
|
||||
take the macOS blue's hue. Other colors, such as the reds, greens and name
|
||||
colors, are kept as night has them.
|
||||
- The chat list, top bar and compose bar use the window color; the chat
|
||||
behind the bubbles and the folder strip use the darker view color.
|
||||
- Telegram is a Qt app, so unlike T3 Code and VS Code it needs no gamma
|
||||
compensation.
|
||||
- The `.tdesktop-theme` is a zip, so it isn't committed; `build.py` builds it
|
||||
from the night palette and the color scheme.
|
||||
|
||||
## Helium notes
|
||||
|
||||
- Helium uses the GTK theme (Settings → Appearance → Theme: GTK) with "Use
|
||||
system title bar and borders" off, so the tab strip doubles as the title
|
||||
bar. Its colors come from Breeze GTK, which `kde-gtk-config` syncs from
|
||||
the scheme; there is no Helium theme to generate.
|
||||
- With the system title bar off, Helium draws the window buttons through
|
||||
GTK. `kde-gtk-config` renders the KWin buttons into
|
||||
`~/.config/gtk-3.0/window_decorations.css`, but hands that file to GTK apps
|
||||
through a GTK module that Helium doesn't load, so Helium would show Breeze
|
||||
GTK's own round buttons instead. `apply.sh` imports the file from `gtk.css`
|
||||
so Helium picks it up too.
|
||||
- In the compact layout, the address bar takes GTK's text field color and the
|
||||
segment with the extension and window buttons takes the window color, which
|
||||
Chromium resolves to the darker view color. `.config/gtk-3.0/chromium.css`
|
||||
gives both the title bar color, and `apply.sh` imports it from `gtk.css`.
|
||||
Chromium adds a `chromium` class to every GTK node it reads colors from, so
|
||||
the rules reach Helium and no other GTK app.
|
||||
- Chromium tags its output as sRGB and KWin shows it with a gamma 2.2 curve,
|
||||
which lifts dark grays (40 becomes 44). T3 Code and VS Code get
|
||||
pre-compensated colors from `build.py`; Helium instead runs with
|
||||
`--disable-features=WaylandWpColorManagerV1`, so its surfaces go untagged
|
||||
and show the GTK colors as they are.
|
||||
|
||||
## When the colors don't show up
|
||||
|
||||
- In System Settings → Colors, take the accent color from the color scheme. A
|
||||
custom accent, or one taken from the wallpaper, replaces the blue.
|
||||
- Use the Plasma style called "Breeze". "Breeze Dark" and "Breeze Light" carry
|
||||
their own colors, so panels and popups ignore the scheme.
|
||||
- GTK apps follow the scheme only with the Breeze GTK theme. Flatpak apps also
|
||||
need `org.gtk.Gtk3theme.Breeze` installed.
|
||||
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env bash
|
||||
# Regenerate the app themes from the color scheme and apply Darwin Breeze.
|
||||
#
|
||||
# Run `stow -d kde -t "$HOME" theme` from the repo root first.
|
||||
set -euo pipefail
|
||||
|
||||
here="$(cd "$(dirname "$0")" && pwd)"
|
||||
data="${XDG_DATA_HOME:-$HOME/.local/share}"
|
||||
|
||||
if [ ! -e "$data/color-schemes/DarwinBreezeDark.colors" ]; then
|
||||
echo 'DarwinBreezeDark.colors is not installed; run: stow -d kde -t "$HOME" theme' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
python3 -I "$here/build.py"
|
||||
|
||||
plasma-apply-lookandfeel --apply dev.trivk.darwinbreeze.dark
|
||||
|
||||
# plasma-apply-colorscheme skips a scheme that is already active, so edits
|
||||
# to the .colors file would not be picked up. Bounce through stock Breeze.
|
||||
plasma-apply-colorscheme BreezeClassic >/dev/null
|
||||
plasma-apply-colorscheme DarwinBreezeDark >/dev/null
|
||||
|
||||
# kde-gtk-config writes gtk.css; add our imports to it.
|
||||
gtk_import() {
|
||||
local css="${XDG_CONFIG_HOME:-$HOME/.config}/$1/gtk.css"
|
||||
if [ -e "$css" ] && ! grep -qF "'$2'" "$css"; then
|
||||
sed -i "\$a @import '$2';" "$css"
|
||||
fi
|
||||
}
|
||||
# kde-gtk-config gives GTK apps the KWin title buttons through a GTK module,
|
||||
# which Helium doesn't load, so it would fall back to Breeze GTK's own
|
||||
# buttons. Importing the same CSS from gtk.css reaches Helium too.
|
||||
gtk_import gtk-3.0 window_decorations.css
|
||||
gtk_import gtk-4.0 window_decorations.css
|
||||
# Helium's tab strip colors (see chromium.css).
|
||||
gtk_import gtk-3.0 chromium.css
|
||||
|
||||
# Drop the line under the title bar so it blends into the toolbar.
|
||||
kwriteconfig6 --file breezerc --group Windeco --key DrawTitleBarSeparator false
|
||||
|
||||
# A wallpaper-derived accent color would override the blue from the scheme.
|
||||
kwriteconfig6 --file kdeglobals --group General --key AccentColor --delete
|
||||
kwriteconfig6 --file kdeglobals --group General --key accentColorFromWallpaper false
|
||||
|
||||
qdbus6 org.kde.KWin /KWin reconfigure 2>/dev/null \
|
||||
|| dbus-send --session --type=signal /KWin org.kde.KWin.reloadConfig
|
||||
|
||||
# T3 Code skips symlinked theme files, so publish a copy instead of stowing it.
|
||||
t3="$(command -v t3 || echo "$HOME/.t3/bin/t3")"
|
||||
if [ -x "$t3" ]; then
|
||||
"$t3" theme set "$here/t3/darwin-breeze.json" >/dev/null
|
||||
fi
|
||||
|
||||
# VS Code only loads themes from installed extensions. --force reinstalls the
|
||||
# same version, so color changes land without a version bump.
|
||||
if command -v code >/dev/null; then
|
||||
code --install-extension "$here/vscode/darwin-breeze.vsix" --force >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
echo "Applied Darwin Breeze"
|
||||
if pgrep -x helium >/dev/null; then
|
||||
echo "Restart Helium to pick up the new colors"
|
||||
fi
|
||||
@@ -0,0 +1,617 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate app themes from the Darwin Breeze KDE color scheme.
|
||||
|
||||
.local/share/color-schemes/DarwinBreezeDark.colors is the only place colors
|
||||
are defined. This script derives from it:
|
||||
|
||||
t3/darwin-breeze.json (published to T3 Code by apply.sh)
|
||||
telegram/DarwinBreezeDark.tdesktop-theme (not committed; imported into Telegram by hand)
|
||||
vscode/ (packed into vscode/darwin-breeze.vsix, installed by apply.sh)
|
||||
"""
|
||||
|
||||
import colorsys
|
||||
import configparser
|
||||
import io
|
||||
import json
|
||||
import re
|
||||
import struct
|
||||
import zipfile
|
||||
import zlib
|
||||
from collections.abc import Callable, Mapping, Sequence
|
||||
from pathlib import Path
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
PKG = HERE
|
||||
SCHEME = PKG / ".local/share/color-schemes/DarwinBreezeDark.colors"
|
||||
T3 = HERE / "t3/darwin-breeze.json"
|
||||
# Telegram Desktop's built-in night theme, used as the base for every key the
|
||||
# scheme has no role for: the colors file from telegramdesktop/tdesktop at
|
||||
# 837b256, Telegram/Resources/night.tdesktop-theme.
|
||||
TELEGRAM_BASE = HERE / "telegram/night.tdesktop-palette"
|
||||
TELEGRAM = HERE / "telegram/DarwinBreezeDark.tdesktop-theme"
|
||||
VSCODE = HERE / "vscode"
|
||||
VSCODE_THEME = "themes/DarwinBreezeDark-color-theme.json"
|
||||
# VS Code's default dark theme, Dark 2026 (which includes Dark Modern, Dark+
|
||||
# and Visual Studio Dark), from Code - OSS 1.138 extensions/theme-defaults.
|
||||
# The workbench colors start from it.
|
||||
VSCODE_UI = VSCODE / "base/2026-dark.json"
|
||||
# Pierre Dark, the syntax theme T3 Code highlights code with (from T3 Code
|
||||
# 0.1.4). The editor uses its token colors as they are.
|
||||
VSCODE_SYNTAX = VSCODE / "base/pierre-dark.json"
|
||||
|
||||
# An RGB or RGBA color, 0-255 per channel.
|
||||
type Color = tuple[int, ...]
|
||||
# Looks up a color in the scheme by group and key.
|
||||
type ColorFn = Callable[[str, str], Color]
|
||||
|
||||
WHITE = (255, 255, 255)
|
||||
|
||||
# Apple systemCyan; the KDE scheme has no cyan role.
|
||||
CYAN = (100, 210, 255)
|
||||
|
||||
# Apple systemYellow; search highlights in T3 Code.
|
||||
YELLOW = (255, 255, 0)
|
||||
|
||||
|
||||
def load() -> ColorFn:
|
||||
cp = configparser.ConfigParser(interpolation=None, strict=False)
|
||||
cp.optionxform = str # type: ignore[method-assign,assignment]
|
||||
cp.read(SCHEME)
|
||||
|
||||
def color(group: str, key: str) -> Color:
|
||||
return tuple(int(v) for v in cp[f"Colors:{group}"][key].split(","))
|
||||
|
||||
return color
|
||||
|
||||
|
||||
def mix(a: Sequence[int], b: Sequence[int], t: float) -> Color:
|
||||
return tuple(round(x + (y - x) * t) for x, y in zip(a, b))
|
||||
|
||||
|
||||
def hexc(c: Sequence[int]) -> str:
|
||||
"""#rrggbb, or #rrggbbaa when c carries an alpha."""
|
||||
return "#" + "".join(f"{v:02x}" for v in c)
|
||||
|
||||
|
||||
def kwin_compensate(c: Sequence[int]) -> list[int]:
|
||||
"""Pre-distort a color for Chromium on KWin.
|
||||
|
||||
Chromium tags its surfaces as sRGB, KWin shows them with a gamma 2.2
|
||||
curve, so dark grays come out lighter (40 -> 44). Encoding the target
|
||||
with the inverse makes Chromium apps land on the same values as native
|
||||
apps.
|
||||
"""
|
||||
|
||||
def ch(v: int) -> int:
|
||||
lin: float = (v / 255) ** 2.2
|
||||
enc = 12.92 * lin if lin <= 0.0031308 else 1.055 * lin ** (1 / 2.4) - 0.055
|
||||
return round(enc * 255)
|
||||
|
||||
return [ch(v) for v in c]
|
||||
|
||||
|
||||
def ansi(color: ColorFn) -> list[Color]:
|
||||
"""The 16 colors for the VS Code terminal."""
|
||||
bg = color("View", "BackgroundNormal")
|
||||
fg = color("View", "ForegroundNormal")
|
||||
normal = [
|
||||
mix(bg, fg, 0.15),
|
||||
color("View", "ForegroundNegative"),
|
||||
color("View", "ForegroundPositive"),
|
||||
color("View", "ForegroundNeutral"),
|
||||
color("View", "ForegroundLink"),
|
||||
color("View", "ForegroundVisited"),
|
||||
CYAN,
|
||||
fg,
|
||||
]
|
||||
bright = [
|
||||
mix(bg, fg, 0.45),
|
||||
*(mix(c, WHITE, 0.25) for c in normal[1:7]),
|
||||
mix(fg, WHITE, 0.6),
|
||||
]
|
||||
return normal + bright
|
||||
|
||||
|
||||
def t3(color: ColorFn) -> dict[str, str]:
|
||||
"""Every color slot of a T3 Code theme, mapped onto a scheme role."""
|
||||
window, window_text = color("Window", "BackgroundNormal"), color("Window", "ForegroundNormal")
|
||||
view, view_text = color("View", "BackgroundNormal"), color("View", "ForegroundNormal")
|
||||
header, header_text = color("Header", "BackgroundNormal"), color("Header", "ForegroundNormal")
|
||||
button, button_text = color("Button", "BackgroundNormal"), color("Button", "ForegroundNormal")
|
||||
accent, accent_text = color("Selection", "BackgroundNormal"), color("Selection", "ForegroundNormal")
|
||||
unfocused = color("Selection][Inactive", "BackgroundNormal")
|
||||
unfocused_text = color("Selection][Inactive", "ForegroundNormal")
|
||||
muted = color("View", "ForegroundInactive")
|
||||
negative = color("View", "ForegroundNegative")
|
||||
neutral = color("View", "ForegroundNeutral")
|
||||
link = color("View", "ForegroundLink")
|
||||
window_line = mix(window, window_text, 0.115)
|
||||
|
||||
colors = {
|
||||
"canvas": view,
|
||||
"chrome": header,
|
||||
"toolbar": header,
|
||||
"toolbarForeground": header_text,
|
||||
"toolbarBorder": mix(header, header_text, 0.115),
|
||||
"toolbarControl": button,
|
||||
"toolbarControlForeground": button_text,
|
||||
"toolbarControlHover": color("Button", "BackgroundAlternate"),
|
||||
"surface": view,
|
||||
"surfaceRaised": window,
|
||||
"surfaceOverlay": window,
|
||||
"text": view_text,
|
||||
"textMuted": muted,
|
||||
"border": mix(view, view_text, 0.115),
|
||||
"input": mix(view, view_text, 0.3),
|
||||
"focus": mix(view, accent, 0.5),
|
||||
"accent": accent,
|
||||
"accentForeground": accent_text,
|
||||
"secondary": button,
|
||||
"secondaryForeground": button_text,
|
||||
"muted": window,
|
||||
"mutedForeground": color("Window", "ForegroundInactive"),
|
||||
"placeholder": muted,
|
||||
"secondaryLabel": muted,
|
||||
"iconMuted": muted,
|
||||
"error": negative,
|
||||
"errorForeground": negative,
|
||||
"errorSurface": mix(view, negative, 0.1),
|
||||
"warning": neutral,
|
||||
"warningForeground": neutral,
|
||||
"warningSurface": mix(view, neutral, 0.1),
|
||||
"update": link,
|
||||
"updateForeground": link,
|
||||
"updateSurface": mix(view, link, 0.12),
|
||||
"accentSurface": unfocused,
|
||||
"accentSurfaceForeground": unfocused_text,
|
||||
"messageSurface": window,
|
||||
"messageForeground": window_text,
|
||||
"messageAction": accent,
|
||||
"messageActionForeground": accent_text,
|
||||
"messageActionHover": color("Selection", "BackgroundAlternate"),
|
||||
"codeBackground": window,
|
||||
"codeForeground": WHITE,
|
||||
"searchMatchBackground": mix(view, YELLOW, 0.25),
|
||||
"searchMatchForeground": view_text,
|
||||
"searchMatchActiveBackground": YELLOW,
|
||||
"searchMatchActiveForeground": (0, 0, 0),
|
||||
"sidebar": window,
|
||||
"sidebarForeground": window_text,
|
||||
"sidebarMutedForeground": color("Window", "ForegroundInactive"),
|
||||
"sidebarControlSurface": button,
|
||||
"sidebarRowHover": window_line,
|
||||
"sidebarRowActive": unfocused,
|
||||
"sidebarRowSelected": unfocused,
|
||||
"sidebarBorder": window_line,
|
||||
"terminalBackground": view,
|
||||
"terminalForeground": WHITE,
|
||||
"terminalCursor": WHITE,
|
||||
"terminalSelection": mix(view, accent, 0.4),
|
||||
"terminalScrollbar": mix(view, view_text, 0.3),
|
||||
"terminalScrollbarHover": muted,
|
||||
}
|
||||
# T3 Code runs on Chromium too, so it needs the same KWin compensation.
|
||||
return {k: hexc(kwin_compensate(v)) for k, v in colors.items()}
|
||||
|
||||
|
||||
def telegram(color: ColorFn) -> dict[str, Color]:
|
||||
"""Telegram keys mapped onto a scheme role; the rest come from night."""
|
||||
window, window_text = color("Window", "BackgroundNormal"), color("Window", "ForegroundNormal")
|
||||
view, view_text = color("View", "BackgroundNormal"), color("View", "ForegroundNormal")
|
||||
header, header_text = color("Header", "BackgroundNormal"), color("Header", "ForegroundNormal")
|
||||
title_inactive = color("Header][Inactive", "BackgroundNormal")
|
||||
title_inactive_text = color("Header][Inactive", "ForegroundNormal")
|
||||
tooltip, tooltip_text = color("Tooltip", "BackgroundNormal"), color("Tooltip", "ForegroundNormal")
|
||||
accent, accent_text = color("Selection", "BackgroundNormal"), color("Selection", "ForegroundNormal")
|
||||
accent_hover = color("Selection", "BackgroundAlternate")
|
||||
muted = color("Window", "ForegroundInactive")
|
||||
negative = color("Window", "ForegroundNegative")
|
||||
positive = color("Window", "ForegroundPositive")
|
||||
link = color("Window", "ForegroundLink")
|
||||
hover = mix(window, window_text, 0.115)
|
||||
ripple = mix(window, window_text, 0.18)
|
||||
control = mix(window, window_text, 0.3)
|
||||
msg_in = mix(view, view_text, 0.1)
|
||||
msg_out = mix(view, accent, 0.5)
|
||||
|
||||
return {
|
||||
"windowBg": window,
|
||||
"windowFg": window_text,
|
||||
"windowBgOver": hover,
|
||||
"windowBgRipple": ripple,
|
||||
"windowFgOver": window_text,
|
||||
"windowSubTextFg": muted,
|
||||
"windowSubTextFgOver": mix(muted, window_text, 0.2),
|
||||
"windowBoldFg": window_text,
|
||||
"windowBoldFgOver": window_text,
|
||||
"windowBgActive": accent,
|
||||
"windowFgActive": accent_text,
|
||||
"windowActiveTextFg": link,
|
||||
"windowShadowFgFallback": window,
|
||||
"activeButtonBg": accent,
|
||||
"activeButtonBgOver": accent_hover,
|
||||
"activeButtonBgRipple": mix(accent, WHITE, 0.2),
|
||||
"activeButtonFg": accent_text,
|
||||
"activeButtonFgOver": accent_text,
|
||||
"activeButtonSecondaryFg": mix(accent, accent_text, 0.75),
|
||||
"activeLineFg": accent,
|
||||
"activeLineFgError": negative,
|
||||
"lightButtonBg": window,
|
||||
"lightButtonBgOver": mix(window, accent, 0.12),
|
||||
"lightButtonBgRipple": mix(window, accent, 0.2),
|
||||
"lightButtonFg": link,
|
||||
"attentionButtonFg": negative,
|
||||
"attentionButtonFgOver": negative,
|
||||
"attentionButtonBgOver": mix(window, negative, 0.12),
|
||||
"attentionButtonBgRipple": mix(window, negative, 0.2),
|
||||
"outlineButtonOutlineFg": accent,
|
||||
"menuBg": window,
|
||||
"menuBgOver": hover,
|
||||
"menuBgRipple": ripple,
|
||||
"menuIconFg": muted,
|
||||
"menuIconFgOver": mix(muted, window_text, 0.3),
|
||||
"menuSubmenuArrowFg": muted,
|
||||
"menuFgDisabled": control,
|
||||
"menuSeparatorFg": hover,
|
||||
"checkboxFg": muted,
|
||||
"sliderBgInactive": control,
|
||||
"sliderBgActive": accent,
|
||||
"inputBorderFg": control,
|
||||
# Breeze draws text fields in the view color with a blue focus ring.
|
||||
"filterInputActiveBg": view,
|
||||
"filterInputInactiveBg": view,
|
||||
"filterInputBorderFg": accent,
|
||||
"tooltipBg": tooltip,
|
||||
"tooltipFg": tooltip_text,
|
||||
"tooltipBorderFg": mix(tooltip, tooltip_text, 0.115),
|
||||
"titleBg": title_inactive,
|
||||
"titleBgActive": header,
|
||||
"titleFg": title_inactive_text,
|
||||
"titleFgActive": header_text,
|
||||
"topBarBg": header,
|
||||
"boxBg": window,
|
||||
"boxTitleFg": window_text,
|
||||
"boxTextFgGood": positive,
|
||||
"boxTextFgError": negative,
|
||||
# Folder strip in the view color, so the selected folder merges into
|
||||
# the chat list next to it.
|
||||
"sideBarBg": view,
|
||||
"sideBarBgActive": window,
|
||||
"sideBarBgRipple": mix(view, window_text, 0.1),
|
||||
"sideBarTextFg": muted,
|
||||
"sideBarTextFgActive": link,
|
||||
"sideBarIconFg": muted,
|
||||
"sideBarIconFgActive": link,
|
||||
"sideBarBadgeBg": accent,
|
||||
"sideBarBadgeBgMuted": control,
|
||||
"sideBarBadgeFg": accent_text,
|
||||
"dialogsBg": window,
|
||||
"dialogsBgOver": hover,
|
||||
"dialogsRippleBg": ripple,
|
||||
"dialogsBgActive": accent,
|
||||
"dialogsRippleBgActive": accent_hover,
|
||||
"dialogsNameFg": window_text,
|
||||
"dialogsTextFg": muted,
|
||||
"dialogsTextFgOver": muted,
|
||||
"dialogsTextFgService": link,
|
||||
"dialogsTextFgServiceOver": link,
|
||||
"dialogsDateFg": muted,
|
||||
"dialogsDateFgOver": muted,
|
||||
"dialogsDraftFg": negative,
|
||||
"dialogsOnlineBadgeFg": positive,
|
||||
"dialogsVerifiedIconBg": link,
|
||||
"dialogsVerifiedIconFg": window,
|
||||
"dialogsUnreadBg": accent,
|
||||
"dialogsUnreadBgOver": accent,
|
||||
"dialogsUnreadFg": accent_text,
|
||||
"dialogsUnreadBgMuted": control,
|
||||
"dialogsUnreadBgMutedOver": mix(window, window_text, 0.35),
|
||||
"dialogsUnreadBgActive": accent_text,
|
||||
"dialogsUnreadFgActive": accent,
|
||||
"dialogsUnreadBgMutedActive": mix(accent, accent_text, 0.55),
|
||||
"historyComposeAreaBg": window,
|
||||
"historyComposeAreaFg": window_text,
|
||||
"historyComposeButtonBgOver": hover,
|
||||
"historyComposeButtonBgRipple": ripple,
|
||||
"historyTextInFg": view_text,
|
||||
"historyTextOutFg": view_text,
|
||||
"historyLinkInFg": link,
|
||||
"msgInBg": msg_in,
|
||||
"msgInBgSelected": mix(msg_in, accent, 0.3),
|
||||
"msgOutBg": msg_out,
|
||||
"msgOutBgSelected": mix(msg_out, accent, 0.3),
|
||||
"msgInDateFg": muted,
|
||||
"msgOutDateFg": mix(msg_out, WHITE, 0.55),
|
||||
"msgSelectOverlay": (*accent, 0x4C),
|
||||
"msgStickerOverlay": (*accent, 0x7F),
|
||||
}
|
||||
|
||||
|
||||
def luma(c: Sequence[int]) -> float:
|
||||
return 0.299 * c[0] + 0.587 * c[1] + 0.114 * c[2]
|
||||
|
||||
|
||||
def interp(points: Sequence[tuple[float, float]], x: float) -> float:
|
||||
for (x0, y0), (x1, y1) in zip(points, points[1:]):
|
||||
if x <= x1:
|
||||
return y0 + (y1 - y0) * (x - x0) / (x1 - x0)
|
||||
return points[-1][1]
|
||||
|
||||
|
||||
def parse_hex(v: str) -> Color:
|
||||
h = v[1:]
|
||||
if len(h) in (3, 4):
|
||||
h = "".join(ch * 2 for ch in h)
|
||||
return tuple(int(h[i:i + 2], 16) for i in range(0, len(h), 2))
|
||||
|
||||
|
||||
def telegram_theme(color: ColorFn) -> str:
|
||||
"""The night theme, recolored onto the scheme.
|
||||
|
||||
Night tints everything blue. Its tinted grays become scheme grays of
|
||||
matching brightness, its blues take the accent's hue and saturation, and
|
||||
other hues (reds, greens, name colors) stay. telegram() then pins every
|
||||
key that has a scheme role.
|
||||
"""
|
||||
base = TELEGRAM_BASE.read_text()
|
||||
line_re = re.compile(r"^(\w+):\s*(#[0-9a-fA-F]+)\s*;")
|
||||
night = {m[1]: parse_hex(m[2]) for m in map(line_re.match, base.splitlines()) if m}
|
||||
|
||||
window, muted = color("Window", "BackgroundNormal"), color("Window", "ForegroundInactive")
|
||||
grays = sorted({
|
||||
(0, 0),
|
||||
(luma(night["windowBg"]), window[0]),
|
||||
(luma(night["windowSubTextFg"]), muted[0]),
|
||||
(255, 255),
|
||||
})
|
||||
accent_h, _, accent_s = colorsys.rgb_to_hls(*(v / 255 for v in color("Selection", "BackgroundNormal")))
|
||||
|
||||
def recolor(c: Color) -> Color:
|
||||
rgb, alpha = c[:3], c[3:]
|
||||
chroma = max(rgb) - min(rgb)
|
||||
h, l, _ = colorsys.rgb_to_hls(*(v / 255 for v in rgb))
|
||||
if chroma <= 4 or not 195 <= h * 360 <= 225:
|
||||
return c
|
||||
if chroma <= 55:
|
||||
g = round(interp(grays, luma(rgb)))
|
||||
return (g, g, g, *alpha)
|
||||
return (*(round(v * 255) for v in colorsys.hls_to_rgb(accent_h, l, accent_s)), *alpha)
|
||||
|
||||
pinned = telegram(color)
|
||||
seen: set[str] = set()
|
||||
out = [f"// Generated by kde/theme/build.py from {SCHEME.name}"]
|
||||
for line in base.splitlines():
|
||||
m = line_re.match(line)
|
||||
if m:
|
||||
key = m[1]
|
||||
seen.add(key)
|
||||
c = pinned[key] if key in pinned else recolor(night[key])
|
||||
line = f"{key}: {hexc(c)};" + line[m.end():]
|
||||
elif re.match(r"^(\w+):", line) and line.split(":")[0] in pinned:
|
||||
key = line.split(":")[0]
|
||||
seen.add(key)
|
||||
line = f"{key}: {hexc(pinned[key])};"
|
||||
out.append(line)
|
||||
out += [f"{k}: {hexc(c)};" for k, c in pinned.items() if k not in seen]
|
||||
return "\n".join(out) + "\n"
|
||||
|
||||
|
||||
def vscode_base_colors() -> dict[str, Color]:
|
||||
"""Dark 2026's colors with its include chain resolved."""
|
||||
chain: list[dict[str, str]] = []
|
||||
path: Path | None = VSCODE_UI
|
||||
while path:
|
||||
theme = json.loads(path.read_text())
|
||||
chain.append(theme.get("colors", {}))
|
||||
path = path.parent / theme["include"] if "include" in theme else None
|
||||
colors: dict[str, str] = {}
|
||||
for layer in reversed(chain):
|
||||
colors.update(layer)
|
||||
return {k: parse_hex(v) for k, v in colors.items()}
|
||||
|
||||
|
||||
def vscode(color: ColorFn) -> dict[str, str]:
|
||||
"""Workbench colors: Dark 2026, recolored onto the scheme.
|
||||
|
||||
Dark 2026 lays out its grays the way the scheme does: the chrome lighter
|
||||
than the editor, widgets lighter still. Each of those grays becomes the
|
||||
scheme gray in the same place, and the grays in between are interpolated.
|
||||
Each hue takes the hue of the matching scheme color but keeps its own
|
||||
lightness and saturation, so a muted dark red background stays one. pins
|
||||
then sets the keys that have an exact scheme role, which is where the full
|
||||
macOS blue shows.
|
||||
"""
|
||||
window, window_text = color("Window", "BackgroundNormal"), color("Window", "ForegroundNormal")
|
||||
view, view_text = color("View", "BackgroundNormal"), color("View", "ForegroundNormal")
|
||||
accent, accent_text = color("Selection", "BackgroundNormal"), color("Selection", "ForegroundNormal")
|
||||
muted = color("Window", "ForegroundInactive")
|
||||
negative = color("View", "ForegroundNegative")
|
||||
neutral = color("View", "ForegroundNeutral")
|
||||
positive = color("View", "ForegroundPositive")
|
||||
link = color("View", "ForegroundLink")
|
||||
base = vscode_base_colors()
|
||||
|
||||
grays = sorted({
|
||||
(0, 0),
|
||||
(luma(base["editor.background"]), view[0]),
|
||||
(luma(base["sideBar.background"]), window[0]),
|
||||
(luma(base["editorWidget.background"]), color("Window", "BackgroundAlternate")[0]),
|
||||
(luma(base["sideBar.border"]), mix(window, window_text, 0.115)[0]),
|
||||
(luma(base["descriptionForeground"]), muted[0]),
|
||||
(luma(base["foreground"]), window_text[0]),
|
||||
(255, 255),
|
||||
})
|
||||
assert all(a[1] <= b[1] for a, b in zip(grays, grays[1:])), grays
|
||||
|
||||
def hls(c: Sequence[int]) -> tuple[float, float, float]:
|
||||
return colorsys.rgb_to_hls(*(v / 255 for v in c))
|
||||
|
||||
# (hue range in degrees, scheme color whose hue it takes)
|
||||
families: list[tuple[tuple[int, int], Color]] = [
|
||||
((0, 15), negative),
|
||||
((15, 70), neutral),
|
||||
((70, 170), positive),
|
||||
((170, 250), accent),
|
||||
((250, 330), color("View", "ForegroundVisited")),
|
||||
((330, 360), negative),
|
||||
]
|
||||
|
||||
def recolor(c: Color) -> Color:
|
||||
rgb, alpha = c[:3], c[3:]
|
||||
if max(rgb) - min(rgb) <= 10:
|
||||
g = round(interp(grays, luma(rgb)))
|
||||
return (g, g, g, *alpha)
|
||||
h, l, sat = hls(rgb)
|
||||
target = next(t for (lo, hi), t in families if lo <= h * 360 < hi)
|
||||
return (*(round(v * 255) for v in colorsys.hls_to_rgb(hls(target)[0], l, sat)), *alpha)
|
||||
|
||||
pins: dict[str, Color] = {
|
||||
"editor.background": view,
|
||||
"editor.foreground": view_text,
|
||||
"titleBar.inactiveBackground": color("Header][Inactive", "BackgroundNormal"),
|
||||
"titleBar.inactiveForeground": color("Header][Inactive", "ForegroundNormal"),
|
||||
"focusBorder": (*accent, 0xB3),
|
||||
"quickInputList.focusBackground": accent,
|
||||
"button.background": accent,
|
||||
"button.border": accent,
|
||||
"button.hoverBackground": color("Selection", "BackgroundAlternate"),
|
||||
"button.foreground": accent_text,
|
||||
"badge.background": accent,
|
||||
"badge.foreground": accent_text,
|
||||
"activityBarBadge.background": accent,
|
||||
"activityBarBadge.foreground": accent_text,
|
||||
"tab.activeBorderTop": accent,
|
||||
"panelTitle.activeBorder": accent,
|
||||
"textLink.foreground": link,
|
||||
"textLink.activeForeground": link,
|
||||
}
|
||||
names = ["Black", "Red", "Green", "Yellow", "Blue", "Magenta", "Cyan", "White"]
|
||||
for i, c in enumerate(ansi(color)):
|
||||
pins[f"terminal.ansi{'Bright' if i >= 8 else ''}{names[i % 8]}"] = c
|
||||
|
||||
colors = {k: pins.get(k) or recolor(c) for k, c in base.items()}
|
||||
colors.update(pins)
|
||||
# Electron is Chromium, so it needs the KWin compensation.
|
||||
return {k: hexc(kwin_compensate(c[:3]) + list(c[3:])) for k, c in sorted(colors.items())}
|
||||
|
||||
|
||||
def vscode_files(color: ColorFn) -> dict[str, str]:
|
||||
"""The extension files, keyed by their path inside it."""
|
||||
name = "Darwin Breeze Dark"
|
||||
# Syntax colors as T3 Code shows them. T3 Code doesn't compensate them
|
||||
# either, so the two render the same.
|
||||
syntax = json.loads(VSCODE_SYNTAX.read_text())
|
||||
theme = {
|
||||
"$schema": "vscode://schemas/color-theme",
|
||||
"name": name,
|
||||
"type": "dark",
|
||||
"semanticHighlighting": True,
|
||||
"colors": vscode(color),
|
||||
"tokenColors": syntax["tokenColors"],
|
||||
"semanticTokenColors": syntax["semanticTokenColors"],
|
||||
}
|
||||
package = {
|
||||
"name": "darwin-breeze",
|
||||
"displayName": "Darwin Breeze",
|
||||
"description": f"Generated by kde/theme/build.py from {SCHEME.name}",
|
||||
"publisher": "trivk",
|
||||
"version": "1.0.0",
|
||||
"engines": {"vscode": "^1.70.0"},
|
||||
"categories": ["Themes"],
|
||||
"contributes": {
|
||||
"themes": [{"label": name, "uiTheme": "vs-dark", "path": f"./{VSCODE_THEME}"}],
|
||||
},
|
||||
}
|
||||
return {
|
||||
"package.json": json.dumps(package, indent=2) + "\n",
|
||||
VSCODE_THEME: json.dumps(theme, indent=2) + "\n",
|
||||
}
|
||||
|
||||
|
||||
def vsix(files: Mapping[str, str]) -> bytes:
|
||||
"""Pack the extension the way vsce does, for code --install-extension."""
|
||||
manifest = """<?xml version="1.0" encoding="utf-8"?>
|
||||
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
|
||||
<Metadata>
|
||||
<Identity Language="en-US" Id="darwin-breeze" Version="1.0.0" Publisher="trivk"/>
|
||||
<DisplayName>Darwin Breeze</DisplayName>
|
||||
<Description xml:space="preserve">Darwin Breeze Dark color theme</Description>
|
||||
<Categories>Themes</Categories>
|
||||
<Properties>
|
||||
<Property Id="Microsoft.VisualStudio.Code.Engine" Value="^1.70.0"/>
|
||||
</Properties>
|
||||
</Metadata>
|
||||
<Installation>
|
||||
<InstallationTarget Id="Microsoft.VisualStudio.Code"/>
|
||||
</Installation>
|
||||
<Dependencies/>
|
||||
<Assets>
|
||||
<Asset Type="Microsoft.VisualStudio.Code.Manifest" Path="extension/package.json" Addressable="true"/>
|
||||
</Assets>
|
||||
</PackageManifest>
|
||||
"""
|
||||
content_types = """<?xml version="1.0" encoding="utf-8"?>
|
||||
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension=".json" ContentType="application/json"/><Default Extension=".vsixmanifest" ContentType="text/xml"/></Types>
|
||||
"""
|
||||
return zip_bytes({
|
||||
"[Content_Types].xml": content_types,
|
||||
"extension.vsixmanifest": manifest,
|
||||
**{f"extension/{path}": text for path, text in files.items()},
|
||||
})
|
||||
|
||||
|
||||
def solid_png(c: Sequence[int]) -> bytes:
|
||||
"""A 1x1 PNG; Telegram stretches it over the chat as a plain background."""
|
||||
|
||||
def chunk(kind: bytes, data: bytes) -> bytes:
|
||||
return struct.pack(">I", len(data)) + kind + data + struct.pack(">I", zlib.crc32(kind + data))
|
||||
|
||||
return (
|
||||
b"\x89PNG\r\n\x1a\n"
|
||||
+ chunk(b"IHDR", struct.pack(">IIBBBBB", 1, 1, 8, 2, 0, 0, 0))
|
||||
+ chunk(b"IDAT", zlib.compress(bytes([0, *c])))
|
||||
+ chunk(b"IEND", b"")
|
||||
)
|
||||
|
||||
|
||||
def zip_bytes(files: Mapping[str, str | bytes]) -> bytes:
|
||||
"""A zip with fixed timestamps, so an unchanged theme rebuilds byte-identical."""
|
||||
buf = io.BytesIO()
|
||||
with zipfile.ZipFile(buf, "w", zipfile.ZIP_DEFLATED) as z:
|
||||
for name, data in files.items():
|
||||
info = zipfile.ZipInfo(name, (1980, 1, 1, 0, 0, 0))
|
||||
info.compress_type = zipfile.ZIP_DEFLATED
|
||||
info.external_attr = 0o644 << 16
|
||||
z.writestr(info, data)
|
||||
return buf.getvalue()
|
||||
|
||||
|
||||
def write(path: Path, data: str | bytes) -> bool:
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
if isinstance(data, str):
|
||||
data = data.encode()
|
||||
if path.exists() and path.read_bytes() == data:
|
||||
return False
|
||||
path.write_bytes(data)
|
||||
print(f"wrote {path.relative_to(PKG.parent)}")
|
||||
return True
|
||||
|
||||
|
||||
def main() -> None:
|
||||
color = load()
|
||||
theme = {"version": 1, "name": "Darwin Breeze", "appearance": "dark", "colors": t3(color)}
|
||||
write(T3, json.dumps(theme, indent=2) + "\n")
|
||||
|
||||
write(TELEGRAM, zip_bytes({
|
||||
"colors.tdesktop-theme": telegram_theme(color),
|
||||
"background.png": solid_png(color("View", "BackgroundNormal")),
|
||||
}))
|
||||
|
||||
files = vscode_files(color)
|
||||
for path, text in files.items():
|
||||
write(VSCODE / path, text)
|
||||
write(VSCODE / "darwin-breeze.vsix", vsix(files))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"version": 1,
|
||||
"name": "Darwin Breeze",
|
||||
"appearance": "dark",
|
||||
"colors": {
|
||||
"canvas": "#181818",
|
||||
"chrome": "#232323",
|
||||
"toolbar": "#232323",
|
||||
"toolbarForeground": "#dfdfdf",
|
||||
"toolbarBorder": "#3a3a3a",
|
||||
"toolbarControl": "#5d5d5d",
|
||||
"toolbarControlForeground": "#e7e7e7",
|
||||
"toolbarControlHover": "#6d6d6d",
|
||||
"surface": "#181818",
|
||||
"surfaceRaised": "#232323",
|
||||
"surfaceOverlay": "#232323",
|
||||
"text": "#dedede",
|
||||
"textMuted": "#9b9b9b",
|
||||
"border": "#313131",
|
||||
"input": "#565656",
|
||||
"focus": "#064b8f",
|
||||
"accent": "#007bff",
|
||||
"accentForeground": "#ffffff",
|
||||
"secondary": "#5d5d5d",
|
||||
"secondaryForeground": "#e7e7e7",
|
||||
"muted": "#232323",
|
||||
"mutedForeground": "#9b9b9b",
|
||||
"placeholder": "#9b9b9b",
|
||||
"secondaryLabel": "#9b9b9b",
|
||||
"iconMuted": "#9b9b9b",
|
||||
"error": "#ff494b",
|
||||
"errorForeground": "#ff494b",
|
||||
"errorSurface": "#311c1e",
|
||||
"warning": "#ff932c",
|
||||
"warningForeground": "#ff932c",
|
||||
"warningSurface": "#31251a",
|
||||
"update": "#3f9dff",
|
||||
"updateForeground": "#3f9dff",
|
||||
"updateSurface": "#1c2936",
|
||||
"accentSurface": "#444444",
|
||||
"accentSurfaceForeground": "#ffffff",
|
||||
"messageSurface": "#232323",
|
||||
"messageForeground": "#dfdfdf",
|
||||
"messageAction": "#007bff",
|
||||
"messageActionForeground": "#ffffff",
|
||||
"messageActionHover": "#1288ff",
|
||||
"codeBackground": "#232323",
|
||||
"codeForeground": "#ffffff",
|
||||
"searchMatchBackground": "#55550e",
|
||||
"searchMatchForeground": "#dedede",
|
||||
"searchMatchActiveBackground": "#ffff00",
|
||||
"searchMatchActiveForeground": "#000000",
|
||||
"sidebar": "#232323",
|
||||
"sidebarForeground": "#dfdfdf",
|
||||
"sidebarMutedForeground": "#9b9b9b",
|
||||
"sidebarControlSurface": "#5d5d5d",
|
||||
"sidebarRowHover": "#3a3a3a",
|
||||
"sidebarRowActive": "#444444",
|
||||
"sidebarRowSelected": "#444444",
|
||||
"sidebarBorder": "#3a3a3a",
|
||||
"terminalBackground": "#181818",
|
||||
"terminalForeground": "#ffffff",
|
||||
"terminalCursor": "#ffffff",
|
||||
"terminalSelection": "#0a4179",
|
||||
"terminalScrollbar": "#565656",
|
||||
"terminalScrollbarHover": "#9b9b9b"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,467 @@
|
||||
windowBg: #17212b; // white: fallback for background
|
||||
windowFg: #f5f5f5; // black: fallback for text
|
||||
windowBgOver: #232e3c; // light gray: fallback for background with mouse over
|
||||
windowBgRipple: #24303d; // darker gray: fallback for ripple effect
|
||||
windowFgOver: #e9ecf0; // black: fallback for text with mouse over
|
||||
windowSubTextFg: #708499; // gray: fallback for additional text
|
||||
windowSubTextFgOver: #7c90a4; // darker gray: fallback for additional text with mouse over
|
||||
windowBoldFg: #e9e8e8; // dark gray: fallback for bold text
|
||||
windowBoldFgOver: #e9e9e9; // dark gray: fallback for bold text with mouse over
|
||||
windowBgActive: #5288c1; // bright blue: fallback for blue filled active areas
|
||||
windowFgActive: #ffffff; // white: fallback for text on active areas
|
||||
windowActiveTextFg: #6ab3f3; // online blue: fallback for active text like online status
|
||||
windowShadowFg: #000000; // black: fallback for shadow
|
||||
windowShadowFgFallback: #17212b; // gray: fallback for shadow without opacity
|
||||
shadowFg: #04080e56; // most shadows (including opacity)
|
||||
slideFadeOutBg: #0000003c; // slide animation (chat to profile) fade out filling
|
||||
slideFadeOutShadowFg: windowShadowFg; // slide animation (chat to profile) fade out right section shadow
|
||||
imageBg: #000000; // image background fallback (when photo size is less than minimum allowed)
|
||||
imageBgTransparent: #ffffff; // image background when displaying an image with opacity where no opacity is needed
|
||||
activeButtonBg: #2f6ea5; // default active button background
|
||||
activeButtonBgOver: #3476ab; // default active button background with mouse over
|
||||
activeButtonBgRipple: #3b7cb1; // default active button ripple effect
|
||||
activeButtonFg: #ffffff; // default active button text
|
||||
activeButtonFgOver: #ffffff; // default active button text with mouse over
|
||||
activeButtonSecondaryFg: #9abfe7; // default active button additional text (selected messages counter in forward / delete buttons)
|
||||
activeButtonSecondaryFgOver: activeButtonSecondaryFg; // default active button additional text with mouse over
|
||||
activeLineFg: #6396cb; // default active line (like code input field bottom border when you log in and field is focused)
|
||||
activeLineFgError: #ef5959; // default active line for error state (like code input field bottom border when you log in and you've entered incorrect code)
|
||||
lightButtonBg: #17212b; // default light button background (like buttons in boxes)
|
||||
lightButtonBgOver: #1d2a39; // default light button background with mouse over
|
||||
lightButtonBgRipple: #223143; // default light button ripple effect
|
||||
lightButtonFg: #6ab2f2; // default light button text
|
||||
lightButtonFgOver: lightButtonFg; // default light button text with mouse over
|
||||
attentionButtonFg: #ec3942; // default attention button text (like confirm button on log out)
|
||||
attentionButtonFgOver: #ec3942; // default attention button text with mouse over
|
||||
attentionButtonBgOver: #592a2a64; // default attention button background with mouse over
|
||||
attentionButtonBgRipple: #68323264; // default attention button ripple effect
|
||||
outlineButtonBg: windowBg; // default left outlined button background (like shared media links in profiles)
|
||||
outlineButtonBgOver: #202b37; // default left outlined button background with mouse over
|
||||
outlineButtonOutlineFg: #3983c3; // default left outlined button left outline border
|
||||
outlineButtonBgRipple: #27323f; // default left outlined button ripple effect
|
||||
menuBg: #17212b; // default popup menu background
|
||||
menuBgOver: #ffffff; // default popup menu item background with mouse over
|
||||
menuBgRipple: #1f2934; // default popup menu item ripple effect
|
||||
menuIconFg: #6c7883; // default popup menu item icon (like main menu)
|
||||
menuIconFgOver: #dcdcdc; // default popup menu item icon with mouse over
|
||||
menuSubmenuArrowFg: #637c95; // default popup menu submenu arrow icon (like in message field context menu in case of RTL system language)
|
||||
menuFgDisabled: #3d4e5c; // default popup menu item disabled text (like unavailable items in message field context menu)
|
||||
menuSeparatorFg: #232f39; // default popup menu separator (like in message field context menu)
|
||||
scrollBarBg: #ffffff53; // default scroll bar current rectangle, the bar itself (like in chats list)
|
||||
scrollBarBgOver: #ffffff7a; // default scroll bar current rectangle with mouse over it
|
||||
scrollBg: #ffffff1a; // default scroll bar background
|
||||
scrollBgOver: #ffffff2c; // default scroll bar background with mouse over the scroll bar
|
||||
smallCloseIconFg: #55616c; // small X icon (like in Show all sessions box to the right for sessions termination)
|
||||
smallCloseIconFgOver: #a3a3a3; // small X icon with mouse over
|
||||
radialFg: windowFgActive; // default radial loader line (like in Media Viewer when loading a photo)
|
||||
radialBg: #00000056; // default radial loader background (like in Media Viewer when loading a photo)
|
||||
placeholderFg: #6d7883; // default input field placeholder when field is not focused (like in phone input field when you log in)
|
||||
placeholderFgActive: #4f5b67; // default input field placeholder when field is focused
|
||||
inputBorderFg: #313c49; // default input field bottom border (like in code input field when you log in and field is not focused)
|
||||
filterInputBorderFg: #242f3d; // default rounded input field border (like in chats list search field when field is focused)
|
||||
filterInputInactiveBg: #242f3d; // default rounded input field background (like in chats list search field when field is inactive)
|
||||
checkboxFg: #4f6276; // default unchecked checkbox rounded rectangle (and also emoji category icons)
|
||||
sliderBgInactive: #364554; // default slider not active bar (like in Settings when you choose interface scale or custom notifications count)
|
||||
sliderBgActive: #4a81bc; // default slider active bar (like in Settings when you choose interface scale or custom notifications count)
|
||||
tooltipBg: #16222d; // tooltip background (like when you put mouse over the message timestamp and wait)
|
||||
tooltipFg: #d4e0ea; // tooltip text
|
||||
tooltipBorderFg: #16222d; // tooltip border
|
||||
titleShadow: #00000000; // one pixel line shadow at the bottom of custom window title
|
||||
titleBg: #1f2936; // custom window title background when window is inactive
|
||||
titleBgActive: #242f3d; // custom window title background when window is active
|
||||
titleButtonBg: titleBg; // custom window title minimize/maximize/restore button background when window is inactive (Windows only)
|
||||
titleButtonFg: #576673; // custom window title minimize/maximize/restore button icon when window is inactive (Windows only)
|
||||
titleButtonBgOver: #25303e; // custom window title minimize/maximize/restore button background with mouse over when window is inactive (Windows only)
|
||||
titleButtonFgOver: #e0e0e0; // custom window title minimize/maximize/restore button icon with mouse over when window is inactive (Windows only)
|
||||
titleButtonBgActive: #242f3d; // custom window title minimize/maximize/restore button background when window is active (Windows only)
|
||||
titleButtonFgActive: titleButtonFg; // custom window title minimize/maximize/restore button icon when window is active (Windows only)
|
||||
titleButtonBgActiveOver: #2c3847; // custom window title minimize/maximize/restore button background with mouse over when window is active (Windows only)
|
||||
titleButtonFgActiveOver: titleButtonFgOver; // custom window title minimize/maximize/restore button icon with mouse over when window is active (Windows only)
|
||||
titleButtonCloseBg: titleButtonBg; // custom window title close button background when window is inactive (Windows only)
|
||||
titleButtonCloseFg: titleButtonFg; // custom window title close button icon when window is inactive (Windows only)
|
||||
titleButtonCloseBgOver: #e92539; // custom window title close button background with mouse over when window is inactive (Windows only)
|
||||
titleButtonCloseFgOver: windowFgActive; // custom window title close button icon with mouse over when window is inactive (Windows only)
|
||||
titleButtonCloseBgActive: #242f3d; // custom window title close button background when window is active (Windows only)
|
||||
titleButtonCloseFgActive: titleButtonCloseFg; // custom window title close button icon when window is active (Windows only)
|
||||
titleButtonCloseBgActiveOver: #e92539; // custom window title close button background with mouse over when window is active (Windows only)
|
||||
titleButtonCloseFgActiveOver: titleButtonCloseFgOver; // custom window title close button icon with mouse over when window is active (Windows only)
|
||||
titleFg: #6a7680; // custom window title text when window is inactive (macOS only)
|
||||
titleFgActive: #91a3b3; // custom window title text when window is active (macOS only)
|
||||
trayCounterBg: #f23c34; // tray icon counter background
|
||||
trayCounterBgMute: #888888; // tray icon counter background if all unread messages are muted
|
||||
trayCounterFg: #ffffff; // tray icon counter text
|
||||
trayCounterBgMacInvert: #ffffff; // tray icon counter background when tray icon is pressed or when dark theme of macOS is used (macOS only)
|
||||
trayCounterFgMacInvert: #ffffff01; // tray icon counter text when tray icon is pressed or when dark theme of macOS is used (macOS only)
|
||||
layerBg: #0000007f; // box and main menu background layer fade
|
||||
cancelIconFg: #737e87; // default for settings close icon and box search cancel icon
|
||||
cancelIconFgOver: #dcdcdc; // default for settings close icon and box search cancel icon with mouse over
|
||||
boxBg: #17212b; // box background
|
||||
boxTextFg: windowFg; // box text
|
||||
boxTextFgGood: #5598db; // accepted box text (like when choosing username that is not occupied)
|
||||
boxTextFgError: #dc3d3d; // rejecting box text (like when choosing username that is occupied)
|
||||
boxTitleFg: #ebebeb; // box title text
|
||||
boxSearchBg: #17212b; // box search field background (like in contacts box)
|
||||
boxTitleAdditionalFg: #6d7f8f; // box title additional text (like in create group box when you see chosen members count)
|
||||
boxTitleCloseFg: cancelIconFg; // settings close icon and box search cancel icon (like in contacts box)
|
||||
boxTitleCloseFgOver: cancelIconFgOver; // settings close icon and box search cancel icon (like in contacts box) with mouse over
|
||||
membersAboutLimitFg: #677a8b; // text in channel members box about the limit (max 200 last members are shown)
|
||||
contactsBg: #17212b; // contacts (and some other) box row background
|
||||
contactsBgOver: #1f2c39; // contacts (and some other) box row background with mouse over
|
||||
contactsNameFg: boxTextFg; // contacts (and some other) box row name text
|
||||
contactsStatusFg: #677a8b; // contacts (and some other) box row additional text (like last seen stamp)
|
||||
contactsStatusFgOver: #677a8b; // contacts (and some other) box row additional text (like last seen stamp) with mouse over
|
||||
contactsStatusFgOnline: #559be0; // contacts (and some other) box row active additional text (like online status)
|
||||
photoCropFadeBg: layerBg; // avatar crop box fade background (when choosing a new photo in Settings or for a group)
|
||||
photoCropPointFg: #ffffff7f; // avatar crop box corner rectangles (when choosing a new photo in Settings or for a group)
|
||||
callArrowFg: #49a2f0; // received phone call arrow (in calls list box)
|
||||
callArrowMissedFg: #ed5050; // missed phone call arrow (in calls list box)
|
||||
introBg: windowBg; // login background
|
||||
introTitleFg: #eeeeee; // login title text
|
||||
introDescriptionFg: #72879b; // login description text
|
||||
introErrorFg: #e94040; // login error text (like when providing a wrong log in code)
|
||||
introCoverTopBg: #124a82; // intro gradient top (from)
|
||||
introCoverBottomBg: #23659f; // intro gradient bottom (to)
|
||||
introCoverIconsFg: #3b7cbd; // intro cloud graphics
|
||||
introCoverPlaneTrace: #3870a8; // intro plane traces
|
||||
introCoverPlaneInner: #ced9e2; // intro plane part
|
||||
introCoverPlaneOuter: #97a9b5; // intro plane part
|
||||
introCoverPlaneTop: #ffffff; // intro plane part
|
||||
dialogsMenuIconFg: menuIconFg; // main menu and lock telegram icon
|
||||
dialogsMenuIconFgOver: menuIconFgOver; // main menu and lock telegram icon with mouse over
|
||||
dialogsBg: windowBg; // chat list background
|
||||
dialogsNameFg: #f5f5f5; // chat list name text
|
||||
dialogsChatIconFg: dialogsNameFg; // chat list group or channel icon
|
||||
dialogsDateFg: #8696a8; // chat list date text
|
||||
dialogsTextFg: #7f91a4; // chat list message text
|
||||
dialogsTextFgService: #73b9f5; // chat list group sender name text (or media message type text)
|
||||
dialogsDraftFg: #ff525d; // chat list draft label
|
||||
dialogsVerifiedIconBg: #6ab3f3; // chat list verified icon background
|
||||
dialogsVerifiedIconFg: #17212b; // chat list verified icon check
|
||||
dialogsSendingIconFg: #647d96; // chat list sending message icon (clock)
|
||||
dialogsSentIconFg: #72bcfd; // chat list sent message tick / double tick icon
|
||||
dialogsUnreadBg: #4082bc; // chat list unread badge background for not muted chat
|
||||
dialogsUnreadBgMuted: #3e546a; // chat list unread badge background for muted chat
|
||||
dialogsUnreadFg: #ffffff; // chat list unread badge text
|
||||
dialogsBgOver: #202b36; // chat list background with mouse over
|
||||
dialogsOnlineBadgeFg: #63b6ff; // chat list online status
|
||||
dialogsNameFgOver: windowBoldFgOver; // chat list name text with mouse over
|
||||
dialogsChatIconFgOver: dialogsNameFgOver; // chat list group or channel icon with mouse over
|
||||
dialogsDateFgOver: #8495a9; // chat list date text with mouse over
|
||||
dialogsTextFgOver: #91a3b5; // chat list message text with mouse over
|
||||
dialogsTextFgServiceOver: #73b9f5; // chat list group sender name text with mouse over
|
||||
dialogsDraftFgOver: dialogsDraftFg; // chat list draft label with mouse over
|
||||
dialogsVerifiedIconBgOver: #6ab3f3; // chat list verified icon background with mouse over
|
||||
dialogsVerifiedIconFgOver: dialogsVerifiedIconFg; // chat list verified icon check with mouse over
|
||||
dialogsSendingIconFgOver: dialogsSendingIconFg; // chat list sending message icon (clock) with mouse over
|
||||
dialogsSentIconFgOver: #72bcfd; // chat list sent message tick / double tick icon with mouse over
|
||||
dialogsUnreadBgOver: #4082bc; // chat list unread badge background for not muted chat with mouse over
|
||||
dialogsUnreadBgMutedOver: #4d5762; // chat list unread badge background for muted chat with mouse over
|
||||
dialogsUnreadFgOver: dialogsUnreadFg; // chat list unread badge text with mouse over
|
||||
dialogsBgActive: #2b5278; // chat list background for current (active) chat
|
||||
dialogsNameFgActive: windowFgActive; // chat list name text for current (active) chat
|
||||
dialogsChatIconFgActive: dialogsNameFgActive; // chat list group or channel icon for current (active) chat
|
||||
dialogsDateFgActive: windowFgActive; // chat list date text for current (active) chat
|
||||
dialogsTextFgActive: windowFgActive; // chat list message text for current (active) chat
|
||||
dialogsTextFgServiceActive: dialogsTextFgActive; // chat list group sender name text for current (active) chat
|
||||
dialogsDraftFgActive: #a9caf0; // chat list draft label for current (active) chat
|
||||
dialogsVerifiedIconBgActive: dialogsTextFgActive; // chat list verified icon background for current (active) chat
|
||||
dialogsVerifiedIconFgActive: dialogsBgActive; // chat list verified icon check for current (active) chat
|
||||
dialogsSendingIconFgActive: #ffffff99; // chat list sending message icon (clock) for current (active) chat
|
||||
dialogsSentIconFgActive: dialogsTextFgActive; // chat list sent message tick / double tick icon for current (active) chat
|
||||
dialogsUnreadBgActive: dialogsTextFgActive; // chat list unread badge background for not muted chat for current (active) chat
|
||||
dialogsUnreadBgMutedActive: #7aa3ca; // chat list unread badge background for muted chat for current (active) chat
|
||||
dialogsUnreadFgActive: #2a5378; // chat list unread badge text for current (active) chat
|
||||
dialogsOnlineBadgeFgActive: #ffffff; // chat list online status for current (active) chat
|
||||
dialogsRippleBg: #25313d; //
|
||||
dialogsRippleBgActive: #315a80; //
|
||||
dialogsForwardBg: dialogsBgActive; // forwarding panel background (when forwarding messages in the smallest window size)
|
||||
dialogsForwardFg: dialogsNameFgActive; // forwarding panel text (when forwarding messages in the smallest window size)
|
||||
searchedBarBg: #202b38; // search results bar background (in chats list, contacts box..)
|
||||
searchedBarFg: #8c98a4; // search results bar text (in chats list, contacts box..)
|
||||
topBarBg: #17212b; // top bar background (in chat view, media overview..)
|
||||
emojiPanBg: windowBg; // emoji panel background
|
||||
emojiPanCategories: #17212b; // emoji panel categories background
|
||||
emojiPanHeaderFg: #7c8d9e; // emoji panel section header text
|
||||
emojiPanHeaderBg: #fffffff2; // emoji panel section header background
|
||||
stickerPanDeleteBg: #000000cc; // delete X button background for custom sent stickers in stickers panel (legacy)
|
||||
stickerPanDeleteFg: windowFgActive; // delete X button icon for custom sent stickers in stickers panel (legacy)
|
||||
stickerPreviewBg: #000000b0; // sticker and GIF preview background (when you press and hold on a sticker)
|
||||
historyTextInFg: windowFg; // inbox message text
|
||||
historyTextInFgSelected: #ffffff; // inbox message selected text or text in a selected message
|
||||
historyTextOutFg: #e4ecf2; // outbox message text
|
||||
historyTextOutFgSelected: #ffffff; // outbox message selected text or text in a selected message
|
||||
historyLinkInFg: #70baf5; // inbox message link
|
||||
historyLinkInFgSelected: #aadcff; // inbox message link in a selected text or message
|
||||
historyLinkOutFg: #83caff; // outbox message link
|
||||
historyLinkOutFgSelected: #aadcff; // outbox message link in a selected text or message
|
||||
historyFileNameInFg: historyTextInFg; // inbox media filename text
|
||||
historyFileNameInFgSelected: #ffffff; // inbox media filename text in a selected message
|
||||
historyFileNameOutFg: historyTextOutFg; // outbox media filename text
|
||||
historyFileNameOutFgSelected: #ffffff; // outbox media filename text in a selected message
|
||||
historyOutIconFg: #6bbfff; // outbox message tick / double tick icon
|
||||
historyOutIconFgSelected: #ffffff; // outbox message tick / double tick icon in a selected message
|
||||
historyIconFgInverted: #ffffffe5; // media message tick / double tick icon (like in sent photo)
|
||||
historySendingOutIconFg: #70a4d2; // outbox sending message icon (clock)
|
||||
historySendingInIconFg: #76838b; // inbox sending message icon (clock) (like in sent messages to yourself or in sent messages to a channel)
|
||||
historySendingInvertedIconFg: #ffffffc8; // media sending message icon (clock) (like in sent photo)
|
||||
historyCallArrowInFg: #5093d6; // received phone call arrow
|
||||
historyCallArrowInFgSelected: #ffffff; // received phone call arrow in a selected message
|
||||
historyCallArrowMissedInFg: callArrowMissedFg; // missed phone call arrow
|
||||
historyCallArrowMissedInFgSelected: #ffffff; // missed phone call arrow in a selected message
|
||||
historyCallArrowOutFg: #ffffff; // outgoing phone call arrow
|
||||
historyCallArrowOutFgSelected: #ffffff; // outgoing phone call arrow
|
||||
historyUnreadBarBg: #182433; // new unread messages bar background
|
||||
historyUnreadBarBorder: #03080d00; // new unread messages bar shadow
|
||||
historyUnreadBarFg: #ffffff; // new unread messages bar text
|
||||
historyForwardChooseBg: #0000004c; // forwarding messages in a large window size "choose recipient" background
|
||||
historyForwardChooseFg: windowFgActive; // forwarding messages in a large window size "choose recipient" text
|
||||
historyPeer1NameFg: #fb6169; // red group member name
|
||||
historyPeer1NameFgSelected: #ffffff; // red group member name in a selected message
|
||||
historyPeer1UserpicBg: #ff845e; // red userpic background
|
||||
historyPeer2NameFg: #85de85; // green group member name
|
||||
historyPeer2NameFgSelected: #ffffff; // green group member name in a selected message
|
||||
historyPeer2UserpicBg: #9ad164; // green userpic background
|
||||
historyPeer3NameFg: #f3bc5c; // yellow group member name
|
||||
historyPeer3NameFgSelected: #ffffff; // yellow group member name in a selected message
|
||||
historyPeer3UserpicBg: #e5ca77; // yellow userpic background (actually unused)
|
||||
historyPeer4NameFg: #65bdf3; // blue group member name
|
||||
historyPeer4NameFgSelected: #ffffff; // blue group member name in a selected message
|
||||
historyPeer4UserpicBg: #5caffa; // blue userpic background
|
||||
historyPeer5NameFg: #b48bf2; // purple group member name
|
||||
historyPeer5NameFgSelected: #ffffff; // purple group member name in a selected message
|
||||
historyPeer5UserpicBg: #b694f9; // purple userpic background
|
||||
historyPeer6NameFg: #ff5694; // pink group member name
|
||||
historyPeer6NameFgSelected: #ffffff; // pink group member name in a selected message
|
||||
historyPeer6UserpicBg: #ff8aac; // pink userpic background
|
||||
historyPeer7NameFg: #62d4e3; // sea group member name
|
||||
historyPeer7NameFgSelected: #ffffff; // sea group member name in a selected message
|
||||
historyPeer7UserpicBg: #5bcbe3; // sea userpic background
|
||||
historyPeer8NameFg: #faa357; // orange group member name
|
||||
historyPeer8NameFgSelected: #ffffff; // orange group member name in a selected message
|
||||
historyPeer8UserpicBg: #febb5b; // orange userpic background
|
||||
historyPeerUserpicFg: windowFgActive; // default userpic initials
|
||||
historyPeer1UserpicBg2: #d45246; // the second red userpic background
|
||||
historyPeer2UserpicBg2: #46ba43; // the second green userpic background
|
||||
historyPeer3UserpicBg2: #e5ca77; // the second yellow userpic background (actually unused)
|
||||
historyPeer4UserpicBg2: #408acf; // the second blue userpic background
|
||||
historyPeer5UserpicBg2: #6c61df; // the second purple userpic background
|
||||
historyPeer6UserpicBg2: #d95574; // the second pink userpic background
|
||||
historyPeer7UserpicBg2: #359ad4; // the second sea userpic background
|
||||
historyPeer8UserpicBg2: #f68136; // the second orange userpic background
|
||||
historyPeerSavedMessagesBg2: historyPeer4UserpicBg2; // the second saved messages userpic background
|
||||
historyScrollBarBg: #7f84897a; // scroll bar current rectangle, the bar itself in the chat view (adjusted)
|
||||
historyScrollBarBgOver: #64686cbc; // scroll bar current rectangle with mouse over it in the chat view (adjusted)
|
||||
historyScrollBg: #565a5e4c; // scroll bar background (adjusted)
|
||||
historyScrollBgOver: #5a5d616b; // scroll bar background with mouse over the scroll bar (adjusted)
|
||||
msgInBg: #182533; // inbox message background
|
||||
msgInBgSelected: #2e70a5; // inbox selected message background (and background of selected text in those messages)
|
||||
msgOutBg: #2b5278; // outbox message background
|
||||
msgOutBgSelected: #2e70a5; // outbox selected message background (and background of selected text in those messages)
|
||||
msgSelectOverlay: #3585d44c; // overlay which is filling the media parts of selected messages (like in selected photo message)
|
||||
msgStickerOverlay: #3585d47f; // overlay which is filling the selected sticker message
|
||||
msgInServiceFg: #71bafa; // inbox message information text (like information about a forwarded message original sender)
|
||||
msgInServiceFgSelected: #ffffff; // inbox selected message information text (like information about a forwarded message original sender)
|
||||
msgOutServiceFg: #90caff; // outbox message information text (like information about a forwarded message original sender)
|
||||
msgOutServiceFgSelected: #ffffff; // outbox message information text (like information about a forwarded message original sender)
|
||||
msgInShadow: #748ea200; // inbox message shadow (below the bubble)
|
||||
msgInShadowSelected: #538ebb00; // inbox selected message shadow (below the bubble)
|
||||
msgOutShadow: #00000000; // outbox message shadow (below the bubble)
|
||||
msgOutShadowSelected: #366ea600; // outbox selected message shadow (below the bubble)
|
||||
msgInDateFg: #6d7f8f; // inbox message time text
|
||||
msgInDateFgSelected: #ffffff; // inbox selected message time text
|
||||
msgOutDateFg: #7da8d3; // outbox message time text
|
||||
msgOutDateFgSelected: #ffffff; // outbox selected message time text
|
||||
msgServiceFg: windowFgActive; // service message text (like date dividers or service message about the group title being changed)
|
||||
msgServiceBg: #213040d5; // service message background (like in a service message about group title being changed) (adjusted)
|
||||
msgServiceBgSelected: #2e7ab4; // service message selected text background (like in a service message about group title being changed) (adjusted)
|
||||
msgInReplyBarColor: #429bdb; // inbox message reply outline
|
||||
msgInReplyBarSelColor: #ffffff; // inbox selected message reply outline
|
||||
msgOutReplyBarColor: #65b9f4; // outbox message reply outline
|
||||
msgOutReplyBarSelColor: #ffffff; // outbox selected message reply outline
|
||||
msgImgReplyBarColor: msgServiceFg; // sticker message reply outline
|
||||
msgInMonoFg: #5a8cb7; // inbox message monospace text (like a message sent with `test` text)
|
||||
msgOutMonoFg: #aed1f3; // outbox message monospace text
|
||||
msgInMonoFgSelected: #a3cdf7; // inbox message monospace text in a selected text or message
|
||||
msgOutMonoFgSelected: #a3cdf7; // outbox message monospace text in a selected text or message
|
||||
msgDateImgFg: #fffffff2; // media message time text (like time text in a sent photo)
|
||||
msgDateImgBg: #00000054; // media message time bubble background (like time bubble in a sent photo) or file with thumbnail download icon circle background
|
||||
msgDateImgBgOver: #00000074; // media message download icon circle background with mouse over (like file with thumbnail download icon)
|
||||
msgDateImgBgSelected: #204f7887; // selected media message time bubble background
|
||||
msgFileThumbLinkInFg: lightButtonFg; // inbox media file message with thumbnail download / open with button text
|
||||
msgFileThumbLinkInFgSelected: #ffffff; // inbox selected media file message with thumbnail download / open with button text
|
||||
msgFileThumbLinkOutFg: #6c9ecf; // outbox media file message with thumbnail download / open with button text
|
||||
msgFileThumbLinkOutFgSelected: #ffffff; // outbox selected media file message with thumbnail download / open with button text
|
||||
msgFileInBg: #3f96d0; // inbox audio file download circle background
|
||||
msgFileInBgOver: #489ed7; // inbox audio file download circle background with mouse over
|
||||
msgFileInBgSelected: #6ab4f4; // inbox selected audio file download circle background
|
||||
msgFileOutBg: #4c9ce2; // outbox audio file download circle background
|
||||
msgFileOutBgOver: #54a4e9; // outbox audio file download circle background with mouse over
|
||||
msgFileOutBgSelected: #58abf3; // outbox selected audio file download circle background
|
||||
msgFile1Bg: #3e7eba; // blue shared links / files without image square thumbnail
|
||||
msgFile1BgDark: #24679e; // blue shared files without image download circle background
|
||||
msgFile1BgOver: #1d5e93; // blue shared files without image download circle background with mouse over
|
||||
msgFile1BgSelected: #ffffff; // blue shared files without image download circle background if file is selected
|
||||
msgFile2Bg: #3ea34a; // green shared links / shared files without image square thumbnail
|
||||
msgFile2BgDark: #298835; // green shared files without image download circle background
|
||||
msgFile2BgOver: #1b7725; // green shared files without image download circle background with mouse over
|
||||
msgFile2BgSelected: #1b7725; // green shared files without image download circle background if file is selected
|
||||
msgFile3Bg: #d6454c; // red shared links / shared files without image square thumbnail
|
||||
msgFile3BgDark: #bf333a; // red shared files without image download circle background
|
||||
msgFile3BgOver: #b2282f; // red shared files without image download circle background with mouse over
|
||||
msgFile3BgSelected: #b2282f; // red shared files without image download circle background if file is selected
|
||||
msgFile4Bg: #d99546; // yellow shared links / shared files without image square thumbnail
|
||||
msgFile4BgDark: #c17d39; // yellow shared files without image download circle background
|
||||
msgFile4BgOver: #ac6b29; // yellow shared files without image download circle background with mouse over
|
||||
msgFile4BgSelected: #ac6b29; // yellow shared files without image download circle background if file is selected
|
||||
historyFileInIconFg: #ffffff; // inbox file without thumbnail (like audio file) download arrow icon
|
||||
historyFileInIconFgSelected: #ffffff; // inbox selected file without thumbnail (like audio file) download arrow icon
|
||||
historyFileInRadialFg: #ffffff; // inbox file without thumbnail (like audio file) radial download animation line
|
||||
historyFileInRadialFgSelected: historyFileInIconFgSelected; // inbox selected file without thumbnail (like audio file) radial download animation line
|
||||
historyFileOutIconFg: #ffffff; // outbox file without thumbnail (like audio file) download arrow icon
|
||||
historyFileOutIconFgSelected: #ffffff; // outbox selected file without thumbnail (like audio file) download arrow icon
|
||||
historyFileOutRadialFg: #ffffff; // outbox file without thumbnail (like audio file) radial download animation line
|
||||
historyFileOutRadialFgSelected: #ffffff; // outbox selected file without thumbnail (like audio file) radial download animation line
|
||||
historyFileThumbIconFg: #efefef; // file with thumbnail (or photo / video) download arrow icon
|
||||
historyFileThumbIconFgSelected: #ffffff; // selected file with thumbnail (or photo / video) download arrow icon
|
||||
historyFileThumbRadialFg: historyFileThumbIconFg; // file with thumbnail (or photo / video) radial download animation line
|
||||
historyFileThumbRadialFgSelected: #ffffff; // selected file with thumbnail (or photo / video) radial download animation line
|
||||
historyVideoMessageProgressFg: historyFileThumbIconFg; // radial playback progress in round video messages
|
||||
msgWaveformInActive: #549cd7; // inbox voice message active waveform lines (like played part of currently playing voice message)
|
||||
msgWaveformInActiveSelected: #ffffff; // inbox selected voice message active waveform lines (like played part of currently playing voice message)
|
||||
msgWaveformInInactive: #3a4d61; // inbox voice message inactive waveform lines (like upcoming part of currently playing voice message)
|
||||
msgWaveformInInactiveSelected: #6fa5d4; // inbox selected voice message inactive waveform lines (like upcoming part of currently playing voice message)
|
||||
msgWaveformOutActive: #62b2fd; // outbox voice message active waveform lines (like played part of currently playing voice message)
|
||||
msgWaveformOutActiveSelected: #ffffff; // outbox selected voice message active waveform lines (like played part of currently playing voice message)
|
||||
msgWaveformOutInactive: #4b7fb3; // outbox voice message inactive waveform lines (like upcoming part of currently playing voice message)
|
||||
msgWaveformOutInactiveSelected: #6fa5d4; // outbox selected voice message inactive waveform lines (like upcoming part of currently playing voice message)
|
||||
msgBotKbOverBgAdd: #80b1db0f; // this is painted over a bot inline keyboard button (which has msgServiceBg background) when mouse is over that button
|
||||
msgBotKbIconFg: msgServiceFg; // bot inline keyboard button icon in the top-right corner (like in @vote bot when a poll is ready to be shared)
|
||||
msgBotKbRippleBg: #92c0e50b; // bot inline keyboard button ripple effect
|
||||
mediaInFg: msgInDateFg; // inbox media message status text (like in file that is being downloaded)
|
||||
mediaInFgSelected: msgInDateFgSelected; // inbox selected media message status text (like in file that is being downloaded)
|
||||
mediaOutFg: msgOutDateFg; // outbox media message status text (like in file that is being downloaded)
|
||||
mediaOutFgSelected: msgOutDateFgSelected; // outbox selected media message status text (like in file that is being downloaded)
|
||||
youtubePlayIconBg: #e83131c8; // youtube play icon background (when a link to a youtube video with a webpage preview is sent)
|
||||
youtubePlayIconFg: windowFgActive; // youtube play icon arrow (when a link to a youtube video with a webpage preview is sent)
|
||||
videoPlayIconBg: #0000007f; // other video play icon background (like when a link to a vimeo video with a webpage preview is sent)
|
||||
videoPlayIconFg: #ffffff; // other video play icon arrow (like when a link to a vimeo video with a webpage preview is sent)
|
||||
toastBg: #000000b2; // toast notification background (like when you click on your t.me link when editing your username)
|
||||
toastFg: windowFgActive; // toast notification text (like when you click on your t.me link when editing your username)
|
||||
reportSpamBg: #363c42; // report spam panel background (like a non contact user writes your for the first time)
|
||||
reportSpamFg: windowFg; // report spam panel text (when you send a report from that panel)
|
||||
historyToDownBg: #1d2b3a; // arrow button background (to scroll to the end of the viewed chat)
|
||||
historyToDownBgOver: #243446; // arrow button background with mouse over
|
||||
historyToDownBgRipple: #2b3c4f; // arrow button ripple effect
|
||||
historyToDownFg: #adb4ba; // arrow button icon
|
||||
historyToDownFgOver: menuIconFgOver; // arrow button icon with mouse over
|
||||
historyToDownShadow: #00000040; // arrow button shadow
|
||||
historyComposeAreaBg: #17212b; // history compose area background (message write area / reply information / forwarding information)
|
||||
historyComposeAreaFg: historyTextInFg; // history compose area text
|
||||
historyComposeAreaFgService: msgInDateFg; // history compose area text when replying to a media message
|
||||
historyComposeIconFg: menuIconFg; // history compose area icon (like emoji, attach, bot command..)
|
||||
historyComposeIconFgOver: menuIconFgOver; // history compose area icon with mouse over
|
||||
historySendIconFg: windowBgActive; // send message icon
|
||||
historySendIconFgOver: windowBgActive; // send message icon with mouse over
|
||||
historyPinnedBg: #1b2734; // pinned message area background
|
||||
historyReplyBg: historyComposeAreaBg; // reply / forward / edit message area background
|
||||
historyReplyIconFg: windowBgActive; // reply / forward / edit message left icon
|
||||
historyReplyCancelFg: cancelIconFg; // reply / forward / edit message cancel button
|
||||
historyReplyCancelFgOver: cancelIconFgOver; // reply / forward / edit message cancel button with mouse over
|
||||
historyComposeButtonBg: historyComposeAreaBg; // unblock / join channel / mute channel button background
|
||||
historyComposeButtonBgOver: #1c2835; // unblock / join channel / mute channel button background with mouse over
|
||||
historyComposeButtonBgRipple: #222f3e; // unblock / join channel / mute channel button ripple effect
|
||||
overviewCheckBg: #00000040; // shared files / links checkbox background for not selected rows when some rows are selected
|
||||
overviewCheckFg: #ffffff; // shared files / links checkbox icon for not selected rows when some rows are selected
|
||||
overviewCheckFgActive: #ffffff; // shared files / links checkbox icon for selected rows
|
||||
overviewPhotoSelectOverlay: #3fa2e333; // shared photos / videos / links fill for selected rows
|
||||
profileStatusFgOver: #677a8b; // group members list in group profile user last seen text with mouse over
|
||||
profileVerifiedCheckBg: windowBgActive; // profile verified check icon background
|
||||
profileVerifiedCheckFg: #ffffff; // profile verified check icon tick
|
||||
profileAdminStartFg: #62a9e6; // group members list admin star icon
|
||||
notificationsBoxMonitorFg: windowFg; // custom notifications settings box monitor color
|
||||
notificationsBoxScreenBg: dialogsBgActive; // #6389a8; // custom notifications settings box monitor screen background
|
||||
notificationSampleUserpicFg: windowBgActive; // custom notifications settings box small sample userpic placeholder
|
||||
notificationSampleCloseFg: #d7d7d7; // custom notifications settings box small sample close button placeholder
|
||||
notificationSampleTextFg: #d7d7d7; // custom notifications settings box small sample text placeholder
|
||||
notificationSampleNameFg: #939393; // custom notifications settings box small sample name placeholder
|
||||
changePhoneSimcardFrom: notificationSampleTextFg; // change phone number box left simcard icon
|
||||
changePhoneSimcardTo: notificationSampleNameFg; // change phone number box right simcard and plane icons
|
||||
mainMenuBg: windowBg; // main menu background
|
||||
mainMenuCoverBg: #276899; // main menu top cover background
|
||||
mainMenuCoverFg: windowFgActive; // main menu top cover text
|
||||
mainMenuCloudFg: activeButtonFg; //
|
||||
mainMenuCloudBg: #185680; //
|
||||
mediaPlayerBg: windowBg; // audio file player background
|
||||
mediaPlayerActiveFg: windowBgActive; // audio file player playback progress already played part
|
||||
mediaPlayerInactiveFg: sliderBgInactive; // audio file player playback progress upcoming (not played yet) part with mouse over
|
||||
mediaPlayerDisabledFg: #9dd1ef; // audio file player loading progress (when you're playing an audio file and switch to the previous one which is not loaded yet)
|
||||
mediaviewFileBg: windowBg; // file rectangle background (when you view a png file in Media Viewer and go to a previous, not loaded yet, file)
|
||||
mediaviewFileNameFg: windowFg; // file name in file rectangle
|
||||
mediaviewFileSizeFg: windowSubTextFg; // file size text in file rectangle
|
||||
mediaviewFileRedCornerFg: #d55959; // red file thumbnail placeholder corner in file rectangle (for a file without thumbnail, like .pdf)
|
||||
mediaviewFileYellowCornerFg: #e8a659; // yellow file thumbnail placeholder corner in file rectangle (for a file without thumbnail, like .zip)
|
||||
mediaviewFileGreenCornerFg: #49a957; // green file thumbnail placeholder corner in file rectangle (for a file without thumbnail, like .exe)
|
||||
mediaviewFileBlueCornerFg: #599dcf; // blue file thumbnail placeholder corner in file rectangle (for a file without thumbnail, like .dmg)
|
||||
mediaviewFileExtFg: activeButtonFg; // file extension text in file thumbnail placeholder in file rectangle
|
||||
mediaviewMenuBg: #383838; // context menu in Media Viewer background
|
||||
mediaviewMenuBgOver: #505050; // context menu item background with mouse over
|
||||
mediaviewMenuBgRipple: #676767; // context menu item ripple effect
|
||||
mediaviewMenuFg: windowFgActive; // context menu item text
|
||||
mediaviewBg: #222222eb; // Media Viewer background
|
||||
mediaviewVideoBg: imageBg; // Media Viewer background when viewing a video in full screen
|
||||
mediaviewControlBg: #0000003c; // controls background (like next photo / previous photo)
|
||||
mediaviewControlFg: windowFgActive; // controls icon (like next photo / previous photo)
|
||||
mediaviewCaptionBg: #11111180; // caption text background (when viewing photo with caption)
|
||||
mediaviewCaptionFg: mediaviewControlFg; // caption text
|
||||
mediaviewTextLinkFg: #70baf5; // caption text link
|
||||
mediaviewSaveMsgBg: toastBg; // save to file toast message background in Media Viewer
|
||||
mediaviewSaveMsgFg: toastFg; // save to file toast message text
|
||||
mediaviewPlaybackActive: #c7c7c7; // video playback progress already played part
|
||||
mediaviewPlaybackInactive: #252525; // video playback progress upcoming (not played yet) part
|
||||
mediaviewPlaybackActiveOver: #ffffff; // video playback progress already played part with mouse over
|
||||
mediaviewPlaybackInactiveOver: #474747; // video playback progress upcoming (not played yet) part with mouse over
|
||||
mediaviewPlaybackProgressFg: #ffffffc7; // video playback progress text
|
||||
mediaviewPlaybackIconFg: mediaviewPlaybackActive; // video playback controls icon
|
||||
mediaviewPlaybackIconFgOver: mediaviewPlaybackActiveOver; // video playback controls icon with mouse over
|
||||
mediaviewTransparentBg: #ffffff; // transparent filling part (when viewing a transparent .png file in Media Viewer)
|
||||
mediaviewTransparentFg: #cccccc; // another transparent filling part
|
||||
notificationBg: windowBg; // custom notification window background
|
||||
callBg: #14191ff5; // phone call popup background
|
||||
callNameFg: #ffffff; // phone call popup name text
|
||||
callFingerprintBg: #00000066; // phone call popup emoji fingerprint background
|
||||
callStatusFg: #aaabac; // phone call popup status text
|
||||
callIconFg: #ffffff; // phone call popup answer, hangup and mute mic icon
|
||||
callAnswerBg: #488fc9; // phone call popup answer button background
|
||||
callAnswerRipple: #4286c2; // phone call popup answer button ripple effect
|
||||
callAnswerBgOuter: #3f95eb26; // phone call popup answer button outer ripple effect
|
||||
callHangupBg: #cc4646; // phone call popup hangup button background
|
||||
callHangupRipple: #ca4141; // phone call popup hangup button ripple effect
|
||||
callCancelBg: #ffffff; // phone call popup line busy cancel button background
|
||||
callCancelFg: #536271; // phone call popup line busy cancel button icon
|
||||
callCancelRipple: #435363; // phone call popup line busy cancel button ripple effect
|
||||
callMuteRipple: #ffffff12; // phone call popup mute mic ripple effect
|
||||
callBarBg: #366693; // active phone call bar background
|
||||
callBarMuteRipple: #4b7dab; // active phone call bar mute and hangup button ripple effect
|
||||
callBarBgMuted: #35495d; // phone call bar with muted mic background
|
||||
callBarUnmuteRipple: #435b73; // phone call bar with muted mic mute and hangup button ripple effect
|
||||
callBarFg: dialogsNameFgActive; // phone call bar text and icons
|
||||
importantTooltipBg: toastBg; //
|
||||
importantTooltipFg: toastFg; //
|
||||
importantTooltipFgLink: #65b6fc; //
|
||||
filterInputActiveBg: #242f3d; // default rounded input field active background (like in chats list search field when field is focused)
|
||||
botKbBg: #242f3d; // bot keyboard button background
|
||||
botKbDownBg: #2d3a49; // bot keyboard button ripple effect
|
||||
emojiIconFg: #6c7883; // emoji category icon
|
||||
emojiIconFgActive: #51a0e5; // active emoji category icon
|
||||
overviewCheckBorder: #e4eaef; // shared media round checkbox border
|
||||
sideBarBg: #0e1621; // filters side bar background
|
||||
sideBarBgActive: #25303e; // filters side bar active background
|
||||
sideBarBgRipple: #1e2733; // filters side bar ripple effect
|
||||
sideBarTextFg: #768c9e; // filters side bar text
|
||||
sideBarTextFgActive: #64b9fa; // filters side bar active item text
|
||||
sideBarIconFg: #768c9e; // filters side bar icon
|
||||
sideBarIconFgActive: #5eb5f7; // filters side bar active item icon
|
||||
sideBarBadgeBg: #5eb5f7; // filters side bar badge background
|
||||
sideBarBadgeBgMuted: #768c9e; // filters side bar unimportant badge background
|
||||
statisticsChartInactive: #313d4cc8; // inactive area in footer of statistic charts
|
||||
statisticsChartActive: #526679d8; // sides in footer of statistic charts
|
||||
@@ -0,0 +1,710 @@
|
||||
{
|
||||
"$schema": "vscode://schemas/color-theme",
|
||||
"name": "2026 Dark",
|
||||
"include": "./dark_modern.json",
|
||||
"type": "dark",
|
||||
"colors": {
|
||||
"foreground": "#bfbfbf",
|
||||
"disabledForeground": "#555555",
|
||||
"errorForeground": "#f48771",
|
||||
"descriptionForeground": "#8C8C8C",
|
||||
"icon.foreground": "#8C8C8C",
|
||||
"focusBorder": "#3994BCB3",
|
||||
"textBlockQuote.background": "#242526",
|
||||
"textBlockQuote.border": "#2A2B2C",
|
||||
"textCodeBlock.background": "#242526",
|
||||
"textLink.foreground": "#48A0C7",
|
||||
"textLink.activeForeground": "#53A5CA",
|
||||
"textPreformat.background": "#262626",
|
||||
"textPreformat.foreground": "#8C8C8C",
|
||||
"textSeparator.foreground": "#2a2a2a",
|
||||
"button.background": "#297AA0",
|
||||
"button.foreground": "#FFFFFF",
|
||||
"button.hoverBackground": "#2B7DA3",
|
||||
"button.border": "#297AA0",
|
||||
"button.secondaryHoverBackground": "#FFFFFF10",
|
||||
"button.secondaryBorder": "#333536",
|
||||
"checkbox.background": "#242526",
|
||||
"checkbox.border": "#707070",
|
||||
"checkbox.foreground": "#8C8C8C",
|
||||
"dropdown.background": "#191A1B",
|
||||
"dropdown.border": "#333536",
|
||||
"dropdown.foreground": "#bfbfbf",
|
||||
"dropdown.listBackground": "#191A1B",
|
||||
"input.background": "#191A1B",
|
||||
"input.border": "#333536",
|
||||
"input.foreground": "#bfbfbf",
|
||||
"input.placeholderForeground": "#555555",
|
||||
"inputOption.activeBackground": "#313233",
|
||||
"inputOption.activeForeground": "#bfbfbf",
|
||||
"inputOption.activeBorder": "#2A2B2C",
|
||||
"inputValidation.infoBackground": "#1E3A47",
|
||||
"inputValidation.infoBorder": "#3994BC",
|
||||
"inputValidation.infoForeground": "#bfbfbf",
|
||||
"inputValidation.warningBackground": "#352A05",
|
||||
"inputValidation.warningBorder": "#B89500",
|
||||
"inputValidation.warningForeground": "#bfbfbf",
|
||||
"inputValidation.errorBackground": "#3A1D1D",
|
||||
"inputValidation.errorBorder": "#BE1100",
|
||||
"inputValidation.errorForeground": "#bfbfbf",
|
||||
"scrollbar.shadow": "#191B1D4D",
|
||||
"scrollbarSlider.background": "#A8A9AA85",
|
||||
"scrollbarSlider.hoverBackground": "#A8A9AA90",
|
||||
"scrollbarSlider.activeBackground": "#A8A9AA9C",
|
||||
"badge.background": "#307E9F",
|
||||
"badge.foreground": "#FFFFFF",
|
||||
"progressBar.background": "#878889",
|
||||
"list.activeSelectionBackground": "#FFFFFF22",
|
||||
"list.activeSelectionForeground": "#ededed",
|
||||
"list.inactiveSelectionBackground": "#2C2D2E",
|
||||
"list.inactiveSelectionForeground": "#ededed",
|
||||
"list.hoverBackground": "#FFFFFF14",
|
||||
"list.hoverForeground": "#bfbfbf",
|
||||
"list.dropBackground": "#3994BC1A",
|
||||
"toolbar.activeBackground": "#FFFFFF33",
|
||||
"list.focusBackground": "#FFFFFF22",
|
||||
"list.focusForeground": "#bfbfbf",
|
||||
"list.focusOutline": "#3994BCB3",
|
||||
"list.highlightForeground": "#48A0C7",
|
||||
"list.invalidItemForeground": "#444444",
|
||||
"list.errorForeground": "#f48771",
|
||||
"list.warningForeground": "#e5ba7d",
|
||||
"activityBar.background": "#191A1B",
|
||||
"activityBar.foreground": "#bfbfbf",
|
||||
"activityBar.inactiveForeground": "#8C8C8C",
|
||||
"activityBar.activeBackground": "#313233",
|
||||
"activityBar.border": "#2A2B2C",
|
||||
"activityBar.activeBorder": "#bfbfbf",
|
||||
"activityBar.activeFocusBorder": "#3994BCB3",
|
||||
"activityBarBadge.background": "#307E9F",
|
||||
"activityBarBadge.foreground": "#FFFFFF",
|
||||
"activityBarTop.activeBorder": "#bfbfbf",
|
||||
"sideBar.background": "#191A1B",
|
||||
"sideBar.foreground": "#bfbfbf",
|
||||
"sideBar.border": "#2A2B2C",
|
||||
"sideBarTitle.foreground": "#bfbfbf",
|
||||
"sideBarSectionHeader.background": "#191A1B",
|
||||
"sideBarSectionHeader.foreground": "#bfbfbf",
|
||||
"sideBarSectionHeader.border": "#2A2B2C",
|
||||
"titleBar.activeBackground": "#191A1B",
|
||||
"titleBar.activeForeground": "#8C8C8C",
|
||||
"titleBar.inactiveBackground": "#121314",
|
||||
"titleBar.inactiveForeground": "#8C8C8C",
|
||||
"titleBar.border": "#2A2B2C",
|
||||
"menubar.selectionBackground": "#242526",
|
||||
"menubar.selectionForeground": "#bfbfbf",
|
||||
"menu.background": "#202122",
|
||||
"menu.foreground": "#bfbfbf",
|
||||
"menu.selectionBackground": "#3994BC26",
|
||||
"menu.selectionForeground": "#bfbfbf",
|
||||
"menu.selectionBorder": "#3994BC",
|
||||
"menu.separatorBackground": "#2A2B2C",
|
||||
"menu.border": "#2A2B2C",
|
||||
"commandCenter.foreground": "#bfbfbf",
|
||||
"commandCenter.activeForeground": "#bfbfbf",
|
||||
"commandCenter.background": "#191A1B",
|
||||
"commandCenter.activeBackground": "#FFFFFF0F",
|
||||
"commandCenter.border": "#2E3031",
|
||||
"editor.background": "#121314",
|
||||
"editor.foreground": "#BBBEBF",
|
||||
"editorStickyScroll.background": "#121314",
|
||||
"editorStickyScrollHover.background": "#202122",
|
||||
"editorStickyScroll.border": "#2A2B2C",
|
||||
"editorLineNumber.foreground": "#858889",
|
||||
"editorLineNumber.activeForeground": "#BBBEBF",
|
||||
"editorCursor.foreground": "#BBBEBF",
|
||||
"editor.selectionBackground": "#276782dd",
|
||||
"editor.inactiveSelectionBackground": "#27678260",
|
||||
"editor.selectionHighlightBackground": "#27678260",
|
||||
"editor.wordHighlightBackground": "#27678250",
|
||||
"editor.wordHighlightStrongBackground": "#27678280",
|
||||
"editor.findMatchBackground": "#27678290",
|
||||
"editor.findMatchHighlightBackground": "#27678280",
|
||||
"editor.findRangeHighlightBackground": "#FFFFFF13",
|
||||
"editor.hoverHighlightBackground": "#FFFFFF13",
|
||||
"editor.lineHighlightBackground": "#242526",
|
||||
"editor.rangeHighlightBackground": "#FFFFFF13",
|
||||
"editorLink.activeForeground": "#3a94bc",
|
||||
"editorWhitespace.foreground": "#8C8C8C4D",
|
||||
"editorIndentGuide.background1": "#8384854D",
|
||||
"editorIndentGuide.activeBackground1": "#838485",
|
||||
"editorRuler.foreground": "#848484",
|
||||
"editorCodeLens.foreground": "#8C8C8C",
|
||||
"editorBracketMatch.background": "#3994BC55",
|
||||
"editorBracketMatch.border": "#2A2B2C",
|
||||
"editorWidget.background": "#202122",
|
||||
"editorWidget.border": "#2A2B2C",
|
||||
"editorWidget.foreground": "#bfbfbf",
|
||||
"editorSuggestWidget.background": "#202122",
|
||||
"editorSuggestWidget.border": "#2A2B2C",
|
||||
"editorSuggestWidget.foreground": "#bfbfbf",
|
||||
"editorSuggestWidget.highlightForeground": "#bfbfbf",
|
||||
"editorSuggestWidget.selectedBackground": "#FFFFFF26",
|
||||
"editorSuggestWidget.focusOutline": "#3994BCB3",
|
||||
"editorHoverWidget.background": "#202122",
|
||||
"editorHoverWidget.border": "#2A2B2C",
|
||||
"widget.border": "#2A2B2C",
|
||||
"peekView.border": "#2A2B2C",
|
||||
"peekViewEditor.background": "#191A1B",
|
||||
"peekViewEditor.matchHighlightBackground": "#3994BC33",
|
||||
"peekViewResult.background": "#191A1B",
|
||||
"peekViewResult.fileForeground": "#bfbfbf",
|
||||
"peekViewResult.lineForeground": "#8C8C8C",
|
||||
"peekViewResult.matchHighlightBackground": "#3994BC33",
|
||||
"peekViewResult.selectionBackground": "#3994BC26",
|
||||
"peekViewResult.selectionForeground": "#bfbfbf",
|
||||
"peekViewTitle.background": "#242526",
|
||||
"peekViewTitleDescription.foreground": "#8C8C8C",
|
||||
"peekViewTitleLabel.foreground": "#bfbfbf",
|
||||
"editorGutter.background": "#121314",
|
||||
"editorGutter.addedBackground": "#72C892",
|
||||
"editorGutter.deletedBackground": "#F28772",
|
||||
"diffEditor.insertedLineBackground": "#347d3926",
|
||||
"diffEditor.insertedTextBackground": "#57ab5a4d",
|
||||
"diffEditor.removedLineBackground": "#c93c3726",
|
||||
"diffEditor.removedTextBackground": "#f470674d",
|
||||
"editorOverviewRuler.border": "#2A2B2C",
|
||||
"editorOverviewRuler.findMatchForeground": "#3a94bc99",
|
||||
"editorOverviewRuler.modifiedForeground": "#6ab890",
|
||||
"editorOverviewRuler.addedForeground": "#73c991",
|
||||
"editorOverviewRuler.deletedForeground": "#f48771",
|
||||
"editorOverviewRuler.errorForeground": "#f48771",
|
||||
"editorOverviewRuler.warningForeground": "#e5ba7d",
|
||||
"panel.background": "#191A1B",
|
||||
"panel.border": "#2A2B2C",
|
||||
"panelSection.border": "#2A2B2C",
|
||||
"panelSectionHeader.border": "#2A2B2C",
|
||||
"panelTitle.activeBorder": "#3994BC",
|
||||
"panelTitle.activeForeground": "#bfbfbf",
|
||||
"panelTitle.inactiveForeground": "#8C8C8C",
|
||||
"statusBar.background": "#191A1B",
|
||||
"statusBar.inactiveBackground": "#121314",
|
||||
"statusBar.foreground": "#8C8C8C",
|
||||
"statusBar.border": "#2A2B2C",
|
||||
"statusBar.focusBorder": "#3994BCB3",
|
||||
"statusBar.debuggingBackground": "#3994BC",
|
||||
"statusBar.debuggingForeground": "#FFFFFF",
|
||||
"statusBar.noFolderBackground": "#191A1B",
|
||||
"statusBar.noFolderForeground": "#8C8C8C",
|
||||
"statusBarItem.activeBackground": "#4B4C4D",
|
||||
"statusBarItem.hoverBackground": "#323233",
|
||||
"statusBarItem.focusBorder": "#3994BCB3",
|
||||
"statusBarItem.prominentBackground": "#3994BC",
|
||||
"statusBarItem.prominentForeground": "#FFFFFF",
|
||||
"statusBarItem.prominentHoverBackground": "#3994BC",
|
||||
"tab.activeBackground": "#121314",
|
||||
"tab.activeForeground": "#bfbfbf",
|
||||
"tab.inactiveBackground": "#191A1B",
|
||||
"tab.inactiveForeground": "#8C8C8C",
|
||||
"tab.border": "#2A2B2C",
|
||||
"tab.lastPinnedBorder": "#2A2B2C",
|
||||
"tab.activeBorderTop": "#3994BC",
|
||||
"tab.hoverBackground": "#121314",
|
||||
"tab.hoverForeground": "#bfbfbf",
|
||||
"tab.unfocusedActiveBackground": "#121314",
|
||||
"tab.unfocusedActiveForeground": "#8C8C8C",
|
||||
"tab.unfocusedInactiveBackground": "#191A1B",
|
||||
"tab.unfocusedInactiveForeground": "#444444",
|
||||
"editorGroupHeader.tabsBackground": "#191A1B",
|
||||
"tab.activeBorder": "#121314",
|
||||
"editorGroupHeader.tabsBorder": "#2A2B2C",
|
||||
"breadcrumb.foreground": "#8C8C8C",
|
||||
"breadcrumb.background": "#121314",
|
||||
"breadcrumb.focusForeground": "#bfbfbf",
|
||||
"breadcrumb.activeSelectionForeground": "#bfbfbf",
|
||||
"breadcrumbPicker.background": "#202122",
|
||||
"notificationCenter.border": "#2A2B2C",
|
||||
"notificationCenterHeader.foreground": "#bfbfbf",
|
||||
"notificationCenterHeader.background": "#242526",
|
||||
"notificationToast.border": "#2A2B2C",
|
||||
"notifications.foreground": "#bfbfbf",
|
||||
"notifications.background": "#202122",
|
||||
"notifications.border": "#2A2B2C",
|
||||
"notificationLink.foreground": "#3a94bc",
|
||||
"notificationsWarningIcon.foreground": "#CCA700",
|
||||
"notificationsErrorIcon.foreground": "#f48771",
|
||||
"notificationsInfoIcon.foreground": "#3a94bc",
|
||||
"activityWarningBadge.foreground": "#202020",
|
||||
"activityWarningBadge.background": "#CCA700",
|
||||
"activityErrorBadge.foreground": "#FFFFFF",
|
||||
"activityErrorBadge.background": "#f48771",
|
||||
"extensionButton.prominentBackground": "#297AA0",
|
||||
"extensionButton.prominentForeground": "#FFFFFF",
|
||||
"extensionButton.prominentHoverBackground": "#2B7DA3",
|
||||
"pickerGroup.border": "#2A2B2C",
|
||||
"pickerGroup.foreground": "#bfbfbf",
|
||||
"quickInput.background": "#202122",
|
||||
"quickInput.foreground": "#bfbfbf",
|
||||
"quickInputList.focusBackground": "#297AA0",
|
||||
"quickInputList.focusForeground": "#FFFFFF",
|
||||
"quickInputList.focusIconForeground": "#FFFFFF",
|
||||
"quickInputList.focusHighlightForeground": "#FFFFFF",
|
||||
"terminal.selectionBackground": "#3994BC33",
|
||||
"terminal.background": "#191A1B",
|
||||
"terminal.border": "#2A2B2C",
|
||||
"terminal.tab.activeBorder": "#3994BC00",
|
||||
"terminalCursor.foreground": "#bfbfbf",
|
||||
"terminalCursor.background": "#191A1B",
|
||||
"gitDecoration.addedResourceForeground": "#73c991",
|
||||
"gitDecoration.modifiedResourceForeground": "#e5ba7d",
|
||||
"gitDecoration.deletedResourceForeground": "#f48771",
|
||||
"gitDecoration.untrackedResourceForeground": "#73c991",
|
||||
"gitDecoration.ignoredResourceForeground": "#8C8C8C",
|
||||
"gitDecoration.conflictingResourceForeground": "#f48771",
|
||||
"gitDecoration.stageModifiedResourceForeground": "#e5ba7d",
|
||||
"gitDecoration.stageDeletedResourceForeground": "#f48771",
|
||||
"quickInputTitle.background": "#202122",
|
||||
"commandCenter.activeBorder": "#333536",
|
||||
"chat.requestBubbleBackground": "#ffffff13",
|
||||
"chat.requestBubbleHoverBackground": "#ffffff22",
|
||||
"chat.inputWorkingBorderColor1": "#297AA0",
|
||||
"editorCommentsWidget.rangeBackground": "#488FAE26",
|
||||
"editorCommentsWidget.rangeActiveBackground": "#488FAE46",
|
||||
"charts.foreground": "#CCCCCC",
|
||||
"charts.lines": "#C8CACC80",
|
||||
"charts.blue": "#57A3F8",
|
||||
"charts.red": "#EF8773",
|
||||
"charts.yellow": "#E0B97F",
|
||||
"charts.orange": "#CD861A",
|
||||
"charts.green": "#86CF86",
|
||||
"charts.purple": "#AD80D7",
|
||||
"inlineChat.border": "#00000000",
|
||||
"minimapSlider.background": "#A8A9AA85",
|
||||
"minimapSlider.hoverBackground": "#A8A9AA90",
|
||||
"minimapSlider.activeBackground": "#A8A9AA9C",
|
||||
"agents.background": "#121314",
|
||||
"agentsPanel.background": "#191A1B",
|
||||
"agentsPanel.foreground": "#bfbfbf",
|
||||
"agentsPanel.border": "#2A2B2C",
|
||||
"surface.background": "#191A1B",
|
||||
"surface.foreground": "#bfbfbf",
|
||||
"surface.border": "#2A2B2C",
|
||||
"agentsGradient.tintColor": "#297AA0",
|
||||
"agentsChatInput.background": "#202122",
|
||||
"agentsChatInput.foreground": "#bfbfbf",
|
||||
"agentsChatInput.border": "#333536",
|
||||
"agentsChatInput.focusBorder": "#3994BCB3",
|
||||
"agentsChatInput.placeholderForeground": "#555555",
|
||||
"agentsNewSessionButton.background": "#00000000",
|
||||
"agentsNewSessionButton.foreground": "#bfbfbf",
|
||||
"agentsNewSessionButton.border": "#333536",
|
||||
"agentsNewSessionButton.hoverBackground": "#FFFFFF18",
|
||||
"agentsBadge.background": "#307E9F",
|
||||
"agentsBadge.foreground": "#FFFFFF",
|
||||
"agentsUnreadBadge.background": "#307E9F",
|
||||
"agentsUnreadBadge.foreground": "#FFFFFF",
|
||||
"agentsBottomPanel.border": "#00000000"
|
||||
},
|
||||
"tokenColors": [
|
||||
{
|
||||
"scope": [
|
||||
"comment",
|
||||
"punctuation.definition.comment",
|
||||
"string.comment"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#8b949e"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"constant.other.placeholder",
|
||||
"constant.character"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#ff7b72"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"constant",
|
||||
"entity.name.constant",
|
||||
"variable.other.constant",
|
||||
"variable.other.enummember",
|
||||
"variable.language",
|
||||
"entity"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#79c0ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"entity.name",
|
||||
"meta.export.default",
|
||||
"meta.definition.variable"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#ffa657"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"variable.parameter.function",
|
||||
"meta.jsx.children",
|
||||
"meta.block",
|
||||
"meta.tag.attributes",
|
||||
"entity.name.constant",
|
||||
"meta.object.member",
|
||||
"meta.embedded.expression"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#c9d1d9"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "entity.name.function",
|
||||
"settings": {
|
||||
"foreground": "#d2a8ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"entity.name.tag",
|
||||
"support.class.component"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#7ee787"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "keyword",
|
||||
"settings": {
|
||||
"foreground": "#ff7b72"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"storage",
|
||||
"storage.type"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#ff7b72"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"storage.modifier.package",
|
||||
"storage.modifier.import",
|
||||
"storage.type.java"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#c9d1d9"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"string",
|
||||
"string punctuation.section.embedded source"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#a5d6ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "support",
|
||||
"settings": {
|
||||
"foreground": "#79c0ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "meta.property-name",
|
||||
"settings": {
|
||||
"foreground": "#79c0ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "variable",
|
||||
"settings": {
|
||||
"foreground": "#ffa657"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "variable.other",
|
||||
"settings": {
|
||||
"foreground": "#c9d1d9"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "invalid.broken",
|
||||
"settings": {
|
||||
"foreground": "#ffa198",
|
||||
"fontStyle": "italic"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "invalid.deprecated",
|
||||
"settings": {
|
||||
"foreground": "#ffa198",
|
||||
"fontStyle": "italic"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "invalid.illegal",
|
||||
"settings": {
|
||||
"foreground": "#ffa198",
|
||||
"fontStyle": "italic"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "invalid.unimplemented",
|
||||
"settings": {
|
||||
"foreground": "#ffa198",
|
||||
"fontStyle": "italic"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "carriage-return",
|
||||
"settings": {
|
||||
"foreground": "#f0f6fc",
|
||||
"fontStyle": "italic underline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "message.error",
|
||||
"settings": {
|
||||
"foreground": "#ffa198"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "string variable",
|
||||
"settings": {
|
||||
"foreground": "#79c0ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"source.regexp",
|
||||
"string.regexp"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#a5d6ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"string.regexp.character-class",
|
||||
"string.regexp constant.character.escape",
|
||||
"string.regexp source.ruby.embedded",
|
||||
"string.regexp string.regexp.arbitrary-repitition"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#a5d6ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "string.regexp constant.character.escape",
|
||||
"settings": {
|
||||
"foreground": "#7ee787",
|
||||
"fontStyle": "bold"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "support.constant",
|
||||
"settings": {
|
||||
"foreground": "#79c0ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "support.variable",
|
||||
"settings": {
|
||||
"foreground": "#79c0ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "support.type.property-name.json",
|
||||
"settings": {
|
||||
"foreground": "#7ee787"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "meta.module-reference",
|
||||
"settings": {
|
||||
"foreground": "#79c0ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "punctuation.definition.list.begin.markdown",
|
||||
"settings": {
|
||||
"foreground": "#ffa657"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"markup.heading",
|
||||
"markup.heading entity.name"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#79c0ff",
|
||||
"fontStyle": "bold"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "markup.quote",
|
||||
"settings": {
|
||||
"foreground": "#7ee787"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "markup.italic",
|
||||
"settings": {
|
||||
"foreground": "#c9d1d9",
|
||||
"fontStyle": "italic"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "markup.bold",
|
||||
"settings": {
|
||||
"foreground": "#c9d1d9",
|
||||
"fontStyle": "bold"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"markup.underline"
|
||||
],
|
||||
"settings": {
|
||||
"fontStyle": "underline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"markup.strikethrough"
|
||||
],
|
||||
"settings": {
|
||||
"fontStyle": "strikethrough"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "markup.inline.raw",
|
||||
"settings": {
|
||||
"foreground": "#79c0ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"markup.deleted",
|
||||
"meta.diff.header.from-file",
|
||||
"punctuation.definition.deleted"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#ffa198"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"punctuation.section.embedded"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#ff7b72"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"markup.inserted",
|
||||
"meta.diff.header.to-file",
|
||||
"punctuation.definition.inserted"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#7ee787"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"markup.changed",
|
||||
"punctuation.definition.changed"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#ffa657"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"markup.ignored",
|
||||
"markup.untracked"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#0d1117"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "meta.diff.range",
|
||||
"settings": {
|
||||
"foreground": "#d2a8ff",
|
||||
"fontStyle": "bold"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "meta.diff.header",
|
||||
"settings": {
|
||||
"foreground": "#79c0ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "meta.separator",
|
||||
"settings": {
|
||||
"foreground": "#79c0ff",
|
||||
"fontStyle": "bold"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "meta.output",
|
||||
"settings": {
|
||||
"foreground": "#79c0ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"brackethighlighter.tag",
|
||||
"brackethighlighter.curly",
|
||||
"brackethighlighter.round",
|
||||
"brackethighlighter.square",
|
||||
"brackethighlighter.angle",
|
||||
"brackethighlighter.quote"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#8b949e"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "brackethighlighter.unmatched",
|
||||
"settings": {
|
||||
"foreground": "#ffa198"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"constant.other.reference.link",
|
||||
"string.other.link"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#a5d6ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "token.info-token",
|
||||
"settings": {
|
||||
"foreground": "#6796E6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "token.warn-token",
|
||||
"settings": {
|
||||
"foreground": "#CD9731"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "token.error-token",
|
||||
"settings": {
|
||||
"foreground": "#F44747"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "token.debug-token",
|
||||
"settings": {
|
||||
"foreground": "#B267E6"
|
||||
}
|
||||
}
|
||||
],
|
||||
"semanticHighlighting": true
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
{
|
||||
"$schema": "vscode://schemas/color-theme",
|
||||
"name": "Dark Modern",
|
||||
"include": "./dark_plus.json",
|
||||
"colors": {
|
||||
"activityBar.activeBorder": "#0078D4",
|
||||
"activityBar.background": "#181818",
|
||||
"activityBar.border": "#2B2B2B",
|
||||
"activityBar.foreground": "#D7D7D7",
|
||||
"activityBar.inactiveForeground": "#868686",
|
||||
"activityBarBadge.background": "#0078D4",
|
||||
"activityBarBadge.foreground": "#FFFFFF",
|
||||
"badge.background": "#616161",
|
||||
"badge.foreground": "#F8F8F8",
|
||||
"button.background": "#0078D4",
|
||||
"button.border": "#ffffff1a",
|
||||
"button.foreground": "#FFFFFF",
|
||||
"button.hoverBackground": "#026EC1",
|
||||
"button.secondaryBackground": "#00000000",
|
||||
"button.secondaryForeground": "#CCCCCC",
|
||||
"button.secondaryHoverBackground": "#2B2B2B",
|
||||
"chat.slashCommandBackground": "#26477866",
|
||||
"chat.slashCommandForeground": "#85B6FF",
|
||||
"chat.editedFileForeground": "#E2C08D",
|
||||
"checkbox.background": "#313131",
|
||||
"checkbox.border": "#3C3C3C",
|
||||
"debugToolBar.background": "#181818",
|
||||
"descriptionForeground": "#9D9D9D",
|
||||
"dropdown.background": "#313131",
|
||||
"dropdown.border": "#3C3C3C",
|
||||
"dropdown.foreground": "#CCCCCC",
|
||||
"dropdown.listBackground": "#1F1F1F",
|
||||
"editor.background": "#1F1F1F",
|
||||
"editor.findMatchBackground": "#9E6A03",
|
||||
"editor.foreground": "#CCCCCC",
|
||||
"editorGroup.border": "#FFFFFF17",
|
||||
"editorGroupHeader.tabsBackground": "#181818",
|
||||
"editorGroupHeader.tabsBorder": "#2B2B2B",
|
||||
"editorGutter.addedBackground": "#2EA043",
|
||||
"editorGutter.deletedBackground": "#F85149",
|
||||
"editorGutter.modifiedBackground": "#0078D4",
|
||||
"editorLineNumber.activeForeground": "#CCCCCC",
|
||||
"editorLineNumber.foreground": "#6E7681",
|
||||
"editorOverviewRuler.border": "#010409",
|
||||
"editorWidget.background": "#202020",
|
||||
"errorForeground": "#F85149",
|
||||
"focusBorder": "#0078D4",
|
||||
"foreground": "#CCCCCC",
|
||||
"icon.foreground": "#CCCCCC",
|
||||
"input.background": "#313131",
|
||||
"input.border": "#3C3C3C",
|
||||
"input.foreground": "#CCCCCC",
|
||||
"input.placeholderForeground": "#989898",
|
||||
"inputOption.activeBackground": "#2489DB82",
|
||||
"inputOption.activeBorder": "#2488DB",
|
||||
"keybindingLabel.foreground": "#CCCCCC",
|
||||
"menu.background": "#1F1F1F",
|
||||
"menu.selectionBackground": "#0078d4",
|
||||
"notificationCenterHeader.background": "#1F1F1F",
|
||||
"notificationCenterHeader.foreground": "#CCCCCC",
|
||||
"notifications.background": "#1F1F1F",
|
||||
"notifications.border": "#2B2B2B",
|
||||
"notifications.foreground": "#CCCCCC",
|
||||
"panel.background": "#181818",
|
||||
"panel.border": "#2B2B2B",
|
||||
"panelInput.border": "#2B2B2B",
|
||||
"panelTitle.activeBorder": "#0078D4",
|
||||
"panelTitle.activeForeground": "#CCCCCC",
|
||||
"panelTitle.inactiveForeground": "#9D9D9D",
|
||||
"peekViewEditor.background": "#1F1F1F",
|
||||
"peekViewEditor.matchHighlightBackground": "#BB800966",
|
||||
"peekViewResult.background": "#1F1F1F",
|
||||
"peekViewResult.matchHighlightBackground": "#BB800966",
|
||||
"pickerGroup.border": "#3C3C3C",
|
||||
"progressBar.background": "#0078D4",
|
||||
"quickInput.background": "#222222",
|
||||
"quickInput.foreground": "#CCCCCC",
|
||||
"settings.dropdownBackground": "#313131",
|
||||
"settings.dropdownBorder": "#3C3C3C",
|
||||
"settings.headerForeground": "#FFFFFF",
|
||||
"settings.modifiedItemIndicator": "#BB800966",
|
||||
"sideBar.background": "#181818",
|
||||
"sideBar.border": "#2B2B2B",
|
||||
"sideBar.foreground": "#CCCCCC",
|
||||
"sideBarSectionHeader.background": "#181818",
|
||||
"sideBarSectionHeader.border": "#2B2B2B",
|
||||
"sideBarSectionHeader.foreground": "#CCCCCC",
|
||||
"sideBarTitle.foreground": "#CCCCCC",
|
||||
"statusBar.background": "#181818",
|
||||
"statusBar.inactiveBackground": "#1F1F1F",
|
||||
"statusBar.border": "#2B2B2B",
|
||||
"statusBarItem.hoverBackground": "#F1F1F133",
|
||||
"statusBarItem.hoverForeground": "#FFFFFF",
|
||||
"statusBar.debuggingBackground": "#0078D4",
|
||||
"statusBar.debuggingForeground": "#FFFFFF",
|
||||
"statusBar.focusBorder": "#0078D4",
|
||||
"statusBar.foreground": "#CCCCCC",
|
||||
"statusBar.noFolderBackground": "#1F1F1F",
|
||||
"statusBarItem.focusBorder": "#0078D4",
|
||||
"statusBarItem.prominentBackground": "#6E768166",
|
||||
"statusBarItem.remoteBackground": "#0078D4",
|
||||
"statusBarItem.remoteForeground": "#FFFFFF",
|
||||
"tab.activeBackground": "#1F1F1F",
|
||||
"tab.activeBorder": "#1F1F1F",
|
||||
"tab.activeBorderTop": "#0078D4",
|
||||
"tab.activeForeground": "#FFFFFF",
|
||||
"tab.selectedBorderTop": "#6caddf",
|
||||
"tab.border": "#2B2B2B",
|
||||
"tab.hoverBackground": "#1F1F1F",
|
||||
"tab.inactiveBackground": "#181818",
|
||||
"tab.inactiveForeground": "#9D9D9D",
|
||||
"tab.unfocusedActiveBorder": "#1F1F1F",
|
||||
"tab.unfocusedActiveBorderTop": "#2B2B2B",
|
||||
"tab.unfocusedHoverBackground": "#1F1F1F",
|
||||
"terminal.foreground": "#CCCCCC",
|
||||
"terminal.tab.activeBorder": "#0078D4",
|
||||
"textBlockQuote.background": "#2B2B2B",
|
||||
"textBlockQuote.border": "#616161",
|
||||
"textCodeBlock.background": "#2B2B2B",
|
||||
"textLink.activeForeground": "#4daafc",
|
||||
"textLink.foreground": "#4daafc",
|
||||
"textPreformat.foreground": "#D0D0D0",
|
||||
"textPreformat.background": "#3C3C3C",
|
||||
"textSeparator.foreground": "#21262D",
|
||||
"titleBar.activeBackground": "#181818",
|
||||
"titleBar.activeForeground": "#CCCCCC",
|
||||
"titleBar.border": "#2B2B2B",
|
||||
"titleBar.inactiveBackground": "#1F1F1F",
|
||||
"titleBar.inactiveForeground": "#9D9D9D",
|
||||
"welcomePage.tileBackground": "#2B2B2B",
|
||||
"welcomePage.progress.foreground": "#0078D4",
|
||||
"widget.border": "#313131",
|
||||
"modernActivityBarItem.activeBackground": "#FFFFFF22",
|
||||
"modernActivityBarItem.hoverBackground": "#FFFFFF11",
|
||||
"modernActivityBar.border": "#252526"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
{
|
||||
"$schema": "vscode://schemas/color-theme",
|
||||
"name": "Dark+",
|
||||
"include": "./dark_vs.json",
|
||||
"tokenColors": [
|
||||
{
|
||||
"name": "Function declarations",
|
||||
"scope": [
|
||||
"entity.name.function",
|
||||
"support.function",
|
||||
"support.constant.handlebars",
|
||||
"source.powershell variable.other.member",
|
||||
"entity.name.operator.custom-literal"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#DCDCAA"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Types declaration and references",
|
||||
"scope": [
|
||||
"support.class",
|
||||
"support.type",
|
||||
"entity.name.type",
|
||||
"entity.name.namespace",
|
||||
"entity.other.attribute",
|
||||
"entity.name.scope-resolution",
|
||||
"entity.name.class",
|
||||
"storage.type.numeric.go",
|
||||
"storage.type.byte.go",
|
||||
"storage.type.boolean.go",
|
||||
"storage.type.string.go",
|
||||
"storage.type.uintptr.go",
|
||||
"storage.type.error.go",
|
||||
"storage.type.rune.go",
|
||||
"storage.type.cs",
|
||||
"storage.type.generic.cs",
|
||||
"storage.type.modifier.cs",
|
||||
"storage.type.variable.cs",
|
||||
"storage.type.annotation.java",
|
||||
"storage.type.generic.java",
|
||||
"storage.type.java",
|
||||
"storage.type.object.array.java",
|
||||
"storage.type.primitive.array.java",
|
||||
"storage.type.primitive.java",
|
||||
"storage.type.token.java",
|
||||
"storage.type.groovy",
|
||||
"storage.type.annotation.groovy",
|
||||
"storage.type.parameters.groovy",
|
||||
"storage.type.generic.groovy",
|
||||
"storage.type.object.array.groovy",
|
||||
"storage.type.primitive.array.groovy",
|
||||
"storage.type.primitive.groovy"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#4EC9B0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Types declaration and references, TS grammar specific",
|
||||
"scope": [
|
||||
"meta.type.cast.expr",
|
||||
"meta.type.new.expr",
|
||||
"support.constant.math",
|
||||
"support.constant.dom",
|
||||
"support.constant.json",
|
||||
"entity.other.inherited-class",
|
||||
"punctuation.separator.namespace.ruby"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#4EC9B0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Control flow / Special keywords",
|
||||
"scope": [
|
||||
"keyword.control",
|
||||
"source.cpp keyword.operator.new",
|
||||
"keyword.operator.delete",
|
||||
"keyword.other.using",
|
||||
"keyword.other.directive.using",
|
||||
"keyword.other.operator",
|
||||
"entity.name.operator"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#C586C0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Variable and parameter name",
|
||||
"scope": [
|
||||
"variable",
|
||||
"meta.definition.variable.name",
|
||||
"support.variable",
|
||||
"entity.name.variable",
|
||||
"constant.other.placeholder"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#9CDCFE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Constants and enums",
|
||||
"scope": [
|
||||
"variable.other.constant",
|
||||
"variable.other.enummember"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#4FC1FF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Object keys, TS grammar specific",
|
||||
"scope": [
|
||||
"meta.object-literal.key"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#9CDCFE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "CSS property value",
|
||||
"scope": [
|
||||
"support.constant.property-value",
|
||||
"support.constant.font-name",
|
||||
"support.constant.media-type",
|
||||
"support.constant.media",
|
||||
"constant.other.color.rgb-value",
|
||||
"constant.other.rgb-value",
|
||||
"support.constant.color"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#CE9178"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Regular expression groups",
|
||||
"scope": [
|
||||
"punctuation.definition.group.regexp",
|
||||
"punctuation.definition.group.assertion.regexp",
|
||||
"punctuation.definition.character-class.regexp",
|
||||
"punctuation.character.set.begin.regexp",
|
||||
"punctuation.character.set.end.regexp",
|
||||
"keyword.operator.negation.regexp",
|
||||
"support.other.parenthesis.regexp"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#CE9178"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"constant.character.character-class.regexp",
|
||||
"constant.other.character-class.set.regexp",
|
||||
"constant.other.character-class.regexp",
|
||||
"constant.character.set.regexp"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#d16969"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"keyword.operator.or.regexp",
|
||||
"keyword.control.anchor.regexp"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#DCDCAA"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "keyword.operator.quantifier.regexp",
|
||||
"settings": {
|
||||
"foreground": "#d7ba7d"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"constant.character",
|
||||
"constant.other.option"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#569cd6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "constant.character.escape",
|
||||
"settings": {
|
||||
"foreground": "#d7ba7d"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "entity.name.label",
|
||||
"settings": {
|
||||
"foreground": "#C8C8C8"
|
||||
}
|
||||
}
|
||||
],
|
||||
"semanticTokenColors": {
|
||||
"newOperator": "#C586C0",
|
||||
"stringLiteral": "#ce9178",
|
||||
"customLiteral": "#DCDCAA",
|
||||
"numberLiteral": "#b5cea8"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,423 @@
|
||||
{
|
||||
"$schema": "vscode://schemas/color-theme",
|
||||
"name": "Dark (Visual Studio)",
|
||||
"colors": {
|
||||
"checkbox.border": "#6B6B6B",
|
||||
"editor.background": "#1E1E1E",
|
||||
"editor.foreground": "#D4D4D4",
|
||||
"editor.inactiveSelectionBackground": "#3A3D41",
|
||||
"editorIndentGuide.background1": "#404040",
|
||||
"editorIndentGuide.activeBackground1": "#707070",
|
||||
"editor.selectionHighlightBackground": "#ADD6FF26",
|
||||
"list.dropBackground": "#383B3D",
|
||||
"activityBarBadge.background": "#007ACC",
|
||||
"sideBarTitle.foreground": "#BBBBBB",
|
||||
"input.placeholderForeground": "#A6A6A6",
|
||||
"menu.background": "#252526",
|
||||
"menu.foreground": "#CCCCCC",
|
||||
"menu.separatorBackground": "#454545",
|
||||
"menu.border": "#454545",
|
||||
"menu.selectionBackground": "#0078d4",
|
||||
"statusBarItem.remoteForeground": "#FFF",
|
||||
"statusBarItem.remoteBackground": "#16825D",
|
||||
"statusBar.inactiveBackground": "#1476B8",
|
||||
"titleBar.inactiveBackground": "#323233",
|
||||
"ports.iconRunningProcessForeground": "#369432",
|
||||
"sideBarSectionHeader.background": "#0000",
|
||||
"sideBarSectionHeader.border": "#ccc3",
|
||||
"tab.selectedBackground": "#37373D",
|
||||
"tab.selectedForeground": "#FFFFFF",
|
||||
"tab.lastPinnedBorder": "#ccc3",
|
||||
"list.activeSelectionIconForeground": "#FFF",
|
||||
"terminal.inactiveSelectionBackground": "#3A3D41",
|
||||
"widget.border": "#303031",
|
||||
"actionBar.toggledBackground": "#383a49",
|
||||
"agentsPanel.border": "#303031",
|
||||
"agentsCard.border": "#00000000",
|
||||
"agentsChatInput.border": "#303031",
|
||||
"agentsChatInput.focusBorder": "#007ACC",
|
||||
"agentsNewSessionButton.border": "#303031",
|
||||
"surface.border": "#252526",
|
||||
"modernActivityBarItem.activeBackground": "#1E1E1E",
|
||||
"modernActivityBarItem.hoverBackground": "#1E1E1E66",
|
||||
"modernActivityBar.border": "#252526"
|
||||
},
|
||||
"tokenColors": [
|
||||
{
|
||||
"scope": [
|
||||
"meta.embedded",
|
||||
"source.groovy.embedded",
|
||||
"string meta.image.inline.markdown",
|
||||
"variable.legacy.builtin.python"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#D4D4D4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "emphasis",
|
||||
"settings": {
|
||||
"fontStyle": "italic"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "strong",
|
||||
"settings": {
|
||||
"fontStyle": "bold"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "header",
|
||||
"settings": {
|
||||
"foreground": "#000080"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "comment",
|
||||
"settings": {
|
||||
"foreground": "#6A9955"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "constant.language",
|
||||
"settings": {
|
||||
"foreground": "#569cd6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"constant.numeric",
|
||||
"variable.other.enummember",
|
||||
"keyword.operator.plus.exponent",
|
||||
"keyword.operator.minus.exponent"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#b5cea8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "constant.regexp",
|
||||
"settings": {
|
||||
"foreground": "#646695"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "entity.name.tag",
|
||||
"settings": {
|
||||
"foreground": "#569cd6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"entity.name.tag.css",
|
||||
"entity.name.tag.less"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#d7ba7d"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "entity.other.attribute-name",
|
||||
"settings": {
|
||||
"foreground": "#9cdcfe"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"entity.other.attribute-name.class.css",
|
||||
"source.css entity.other.attribute-name.class",
|
||||
"entity.other.attribute-name.id.css",
|
||||
"entity.other.attribute-name.parent-selector.css",
|
||||
"entity.other.attribute-name.parent.less",
|
||||
"source.css entity.other.attribute-name.pseudo-class",
|
||||
"entity.other.attribute-name.pseudo-element.css",
|
||||
"source.css.less entity.other.attribute-name.id",
|
||||
"entity.other.attribute-name.scss"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#d7ba7d"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "invalid",
|
||||
"settings": {
|
||||
"foreground": "#f44747"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "markup.underline",
|
||||
"settings": {
|
||||
"fontStyle": "underline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "markup.bold",
|
||||
"settings": {
|
||||
"fontStyle": "bold",
|
||||
"foreground": "#569cd6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "markup.heading",
|
||||
"settings": {
|
||||
"fontStyle": "bold",
|
||||
"foreground": "#569cd6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "markup.italic",
|
||||
"settings": {
|
||||
"fontStyle": "italic",
|
||||
"foreground": "#C586C0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "markup.strikethrough",
|
||||
"settings": {
|
||||
"fontStyle": "strikethrough"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "markup.inserted",
|
||||
"settings": {
|
||||
"foreground": "#b5cea8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "markup.deleted",
|
||||
"settings": {
|
||||
"foreground": "#ce9178"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "markup.changed",
|
||||
"settings": {
|
||||
"foreground": "#569cd6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "punctuation.definition.quote.begin.markdown",
|
||||
"settings": {
|
||||
"foreground": "#6A9955"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "punctuation.definition.list.begin.markdown",
|
||||
"settings": {
|
||||
"foreground": "#6796e6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "markup.inline.raw",
|
||||
"settings": {
|
||||
"foreground": "#ce9178"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "brackets of XML/HTML tags",
|
||||
"scope": "punctuation.definition.tag",
|
||||
"settings": {
|
||||
"foreground": "#808080"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"meta.preprocessor",
|
||||
"entity.name.function.preprocessor"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#569cd6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "meta.preprocessor.string",
|
||||
"settings": {
|
||||
"foreground": "#ce9178"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "meta.preprocessor.numeric",
|
||||
"settings": {
|
||||
"foreground": "#b5cea8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "meta.structure.dictionary.key.python",
|
||||
"settings": {
|
||||
"foreground": "#9cdcfe"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "meta.diff.header",
|
||||
"settings": {
|
||||
"foreground": "#569cd6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "storage",
|
||||
"settings": {
|
||||
"foreground": "#569cd6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "storage.type",
|
||||
"settings": {
|
||||
"foreground": "#569cd6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"storage.modifier",
|
||||
"keyword.operator.noexcept"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#569cd6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"string",
|
||||
"meta.embedded.assembly"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#ce9178"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "string.tag",
|
||||
"settings": {
|
||||
"foreground": "#ce9178"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "string.value",
|
||||
"settings": {
|
||||
"foreground": "#ce9178"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "string.regexp",
|
||||
"settings": {
|
||||
"foreground": "#d16969"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "String interpolation",
|
||||
"scope": [
|
||||
"punctuation.definition.template-expression.begin",
|
||||
"punctuation.definition.template-expression.end",
|
||||
"punctuation.section.embedded"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#569cd6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Reset JavaScript string interpolation expression",
|
||||
"scope": [
|
||||
"meta.template.expression"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#d4d4d4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"support.type.vendored.property-name",
|
||||
"support.type.property-name",
|
||||
"source.css variable",
|
||||
"source.coffee.embedded"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#9cdcfe"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "keyword",
|
||||
"settings": {
|
||||
"foreground": "#569cd6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "keyword.control",
|
||||
"settings": {
|
||||
"foreground": "#569cd6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "keyword.operator",
|
||||
"settings": {
|
||||
"foreground": "#d4d4d4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"keyword.operator.new",
|
||||
"keyword.operator.expression",
|
||||
"keyword.operator.cast",
|
||||
"keyword.operator.sizeof",
|
||||
"keyword.operator.alignof",
|
||||
"keyword.operator.typeid",
|
||||
"keyword.operator.alignas",
|
||||
"keyword.operator.instanceof",
|
||||
"keyword.operator.logical.python",
|
||||
"keyword.operator.wordlike"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#569cd6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "keyword.other.unit",
|
||||
"settings": {
|
||||
"foreground": "#b5cea8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"punctuation.section.embedded.begin.php",
|
||||
"punctuation.section.embedded.end.php"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#569cd6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "support.function.git-rebase",
|
||||
"settings": {
|
||||
"foreground": "#9cdcfe"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "constant.sha.git-rebase",
|
||||
"settings": {
|
||||
"foreground": "#b5cea8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "coloring of the Java import and package identifiers",
|
||||
"scope": [
|
||||
"storage.modifier.import.java",
|
||||
"variable.language.wildcard.java",
|
||||
"storage.modifier.package.java"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#d4d4d4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "this.self",
|
||||
"scope": "variable.language",
|
||||
"settings": {
|
||||
"foreground": "#569cd6"
|
||||
}
|
||||
}
|
||||
],
|
||||
"semanticHighlighting": true,
|
||||
"semanticTokenColors": {
|
||||
"newOperator": "#d4d4d4",
|
||||
"stringLiteral": "#ce9178",
|
||||
"customLiteral": "#D4D4D4",
|
||||
"numberLiteral": "#b5cea8"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "darwin-breeze",
|
||||
"displayName": "Darwin Breeze",
|
||||
"description": "Generated by kde/theme/build.py from DarwinBreezeDark.colors",
|
||||
"publisher": "trivk",
|
||||
"version": "1.0.0",
|
||||
"engines": {
|
||||
"vscode": "^1.70.0"
|
||||
},
|
||||
"categories": [
|
||||
"Themes"
|
||||
],
|
||||
"contributes": {
|
||||
"themes": [
|
||||
{
|
||||
"label": "Darwin Breeze Dark",
|
||||
"uiTheme": "vs-dark",
|
||||
"path": "./themes/DarwinBreezeDark-color-theme.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<svg height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(0.78 0 0 0.78 3.52 3.52)"><g transform="matrix(.99917103 0 0 .9988667 .023961 .026876)"><path d="m29.946 15.942c.354 9.205-9.874 16.514-18.469 13.197-8.505-2.569-12.285-13.93-7.003-21.077 4.9-7.801 17.469-8.068 22.695-.48a13.97 13.97 0 0 1 2.777 8.36z" fill="none" opacity=".95" stroke="#f5f5f5" stroke-width="2.093"/><path d="m12.758 26.311v-5.725c-.282.433-.679.792-1.19 1.079a3.216 3.216 0 0 1 -1.613.43c-1.27 0-2.366-.555-3.287-1.663-.914-1.109-1.371-2.628-1.371-4.559 0-1.174.185-2.227.555-3.16.376-.932.917-1.636 1.623-2.114a4.074 4.074 0 0 1 2.34-.726c1.323 0 2.365.609 3.125 1.827v-1.563h1.633v16.174zm-5.596-10.36c0 1.504.29 2.635.867 3.39.579.75 1.27 1.124 2.078 1.124.773 0 1.438-.356 1.996-1.068.558-.72.837-1.81.837-3.27 0-1.557-.296-2.727-.887-3.513-.585-.785-1.274-1.178-2.067-1.178-.787 0-1.456.367-2.007 1.101-.544.727-.817 1.865-.817 3.413m11.938 5.88h-1.683v-16.141h1.815v5.758c.766-1.05 1.744-1.574 2.934-1.574.658 0 1.28.147 1.865.44a3.768 3.768 0 0 1 1.452 1.222c.383.521.682 1.153.897 1.894s.323 1.534.323 2.378c0 2.004-.454 3.553-1.361 4.647-.908 1.093-1.997 1.64-3.267 1.64-1.264 0-2.255-.576-2.974-1.728v1.464m-.02-5.935c0 1.402.174 2.415.524 3.04.571 1.02 1.344 1.53 2.319 1.53.793 0 1.479-.375 2.057-1.123.578-.756.867-1.88.867-3.37 0-1.526-.28-2.653-.837-3.38-.551-.726-1.22-1.09-2.007-1.09-.793 0-1.478.378-2.057 1.134-.578.75-.867 1.835-.867 3.26" fill="#fafafa"/></g></g></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
# Patch netbird-ui's tray icons to Breeze proportions.
|
||||
# Runs as root; the pacman hook re-runs it after every netbird-ui install/upgrade.
|
||||
set -euo pipefail
|
||||
here=$(cd "$(dirname "$0")" && pwd)
|
||||
ROOT=${ROOT:-} # for dry-run testing only
|
||||
bin=$ROOT/usr/bin/netbird-ui
|
||||
[[ -f $bin ]] || exit 0
|
||||
|
||||
# Still the file the package installed: keep it as the original for restore.sh
|
||||
sum=$(zcat "$ROOT"/var/lib/pacman/local/netbird-ui*/mtree 2>/dev/null \
|
||||
| grep -F './usr/bin/netbird-ui ' | grep -o 'sha256digest=[0-9a-f]*' | cut -d= -f2 || true)
|
||||
if [[ -n $sum && $(sha256sum <"$bin" | cut -d' ' -f1) == "$sum" ]]; then
|
||||
install -Dm755 "$bin" "$here/orig/netbird-ui"
|
||||
fi
|
||||
python3 -I "$here/patch.py" "$bin"
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
# Install the netbird-ui tray icon patch and its pacman hook. Usage: sudo ./install.sh
|
||||
set -euo pipefail
|
||||
here=$(cd "$(dirname "$0")" && pwd)
|
||||
ROOT=${ROOT:-} # for dry-run testing only
|
||||
[[ $EUID -eq 0 || -n $ROOT ]] || { echo "Must be run with sudo"; exit 1; }
|
||||
dest=$ROOT/usr/local/share/netbird-breeze-icons
|
||||
|
||||
install -Dm755 "$here/patch.py" "$dest/patch.py"
|
||||
install -m755 "$here/apply.sh" "$dest/apply.sh"
|
||||
install -Dm644 "$here/netbird-breeze-icons.hook" "$ROOT/etc/pacman.d/hooks/netbird-breeze-icons.hook"
|
||||
ROOT=$ROOT "$dest/apply.sh"
|
||||
|
||||
echo "Done. Restart the NetBird UI (without sudo):"
|
||||
echo " pkill -x netbird-ui; setsid -f netbird-ui --daemon-addr unix:///var/run/netbird/main.sock >/dev/null 2>&1"
|
||||
@@ -0,0 +1,11 @@
|
||||
[Trigger]
|
||||
Operation = Install
|
||||
Operation = Upgrade
|
||||
Type = Package
|
||||
Target = netbird-ui
|
||||
Target = netbird-ui-bin
|
||||
|
||||
[Action]
|
||||
Description = Patching NetBird tray icons to match Breeze...
|
||||
When = PostTransaction
|
||||
Exec = /usr/local/share/netbird-breeze-icons/apply.sh
|
||||
@@ -0,0 +1,183 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Shrink and recolor the tray icons embedded in the netbird-ui binary.
|
||||
|
||||
NetBird sends its tray icon as a pixmap, so an icon theme can't replace it.
|
||||
This rewrites the 48x48 monochrome PNGs inside the binary in place: the
|
||||
glyph is scaled to SCALE so it gets the padding of a Breeze status icon,
|
||||
and the white variants take the panel's text color. Each new PNG must fit
|
||||
in the bytes of the old one; the rest is zero-filled, which Go's PNG
|
||||
decoder never reads because it stops at IEND.
|
||||
|
||||
Usage: patch.py BINARY [--check]
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
from pathlib import Path
|
||||
import struct
|
||||
import sys
|
||||
import tempfile
|
||||
import zlib
|
||||
|
||||
SIZE = 48
|
||||
SCALE = 0.8
|
||||
# DarwinBreezeDark ForegroundNormal, as the other tray icons are drawn
|
||||
LIGHT = (222, 222, 222)
|
||||
# A glyph narrower than this already has padding (already patched)
|
||||
MAX_PADDED_WIDTH = round(SIZE * 0.9)
|
||||
SIG = b"\x89PNG\r\n\x1a\n"
|
||||
|
||||
Pixels = list[list[float]] # rows of premultiplied RGBA floats
|
||||
|
||||
|
||||
def decode(png: bytes) -> tuple[int, int, bytes] | None:
|
||||
"""Return (width, height, RGBA rows) for an 8-bit RGBA PNG, else None."""
|
||||
pos, idat, ihdr = 8, b"", b""
|
||||
while pos < len(png):
|
||||
(length,) = struct.unpack(">I", png[pos:pos + 4])
|
||||
kind, body = png[pos + 4:pos + 8], png[pos + 8:pos + 8 + length]
|
||||
if kind == b"IHDR":
|
||||
ihdr = body
|
||||
elif kind == b"IDAT":
|
||||
idat += body
|
||||
elif kind == b"IEND":
|
||||
break
|
||||
pos += 12 + length
|
||||
w, h, depth, color, _, _, interlace = struct.unpack(">IIBBBBB", ihdr)
|
||||
if (depth, color, interlace) != (8, 6, 0):
|
||||
return None
|
||||
raw, stride, out = zlib.decompress(idat), w * 4, bytearray()
|
||||
prev = bytearray(stride)
|
||||
for y in range(h):
|
||||
ftype = raw[y * (stride + 1)]
|
||||
line = bytearray(raw[y * (stride + 1) + 1:(y + 1) * (stride + 1)])
|
||||
for i in range(stride):
|
||||
a = line[i - 4] if i >= 4 else 0
|
||||
b = prev[i]
|
||||
c = prev[i - 4] if i >= 4 else 0
|
||||
if ftype == 1:
|
||||
line[i] = (line[i] + a) & 0xFF
|
||||
elif ftype == 2:
|
||||
line[i] = (line[i] + b) & 0xFF
|
||||
elif ftype == 3:
|
||||
line[i] = (line[i] + (a + b) // 2) & 0xFF
|
||||
elif ftype == 4:
|
||||
p = a + b - c
|
||||
pa, pb, pc = abs(p - a), abs(p - b), abs(p - c)
|
||||
pred = a if pa <= pb and pa <= pc else b if pb <= pc else c
|
||||
line[i] = (line[i] + pred) & 0xFF
|
||||
out += line
|
||||
prev = line
|
||||
return w, h, bytes(out)
|
||||
|
||||
|
||||
def encode(w: int, h: int, rgba: bytes) -> bytes:
|
||||
def chunk(kind: bytes, body: bytes) -> bytes:
|
||||
crc = zlib.crc32(kind + body)
|
||||
return struct.pack(">I", len(body)) + kind + body + struct.pack(">I", crc)
|
||||
|
||||
raw = b"".join(b"\0" + rgba[y * w * 4:(y + 1) * w * 4] for y in range(h))
|
||||
return (SIG + chunk(b"IHDR", struct.pack(">IIBBBBB", w, h, 8, 6, 0, 0, 0))
|
||||
+ chunk(b"IDAT", zlib.compress(raw, 9)) + chunk(b"IEND", b""))
|
||||
|
||||
|
||||
def glyph_width(rgba: bytes) -> int:
|
||||
xs = [i // 4 % SIZE for i in range(3, len(rgba), 4) if rgba[i] > 16]
|
||||
return max(xs) - min(xs) + 1 if xs else 0
|
||||
|
||||
|
||||
def is_light(rgba: bytes) -> bool | None:
|
||||
"""True for a white glyph, False for black, None if not monochrome."""
|
||||
lum = [rgba[i - 3] for i in range(3, len(rgba), 4) if rgba[i] > 200]
|
||||
if not lum or any(abs(rgba[i - 3] - rgba[i - 2]) > 8 for i in range(3, len(rgba), 4)
|
||||
if rgba[i] > 200):
|
||||
return None
|
||||
if all(v > 230 for v in lum):
|
||||
return True
|
||||
if all(v < 25 for v in lum):
|
||||
return False
|
||||
return None
|
||||
|
||||
|
||||
def shrink(rgba: bytes, light: bool) -> bytes:
|
||||
"""Box-filter the image to SCALE, centered on a SIZE canvas."""
|
||||
src: Pixels = []
|
||||
for y in range(SIZE):
|
||||
row: list[float] = []
|
||||
for x in range(SIZE):
|
||||
r, g, b, a = rgba[(y * SIZE + x) * 4:(y * SIZE + x) * 4 + 4]
|
||||
row += [r * a, g * a, b * a, a]
|
||||
src.append(row)
|
||||
inner = SIZE * SCALE
|
||||
off = (SIZE - inner) / 2
|
||||
step = 1 / SCALE
|
||||
out = bytearray(SIZE * SIZE * 4)
|
||||
|
||||
def spans(o: int) -> list[tuple[int, float]]:
|
||||
lo = (o - off) * step
|
||||
hi = lo + step
|
||||
res = []
|
||||
for s in range(max(0, int(lo)), min(SIZE, int(hi) + 1)):
|
||||
cover = min(hi, s + 1) - max(lo, s)
|
||||
if cover > 0:
|
||||
res.append((s, cover))
|
||||
return res
|
||||
|
||||
for oy in range(SIZE):
|
||||
ys = spans(oy)
|
||||
for ox in range(SIZE):
|
||||
acc = [0.0] * 4
|
||||
for sy, wy in ys:
|
||||
for sx, wx in spans(ox):
|
||||
k = wy * wx
|
||||
for c in range(4):
|
||||
acc[c] += src[sy][sx * 4 + c] * k
|
||||
area = step * step
|
||||
a = acc[3] / area
|
||||
if a < 0.5:
|
||||
continue
|
||||
color = LIGHT if light else tuple(round(acc[c] / acc[3]) for c in range(3))
|
||||
out[(oy * SIZE + ox) * 4:(oy * SIZE + ox) * 4 + 4] = bytes(
|
||||
[*color, min(255, round(a))])
|
||||
return bytes(out)
|
||||
|
||||
|
||||
def patch(data: bytearray) -> int:
|
||||
count, pos = 0, 0
|
||||
while (pos := data.find(SIG, pos)) >= 0:
|
||||
end = data.find(b"IEND", pos) + 8
|
||||
old = bytes(data[pos:end])
|
||||
img = decode(old) if old[16:24] == struct.pack(">II", SIZE, SIZE) else None
|
||||
if img is not None:
|
||||
light = is_light(img[2])
|
||||
if light is not None and glyph_width(img[2]) > MAX_PADDED_WIDTH:
|
||||
new = encode(SIZE, SIZE, shrink(img[2], light))
|
||||
if len(new) > len(old):
|
||||
sys.exit(f"Patched icon at {pos} is larger than the original")
|
||||
data[pos:end] = new + bytes(len(old) - len(new))
|
||||
count += 1
|
||||
pos = end
|
||||
return count
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||
parser.add_argument("binary", type=Path)
|
||||
parser.add_argument("--check", action="store_true",
|
||||
help="only print how many icons would be patched")
|
||||
args = parser.parse_args()
|
||||
data = bytearray(args.binary.read_bytes())
|
||||
count = patch(data)
|
||||
print(f"{args.binary}: {count} tray icons {'to patch' if args.check else 'patched'}")
|
||||
if args.check or not count:
|
||||
return
|
||||
mode = args.binary.stat().st_mode
|
||||
fd, tmp = tempfile.mkstemp(dir=args.binary.parent, prefix=".netbird-ui.")
|
||||
with os.fdopen(fd, "wb") as f:
|
||||
f.write(data)
|
||||
os.chmod(tmp, mode & 0o7777)
|
||||
os.replace(tmp, args.binary)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
# Put the original netbird-ui back and remove the hook. Usage: sudo ./restore.sh
|
||||
set -euo pipefail
|
||||
ROOT=${ROOT:-} # for dry-run testing only
|
||||
[[ $EUID -eq 0 || -n $ROOT ]] || { echo "Must be run with sudo"; exit 1; }
|
||||
dest=$ROOT/usr/local/share/netbird-breeze-icons
|
||||
[[ -f $dest/orig/netbird-ui ]] || { echo "No original binary in $dest/orig"; exit 1; }
|
||||
install -m755 "$dest/orig/netbird-ui" "$ROOT/usr/bin/netbird-ui"
|
||||
rm -f "$ROOT/etc/pacman.d/hooks/netbird-breeze-icons.hook"
|
||||
rm -rf "$dest"
|
||||
echo "Restored. Restart the NetBird UI (without sudo):"
|
||||
echo " pkill -x netbird-ui; setsid -f netbird-ui --daemon-addr unix:///var/run/netbird/main.sock >/dev/null 2>&1"
|
||||
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
# Copy the Breeze-style icons over Ngó Sen's monochrome tray icons.
|
||||
# Runs as root; the pacman hook re-runs it after every fcitx5-ngosen install/upgrade.
|
||||
set -euo pipefail
|
||||
here=$(cd "$(dirname "$0")" && pwd)
|
||||
ROOT=${ROOT:-} # for dry-run testing only
|
||||
|
||||
# Ngó Sen points at hicolor, but Plasma looks the icon up by name in breeze/breeze-dark
|
||||
dirs=(usr/share/icons/hicolor/scalable/{apps,status}
|
||||
usr/share/icons/breeze{,-dark}/status/{22,24})
|
||||
mtree=$(zcat "$ROOT"/var/lib/pacman/local/fcitx5-ngosen-*/mtree 2>/dev/null || true)
|
||||
|
||||
for d in "${dirs[@]}"; do
|
||||
for f in "$here"/icons/*.svg; do
|
||||
n=$(basename "$f"); t=$ROOT/$d/$n
|
||||
[[ -f $t ]] || continue
|
||||
# Still the file the package installed: keep it as the original for restore.sh
|
||||
sum=$(grep -F "./$d/$n " <<<"$mtree" | grep -o 'sha256digest=[0-9a-f]*' | cut -d= -f2 || true)
|
||||
if [[ -n $sum && $(sha256sum <"$t" | cut -d' ' -f1) == "$sum" ]]; then
|
||||
install -Dm644 "$t" "$here/orig/$d/$n"
|
||||
fi
|
||||
install -m644 "$f" "$t"
|
||||
done
|
||||
done
|
||||
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22" width="22" height="22">
|
||||
<style id="current-color-scheme" type="text/css">.ColorScheme-Text { color: #232629; }</style>
|
||||
<g class="ColorScheme-Text" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.3">
|
||||
<rect x="3.5" y="3.5" width="15" height="15" rx="2.5" stroke-width="1"/><path d="M8.3 7.5 11 14.5l2.7-7"/>
|
||||
</g></svg>
|
||||
|
After Width: | Height: | Size: 426 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22" width="22" height="22">
|
||||
<style id="current-color-scheme" type="text/css">.ColorScheme-Text { color: #fcfcfc; }</style>
|
||||
<g class="ColorScheme-Text" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.3">
|
||||
<rect x="3.5" y="3.5" width="15" height="15" rx="2.5" stroke-width="1"/><path d="M8.3 7.5 11 14.5l2.7-7"/>
|
||||
</g></svg>
|
||||
|
After Width: | Height: | Size: 426 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22" width="22" height="22">
|
||||
<style id="current-color-scheme" type="text/css">.ColorScheme-Text { color: #232629; }</style>
|
||||
<g class="ColorScheme-Text" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1">
|
||||
<circle cx="11" cy="11" r="7.5"/><path d="M7.8 12.6q3.2 3.2 6.4 0"/><path d="M8.6 8.6v.6M13.4 8.6v.6" stroke-width="1.6"/>
|
||||
</g></svg>
|
||||
|
After Width: | Height: | Size: 440 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22" width="22" height="22">
|
||||
<style id="current-color-scheme" type="text/css">.ColorScheme-Text { color: #fcfcfc; }</style>
|
||||
<g class="ColorScheme-Text" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1">
|
||||
<circle cx="11" cy="11" r="7.5"/><path d="M7.8 12.6q3.2 3.2 6.4 0"/><path d="M8.6 8.6v.6M13.4 8.6v.6" stroke-width="1.6"/>
|
||||
</g></svg>
|
||||
|
After Width: | Height: | Size: 440 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22" width="22" height="22">
|
||||
<style id="current-color-scheme" type="text/css">.ColorScheme-Text { color: #232629; }</style>
|
||||
<g class="ColorScheme-Text" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.3">
|
||||
<rect x="3.5" y="3.5" width="15" height="15" rx="2.5" stroke-width="1"/><path d="M13.3 7.5H8.8v7h4.5M8.8 11h3.7"/>
|
||||
</g></svg>
|
||||
|
After Width: | Height: | Size: 434 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22" width="22" height="22">
|
||||
<style id="current-color-scheme" type="text/css">.ColorScheme-Text { color: #fcfcfc; }</style>
|
||||
<g class="ColorScheme-Text" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.3">
|
||||
<rect x="3.5" y="3.5" width="15" height="15" rx="2.5" stroke-width="1"/><path d="M13.3 7.5H8.8v7h4.5M8.8 11h3.7"/>
|
||||
</g></svg>
|
||||
|
After Width: | Height: | Size: 434 B |
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
# Install Breeze-style tray icons for Ngó Sen. Usage: sudo ./install.sh
|
||||
set -euo pipefail
|
||||
here=$(cd "$(dirname "$0")" && pwd)
|
||||
ROOT=${ROOT:-} # for dry-run testing only
|
||||
[[ $EUID -eq 0 || -n $ROOT ]] || { echo "Must be run with sudo"; exit 1; }
|
||||
owner=${SUDO_USER:-$(id -un "${PKEXEC_UID:-0}")}
|
||||
dest=$ROOT/usr/local/share/ngosen-breeze-icons
|
||||
|
||||
install -d "$dest/icons"
|
||||
install -m644 "$here"/icons/*.svg "$dest/icons/"
|
||||
install -m755 "$here/apply.sh" "$dest/apply.sh"
|
||||
install -Dm644 "$here/ngosen-breeze-icons.hook" "$ROOT/etc/pacman.d/hooks/ngosen-breeze-icons.hook"
|
||||
# Older versions used NoUpgrade in pacman.conf; the hook replaces it
|
||||
sed -i '/^# ngosen-breeze-icons$/,+1d' "$ROOT/etc/pacman.conf"
|
||||
ROOT=$ROOT "$dest/apply.sh"
|
||||
|
||||
# Ngó Sen: use the monochrome icons (not the lotus ones), white for a dark panel
|
||||
conf=$ROOT$(getent passwd "$owner" | cut -d: -f6)/.config/fcitx5/conf/ngosen.conf
|
||||
as_owner() { if [[ -n $ROOT ]]; then "$@"; else runuser -u "$owner" -- "$@"; fi; }
|
||||
if [[ -f $conf ]]; then
|
||||
for kv in UseLotusIcons=False IconTheme=Dark; do
|
||||
k=${kv%%=*}
|
||||
if grep -q "^$k=" "$conf"; then as_owner sed -i "s/^$k=.*/$kv/" "$conf"
|
||||
elif grep -q "^# $k=" "$conf"; then as_owner sed -i "s/^# $k=.*/$kv/" "$conf"
|
||||
else as_owner sh -c "echo '$kv' >> '$conf'"; fi
|
||||
done
|
||||
else
|
||||
as_owner install -Dm600 /dev/stdin "$conf" <<<$'UseLotusIcons=False\nIconTheme=Dark'
|
||||
fi
|
||||
|
||||
echo "Done. Restart fcitx5 and plasmashell (without sudo):"
|
||||
echo " $here/restart-fcitx5.sh; systemctl --user restart plasma-plasmashell"
|
||||
@@ -0,0 +1,10 @@
|
||||
[Trigger]
|
||||
Operation = Install
|
||||
Operation = Upgrade
|
||||
Type = Package
|
||||
Target = fcitx5-ngosen
|
||||
|
||||
[Action]
|
||||
Description = Applying Breeze-style tray icons for Ngó Sen...
|
||||
When = PostTransaction
|
||||
Exec = /usr/local/share/ngosen-breeze-icons/apply.sh
|
||||
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
# Restart fcitx5 through KWin (KDE Wayland) so it keeps the Wayland input method frontend.
|
||||
L=$(kreadconfig6 --file kwinrc --group Wayland --key InputMethod)
|
||||
[[ -n $L ]] || L=/usr/share/applications/fcitx5-wayland-launcher.desktop
|
||||
pkill -x fcitx5; sleep 1
|
||||
kwriteconfig6 --notify --file kwinrc --group Wayland --key InputMethod --delete; sleep 1
|
||||
kwriteconfig6 --notify --file kwinrc --group Wayland --key InputMethod "$L"
|
||||
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
# Put Ngó Sen's original icons back and remove the hook. Usage: sudo ./restore.sh
|
||||
set -euo pipefail
|
||||
ROOT=${ROOT:-} # for dry-run testing only
|
||||
[[ $EUID -eq 0 || -n $ROOT ]] || { echo "Must be run with sudo"; exit 1; }
|
||||
dest=$ROOT/usr/local/share/ngosen-breeze-icons
|
||||
[[ -d $dest/orig/usr ]] || { echo "No original icons in $dest/orig"; exit 1; }
|
||||
(cd "$dest/orig" && find usr -name '*.svg' -print0) | while IFS= read -r -d '' f; do
|
||||
install -m644 "$dest/orig/$f" "$ROOT/$f"
|
||||
done
|
||||
rm -f "$ROOT/etc/pacman.d/hooks/ngosen-breeze-icons.hook"
|
||||
rm -rf "$dest"
|
||||
echo "Restored. To get the lotus icons back, turn them on in Ngó Sen Settings."
|
||||
echo "Restart plasmashell (without sudo): systemctl --user restart plasma-plasmashell"
|
||||
@@ -0,0 +1,76 @@
|
||||
# Tray icons that match Breeze
|
||||
|
||||
```sh
|
||||
stow -d kde -t "$HOME" tray-icons
|
||||
```
|
||||
|
||||
Some icons need one more step after stowing; see below.
|
||||
|
||||
## Ngó Sen (fcitx5-ngosen)
|
||||
|
||||
Replaces Ngó Sen's monochrome tray icons with a V/E inside a rounded frame.
|
||||
|
||||
```sh
|
||||
sudo ~/.local/share/ngosen-breeze-icons/install.sh
|
||||
~/.local/share/ngosen-breeze-icons/restart-fcitx5.sh
|
||||
systemctl --user restart plasma-plasmashell
|
||||
```
|
||||
|
||||
- Ngó Sen points the tray at `/usr/share/icons/hicolor`, but Plasma looks
|
||||
the icon up by name in the `breeze`/`breeze-dark` themes under
|
||||
`/usr/share` and ignores `~/.local/share/icons`, so the system files have
|
||||
to be replaced.
|
||||
- `install.sh` copies the icons and `apply.sh` to
|
||||
`/usr/local/share/ngosen-breeze-icons/`, installs the pacman hook
|
||||
`/etc/pacman.d/hooks/ngosen-breeze-icons.hook` to re-apply them after
|
||||
every package upgrade, and sets `UseLotusIcons=False` and
|
||||
`IconTheme=Dark` in `~/.config/fcitx5/conf/ngosen.conf`.
|
||||
- The original icons are kept in `/usr/local/share/ngosen-breeze-icons/orig/`;
|
||||
`sudo ~/.local/share/ngosen-breeze-icons/restore.sh` puts them back and
|
||||
removes the hook.
|
||||
- On KDE Wayland don't start fcitx5 with `fcitx5 -d`; use
|
||||
`restart-fcitx5.sh` so KWin launches it.
|
||||
|
||||
## NetBird (netbird-ui)
|
||||
|
||||
Scales NetBird's tray icons down to 80% so they get the padding of Breeze
|
||||
status icons, and draws the white ones in the panel's text color
|
||||
(`#dedede`) instead of pure white.
|
||||
|
||||
```sh
|
||||
sudo ~/.local/share/netbird-breeze-icons/install.sh
|
||||
pkill -x netbird-ui; setsid -f netbird-ui --daemon-addr unix:///var/run/netbird/main.sock >/dev/null 2>&1
|
||||
```
|
||||
|
||||
- NetBird sends the tray icon as raw pixels, not an icon name, so an icon
|
||||
theme can't replace it. `patch.py` rewrites the 48x48 PNGs embedded in
|
||||
`/usr/bin/netbird-ui` in place instead; each new PNG fits in the bytes
|
||||
of the old one.
|
||||
- `install.sh` copies `patch.py` and `apply.sh` to
|
||||
`/usr/local/share/netbird-breeze-icons/` and installs the pacman hook
|
||||
`/etc/pacman.d/hooks/netbird-breeze-icons.hook` to re-patch the binary
|
||||
after every `netbird-ui`/`netbird-ui-bin` upgrade.
|
||||
- The original binary is kept in `/usr/local/share/netbird-breeze-icons/orig/`;
|
||||
`sudo ~/.local/share/netbird-breeze-icons/restore.sh` puts it back and
|
||||
removes the hook.
|
||||
|
||||
## qBittorrent
|
||||
|
||||
`qbittorrent-tray-mono.svg` is qBittorrent's monochrome tray icon scaled
|
||||
down to 78%, so it has the same padding as Breeze status icons instead of
|
||||
filling the whole tray slot.
|
||||
|
||||
qBittorrent 5.x only looks the tray icon up in the icon theme when "Use
|
||||
icons from system theme" is on, so also set (qBittorrent closed, or via
|
||||
Tools > Options > Behavior):
|
||||
|
||||
```ini
|
||||
# ~/.config/qBittorrent/qBittorrent.conf
|
||||
[Appearance]
|
||||
TrayIconStyle=Monochrome
|
||||
|
||||
[Preferences]
|
||||
Advanced\useSystemIconTheme=true
|
||||
```
|
||||
|
||||
`qBittorrent.conf` itself isn't stowed: qBittorrent rewrites it on exit.
|
||||
@@ -1,18 +0,0 @@
|
||||
# vim:fileencoding=utf-8:foldmethod=marker
|
||||
|
||||
font_family JetBrainsMono Nerd Font Regular
|
||||
bold_font JetBrainsMono Nerd Font Bold
|
||||
italic_font JetBrainsMono Nerd Font Italic
|
||||
bold_italic_font JetBrainsMono Nerd Font Bold Italic
|
||||
|
||||
font_size 13.0
|
||||
|
||||
background_opacity 0.85
|
||||
|
||||
allow_hyperlinks yes
|
||||
|
||||
shell_integration enabled
|
||||
|
||||
macos_option_as_alt yes
|
||||
|
||||
# include ./mocha.conf
|
||||
@@ -0,0 +1,15 @@
|
||||
# macOS packages
|
||||
|
||||
From the repository root, install all macOS packages:
|
||||
|
||||
```sh
|
||||
(cd mac && stow -t "$HOME" */)
|
||||
```
|
||||
|
||||
Install the package:
|
||||
|
||||
```sh
|
||||
stow -d mac -t "$HOME" ghostty
|
||||
```
|
||||
|
||||
- `ghostty`: JetBrainsMono Nerd Font and Ghostty's bundled SpaceGray Eighties theme.
|
||||
@@ -0,0 +1,3 @@
|
||||
font-family = "JetBrainsMono Nerd Font"
|
||||
theme = "SpaceGray Eighties"
|
||||
cursor-style = bar
|
||||
@@ -1,104 +0,0 @@
|
||||
# Don't ask for confirmations
|
||||
#assume_yes = true
|
||||
|
||||
# Disable specific steps - same options as the command line flag
|
||||
disable = ["system", "emacs", "gem", "node", "pnpm", "pip3", "micro", "containers"]
|
||||
|
||||
display_preamble = false
|
||||
|
||||
# Ignore failures for these steps
|
||||
#ignore_failures = ["powershell"]
|
||||
|
||||
# Run specific steps - same options as the command line flag
|
||||
#only = ["system", "emacs"]
|
||||
|
||||
# Do not ask to retry failed steps (default: false)
|
||||
#no_retry = true
|
||||
|
||||
# Run inside tmux
|
||||
#run_in_tmux = true
|
||||
|
||||
# List of remote machines with Topgrade installed on them
|
||||
#remote_topgrades = ["toothless", "pi", "parnas"]
|
||||
|
||||
# Arguments to pass SSH when upgrading remote systems
|
||||
#ssh_arguments = "-o ConnectTimeout=2"
|
||||
|
||||
# Path to Topgrade executable on remote machines
|
||||
#remote_topgrade_path = ".cargo/bin/topgrade"
|
||||
|
||||
# Arguments to pass tmux when pulling Repositories
|
||||
#tmux_arguments = "-S /var/tmux.sock"
|
||||
|
||||
# Do not set the terminal title
|
||||
#set_title = false
|
||||
|
||||
# Display the time in step titles
|
||||
# display_time = true
|
||||
|
||||
# Cleanup temporary or old files
|
||||
#cleanup = true
|
||||
|
||||
[git]
|
||||
#max_concurrency = 5
|
||||
# Additional git repositories to pull
|
||||
#repos = [
|
||||
# "~/src/*/",
|
||||
# "~/.config/something"
|
||||
#]
|
||||
|
||||
# Don't pull the predefined git repos
|
||||
#pull_predefined = false
|
||||
|
||||
# Arguments to pass Git when pulling Repositories
|
||||
#arguments = "--rebase --autostash"
|
||||
|
||||
[composer]
|
||||
#self_update = true
|
||||
|
||||
# Commands to run before anything
|
||||
[pre_commands]
|
||||
#"Emacs Snapshot" = "rm -rf ~/.emacs.d/elpa.bak && cp -rl ~/.emacs.d/elpa ~/.emacs.d/elpa.bak"
|
||||
|
||||
# Custom commands
|
||||
[commands]
|
||||
#"Python Environment" = "~/dev/.env/bin/pip install -i https://pypi.python.org/simple -U --upgrade-strategy eager jupyter"
|
||||
|
||||
[brew]
|
||||
#greedy_cask = true
|
||||
|
||||
[linux]
|
||||
# Arch Package Manager to use. Allowed values: autodetect, trizen, paru, yay, pikaur, pacman.
|
||||
#arch_package_manager = "pacman"
|
||||
# Arguments to pass yay (or paru) when updating packages
|
||||
#yay_arguments = "--nodevel"
|
||||
#show_arch_news = true
|
||||
#trizen_arguments = "--devel"
|
||||
#pikaur_arguments = ""
|
||||
#enable_tlmgr = true
|
||||
#emerge_sync_flags = "-q"
|
||||
#emerge_update_flags = "-uDNa --with-bdeps=y world"
|
||||
#redhat_distro_sync = false
|
||||
#rpm_ostree = false
|
||||
|
||||
[windows]
|
||||
# Manually select Windows updates
|
||||
#accept_all_updates = false
|
||||
#open_remotes_in_new_terminal = true
|
||||
|
||||
# Causes Topgrade to rename itself during the run to allow package managers
|
||||
# to upgrade it. Use this only if you installed Topgrade by using a package
|
||||
# manager such as Scoop to Cargo
|
||||
#self_rename = true
|
||||
|
||||
[npm]
|
||||
# Use sudo if the NPM directory isn't owned by the current user
|
||||
#use_sudo = true
|
||||
|
||||
[firmware]
|
||||
# Offer to update firmware; if false just check for and display available updates
|
||||
#upgrade = true
|
||||
|
||||
[flatpak]
|
||||
# Use sudo for updating the system-wide installation
|
||||
#use_sudo = true
|
||||
@@ -1,38 +0,0 @@
|
||||
# install zinit
|
||||
source $ZDOTDIR/zinit.zsh
|
||||
|
||||
# load remote plugins
|
||||
zinit wait lucid light-mode for \
|
||||
wintermi/zsh-brew \
|
||||
hlissner/zsh-autopair \
|
||||
Aloxaf/fzf-tab \
|
||||
atinit"zicompinit; zicdreplay -q" \
|
||||
zdharma-continuum/fast-syntax-highlighting zap-zsh/supercharge \
|
||||
atload"_zsh_autosuggest_start" \
|
||||
zsh-users/zsh-autosuggestions \
|
||||
blockf atpull'zinit creinstall -q .' \
|
||||
zsh-users/zsh-completions
|
||||
|
||||
# load prompt theme
|
||||
zinit ice as"command" from"gh-r" \
|
||||
atclone"./starship init zsh > init.zsh; ./starship completions zsh > _starship" \
|
||||
atpull"%atclone" src"init.zsh"
|
||||
zinit light starship/starship
|
||||
|
||||
# load binaries
|
||||
zinit as"command" wait lucid light-mode from"gh-r" for \
|
||||
extract"!" atload="alias cat=bat" lsd-rs/lsd \
|
||||
extract"!" atload="alias nano=micro" zyedidia/micro \
|
||||
extract"!" cp"autocomplete/bat.zsh -> _bat" atload"alias cat=bat" @sharkdp/bat \
|
||||
extract"!" atclone="cp usr/bin/fastfetch .; rm -rf usr" \
|
||||
fastfetch-cli/fastfetch \
|
||||
atclone"./zoxide init zsh > init.zsh" atpull"%atclone" src"init.zsh" \
|
||||
ajeetdsouza/zoxide \
|
||||
atclone"./fzf --zsh > init.zsh" atpull="%atclone" src"init.zsh" \
|
||||
junegunn/fzf \
|
||||
atclone"./fnm env --use-on-cd > init.zsh" atpull"%atclone" src"init.zsh" Schniz/fnm
|
||||
|
||||
# load local snippets
|
||||
source $ZDOTDIR/exports.zsh
|
||||
|
||||
zstyle ':fzf-tab:complete:cd:*' fzf-preview 'lsd -1 --color=always --icon=always $realpath'
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
(($+commands[bat])) && alias cat="bat"
|
||||
(($+commands[lsd])) && alias ls="lsd"
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
ZINIT_HOME="${XDG_DATA_HOME:-${HOME}/.local/share}/zinit/zinit.git"
|
||||
[ ! -d $ZINIT_HOME ] && mkdir -p "$(dirname $ZINIT_HOME)"
|
||||
[ ! -d $ZINIT_HOME/.git ] && git clone https://github.com/zdharma-continuum/zinit.git "$ZINIT_HOME"
|
||||
source "${ZINIT_HOME}/zinit.zsh"
|
||||
@@ -1,3 +0,0 @@
|
||||
export XDG_CONFIG_HOME="${HOME}/.config"
|
||||
export ZDOTDIR="${XDG_CONFIG_HOME}/zsh"
|
||||
export SHELL_SESSIONS_DISABLE=1
|
||||