diff --git a/.github/scripts/sync-wiki.py b/.github/scripts/sync-wiki.py
new file mode 100644
index 0000000..ebf543c
--- /dev/null
+++ b/.github/scripts/sync-wiki.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python3
+import json
+import re
+from pathlib import Path
+
+DOCS_DIR = Path("docs")
+WIKI_DIR = Path("wiki-temp")
+
+FRONTMATTER_RE = re.compile(r"\A---\s*\n.*?^---\s*\n", re.DOTALL | re.MULTILINE)
+DOCS_LINK_RE = re.compile(r"\[([^\]]+)\]\(/docs/(?:[^/)]+/)*([^/)#]+)(#[^)]+)?\)")
+
+
+def collect_all_files() -> list[tuple[Path, str]]:
+ files = []
+
+ def from_dir(directory: Path) -> list[Path]:
+ meta = directory / "meta.json"
+ if meta.exists():
+ data = json.loads(meta.read_text())
+ return [directory / f"{p}.md" for p in data.get("pages", []) if (directory / f"{p}.md").exists()]
+ return sorted(directory.glob("*.md"))
+
+ for src in from_dir(DOCS_DIR):
+ files.append((src, "Home" if src.stem == "index" else src.stem))
+
+ for subdir in sorted(DOCS_DIR.iterdir()):
+ if subdir.is_dir():
+ for src in from_dir(subdir):
+ files.append((src, src.stem))
+
+ return files
+
+
+def main() -> None:
+ files = collect_all_files()
+
+ contents = {src: src.read_text() for src, _ in files}
+
+ for src, dest_name in files:
+ text = FRONTMATTER_RE.sub("", contents[src], count=1).lstrip("\n")
+ text = DOCS_LINK_RE.sub(lambda m: f"[{m.group(1)}]({m.group(2)}{m.group(3) or ''})", text)
+ (WIKI_DIR / f"{dest_name}.md").write_text(text)
+
+ lines: list[str] = []
+ current_section = None
+ for src, dest_name in files:
+ section = "General" if src.parent == DOCS_DIR else src.parent.name.replace("-", " ").title()
+ if section != current_section:
+ if current_section is not None:
+ lines.append("")
+ lines.append(f"## {section}\n")
+ current_section = section
+ if dest_name != "Home":
+ title = dest_name.replace("-", " ").replace("_", " ").title()
+ lines.append(f"- [[{dest_name}|{title}]]")
+
+ (WIKI_DIR / "_Sidebar.md").write_text("\n".join(lines))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
index 43e8bad..d0b19c1 100644
--- a/.github/workflows/stale.yml
+++ b/.github/workflows/stale.yml
@@ -16,7 +16,7 @@ jobs:
days-before-issue-stale: -1
# 手动标记后,14 天后关闭
days-before-issue-close: 7
- # 使用的标签(必须和你手动添加的标签一致)
+ # 使用的标签
stale-issue-label: "stale"
# 自动关闭时自动加上的标签
close-issue-label: "automatic-closing"
diff --git a/.github/workflows/sync-website.yml b/.github/workflows/sync-website.yml
new file mode 100644
index 0000000..3577a65
--- /dev/null
+++ b/.github/workflows/sync-website.yml
@@ -0,0 +1,44 @@
+name: Sync website
+
+on:
+ push:
+ branches: [main]
+ paths:
+ - docs/**
+
+concurrency:
+ group: sync-website
+ cancel-in-progress: true
+
+jobs:
+ sync-website:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 1
+ token: ${{ github.token }}
+
+ - name: Checkout website
+ uses: actions/checkout@v4
+ with:
+ repository: mangowm/mangowm.github.io
+ path: website
+ token: ${{ secrets.WEBSITE_SYNC_TOKEN }}
+ fetch-depth: 1
+
+ - name: Sync docs
+ run: |
+ rm -rf website/apps/web/content/docs
+ cp -r docs website/apps/web/content/docs
+
+ - name: Commit and push
+ working-directory: website
+ run: |
+ git config user.name "github-actions[bot]"
+ git config user.email "github-actions[bot]@users.noreply.github.com"
+ git add apps/web/content/docs
+ git diff --staged --quiet || git commit \
+ -m "docs: content update from mangowm/mango" \
+ -m "${{ github.event.head_commit.message }}\nSource: ${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}"
+ git push
diff --git a/.github/workflows/sync-wiki.yml b/.github/workflows/sync-wiki.yml
new file mode 100644
index 0000000..ef30fe7
--- /dev/null
+++ b/.github/workflows/sync-wiki.yml
@@ -0,0 +1,40 @@
+name: Sync wiki
+
+on:
+ push:
+ branches: [main]
+ paths:
+ - docs/**
+
+concurrency:
+ group: sync-wiki
+ cancel-in-progress: true
+
+permissions:
+ contents: write
+
+jobs:
+ sync-wiki:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Clone wiki
+ run: |
+ git clone --depth 1 \
+ https://x-access-token:${{ github.token }}@github.com/${{ github.repository }}.wiki.git \
+ wiki-temp
+
+ - name: Sync docs to wiki
+ run: |
+ find wiki-temp -not -path 'wiki-temp/.git*' -type f -delete
+ python3 .github/scripts/sync-wiki.py
+
+ - name: Commit and push
+ working-directory: wiki-temp
+ run: |
+ git config user.name "github-actions[bot]"
+ git config user.email "github-actions[bot]@users.noreply.github.com"
+ git add -A
+ git diff --staged --quiet || git commit -m "sync from ${{ github.sha }}"
+ git push
diff --git a/README.md b/README.md
index 087bf13..b927b92 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Mango Wayland Compositor
-

+
This project's development is based on [dwl](https://codeberg.org/dwl/dwl/).
@@ -23,25 +23,22 @@ This project's development is based on [dwl](https://codeberg.org/dwl/dwl/).
- Ipc support(get/send message from/to compositor by external program)
- Hycov-like overview
- Window effects from scenefx (blur, shadow, corner radius, opacity)
+ - Zero flickering - every frame is perfect.
-Master-Stack Layout
+https://github.com/user-attachments/assets/bb83004a-0563-4b48-ad89-6461a9b78b1f
-https://github.com/user-attachments/assets/a9d4776e-b50b-48fb-94ce-651d8a749b8a
+# Mango's Vision
-Scroller Layout
+**Mango's primary goal is stability**: After months of testing and development—and aside from a few lingering GPU compatibility issues—it should now be stable enough. I don't plan on making many breaking changes.
-https://github.com/user-attachments/assets/c9bf9415-fad1-4400-bcdc-3ad2d76de85a
-
-Layer animation
-
-https://github.com/user-attachments/assets/014c893f-115c-4ae9-8342-f9ae3e9a0df0
+**Mango's preference is practicality**: I tend to add features that genuinely help with daily workflows—things that make our work more convenient.
+**Mango won't cater to every user preference**: For niche feature requests, I'll take a wait-and-see approach. I'll only consider adding them if they get a significant number of upvotes.
# Our discord
-[mangowc](https://discord.gg/CPjbDxesh5)
+[mangowm](https://discord.gg/CPjbDxesh5)
# Supported layouts
-
- tile
- scroller
- monocle
@@ -51,21 +48,20 @@ https://github.com/user-attachments/assets/014c893f-115c-4ae9-8342-f9ae3e9a0df0
- vertical_tile
- vertical_grid
- vertical_scroller
+- tgmix
# Installation
+[](https://repology.org/project/mangowm/versions)
+
## Dependencies
-- glibc
- wayland
- wayland-protocols
- libinput
- libdrm
- libxkbcommon
- pixman
-- git
-- meson
-- ninja
- libdisplay-info
- libliftoff
- hwdata
@@ -75,9 +71,9 @@ https://github.com/user-attachments/assets/014c893f-115c-4ae9-8342-f9ae3e9a0df0
- libxcb
## Arch Linux
-The package is in the Arch User Repository and is availble for manual download [here](https://aur.archlinux.org/packages/mangowc-git) or through a AUR helper like yay:
+The package is in the Arch User Repository and is available for manual download [here](https://aur.archlinux.org/packages/mangowm-git) or through a AUR helper like yay:
```bash
-yay -S mangowc-git
+yay -S mangowm-git
```
@@ -91,12 +87,12 @@ eselect repository enable guru
emerge --sync guru
```
-Then, add `gui-libs/scenefx` and `gui-wm/mangowc` to the `package.accept_keywords`.
+Then, add `gui-libs/scenefx` and `gui-wm/mangowm` to the `package.accept_keywords`.
Finally, install the package:
```bash
-emerge --ask --verbose gui-wm/mangowc
+emerge --ask --verbose gui-wm/mangowm
```
## Fedora Linux
@@ -106,9 +102,38 @@ First, add the [Terra Repository](https://terra.fyralabs.com/).
Then, install the package:
```bash
-dnf install mangowc
+dnf install mangowm
```
+## Guix System
+The package definition is described in the source repository.
+First, add `mangowm` channel to `channels.scm` file:
+
+```scheme
+;; In $HOME/.config/guix/channels.scm
+(cons (channel
+ (name 'mangowm)
+ (url "https://github.com/mangowm/mango.git")
+ (branch "main"))
+ ... ;; Your other channels
+ %default-channels)
+```
+
+Then, run `guix pull` and after update you can either run
+`guix install mangowm` or add it to your configuration via:
+
+```scheme
+(use-modules (mangowm)) ;; Add mangowm module
+
+;; Add mangowm to packages list
+(packages (cons*
+ mangowm-git
+ ... ;; Other packages you specified
+ %base-packages))
+```
+
+And then rebuild your system.
+
## Other
```bash
@@ -122,8 +147,8 @@ cd scenefx
meson build -Dprefix=/usr
sudo ninja -C build install
-git clone https://github.com/DreamMaoMao/mangowc.git
-cd mangowc
+git clone https://github.com/mangowm/mango.git
+cd mangowm
meson build -Dprefix=/usr
sudo ninja -C build install
```
@@ -181,9 +206,9 @@ git clone https://github.com/DreamMaoMao/mango-config.git ~/.config/mango
## Config Documentation
-Refer to the repo wiki [wiki](https://github.com/DreamMaoMao/mango/wiki/)
+Refer to the repo wiki [wiki](https://github.com/mangowm/mango/wiki/)
-or the website docs [docs](https://mangowc.vercel.app/docs)
+or the website docs [docs](https://mangowm.github.io/)
# NixOS + Home-manager
@@ -203,7 +228,7 @@ Here's an example of using the modules in a flake:
};
flake-parts.url = "github:hercules-ci/flake-parts";
mango = {
- url = "github:DreamMaoMao/mango";
+ url = "github:mangowm/mango";
inputs.nixpkgs.follows = "nixpkgs";
};
};
@@ -265,9 +290,9 @@ Here's an example of using the modules in a flake:
To package mango for other distributions, you can check the reference setup for:
-- [nix](https://github.com/DreamMaoMao/mangowc/blob/main/nix/default.nix)
-- [arch](https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=mangowc-git).
-- [gentoo](https://data.gpo.zugaina.org/guru/gui-wm/mangowc)
+- [nix](https://github.com/mangowm/mango/blob/main/nix/default.nix)
+- [arch](https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=mangowm-git).
+- [gentoo](https://data.gpo.zugaina.org/guru/gui-wm/mangowm)
You might need to package `scenefx` for your distribution, check availability [here](https://github.com/wlrfx/scenefx.git).
@@ -285,3 +310,15 @@ Read The Friendly Manual on packaging software in your distribution first.
- https://github.com/swaywm/sway - Sample of Wayland protocol
- https://github.com/wlrfx/scenefx - Make it simple to add window effect.
+
+
+# Sponsor
+At present, I can only accept sponsorship through an encrypted connection.
+If you find this project helpful to you, you can offer sponsorship in the following ways.
+
+
+
+
+Thanks to the following friends for their sponsorship of this project
+
+[@tonybanters](https://github.com/tonybanters)
diff --git a/config.conf b/assets/config.conf
similarity index 97%
rename from config.conf
rename to assets/config.conf
index 5483a14..15b654c 100644
--- a/config.conf
+++ b/assets/config.conf
@@ -26,7 +26,7 @@ focused_opacity=1.0
unfocused_opacity=1.0
# Animation Configuration(support type:zoom,slide)
-# tag_animation_direction: 0-horizontal,1-vertical
+# tag_animation_direction: 1-horizontal,0-vertical
animations=1
layer_animations=1
animation_type_open=slide
@@ -240,12 +240,11 @@ bind=CTRL+ALT,Left,resizewin,-50,+0
bind=CTRL+ALT,Right,resizewin,+50,+0
# Mouse Button Bindings
-# NONE mode key only work in ov mode
+# btn_left and btn_right can't bind none mod key
mousebind=SUPER,btn_left,moveresize,curmove
mousebind=NONE,btn_middle,togglemaximizescreen,0
mousebind=SUPER,btn_right,moveresize,curresize
-mousebind=NONE,btn_left,toggleoverview,1
-mousebind=NONE,btn_right,killclient,0
+
# Axis Bindings
axisbind=SUPER,UP,viewtoleft_have_client
diff --git a/assets/mango-portals.conf b/assets/mango-portals.conf
new file mode 100644
index 0000000..aebea31
--- /dev/null
+++ b/assets/mango-portals.conf
@@ -0,0 +1,5 @@
+[preferred]
+default=gtk
+org.freedesktop.impl.portal.ScreenCast=wlr
+org.freedesktop.impl.portal.Screenshot=wlr
+org.freedesktop.impl.portal.Inhibit=none
diff --git a/mango.desktop b/assets/mango.desktop
similarity index 78%
rename from mango.desktop
rename to assets/mango.desktop
index 0c109ce..37c4fad 100644
--- a/mango.desktop
+++ b/assets/mango.desktop
@@ -1,6 +1,7 @@
[Desktop Entry]
Encoding=UTF-8
Name=Mango
+DesktopNames=mango;wlroots
Comment=mango WM
Exec=mango
Icon=mango
diff --git a/docs/bindings/keys.md b/docs/bindings/keys.md
new file mode 100644
index 0000000..64ba64b
--- /dev/null
+++ b/docs/bindings/keys.md
@@ -0,0 +1,204 @@
+---
+title: Key Bindings
+description: Define keyboard shortcuts and modes.
+---
+
+## Syntax
+
+Key bindings follow this format:
+
+```ini
+bind[flags]=MODIFIERS,KEY,COMMAND,PARAMETERS
+```
+
+- **Modifiers**: `SUPER`, `CTRL`, `ALT`, `SHIFT`, `NONE` (combine with `+`, e.g. `SUPER+CTRL+ALT`).
+- **Key**: Key name (from `xev` or `wev`) or keycode (e.g., `code:24` for `q`).
+
+> **Info:** `bind` automatically converts keysym to keycode for comparison. This makes it compatible with all keyboard layouts, but the matching may not always be precise. If a key combination doesn't work on your keyboard layout, use a keycode instead (e.g., `code:24` instead of `q`).
+
+### Flags
+
+- `l`: Works even when screen is locked.
+- `s`: Uses keysym instead of keycode to bind.
+- `r`: Triggers on key release instead of press.
+- `p`: Pass key event to client.
+
+**Examples:**
+
+```ini
+bind=SUPER,Q,killclient
+bindl=SUPER,L,spawn,swaylock
+
+# Using keycode instead of key name
+bind=ALT,code:24,killclient
+
+# Combining keycodes for modifiers and keys
+bind=code:64,code:24,killclient
+bind=code:64+code:133,code:24,killclient
+
+# Bind with no modifier
+bind=NONE,XF86MonBrightnessUp,spawn,brightnessctl set +5%
+
+# Bind a modifier key itself as the trigger key
+bind=alt,shift_l,switch_keyboard_layout
+```
+
+## Key Modes (Submaps)
+
+You can divide key bindings into named modes. Rules:
+
+1. Set `keymode=` before a group of `bind` lines — those binds only apply in that mode.
+2. If no `keymode` is set before a bind, it belongs to the `default` mode.
+3. The special `common` keymode applies its binds **across all modes**.
+
+Use `setkeymode` to switch modes, and `mmsg -b` to query the current mode.
+
+```ini
+# Binds in 'common' apply in every mode
+keymode=common
+bind=SUPER,r,reload_config
+
+# Default mode bindings
+keymode=default
+bind=ALT,Return,spawn,foot
+bind=SUPER,F,setkeymode,resize
+
+# 'resize' mode bindings
+keymode=resize
+bind=NONE,Left,resizewin,-10,0
+bind=NONE,Right,resizewin,+10,0
+bind=NONE,Escape,setkeymode,default
+```
+
+### Single Modifier Key Binding
+
+When binding a modifier key itself, use `NONE` for press and the modifier name for release:
+
+```ini
+# Trigger on press of Super key
+bind=none,Super_L,spawn,rofi -show run
+
+# Trigger on release of Super key
+bindr=Super,Super_L,spawn,rofi -show run
+```
+
+## Dispatchers List
+
+### Window Management
+
+| Command | Param | Description |
+| :--- | :--- | :--- |
+| `killclient` | - | Close the focused window. |
+| `togglefloating` | - | Toggle floating state. |
+| `togglefullscreen` | - | Toggle fullscreen. |
+| `togglefakefullscreen` | - | Toggle "fake" fullscreen (remains constrained). |
+| `togglemaximizescreen` | - | Maximize window (keep decoration/bar). |
+| `toggleglobal` | - | Pin window to all tags. |
+| `toggle_render_border` | - | Toggle border rendering. |
+| `centerwin` | - | Center the floating window. |
+| `minimized` | - | Minimize window to scratchpad. |
+| `restore_minimized` | - | Restore window from scratchpad. |
+| `toggle_scratchpad` | - | Toggle scratchpad. |
+| `toggle_named_scratchpad` | `appid,title,cmd` | Toggle named scratchpad. Launches app if not running, otherwise shows/hides it. |
+
+### Focus & Movement
+
+| Command | Param | Description |
+| :--- | :--- | :--- |
+| `focusdir` | `left/right/up/down` | Focus window in direction. |
+| `focusstack` | `next/prev` | Cycle focus within the stack. |
+| `focuslast` | - | Focus the previously active window. |
+| `exchange_client` | `left/right/up/down` | Swap window with neighbor in direction. |
+| `exchange_stack_client` | `next/prev` | Exchange window position in stack. |
+| `zoom` | - | Swap focused window with Master. |
+
+### Tags & Monitors
+
+| Command | Param | Description |
+| :--- | :--- | :--- |
+| `view` | `-1/0/1-9` or `mask [,synctag]` | View tag. `-1` = previous tagset, `0` = all tags, `1-9` = specific tag, mask e.g. `1\|3\|5`. Optional `synctag` (0/1) syncs the action to all monitors. |
+| `viewtoleft` | `[synctag]` | View previous tag. Optional `synctag` (0/1) syncs to all monitors. |
+| `viewtoright` | `[synctag]` | View next tag. Optional `synctag` (0/1) syncs to all monitors. |
+| `viewtoleft_have_client` | `[synctag]` | View left tag and focus client if present. Optional `synctag` (0/1). |
+| `viewtoright_have_client` | `[synctag]` | View right tag and focus client if present. Optional `synctag` (0/1). |
+| `viewcrossmon` | `tag,monitor_spec` | View specified tag on specified monitor. |
+| `tag` | `1-9 [,synctag]` | Move window to tag. Optional `synctag` (0/1) syncs to all monitors. |
+| `tagsilent` | `1-9` | Move window to tag without focusing it. |
+| `tagtoleft` | `[synctag]` | Move window to left tag. Optional `synctag` (0/1). |
+| `tagtoright` | `[synctag]` | Move window to right tag. Optional `synctag` (0/1). |
+| `tagcrossmon` | `tag,monitor_spec` | Move window to specified tag on specified monitor. |
+| `toggletag` | `0-9` | Toggle tag on window (0 means all tags). |
+| `toggleview` | `1-9` | Toggle tag view. |
+| `comboview` | `1-9` | View multi tags pressed simultaneously. |
+| `focusmon` | `left/right/up/down/monitor_spec` | Focus monitor by direction or [monitor spec](/docs/configuration/monitors#monitor-spec-format). |
+| `tagmon` | `left/right/up/down/monitor_spec,[keeptag]` | Move window to monitor by direction or [monitor spec](/docs/configuration/monitors#monitor-spec-format). `keeptag` is 0 or 1. |
+
+### Layouts
+
+| Command | Param | Description |
+| :--- | :--- | :--- |
+| `setlayout` | `name` | Switch to layout (e.g., `scroller`, `tile`). |
+| `switch_layout` | - | Cycle through available layouts. |
+| `incnmaster` | `+1/-1` | Increase/Decrease number of master windows. |
+| `setmfact` | `+0.05` | Increase/Decrease master area size. |
+| `set_proportion` | `float` | Set scroller window proportion (0.0–1.0). |
+| `switch_proportion_preset` | - | Cycle proportion presets of scroller window. |
+| `scroller_stack` | `left/right/up/down` | Move window inside/outside scroller stack by direction. |
+| `incgaps` | `+/-value` | Adjust gap size. |
+| `togglegaps` | - | Toggle gaps. |
+
+### System
+
+| Command | Param | Description |
+| :--- | :--- | :--- |
+| `spawn` | `cmd` | Execute a command. |
+| `spawn_shell` | `cmd` | Execute shell command (supports pipes `\|`). |
+| `spawn_on_empty` | `cmd,tagnumber` | Open command on empty tag. |
+| `reload_config` | - | Hot-reload configuration. |
+| `quit` | - | Exit mangowm. |
+| `toggleoverview` | - | Toggle overview mode. |
+| `create_virtual_output` | - | Create a headless monitor (for VNC/Sunshine). |
+| `destroy_all_virtual_output` | - | Destroy all virtual monitors. |
+| `toggleoverlay` | - | Toggle overlay state for the focused window. |
+| `toggle_trackpad_enable` | - | Toggle trackpad enable. |
+| `setkeymode` | `mode` | Set keymode. |
+| `switch_keyboard_layout` | `[index]` | Switch keyboard layout. Optional index (0, 1, 2...) to switch to specific layout. |
+| `setoption` | `key,value` | Set config option temporarily. |
+| `disable_monitor` | `monitor_spec` | Shutdown monitor. Accepts a [monitor spec](/docs/configuration/monitors#monitor-spec-format). |
+| `enable_monitor` | `monitor_spec` | Power on monitor. Accepts a [monitor spec](/docs/configuration/monitors#monitor-spec-format). |
+| `toggle_monitor` | `monitor_spec` | Toggle monitor power. Accepts a [monitor spec](/docs/configuration/monitors#monitor-spec-format). |
+
+### Media Controls
+
+> **Warning:** Some keyboards don't send standard media keys. Run `wev` and press your key to check the exact key name.
+
+#### Brightness
+
+Requires: `brightnessctl`
+
+```ini
+bind=NONE,XF86MonBrightnessUp,spawn,brightnessctl s +2%
+bind=SHIFT,XF86MonBrightnessUp,spawn,brightnessctl s 100%
+bind=NONE,XF86MonBrightnessDown,spawn,brightnessctl s 2%-
+bind=SHIFT,XF86MonBrightnessDown,spawn,brightnessctl s 1%
+```
+
+#### Volume
+
+Requires: `wpctl` (WirePlumber)
+
+```ini
+bind=NONE,XF86AudioRaiseVolume,spawn,wpctl set-volume @DEFAULT_SINK@ 5%+
+bind=NONE,XF86AudioLowerVolume,spawn,wpctl set-volume @DEFAULT_SINK@ 5%-
+bind=NONE,XF86AudioMute,spawn,wpctl set-mute @DEFAULT_SINK@ toggle
+bind=SHIFT,XF86AudioMute,spawn,wpctl set-mute @DEFAULT_SOURCE@ toggle
+```
+
+### Floating Window Movement
+
+| Command | Param | Description |
+| :--- | :--- | :--- |
+| `smartmovewin` | `left/right/up/down` | Move floating window by snap distance. |
+| `smartresizewin` | `left/right/up/down` | Resize floating window by snap distance. |
+| `movewin` | `(x,y)` | Move floating window. |
+| `resizewin` | `(width,height)` | Resize window. |
\ No newline at end of file
diff --git a/docs/bindings/meta.json b/docs/bindings/meta.json
new file mode 100644
index 0000000..f1b629b
--- /dev/null
+++ b/docs/bindings/meta.json
@@ -0,0 +1,4 @@
+{
+ "title": "Bindings & Input",
+ "pages": ["keys", "mouse-gestures"]
+}
diff --git a/docs/bindings/mouse-gestures.md b/docs/bindings/mouse-gestures.md
new file mode 100644
index 0000000..c4a3688
--- /dev/null
+++ b/docs/bindings/mouse-gestures.md
@@ -0,0 +1,116 @@
+---
+title: Mouse & Gestures
+description: Configure mouse buttons, scrolling, gestures, and lid switches.
+---
+
+## Mouse Bindings
+
+Assign actions to mouse button presses with optional modifier keys.
+
+### Syntax
+
+```ini
+mousebind=MODIFIERS,BUTTON,COMMAND,PARAMETERS
+```
+
+- **Modifiers**: `SUPER`, `CTRL`, `ALT`, `SHIFT`, `NONE`. Combine with `+` (e.g., `SUPER+CTRL`)
+- **Buttons**: `btn_left`, `btn_right`, `btn_middle`, `btn_side`, `btn_extra`, `btn_forward`, `btn_back`, `btn_task`
+
+> **Warning:** When modifiers are set to `NONE`, only `btn_middle` works in normal mode. `btn_left` and `btn_right` only work in overview mode.
+
+### Examples
+
+```ini
+# Window manipulation
+mousebind=SUPER,btn_left,moveresize,curmove
+mousebind=SUPER,btn_right,moveresize,curresize
+mousebind=SUPER+CTRL,btn_right,killclient
+
+# Overview mode (requires NONE modifier)
+mousebind=NONE,btn_left,toggleoverview,-1
+mousebind=NONE,btn_right,killclient,0
+mousebind=NONE,btn_middle,togglemaximizescreen,0
+```
+
+---
+
+## Axis Bindings
+
+Map scroll wheel movements to actions for workspace and window navigation.
+
+### Syntax
+
+```ini
+axisbind=MODIFIERS,DIRECTION,COMMAND,PARAMETERS
+```
+
+- **Direction**: `UP`, `DOWN`, `LEFT`, `RIGHT`
+
+### Examples
+
+```ini
+axisbind=SUPER,UP,viewtoleft_have_client
+axisbind=SUPER,DOWN,viewtoright_have_client
+```
+
+---
+
+## Gesture Bindings
+
+Enable touchpad swipe gestures for navigation and window management.
+
+### Syntax
+
+```ini
+gesturebind=MODIFIERS,DIRECTION,FINGERS,COMMAND,PARAMETERS
+```
+
+- **Direction**: `up`, `down`, `left`, `right`
+- **Fingers**: `3` or `4`
+
+> **Info:** Gestures require proper touchpad configuration. See [Input Devices](/docs/configuration/input) for touchpad settings like `tap_to_click` and `disable_while_typing`.
+
+### Examples
+
+```ini
+# 3-finger: Window focus
+gesturebind=none,left,3,focusdir,left
+gesturebind=none,right,3,focusdir,right
+gesturebind=none,up,3,focusdir,up
+gesturebind=none,down,3,focusdir,down
+
+# 4-finger: Workspace navigation
+gesturebind=none,left,4,viewtoleft_have_client
+gesturebind=none,right,4,viewtoright_have_client
+gesturebind=none,up,4,toggleoverview
+gesturebind=none,down,4,toggleoverview
+```
+
+---
+
+## Switch Bindings
+
+Trigger actions on hardware events like laptop lid open/close.
+
+### Syntax
+
+```ini
+switchbind=FOLD_STATE,COMMAND,PARAMETERS
+```
+
+- **Fold State**: `fold` (lid closed), `unfold` (lid opened)
+
+> **Warning:** Disable system lid handling in `/etc/systemd/logind.conf`:
+>
+> ```ini
+> HandleLidSwitch=ignore
+> HandleLidSwitchExternalPower=ignore
+> HandleLidSwitchDocked=ignore
+> ```
+
+### Examples
+
+```ini
+switchbind=fold,spawn,swaylock -f -c 000000
+switchbind=unfold,spawn,wlr-dpms on
+```
diff --git a/docs/configuration/basics.md b/docs/configuration/basics.md
new file mode 100644
index 0000000..7afa343
--- /dev/null
+++ b/docs/configuration/basics.md
@@ -0,0 +1,87 @@
+---
+title: Basic Configuration
+description: Learn how to configure mangowm files, environment variables, and autostart scripts.
+---
+
+## Configuration File
+
+mangowm uses a simple configuration file format. By default, it looks for a configuration file in `~/.config/mango/`.
+
+1. **Locate Default Config**
+
+ A fallback configuration is provided at `/etc/mango/config.conf`. You can use this as a reference.
+
+2. **Create User Config**
+
+ Copy the default config to your local config directory to start customizing.
+
+ ```bash
+ mkdir -p ~/.config/mango
+ cp /etc/mango/config.conf ~/.config/mango/config.conf
+ ```
+
+3. **Launch with Custom Config (Optional)**
+
+ If you prefer to keep your config elsewhere, you can launch mango with the `-c` flag.
+
+ ```bash
+ mango -c /path/to/your_config.conf
+ ```
+
+### Sub-Configuration
+
+To keep your configuration organized, you can split it into multiple files and include them using the `source` keyword.
+
+```ini
+# Import keybindings from a separate file
+source=~/.config/mango/bind.conf
+
+# Relative paths work too
+source=./theme.conf
+
+# Optional: ignore if file doesn't exist (useful for shared configs)
+source-optional=~/.config/mango/optional.conf
+```
+
+### Validate Configuration
+
+You can check your configuration for errors without starting mangowm:
+
+```bash
+mango -c /path/to/config.conf -p
+```
+
+Use with `source-optional` for shared configs across different setups.
+
+## Environment Variables
+
+You can define environment variables directly within your config file. These are set before the window manager fully initializes.
+
+> **Warning:** Environment variables defined here will be **reset** every time you reload the configuration.
+
+```ini
+env=QT_IM_MODULES,wayland;fcitx
+env=XMODIFIERS,@im=fcitx
+```
+
+## Autostart
+
+mangowm can automatically run commands or scripts upon startup. There are two modes for execution:
+
+| Command | Behavior | Usage Case |
+| :--- | :--- | :--- |
+| `exec-once` | Runs **only once** when mangowm starts. | Status bars, Wallpapers, Notification daemons |
+| `exec` | Runs **every time** the config is reloaded. | Scripts that need to refresh settings |
+
+### Example Setup
+
+```ini
+# Start the status bar once
+exec-once=waybar
+
+# Set wallpaper
+exec-once=swaybg -i ~/.config/mango/wallpaper/room.png
+
+# Reload a custom script on config change
+exec=bash ~/.config/mango/reload-settings.sh
+```
diff --git a/docs/configuration/input.md b/docs/configuration/input.md
new file mode 100644
index 0000000..6d5eefd
--- /dev/null
+++ b/docs/configuration/input.md
@@ -0,0 +1,151 @@
+---
+title: Input Devices
+description: Configure keyboard layouts, mouse sensitivity, and touchpad gestures.
+---
+
+## Device Configuration
+
+mangowm provides granular control over different input devices.
+
+### Keyboard Settings
+
+Control key repeat rates and layout rules.
+
+| Setting | Type | Default | Description |
+| :--- | :--- | :--- | :--- |
+| `repeat_rate` | `int` | `25` | How many times a key repeats per second. |
+| `repeat_delay` | `int` | `600` | Delay (ms) before a held key starts repeating. |
+| `numlockon` | `0` or `1` | `0` | Enable NumLock on startup. |
+| `xkb_rules_rules` | `string` | - | XKB rules file (e.g., `evdev`, `base`). Usually auto-detected. |
+| `xkb_rules_model` | `string` | - | Keyboard model (e.g., `pc104`, `macbook`). |
+| `xkb_rules_layout` | `string` | - | Keyboard layout code (e.g., `us`, `de`, `us,de`). |
+| `xkb_rules_variant` | `string` | - | Layout variant (e.g., `dvorak`, `colemak`, `intl`). |
+| `xkb_rules_options` | `string` | - | XKB options (e.g., `caps:escape`, `ctrl:nocaps`). |
+
+**Example:**
+
+```ini
+repeat_rate=40
+repeat_delay=300
+numlockon=1
+xkb_rules_layout=us,de
+xkb_rules_variant=dvorak
+xkb_rules_options=caps:escape,ctrl:nocaps
+```
+
+---
+
+### Trackpad Settings
+
+Specific settings for laptop touchpads. Some settings may require a relogin to take effect.
+
+| Setting | Default | Description |
+| :--- | :--- | :--- |
+| `disable_trackpad` | `0` | Set to `1` to disable the trackpad entirely. |
+| `tap_to_click` | `1` | Tap to trigger a left click. |
+| `tap_and_drag` | `1` | Tap and hold to drag items. |
+| `trackpad_natural_scrolling` | `0` | Invert scrolling direction (natural scrolling). |
+| `scroll_method` | `1` | `1` (Two-finger), `2` (Edge), `4` (Button). |
+| `click_method` | `1` | `1` (Button areas), `2` (Clickfinger). |
+| `drag_lock` | `1` | Lock dragging after tapping. |
+| `disable_while_typing` | `1` | Disable trackpad while typing. |
+| `left_handed` | `0` | Swap left/right buttons. |
+| `middle_button_emulation` | `0` | Emulate middle button. |
+| `swipe_min_threshold` | `1` | Minimum swipe threshold. |
+
+---
+
+**Detailed descriptions:**
+
+- `scroll_method` values:
+ - `0` — Never send scroll events (no scrolling).
+ - `1` — Two-finger scrolling: send scroll events when two fingers are logically down on the device.
+ - `2` — Edge scrolling: send scroll events when a finger moves along the bottom or right edge.
+ - `4` — Button scrolling: send scroll events when a button is held and the device moves along a scroll axis.
+
+- `click_method` values:
+ - `0` — No software click emulation.
+ - `1` — Button areas: use software-defined areas on the touchpad to generate button events.
+ - `2` — Clickfinger: the number of fingers determines which button is pressed.
+
+- `accel_profile` values:
+ - `0` — No acceleration.
+ - `1` — Flat: no dynamic acceleration. Pointer speed = original input speed × (1 + `accel_speed`).
+ - `2` — Adaptive: slow movement results in less acceleration, fast movement results in more.
+
+- `button_map` values:
+ - `0` — 1/2/3 finger tap maps to left / right / middle.
+ - `1` — 1/2/3 finger tap maps to left / middle / right.
+
+- `send_events_mode` values:
+ - `0` — Send events from this device normally.
+ - `1` — Do not send events from this device.
+ - `2` — Disable this device when an external pointer device is plugged in.
+
+---
+
+### Mouse Settings
+
+Configuration for external mice.
+
+| Setting | Default | Description |
+| :--- | :--- | :--- |
+| `mouse_natural_scrolling` | `0` | Invert scrolling direction. |
+| `accel_profile` | `2` | `0` (None), `1` (Flat), `2` (Adaptive). |
+| `accel_speed` | `0.0` | Speed adjustment (-1.0 to 1.0). |
+| `left_handed` | `0` | Swap left and right buttons. |
+| `middle_button_emulation` | `0` | Emulate middle button. |
+| `swipe_min_threshold` | `1` | Minimum swipe threshold. |
+| `send_events_mode` | `0` | `0` (Enabled), `1` (Disabled), `2` (Disabled on external mouse). |
+| `button_map` | `0` | `0` (Left/right/middle), `1` (Left/middle/right). |
+
+---
+
+---
+
+## Keyboard Layout Switching
+
+To bind multiple layouts and toggle between them, define the layouts in `xkb_rules_layout` and use `xkb_rules_options` to set a toggle key combination. Then bind `switch_keyboard_layout` to trigger a switch.
+
+```ini
+# Define two layouts: US QWERTY and US Dvorak
+xkb_rules_layout=us,us
+xkb_rules_variant=,dvorak
+xkb_rules_options=grp:lalt_lshift_toggle
+```
+
+Or bind it manually to a key:
+
+```ini
+# Bind Alt+Shift_L to cycle keyboard layout
+bind=alt,shift_l,switch_keyboard_layout
+```
+
+Use `mmsg -g -k` to query the current keyboard layout at any time.
+
+---
+
+## Input Method Editor (IME)
+
+To use Fcitx5 or IBus, set these environment variables in your config file.
+
+> **Info:** These settings require a restart of the window manager to take effect.
+
+**For Fcitx5:**
+
+```ini
+env=GTK_IM_MODULE,fcitx
+env=QT_IM_MODULE,fcitx
+env=QT_IM_MODULES,wayland;fcitx
+env=SDL_IM_MODULE,fcitx
+env=XMODIFIERS,@im=fcitx
+env=GLFW_IM_MODULE,ibus
+```
+
+**For IBus:**
+
+```ini
+env=GTK_IM_MODULE,ibus
+env=QT_IM_MODULE,ibus
+env=XMODIFIERS,@im=ibus
+```
diff --git a/docs/configuration/meta.json b/docs/configuration/meta.json
new file mode 100644
index 0000000..bc209b4
--- /dev/null
+++ b/docs/configuration/meta.json
@@ -0,0 +1,4 @@
+{
+ "title": "Configuration",
+ "pages": ["basics", "monitors", "input", "xdg-portals", "miscellaneous"]
+}
diff --git a/docs/configuration/miscellaneous.md b/docs/configuration/miscellaneous.md
new file mode 100644
index 0000000..2e5a1e9
--- /dev/null
+++ b/docs/configuration/miscellaneous.md
@@ -0,0 +1,51 @@
+---
+title: Miscellaneous
+description: Advanced settings for XWayland, focus behavior, and system integration.
+---
+
+## System & Hardware
+
+| Setting | Default | Description |
+| :--- | :--- | :--- |
+| `xwayland_persistence` | `1` | Keep XWayland running even when no X11 apps are open (reduces startup lag). |
+| `syncobj_enable` | `0` | Enable `drm_syncobj` timeline support (helps with gaming stutter/lag). **Requires restart.** |
+| `allow_lock_transparent` | `0` | Allow the lock screen to be transparent. |
+| `allow_shortcuts_inhibit` | `1` | Allow shortcuts to be inhibited by clients. |
+| `vrr` | - | Set via [monitor rule](/docs/configuration/monitors#monitor-rules). |
+
+## Focus & Input
+
+| Setting | Default | Description |
+| :--- | :--- | :--- |
+| `focus_on_activate` | `1` | Automatically focus windows when they request activation. |
+| `sloppyfocus` | `1` | Focus follows the mouse cursor. |
+| `warpcursor` | `1` | Warp the cursor to the center of the window when focus changes via keyboard. |
+| `cursor_hide_timeout` | `0` | Hide the cursor after `N` seconds of inactivity (`0` to disable). |
+| `drag_tile_to_tile` | `0` | Allow dragging a tiled window onto another to swap their positions. |
+| `drag_corner` | `3` | Corner for drag-to-tile detection (0: none, 1–3: corners, 4: auto-detect). |
+| `drag_warp_cursor` | `1` | Warp cursor when dragging windows to tile. |
+| `axis_bind_apply_timeout` | `100` | Timeout (ms) for detecting consecutive scroll events for axis bindings. |
+| `axis_scroll_factor` | `1.0` | Scroll factor for axis scroll speed (0.1–10.0). |
+
+## Multi-Monitor & Tags
+
+| Setting | Default | Description |
+| :--- | :--- | :--- |
+| `focus_cross_monitor` | `0` | Allow directional focus to cross monitor boundaries. |
+| `exchange_cross_monitor` | `0` | Allow exchanging clients across monitor boundaries. |
+| `focus_cross_tag` | `0` | Allow directional focus to cross into other tags. |
+| `view_current_to_back` | `0` | Toggling the current tag switches back to the previously viewed tag. |
+| `scratchpad_cross_monitor` | `0` | Share the scratchpad pool across all monitors. |
+| `single_scratchpad` | `1` | Only allow one scratchpad (named or standard) to be visible at a time. |
+| `circle_layout` | - | A comma-separated list of layouts `switch_layout` cycles through,the value sample:`tile,scroller`. |
+
+## Window Behavior
+
+| Setting | Default | Description |
+| :--- | :--- | :--- |
+| `enable_floating_snap` | `0` | Snap floating windows to edges or other windows. |
+| `snap_distance` | `30` | Max distance (pixels) to trigger floating snap. |
+| `no_border_when_single` | `0` | Remove window borders when only one window is visible on the tag. |
+| `idleinhibit_ignore_visible` | `0` | Allow invisible clients (e.g., background audio players) to inhibit idle. |
+| `drag_tile_refresh_interval` | `8.0` | Interval (1.0–16.0) to refresh tiled window resize during drag. Too small may cause application lag. |
+| `drag_floating_refresh_interval` | `8.0` | Interval (1.0–16.0) to refresh floating window resize during drag. Too small may cause application lag. |
\ No newline at end of file
diff --git a/docs/configuration/monitors.md b/docs/configuration/monitors.md
new file mode 100644
index 0000000..5501c77
--- /dev/null
+++ b/docs/configuration/monitors.md
@@ -0,0 +1,274 @@
+---
+title: Monitors
+description: Manage display outputs, resolution, scaling, and tearing.
+---
+
+## Monitor Rules
+
+You can configure each display output individually using the `monitorrule` keyword.
+
+**Syntax:**
+
+```ini
+monitorrule=name:Values,Parameter:Values,Parameter:Values
+```
+
+> **Info:** If any of the matching fields (`name`, `make`, `model`, `serial`) are set, **all** of the set ones must match to be considered a match. Use `wlr-randr` to get your monitor's name, make, model, and serial.
+
+### Parameters
+
+| Parameter | Type | Values | Description |
+| :--- | :--- | :--- | :--- |
+| `name` | string | Any | Match by monitor name (supports regex) |
+| `make` | string | Any | Match by monitor manufacturer |
+| `model` | string | Any | Match by monitor model |
+| `serial` | string | Any | Match by monitor serial number |
+| `width` | integer | 0-9999 | Monitor width |
+| `height` | integer | 0-9999 | Monitor height |
+| `refresh` | float | 0.001-9999.0 | Monitor refresh rate |
+| `x` | integer | 0-99999 | X position |
+| `y` | integer | 0-99999 | Y position |
+| `scale` | float | 0.01-100.0 | Monitor scale |
+| `vrr` | integer | 0, 1 | Enable variable refresh rate |
+| `rr` | integer | 0-7 | Monitor transform |
+| `custom` | integer | 0, 1 | Enable custom mode (not supported on all displays — may cause black screen) |
+
+### Transform Values
+
+| Value | Rotation |
+| :--- | :--- |
+| `0` | No transform |
+| `1` | 90° counter-clockwise |
+| `2` | 180° counter-clockwise |
+| `3` | 270° counter-clockwise |
+| `4` | 180° vertical flip |
+| `5` | Flip + 90° counter-clockwise |
+| `6` | Flip + 180° counter-clockwise |
+| `7` | Flip + 270° counter-clockwise |
+
+> **Critical:** If you use XWayland applications, **never use negative coordinates** for your monitor positions. This is a known XWayland bug that causes click events to malfunction. Always arrange your monitors starting from `0,0` and extend into positive coordinates.
+
+### Examples
+
+```ini
+# Laptop display: 1080p, 60Hz, positioned at origin
+monitorrule=name:eDP-1,width:1920,height:1080,refresh:60,x:0,y:10
+
+# Match by make and model instead of name
+monitorrule=make:Chimei Innolux Corporation,model:0x15F5,width:1920,height:1080,refresh:60,x:0,y:0
+
+# Virtual monitor with pattern matching
+monitorrule=name:HEADLESS-.*,width:1920,height:1080,refresh:60,x:1926,y:0,scale:1,rr:0,vrr:0
+```
+
+---
+
+## Monitor Spec Format
+
+Several commands (`focusmon`, `tagmon`, `disable_monitor`, `enable_monitor`, `toggle_monitor`, `viewcrossmon`, `tagcrossmon`) accept a **monitor_spec** string to identify a monitor.
+
+**Format:**
+
+```text
+name:xxx&&make:xxx&&model:xxx&&serial:xxx
+```
+
+- Any field can be omitted and there is no order requirement.
+- If all fields are omitted, the string is treated as the monitor name directly (e.g., `eDP-1`).
+- Use `wlr-randr` to find your monitor's name, make, model, and serial.
+
+**Examples:**
+
+```bash
+# By name (shorthand)
+mmsg -d toggle_monitor,eDP-1
+
+# By make and model
+mmsg -d toggle_monitor,make:Chimei Innolux Corporation&&model:0x15F5
+
+# By serial
+mmsg -d toggle_monitor,serial:12345678
+```
+
+---
+
+## Tearing (Game Mode)
+
+Tearing allows games to bypass the compositor's VSync for lower latency.
+
+| Setting | Default | Description |
+| :--- | :--- | :--- |
+| `allow_tearing` | `0` | Global tearing control: `0` (Disable), `1` (Enable), `2` (Fullscreen only). |
+
+### Configuration
+
+**Enable Globally:**
+
+```ini
+allow_tearing=1
+```
+
+**Enable per Window:**
+
+Use a window rule to force tearing for specific games.
+
+```ini
+windowrule=force_tearing:1,title:vkcube
+```
+
+### Tearing Behavior Matrix
+
+| `force_tearing` \ `allow_tearing` | DISABLED (0) | ENABLED (1) | FULLSCREEN_ONLY (2) |
+| :--- | :--- | :--- | :--- |
+| **UNSPECIFIED** (0) | Not Allowed | Follows tearing_hint | Only fullscreen follows tearing_hint |
+| **ENABLED** (1) | Not Allowed | Allowed | Only fullscreen allowed |
+| **DISABLED** (2) | Not Allowed | Not Allowed | Not Allowed |
+
+### Graphics Card Compatibility
+
+> **Warning:** Some graphics cards require setting the `WLR_DRM_NO_ATOMIC` environment variable before mango starts to successfully enable tearing.
+
+Add this to `/etc/environment` and reboot:
+
+```bash
+WLR_DRM_NO_ATOMIC=1
+```
+
+Or run mango with the environment variable:
+
+```bash
+WLR_DRM_NO_ATOMIC=1 mango
+```
+
+---
+
+## GPU Compatibility
+
+If mango cannot display correctly or shows a black screen, try selecting a specific GPU:
+
+```bash
+# Use a single GPU
+WLR_DRM_DEVICES=/dev/dri/card1 mango
+
+# Use multiple GPUs
+WLR_DRM_DEVICES=/dev/dri/card0:/dev/dri/card1 mango
+```
+
+Some GPUs have compatibility issues with `syncobj_enable=1` — it may crash apps like `kitty` that use syncobj. Set `WLR_DRM_NO_ATOMIC=1` in `/etc/environment` and reboot to resolve this.
+
+---
+
+## Power Management
+
+You can control monitor power using the `mmsg` IPC tool.
+
+```bash
+# Turn off
+mmsg -d disable_monitor,eDP-1
+
+# Turn on
+mmsg -d enable_monitor,eDP-1
+
+# Toggle
+mmsg -d toggle_monitor,eDP-1
+```
+
+You can also use `wlr-randr` for monitor management:
+
+```bash
+# Turn off monitor
+wlr-randr --output eDP-1 --off
+
+# Turn on monitor
+wlr-randr --output eDP-1 --on
+
+# Show all monitors
+wlr-randr
+```
+
+---
+
+## Screen Scale
+
+### Without Global Scale (Recommended)
+
+- If you do not use XWayland apps, you can use monitor rules or `wlr-randr` to set a global monitor scale.
+- If you are using XWayland apps, it is not recommended to set a global monitor scale.
+
+You can set scale like this, for example with a 1.4 factor.
+
+**Dependencies:**
+
+```bash
+yay -S xorg-xrdb
+yay -S xwayland-satellite
+```
+
+**In config file:**
+
+```ini
+env=QT_AUTO_SCREEN_SCALE_FACTOR,1
+env=QT_WAYLAND_FORCE_DPI,140
+```
+
+**In autostart:**
+
+```bash
+echo "Xft.dpi: 140" | xrdb -merge
+gsettings set org.gnome.desktop.interface text-scaling-factor 1.4
+```
+
+**Edit autostart for XWayland:**
+
+```bash
+# Start xwayland
+/usr/sbin/xwayland-satellite :11 &
+# Apply scale 1.4 for xwayland
+sleep 0.5s && echo "Xft.dpi: 140" | xrdb -merge
+```
+
+### Using xwayland-satellite to Prevent Blurry XWayland Apps
+
+If you use fractional scaling, you can use `xwayland-satellite` to automatically scale XWayland apps to prevent blurriness, for example with a scale of 1.4.
+
+**Dependencies:**
+
+```bash
+yay -S xwayland-satellite
+```
+
+**In config file:**
+
+```ini
+env=DISPLAY,:2
+exec-once=xwayland-satellite :2
+monitorrule=name:eDP-1,width:1920,height:1080,refresh:60,x:0,y:0,scale:1.4,vrr:0,rr:0
+```
+
+> **Warning:** Use a `DISPLAY` value other than `:1` to avoid conflicting with mangowm.
+
+---
+
+## Virtual Monitors
+
+You can create and manage virtual displays through IPC commands:
+
+```bash
+# Create virtual output
+mmsg -d create_virtual_output
+
+# Destroy all virtual outputs
+mmsg -d destroy_all_virtual_output
+```
+
+You can configure virtual monitors using `wlr-randr`:
+
+```bash
+# Show all monitors
+wlr-randr
+
+# Configure virtual monitor
+wlr-randr --output HEADLESS-1 --pos 1921,0 --scale 1 --custom-mode 1920x1080@60Hz
+```
+
+Virtual monitors can be used for screen sharing with tools like [Sunshine](https://github.com/LizardByte/Sunshine) and [Moonlight](https://github.com/moonlight-stream/moonlight-android), allowing other devices to act as extended monitors.
\ No newline at end of file
diff --git a/docs/configuration/xdg-portals.md b/docs/configuration/xdg-portals.md
new file mode 100644
index 0000000..27819ad
--- /dev/null
+++ b/docs/configuration/xdg-portals.md
@@ -0,0 +1,76 @@
+---
+title: XDG Portals
+description: Set up screen sharing, clipboard, keyring, and file pickers using XDG portals.
+---
+
+## Portal Configuration
+
+You can customize portal settings via the following paths:
+
+- **User Configuration (Priority):** `~/.config/xdg-desktop-portal/mango-portals.conf`
+- **System Fallback:** `/usr/share/xdg-desktop-portal/mango-portals.conf`
+
+> **Warning:** If you previously added `dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=wlroots` to your config, remove it. Mango now handles this automatically.
+
+## Screen Sharing
+
+To enable screen sharing (OBS, Discord, WebRTC), you need `xdg-desktop-portal-wlr`.
+
+1. **Install Dependencies**
+
+ `pipewire`, `pipewire-pulse`, `xdg-desktop-portal-wlr`
+
+2. **Optional: Add to autostart**
+
+ In some situations the portal may not start automatically. You can add this to your autostart script to ensure it launches:
+
+ ```bash
+ /usr/lib/xdg-desktop-portal-wlr &
+ ```
+
+3. **Restart your computer** to apply changes.
+
+### Known Issues
+
+- **Window screen sharing:** Some applications may have issues sharing individual windows. See [#184](https://github.com/mangowm/mango/pull/184) for workarounds.
+
+- **Screen recording lag:** If you experience stuttering during screen recording, see [xdg-desktop-portal-wlr#351](https://github.com/emersion/xdg-desktop-portal-wlr/issues/351).
+
+## Clipboard Manager
+
+Use `cliphist` to manage clipboard history.
+
+**Dependencies:** `wl-clipboard`, `cliphist`, `wl-clip-persist`
+
+**Autostart Config:**
+
+```bash
+# Keep clipboard content after app closes
+wl-clip-persist --clipboard regular --reconnect-tries 0 &
+
+# Watch clipboard and store history
+wl-paste --type text --watch cliphist store &
+```
+
+## GNOME Keyring
+
+If you need to store passwords or secrets (e.g., for VS Code or Minecraft launchers), install `gnome-keyring`.
+
+**Configuration:**
+
+Add the following to `~/.config/xdg-desktop-portal/mango-portals.conf`:
+
+```ini
+[preferred]
+default=gtk
+org.freedesktop.impl.portal.ScreenCast=wlr
+org.freedesktop.impl.portal.Screenshot=wlr
+org.freedesktop.impl.portal.Secret=gnome-keyring
+org.freedesktop.impl.portal.Inhibit=none
+```
+
+## File Picker (File Selector)
+
+**Dependencies:** `xdg-desktop-portal`, `xdg-desktop-portal-gtk`
+
+Reboot your computer once to apply.
\ No newline at end of file
diff --git a/docs/faq.md b/docs/faq.md
new file mode 100644
index 0000000..13c6391
--- /dev/null
+++ b/docs/faq.md
@@ -0,0 +1,101 @@
+---
+title: FAQ
+description: Frequently asked questions and troubleshooting.
+---
+
+### How do I arrange tiled windows with my mouse?
+
+You can enable the `drag_tile_to_tile` option in your config. This allows you to drag a tiled window onto another to swap them.
+
+```ini
+drag_tile_to_tile=1
+```
+
+---
+
+### Why is my background blurry or why does blur look wrong?
+
+Blur applies to the transparent areas of windows. To disable it entirely, set `blur=0`.
+
+If you are experiencing **performance issues with blur**, make sure `blur_optimized=1` (the default). This caches the wallpaper as the blur background, which is much cheaper on the GPU:
+
+```ini
+blur_optimized=1
+```
+
+---
+
+### Blur shows my wallpaper instead of the real background content
+
+This is expected behavior when `blur_optimized=1` (the default). The optimizer caches the wallpaper to reduce GPU load — windows will blur against the wallpaper rather than the actual content stacked beneath them.
+
+If you want blur to composite against the true background (i.e., show whatever is actually behind the window), set:
+
+```ini
+blur_optimized=0
+```
+
+> **Warning:** Disabling `blur_optimized` significantly increases GPU consumption and may cause rendering lag, especially on lower-end hardware.
+
+---
+
+### My games are lagging or stuttering
+
+Try enabling **SyncObj** timeline support and **Adaptive Sync** (VRR) if your monitor supports it.
+
+```ini
+syncobj_enable=1
+adaptive_sync=1
+```
+
+---
+
+### My games have high input latency
+
+You can enable **Tearing** (similar to VSync off).
+
+First, enable it globally:
+
+```ini
+allow_tearing=1
+```
+
+Then force it for your specific game:
+
+```ini
+windowrule=force_tearing:1,title:Counter-Strike 2
+```
+
+> **Warning:** Some graphics cards require setting `WLR_DRM_NO_ATOMIC=1` before mango starts for tearing to work. Add it to `/etc/environment` and reboot, or launch mango with `WLR_DRM_NO_ATOMIC=1 mango`. See [Monitors — Tearing](/docs/configuration/monitors#tearing-game-mode) for details.
+
+---
+
+### How do I use pipes `|` in spawn commands?
+
+The standard `spawn` command does not support shell pipes directly. You must use `spawn_shell` instead.
+
+```ini
+bind=SUPER,P,spawn_shell,echo "hello" | rofi -dmenu
+```
+
+---
+
+### Certain key combinations do not work on my keyboard layout.
+
+`bind` automatically converts keysym to keycode, which is compatible with most layouts but can sometimes be imprecise. If a key combination is not triggering, use the **keycode** directly instead of the key name.
+
+Run `wev` and press the key to find its keycode, then use it in your bind:
+
+```ini
+# Instead of:
+bind=ALT,q,killclient
+
+# Use the keycode (e.g., code:24 = q on most layouts):
+bind=ALT,code:24,killclient
+```
+
+You can also use `binds` (the `s` flag) to match by keysym instead of keycode:
+
+```ini
+binds=ALT,q,killclient
+```
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..d308370
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,42 @@
+---
+title: Introduction
+description: A lightweight and feature-rich Wayland compositor based on dwl.
+---
+
+
+**mango** is a Wayland compositor based on [dwl](https://codeberg.org/dwl/dwl/). It aims to be as lightweight as `dwl` and can be built completely within a few seconds, without compromising on functionality.
+
+> **Philosophy:** **Lightweight & Fast**: mango is designed to be minimal yet functional. It compiles in seconds and offers a robust set of features out of the box.
+
+## Feature Highlights
+
+Beyond basic window management, mangowm provides a rich set of features designed for a modern Wayland experience.
+
+- **[Animations](/docs/visuals/animations)** — Smooth, customizable animations for opening, moving, closing windows and tag switching.
+- **[Layouts](/docs/window-management/layouts)** — Supports Scroller, Master-Stack, Monocle, Grid, Deck, and more, with per-tag layouts.
+- **[Visual Effects](/docs/visuals/effects)** — Built-in blur, shadows, corner radius, and opacity effects powered by scenefx.
+- **[IPC & Scripting](/docs/ipc)** — Control the compositor externally with robust IPC support for custom scripts and widgets.
+
+## Additional Features
+
+- **XWayland Support** — Excellent compatibility for legacy X11 applications.
+- **Tag System** — Uses tags instead of workspaces, allowing separate window layouts for each tag.
+- **Input Methods** — Great support for text input v2/v3 (Fcitx5, IBus).
+- **Window States** — Rich states including swallow, minimize, maximize, fullscreen, and overlay.
+- **Hot-Reload Config** — Simple external configuration that supports hot-reloading without restarting.
+- **Scratchpads** — Support for both Sway-like and named scratchpads.
+
+## Community
+
+- **[Join the mangowm Discord](https://discord.gg/CPjbDxesh5)** — Chat with the community, get support, share your setup, and stay updated with the latest mangowm news.
+- **[Join the GitHub Discussions](https://github.com/mangowm/mango/discussions)** — Ask questions, request features, report issues, or share ideas directly with contributors and other users.
+
+## Acknowledgements
+
+This project is built upon the hard work of several open-source projects:
+
+- **[wlroots](https://gitlab.freedesktop.org/wlroots/wlroots)** — Implementation of the Wayland protocol.
+- **[mwc](https://github.com/nikoloc/mwc)** — Basal window animation reference.
+- **[dwl](https://codeberg.org/dwl/dwl)** — Basal dwl features.
+- **[sway](https://github.com/swaywm/sway)** — Sample implementation of the Wayland protocol.
+- **[scenefx](https://github.com/wlrfx/scenefx)** — Library to simplify adding window effects.
diff --git a/docs/installation.md b/docs/installation.md
new file mode 100644
index 0000000..10d2bd4
--- /dev/null
+++ b/docs/installation.md
@@ -0,0 +1,239 @@
+---
+title: Installation
+description: Install mangowm on AerynOS, Arch, Fedora, Gentoo, Guix System, NixOS, PikaOS, or build from source.
+---
+
+## Package Installation
+
+mangowm is available as a pre-built package on several distributions. Choose your distribution below.
+
+---
+
+### AerynOS
+
+mangowm is available in the **AerynOS package repository**.
+
+You can install it using the `moss` package manager:
+
+```bash
+sudo moss install mangowm
+```
+
+---
+
+### Arch Linux
+
+mangowm is available in the **Arch User Repository (AUR)**.
+
+You can install it using an AUR helper like `yay` or `paru`:
+
+```bash
+yay -S mangowm-git
+```
+
+> **Tip:** This package pulls the latest git version, ensuring you have the newest features and fixes.
+
+---
+
+### Fedora
+
+The package is in the third-party **Terra repository**. First, add the Terra Repository.
+
+> **Warning:** Both commands require root privileges. Use `sudo` if needed.
+
+```bash
+dnf install --nogpgcheck --repofrompath 'terra,https://repos.fyralabs.com/terra$releasever' terra-release
+```
+
+Then, install the package:
+
+```bash
+dnf install mangowm
+```
+
+---
+
+### Gentoo
+
+The package is hosted in the community-maintained **GURU** repository.
+
+1. **Add the GURU repository**
+ ```bash
+ emerge --ask --verbose eselect-repository
+ eselect repository enable guru
+ emerge --sync guru
+ ```
+
+2. **Unmask packages**
+ Add the required packages to your `package.accept_keywords` file:
+ - `gui-libs/scenefx`
+ - `gui-wm/mangowm`
+
+3. **Install mango**
+ ```bash
+ emerge --ask --verbose gui-wm/mangowm
+ ```
+
+---
+
+### Guix System
+
+The package definition is described in the source repository.
+
+1. **Add mango channel**
+ Add to `$HOME/.config/guix/channels.scm`:
+ ```scheme
+ (cons (channel
+ (name 'mangowm)
+ (url "https://github.com/mangowm/mango.git")
+ (branch "main"))
+ %default-channels)
+ ```
+
+2. **Install**
+ After running `guix pull`, you can install mangowm:
+ ```bash
+ guix install mangowm
+ ```
+
+ Or add it to your system configuration using the mangowm module:
+ ```scheme
+ (use-modules (mangowm))
+
+ (packages (cons*
+ mangowm-git
+ ... ;; Other packages
+ %base-packages))
+ ```
+
+> **Tip:** For more information, see the [Guix System documentation](https://guix.gnu.org/manual/devel/en/html_node/Channels.html).
+
+---
+
+### NixOS
+
+The repository provides a Flake with a NixOS module.
+
+1. **Add flake input**
+ ```nix
+ # flake.nix
+ {
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+ mangowm = {
+ url = "github:mangowm/mango";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ # other inputs ...
+ };
+ }
+ ```
+
+2. **Import the NixOS module**
+
+ **Option A — Import in `configuration.nix`:**
+ ```nix
+ # configuration.nix (or any other file that you import)
+ {inputs, ...}: {
+ imports = [
+ inputs.mangowm.nixosModules.mango
+ # .. other imports ...
+ ];
+
+ # ...
+ }
+ ```
+
+ **Option B — Import directly in flake:**
+ ```nix
+ # flake.nix
+ {
+ # ...
+
+ outputs = { self, nixpkgs, mangowm, ...}@inputs: let
+ inherit (nixpkgs) lib;
+ # ...
+ in {
+ nixosConfigurations.YourHostName = lib.nixosSystem {
+ modules = [
+ mangowm.nixosModules.mango # or inputs.mangowm.nixosModules.mango
+ # other imports ...
+ ];
+ };
+ }
+ }
+ ```
+
+3. **Enable the module**
+ ```nix
+ # configuration.nix (or any other file that you import)
+ {
+ programs.mango.enable = true;
+ }
+ ```
+
+4. **Extra options**
+ - `programs.mango.package` — the mango package to use, allows usage of custom mango drvs
+ - `programs.mango.addLoginEntry` (default: `true`) — adds login entry to the display manager
+
+---
+
+### PikaOS
+
+mangowm is available in the **PikaOS package repository**.
+
+You can install it using the `pikman` package manager:
+
+```bash
+pikman install mangowc
+```
+
+---
+
+## Building from Source
+
+If your distribution isn't listed above, or you want the latest unreleased changes, you can build mangowm from source.
+
+> **Info:** Ensure the following dependencies are installed before proceeding:
+> - `wayland`
+> - `wayland-protocols`
+> - `libinput`
+> - `libdrm`
+> - `libxkbcommon`
+> - `pixman`
+> - `libdisplay-info`
+> - `libliftoff`
+> - `hwdata`
+> - `seatd`
+> - `pcre2`
+> - `xorg-xwayland`
+> - `libxcb`
+
+You will need to build `wlroots` and `scenefx` manually as well.
+
+1. **Build wlroots**
+ Clone and install the specific version required (check README for latest version).
+ ```bash
+ git clone -b 0.19.2 https://gitlab.freedesktop.org/wlroots/wlroots.git
+ cd wlroots
+ meson build -Dprefix=/usr
+ sudo ninja -C build install
+ ```
+
+2. **Build scenefx**
+ This library handles the visual effects.
+ ```bash
+ git clone -b 0.4.1 https://github.com/wlrfx/scenefx.git
+ cd scenefx
+ meson build -Dprefix=/usr
+ sudo ninja -C build install
+ ```
+
+3. **Build mangowm**
+ Finally, compile the compositor itself.
+ ```bash
+ git clone https://github.com/mangowm/mango.git
+ cd mango
+ meson build -Dprefix=/usr
+ sudo ninja -C build install
+ ```
diff --git a/docs/ipc.md b/docs/ipc.md
new file mode 100644
index 0000000..72beefb
--- /dev/null
+++ b/docs/ipc.md
@@ -0,0 +1,154 @@
+---
+title: IPC
+description: Control mangowm programmatically using mmsg.
+---
+
+## Introduction
+
+mangowm includes a powerful IPC (Inter-Process Communication) tool called `mmsg`. This allows you to query the window manager's state, watch for events, and execute commands from external scripts.
+
+## Basic Usage
+
+The general syntax for `mmsg` is:
+
+```bash
+mmsg [-OTLq]
+mmsg [-o