Compare commits
4 Commits
release-pl
...
chore/use-
Author | SHA1 | Date | |
---|---|---|---|
|
fd8311f2d4 | ||
|
40d4eb967b | ||
|
0a214efef1 | ||
|
e9b9a2f350 |
51
.github/workflows/build.yml
vendored
@@ -3,64 +3,33 @@ name: "Generate test artifacts"
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, reopened, synchronize]
|
||||
|
||||
# env:
|
||||
# TAG: latest
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
# container:
|
||||
# image: ghcr.io/${{ github.repository_owner }}/${{ github.repository }}:${{ env.TAG }}
|
||||
#
|
||||
# # is this really necessary?
|
||||
# credentials:
|
||||
# username: ${{ github.actor }}
|
||||
# password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
steps:
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
cache: "pip"
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt update && sudo apt install -y sassc inkscape optipng
|
||||
pip install -r requirements.txt
|
||||
|
||||
run: pip install -r requirements.txt
|
||||
- name: Install colloid specific dependencies
|
||||
run: sudo apt update && sudo apt install -y sassc inkscape optipng
|
||||
- name: Generate themes
|
||||
run: |
|
||||
set -eu pipefile
|
||||
|
||||
python sources/patches/xfwm4/generate_assets.py
|
||||
|
||||
python ./build.py mocha --all-accents --zip -d $PWD/releases > mocha.log 2>&1 &
|
||||
python ./build.py macchiato --all-accents --zip -d $PWD/releases > macchiato.log 2>&1 &
|
||||
python ./build.py frappe --all-accents --zip -d $PWD/releases > frappe.log 2>&1 &
|
||||
python ./build.py latte --all-accents --zip -d $PWD/releases > latte.log 2>&1 &
|
||||
|
||||
declare -i err=0 werr=0
|
||||
while wait -fn || werr=$?; ((werr != 127)); do
|
||||
err=$werr
|
||||
if [[ $err -ne 0 ]]; then
|
||||
echo "Build failure, abort"
|
||||
cat *.log
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
cat *.log
|
||||
python patches/xfwm4/generate_assets.py
|
||||
|
||||
python ./build.py mocha --all-accents --zip -d $PWD/releases &&
|
||||
python ./build.py macchiato --all-accents --zip -d $PWD/releases &&
|
||||
python ./build.py frappe --all-accents --zip -d $PWD/releases &&
|
||||
python ./build.py latte --all-accents --zip -d $PWD/releases
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: '${{ github.sha }}-artifacts'
|
||||
path: ./releases/*.zip
|
||||
path: ./releases/*.zip
|
||||
|
||||
|
27
.github/workflows/docker.yml
vendored
@@ -1,27 +0,0 @@
|
||||
name: "Publish containers for build"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
# types: [opened, reopened, synchronize]
|
||||
types: [synchronize]
|
||||
|
||||
permissions: write-all
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Generate and push image to ghcr
|
||||
run: |
|
||||
# build docker image for the ci
|
||||
sh docker/build.sh -v no
|
||||
|
||||
# push the image to the registry
|
||||
sh docker/push.sh -u "${{ github.actor }}" -p "${{ secrets.GITHUB_TOKEN }}"
|
57
.github/workflows/release.yml
vendored
@@ -1,68 +1,33 @@
|
||||
name: release
|
||||
name: "Mainline release"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
tags:
|
||||
- "v*"
|
||||
jobs:
|
||||
release-please:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: googleapis/release-please-action@v4
|
||||
id: release
|
||||
outputs:
|
||||
release_created: ${{ steps.release.outputs.release_created }}
|
||||
tag_name: ${{ steps.release.outputs.tag_name }}
|
||||
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: release-please
|
||||
if: ${{ needs.release-please.outputs.release_created }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
cache: "pip"
|
||||
|
||||
- name: Install dependencies
|
||||
run: pip install -r requirements.txt
|
||||
|
||||
- name: Install colloid specific dependencies
|
||||
run: sudo apt update && sudo apt install -y sassc inkscape optipng
|
||||
|
||||
- name: Generate themes
|
||||
run: |
|
||||
set -eu pipefile
|
||||
|
||||
python sources/patches/xfwm4/generate_assets.py
|
||||
|
||||
python ./build.py mocha --all-accents --zip -d $PWD/releases > mocha.log 2>&1 &
|
||||
python ./build.py macchiato --all-accents --zip -d $PWD/releases > macchiato.log 2>&1 &
|
||||
python ./build.py frappe --all-accents --zip -d $PWD/releases > frappe.log 2>&1 &
|
||||
python ./build.py latte --all-accents --zip -d $PWD/releases > latte.log 2>&1 &
|
||||
declare -i err=0 werr=0
|
||||
while wait -fn || werr=$?; ((werr != 127)); do
|
||||
err=$werr
|
||||
if [[ $err -ne 0 ]]; then
|
||||
echo "Build failure, abort"
|
||||
cat *.log
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
cat *.log
|
||||
|
||||
python ./build.py mocha --all-accents --zip -d $PWD/releases &&
|
||||
python ./build.py macchiato --all-accents --zip -d $PWD/releases &&
|
||||
python ./build.py frappe --all-accents --zip -d $PWD/releases &&
|
||||
python ./build.py latte --all-accents --zip -d $PWD/releases
|
||||
- name: Add zips to release
|
||||
run: gh release upload ${{ needs.release-please.outputs.tag_name }} releases/*.zip
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
draft: true
|
||||
files: ./releases/*.zip
|
||||
|
3
.gitignore
vendored
@@ -8,9 +8,6 @@ lib*/
|
||||
*.cfg
|
||||
.direnv
|
||||
build/
|
||||
*.log
|
||||
.ruff-cache
|
||||
.tmp
|
||||
|
||||
# Releases folder
|
||||
releases
|
||||
|
2
.gitmodules
vendored
@@ -1,3 +1,3 @@
|
||||
[submodule "colloid"]
|
||||
path = sources/colloid
|
||||
path = colloid
|
||||
url = https://github.com/vinceliuice/Colloid-gtk-theme.git
|
||||
|
@@ -1,3 +0,0 @@
|
||||
{
|
||||
".": "1.0.4"
|
||||
}
|
20
CHANGELOG.md
@@ -1,20 +0,0 @@
|
||||
# Changelog
|
||||
|
||||
## [1.0.4](https://github.com/catppuccin/gtk/compare/v1.0.3...v1.0.4) (2024-06-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* alt tab menu ([#209](https://github.com/catppuccin/gtk/issues/209)) ([cae57c8](https://github.com/catppuccin/gtk/commit/cae57c80f81fd1cc40fab2655109b09fa97103b9))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* improving performance, layout ([#215](https://github.com/catppuccin/gtk/issues/215)) ([cadc3e2](https://github.com/catppuccin/gtk/commit/cadc3e2ac24f93c6641f9f87ee5d044433c65ce7))
|
||||
|
||||
## [1.0.3](https://github.com/catppuccin/gtk/compare/v1.0.2...v1.0.3) (2024-06-01)
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* improving performance, layout ([#215](https://github.com/catppuccin/gtk/issues/215)) ([cadc3e2](https://github.com/catppuccin/gtk/commit/cadc3e2ac24f93c6641f9f87ee5d044433c65ce7))
|
@@ -1,29 +1,15 @@
|
||||
## Development
|
||||
|
||||
Information regarding the architecture of the project can be found [in the ARCHITECTURE.md](./ARCHITECTURE.md) document.
|
||||
|
||||
### Requirements
|
||||
- All the [requirements for building](#building)
|
||||
- `whiskers`, optionally, from [catppuccin/toolbox](https://github.com/catppuccin/toolbox/tree/main/whiskers#installation)
|
||||
|
||||
### Project structure
|
||||
|
||||
`sources/` contains all of the source files needed for the project to build, including the Colloid submodule.
|
||||
It also contains our patches for Colloid, alongside the core build system implemented by us to replace the one from Colloid.
|
||||
|
||||
`build.py` is the entrypoint to the build system, placed at the root for convenience. The plumbing this utilizes is in
|
||||
`sources/build`.
|
||||
|
||||
`install.py` is our officially supported install script, which will automate the process of pulling the release, extracting it,
|
||||
and optionally adding symlinks for GTK-4.0 support. This script intentionally has no dependencies other than Python 3 itself.
|
||||
This keeps the end user experience simple and reproducible. Do not add external dependencies to this script.
|
||||
|
||||
### Patching colloid
|
||||
> [!TIP]
|
||||
> If you need to change the patches, reset the submodule and rerun the build script.
|
||||
|
||||
We patch upstream colloid through a series of `.patch` files, applied through `git apply` once when the build begins.
|
||||
The patches are located in `./patches/colloid/`.
|
||||
The patches are located in `./patches/colloid/`.
|
||||
|
||||
Once the build script patches the submodule, it will write a file into
|
||||
`colloid/.patched`, to signal to future invocations that the patches have already been applied.
|
||||
@@ -39,12 +25,12 @@ Now and again, Colloid will have bugs upstream that impacts our theme. With our
|
||||
but we still want to contribute the fixes upstream to benefit all users & forks of Colloid.
|
||||
|
||||
To avoid stalling unnecessarily, our procedure for the above is as follows:
|
||||
1) Open a PR to fix the issue, by adding a patch file to our theme, add `upstream:intended`
|
||||
1) Open a PR to fix the issue, by adding a patch file to our theme, add `upstream:intended`
|
||||
to signal these changes are to be sent to Colloid eventually.
|
||||
2) Merge the PR & close the issue in our theme pertaining to the issue, once reviewed and approved
|
||||
3) Open a PR in Colloid with the patch
|
||||
4) Open a new issue in our theme, with these details:
|
||||
- The initial issue in our theme
|
||||
- The initial issue in our theme
|
||||
- The PR in Colloid that fixes the issue there
|
||||
- The PR that fixed the issue in our theme
|
||||
|
||||
@@ -55,7 +41,7 @@ to signal these changes are to be sent to Colloid eventually.
|
||||
- The tracking issue
|
||||
- The commit that fixed the issue in Colloid
|
||||
3) Close the tracking issue & merge the PR to remove the patch file
|
||||
|
||||
|
||||
|
||||
### Running test builds
|
||||
We support building and publishing test builds from PRs. When you open PRs, the CI will automatically build with your changes and push an artifact
|
||||
@@ -67,10 +53,10 @@ pass the path into `install.py` under the `--from-artifact` option:
|
||||
python3 install.py mocha blue --dest ./build --from-artifact ~/downloads/7bff2448a81e36bf3b0e03bfbd649bebe6973ec7-artifacts.zip
|
||||
```
|
||||
|
||||
This will take the target flavor / accent out of the zip, and install it using the regular install process.
|
||||
This will take the target flavor / accent out of the zip, and install it using the regular install process.
|
||||
|
||||
It is advised to pass a `--dest` when running in this mode, because the released zips follow the exact same naming scheme as regular builds.
|
||||
This wil cause conflicts when you install, if you already had that theme installed. Passing a different destination allows you to move the
|
||||
This wil cause conflicts when you install, if you already had that theme installed. Passing a different destination allows you to move the
|
||||
extracted folders to `~/.local/share/themes` yourself, adding a suffix as appropriate to avoid conflicts.
|
||||
|
||||
> [!WARNING]
|
||||
@@ -79,4 +65,4 @@ extracted folders to `~/.local/share/themes` yourself, adding a suffix as approp
|
||||
|
||||
### Useful resources
|
||||
- GNOME-shell sources: https://gitlab.gnome.org/GNOME/gnome-shell/-/tree/gnome-46/data/theme
|
||||
- GTK inspector guide: https://developer.gnome.org/documentation/tools/inspector.html
|
||||
- GTK inspector guide: https://developer.gnome.org/documentation/tools/inspector.html
|
12
README.md
@@ -28,10 +28,8 @@ This GTK theme requires:
|
||||
|
||||
We provide a Python script to automate the process of installing the theme:
|
||||
|
||||
<!-- x-release-please-start-version -->
|
||||
|
||||
```bash
|
||||
curl -LsSO "https://raw.githubusercontent.com/catppuccin/gtk/v1.0.4/install.py"
|
||||
curl -LsS "https://raw.githubusercontent.com/catppuccin/gtk/main/install.py" -o install.py
|
||||
python3 install.py <flavor> <accent>
|
||||
[catppuccin-gtk] [INFO] - Installation info:
|
||||
flavor: mocha
|
||||
@@ -39,7 +37,7 @@ python3 install.py <flavor> <accent>
|
||||
dest: /home/<user>/.local/share/themes
|
||||
link: False
|
||||
|
||||
remote_url: https://github.com/catppuccin/gtk/releases/download/v1.0.4/catppuccin-mocha-blue-standard+default.zip
|
||||
remote_url: https://github.com/catppuccin/gtk/releases/download/v1.0.0-alpha/catppuccin-mocha-blue-standard+default.zip
|
||||
[catppuccin-gtk] [INFO] - Starting download...
|
||||
[catppuccin-gtk] [INFO] - Response status: 200
|
||||
[catppuccin-gtk] [INFO] - Download finished, zip is valid
|
||||
@@ -103,7 +101,7 @@ sudo flatpak override --env=GTK_THEME="catppuccin-${FLAVOR}-${ACCENT}-standard+d
|
||||
|
||||
### Manual installation
|
||||
|
||||
If your distro does not package our theme, and the installation script will not work for your use case, you can pull down releases and extract them yourself. You can find the [latest release on GitHub](https://github.com/catppuccin/gtk/releases/tag/v1.0.4).
|
||||
If your distro does not package our theme, and the installation script will not work for your use case, you can pull down releases and extract them yourself. You can find the [latest release on GitHub](https://github.com/catppuccin/gtk/releases/latest).
|
||||
|
||||
```bash
|
||||
cd ~/.local/share/themes
|
||||
@@ -112,7 +110,7 @@ cd ~/.local/share/themes
|
||||
export ROOT_URL="https://https://github.com/catppuccin/gtk/releases/download"
|
||||
|
||||
# Change to the tag you want to download
|
||||
export RELEASE="v1.0.4"
|
||||
export RELEASE="v1.0.0"
|
||||
|
||||
# Change to suite your flavor / accent combination
|
||||
export FLAVOR="mocha"
|
||||
@@ -132,8 +130,6 @@ ln -sf "${THEME_DIR}/gtk-4.0/gtk.css" "${HOME}/.config/gtk-4.0/gtk.css" &&
|
||||
ln -sf "${THEME_DIR}/gtk-4.0/gtk-dark.css" "${HOME}/.config/gtk-4.0/gtk-dark.css"
|
||||
```
|
||||
|
||||
<!-- x-release-please-end -->
|
||||
|
||||
## Building
|
||||
|
||||
If our prebuilt offerings do not match your requirements, you will have to build the theme from source.
|
||||
|
645
build.py
@@ -1,22 +1,633 @@
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import os
|
||||
#!/usr/bin/env python3
|
||||
import os, re, shutil, subprocess, argparse, glob, logging, zipfile, sys
|
||||
|
||||
from sources.build import execute_build
|
||||
from sources.build.args import parse_args
|
||||
from sources.build.logger import logger
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Literal, List
|
||||
|
||||
if __name__ == "__main__":
|
||||
git_root = os.path.dirname(os.path.realpath(__file__))
|
||||
from catppuccin import PALETTE
|
||||
from catppuccin.models import Flavor, Color
|
||||
|
||||
THIS_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||
SRC_DIR = f"{THIS_DIR}/colloid/src"
|
||||
SASSC_OPT = ["-M", "-t", "expanded"]
|
||||
|
||||
logger = logging.getLogger("catppuccin-gtk")
|
||||
logger.setLevel(logging.DEBUG)
|
||||
ch = logging.StreamHandler()
|
||||
formatter = logging.Formatter("[%(name)s] [%(levelname)s] - %(message)s")
|
||||
ch.setFormatter(formatter)
|
||||
logger.addHandler(ch)
|
||||
|
||||
|
||||
@dataclass
|
||||
class Tweaks:
|
||||
tweaks: List[str]
|
||||
|
||||
def has(self, tweak: str) -> bool:
|
||||
return tweak in self.tweaks
|
||||
|
||||
def id(self) -> str:
|
||||
return ",".join(self.tweaks)
|
||||
|
||||
|
||||
@dataclass
|
||||
class Suffix:
|
||||
true_value: str
|
||||
test: Any # callback function
|
||||
false_value: str = ""
|
||||
|
||||
|
||||
IS_DARK = Suffix(true_value="-Dark", test=lambda ctx: ctx.flavor.dark)
|
||||
IS_LIGHT = Suffix(true_value="-Light", test=lambda ctx: not ctx.flavor.dark)
|
||||
IS_WINDOW_NORMAL = Suffix(true_value="-Normal", test=lambda ctx: ctx.tweaks.has('normal'))
|
||||
DARK_LIGHT = Suffix(
|
||||
true_value="-Dark", false_value="-Light", test=lambda ctx: ctx.flavor.dark
|
||||
)
|
||||
|
||||
@dataclass
|
||||
class BuildContext:
|
||||
build_root: str
|
||||
output_format: Literal["zip"] | Literal["dir"]
|
||||
theme_name: str
|
||||
flavor: Flavor
|
||||
accent: Color
|
||||
size: Literal["standard"] | Literal["compact"]
|
||||
tweaks: Tweaks
|
||||
|
||||
def output_dir(self) -> str:
|
||||
return f"{self.build_root}/{self.build_id()}"
|
||||
|
||||
def build_id(self) -> str:
|
||||
return f"{self.theme_name}-{self.flavor.identifier}-{self.accent.identifier}-{self.size}+{self.tweaks.id() or 'default'}"
|
||||
|
||||
def apply_suffix(self, suffix: Suffix) -> str:
|
||||
if suffix.test(self):
|
||||
return suffix.true_value
|
||||
else:
|
||||
return suffix.false_value
|
||||
|
||||
|
||||
def build(ctx: BuildContext):
|
||||
output_dir = ctx.output_dir()
|
||||
logger.info(f"Building into '{output_dir}'...")
|
||||
|
||||
apply_tweaks(ctx)
|
||||
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
with open(f"{output_dir}/index.theme", "w") as file:
|
||||
file.write("[Desktop Entry]\n")
|
||||
file.write("Type=X-GNOME-Metatheme\n")
|
||||
file.write(f"Name={ctx.build_id()}\n")
|
||||
file.write("Comment=An Flat Gtk+ theme based on Elegant Design\n")
|
||||
file.write("Encoding=UTF-8\n")
|
||||
file.write("\n")
|
||||
file.write("[X-GNOME-Metatheme]\n")
|
||||
file.write(f"GtkTheme={ctx.build_id()}\n")
|
||||
file.write(f"MetacityTheme={ctx.build_id()}\n")
|
||||
file.write(f"IconTheme=Tela-circle{ctx.apply_suffix(IS_DARK)}\n")
|
||||
file.write(f"CursorTheme={ctx.flavor.name}-cursors\n")
|
||||
file.write("ButtonLayout=close,minimize,maximize:menu\n")
|
||||
|
||||
os.makedirs(f"{output_dir}/gnome-shell", exist_ok=True)
|
||||
shutil.copyfile(
|
||||
f"{SRC_DIR}/main/gnome-shell/pad-osd.css",
|
||||
f"{output_dir}/gnome-shell/pad-osd.css",
|
||||
)
|
||||
subprocess.check_call(
|
||||
[
|
||||
"sassc",
|
||||
*SASSC_OPT,
|
||||
f"{SRC_DIR}/main/gnome-shell/gnome-shell{ctx.apply_suffix(DARK_LIGHT)}.scss",
|
||||
f"{output_dir}/gnome-shell/gnome-shell.css",
|
||||
]
|
||||
)
|
||||
|
||||
os.makedirs(f"{output_dir}/gtk-3.0", exist_ok=True)
|
||||
subprocess.check_call(
|
||||
[
|
||||
"sassc",
|
||||
*SASSC_OPT,
|
||||
f"{SRC_DIR}/main/gtk-3.0/gtk{ctx.apply_suffix(DARK_LIGHT)}.scss",
|
||||
f"{output_dir}/gtk-3.0/gtk.css",
|
||||
]
|
||||
)
|
||||
subprocess.check_call(
|
||||
[
|
||||
"sassc",
|
||||
*SASSC_OPT,
|
||||
# NOTE: This uses 'Dark' for the source, but 'dark' for the destination. This is intentional. Do !!NOT!! change it without consultation
|
||||
f"{SRC_DIR}/main/gtk-3.0/gtk-Dark.scss",
|
||||
f"{output_dir}/gtk-3.0/gtk-dark.css",
|
||||
]
|
||||
)
|
||||
|
||||
os.makedirs(f"{output_dir}/gtk-4.0", exist_ok=True)
|
||||
subprocess.check_call(
|
||||
[
|
||||
"sassc",
|
||||
*SASSC_OPT,
|
||||
f"{SRC_DIR}/main/gtk-4.0/gtk{ctx.apply_suffix(DARK_LIGHT)}.scss",
|
||||
f"{output_dir}/gtk-4.0/gtk.css",
|
||||
]
|
||||
)
|
||||
subprocess.check_call(
|
||||
[
|
||||
"sassc",
|
||||
*SASSC_OPT,
|
||||
# NOTE: This uses 'Dark' for the source, but 'dark' for the destination. This is intentional. Do !!NOT!! change it without consultation
|
||||
f"{SRC_DIR}/main/gtk-4.0/gtk-Dark.scss",
|
||||
f"{output_dir}/gtk-4.0/gtk-dark.css",
|
||||
]
|
||||
)
|
||||
|
||||
os.makedirs(f"{output_dir}/cinnamon", exist_ok=True)
|
||||
subprocess.check_call(
|
||||
[
|
||||
"sassc",
|
||||
*SASSC_OPT,
|
||||
f"{SRC_DIR}/main/cinnamon/cinnamon{ctx.apply_suffix(DARK_LIGHT)}.scss",
|
||||
f"{output_dir}/cinnamon/cinnamon.css",
|
||||
]
|
||||
)
|
||||
|
||||
os.makedirs(f"{output_dir}/metacity-1", exist_ok=True)
|
||||
shutil.copyfile(
|
||||
f"{SRC_DIR}/main/metacity-1/metacity-theme-3{ctx.apply_suffix(IS_WINDOW_NORMAL)}.xml",
|
||||
f"{output_dir}/metacity-1/metacity-theme-3.xml",
|
||||
)
|
||||
# FIXME: Symlinks aren't working as intended
|
||||
# FIXME: Do we need them?
|
||||
# os.symlink(
|
||||
# f"{output_dir}/metacity-1/metacity-theme-3.xml",
|
||||
# f"{output_dir}/metacity-1/metacity-theme-2.xml",
|
||||
# )
|
||||
# os.symlink(
|
||||
# f"{output_dir}/metacity-1/metacity-theme-3.xml",
|
||||
# f"{output_dir}/metacity-1/metacity-theme-1.xml",
|
||||
# )
|
||||
|
||||
os.makedirs(f"{output_dir}/xfwm4", exist_ok=True)
|
||||
shutil.copyfile(
|
||||
f"{SRC_DIR}/main/xfwm4/themerc{ctx.apply_suffix(IS_LIGHT)}",
|
||||
f"{output_dir}/xfwm4/themerc",
|
||||
)
|
||||
|
||||
os.makedirs(f"{output_dir}-hdpi/xfwm4", exist_ok=True)
|
||||
shutil.copyfile(
|
||||
f"{SRC_DIR}/main/xfwm4/themerc{ctx.apply_suffix(IS_LIGHT)}",
|
||||
f"{output_dir}-hdpi/xfwm4/themerc",
|
||||
)
|
||||
subst_text(f"{output_dir}-hdpi/xfwm4/themerc", "button_offset=6", "button_offset=9")
|
||||
|
||||
os.makedirs(f"{output_dir}-xhdpi/xfwm4", exist_ok=True)
|
||||
shutil.copyfile(
|
||||
f"{SRC_DIR}/main/xfwm4/themerc{ctx.apply_suffix(IS_LIGHT)}",
|
||||
f"{output_dir}-xhdpi/xfwm4/themerc",
|
||||
)
|
||||
subst_text(
|
||||
f"{output_dir}-xhdpi/xfwm4/themerc", "button_offset=6", "button_offset=12"
|
||||
)
|
||||
|
||||
if not ctx.flavor.dark:
|
||||
shutil.copytree(
|
||||
f"{SRC_DIR}/main/plank/theme-Light-Catppuccin/", f"{output_dir}/plank", dirs_exist_ok=True
|
||||
)
|
||||
else:
|
||||
shutil.copytree(
|
||||
f"{SRC_DIR}/main/plank/theme-Dark-Catppuccin/", f"{output_dir}/plank", dirs_exist_ok=True
|
||||
)
|
||||
|
||||
|
||||
def init_tweaks_temp():
|
||||
shutil.copyfile(f"{SRC_DIR}/sass/_tweaks.scss", f"{SRC_DIR}/sass/_tweaks-temp.scss")
|
||||
|
||||
|
||||
def subst_text(path, _from, to):
|
||||
with open(path, "r+") as f:
|
||||
content = f.read()
|
||||
f.seek(0)
|
||||
f.truncate()
|
||||
f.write(re.sub(_from, to, content))
|
||||
|
||||
|
||||
GS_VERSION = "46-0"
|
||||
|
||||
|
||||
def gnome_shell_version():
|
||||
shutil.copyfile(
|
||||
f"{SRC_DIR}/sass/gnome-shell/_common.scss",
|
||||
f"{SRC_DIR}/sass/gnome-shell/_common-temp.scss",
|
||||
)
|
||||
subst_text(
|
||||
f"{SRC_DIR}/sass/gnome-shell/_common-temp.scss",
|
||||
"@import 'widgets-40-0';",
|
||||
f"@import 'widgets-{GS_VERSION}';",
|
||||
)
|
||||
|
||||
if GS_VERSION == "3-28":
|
||||
subst_text(
|
||||
f"{SRC_DIR}/sass/gnome-shell/_common-temp.scss",
|
||||
"@import 'extensions-40-0';",
|
||||
f"@import 'extensions-{GS_VERSION}';",
|
||||
)
|
||||
|
||||
def write_tweak(key, default, value):
|
||||
subst_text(
|
||||
f"{SRC_DIR}/sass/_tweaks-temp.scss", f"\\${key}: {default}", f"${key}: {value}"
|
||||
)
|
||||
|
||||
def apply_tweaks(ctx: BuildContext):
|
||||
write_tweak("theme", "'default'", f"'{ctx.accent.identifier}'")
|
||||
|
||||
if ctx.size == "compact":
|
||||
write_tweak("compact", "'false'", "'true'")
|
||||
|
||||
subst_text(
|
||||
f"{SRC_DIR}/sass/_tweaks-temp.scss",
|
||||
"@import 'color-palette-default';",
|
||||
f"@import 'color-palette-catppuccin-{ctx.flavor.identifier}';",
|
||||
)
|
||||
write_tweak("colorscheme", "'default'", "'catppuccin'")
|
||||
|
||||
if ctx.tweaks.has("black"):
|
||||
write_tweak("blackness", "'false'", "'true'")
|
||||
|
||||
if ctx.tweaks.has("rimless"):
|
||||
write_tweak("rimless", "'false'", "'true'")
|
||||
|
||||
if ctx.tweaks.has("normal"):
|
||||
write_tweak("window_button", "'mac'", "'normal'")
|
||||
|
||||
if ctx.tweaks.has("float"):
|
||||
write_tweak("float", "'false'", "'true'")
|
||||
|
||||
|
||||
def make_assets(ctx: BuildContext):
|
||||
output_dir = ctx.output_dir()
|
||||
|
||||
os.makedirs(f"{output_dir}/cinnamon/assets", exist_ok=True)
|
||||
for file in glob.glob(f"{SRC_DIR}/assets/cinnamon/theme/*.svg"):
|
||||
shutil.copy(file, f"{output_dir}/cinnamon/assets")
|
||||
shutil.copy(
|
||||
f"{SRC_DIR}/assets/cinnamon/thumbnail{ctx.apply_suffix(DARK_LIGHT)}.svg",
|
||||
f"{output_dir}/cinnamon/thumbnail.png",
|
||||
)
|
||||
|
||||
os.makedirs(f"{output_dir}/gnome-shell/assets", exist_ok=True)
|
||||
for file in glob.glob(f"{SRC_DIR}/assets/gnome-shell/theme/*.svg"):
|
||||
shutil.copy(file, f"{output_dir}/gnome-shell/assets")
|
||||
|
||||
shutil.copytree(
|
||||
f"{SRC_DIR}/assets/gtk/assets",
|
||||
f"{output_dir}/gtk-3.0/assets",
|
||||
dirs_exist_ok=True,
|
||||
)
|
||||
shutil.copytree(
|
||||
f"{SRC_DIR}/assets/gtk/assets",
|
||||
f"{output_dir}/gtk-4.0/assets",
|
||||
dirs_exist_ok=True,
|
||||
)
|
||||
shutil.copyfile(
|
||||
f"{SRC_DIR}/assets/gtk/thumbnail{ctx.apply_suffix(IS_DARK)}.svg",
|
||||
f"{output_dir}/gtk-3.0/thumbnail.png",
|
||||
)
|
||||
shutil.copyfile(
|
||||
f"{SRC_DIR}/assets/gtk/thumbnail{ctx.apply_suffix(IS_DARK)}.svg",
|
||||
f"{output_dir}/gtk-4.0/thumbnail.png",
|
||||
)
|
||||
|
||||
theme_color = ctx.accent.hex
|
||||
|
||||
palette = ctx.flavor.colors
|
||||
background = palette.base.hex
|
||||
background_alt = palette.mantle.hex
|
||||
titlebar = palette.overlay0.hex
|
||||
|
||||
for file in glob.glob(f"{output_dir}/cinnamon/assets/*.svg"):
|
||||
subst_text(file, "#5b9bf8", theme_color)
|
||||
subst_text(file, "#3c84f7", theme_color)
|
||||
|
||||
for file in glob.glob(f"{output_dir}/gnome-shell/assets/*.svg"):
|
||||
subst_text(file, "#5b9bf8", theme_color)
|
||||
subst_text(file, "#3c84f7", theme_color)
|
||||
|
||||
for file in glob.glob(f"{output_dir}/gtk-3.0/assets/*.svg"):
|
||||
subst_text(file, "#5b9bf8", theme_color)
|
||||
subst_text(file, "#3c84f7", theme_color)
|
||||
subst_text(file, "#ffffff", background)
|
||||
subst_text(file, "#2c2c2c", background)
|
||||
subst_text(file, "#3c3c3c", background_alt)
|
||||
|
||||
for file in glob.glob(f"{output_dir}/gtk-4.0/assets/*.svg"):
|
||||
subst_text(file, "#5b9bf8", theme_color)
|
||||
subst_text(file, "#3c84f7", theme_color)
|
||||
subst_text(file, "#ffffff", background)
|
||||
subst_text(file, "#2c2c2c", background)
|
||||
subst_text(file, "#3c3c3c", background_alt)
|
||||
|
||||
if ctx.flavor.dark:
|
||||
subst_text(f"{output_dir}/cinnamon/thumbnail.png", "#2c2c2c", background)
|
||||
subst_text(f"{output_dir}/cinnamon/thumbnail.png", "#5b9bf8", theme_color)
|
||||
|
||||
subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", "#2c2c2c", background)
|
||||
subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", "#2c2c2c", background)
|
||||
|
||||
subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", "#5b9bf8", theme_color)
|
||||
subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", "#5b9bf8", theme_color)
|
||||
else:
|
||||
subst_text(f"{output_dir}/cinnamon/thumbnail.png", "#ffffff", background)
|
||||
subst_text(f"{output_dir}/cinnamon/thumbnail.png", "#f2f2f2", titlebar)
|
||||
subst_text(f"{output_dir}/cinnamon/thumbnail.png", "#3c84f7", theme_color)
|
||||
|
||||
subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", "#f2f2f2", titlebar)
|
||||
subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", "#3c84f7", theme_color)
|
||||
|
||||
subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", "#f2f2f2", titlebar)
|
||||
subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", "#3c84f7", theme_color)
|
||||
|
||||
for file in glob.glob(f"{SRC_DIR}/assets/cinnamon/common-assets/*.svg"):
|
||||
shutil.copy(file, f"{output_dir}/cinnamon/assets")
|
||||
|
||||
for file in glob.glob(f"{SRC_DIR}/assets/cinnamon/assets{ctx.apply_suffix(IS_DARK)}/*.svg"):
|
||||
shutil.copy(file, f"{output_dir}/cinnamon/assets")
|
||||
|
||||
for file in glob.glob(f"{SRC_DIR}/assets/gnome-shell/common-assets/*.svg"):
|
||||
shutil.copy(file, f"{output_dir}/gnome-shell/assets")
|
||||
|
||||
for file in glob.glob(f"{SRC_DIR}/assets/gnome-shell/assets{ctx.apply_suffix(IS_DARK)}/*.svg"):
|
||||
shutil.copy(file, f"{output_dir}/gnome-shell/assets")
|
||||
|
||||
for file in glob.glob(f"{SRC_DIR}/assets/gtk/symbolics/*.svg"):
|
||||
shutil.copy(file, f"{output_dir}/gtk-3.0/assets")
|
||||
shutil.copy(file, f"{output_dir}/gtk-4.0/assets")
|
||||
|
||||
for file in glob.glob(f"{SRC_DIR}/assets/metacity-1/assets{ctx.apply_suffix(IS_WINDOW_NORMAL)}/*.svg"):
|
||||
shutil.copy(file, f"{output_dir}/metacity-1/assets")
|
||||
shutil.copy(
|
||||
f"{SRC_DIR}/assets/metacity-1/thumbnail{ctx.apply_suffix(IS_DARK)}.png",
|
||||
f"{output_dir}/metacity-1/thumbnail.png",
|
||||
)
|
||||
|
||||
xfwm4_assets = f"{THIS_DIR}/patches/xfwm4/generated/assets-catppuccin-{ctx.flavor.identifier}"
|
||||
for file in glob.glob(xfwm4_assets + '/*'):
|
||||
shutil.copy(file, f"{output_dir}/xfwm4")
|
||||
|
||||
xfwm4_assets = xfwm4_assets + "-hdpi/*"
|
||||
for file in glob.glob(xfwm4_assets):
|
||||
shutil.copy(file, f"{output_dir}-hdpi/xfwm4")
|
||||
|
||||
xfwm4_assets = xfwm4_assets + "-xhdpi/*"
|
||||
for file in glob.glob(xfwm4_assets):
|
||||
shutil.copy(file, f"{output_dir}-xhdpi/xfwm4")
|
||||
|
||||
|
||||
def zip_dir(path, zip_file):
|
||||
# Ref: https://stackoverflow.com/questions/46229764/python-zip-multiple-directories-into-one-zip-file
|
||||
for root, _, files in os.walk(path):
|
||||
for file in files:
|
||||
zip_file.write(
|
||||
os.path.join(root, file),
|
||||
os.path.relpath(os.path.join(root, file), os.path.join(path, "..")),
|
||||
)
|
||||
|
||||
|
||||
def zip_artifacts(dir_list, zip_name, remove=True):
|
||||
with zipfile.ZipFile(zip_name, "w", zipfile.ZIP_DEFLATED) as zipf:
|
||||
for dir in dir_list:
|
||||
zip_dir(dir, zipf)
|
||||
|
||||
if remove:
|
||||
for dir in dir_list:
|
||||
shutil.rmtree(dir)
|
||||
|
||||
|
||||
def build_theme(ctx: BuildContext):
|
||||
build_info = f"""Build info:
|
||||
build_root: {ctx.build_root}
|
||||
theme_name: {ctx.theme_name}
|
||||
flavor: {ctx.flavor.identifier}
|
||||
accent: {ctx.accent.identifier}
|
||||
size: {ctx.size}
|
||||
tweaks: {ctx.tweaks}"""
|
||||
logger.info(build_info)
|
||||
build(ctx)
|
||||
logger.info(f"Main build complete")
|
||||
|
||||
logger.info("Bundling assets...")
|
||||
make_assets(ctx)
|
||||
logger.info("Asset bundling done")
|
||||
|
||||
if ctx.output_format == "zip":
|
||||
zip_artifacts(
|
||||
[
|
||||
ctx.output_dir(),
|
||||
f"{ctx.output_dir()}-hdpi",
|
||||
f"{ctx.output_dir()}-xhdpi",
|
||||
],
|
||||
f"{ctx.build_root}/{ctx.build_id()}.zip",
|
||||
True,
|
||||
)
|
||||
|
||||
"""
|
||||
if (command -v xfce4-popup-whiskermenu &> /dev/null) && $(sed -i "s|.*menu-opacity=.*|menu-opacity=95|" "$HOME/.config/xfce4/panel/whiskermenu"*".rc" &> /dev/null); then
|
||||
sed -i "s|.*menu-opacity=.*|menu-opacity=95|" "$HOME/.config/xfce4/panel/whiskermenu"*".rc"
|
||||
fi
|
||||
|
||||
if (pgrep xfce4-session &> /dev/null); then
|
||||
xfce4-panel -r
|
||||
fi
|
||||
"""
|
||||
|
||||
|
||||
def apply_colloid_patches():
|
||||
if os.path.isfile("colloid/.patched"):
|
||||
logger.info(
|
||||
'Patches seem to be applied, remove "colloid/.patched" to force application (this may fail)'
|
||||
)
|
||||
return
|
||||
|
||||
logger.info("Applying patches...")
|
||||
# Change into colloid
|
||||
for patch in [
|
||||
"plank-dark.patch",
|
||||
"plank-light.patch",
|
||||
"theme-func.patch",
|
||||
"sass-palette-frappe.patch",
|
||||
"sass-palette-mocha.patch",
|
||||
"sass-palette-latte.patch",
|
||||
"sass-palette-macchiato.patch",
|
||||
]:
|
||||
path = f"./patches/colloid/{patch}"
|
||||
logger.info(f"Applying patch '{patch}', located at '{path}'")
|
||||
subprocess.check_call(["git", "apply", path, "--directory", f"colloid"])
|
||||
|
||||
with open("colloid/.patched", "w") as f:
|
||||
f.write("true")
|
||||
|
||||
logger.info("Patching finished.")
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"flavor",
|
||||
type=str,
|
||||
choices=["mocha", "frappe", "macchiato", "latte"],
|
||||
help="Flavor of the theme to apply.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--name",
|
||||
"-n",
|
||||
type=str,
|
||||
default="catppuccin",
|
||||
dest="name",
|
||||
help="Name of the theme to apply.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--dest",
|
||||
"-d",
|
||||
type=str,
|
||||
required=True,
|
||||
dest="dest",
|
||||
help="Destination of the files.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--accent",
|
||||
"-a",
|
||||
type=str,
|
||||
default="mauve",
|
||||
nargs='+',
|
||||
dest="accents",
|
||||
choices=[
|
||||
"rosewater",
|
||||
"flamingo",
|
||||
"pink",
|
||||
"mauve",
|
||||
"red",
|
||||
"maroon",
|
||||
"peach",
|
||||
"yellow",
|
||||
"green",
|
||||
"teal",
|
||||
"sky",
|
||||
"sapphire",
|
||||
"blue",
|
||||
"lavender",
|
||||
],
|
||||
help="Accent of the theme.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--all-accents",
|
||||
help="Whether to build all accents",
|
||||
dest="all_accents",
|
||||
action="store_true",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--size",
|
||||
"-s",
|
||||
type=str,
|
||||
default="standard",
|
||||
dest="size",
|
||||
choices=["standard", "compact"],
|
||||
help="Size variant of the theme.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--tweaks",
|
||||
type=str,
|
||||
default=[],
|
||||
nargs="+",
|
||||
dest="tweaks",
|
||||
choices=["black", "rimless", "normal", "float"],
|
||||
help="Tweaks to apply to the build.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--zip",
|
||||
help="Whether to bundle the theme into a zip",
|
||||
type=bool,
|
||||
default=False,
|
||||
action=argparse.BooleanOptionalAction,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--patch",
|
||||
help="Whether to patch the colloid submodule",
|
||||
type=bool,
|
||||
default=True,
|
||||
action=argparse.BooleanOptionalAction,
|
||||
)
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
if args.patch:
|
||||
apply_colloid_patches()
|
||||
|
||||
try:
|
||||
start = time.time()
|
||||
execute_build(git_root, args)
|
||||
end = time.time() - start
|
||||
if args.zip:
|
||||
output_format = "zip"
|
||||
else:
|
||||
output_format = "dir"
|
||||
|
||||
logger.info("")
|
||||
logger.info(f"Built in {round(end, 3)}s")
|
||||
except Exception as e:
|
||||
logger.error("Something went wrong when building the theme:", exc_info=e)
|
||||
tweaks = Tweaks(tweaks=args.tweaks)
|
||||
|
||||
palette = getattr(PALETTE, args.flavor)
|
||||
|
||||
accents = args.accents
|
||||
if args.all_accents:
|
||||
accents = [
|
||||
"rosewater",
|
||||
"flamingo",
|
||||
"pink",
|
||||
"mauve",
|
||||
"red",
|
||||
"maroon",
|
||||
"peach",
|
||||
"yellow",
|
||||
"green",
|
||||
"teal",
|
||||
"sky",
|
||||
"sapphire",
|
||||
"blue",
|
||||
"lavender",
|
||||
]
|
||||
|
||||
for accent in accents:
|
||||
accent = getattr(palette.colors, accent)
|
||||
|
||||
tweaks = Tweaks(tweaks=args.tweaks)
|
||||
|
||||
if args.zip:
|
||||
output_format = "zip"
|
||||
else:
|
||||
output_format = "dir"
|
||||
ctx = BuildContext(
|
||||
build_root=args.dest,
|
||||
theme_name=args.name,
|
||||
flavor=palette,
|
||||
accent=accent,
|
||||
size=args.size,
|
||||
tweaks=tweaks,
|
||||
output_format=output_format,
|
||||
)
|
||||
logger.info("Building temp tweaks file")
|
||||
init_tweaks_temp()
|
||||
logger.info("Inserting gnome-shell imports")
|
||||
gnome_shell_version()
|
||||
logger.info("Building main theme")
|
||||
build_theme(ctx)
|
||||
logger.info(f"Completed {palette.identifier} with {accent.identifier}")
|
||||
|
||||
logger.info("Done!")
|
||||
|
||||
try:
|
||||
main()
|
||||
except Exception as e:
|
||||
logger.error("Something went wrong when building the theme:", exc_info=e)
|
||||
sys.exit(1)
|
||||
|
@@ -1,14 +0,0 @@
|
||||
# This dockerfile generates a container with the needed dependencies to build the theme
|
||||
|
||||
FROM python:alpine
|
||||
|
||||
RUN apk add sassc inkscape optipng
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY requirements.txt .
|
||||
|
||||
RUN pip install --no-cache-dir -r requirements.txt && rm requirements.txt
|
||||
|
||||
# The reason for this is to allow the GH Actions Workflow execute commands within the container
|
||||
CMD ["sleep", "infinity"]
|
@@ -1,83 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Default value for custom_version
|
||||
VERSION="no"
|
||||
|
||||
while getopts v:h opt 2>/dev/null; do
|
||||
case "$opt" in
|
||||
v)
|
||||
VERSION=$OPTARG
|
||||
;;
|
||||
h)
|
||||
echo "\
|
||||
Usage: $0 [-v <version>]
|
||||
|
||||
Push script for Catppuccin's GTK docker build image
|
||||
|
||||
-v Custom version to build the image (<your-image-name>:<version>)
|
||||
If you only want to generate the image with tag 'latest' use '-v no'
|
||||
-h Print this help text" >&2
|
||||
exit 0
|
||||
;;
|
||||
?)
|
||||
echo "Usage: $0 [-h]" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
if [ $# -eq 0 ]
|
||||
then
|
||||
echo "Usage: $0 [-h]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Resolve the absolute path of the script without readlink
|
||||
SCRIPT_PATH="$0"
|
||||
|
||||
# Check if SCRIPT_PATH is a symbolic link
|
||||
while [ -h "$SCRIPT_PATH" ]; do
|
||||
LS=$(ls -ld "$SCRIPT_PATH")
|
||||
LINK=$(expr "$LS" : '.*-> \(.*\)$')
|
||||
if expr "$LINK" : '/.*' > /dev/null; then
|
||||
SCRIPT_PATH="$LINK"
|
||||
else
|
||||
SCRIPT_PATH=$(dirname "$SCRIPT_PATH")/"$LINK"
|
||||
fi
|
||||
done
|
||||
|
||||
# Ensure we have an absolute path
|
||||
case "$SCRIPT_PATH" in
|
||||
/*) ;;
|
||||
*) SCRIPT_PATH="$(pwd)/$SCRIPT_PATH" ;;
|
||||
esac
|
||||
|
||||
# Path to script' dir
|
||||
SCRIPT_DIR=$(cd "$(dirname "$SCRIPT_PATH")" && pwd)
|
||||
|
||||
# Path to the Dockerfile
|
||||
DOCKERFILE_PATH="$SCRIPT_DIR/Dockerfile"
|
||||
|
||||
# Docker variables
|
||||
IMAGE_NAME="ghcr.io/catppuccin/gtk"
|
||||
|
||||
# Detect podman
|
||||
if command -v podman > /dev/null 2>&1; then
|
||||
CONTAINER_TOOL="podman"
|
||||
elif command -v docker > /dev/null 2>&1; then
|
||||
CONTAINER_TOOL="docker"
|
||||
else
|
||||
echo "Error: Neither podman nor docker is installed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Clean previous generated images
|
||||
$CONTAINER_TOOL image rm "$IMAGE_NAME:latest" 2> /dev/null
|
||||
$CONTAINER_TOOL image rm "$IMAGE_NAME:$VERSION" 2> /dev/null
|
||||
|
||||
# Build the Docker image with latest tag
|
||||
$CONTAINER_TOOL build -t "$IMAGE_NAME:latest" -f "$DOCKERFILE_PATH" "$SCRIPT_DIR/.."
|
||||
|
||||
# Execute docker tag command if VERSION is not "no"
|
||||
if [ "$VERSION" != "no" ]; then
|
||||
$CONTAINER_TOOL tag "$IMAGE_NAME:latest" "$IMAGE_NAME:$VERSION"
|
||||
fi
|
@@ -1,66 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Default value for parameters
|
||||
VERSION="no"
|
||||
USERNAME="no"
|
||||
PASSWORD="no"
|
||||
|
||||
while getopts u:p:v:h opt 2>/dev/null; do
|
||||
case "$opt" in
|
||||
v)
|
||||
VERSION=$OPTARG
|
||||
;;
|
||||
u)
|
||||
USERNAME=$OPTARG
|
||||
;;
|
||||
p)
|
||||
PASSWORD=$OPTARG
|
||||
;;
|
||||
h)
|
||||
echo "\
|
||||
Usage: $0 [-v <version> | -u [your-github-username] | -p [your-github-password]]
|
||||
|
||||
Push script for Catppuccin's GTK docker build image
|
||||
|
||||
-v Custom version to push the image (<your-image-name>:<version>)
|
||||
-u Your GitHub username that will be used to log into GHCR
|
||||
-p Your GitHub password that will be used to log into GHCR
|
||||
-h Print this help text" >&2
|
||||
exit 0
|
||||
;;
|
||||
?)
|
||||
echo "Usage: $0 [-h]" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
if [ $# -eq 0 ]
|
||||
then
|
||||
echo "Usage: $0 [-h]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# Detect podman
|
||||
if command -v podman > /dev/null 2>&1; then
|
||||
CONTAINER_TOOL="podman"
|
||||
elif command -v docker > /dev/null 2>&1; then
|
||||
CONTAINER_TOOL="docker"
|
||||
else
|
||||
echo "Error: Neither podman nor docker is installed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Docker variables
|
||||
IMAGE_NAME="ghcr.io/catppuccin/gtk"
|
||||
|
||||
# Log into ghcr
|
||||
$CONTAINER_TOOL login ghcr.io -u $USERNAME --password $PASSWORD
|
||||
|
||||
# Push docker image with latest tag
|
||||
$CONTAINER_TOOL push "$IMAGE_NAME:latest"
|
||||
|
||||
# Execute docker push for specific version if VERSION is not "no"
|
||||
if [ "$VERSION" != "no" ]; then
|
||||
$CONTAINER_TOOL push "$IMAGE_NAME:$VERSION"
|
||||
fi
|
@@ -1,74 +0,0 @@
|
||||
## Build pipeline
|
||||
|
||||
The GTK port has a fairly complicated build pipeline / system, chiefly stemming from our use of Colloid as a base theme.
|
||||
We use Colloid as a base to reduce development overhead of creating our own theme from scratch, we look to replace this in the future
|
||||
to give us more flexibility and control over the theme (see https://github.com/catppuccin/gtk/issues/164).
|
||||
|
||||
We have reimplemented Colloid's build system (previously implemented in Shell) in Python to make it easier to maintain, extend, and iterate on.
|
||||
With this re-implementation, we have several distinct components in the system, described below:
|
||||
1) Patching
|
||||
2) SCSS
|
||||
2) Assets
|
||||
|
||||
## Patching
|
||||
|
||||
We patch our colloid submodule to add additional functionality and (temporarily) fix bugs found in Colloid.
|
||||
We do this through `.patch` files, applied with `git apply` when the build script boots up.
|
||||
The build script will store some state in the submodule to ensure it does not get needlessly patched.
|
||||
|
||||
The patches are stored in `patches/colloid`, and currently have our palette, the Plank theme, and a modification to Colloid
|
||||
to allow all of our accents to load. When we find issues in Colloid, they will be patched through this system before being submitted upstream.
|
||||
|
||||
## SCSS
|
||||
|
||||
[This section assumes the directory root is at `colliod/src/sass`]
|
||||
|
||||
The bulk of the theme is implemented here, in SCSS. This is by far the most modular part of Colloid out of the box, requiring minimal patching from our end to function.
|
||||
To start, we move the Colloid submodule into its own temporary copy. This is to allow us to run multiple builds in parallel, which would be otherwise impossible due to the
|
||||
file changes necessitated by each build, described below.
|
||||
|
||||
With our temporary copy established, we generate the 'tweaks' for the build. This sets up a file (`_tweaks-temp.scss`) which describes the various knobs and dials for the build:
|
||||
```scss
|
||||
@import 'color-palette-catppuccin-mocha';
|
||||
|
||||
$colorscheme: 'catppuccin';
|
||||
$colortype: 'system';
|
||||
$opacity: 'default';
|
||||
$theme: 'mauve';
|
||||
$compact: 'false';
|
||||
$translucent: 'false';
|
||||
$panel_opacity: 1.0;
|
||||
$blackness: 'false';
|
||||
$rimless: 'false';
|
||||
$window_button: 'mac';
|
||||
$float: 'false';
|
||||
```
|
||||
We edit in the correct palette import for the flavour we're building, and set the other variables based on user / build state input.
|
||||
|
||||
With the tweaks setup, we can now invoke `sassc` (the SCSS compiler) to build all of our CSS files. We run all of the SCSS builds in parallel, for performance.
|
||||
With the SCSS complete, we have now finished most of the work required for the build.
|
||||
|
||||
|
||||
## Assets
|
||||
|
||||
We build our own assets to ship with the theme, based on the processes used in Colloid.
|
||||
|
||||
We build assets for GTK, to include UI elements such as buttons, checkboxes,
|
||||
etc. This is done through standard find-and-replace, as these assets are just SVGs. We do not support GTK2, so do not have to support the older PNG assets used there.
|
||||
|
||||
We also build assets for Xfce's Xfwm4, which are first patched from a source SVG, and then rendered through the `inkscape` CLI.
|
||||
This operation is done once, at the start of a build process (e.g CI, to be reused for every subsequent build), or once until they change in the future for local development.
|
||||
The script to generate these assets can be found at [`patches/xfwm4/generate_assets.py`](./patches/xfwm4/generate_assets.py)
|
||||
|
||||
|
||||
## CI integration
|
||||
|
||||
The CI system utilizes the build system, as described above, but with some unique parallelization elements to improve performance.
|
||||
We have chosen to only build a limited subset of possible tweaks in CI, to constrain the time it takes to run.
|
||||
|
||||
Currently, we build a matrix of:
|
||||
- Flavor
|
||||
- Accent
|
||||
|
||||
The CI will run all 4 flavours in parallel (see above for precautions taken to ensure this functions correctly), and build each accent serially.
|
||||
We collate the logs for these runs into files so that they can be shown neatly at the end of the run.
|
@@ -1,15 +0,0 @@
|
||||
# Changelog
|
||||
|
||||
## [1.0.2](https://github.com/catppuccin/gtk/compare/v1.0.1...v1.0.2) (2024-05-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* alt tab menu ([#209](https://github.com/catppuccin/gtk/issues/209)) ([cae57c8](https://github.com/catppuccin/gtk/commit/cae57c80f81fd1cc40fab2655109b09fa97103b9))
|
||||
|
||||
## [1.0.1](https://github.com/catppuccin/gtk/compare/v1.0.0...v1.0.1) (2024-05-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* alt tab menu ([#209](https://github.com/catppuccin/gtk/issues/209)) ([cae57c8](https://github.com/catppuccin/gtk/commit/cae57c80f81fd1cc40fab2655109b09fa97103b9))
|
20
install.py
@@ -1,15 +1,11 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import zipfile
|
||||
import argparse
|
||||
import logging
|
||||
import io
|
||||
|
||||
import os, zipfile, argparse, logging, io
|
||||
from typing import Optional
|
||||
from pathlib import Path
|
||||
from dataclasses import dataclass
|
||||
from urllib.request import urlopen, Request
|
||||
from urllib.parse import urlparse
|
||||
|
||||
logger = logging.getLogger("catppuccin-gtk")
|
||||
logger.setLevel(logging.DEBUG)
|
||||
@@ -97,11 +93,10 @@ def parse_args():
|
||||
|
||||
|
||||
def build_release_url(ctx: InstallContext) -> str:
|
||||
repo_root = "https://github.com/catppuccin/gtk/releases/download"
|
||||
release = "v1.0.4" # x-release-please-version
|
||||
root = "https://github.com/catppuccin/gtk/releases/latest/download"
|
||||
zip_name = f"catppuccin-{ctx.flavor}-{ctx.accent}-standard+default.zip"
|
||||
|
||||
return f"{repo_root}/{release}/{zip_name}"
|
||||
return f"{root}/{zip_name}"
|
||||
|
||||
|
||||
def fetch_zip(url: str) -> Optional[zipfile.ZipFile]:
|
||||
@@ -124,11 +119,8 @@ def fetch_zip(url: str) -> Optional[zipfile.ZipFile]:
|
||||
|
||||
|
||||
def add_libadwaita_links(ctx: InstallContext, rewrite: bool = False):
|
||||
suffix = "light"
|
||||
if ctx.flavor != "latte":
|
||||
suffix = "dark"
|
||||
dir_name = (
|
||||
ctx.dest / f"catppuccin-{ctx.flavor}-{ctx.accent}-standard+default-{suffix}" / "gtk-4.0"
|
||||
ctx.dest / f"catppuccin-{ctx.flavor}-{ctx.accent}-standard+default" / "gtk-4.0"
|
||||
).absolute()
|
||||
gtk4_dir = (Path(os.path.expanduser("~")) / ".config" / "gtk-4.0").absolute()
|
||||
os.makedirs(gtk4_dir, exist_ok=True)
|
||||
@@ -164,7 +156,6 @@ def install(ctx: InstallContext):
|
||||
if ctx.link:
|
||||
add_libadwaita_links(ctx)
|
||||
|
||||
|
||||
def install_from_artifact(ctx: InstallContext, artifact_path: Path):
|
||||
# Working from a pull request, special case it
|
||||
logger.info(f"Extracting artifact from '{artifact_path}'")
|
||||
@@ -194,7 +185,6 @@ def install_from_artifact(ctx: InstallContext, artifact_path: Path):
|
||||
add_libadwaita_links(ctx, True)
|
||||
logger.info("Links added")
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
|
||||
|
@@ -77,7 +77,7 @@ index 00000000..4ff0da0d
|
||||
+$grey-600: red;
|
||||
+$grey-650: #{{ palette.surface0.hex }};
|
||||
+$grey-700: #{{ palette.base.hex }};
|
||||
+$grey-750: #{{ palette.mantle.hex }};
|
||||
+$grey-750: #{{ palette.crust.hex }};
|
||||
+$grey-800: #{{ palette.crust.hex }};
|
||||
+$grey-850: #020202;
|
||||
+$grey-900: #010101;
|
@@ -68,7 +68,7 @@ index 00000000..4ff0da0d
|
||||
+$grey-600: red;
|
||||
+$grey-650: #414559;
|
||||
+$grey-700: #303446;
|
||||
+$grey-750: #292c3c;
|
||||
+$grey-750: #232634;
|
||||
+$grey-800: #232634;
|
||||
+$grey-850: #020202;
|
||||
+$grey-900: #010101;
|
@@ -68,7 +68,7 @@ index 00000000..4ff0da0d
|
||||
+$grey-600: red;
|
||||
+$grey-650: #363a4f;
|
||||
+$grey-700: #24273a;
|
||||
+$grey-750: #1e2030;
|
||||
+$grey-750: #181926;
|
||||
+$grey-800: #181926;
|
||||
+$grey-850: #020202;
|
||||
+$grey-900: #010101;
|
@@ -68,7 +68,7 @@ index 00000000..4ff0da0d
|
||||
+$grey-600: red;
|
||||
+$grey-650: #313244;
|
||||
+$grey-700: #1e1e2e;
|
||||
+$grey-750: #181825;
|
||||
+$grey-750: #11111b;
|
||||
+$grey-800: #11111b;
|
||||
+$grey-850: #020202;
|
||||
+$grey-900: #010101;
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
@@ -2,11 +2,7 @@ from typing import List
|
||||
from catppuccin import PALETTE
|
||||
from catppuccin.models import Flavor
|
||||
|
||||
import re
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import time
|
||||
import re, os, shutil, subprocess, time
|
||||
from dataclasses import dataclass
|
||||
|
||||
THIS_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||
@@ -87,9 +83,9 @@ def generate_for_flavor(flavor: Flavor):
|
||||
# Setup the palette
|
||||
palette = flavor.colors
|
||||
|
||||
close_color = f"#{palette.red.hex}"
|
||||
max_color = f"#{palette.green.hex}"
|
||||
min_color = f"#{palette.yellow.hex}"
|
||||
close_color=f'#{palette.red.hex}'
|
||||
max_color=f'#{palette.green.hex}'
|
||||
min_color=f'#{palette.yellow.hex}'
|
||||
|
||||
# We expand the source assets into the 4 flavors, but need to map between
|
||||
# Their definition of dark and ours. This means that latte will get the -light assets
|
||||
@@ -155,9 +151,6 @@ def call_subprocesses(inp: WorkerInput):
|
||||
return [
|
||||
subprocess.Popen(
|
||||
[
|
||||
# FIXME: https://gitlab.com/inkscape/inkscape/-/issues/4716#note_1882967469Z
|
||||
"unshare",
|
||||
"--user",
|
||||
inkscape,
|
||||
"--export-id",
|
||||
inp.ident,
|
||||
@@ -191,9 +184,8 @@ screen_to_dpi = {
|
||||
"-xhdpi": "192",
|
||||
}
|
||||
|
||||
|
||||
def render_for_screen(state: RenderState, flavor: Flavor, screen: str, ident: str):
|
||||
# NOTE: We do not generate for the -normal variant currently, that would just be
|
||||
# NOTE: We do not generate for the -normal variant currently, that would just be
|
||||
# a stupid amount of compute and time for little benefit
|
||||
src_file = f"{state.input_root}/assets-catppuccin-{flavor.identifier}.svg"
|
||||
|
||||
@@ -220,7 +212,9 @@ def render_for_screen(state: RenderState, flavor: Flavor, screen: str, ident: st
|
||||
|
||||
|
||||
def render_for_flavor(flavor: Flavor, state: RenderState):
|
||||
print(f"Starting render tasks for {flavor.identifier}")
|
||||
print(
|
||||
f"Starting render tasks for {flavor.identifier}"
|
||||
)
|
||||
for ident in INDEX:
|
||||
render_for_screen(state=state, flavor=flavor, screen="", ident=ident)
|
||||
render_for_screen(state=state, flavor=flavor, screen="-hdpi", ident=ident)
|
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"last-release-sha": "8b54c05ff5de6c7fabc68fab410cfd093a91193c",
|
||||
"draft": true,
|
||||
"packages": {
|
||||
".": {
|
||||
"package-name": "",
|
||||
"release-type": "simple",
|
||||
"extra-files": [
|
||||
{ "type": "generic", "path": "README.md" },
|
||||
{ "type": "generic", "path": "install.py" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
|
||||
}
|
@@ -1,74 +0,0 @@
|
||||
from argparse import Namespace
|
||||
import shutil
|
||||
|
||||
from .patches import apply_colloid_patches
|
||||
from .theme import build_with_context, gnome_shell_version
|
||||
from .utils import init_tweaks_temp
|
||||
from .context import Tweaks, BuildContext
|
||||
from .logger import logger
|
||||
from catppuccin import PALETTE
|
||||
|
||||
|
||||
def execute_build(git_root: str, args: Namespace):
|
||||
|
||||
colloid_dir = f"{git_root}/sources/colloid"
|
||||
colloid_tmp_dir = f"{git_root}/.tmp/colloid-tmp-{args.flavor}"
|
||||
shutil.copytree(colloid_dir, colloid_tmp_dir)
|
||||
src_dir = colloid_tmp_dir + "/src"
|
||||
|
||||
tweaks = Tweaks(tweaks=args.tweaks)
|
||||
palette = getattr(PALETTE, args.flavor)
|
||||
output_format = "zip" if args.zip else "dir"
|
||||
|
||||
if args.patch:
|
||||
patch_dir = git_root + "/sources/patches/colloid/"
|
||||
apply_colloid_patches(colloid_tmp_dir, patch_dir)
|
||||
|
||||
accents = args.accents
|
||||
if args.all_accents:
|
||||
accents = [
|
||||
"rosewater",
|
||||
"flamingo",
|
||||
"pink",
|
||||
"mauve",
|
||||
"red",
|
||||
"maroon",
|
||||
"peach",
|
||||
"yellow",
|
||||
"green",
|
||||
"teal",
|
||||
"sky",
|
||||
"sapphire",
|
||||
"blue",
|
||||
"lavender",
|
||||
]
|
||||
|
||||
for accent in accents:
|
||||
accent = getattr(palette.colors, accent)
|
||||
|
||||
ctx = BuildContext(
|
||||
output_root=args.dest,
|
||||
colloid_src_dir=src_dir,
|
||||
git_root=git_root,
|
||||
theme_name=args.name,
|
||||
flavor=palette,
|
||||
accent=accent,
|
||||
size=args.size,
|
||||
tweaks=tweaks,
|
||||
output_format=output_format,
|
||||
)
|
||||
|
||||
logger.info("Building temp tweaks file")
|
||||
init_tweaks_temp(src_dir)
|
||||
|
||||
logger.info("Inserting gnome-shell imports")
|
||||
gnome_shell_version(src_dir)
|
||||
|
||||
logger.info("Building main theme")
|
||||
build_with_context(ctx)
|
||||
|
||||
logger.info(f"Completed {palette.identifier} with {accent.identifier}")
|
||||
print()
|
||||
|
||||
shutil.rmtree(colloid_tmp_dir)
|
||||
logger.info("Done!")
|
@@ -1,100 +0,0 @@
|
||||
import argparse
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"flavor",
|
||||
type=str,
|
||||
choices=["mocha", "frappe", "macchiato", "latte"],
|
||||
help="Flavor of the theme to apply.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--name",
|
||||
"-n",
|
||||
type=str,
|
||||
default="catppuccin",
|
||||
dest="name",
|
||||
help="Name of the theme to apply.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--dest",
|
||||
"-d",
|
||||
type=str,
|
||||
required=True,
|
||||
dest="dest",
|
||||
help="Destination of the files.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--accent",
|
||||
"-a",
|
||||
type=str,
|
||||
default="mauve",
|
||||
nargs="+",
|
||||
dest="accents",
|
||||
choices=[
|
||||
"rosewater",
|
||||
"flamingo",
|
||||
"pink",
|
||||
"mauve",
|
||||
"red",
|
||||
"maroon",
|
||||
"peach",
|
||||
"yellow",
|
||||
"green",
|
||||
"teal",
|
||||
"sky",
|
||||
"sapphire",
|
||||
"blue",
|
||||
"lavender",
|
||||
],
|
||||
help="Accent of the theme.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--all-accents",
|
||||
help="Whether to build all accents",
|
||||
dest="all_accents",
|
||||
action="store_true",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--size",
|
||||
"-s",
|
||||
type=str,
|
||||
default="standard",
|
||||
dest="size",
|
||||
choices=["standard", "compact"],
|
||||
help="Size variant of the theme.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--tweaks",
|
||||
type=str,
|
||||
default=[],
|
||||
nargs="+",
|
||||
dest="tweaks",
|
||||
choices=["black", "rimless", "normal", "float"],
|
||||
help="Tweaks to apply to the build.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--zip",
|
||||
help="Whether to bundle the theme into a zip",
|
||||
type=bool,
|
||||
default=False,
|
||||
action=argparse.BooleanOptionalAction,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--patch",
|
||||
help="Whether to patch the colloid submodule",
|
||||
type=bool,
|
||||
default=True,
|
||||
action=argparse.BooleanOptionalAction,
|
||||
)
|
||||
|
||||
return parser.parse_args()
|
@@ -1,69 +0,0 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Literal, List
|
||||
from catppuccin.models import Flavor, Color
|
||||
from .utils import find_and_replace, Subsitution
|
||||
|
||||
|
||||
@dataclass
|
||||
class Tweaks:
|
||||
tweaks: List[str]
|
||||
|
||||
def has(self, tweak: str) -> bool:
|
||||
return tweak in self.tweaks
|
||||
|
||||
def id(self) -> str:
|
||||
return ",".join(self.tweaks)
|
||||
|
||||
|
||||
@dataclass
|
||||
class Suffix:
|
||||
true_value: str
|
||||
test: Any
|
||||
false_value: str = ""
|
||||
|
||||
|
||||
@dataclass
|
||||
class BuildContext:
|
||||
# The src dir of the Colloid copy to operate on
|
||||
colloid_src_dir: str
|
||||
|
||||
# The root of the project
|
||||
git_root: str
|
||||
|
||||
# The root of the output dir (as specified by --dest if given)
|
||||
output_root: str
|
||||
|
||||
output_format: Literal["zip"] | Literal["dir"]
|
||||
|
||||
theme_name: str
|
||||
flavor: Flavor
|
||||
accent: Color
|
||||
size: Literal["standard"] | Literal["compact"]
|
||||
tweaks: Tweaks
|
||||
|
||||
def output_dir(self) -> str:
|
||||
return f"{self.output_root}/{self.build_id()}"
|
||||
|
||||
def build_id(self) -> str:
|
||||
return f"{self.theme_name}-{self.flavor.identifier}-{self.accent.identifier}-{self.size}+{self.tweaks.id() or 'default'}"
|
||||
|
||||
def apply_suffix(self, suffix: Suffix) -> str:
|
||||
if suffix.test(self):
|
||||
return suffix.true_value
|
||||
else:
|
||||
return suffix.false_value
|
||||
|
||||
def apply_tweak(self, key, default, value):
|
||||
find_and_replace(
|
||||
f"{self.colloid_src_dir}/sass/_tweaks-temp.scss",
|
||||
Subsitution(find=f"\\${key}: {default}", replace=f"${key}: {value}"),
|
||||
)
|
||||
|
||||
IS_DARK = Suffix(true_value="-Dark", test=lambda ctx: ctx.flavor.dark)
|
||||
IS_LIGHT = Suffix(true_value="-Light", test=lambda ctx: not ctx.flavor.dark)
|
||||
IS_WINDOW_NORMAL = Suffix(
|
||||
true_value="-Normal", test=lambda ctx: ctx.tweaks.has("normal")
|
||||
)
|
||||
DARK_LIGHT = Suffix(
|
||||
true_value="-Dark", false_value="-Light", test=lambda ctx: ctx.flavor.dark
|
||||
)
|
@@ -1,9 +0,0 @@
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger("catppuccin-gtk")
|
||||
|
||||
logger.setLevel(logging.DEBUG)
|
||||
ch = logging.StreamHandler()
|
||||
formatter = logging.Formatter("[%(name)s] [%(levelname)s] - %(message)s")
|
||||
ch.setFormatter(formatter)
|
||||
logger.addHandler(ch)
|
@@ -1,35 +0,0 @@
|
||||
import os
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from .logger import logger
|
||||
|
||||
|
||||
def apply_colloid_patches(colloid_dir, patch_dir):
|
||||
colloid_dir = Path(colloid_dir).relative_to(os.getcwd())
|
||||
if os.path.isfile(colloid_dir / ".patched"):
|
||||
logger.info(
|
||||
f'Patches seem to be applied, remove "{colloid_dir}/.patched" to force application (this may fail)'
|
||||
)
|
||||
return
|
||||
|
||||
logger.info("Applying patches...")
|
||||
# Change into colloid
|
||||
for patch in [
|
||||
"plank-dark.patch",
|
||||
"plank-light.patch",
|
||||
"sass-palette-frappe.patch",
|
||||
"sass-palette-mocha.patch",
|
||||
"sass-palette-latte.patch",
|
||||
"sass-palette-macchiato.patch",
|
||||
"theme-func.patch",
|
||||
]:
|
||||
path = (Path(patch_dir) / patch).relative_to(os.getcwd())
|
||||
logger.info(f"Applying patch '{patch}', located at '{path}'")
|
||||
subprocess.check_call(
|
||||
["git", "apply", str(path), "--directory", str(colloid_dir)]
|
||||
)
|
||||
|
||||
with open(colloid_dir / ".patched", "w") as f:
|
||||
f.write("true")
|
||||
|
||||
logger.info("Patching finished.")
|
@@ -1,390 +0,0 @@
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import glob
|
||||
import zipfile
|
||||
from .logger import logger
|
||||
from .utils import find_and_replace, Subsitution
|
||||
from .context import BuildContext, IS_DARK, IS_LIGHT, IS_WINDOW_NORMAL, DARK_LIGHT
|
||||
|
||||
|
||||
def apply_tweaks(ctx: BuildContext):
|
||||
ctx.apply_tweak("theme", "'default'", f"'{ctx.accent.identifier}'")
|
||||
|
||||
if ctx.size == "compact":
|
||||
ctx.apply_tweak("compact", "'false'", "'true'")
|
||||
|
||||
find_and_replace(
|
||||
f"{ctx.colloid_src_dir}/sass/_tweaks-temp.scss",
|
||||
Subsitution(
|
||||
find="@import 'color-palette-default';",
|
||||
replace=f"@import 'color-palette-catppuccin-{ctx.flavor.identifier}';",
|
||||
),
|
||||
)
|
||||
ctx.apply_tweak("colorscheme", "'default'", "'catppuccin'")
|
||||
|
||||
if ctx.tweaks.has("black"):
|
||||
ctx.apply_tweak("blackness", "'false'", "'true'")
|
||||
|
||||
if ctx.tweaks.has("rimless"):
|
||||
ctx.apply_tweak("rimless", "'false'", "'true'")
|
||||
|
||||
if ctx.tweaks.has("normal"):
|
||||
ctx.apply_tweak("window_button", "'mac'", "'normal'")
|
||||
|
||||
if ctx.tweaks.has("float"):
|
||||
ctx.apply_tweak("float", "'false'", "'true'")
|
||||
|
||||
|
||||
SASSC_OPT = ["-M", "-t", "expanded"]
|
||||
|
||||
|
||||
def compile_sass(src: str, dest: str) -> subprocess.Popen:
|
||||
return subprocess.Popen(["sassc", *SASSC_OPT, src, dest])
|
||||
|
||||
|
||||
def execute_build(ctx: BuildContext):
|
||||
src_dir = ctx.colloid_src_dir
|
||||
output_dir = ctx.output_dir()
|
||||
|
||||
logger.info(f"Building into '{output_dir}'...")
|
||||
|
||||
apply_tweaks(ctx)
|
||||
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
with open(f"{output_dir}/index.theme", "w") as file:
|
||||
file.write("[Desktop Entry]\n")
|
||||
file.write("Type=X-GNOME-Metatheme\n")
|
||||
file.write(f"Name={ctx.build_id()}\n")
|
||||
file.write("Comment=An Flat Gtk+ theme based on Elegant Design\n")
|
||||
file.write("Encoding=UTF-8\n")
|
||||
file.write("\n")
|
||||
file.write("[X-GNOME-Metatheme]\n")
|
||||
file.write(f"GtkTheme={ctx.build_id()}\n")
|
||||
file.write(f"MetacityTheme={ctx.build_id()}\n")
|
||||
file.write(f"IconTheme=Tela-circle{ctx.apply_suffix(IS_DARK)}\n")
|
||||
file.write(f"CursorTheme={ctx.flavor.name}-cursors\n")
|
||||
file.write("ButtonLayout=close,minimize,maximize:menu\n")
|
||||
|
||||
sassc_tasks = []
|
||||
|
||||
os.makedirs(f"{output_dir}/gnome-shell", exist_ok=True)
|
||||
shutil.copyfile(
|
||||
f"{src_dir}/main/gnome-shell/pad-osd.css",
|
||||
f"{output_dir}/gnome-shell/pad-osd.css",
|
||||
)
|
||||
|
||||
sassc_tasks.append(
|
||||
compile_sass(
|
||||
f"{src_dir}/main/gnome-shell/gnome-shell{ctx.apply_suffix(DARK_LIGHT)}.scss",
|
||||
f"{output_dir}/gnome-shell/gnome-shell.css",
|
||||
)
|
||||
)
|
||||
|
||||
os.makedirs(f"{output_dir}/gtk-3.0", exist_ok=True)
|
||||
sassc_tasks.append(
|
||||
compile_sass(
|
||||
f"{src_dir}/main/gtk-3.0/gtk{ctx.apply_suffix(DARK_LIGHT)}.scss",
|
||||
f"{output_dir}/gtk-3.0/gtk.css",
|
||||
)
|
||||
)
|
||||
sassc_tasks.append(
|
||||
compile_sass(
|
||||
f"{src_dir}/main/gtk-3.0/gtk-Dark.scss",
|
||||
f"{output_dir}/gtk-3.0/gtk-dark.css",
|
||||
)
|
||||
)
|
||||
|
||||
os.makedirs(f"{output_dir}/gtk-4.0", exist_ok=True)
|
||||
sassc_tasks.append(
|
||||
compile_sass(
|
||||
f"{src_dir}/main/gtk-4.0/gtk{ctx.apply_suffix(DARK_LIGHT)}.scss",
|
||||
f"{output_dir}/gtk-4.0/gtk.css",
|
||||
)
|
||||
)
|
||||
sassc_tasks.append(
|
||||
compile_sass(
|
||||
f"{src_dir}/main/gtk-4.0/gtk-Dark.scss",
|
||||
f"{output_dir}/gtk-4.0/gtk-dark.css",
|
||||
)
|
||||
)
|
||||
|
||||
os.makedirs(f"{output_dir}/cinnamon", exist_ok=True)
|
||||
sassc_tasks.append(
|
||||
compile_sass(
|
||||
f"{src_dir}/main/cinnamon/cinnamon{ctx.apply_suffix(DARK_LIGHT)}.scss",
|
||||
f"{output_dir}/cinnamon/cinnamon.css",
|
||||
)
|
||||
)
|
||||
|
||||
for task in sassc_tasks:
|
||||
task.wait()
|
||||
|
||||
os.makedirs(f"{output_dir}/metacity-1", exist_ok=True)
|
||||
shutil.copyfile(
|
||||
f"{src_dir}/main/metacity-1/metacity-theme-3{ctx.apply_suffix(IS_WINDOW_NORMAL)}.xml",
|
||||
f"{output_dir}/metacity-1/metacity-theme-3.xml",
|
||||
)
|
||||
|
||||
os.makedirs(f"{output_dir}/xfwm4", exist_ok=True)
|
||||
shutil.copyfile(
|
||||
f"{src_dir}/main/xfwm4/themerc{ctx.apply_suffix(IS_LIGHT)}",
|
||||
f"{output_dir}/xfwm4/themerc",
|
||||
)
|
||||
|
||||
os.makedirs(f"{output_dir}-hdpi/xfwm4", exist_ok=True)
|
||||
shutil.copyfile(
|
||||
f"{src_dir}/main/xfwm4/themerc{ctx.apply_suffix(IS_LIGHT)}",
|
||||
f"{output_dir}-hdpi/xfwm4/themerc",
|
||||
)
|
||||
find_and_replace(
|
||||
f"{output_dir}-hdpi/xfwm4/themerc",
|
||||
Subsitution(find="button_offset=6", replace="button_offset=9"),
|
||||
)
|
||||
|
||||
os.makedirs(f"{output_dir}-xhdpi/xfwm4", exist_ok=True)
|
||||
shutil.copyfile(
|
||||
f"{src_dir}/main/xfwm4/themerc{ctx.apply_suffix(IS_LIGHT)}",
|
||||
f"{output_dir}-xhdpi/xfwm4/themerc",
|
||||
)
|
||||
|
||||
find_and_replace(
|
||||
f"{output_dir}-xhdpi/xfwm4/themerc",
|
||||
Subsitution(find="button_offset=6", replace="button_offset=12"),
|
||||
)
|
||||
|
||||
if not ctx.flavor.dark:
|
||||
shutil.copytree(
|
||||
f"{src_dir}/main/plank/theme-Light-Catppuccin/",
|
||||
f"{output_dir}/plank",
|
||||
dirs_exist_ok=True,
|
||||
)
|
||||
else:
|
||||
shutil.copytree(
|
||||
f"{src_dir}/main/plank/theme-Dark-Catppuccin/",
|
||||
f"{output_dir}/plank",
|
||||
dirs_exist_ok=True,
|
||||
)
|
||||
|
||||
|
||||
def make_assets(ctx: BuildContext):
|
||||
output_dir = ctx.output_dir()
|
||||
src_dir = ctx.colloid_src_dir
|
||||
|
||||
os.makedirs(f"{output_dir}/cinnamon/assets", exist_ok=True)
|
||||
for file in glob.glob(f"{src_dir}/assets/cinnamon/theme/*.svg"):
|
||||
shutil.copy(file, f"{output_dir}/cinnamon/assets")
|
||||
shutil.copy(
|
||||
f"{src_dir}/assets/cinnamon/thumbnail{ctx.apply_suffix(DARK_LIGHT)}.svg",
|
||||
f"{output_dir}/cinnamon/thumbnail.png",
|
||||
)
|
||||
|
||||
os.makedirs(f"{output_dir}/gnome-shell/assets", exist_ok=True)
|
||||
for file in glob.glob(f"{src_dir}/assets/gnome-shell/theme/*.svg"):
|
||||
shutil.copy(file, f"{output_dir}/gnome-shell/assets")
|
||||
|
||||
shutil.copytree(
|
||||
f"{src_dir}/assets/gtk/assets",
|
||||
f"{output_dir}/gtk-3.0/assets",
|
||||
dirs_exist_ok=True,
|
||||
)
|
||||
shutil.copytree(
|
||||
f"{src_dir}/assets/gtk/assets",
|
||||
f"{output_dir}/gtk-4.0/assets",
|
||||
dirs_exist_ok=True,
|
||||
)
|
||||
shutil.copyfile(
|
||||
f"{src_dir}/assets/gtk/thumbnail{ctx.apply_suffix(IS_DARK)}.svg",
|
||||
f"{output_dir}/gtk-3.0/thumbnail.png",
|
||||
)
|
||||
shutil.copyfile(
|
||||
f"{src_dir}/assets/gtk/thumbnail{ctx.apply_suffix(IS_DARK)}.svg",
|
||||
f"{output_dir}/gtk-4.0/thumbnail.png",
|
||||
)
|
||||
|
||||
theme_color = ctx.accent.hex
|
||||
|
||||
palette = ctx.flavor.colors
|
||||
background = palette.base.hex
|
||||
background_alt = palette.mantle.hex
|
||||
titlebar = palette.overlay0.hex
|
||||
|
||||
for file in glob.glob(f"{output_dir}/cinnamon/assets/*.svg"):
|
||||
find_and_replace(
|
||||
file,
|
||||
Subsitution(find="#5b9bf8", replace=theme_color),
|
||||
Subsitution(find="#3c84f7", replace=theme_color),
|
||||
)
|
||||
|
||||
for file in glob.glob(f"{output_dir}/gnome-shell/assets/*.svg"):
|
||||
find_and_replace(
|
||||
file,
|
||||
Subsitution(find="#5b9bf8", replace=theme_color),
|
||||
Subsitution(find="#3c84f7", replace=theme_color),
|
||||
)
|
||||
|
||||
for file in glob.glob(f"{output_dir}/gtk-3.0/assets/*.svg"):
|
||||
find_and_replace(
|
||||
file,
|
||||
Subsitution(find="#5b9bf8", replace=theme_color),
|
||||
Subsitution(find="#3c84f7", replace=theme_color),
|
||||
Subsitution(find="#ffffff", replace=background),
|
||||
Subsitution(find="#2c2c2c", replace=background),
|
||||
Subsitution(find="#3c3c3c", replace=background_alt),
|
||||
)
|
||||
|
||||
for file in glob.glob(f"{output_dir}/gtk-4.0/assets/*.svg"):
|
||||
find_and_replace(
|
||||
file,
|
||||
Subsitution(find="#5b9bf8", replace=theme_color),
|
||||
Subsitution(find="#3c84f7", replace=theme_color),
|
||||
Subsitution(find="#ffffff", replace=background),
|
||||
Subsitution(find="#2c2c2c", replace=background),
|
||||
Subsitution(find="#3c3c3c", replace=background_alt),
|
||||
)
|
||||
|
||||
if ctx.flavor.dark:
|
||||
find_and_replace(
|
||||
f"{output_dir}/cinnamon/thumbnail.png",
|
||||
Subsitution(find="#2c2c2c", replace=background),
|
||||
Subsitution(find="#5b9bf8", replace=theme_color),
|
||||
)
|
||||
|
||||
find_and_replace(
|
||||
f"{output_dir}/gtk-3.0/thumbnail.png",
|
||||
Subsitution(find="#5b9bf8", replace=theme_color),
|
||||
Subsitution(find="#2c2c2c", replace=background),
|
||||
)
|
||||
|
||||
find_and_replace(
|
||||
f"{output_dir}/gtk-4.0/thumbnail.png",
|
||||
Subsitution(find="#5b9bf8", replace=theme_color),
|
||||
Subsitution(find="#2c2c2c", replace=background),
|
||||
)
|
||||
else:
|
||||
find_and_replace(
|
||||
f"{output_dir}/cinnamon/thumbnail.png",
|
||||
Subsitution(find="#ffffff", replace=background),
|
||||
Subsitution(find="#f2f2f2", replace=titlebar),
|
||||
Subsitution(find="#3c84f7", replace=theme_color),
|
||||
)
|
||||
|
||||
find_and_replace(
|
||||
f"{output_dir}/gtk-3.0/thumbnail.png",
|
||||
Subsitution(find="#f2f2f2", replace=titlebar),
|
||||
Subsitution(find="#3c84f7", replace=theme_color),
|
||||
)
|
||||
|
||||
find_and_replace(
|
||||
f"{output_dir}/gtk-4.0/thumbnail.png",
|
||||
Subsitution(find="#f2f2f2", replace=titlebar),
|
||||
Subsitution(find="#3c84f7", replace=theme_color),
|
||||
)
|
||||
|
||||
for file in glob.glob(f"{src_dir}/assets/cinnamon/common-assets/*.svg"):
|
||||
shutil.copy(file, f"{output_dir}/cinnamon/assets")
|
||||
|
||||
for file in glob.glob(
|
||||
f"{src_dir}/assets/cinnamon/assets{ctx.apply_suffix(IS_DARK)}/*.svg"
|
||||
):
|
||||
shutil.copy(file, f"{output_dir}/cinnamon/assets")
|
||||
|
||||
for file in glob.glob(f"{src_dir}/assets/gnome-shell/common-assets/*.svg"):
|
||||
shutil.copy(file, f"{output_dir}/gnome-shell/assets")
|
||||
|
||||
for file in glob.glob(
|
||||
f"{src_dir}/assets/gnome-shell/assets{ctx.apply_suffix(IS_DARK)}/*.svg"
|
||||
):
|
||||
shutil.copy(file, f"{output_dir}/gnome-shell/assets")
|
||||
|
||||
for file in glob.glob(f"{src_dir}/assets/gtk/symbolics/*.svg"):
|
||||
shutil.copy(file, f"{output_dir}/gtk-3.0/assets")
|
||||
shutil.copy(file, f"{output_dir}/gtk-4.0/assets")
|
||||
|
||||
for file in glob.glob(
|
||||
f"{src_dir}/assets/metacity-1/assets{ctx.apply_suffix(IS_WINDOW_NORMAL)}/*.svg"
|
||||
):
|
||||
shutil.copy(file, f"{output_dir}/metacity-1/assets")
|
||||
shutil.copy(
|
||||
f"{src_dir}/assets/metacity-1/thumbnail{ctx.apply_suffix(IS_DARK)}.png",
|
||||
f"{output_dir}/metacity-1/thumbnail.png",
|
||||
)
|
||||
|
||||
xfwm4_assets = f"{ctx.git_root}/patches/xfwm4/generated/assets-catppuccin-{ctx.flavor.identifier}"
|
||||
for file in glob.glob(xfwm4_assets + "/*"):
|
||||
shutil.copy(file, f"{output_dir}/xfwm4")
|
||||
|
||||
xfwm4_assets = xfwm4_assets + "-hdpi/*"
|
||||
for file in glob.glob(xfwm4_assets):
|
||||
shutil.copy(file, f"{output_dir}-hdpi/xfwm4")
|
||||
|
||||
xfwm4_assets = xfwm4_assets + "-xhdpi/*"
|
||||
for file in glob.glob(xfwm4_assets):
|
||||
shutil.copy(file, f"{output_dir}-xhdpi/xfwm4")
|
||||
|
||||
|
||||
def zip_dir(path, zip_file):
|
||||
for root, _, files in os.walk(path):
|
||||
for file in files:
|
||||
zip_file.write(
|
||||
os.path.join(root, file),
|
||||
os.path.relpath(os.path.join(root, file), os.path.join(path, "..")),
|
||||
)
|
||||
|
||||
|
||||
def zip_artifacts(dir_list, zip_name, remove=True):
|
||||
with zipfile.ZipFile(zip_name, "w", zipfile.ZIP_DEFLATED) as zipf:
|
||||
for dir in dir_list:
|
||||
zip_dir(dir, zipf)
|
||||
|
||||
if remove:
|
||||
for dir in dir_list:
|
||||
shutil.rmtree(dir)
|
||||
|
||||
|
||||
def build_with_context(ctx: BuildContext):
|
||||
build_info = f"""Build info:
|
||||
build_root: {ctx.output_root}
|
||||
src_root: {ctx.colloid_src_dir}
|
||||
theme_name: {ctx.theme_name}
|
||||
flavor: {ctx.flavor.identifier}
|
||||
accent: {ctx.accent.identifier}
|
||||
size: {ctx.size}
|
||||
tweaks: {ctx.tweaks}"""
|
||||
logger.info(build_info)
|
||||
|
||||
execute_build(ctx)
|
||||
logger.info("Main build complete")
|
||||
|
||||
logger.info("Bundling assets...")
|
||||
make_assets(ctx)
|
||||
logger.info("Asset bundling done")
|
||||
|
||||
if ctx.output_format == "zip":
|
||||
zip_artifacts(
|
||||
[
|
||||
ctx.output_dir(),
|
||||
f"{ctx.output_dir()}-hdpi",
|
||||
f"{ctx.output_dir()}-xhdpi",
|
||||
],
|
||||
f"{ctx.output_root}/{ctx.build_id()}.zip",
|
||||
True,
|
||||
)
|
||||
|
||||
|
||||
def gnome_shell_version(src_dir):
|
||||
# Hardcoded here, Colloid checks for this on end user machines
|
||||
# but we cannot do that. Old build system would've resulted in this too.
|
||||
gs_version = "46-0"
|
||||
|
||||
shutil.copyfile(
|
||||
f"{src_dir}/sass/gnome-shell/_common.scss",
|
||||
f"{src_dir}/sass/gnome-shell/_common-temp.scss",
|
||||
)
|
||||
find_and_replace(
|
||||
f"{src_dir}/sass/gnome-shell/_common-temp.scss",
|
||||
Subsitution(
|
||||
find="@import 'widgets-40-0';",
|
||||
replace=f"@import 'widgets-{gs_version}';",
|
||||
),
|
||||
)
|
@@ -1,23 +0,0 @@
|
||||
import re
|
||||
import shutil
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Subsitution:
|
||||
find: str
|
||||
replace: str
|
||||
|
||||
|
||||
def find_and_replace(path: str, *subs: Subsitution):
|
||||
with open(path, "r+") as f:
|
||||
content = f.read()
|
||||
f.seek(0)
|
||||
f.truncate()
|
||||
for sub in subs:
|
||||
content = re.sub(sub.find, sub.replace, content)
|
||||
f.write(content)
|
||||
|
||||
|
||||
def init_tweaks_temp(src_dir):
|
||||
shutil.copyfile(f"{src_dir}/sass/_tweaks.scss", f"{src_dir}/sass/_tweaks-temp.scss")
|
@@ -1,13 +0,0 @@
|
||||
diff --git a/src/sass/gnome-shell/common/_switcher-popup.scss b/src/sass/gnome-shell/common/_switcher-popup.scss
|
||||
index 90b51ab4..408662fb 100644
|
||||
--- a/src/sass/gnome-shell/common/_switcher-popup.scss
|
||||
+++ b/src/sass/gnome-shell/common/_switcher-popup.scss
|
||||
@@ -14,6 +14,8 @@
|
||||
border-radius: $base_radius;
|
||||
border: 1px solid transparent;
|
||||
|
||||
+ background-color: $osd;
|
||||
+
|
||||
&:outlined {
|
||||
background-color: $divider;
|
||||
color: $text; // for Ubuntu session
|