# Technical Documentation: end-4/dots-hyprland

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/end-4/dots-hyprland)

### Overview (`.github/README.md`)

<div align="center">
    <h1>【 end_4's Hyprland dotfiles 】</h1>
    <h3></h3>
</div>

<div align="center"> 




<a href="https://discord.gg/GtdRBXgMwq"> <img alt="Dynamic JSON Badge" src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fdiscordapp.com%2Fapi%2Finvites%2FGtdRBXgMwq%3Fwith_counts%3Dtrue&query=approximate_member_count&style=for-the-badge&logo=discord&logoColor=D9E0EE&label=discord&labelColor=%231E202B&color=86dbc0&link=https%3A%2F%2Fdiscord.gg%2FGtdRBXgMwq"> </a>

</div>

<div align="center">
    <h2>• overview •</h2>
    <h3></h3>
</div>

> [!WARNING]  
> Hyprland 0.55 update:
> If your distro has not shipped Hyprland 0.55 and/or you're not ready for it, you should switch to the Pre-Hyprland Luaification release (or not update yet, if you're going to do that). See the wiki for more info: [Install](https://ii.clsty.link/en/ii-qs/01setup/#automated-installation) | [Update](https://ii.clsty.link/en/ii-qs/01setup/#updating)

<details> 
  <summary>What this is/isn't</summary>

  - Technically, configuration files
  - Realistically, mostly the custom graphical shell
  - NOT a system setup script: no graphic drivers, no zram setup, etc.
  
</details>

<details> 
  <summary>Notable features</summary>
     
  - **Overview**: Shows open apps with live previews
  - **AI**: Gemini, Ollama, and more
  - **QoL**: screen translation, anti-flashbang, Google Lens
  - **Material themes**: Choose your wallpaper, done, enjoy
  - **Transparent installation**: Every command is shown before it's run
</details>

<details> 
  <summary>Installation</summary>

   - **IMPORTANT: Hyprland 0.55 Update**: If your distro has not shipped Hyprland 0.55 and/or you're not ready for it, you should switch to the Pre-Hyprland Luaification release. See [the wiki](https://ii.clsty.link/en/ii-qs/01setup/) for more info
   - Just run `bash <(curl -s https://ii.clsty.link/get)`
     - Or, clone this repo and run `./setup install`
     - See [the wiki](https://ii.clsty.link/en/ii-qs/01setup/) for more details
   - **Keybinds**: Should be somewhat familiar to Windows or GNOME users. Important ones:
     - `Super`+`/` = keybind list
     - `Super`+`Enter` = terminal


</details>

<details>
  <summary>Software overview</summary>

  | Software | Purpose |
  | ------------- | ------------- |
  | [Hyprland](https://github.com/hyprwm/hyprland) | The compositor (manages and renders windows) |
  | [Quickshell](https://quickshell.outfoxxed.me/) | A QtQuick-based widget system, used for the status bar, sidebars, etc. |
  | Others | See [deps-info.md](https://github.com/end-4/dots-hyprland/blob/main/sdata/deps-info.md) |

</details>

<details>
    <summary>Discord</summary>
        <a href="https://discord.gg/GtdRBXgMwq"> Server link</a> | I hope this provides a friendlier environment for support without needing me to personally accept every friend request/DM. For real issues, prefer GitHub

</details>

<div align="center">
    <h2>• screenshots •</h2>
    <h3></h3>
</div>

<div align="center">
    <img src="assets/illogical-impulse.svg" alt="illogical-impulse logo" style="float:left; width:400;">
</div>

Widget system: Quickshell | Support: Yes

[Showcase video](https://www.youtube.com/watch?v=RPwovTInagE)

| AI, settings app | Some widgets |
|:---|:---------------|
| <img width="1920" height="1080" alt="image" src="https://github.com/user-attachments/assets/5d4e7d07-d0b4-4406-a4c9-ed7ba90e3fe4" /> | <img width="1920" height="1080" alt="image" src="https://github.com/user-attachments/assets/6a32395f-9437-4192-8faf-2951a9e84cbe" /> |
| Window management | wow look its orange |
| <img width="1920" height="1080" alt="image" src="https://github.com/user-attachments/assets/c51bed8b-3670-4d4c-9074-873be224fb8e" /> | <img width="1920" height="1080" alt="image" src="https://github.com/user-attachments/assets/98703a66-0743-439f-a721-cef7afa6ab95" /> |

<div align="center">
    <h2>• thank you •</h2>
    <h3></h3>
</div>

 - [@clsty](https://github.com/clsty) for making the dotfiles accessible by taking care of the install script and many other things
 - [@midn8hustlr](https://github.com/midn8hustlr) for greatly improving the color generation system
 - [@outfoxxed](https://github.com/outfoxxed/) for being extremely supportive in my Quickshell journey
 - Quickshell: [Soramane](https://github.com/caelestia-dots/shell/), [FridayFaerie](https://github.com/FridayFaerie/quickshell), [nydragon](https://github.com/nydragon/nysh)
 - AGS: [Aylur](https://github.com/Aylur/dotfiles/tree/ags-pre-ts), [kotontrion](https://github.com/kotontrion/dotfiles)
 - EWW: [fufexan](https://github.com/fufexan/dotfiles)

<div align="center">
    <h2>• stonks •</h2>
    <h3></h3>
</div>

- I promise not to attempt an +ULTRARICOSHOT irl... Coins can go here: https://github.com/sponsors/end-4
- Tentacle cat hub twinkle internet points

[](https://starchart.cc/end-4/dots-hyprland)


---

<div align="center">
    <h2>• previous styles •</h2>
    <h3></h3>
</div>

- **Unsupported!**
- **Source**: illogical-impulse AGS in `ii-ags` branch, others in `archive` branch.
- List is in reverse chronological order

### illogical-impulse (AGS)

Widget system: AGS | Support: No

| AI | Common widgets |
|:---|:---------------|
|  |  |
| Window management | Weeb power |
|  |  |

#### m3ww

Widget system: EWW | Support: No

<a href="https://streamable.com/85ch8x">
<img src="https://github.com/end-4/dots-hyprland/assets/97237370/09533e64-b6d7-47eb-a840-ee90c6776adf" alt="Material Eww!">
</a>

#### NovelKnock

Widget system: EWW | Support: No

<a href="https://streamable.com/7vo61k">
<img src="https://github.com/end-4/dots-hyprland/assets/97237370/42903d03-bf6f-49d4-be7f-dd77e6cb389d" alt="Desktop Preview">
</a>

#### Hybrid

Widget system: EWW | Support: No

<a href="https://streamable.com/4oogot">
<img src="https://github.com/end-4/dots-hyprland/assets/97237370/190deb1e-f6f5-46ce-8cf0-9b39944c079d" alt="click the circles!">
</a>

#### Windoes

Widget system: EWW | Support: No

<a href="https://streamable.com/5qx614">
<img src="https://github.com/end-4/dots-hyprland/assets/97237370/b15317b1-f295-49f5-b90c-fb6328b8d886" alt="Desktop Preview">
</a>



<div align="center">
    <h2>• inspirations/copying •</h2>
    <h3></h3>
</div>

 - Inspiration: osu!lazer (Hybrid), Windows 11 (Windoes), AvdanOS (NovelKnock), Material Design 3 (m3ww & later)
 - Copying: Absolutely, feel free. Just follow the license and it's all good

---

### Overview (`licenses/README.md`)

# Licenses

This repository contains code from other repositories. Files containing such code should include a license notice, and a copy should be stored in this folder.

---

### Overview (`sdata/README.md`)

This folder mainly contains data for the script `setup`.

- TODO: output the logs to a temp file, then show the path of the file so users will be able to read it again or upload it to issue.
- TODO: unify the message output via functions (for example `log_error`, `log_warning`).

---

### Overview (`dots-extra/via-nix/README.md`)

This folder contains tweakd configs when --via-nix is specified.

---

### Overview (`sdata/dist-arch/README.md`)

# Install scripts for Arch Linux

- See also [Install scripts | illogical-impulse](https://ii.clsty.link/en/dev/inst-script/)

## Old Dependency Installation Method
The old deps install method mainly involved `./sdata/dependencies.conf` (which has been removed now).

## Current Dependency Installation
Local PKGBUILDs under `./sdata/dist-arch/` are used to install dependencies.

The mechanism is introduced by [Makrennel](https://github.com/Makrennel) in [PR#570](https://github.com/end-4/dots-hyprland/pull/570).

Why is this awesome?
- It makes it possible to control version since some packages may involve breaking changes from time to time.
- It makes the dependency trackable for package manager, so that you always know why you have installed some package.
- As a result, it enables a workable uninstall process.

The PKGBUILDs contains two forms of dependencies:
- Package name written in dependencies, like a "meta" package.
- Normal PKGBUILD content to build dependencies, e.g. AGS, which is often for version controlling.

## Note
- `pkgver()` should be removed from `PKGBUILD` cuz it will modify the `PKGBUILD` which is tracked by Git and should not be modified during building.

---

### Overview (`sdata/dist-fedora/README.md`)

# Install scripts for Fedora Linux

Note:
- The scripts here are **not** meant to be executed directly.
- This folder should reflect the equivalents of `/sdata/dist-arch/` but under Fedora.
  - **When `/sdata/dist-arch/` is newer than this folder, an update on this folder is very likely needed.**
  - Useful link: [Commit history on sdata/dist-arch/](https://github.com/end-4/dots-hyprland/commits/main/sdata/dist-arch)
- See also [Install scripts | illogical-impulse](https://ii.clsty.link/en/dev/inst-script/)

## Contributors
- Author: [ririko6z](https://github.com/ririko6z)

## Tested
- It has been tested on Fedora Everything 44 on the `x86_64` platform.

## Post installation
- Fix the issue of the right column crashing when clicking the `Details` button in Wi-Fi mode. Edit this file: `~/.config/illogical-impulse/config.json`
- Replace `pacman` with `dnf` in update app.
```diff
@@ 44,3 44,3 @@
-  "apps": {
-    "bluetooth": "kcmshell6 kcm_bluetooth",
-    "network": "kitty -1 fish -c nmtui",
-    "update": "kitty -1 --hold=yes fish -i -c 'pkexec pacman -Syu'",

+  "apps": {
+    "bluetooth": "kcmshell6 kcm_bluetooth",
+    "network": "plasmawindowed org.kde.plasma.networkmanagement",
+    "update": "kitty -1 --hold=yes fish -i -c 'sudo dnf update -y'",
```

---

### Overview (`sdata/dist-gentoo/README.md`)

# Install scripts for Gentoo

Note:
- The scripts here are **not** meant to be executed directly.
- This folder should reflect the equivalents of `/sdata/dist-arch/` but under Gentoo.
  - **When `/sdata/dist-arch/` is newer than this folder, an update on this folder is very likely needed.**
  - Useful link: [Commit history on sdata/dist-arch/](https://github.com/end-4/dots-hyprland/commits/main/sdata/dist-arch)
- See also [Install scripts | illogical-impulse](https://ii.clsty.link/en/dev/inst-script/)

## Contributors

- Author: [jwihardi](https://github.com/jwihardi)

This directory contains the Gentoo dependency definitions used by the main
illogical-impulse installer. It mirrors the package groups maintained in
[`sdata/dist-arch`](../dist-arch/) with Gentoo metapackages and a local Portage
overlay.

The complete package set is currently intended for **amd64**. Some individual
ebuilds also carry arm64 or x86 keywords, but not every illogical-impulse
metapackage supports those architectures yet.

## How installation works

The dependency installer:

1. Installs `eselect-repository`, `rsync`, and `smart-live-rebuild`.
2. Enables the GURU repository when necessary.
3. Copies [`overlay/`](overlay/) to `/var/db/repos/ii-dots` and installs its
   repository configuration.
4. Generates `/etc/portage/package.accept_keywords/illogical-impulse` for the
   current architecture from [`keywords`](keywords).
5. Installs [`useflags`](useflags) and [`additional-useflags`](additional-useflags)
   as `/etc/portage/package.use/illogical-impulse`.
6. Syncs configured repositories, updates `@world`, and rebuilds
   installed live packages.
7. Emerges every metapackage listed in [`metapkgs.sh`](metapkgs.sh).

Note: The installer also ensures Python 3.12 is installed.

The `ii-dots` repository has `auto-sync = no`. A normal `emerge --sync` does
not update it; rerun the illogical-impulse installer to copy the current
overlay into Portage.

## Repository contents

| Path | Purpose |
| --- | --- |
| [`overlay/`](overlay/) | Local ebuild repository containing the II metapackages and packages not provided in the required form elsewhere. |
| [`ii-dots.conf`](ii-dots.conf) | Portage repository configuration installed under `/etc/portage/repos.conf`. |
| [`keywords`](keywords) | Packages that must accept testing or unkeyworded ebuilds. The installer appends the current testing keyword. |
| [`useflags`](useflags) | Direct feature requirements for the II package set. |
| [`additional-useflags`](additional-useflags) | Transitive feature requirements appended to the same Portage package.use file. |
| [`metapkgs.sh`](metapkgs.sh) | Package groups installed and removed by the dependency scripts. |

MicroTeX and Material Symbols use live ebuilds. Quickshell keeps the `-git`
package name for compatibility but is pinned to a tested upstream commit.
Versioned theme and font ebuilds may also use pinned commits as their source.

## System requirements

Choose either `elogind` or `systemd` globally so all installed packages use
the same session manager. On OpenRC, `elogind` is recommended and
must be running so the user session receives `XDG_RUNTIME_DIR`.

## Uninstalling

The uninstall path removes the II metapackages, local overlay, repository
configuration, keyword file, and USE file. It does not automatically remove
dependencies that have become unused; review `emerge --depclean --pretend`
before deciding whether to depclean them.

---

### Overview (`sdata/dist-nix/README.md`)

# Install scripts using Nix to achieve cross-distros
- This directory is currently WIP.
- See also [Install scripts | illogical-impulse](https://ii.clsty.link/en/dev/inst-script/)
- See also [#1061](https://github.com/end-4/dots-hyprland/issues/1061)

**NOTE: The `dist-nix` is not for NixOS but every distro, using Nix and home-manager.**

As we all know Nix and Home-manager has two major functionalities:
- Handling dependencies (i.e. package installation)
- Handling dotfiles

They are discussed in following sections.

# Handling dependencies
## Status
Partially works. See [Discussion #2382](https://github.com/end-4/dots-hyprland/discussions/2382).
## plan
Note that this script must be idempotent.

TODO:
- [ ] Fix all TODOs inside `dist-nix`. ([search online](https://github.com/search?q=repo%3Aend-4%2Fdots-hyprland+path%3A%2F%5Esdata%5C%2Fdist-nix%5C%2F%2F+TODO&type=code))
- [ ] Since Nix uses a large number of inodes, need to warn user if inode-limited filesystem (typically ext4) is used.
- [ ] Deal with error when running `systemctl --user enable ydotool --now`:
  ```plain
  Failed to connect to user scope bus via local transport: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined (consider using --machine=<user>@.host --user to connect to bus of other user)
  ```
- [ ] Handle problem that `pkill qs` and `pkill hyprland` does not work (should be `.quickshell-wra` and `.Hyprland-wrapp` when installed via Nix).

## Attentions
### PAM
On non-NixOS distros, programs using PAM (typically screen locker) will not work if installed via Nix, so user has to use their own distro's package for the screen lock.

- One problem is that Debian(-based) distros use modified version of PAM which supports `@include` directive in `/etc/pam.d` config files but the PAM from Nix does not support it, see [this comment](https://github.com/NixOS/nixpkgs/issues/128523#issuecomment-1086106614).
- Another problem is the location of a suid helper binary that is necessary, see [this comment](https://github.com/end-4/dots-hyprland/issues/1061#issuecomment-3403195230).

As [commented](https://github.com/end-4/dots-hyprland/issues/1061#issuecomment-3403195230) by @Cu3PO42 , both the problem could be solved by using the system-provided libpam instead.

See also [caelestia-dots/shell#668](https://github.com/caelestia-dots/shell/issues/668).

### GPU
On non-NixOS distros, packages installed via home-manager have problem accessing GPU, especially Hyprland because it requires GPU acceleration to launch.

~~`nixGL` should be used to address the problem.~~

Since home-manager 25.11, for non-NixOS just set the following:
```nix
targets.genericLinux.enable = true;
```
Then during building, home-manager will show a message to tell you running a command manually to configure GPU, like:
```bash
sudo /nix/store/<HASH>-non-nixos-gpu/bin/non-nixos-gpu-setup
```
It runs a bash script with following content:
```
#!/nix/store/<HASH>-bash-<VERSION>/bin/bash

set -e

# Install the systemd service file and ensure that the store path won't be
# garbage-collected as long as it's installed.
unit_path=/etc/systemd/system/non-nixos-gpu.service
ln -sf /nix/store/<HASH>-non-nixos-gpu/resources/non-nixos-gpu.service "$unit_path"
ln -sf "$unit_path" "/nix/var/nix"/gcroots/non-nixos-gpu.service

systemctl daemon-reload
systemctl enable non-nixos-gpu.service
systemctl restart non-nixos-gpu.service
```
_Note: it uses `systemctl`, maybe won't work for OpenRC..._

See [gpu-non-nixos](https://nix-community.github.io/home-manager/index.xhtml#sec-usage-gpu-non-nixos).

# Handling dot files
## Status
Paused, until some suitable method has been confirmed to meet the requirements below.
## Requirements
About handling the dotfiles, i.e. `dots/`, if we are doing this using Nix then the following requirements must be fulfilled.

**1. Allow modifications over the existing dotfiles.**

Current state of `./setup install`:
- After finishing running `./setup install`, users can modify any dotfiles in a traditional way, and if they run `./setup install` again to update then they need to skip the steps which overwrite the targets that they have modified and later sync the upgrade manually for such targets by themselves.
  - For Hyprland, specially we have a `custom` folder along with `~/.config/hypr/hyprland.conf` which will only get overwritten the first time but not the later times running `./setup install`.
- This works but is not elegant. An experimental solution is using yaml config to store the selected behavior for each target, see [#2137](https://github.com/end-4/dots-hyprland/issues/2137).

If we use Nix to handle dotfiles, then it must be at least better than the current state described above, mainly in terms of convenience and automation.

**2. Allow choosing targets.**

This is similar to the above. For example user may want to use their own `~/.config/foot` instead of the files under `dots/.config/foot` entirely.

**3. Easy developing dotfiles or at least not worse than current state.**

About the current state:
- @clsty: "If I were the one who develops the dotfiles, I will make changes to the local Git repo `dots-hyprland` and rerun `./setup install-files -f` to apply the changes to observe the outcome."
- @end-4 (who develops the dots; see [comment](https://github.com/end-4/dots-hyprland/pull/2278#issuecomment-3454929577)): "I modify my local copy of stuff, copy the relevant parts over, optionally selectively pick changes then commit. It's.... the most obvious way but I guess not necessarily the cleanest"

If we use Nix to handle dotfiles, then it must be at least better than the current state described above, mainly in terms of convenience and automation.

**4. Others**

Find out a good method to avoid what @end-4 [mentioned](https://github.com/end-4/dots-hyprland/issues/1061#issuecomment-2954725029):

> About home-manager, from my limited understanding of and experience with it, any change to the config files require a rebuild right? If this is indeed the case, switching entirely to this is not okay. Having to wait 20 seconds for each change is absurd.

Some information may help, e.g. @darsh032 [commented](https://github.com/end-4/dots-hyprland/issues/1061#issuecomment-3336839862):

> I mean thats not really needed you can use mkOutOfStoreSymlink or use hjem-impure to change the configs without rebuilding

And also the "hmrice" [mentioned](https://github.com/end-4/dots-hyprland/issues/1061#issuecomment-3353345504) by @Markus328 , and the `flake.nix` (for quickshell only) [mentioned](https://github.com/end-4/dots-hyprland/issues/1061#issuecomment-3354387126) by @darsh032 .

---

### Overview (`sdata/uv/README.md`)

## Why is this important?
Instead of installing python packages via system package manager, we should install them into virtual environment.

This is important because there has been so many complaints about the failure installing/updating python packages via system package manager, see [#1017](https://github.com/end-4/dots-hyprland/issues/1017).

## How to add/remove python package?

1. Edit `requirements.in`. You may refer to [PyPI](https://pypi.org/) for possible package names.
  - If PyPI does not have the needed package, we probably need to build it manually inside the venv. In such case we need to edit the install scripts.
2. Run `uv pip compile requirements.in -o requirements.txt` in this folder.

**Notes:**
- For reference see [uv doc](https://docs.astral.sh/uv/pip/dependencies/#using-requirementsin).
- `requirements.txt` is included in Git. It's for locking package versions to enhance stability and reproducibility.[^1]

[^1]: In fact, including package version lock file in Git is also the most common way for similar situations, for example the `package-lock.json` of Node.js projects (see also [this stackoverflow question](https://stackoverflow.com/questions/48524417/should-the-package-lock-json-file-be-added-to-gitignore)). Although there are some situations when it's not suitable to include the lock file, for example [the poetry document](https://python-poetry.org/docs/basic-usage/#committing-your-poetrylock-file-to-version-control) recommend application developers to include package version lock file in Git, but library developers should consider more, such as not including the lock file or including it but refreshing regularly.

## How will the python packages get installed?

For summary:
- They will be installed to the virtual environment `$ILLOGICAL_IMPULSE_VIRTUAL_ENV`.
- The default value of `$ILLOGICAL_IMPULSE_VIRTUAL_ENV` is `$XDG_STATE_HOME/quickshell/.venv`.
  - The default value of `$XDG_STATE_HOME` is `$HOME/.local/state`.
- Currently we use `env = ILLOGICAL_IMPULSE_VIRTUAL_ENV, ~/.local/state/quickshell/.venv` in `~/.config/hypr/hyprland/env.conf` to set this environment variable.[^2]

For details: see the function `install-python-packages()` defined in `/sdata/lib/package-installers.sh`.

[^2]: Hyprland seems to have weird problem dealing with recursive variable, so we can not use `$XDG_STATE_HOME/quickshell/.venv` even if we had set `$XDG_STATE_HOME` to `~/.local/state` explicitly, else `$XDG_STATE_HOME` will possibly not get expanded but get recognised as literally `$XDG_STATE_HOME`. This problem never happens for some users, but according to some issues when we were using recursive variable setting in the past, it's possible to happen for other users. Reason unknown.

## How to use the python packages installed through here?

Basically you'll need to activate the virtual environment first:
```bash
source $(eval echo $ILLOGICAL_IMPULSE_VIRTUAL_ENV)/bin/activate
```

It will add the python executable located in the venv to `$PATH` and give it the highest priority.
Run `which python` and you'll understand.

This python executable will also search and use the python package inside the venv,
which enables running any python script or running command provided via python package using the venv.

After that you probably need to deactivate it:
```bash
deactivate
```

### Situation 1: As a single command
**Description:** At someplace which accept a single command,
- run a python script,
- or run a command provided by python package.

Example: In `~/‎.config/quickshell/ii/screenshot.qml`:
```qml
Process {
id: imageDetectionProcess
                command: ["bash", "-c", `${Directories.scriptPath}/images/find_regions.py ` 
+ `--hyprctl ` 
+ `--image '${StringUtils.shellSingleQuoteEscape(panelWindow.screenshotPath)}' ` 
+ `--max-width ${Math.round(panelWindow.screen.width * root.falsePositivePreventionRatio)} ` 
```
In this example, python script `find_regions.py` is called and receives some arguments.

#### Solution A: shebang

Add the shebang below to the beginning of python script:
```python
#!/usr/bin/env -S\_/bin/sh\_-c\_"source\_\$(eval\_echo\_\$ILLOGICAL_IMPULSE_VIRTUAL_ENV)/bin/activate&&exec\_python\_-E\_"\$0"\_"\$@""
```
And that's it!

**Note:** This is the simplest solution as it only modifies the shebang of python script.
**However:**
- It's only for python script, not the command provided by python package.
- It can not deal with complex argument (e.g. filename containing spaces) passed to the python script.
  - If we apply this solution to the example above, it may cause problem, considering that `--image '${StringUtils.shellSingleQuoteEscape(panelWindow.screenshotPath)}'` could be a rather complex argument passed to `find_regions.py`.
- This solution rely on shebang to activate the correct python venv, but the shebang will be ignored if the script is directly passed to the interpreter, e.g. `python3 foo.py`.

#### Solution B: bash script as wrapper

First make sure the python script is using the shebang `#!/usr/bin/env python3`, instead of `#!/usr/bin/python3` or something else.

Then write a wrapper script in bash.
Let's continue the `screenshot.qml` example, in the same directory as `find_regions.py`, write a `find-regions-venv.sh`:
```bash
#!/usr/bin/env bash

# Specify the path of the python script.
# The example below only applies when `find_regions.py` and this wrapper script are under the same folder.
PY_SCRIPT="$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)/find_regions.py"

source $(eval echo $ILLOGICAL_IMPULSE_VIRTUAL_ENV)/bin/activate
"$PY_SCRIPT" "$@"
deactivate
```
**Not done yet!** Do not forget to update the code calling the original python script.
In this example, in `~/‎.config/quickshell/ii/screenshot.qml` we should modify `find_regions.py` to the wrapper script `find-regions-venv.sh`:
```qml
Process {
id: imageDetectionProcess
                command: ["bash", "-c", `${Directories.scriptPath}/images/find-regions-venv.sh ` 
+ `--hyprctl ` 
+ `--image '${StringUtils.shellSingleQuoteEscape(panelWindow.screenshotPath)}' ` 
+ `--max-width ${Math.round(panelWindow.screen.width * root.falsePositivePreventionRatio)} ` 
```

### Situation 2: Inside a bash script
Note: the solutions for `Situation 1: As a single command` also apply here; but **not** vice versa.

**Description:**
Inside a bash script,
- run a python script,
- or run a command provided by python package.

**Solution:**
- Add "activation command" before the target line,
- Also add "deactivation command" after the target line.

**Example:**

For running a python script,
take `generate_colors_material.py` as example:
```bash
source "$(eval echo $ILLOGICAL_IMPULSE_VIRTUAL_ENV)/bin/activate"
python3 "$SCRIPT_DIR/generate_colors_material.py" "${generate_colors_material_args[@]}" \
  > "$STATE_DIR"/user/generated/material_colors.scss
"$SCRIPT_DIR"/applycolor.sh
```

For running a python script provided by python package,
take `kde-material-you-colors` as example:
```bash
source "$(eval echo $ILLOGICAL_IMPULSE_VIRTUAL_ENV)/bin/activate"
kde-material-you-colors "$mode_flag" --color "$color" -sv "$sv_num"
deactivate
```

---

### Overview (`dots/.config/quickshell/ii/defaults/ai/README.md`)

## A note about sources of the prompts

- `ii-` prefixed ones are from illogical impulse
- The Acchan one is from [Nyarch Assistant](https://github.com/NyarchLinux/NyarchAssistant) (GPLv3). I know there's already the Imouto one but this one's very 😭💢
- `w-` prefixed ones... I don't remember what w stands for but these prompts are [*cough cough*] inspired by certain apps

---

### Overview (`dots/.config/quickshell/ii/modules/waffle/README.md`)

## Waffle

A recreation of Windoes. It's WIP!

- If you install illogical-impulse fully, you can press Super+Alt+W to switch to this style.
- If you're just copying the Quickshell config, run the config as usual (`qs -c ii`) then run `qs -c ii ipc call panelFamily cycle`

## From EWW version to Quickshell

Just a reflection, in case anyone's interested. My blog is probably a better place for this, but it does not exist. Besides, this is going to change as I do more stuff. Currently there's just the bar.

### Improvements

- QtQuick's `Button` has the `{top/bottom/left/right}Inset` properties, so we can have clickable regions expanding beyond the button background for free. With EWW it was annoying to wrap the button content with an `eventbox` that has some padding, then somehow use CSS selectors to make sure hovering effects work. I have to admit, (a large) part of that annoyance was with how bad my copy-pasting coding practice was at the time, but still...

- Fancy effects: Gtk3 CSS does not support transformations. In QtQuick we can smack `rotation` and `scale` almost everywhere, so it's simple to make bouncy icons and rotating chevrons

- Quickshell provides a system tray service (EWW does now but didn't at the time I created the EWW Windoes version), so now there's no Waybar needed for the tray.

- QtQuick has `Loader`s, so we can have this live-switchable from the main style without killing the widget system, moving styles to the correct folder, and relaunching.

- This time my computer is powerful enough to run a VM, so I don't have to occasionally reboot to take quick screenshots for reference. I try to make everything pixel-perfect so this is necessary. Speaking about pixel-perfectness, in the EWW version I hardcoded sizes, but this time I'm still doing that (lol), BUT that's normal and not a problem because Qt has the `QT_SCALE_FACTOR` env var for scaling. (Please feel free to prove me wrong in saying Gtk3 doesn't have that magic)

### Challenges

- Qt is not Gtk and definitely not React
  - We don't get directional border on QtQuick `Rectangle`s like in CSS. I was able to get around this with manual drawing, but it was a bit more work

- Fluent Icons is difficult to use, compared to Material Symbols
  - No React, so no clean use via a library.
  - If we use the font, there's no proper, searchable **codepoint** cheatsheet like Nerd Fonts, and there's no ligatures
  - I resorted to downloading individual SVGs. Not that nice, but it's better than scanning the whole table of icons every time I want one. For this we have fluenticon.com and fluenticons.co, but icons are awkwardly named and there's no alias. Why is the reload/refresh icon called "arrow-sync"? Well, the name is not misleading, but arguably reload/refresh are more common actions. From Fluent Design's [page on Iconography](https://fluent2.microsoft.design/iconography):

  > Fluent system icons are literal metaphors and are named for the shape or object they represent, not the functionality they provide

  "sync" is functionality.

---

### Overview (`dots/.config/quickshell/ii/assets/icons/fluent/README.md`)

The "start-here", "search" and "task view" icons are from here, with modifications

[Windows 11 by Joshua Oghenekaro Okwe - Figma](https://www.figma.com/community/file/1123040825921884189/windows-11)

License: [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/deed.en)

---

--- METRICS ---
- Files Extracted: 12
- Estimated Token Budget: ~7758 tokens
- Canonical Reference: https://codewiki.google/github.com/end-4/dots-hyprland
