docs: add comprehensive documentation for installation, architecture, and styling
This commit is contained in:
6 files changed
+277
No files matched your search
@@ -0,0 +1,39 @@
|
||||
# Modus Documentation
|
||||
|
||||
Welcome to the official documentation for Modus!
|
||||
|
||||
Modus is a highly customizable, hackable shell environment designed specifically for Hyprland on Wayland, built using Python and the [Fabric](https://github.com/Fabric-Development/fabric/) framework.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. **[Installation Guide](installation.md)**
|
||||
- Automated installation via `install.sh`.
|
||||
- Manual installation and compiling C-extensions.
|
||||
- Post-installation steps and recommended themes.
|
||||
|
||||
2. **[Configuration Guide](configuration.md)**
|
||||
- How to configure the shell using `config.toml`.
|
||||
- Setting up custom panel buttons with `mods.toml`.
|
||||
- Pinning apps to the dock via `dock.toml`.
|
||||
|
||||
3. **[Styling Guide](styling.md)**
|
||||
- How Matugen dynamically generates colors based on your wallpaper.
|
||||
- Customizing CSS components in `src/shared/styles/`.
|
||||
|
||||
4. **[Architecture Overview](architecture.md)**
|
||||
- Deep dive into how Modus is built.
|
||||
- The Wayland Window Switcher C-Backend (`AppCapture`).
|
||||
- The Global Menu DBus implementation.
|
||||
|
||||
5. **[FAQs & Tips](faqs_tips.md)**
|
||||
- Troubleshooting common issues (Dock occlusion, CPU usage, OSD).
|
||||
- Pro tips for keyboard shortcuts and live-reloading.
|
||||
|
||||
---
|
||||
|
||||
## Contributing
|
||||
|
||||
Modus is open-source and hackable by design. If you want to contribute to the project:
|
||||
1. Familiarize yourself with the [Architecture Overview](architecture.md).
|
||||
2. Write Python code using the Fabric framework widgets.
|
||||
3. Ensure you test your changes by running `uv run start` before opening a pull request.
|
||||
@@ -0,0 +1,43 @@
|
||||
# Architecture Overview
|
||||
|
||||
Modus is built using **Python** and the **Fabric** framework (a GTK/Wayland wrapper), along with custom C extensions for high-performance Wayland interactions.
|
||||
|
||||
## 1. Core Application Loop
|
||||
|
||||
The entry point of Modus is `start.py`, which delegates to `src/main.py`.
|
||||
`main.py` instantiates the `fabric.Application` object. This central application manages the lifecycle of various floating Wayland windows (called "widgets" or "panels" in Modus).
|
||||
|
||||
Key windows include:
|
||||
- **Panel**: The top bar (`src/window/panel/`)
|
||||
- **Dock**: The macOS-style bottom dock (`src/window/dock/`)
|
||||
- **Control Center**: The right-side quick settings panel (`src/window/controlcenter/`)
|
||||
- **App Switcher**: The Alt-Tab window switcher (`src/window/switcher/`)
|
||||
- **Lock Screen**: The session lock screen (`src/window/lock.py`)
|
||||
|
||||
## 2. High-Performance App Switcher (AppCapture)
|
||||
|
||||
The App Switcher (`Alt+Tab`) needs to display live video previews of running Wayland windows. Doing this in pure Python via DBus polling would be far too slow and resource-intensive.
|
||||
|
||||
To solve this, Modus uses a custom C-extension located in `src/window/switcher/app-capture/`.
|
||||
- **How it works**: It uses the `hyprland-toplevel-export-v1` Wayland protocol to ask Hyprland for direct memory-mapped buffers (dmabuf/shm) of the window contents.
|
||||
- **Python Integration**: The C-backend is compiled to `libappcapture.so` and exposed to Python via GObject Introspection.
|
||||
- **Optimization**: To prevent CPU spikes when capturing 4K windows, the capture framerate is intentionally throttled by Python using `invoke_repeater`, controlled by `switcher_live_preview_delay_ms` in `config.toml`.
|
||||
|
||||
## 3. Global Menu (DBus)
|
||||
|
||||
Modus features a macOS-style Global Menu (the application menu bar sits in the top panel instead of inside the app window).
|
||||
|
||||
- **How it works**: Apps export their menus over the `com.canonical.dbusmenu` DBus interface.
|
||||
- **The Shim**: To force GTK apps to export their menus even if they weren't natively designed to, Modus preloads a custom C library (`src/globalmenu/libmenu_button_shim.c`). This shim hooks into GTK's menu generation and forces the export.
|
||||
- **Python Daemon**: The Python side (`src/globalmenu/service.py`) acts as a DBus server, listens for these exported menus, and dynamically renders them as Fabric widgets in the top panel.
|
||||
|
||||
## 4. State Management & Services
|
||||
|
||||
Modus relies heavily on asynchronous event-driven services located in `src/services/`.
|
||||
These services monitor system states and emit signals when things change, updating the UI reactively:
|
||||
- `battery.py`: Uses UPower over DBus to track battery state.
|
||||
- `bluetooth.py`: Uses BlueZ over DBus.
|
||||
- `brightness.py`: Uses `brightnessctl` or `ddcutil`.
|
||||
- `network.py`: Uses NetworkManager over DBus.
|
||||
|
||||
By using signals (`connect("changed", update_ui)`), Modus ensures that it uses virtually 0% CPU while idle.
|
||||
@@ -0,0 +1,73 @@
|
||||
# Configuration Guide
|
||||
|
||||
Modus is highly configurable using TOML files located in the `config/` directory.
|
||||
|
||||
## File Overview
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `config.toml` | Main application configuration (modules, features, toggles). |
|
||||
| `mods.toml` | Custom panel button definitions (menus, shell commands). |
|
||||
| `launcher.toml` | Settings specific to the application launcher/spotlight. |
|
||||
| `dock.toml` | Pinned applications for the dock. |
|
||||
|
||||
---
|
||||
|
||||
## `config.toml` (Main Settings)
|
||||
|
||||
The `config.toml` file controls which widgets and services are enabled. Most changes here require restarting Modus (`uv run start`).
|
||||
|
||||
**Key Settings:**
|
||||
- `wallpapers_dir`: Path to the directory where your wallpapers are stored.
|
||||
- `dock_enabled`: Toggle the dock widget (`true`/`false`).
|
||||
- `dock_auto_hide`: Whether the dock hides automatically when windows overlap it.
|
||||
- `notification_timeout`: Duration before a notification automatically dismisses (e.g., `"5s"`).
|
||||
- `notification_ignored_apps`: Array of app names whose notifications should be suppressed.
|
||||
- `weather_location`: Set your city for the weather widget (e.g., `"Patan, Nepal"`).
|
||||
|
||||
**App Switcher & Screencapture:**
|
||||
- `window_switcher`: Enables the custom Alt-Tab window switcher.
|
||||
- `switcher_live_preview`: Enables real-time Wayland video previews of running applications.
|
||||
- `switcher_live_preview_delay_ms`: Framerate delay for previews (e.g., `200` = ~5fps). Lower is smoother but uses more CPU.
|
||||
- `osd`: Enables on-screen displays for volume and brightness changes.
|
||||
|
||||
---
|
||||
|
||||
## `mods.toml` (Custom Panel Buttons)
|
||||
|
||||
You can define custom buttons for the top panel that run shell commands or show dropdown menus. **Changes to this file reload instantly!**
|
||||
|
||||
```toml
|
||||
[Mods.terminal]
|
||||
icon = "terminal.svg"
|
||||
icon-size = 16
|
||||
order = 1
|
||||
on-clicked = "kitty"
|
||||
|
||||
[Mods.color-picker]
|
||||
icon = "misc/color-picker.svg"
|
||||
icon-size = 22
|
||||
order = 0
|
||||
on-left = "hyprpicker -a -n -f hex | wl-copy"
|
||||
on-right = "hyprpicker -n -f hsv | wl-copy"
|
||||
```
|
||||
|
||||
**Properties:**
|
||||
- `icon`: The name of an SVG icon placed in `src/assets/icons/`.
|
||||
- `icon-size`: Defaults to 16.
|
||||
- `order`: Determines left-to-right position (lower numbers appear first).
|
||||
- `on-clicked`, `on-left`, `on-right`, `on-middle`: Shell commands executed via `sh -c`. Supports complex piping `|` and `&&`.
|
||||
|
||||
---
|
||||
|
||||
## `dock.toml` (Pinned Apps)
|
||||
|
||||
Controls which applications are permanently pinned to the dock.
|
||||
```toml
|
||||
pinned = [
|
||||
"firefox",
|
||||
"kitty",
|
||||
"org.gnome.Nautilus"
|
||||
]
|
||||
```
|
||||
Ensure you use the exact `.desktop` file name or application ID.
|
||||
@@ -0,0 +1,37 @@
|
||||
# FAQs & Tips
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
### 1. The Global Menu isn't showing up for some apps?
|
||||
Modus uses a custom `libmenu_button_shim.so` along with `appmenu-gtk-module` to export GTK menus over DBus.
|
||||
- Ensure `appmenu-gtk-module` is installed.
|
||||
- Ensure the shim was compiled correctly during installation.
|
||||
- Note that non-GTK apps (like Electron apps or Qt apps) might need specific flags (like `export QT_QPA_PLATFORMTHEME=appmenu-qt5`) to export their menus.
|
||||
|
||||
### 2. High CPU Usage when the Application Switcher is open?
|
||||
The Modus App Switcher uses a custom Wayland C-Backend (`app-capture`) to generate live video previews of your running windows.
|
||||
- The previews are software-rendered via Cairo.
|
||||
- If you have many 4k windows open, generating live thumbnails might cause a CPU spike.
|
||||
- **Fix:** You can throttle the framerate in `config.toml` by increasing `switcher_live_preview_delay_ms` (e.g., set to `200` for ~5 FPS), or entirely disable live previews by setting `switcher_live_preview = false`.
|
||||
|
||||
### 3. The Dock is covering my fullscreen games/videos?
|
||||
Ensure you have `dock_auto_hide = true` in your `config.toml`. The dock intelligently hides when a window is maximized or goes fullscreen.
|
||||
|
||||
### 4. Why isn't my Volume or Brightness OSD showing up?
|
||||
Ensure that `osd = true` is set in your `config.toml`. The On-Screen Display relies on `brightnessctl` for brightness and standard audio services (like Pipewire/Wireplumber) for volume. Make sure those underlying tools are working correctly on your system.
|
||||
|
||||
### 5. The Weather widget is showing the wrong location?
|
||||
You can easily fix this by updating the `weather_location` setting in your `config.toml`. Simply type your city and country (e.g., `"London, UK"` or `"Patan, Nepal"`), and the widget will fetch the correct local weather.
|
||||
|
||||
---
|
||||
|
||||
## Pro Tips
|
||||
|
||||
- **Live Reload for Mods:** The `config/mods.toml` file is actively monitored. Any changes you make to custom panel buttons or dropdown menus are instantly loaded—no shell restart required!
|
||||
- **Pinning Apps Correctly:** When pinning apps in `dock.toml`, ensure you use the exact `.desktop` file name (excluding the `.desktop` extension). For example, use `"org.gnome.Nautilus"` instead of just `"nautilus"` or `"Files"`.
|
||||
- **Custom Scripts in Panel:** You aren't limited to simple commands in `mods.toml`. You can point the `on-clicked` actions to complex bash scripts stored in your home directory to create advanced panel utilities.
|
||||
- **Forcing a Theme Update:** Because Modus uses Matugen for styling, the entire shell's color scheme is tethered to your wallpaper. If you want to completely change the look of your desktop, simply set a new wallpaper! Modus will automatically generate a new palette and hot-reload the UI without dropping your session.
|
||||
- **Keyboard Shortcuts:**
|
||||
- `uv run start` — Starts the main shell daemon.
|
||||
- `uv run lock` — Triggers the session lock screen.
|
||||
- **Wayland Screencapture:** You can quickly toggle the screen recording/capture widget from the panel or bind it to a key using your Hyprland config (e.g. `bind = SUPER, S, exec, fabric-cli exec modus 'screencapture.toggle()'`).
|
||||
@@ -0,0 +1,62 @@
|
||||
# Installation Guide
|
||||
|
||||
Modus is a hackable shell for Hyprland built with Fabric. There are two primary ways to install it on Arch Linux.
|
||||
|
||||
## Automated Installation (Recommended)
|
||||
|
||||
> [!IMPORTANT]
|
||||
> You need a working installation of Hyprland and knowledge of how it works. Ensure you are running this as a regular user (not root).
|
||||
|
||||
1. **Clone the Repository:**
|
||||
```bash
|
||||
git clone https://github.com/S4NKALP/Modus ~/.config/Modus
|
||||
cd ~/.config/Modus
|
||||
```
|
||||
|
||||
2. **Run the Installer Script:**
|
||||
```bash
|
||||
./install.sh
|
||||
```
|
||||
The interactive installer will check requirements, install missing dependencies via `paru`/`yay`, build the necessary C-extensions (like `libappcapture.so` and `libmenu_button_shim.so`), and configure your Hyprland environment automatically.
|
||||
|
||||
## Manual Installation
|
||||
|
||||
If you prefer to install dependencies and compile the extensions manually:
|
||||
|
||||
1. **Install Dependencies:**
|
||||
```bash
|
||||
paru -S uv fabric-cli-git cliphist gnome-bluetooth-3.0 slurp ffmpeg hypridle hyprsunset hyprpicker hyprshot grim libnotify matugen-bin playerctl gtk-session-lock awww apple-fonts swappy wl-clipboard webp-pixbuf-loader wf-recorder acpi brightnessctl power-profiles-daemon uwsm cinnamon-desktop ddcutil at-spi2-core gcc make pkgconf appmenu-gtk-module libdbusmenu-gtk3 libdbusmenu-qt5 meson ninja wayland-protocols --needed
|
||||
```
|
||||
|
||||
2. **Clone and Sync:**
|
||||
```bash
|
||||
git clone https://github.com/S4NKALP/Modus ~/.config/Modus
|
||||
cd ~/.config/Modus
|
||||
uv sync
|
||||
```
|
||||
|
||||
3. **Compile the App Switcher C-Backend:**
|
||||
```bash
|
||||
cd src/window/switcher/app-capture
|
||||
meson setup builddir
|
||||
meson compile -C builddir
|
||||
cd ../../../..
|
||||
```
|
||||
|
||||
4. **Compile the Global Menu Shim:**
|
||||
```bash
|
||||
cd src/globalmenu
|
||||
gcc -shared -fPIC -O2 -o libmenu_button_shim.so libmenu_button_shim.c $(pkg-config --cflags --libs gtk+-3.0) -ldl
|
||||
cd ../..
|
||||
```
|
||||
|
||||
5. **Start Modus:**
|
||||
```bash
|
||||
uv run start
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> ### Post-Installation Recommendations
|
||||
> - Install the recommended icon theme: [MacTahoe-icon-theme](https://github.com/vinceliuice/MacTahoe-icon-theme)
|
||||
> - Install the recommended GTK theme: [MacTahoe-gtk-theme](https://github.com/vinceliuice/MacTahoe-gtk-theme)
|
||||
> - Edit your Hyprland configuration file to source `~/.config/Modus/config/hypr/modus.conf` for the best compatibility.
|
||||
@@ -0,0 +1,23 @@
|
||||
# Styling Guide
|
||||
|
||||
Modus handles styling dynamically using **Matugen**. This allows the shell to automatically match its color palette with your current wallpaper.
|
||||
|
||||
## How it works
|
||||
|
||||
1. When a new wallpaper is set (or the shell starts), Matugen generates a color palette.
|
||||
2. Modus uses a Matugen template located at `config/matugen/templates/modus.css`.
|
||||
3. Matugen processes the template and outputs the final stylesheet to `src/shared/styles/colors.css`.
|
||||
4. Modus automatically hot-reloads the new CSS, instantly applying the colors to the panel, dock, widgets, and menus.
|
||||
|
||||
## Customizing the Look
|
||||
|
||||
If you want to manually tweak borders, padding, font sizes, or add custom CSS classes, you should modify the files in `src/shared/styles/`.
|
||||
|
||||
### The CSS Hierarchy
|
||||
|
||||
- `src/shared/styles/main.css`: The primary entry point. It imports all other CSS components.
|
||||
- `src/shared/styles/colors.css`: **DO NOT EDIT THIS MANUALLY.** This is automatically generated by Matugen. If you want to change how colors are generated, edit the template at `config/matugen/templates/modus.css`.
|
||||
- `src/shared/styles/components/`: Contains isolated CSS for specific widgets (e.g. `dock.css`, `notification.css`, `panel.css`).
|
||||
|
||||
> [!TIP]
|
||||
> If you create a custom widget or add a new component, you can add a `.css` file inside the `components` directory and then `@import` it in `main.css`. Modus will apply it the next time it restarts!
|
||||
Reference in new issue
Block a user