mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-03-23 05:35:53 -04:00
Merge branch 'mangowm:main' into main
This commit is contained in:
commit
e3309c7e1b
46 changed files with 3533 additions and 1014 deletions
61
.github/scripts/sync-wiki.py
vendored
Normal file
61
.github/scripts/sync-wiki.py
vendored
Normal file
|
|
@ -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()
|
||||
44
.github/workflows/sync-website.yml
vendored
Normal file
44
.github/workflows/sync-website.yml
vendored
Normal file
|
|
@ -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.server_url }}/${{ github.repository }}/commit/${{ github.sha }}"
|
||||
git push
|
||||
40
.github/workflows/sync-wiki.yml
vendored
Normal file
40
.github/workflows/sync-wiki.yml
vendored
Normal file
|
|
@ -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
|
||||
15
docs/bindings/index.mdx
Normal file
15
docs/bindings/index.mdx
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
title: Bindings & Input
|
||||
description: Keybindings, mouse gestures, and input devices.
|
||||
icon: Keyboard
|
||||
---
|
||||
|
||||
Configure how you interact with mangowm using flexible keybindings and input options.
|
||||
|
||||
<Cards>
|
||||
|
||||
<Card href="/docs/bindings/keys" title="Key Bindings" description="Keyboard shortcuts and modes" />
|
||||
|
||||
<Card href="/docs/bindings/mouse-gestures" title="Mouse Gestures" description="Touchpad and mouse gestures" />
|
||||
|
||||
</Cards>
|
||||
204
docs/bindings/keys.md
Normal file
204
docs/bindings/keys.md
Normal file
|
|
@ -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=<name>` 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. |
|
||||
4
docs/bindings/meta.json
Normal file
4
docs/bindings/meta.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"title": "Bindings & Input",
|
||||
"pages": ["keys", "mouse-gestures"]
|
||||
}
|
||||
116
docs/bindings/mouse-gestures.md
Normal file
116
docs/bindings/mouse-gestures.md
Normal file
|
|
@ -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
|
||||
```
|
||||
87
docs/configuration/basics.md
Normal file
87
docs/configuration/basics.md
Normal file
|
|
@ -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
|
||||
```
|
||||
21
docs/configuration/index.mdx
Normal file
21
docs/configuration/index.mdx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
title: Configuration
|
||||
description: Configure mangowm with config files, environment variables, and autostart.
|
||||
icon: Settings
|
||||
---
|
||||
|
||||
Configure mangowm through config files, environment variables, and autostart.
|
||||
|
||||
<Cards>
|
||||
|
||||
<Card href="/docs/configuration/basics" title="Basics" description="Config files, env vars, exec-once, exec" />
|
||||
|
||||
<Card href="/docs/configuration/monitors" title="Monitors" description="Monitor settings and resolution" />
|
||||
|
||||
<Card href="/docs/configuration/input" title="Input" description="Keyboard, mouse, and touchpad" />
|
||||
|
||||
<Card href="/docs/configuration/xdg-portals" title="XDG Portals" description="File pickers and notifications" />
|
||||
|
||||
<Card href="/docs/configuration/miscellaneous" title="Miscellaneous" description="Additional options" />
|
||||
|
||||
</Cards>
|
||||
151
docs/configuration/input.md
Normal file
151
docs/configuration/input.md
Normal file
|
|
@ -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
|
||||
```
|
||||
4
docs/configuration/meta.json
Normal file
4
docs/configuration/meta.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"title": "Configuration",
|
||||
"pages": ["basics", "monitors", "input", "xdg-portals", "miscellaneous"]
|
||||
}
|
||||
51
docs/configuration/miscellaneous.md
Normal file
51
docs/configuration/miscellaneous.md
Normal file
|
|
@ -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. |
|
||||
276
docs/configuration/monitors.md
Normal file
276
docs/configuration/monitors.md
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
---
|
||||
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.
|
||||
|
||||
> **Note:** that "name" is a regular expression. If you want an exact match, you need to add `^` and `$` to the beginning and end of the expression, for example, `^eDP-1$` matches exactly the string `eDP-1`.
|
||||
|
||||
### 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.
|
||||
76
docs/configuration/xdg-portals.md
Normal file
76
docs/configuration/xdg-portals.md
Normal file
|
|
@ -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.
|
||||
101
docs/faq.md
Normal file
101
docs/faq.md
Normal file
|
|
@ -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
|
||||
```
|
||||
42
docs/index.md
Normal file
42
docs/index.md
Normal file
|
|
@ -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.
|
||||
239
docs/installation.md
Normal file
239
docs/installation.md
Normal file
|
|
@ -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
|
||||
```
|
||||
154
docs/ipc.md
Normal file
154
docs/ipc.md
Normal file
|
|
@ -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 <output>] -s [-t <tags>] [-l <layout>] [-c <tags>] [-d <cmd>,<arg1>,<arg2>,<arg3>,<arg4>,<arg5>]
|
||||
mmsg [-o <output>] (-g | -w) [-OotlcvmfxekbA]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
| Flag | Description |
|
||||
| :--- | :--- |
|
||||
| `-q` | Quit mangowm. |
|
||||
| `-g` | **Get** values (tags, layout, focused client). |
|
||||
| `-s` | **Set** values (switch tags, layouts). |
|
||||
| `-w` | **Watch** mode (streams events). |
|
||||
| `-O` | Get all output (monitor) information. |
|
||||
| `-T` | Get number of tags. |
|
||||
| `-L` | Get all available layouts. |
|
||||
| `-o` | Select output (monitor). |
|
||||
| `-t` | Get/set selected tags (set with `[+-^.]`). |
|
||||
| `-l` | Get/set current layout. |
|
||||
| `-c` | Get title and appid of focused client. |
|
||||
| `-v` | Get visibility of statusbar. |
|
||||
| `-m` | Get fullscreen status. |
|
||||
| `-f` | Get floating status. |
|
||||
| `-d` | **Dispatch** an internal command. |
|
||||
| `-x` | Get focused client geometry. |
|
||||
| `-e` | Get the name of the last focused layer. |
|
||||
| `-k` | Get current keyboard layout. |
|
||||
| `-b` | Get current keybind mode. |
|
||||
| `-A` | Get scale factor of monitor. |
|
||||
|
||||
## Examples
|
||||
|
||||
### Tag Management
|
||||
|
||||
You can perform arithmetic on tags using the `-t` flag with `-s` (set).
|
||||
|
||||
```bash
|
||||
# Switch to Tag 1
|
||||
mmsg -t 1
|
||||
|
||||
# Add Tag 2 to current view (Multiview)
|
||||
mmsg -s -t 2+
|
||||
|
||||
# Remove Tag 2 from current view
|
||||
mmsg -s -t 2-
|
||||
|
||||
# Toggle Tag 2
|
||||
mmsg -s -t 2^
|
||||
```
|
||||
|
||||
### Layouts
|
||||
|
||||
Switch layouts programmatically. Layout codes: `S` (Scroller), `T` (Tile), `G` (Grid), `M` (Monocle), `K` (Deck), `CT` (Center Tile), `RT` (Right Tile), `VS` (Vertical Scroller), `VT` (Vertical Tile), `VG` (Vertical Grid), `VK` (Vertical Deck), `TG` (TGMix).
|
||||
|
||||
```bash
|
||||
# Switch to Scroller
|
||||
mmsg -l "S"
|
||||
|
||||
# Switch to Tile
|
||||
mmsg -l "T"
|
||||
```
|
||||
|
||||
### Dispatching Commands
|
||||
|
||||
Any command available in `config.conf` keybindings can be run via IPC.
|
||||
|
||||
```bash
|
||||
# Close the focused window
|
||||
mmsg -d killclient
|
||||
|
||||
# Resize window by +10 width
|
||||
mmsg -d resizewin,+10,0
|
||||
|
||||
# Toggle fullscreen
|
||||
mmsg -d togglefullscreen
|
||||
|
||||
# Disable a monitor power
|
||||
mmsg -d disable_monitor,eDP-1
|
||||
```
|
||||
|
||||
### Monitoring & Status
|
||||
|
||||
Use `-g` or `-w` to build custom status bars or automation scripts.
|
||||
|
||||
```bash
|
||||
# Watch for all message changes
|
||||
mmsg -w
|
||||
|
||||
# Get all messages without watch
|
||||
mmsg -g
|
||||
|
||||
# Watch focused client appid and title
|
||||
mmsg -w -c
|
||||
|
||||
# Get all available outputs
|
||||
mmsg -O
|
||||
|
||||
# Get all tags message
|
||||
mmsg -g -t
|
||||
|
||||
# Get current focused client message
|
||||
mmsg -g -c
|
||||
|
||||
# Get current keyboard layout
|
||||
mmsg -g -k
|
||||
|
||||
# Get current keybind mode
|
||||
mmsg -g -b
|
||||
|
||||
# Get scale factor of current monitor
|
||||
mmsg -g -A
|
||||
```
|
||||
|
||||
#### Tag Message Format
|
||||
|
||||
- State: 0 → none, 1 → active, 2 → urgent
|
||||
|
||||
Example output:
|
||||
|
||||
| Monitor | Tag Number | Tag State | Clients in Tag | Focused Client |
|
||||
|---------|------------|-----------|----------------|----------------|
|
||||
| eDP-1 | tag 2 | 0 | 1 | 0 |
|
||||
|
||||
| Monitor | occupied tags mask | active tags mask | urgent tags mask |
|
||||
|---------|--------------------|------------------|------------------|
|
||||
| eDP-1 | 14 | 6 | 0 |
|
||||
|
||||
## Virtual Monitors
|
||||
|
||||
You can create headless outputs for screen mirroring or remote desktop access (e.g., Sunshine/Moonlight).
|
||||
|
||||
```bash
|
||||
# Create a virtual output
|
||||
mmsg -d create_virtual_output
|
||||
|
||||
# Configure it (set resolution)
|
||||
wlr-randr --output HEADLESS-1 --pos 1920,0 --mode 1920x1080@60Hz
|
||||
|
||||
# Destroy all virtual outputs
|
||||
mmsg -d destroy_all_virtual_output
|
||||
17
docs/meta.json
Normal file
17
docs/meta.json
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"title": "mangowm",
|
||||
"pages": [
|
||||
"---Getting Started---",
|
||||
"index",
|
||||
"installation",
|
||||
"quick-start",
|
||||
"---Configuration---",
|
||||
"configuration",
|
||||
"visuals",
|
||||
"window-management",
|
||||
"bindings",
|
||||
"---Reference---",
|
||||
"ipc",
|
||||
"faq"
|
||||
]
|
||||
}
|
||||
88
docs/quick-start.md
Normal file
88
docs/quick-start.md
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
---
|
||||
title: Quick Start
|
||||
description: Basic configuration and first steps with mangowm.
|
||||
---
|
||||
|
||||
Now that you have mangowm installed, let's get your environment set up.
|
||||
|
||||
## Initial Setup
|
||||
|
||||
1. **Create Configuration Directory**
|
||||
|
||||
mangowm looks for configuration files in `~/.config/mango/`.
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.config/mango
|
||||
```
|
||||
|
||||
2. **Copy Default Config**
|
||||
|
||||
A default configuration file is provided at `/etc/mango/config.conf`. Copy it to your local directory to start customizing.
|
||||
|
||||
```bash
|
||||
cp /etc/mango/config.conf ~/.config/mango/config.conf
|
||||
```
|
||||
|
||||
3. **Launch mangowm**
|
||||
|
||||
You can now start the compositor from your TTY.
|
||||
|
||||
```bash
|
||||
mango
|
||||
```
|
||||
|
||||
Optional: To specify a custom config file path:
|
||||
|
||||
```bash
|
||||
mango -c /path/to/your/config.conf
|
||||
```
|
||||
|
||||
## Essential Keybindings
|
||||
|
||||
mangowm uses the following keybinds by default:
|
||||
|
||||
| Key Combination | Action |
|
||||
| :--- | :--- |
|
||||
| `Alt` + `Return` | Open Terminal (defaults to `foot`) |
|
||||
| `Alt` + `Space` | Open Launcher (defaults to `rofi`) |
|
||||
| `Alt` + `Q` | Close (Kill) the active window |
|
||||
| `Super` + `M` | Quit mangowm |
|
||||
| `Super` + `F` | Toggle Fullscreen |
|
||||
| `Alt` + `Arrow Keys` | Move focus (Left, Right, Up, Down) |
|
||||
| `Ctrl` + `1-9` | Switch to Tag 1-9 |
|
||||
| `Alt` + `1-9` | Move window to Tag 1-9 |
|
||||
|
||||
> **Warning:** Some default bindings rely on specific tools like `foot` (terminal) and `rofi` (launcher). Ensure you have them installed or update your `config.conf` to use your preferred alternatives.
|
||||
|
||||
## Recommended Tools
|
||||
|
||||
To get a fully functional desktop experience, we recommend installing the following components:
|
||||
|
||||
| Category | Recommended Tools |
|
||||
| :--- | :--- |
|
||||
| Application Launcher | rofi, bemenu, wmenu, fuzzel |
|
||||
| Terminal Emulator | foot, wezterm, alacritty, kitty, ghostty |
|
||||
| Status Bar | waybar, eww, quickshell, ags |
|
||||
| Desktop Shell | Noctalia, DankMaterialShell |
|
||||
| Wallpaper Setup | swww, swaybg |
|
||||
| Notification Daemon | swaync, dunst, mako |
|
||||
| Desktop Portal | xdg-desktop-portal, xdg-desktop-portal-wlr, xdg-desktop-portal-gtk |
|
||||
| Clipboard | wl-clipboard, wl-clip-persist, cliphist |
|
||||
| Gamma Control / Night Light | wlsunset, gammastep |
|
||||
| Miscellaneous | xfce-polkit, wlogout |
|
||||
|
||||
## Example Configuration
|
||||
|
||||
Check out the [example configuration](https://github.com/DreamMaoMao/mango-config) by the creator of mangowm, including complete setups for mangowm, Waybar, Rofi, and more.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/DreamMaoMao/mango-config.git ~/.config/mango
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
Now that you are up and running, dive deeper into customizing mangowm:
|
||||
|
||||
- [Configure Monitors](/docs/configuration/monitors) — Set up resolution, scaling, and multi-monitor layouts.
|
||||
- [Window Rules](/docs/window-management/rules#window-rules) — Define how specific applications should behave.
|
||||
- [Appearance](/docs/visuals/theming) — Customize colors, borders, gaps, and effects.
|
||||
108
docs/visuals/animations.md
Normal file
108
docs/visuals/animations.md
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
---
|
||||
title: Animations
|
||||
description: Configure smooth transitions for windows and layers.
|
||||
---
|
||||
|
||||
## Enabling Animations
|
||||
|
||||
mangowm supports animations for both standard windows and layer shell surfaces (like bars and notifications).
|
||||
|
||||
```ini
|
||||
animations=1
|
||||
layer_animations=1
|
||||
```
|
||||
|
||||
## Animation Types
|
||||
|
||||
You can define different animation styles for opening and closing windows and layer surfaces.
|
||||
|
||||
Available types: `slide`, `zoom`, `fade`, `none`.
|
||||
|
||||
```ini
|
||||
animation_type_open=zoom
|
||||
animation_type_close=slide
|
||||
layer_animation_type_open=slide
|
||||
layer_animation_type_close=slide
|
||||
```
|
||||
|
||||
## Fade Settings
|
||||
|
||||
Control the fade-in and fade-out effects for animations.
|
||||
|
||||
```ini
|
||||
animation_fade_in=1
|
||||
animation_fade_out=1
|
||||
fadein_begin_opacity=0.5
|
||||
fadeout_begin_opacity=0.5
|
||||
```
|
||||
|
||||
- `animation_fade_in` — Enable fade-in effect (0: disable, 1: enable)
|
||||
- `animation_fade_out` — Enable fade-out effect (0: disable, 1: enable)
|
||||
- `fadein_begin_opacity` — Starting opacity for fade-in animations (0.0–1.0)
|
||||
- `fadeout_begin_opacity` — Starting opacity for fade-out animations (0.0–1.0)
|
||||
|
||||
## Zoom Settings
|
||||
|
||||
Adjust the zoom ratios for zoom animations.
|
||||
|
||||
```ini
|
||||
zoom_initial_ratio=0.3
|
||||
zoom_end_ratio=0.8
|
||||
```
|
||||
|
||||
- `zoom_initial_ratio` — Initial zoom ratio
|
||||
- `zoom_end_ratio` — End zoom ratio
|
||||
|
||||
## Durations
|
||||
|
||||
Control the speed of animations (in milliseconds).
|
||||
|
||||
| Setting | Type | Default | Description |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| `animation_duration_move` | integer | `500` | Move animation duration (ms) |
|
||||
| `animation_duration_open` | integer | `400` | Open animation duration (ms) |
|
||||
| `animation_duration_tag` | integer | `300` | Tag animation duration (ms) |
|
||||
| `animation_duration_close` | integer | `300` | Close animation duration (ms) |
|
||||
| `animation_duration_focus` | integer | `0` | Focus change (opacity transition) animation duration (ms) |
|
||||
|
||||
```ini
|
||||
animation_duration_move=500
|
||||
animation_duration_open=400
|
||||
animation_duration_tag=300
|
||||
animation_duration_close=300
|
||||
animation_duration_focus=0
|
||||
```
|
||||
|
||||
## Custom Bezier Curves
|
||||
|
||||
Bezier curves determine the "feel" of an animation (e.g., linear vs. bouncy). The format is `x1,y1,x2,y2`.
|
||||
|
||||
You can visualize and generate curve values using online tools like [cssportal.com](https://www.cssportal.com/css-cubic-bezier-generator/) or [easings.net](https://easings.net).
|
||||
|
||||
| Setting | Type | Default | Description |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| `animation_curve_open` | string | `0.46,1.0,0.29,0.99` | Open animation bezier curve |
|
||||
| `animation_curve_move` | string | `0.46,1.0,0.29,0.99` | Move animation bezier curve |
|
||||
| `animation_curve_tag` | string | `0.46,1.0,0.29,0.99` | Tag animation bezier curve |
|
||||
| `animation_curve_close` | string | `0.46,1.0,0.29,0.99` | Close animation bezier curve |
|
||||
| `animation_curve_focus` | string | `0.46,1.0,0.29,0.99` | Focus change (opacity transition) animation bezier curve |
|
||||
| `animation_curve_opafadein` | string | `0.46,1.0,0.29,0.99` | Open opacity animation bezier curve |
|
||||
| `animation_curve_opafadeout` | string | `0.5,0.5,0.5,0.5` | Close opacity animation bezier curve |
|
||||
|
||||
```ini
|
||||
animation_curve_open=0.46,1.0,0.29,0.99
|
||||
animation_curve_move=0.46,1.0,0.29,0.99
|
||||
animation_curve_tag=0.46,1.0,0.29,0.99
|
||||
animation_curve_close=0.46,1.0,0.29,0.99
|
||||
animation_curve_focus=0.46,1.0,0.29,0.99
|
||||
animation_curve_opafadein=0.46,1.0,0.29,0.99
|
||||
animation_curve_opafadeout=0.5,0.5,0.5,0.5
|
||||
```
|
||||
|
||||
## Tag Animation Direction
|
||||
|
||||
Control the direction of tag switch animations.
|
||||
|
||||
| Setting | Default | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `tag_animation_direction` | `1` | Tag animation direction (1: horizontal, 0: vertical) |
|
||||
82
docs/visuals/effects.md
Normal file
82
docs/visuals/effects.md
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
---
|
||||
title: Window Effects
|
||||
description: Add visual polish with blur, shadows, and opacity.
|
||||
---
|
||||
|
||||
## Blur
|
||||
|
||||
Blur creates a frosted glass effect for transparent windows.
|
||||
|
||||
| Setting | Default | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `blur` | `0` | Enable blur for windows. |
|
||||
| `blur_layer` | `0` | Enable blur for layer surfaces (like bars/docks). |
|
||||
| `blur_optimized` | `1` | Caches the wallpaper and blur background, significantly reducing GPU usage. Disabling it will significantly increase GPU consumption and may cause rendering lag. **Highly recommended.** |
|
||||
| `blur_params_radius` | `5` | The strength (radius) of the blur. |
|
||||
| `blur_params_num_passes` | `1` | Number of passes. Higher = smoother but more expensive. |
|
||||
| `blur_params_noise` | `0.02` | Blur noise level. |
|
||||
| `blur_params_brightness` | `0.9` | Blur brightness adjustment. |
|
||||
| `blur_params_contrast` | `0.9` | Blur contrast adjustment. |
|
||||
| `blur_params_saturation` | `1.2` | Blur saturation adjustment. |
|
||||
|
||||
> **Warning:** Blur has a relatively high impact on performance. If your hardware is limited, it is not recommended to enable it. If you experience lag with blur on, ensure `blur_optimized=1` — disabling it will significantly increase GPU consumption and may cause rendering lag. To disable blur entirely, set `blur=0`.
|
||||
|
||||
---
|
||||
|
||||
## Shadows
|
||||
|
||||
Drop shadows help distinguish floating windows from the background.
|
||||
|
||||
| Setting | Default | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `shadows` | `0` | Enable shadows. |
|
||||
| `layer_shadows` | `0` | Enable shadows for layer surfaces. |
|
||||
| `shadow_only_floating` | `1` | Only draw shadows for floating windows (saves performance). |
|
||||
| `shadows_size` | `10` | Size of the shadow. |
|
||||
| `shadows_blur` | `15` | Shadow blur amount. |
|
||||
| `shadows_position_x` | `0` | Shadow X offset. |
|
||||
| `shadows_position_y` | `0` | Shadow Y offset. |
|
||||
| `shadowscolor` | `0x000000ff` | Color of the shadow. |
|
||||
|
||||
```ini
|
||||
# Example shadows configuration
|
||||
shadows=1
|
||||
layer_shadows=1
|
||||
shadow_only_floating=1
|
||||
shadows_size=12
|
||||
shadows_blur=15
|
||||
shadows_position_x=0
|
||||
shadows_position_y=0
|
||||
shadowscolor=0x000000ff
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Opacity & Corner Radius
|
||||
|
||||
Control the transparency and roundness of your windows.
|
||||
|
||||
| Setting | Default | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `border_radius` | `0` | Window corner radius in pixels. |
|
||||
| `border_radius_location_default` | `0` | Corner radius location: `0` (all), `1` (top-left), `2` (top-right), `3` (bottom-left), `4` (bottom-right), `5` (closest corner). |
|
||||
| `no_radius_when_single` | `0` | Disable radius if only one window is visible. |
|
||||
| `focused_opacity` | `1.0` | Opacity for the active window (0.0 - 1.0). |
|
||||
| `unfocused_opacity` | `1.0` | Opacity for inactive windows (0.0 - 1.0). |
|
||||
|
||||
```ini
|
||||
# Window corner radius in pixels
|
||||
border_radius=0
|
||||
|
||||
# Corner radius location (0=all, 1=top-left, 2=top-right, 3=bottom-left, 4=bottom-right)
|
||||
border_radius_location_default=0
|
||||
|
||||
# Disable radius if only one window is visible
|
||||
no_radius_when_single=0
|
||||
|
||||
# Opacity for the active window (0.0 - 1.0)
|
||||
focused_opacity=1.0
|
||||
|
||||
# Opacity for inactive windows
|
||||
unfocused_opacity=1.0
|
||||
```
|
||||
19
docs/visuals/index.mdx
Normal file
19
docs/visuals/index.mdx
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
title: Visuals
|
||||
description: Customize borders, colors, effects, and animations.
|
||||
icon: Palette
|
||||
---
|
||||
|
||||
Customize the look of your desktop.
|
||||
|
||||
<Cards>
|
||||
|
||||
<Card href="/docs/visuals/theming" title="Theming" description="Borders, colors, and cursor" />
|
||||
|
||||
<Card href="/docs/visuals/status-bar" title="Status Bar" description="Built-in status bar" />
|
||||
|
||||
<Card href="/docs/visuals/effects" title="Effects" description="Blur, shadows, rounded corners" />
|
||||
|
||||
<Card href="/docs/visuals/animations" title="Animations" description="Window and tag animations" />
|
||||
|
||||
</Cards>
|
||||
4
docs/visuals/meta.json
Normal file
4
docs/visuals/meta.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"title": "Visuals",
|
||||
"pages": ["theming", "status-bar", "effects", "animations"]
|
||||
}
|
||||
141
docs/visuals/status-bar.md
Normal file
141
docs/visuals/status-bar.md
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
---
|
||||
title: Status Bar
|
||||
description: Configure Waybar for mangowm.
|
||||
---
|
||||
|
||||
## Module Configuration
|
||||
|
||||
mangowm is compatible with Waybar's `ext/workspaces` module (Wayland standard) or the `dwl/tags` module. We recommend `ext/workspaces` for the best experience.
|
||||
|
||||
> **Tip:** You can also use the `dwl/tags` module, but `ext/workspaces` provides better integration with mangowm's features. The `ext/workspaces` module requires **Waybar > 0.14.0**.
|
||||
|
||||
### `config.jsonc`
|
||||
|
||||
Add the following to your Waybar configuration:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"modules-left": [
|
||||
"ext/workspaces",
|
||||
"dwl/window"
|
||||
],
|
||||
"ext/workspaces": {
|
||||
"format": "{icon}",
|
||||
"ignore-hidden": true,
|
||||
"on-click": "activate",
|
||||
"on-click-right": "deactivate",
|
||||
"sort-by-id": true
|
||||
},
|
||||
"dwl/window": {
|
||||
"format": "[{layout}] {title}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Styling
|
||||
|
||||
You can style the tags using standard CSS in `style.css`.
|
||||
|
||||
### `style.css`
|
||||
|
||||
```css
|
||||
#workspaces {
|
||||
border-radius: 4px;
|
||||
border-width: 2px;
|
||||
border-style: solid;
|
||||
border-color: #c9b890;
|
||||
margin-left: 4px;
|
||||
padding-left: 10px;
|
||||
padding-right: 6px;
|
||||
background: rgba(40, 40, 40, 0.76);
|
||||
}
|
||||
|
||||
#workspaces button {
|
||||
border: none;
|
||||
background: none;
|
||||
box-shadow: inherit;
|
||||
text-shadow: inherit;
|
||||
color: #ddca9e;
|
||||
padding: 1px;
|
||||
padding-left: 1px;
|
||||
padding-right: 1px;
|
||||
margin-right: 2px;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
#workspaces button.hidden {
|
||||
color: #9e906f;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#workspaces button.visible {
|
||||
color: #ddca9e;
|
||||
}
|
||||
|
||||
#workspaces button:hover {
|
||||
color: #d79921;
|
||||
}
|
||||
|
||||
#workspaces button.active {
|
||||
background-color: #ddca9e;
|
||||
color: #282828;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
padding-top: 1px;
|
||||
padding-bottom: 0px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
#workspaces button.urgent {
|
||||
background-color: #ef5e5e;
|
||||
color: #282828;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
padding-top: 1px;
|
||||
padding-bottom: 0px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
#tags {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#tags button {
|
||||
background-color: #fff;
|
||||
color: #a585cd;
|
||||
}
|
||||
|
||||
#tags button:not(.occupied):not(.focused) {
|
||||
font-size: 0;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
margin: -17px;
|
||||
padding: 0;
|
||||
color: transparent;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#tags button.occupied {
|
||||
background-color: #fff;
|
||||
color: #cdc885;
|
||||
}
|
||||
|
||||
#tags button.focused {
|
||||
background-color: rgb(186, 142, 213);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#tags button.urgent {
|
||||
background: rgb(171, 101, 101);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#window {
|
||||
background-color: rgb(237, 196, 147);
|
||||
color: rgb(63, 37, 5);
|
||||
}
|
||||
```
|
||||
|
||||
## Complete Configuration Example
|
||||
|
||||
> **Tip:** You can find a complete Waybar configuration for mangowm at [waybar-config](https://github.com/DreamMaoMao/waybar-config).
|
||||
56
docs/visuals/theming.md
Normal file
56
docs/visuals/theming.md
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
---
|
||||
title: Theming
|
||||
description: Customize the visual appearance of borders, colors, and the cursor.
|
||||
---
|
||||
|
||||
## Dimensions
|
||||
|
||||
Control the sizing of window borders and gaps.
|
||||
|
||||
| Setting | Default | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `borderpx` | `4` | Border width in pixels. |
|
||||
| `gappih` | `5` | Horizontal inner gap (between windows). |
|
||||
| `gappiv` | `5` | Vertical inner gap. |
|
||||
| `gappoh` | `10` | Horizontal outer gap (between windows and screen edges). |
|
||||
| `gappov` | `10` | Vertical outer gap. |
|
||||
|
||||
## Colors
|
||||
|
||||
Colors are defined in `0xRRGGBBAA` hex format.
|
||||
|
||||
```ini
|
||||
# Background color of the root window
|
||||
rootcolor=0x323232ff
|
||||
|
||||
# Inactive window border
|
||||
bordercolor=0x444444ff
|
||||
|
||||
# Active window border
|
||||
focuscolor=0xc66b25ff
|
||||
|
||||
# Urgent window border (alerts)
|
||||
urgentcolor=0xad401fff
|
||||
```
|
||||
|
||||
### State-Specific Colors
|
||||
|
||||
You can also color-code windows based on their state:
|
||||
|
||||
| State | Config Key | Default Color |
|
||||
| :--- | :--- | :--- |
|
||||
| Maximized | `maximizescreencolor` | `0x89aa61ff` |
|
||||
| Scratchpad | `scratchpadcolor` | `0x516c93ff` |
|
||||
| Global | `globalcolor` | `0xb153a7ff` |
|
||||
| Overlay | `overlaycolor` | `0x14a57cff` |
|
||||
|
||||
> **Tip:** For scratchpad window sizing, see [Scratchpad](/docs/window-management/scratchpad) configuration.
|
||||
|
||||
## Cursor Theme
|
||||
|
||||
Set the size and theme of your mouse cursor.
|
||||
|
||||
```ini
|
||||
cursor_size=24
|
||||
cursor_theme=Adwaita
|
||||
```
|
||||
19
docs/window-management/index.mdx
Normal file
19
docs/window-management/index.mdx
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
title: Window Management
|
||||
description: Layouts, rules, and window behavior.
|
||||
icon: LayoutGrid
|
||||
---
|
||||
|
||||
Window management with layouts, rules, and scratchpad support.
|
||||
|
||||
<Cards>
|
||||
|
||||
<Card href="/docs/window-management/layouts" title="Layouts" description="Tile, scroller, monocle, grid, deck" />
|
||||
|
||||
<Card href="/docs/window-management/rules" title="Rules" description="Window rules and conditions" />
|
||||
|
||||
<Card href="/docs/window-management/overview" title="Overview" description="Window states and properties" />
|
||||
|
||||
<Card href="/docs/window-management/scratchpad" title="Scratchpad" description="Quick access to applications" />
|
||||
|
||||
</Cards>
|
||||
99
docs/window-management/layouts.md
Normal file
99
docs/window-management/layouts.md
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
---
|
||||
title: Layouts
|
||||
description: Configure and switch between different window layouts.
|
||||
---
|
||||
|
||||
## Supported Layouts
|
||||
|
||||
mangowm supports a variety of layouts that can be assigned per tag.
|
||||
|
||||
- `tile`
|
||||
- `scroller`
|
||||
- `monocle`
|
||||
- `grid`
|
||||
- `deck`
|
||||
- `center_tile`
|
||||
- `vertical_tile`
|
||||
- `right_tile`
|
||||
- `vertical_scroller`
|
||||
- `vertical_grid`
|
||||
- `vertical_deck`
|
||||
- `tgmix`
|
||||
|
||||
---
|
||||
|
||||
## Scroller Layout
|
||||
|
||||
The Scroller layout positions windows in a scrollable strip, similar to PaperWM.
|
||||
|
||||
### Configuration
|
||||
|
||||
| Setting | Default | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `scroller_structs` | `20` | Width reserved on sides when window ratio is 1. |
|
||||
| `scroller_default_proportion` | `0.9` | Default width proportion for new windows. |
|
||||
| `scroller_focus_center` | `0` | Always center the focused window (1 = enable). |
|
||||
| `scroller_prefer_center` | `0` | Center focused window only if it was outside the view. |
|
||||
| `scroller_prefer_overspread` | `1` | Allow windows to overspread when there's extra space. |
|
||||
| `edge_scroller_pointer_focus` | `1` | Focus windows even if partially off-screen. |
|
||||
| `scroller_proportion_preset` | `0.5,0.8,1.0` | Presets for cycling window widths. |
|
||||
| `scroller_ignore_proportion_single` | `1` | Ignore proportion adjustments for single windows. |
|
||||
| `scroller_default_proportion_single` | `1.0` | Default proportion for single windows in scroller. **Requires `scroller_ignore_proportion_single=0` to take effect.** |
|
||||
|
||||
> **Warning:** `scroller_prefer_overspread`, `scroller_focus_center`, and `scroller_prefer_center` interact with each other. Their priority order is:
|
||||
>
|
||||
> **scroller_prefer_overspread > scroller_focus_center > scroller_prefer_center**
|
||||
>
|
||||
> To ensure a lower-priority setting takes effect, you must set all higher-priority options to `0`.
|
||||
|
||||
```ini
|
||||
# Example scroller configuration
|
||||
scroller_structs=20
|
||||
scroller_default_proportion=0.9
|
||||
scroller_focus_center=0
|
||||
scroller_prefer_center=0
|
||||
scroller_prefer_overspread=1
|
||||
edge_scroller_pointer_focus=1
|
||||
scroller_default_proportion_single=1.0
|
||||
scroller_proportion_preset=0.5,0.8,1.0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Master-Stack Layouts
|
||||
|
||||
These settings apply to layouts like `tile` and `center_tile`.
|
||||
|
||||
| Setting | Default | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `new_is_master` | `1` | New windows become the master window. |
|
||||
| `default_mfact` | `0.55` | The split ratio between master and stack areas. |
|
||||
| `default_nmaster` | `1` | Number of allowed master windows. |
|
||||
| `smartgaps` | `0` | Disable gaps when only one window is present. |
|
||||
| `center_master_overspread` | `0` | (Center Tile) Master spreads across screen if no stack exists. |
|
||||
| `center_when_single_stack` | `1` | (Center Tile) Center master when only one stack window exists. |
|
||||
|
||||
```ini
|
||||
# Example master-stack configuration
|
||||
new_is_master=1
|
||||
smartgaps=0
|
||||
default_mfact=0.55
|
||||
default_nmaster=1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Switching Layouts
|
||||
|
||||
You can switch layouts dynamically or set a default for specific tags using [Tag Rules](/docs/window-management/rules#tag-rules).
|
||||
|
||||
**Keybinding Examples:**
|
||||
|
||||
```ini
|
||||
# Cycle through layouts
|
||||
bind=SUPER,n,switch_layout
|
||||
|
||||
# Set specific layout
|
||||
bind=SUPER,t,setlayout,tile
|
||||
bind=SUPER,s,setlayout,scroller
|
||||
```
|
||||
4
docs/window-management/meta.json
Normal file
4
docs/window-management/meta.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"title": "Window Management",
|
||||
"pages": ["layouts", "rules", "overview", "scratchpad"]
|
||||
}
|
||||
29
docs/window-management/overview.md
Normal file
29
docs/window-management/overview.md
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
title: Overview
|
||||
description: Configure the overview mode for window navigation.
|
||||
---
|
||||
|
||||
## Overview Settings
|
||||
|
||||
| Setting | Type | Default | Description |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| `hotarea_size` | integer | `10` | Hot area size in pixels. |
|
||||
| `enable_hotarea` | integer | `1` | Enable hot areas (0: disable, 1: enable). |
|
||||
| `hotarea_corner` | integer | `2` | Hot area corner (0: top-left, 1: top-right, 2: bottom-left, 3: bottom-right). |
|
||||
| `ov_tab_mode` | integer | `0` | Overview tab mode (0: disable, 1: enable). |
|
||||
| `overviewgappi` | integer | `5` | Inner gap in overview mode. |
|
||||
| `overviewgappo` | integer | `30` | Outer gap in overview mode. |
|
||||
|
||||
### Setting Descriptions
|
||||
|
||||
- `enable_hotarea` — Toggles overview when the cursor enters the configured corner.
|
||||
- `hotarea_size` — Size of the hot area trigger zone in pixels.
|
||||
- `hotarea_corner` — Corner that triggers the hot area (0: top-left, 1: top-right, 2: bottom-left, 3: bottom-right).
|
||||
- `ov_tab_mode` — Circles focus through windows in overview; releasing the mod key exits overview.
|
||||
|
||||
### Mouse Interaction in Overview
|
||||
|
||||
When in overview mode:
|
||||
|
||||
- **Left mouse button** — Jump to (focus) a window.
|
||||
- **Right mouse button** — Close a window.
|
||||
249
docs/window-management/rules.md
Normal file
249
docs/window-management/rules.md
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
---
|
||||
title: Rules
|
||||
description: Define behavior for specific windows, tags, and layers.
|
||||
---
|
||||
|
||||
## Window Rules
|
||||
|
||||
Window rules allow you to set specific properties (floating, opacity, size, animations, etc.) for applications based on their `appid` or `title`. You can set all parameters in one line, and if you both set appid and title, the window will only follow the rules when appid and title both match.
|
||||
|
||||
**Format:**
|
||||
|
||||
```ini
|
||||
windowrule=Parameter:Values,title:Values
|
||||
windowrule=Parameter:Values,Parameter:Values,appid:Values,title:Values
|
||||
```
|
||||
|
||||
### State & Behavior Parameters
|
||||
|
||||
| Parameter | Type | Values | Description |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| `appid` | string | Any | Match by application ID, supports regex |
|
||||
| `title` | string | Any | Match by window title, supports regex |
|
||||
| `isfloating` | integer | `0` / `1` | Force floating state |
|
||||
| `isfullscreen` | integer | `0` / `1` | Force fullscreen state |
|
||||
| `isfakefullscreen` | integer | `0` / `1` | Force fake-fullscreen state (window stays constrained) |
|
||||
| `isglobal` | integer | `0` / `1` | Open as global window (sticky across tags) |
|
||||
| `isoverlay` | integer | `0` / `1` | Make it always in top layer |
|
||||
| `isopensilent` | integer | `0` / `1` | Open without focus |
|
||||
| `istagsilent` | integer | `0` / `1` | Don't focus if client is not in current view tag |
|
||||
| `force_maximize` | integer | `0` / `1` (default 1) | The state of client default to maximized |
|
||||
| `ignore_maximize` | integer | `0` / `1` (default 1) | Don't handle maximize request from client |
|
||||
| `ignore_minimize` | integer | `0` / `1` (default 1) | Don't handle minimize request from client |
|
||||
| `force_tiled_state` | integer | `0` / `1` | Deceive the window into thinking it is tiling, so it better adheres to assigned dimensions |
|
||||
| `noopenmaximized` | integer | `0` / `1` | Window does not open as maximized mode |
|
||||
| `single_scratchpad` | integer | `0` / `1` (default 1) | Only show one out of named scratchpads or the normal scratchpad |
|
||||
| `allow_shortcuts_inhibit` | integer | `0` / `1` (default 1) | Allow shortcuts to be inhibited by clients |
|
||||
| `indleinhibit_when_focus` | integer | `0` / `1` (default 0) | Automatically keep idle inhibit active when this window is focused |
|
||||
|
||||
### Geometry & Position
|
||||
|
||||
| Parameter | Type | Values | Description |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| `width` | integer | 0-9999 | Window width when it becomes a floating window |
|
||||
| `height` | integer | 0-9999 | Window height when it becomes a floating window |
|
||||
| `offsetx` | integer | -999-999 | X offset from center (%), 100 is the edge of screen with outer gap |
|
||||
| `offsety` | integer | -999-999 | Y offset from center (%), 100 is the edge of screen with outer gap |
|
||||
| `monitor` | string | Any | Assign to monitor by [monitor spec](/docs/configuration/monitors#monitor-spec-format) (name, make, model, or serial) |
|
||||
| `tags` | integer | 1-9 | Assign to specific tag |
|
||||
| `no_force_center` | integer | `0` / `1` | Window does not force center |
|
||||
| `isnosizehint` | integer | `0` / `1` | Don't use min size and max size for size hints |
|
||||
|
||||
### Visuals & Decoration
|
||||
|
||||
| Parameter | Type | Values | Description |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| `noblur` | integer | `0` / `1` | Window does not have blur effect |
|
||||
| `isnoborder` | integer | `0` / `1` | Remove window border |
|
||||
| `isnoshadow` | integer | `0` / `1` | Not apply shadow |
|
||||
| `isnoradius` | integer | `0` / `1` | Not apply corner radius |
|
||||
| `isnoanimation` | integer | `0` / `1` | Not apply animation |
|
||||
| `focused_opacity` | integer | `0` / `1` | Window focused opacity |
|
||||
| `unfocused_opacity` | integer | `0` / `1` | Window unfocused opacity |
|
||||
| `allow_csd` | integer | `0` / `1` | Allow client side decoration |
|
||||
|
||||
> **Tip:** For detailed visual effects configuration, see the [Window Effects](/docs/visuals/effects) page for blur, shadows, and opacity settings.
|
||||
|
||||
### Layout & Scroller
|
||||
|
||||
| Parameter | Type | Values | Description |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| `scroller_proportion` | float | 0.1-1.0 | Set scroller proportion |
|
||||
| `scroller_proportion_single` | float | 0.1-1.0 | Set scroller auto adjust proportion when it is single window |
|
||||
|
||||
> **Tip:** For comprehensive layout configuration, see the [Layouts](/docs/window-management/layouts) page for all layout options and detailed settings.
|
||||
|
||||
### Animation
|
||||
|
||||
| Parameter | Type | Values | Description |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| `animation_type_open` | string | zoom, slide, fade, none | Set open animation |
|
||||
| `animation_type_close` | string | zoom, slide, fade, none | Set close animation |
|
||||
| `nofadein` | integer | `0` / `1` | Window ignores fade-in animation |
|
||||
| `nofadeout` | integer | `0` / `1` | Window ignores fade-out animation |
|
||||
|
||||
> **Tip:** For detailed animation configuration, see the [Animations](/docs/visuals/animations) page for available types and settings.
|
||||
|
||||
### Terminal & Swallowing
|
||||
|
||||
| Parameter | Type | Values | Description |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| `isterm` | integer | `0` / `1` | A new GUI window will replace the isterm window when it is opened |
|
||||
| `noswallow` | integer | `0` / `1` | The window will not replace the isterm window |
|
||||
|
||||
### Global & Special Windows
|
||||
|
||||
| Parameter | Type | Values | Description |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| `globalkeybinding` | string | `[mod combination][-][key]` | Global keybinding (only works for Wayland apps) |
|
||||
| `isunglobal` | integer | `0` / `1` | Open as unmanaged global window (for desktop pets or camera windows) |
|
||||
| `isnamedscratchpad` | integer | `0` / `1` | 0: disable, 1: named scratchpad |
|
||||
|
||||
> **Tip:** For scratchpad usage, see the [Scratchpad](/docs/window-management/scratchpad) page for detailed configuration examples.
|
||||
|
||||
### Performance & Tearing
|
||||
|
||||
| Parameter | Type | Values | Description |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| `force_tearing` | integer | `0` / `1` | Set window to tearing state, refer to [Tearing](/docs/configuration/monitors#tearing-game-mode) |
|
||||
|
||||
### Examples
|
||||
|
||||
```ini
|
||||
# Set specific window size and position
|
||||
windowrule=width:1000,height:900,appid:yesplaymusic,title:Demons
|
||||
|
||||
# Global keybindings for OBS Studio
|
||||
windowrule=globalkeybinding:ctrl+alt-o,appid:com.obsproject.Studio
|
||||
windowrule=globalkeybinding:ctrl+alt+n,appid:com.obsproject.Studio
|
||||
windowrule=isopensilent:1,appid:com.obsproject.Studio
|
||||
|
||||
# Force tearing for games
|
||||
windowrule=force_tearing:1,title:vkcube
|
||||
windowrule=force_tearing:1,title:Counter-Strike 2
|
||||
|
||||
# Named scratchpad for file manager
|
||||
windowrule=isnamedscratchpad:1,width:1280,height:800,appid:st-yazi
|
||||
|
||||
# Custom opacity for specific apps
|
||||
windowrule=focused_opacity:0.8,appid:firefox
|
||||
windowrule=unfocused_opacity:0.6,appid:foot
|
||||
|
||||
# Disable blur for selection tools
|
||||
windowrule=noblur:1,appid:slurp
|
||||
|
||||
# Position windows relative to screen center
|
||||
windowrule=offsetx:20,offsety:-30,width:800,height:600,appid:alacritty
|
||||
|
||||
# Send to specific tag and monitor
|
||||
windowrule=tags:9,monitor:HDMI-A-1,appid:discord
|
||||
|
||||
# Terminal swallowing setup
|
||||
windowrule=isterm:1,appid:st
|
||||
windowrule=noswallow:1,appid:foot
|
||||
|
||||
# Disable client-side decorations
|
||||
windowrule=allow_csd:1,appid:firefox
|
||||
|
||||
# Unmanaged global window (desktop pets, camera)
|
||||
windowrule=isunglobal:1,appid:cheese
|
||||
|
||||
# Named scratchpad toggle
|
||||
bind=alt,h,toggle_named_scratchpad,st-yazi,none,st -c st-yazi -e yazi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tag Rules
|
||||
|
||||
You can set all parameters in one line. If only `id` is set, the rule is followed when the id matches. If any of `monitor_name`, `monitor_make`, `monitor_model`, or `monitor_serial` are set, the rule is followed only if **all** of the set monitor fields match.
|
||||
|
||||
> **Warning:** Layouts set in tag rules have a higher priority than monitor rule layouts.
|
||||
|
||||
**Format:**
|
||||
|
||||
```ini
|
||||
tagrule=id:Values,Parameter:Values,Parameter:Values
|
||||
tagrule=id:Values,monitor_name:eDP-1,Parameter:Values,Parameter:Values
|
||||
tagrule=id:Values,monitor_make:xxx,monitor_model:xxx,Parameter:Values
|
||||
```
|
||||
|
||||
> **Tip:** See [Layouts](/docs/window-management/layouts#supported-layouts) for detailed descriptions of each layout type.
|
||||
|
||||
| Parameter | Type | Values | Description |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| `id` | integer | 0-9 | Match by tag id, 0 means the ~0 tag |
|
||||
| `monitor_name` | string | monitor name | Match by monitor name |
|
||||
| `monitor_make` | string | monitor make | Match by monitor manufacturer |
|
||||
| `monitor_model` | string | monitor model | Match by monitor model |
|
||||
| `monitor_serial` | string | monitor serial | Match by monitor serial number |
|
||||
| `layout_name` | string | layout name | Layout name to set |
|
||||
| `no_render_border` | integer | `0` / `1` | Disable render border |
|
||||
| `no_hide` | integer | `0` / `1` | Not hide even if the tag is empty |
|
||||
| `nmaster` | integer | 0, 99 | Number of master windows |
|
||||
| `mfact` | float | 0.1–0.9 | Master area factor |
|
||||
|
||||
### Examples
|
||||
|
||||
```ini
|
||||
# Set layout for specific tags
|
||||
tagrule=id:1,layout_name:scroller
|
||||
tagrule=id:2,layout_name:scroller
|
||||
|
||||
# Limit to specific monitor
|
||||
tagrule=id:1,monitor_name:eDP-1,layout_name:scroller
|
||||
tagrule=id:2,monitor_name:eDP-1,layout_name:scroller
|
||||
|
||||
# Persistent tags (1-4) with layout assignment
|
||||
tagrule=id:1,no_hide:1,layout_name:scroller
|
||||
tagrule=id:2,no_hide:1,layout_name:scroller
|
||||
tagrule=id:3,monitor_name:eDP-1,no_hide:1,layout_name:scroller
|
||||
tagrule=id:4,monitor_name:eDP-1,no_hide:1,layout_name:scroller
|
||||
|
||||
# Advanced tag configuration with master layout settings
|
||||
tagrule=id:5,layout_name:tile,nmaster:2,mfact:0.6
|
||||
tagrule=id:6,monitor_name:HDMI-A-1,layout_name:monocle,no_render_border:1
|
||||
```
|
||||
|
||||
> **Tip:** For Waybar configuration with persistent tags, see [Status Bar](/docs/visuals/status-bar) documentation.
|
||||
|
||||
---
|
||||
|
||||
## Layer Rules
|
||||
|
||||
You can set all parameters in one line. Target "layer shell" surfaces like status bars (`waybar`), launchers (`rofi`), or notification daemons.
|
||||
|
||||
**Format:**
|
||||
|
||||
```ini
|
||||
layerrule=layer_name:Values,Parameter:Values,Parameter:Values
|
||||
```
|
||||
|
||||
> **Tip:** You can use `mmsg -e` to get the last open layer name for debugging.
|
||||
|
||||
| Parameter | Type | Values | Description |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| `layer_name` | string | layer name | Match name of layer, supports regex |
|
||||
| `animation_type_open` | string | slide, zoom, fade, none | Set open animation |
|
||||
| `animation_type_close` | string | slide, zoom, fade, none | Set close animation |
|
||||
| `noblur` | integer | `0` / `1` | Disable blur |
|
||||
| `noanim` | integer | `0` / `1` | Disable layer animation |
|
||||
| `noshadow` | integer | `0` / `1` | Disable layer shadow |
|
||||
|
||||
> **Tip:** For animation types, see [Animations](/docs/visuals/animations#animation-types). For visual effects, see [Window Effects](/docs/visuals/effects).
|
||||
|
||||
### Examples
|
||||
|
||||
```ini
|
||||
# No blur or animation for slurp selection layer (avoids occlusion and ghosting in screenshots)
|
||||
layerrule=noanim:1,noblur:1,layer_name:selection
|
||||
|
||||
# Zoom animation for Rofi with multiple parameters
|
||||
layerrule=animation_type_open:zoom,noanim:0,layer_name:rofi
|
||||
|
||||
# Disable animations and shadows for notification daemon
|
||||
layerrule=noanim:1,noshadow:1,layer_name:swaync
|
||||
|
||||
# Multiple effects for launcher
|
||||
layerrule=animation_type_open:slide,animation_type_close:fade,noblur:1,layer_name:wofi
|
||||
```
|
||||
73
docs/window-management/scratchpad.md
Normal file
73
docs/window-management/scratchpad.md
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
---
|
||||
title: Scratchpad
|
||||
description: Manage hidden "scratchpad" windows for quick access.
|
||||
---
|
||||
|
||||
mangowm supports two types of scratchpads: the standard pool (Sway-like) and named scratchpads.
|
||||
|
||||
## Standard Scratchpad
|
||||
|
||||
Any window can be sent to the "scratchpad" pile, which hides it. You can then cycle through them.
|
||||
|
||||
**Keybindings:**
|
||||
|
||||
```ini
|
||||
# Send current window to scratchpad
|
||||
bind=SUPER,i,minimized
|
||||
|
||||
# Toggle (show/hide) the scratchpad
|
||||
bind=ALT,z,toggle_scratchpad
|
||||
|
||||
# Retrieve window from scratchpad (restore)
|
||||
bind=SUPER+SHIFT,i,restore_minimized
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Named Scratchpad
|
||||
|
||||
Named scratchpads are bound to specific keys and applications. When triggered, mangowm will either launch the app (if not running) or toggle its visibility.
|
||||
|
||||
**1. Define the Window Rule**
|
||||
|
||||
You must identify the app using a unique `appid` or `title` and mark it as a named scratchpad. The application must support setting a custom appid or title at launch. Common examples:
|
||||
|
||||
- `st -c my-appid` — sets the appid
|
||||
- `kitty -T my-title` — sets the window title
|
||||
- `foot --app-id my-appid` — sets the appid
|
||||
|
||||
Use `none` as a placeholder when you only want to match by one field.
|
||||
|
||||
```ini
|
||||
# Match by appid
|
||||
windowrule=isnamedscratchpad:1,width:1280,height:800,appid:st-yazi
|
||||
|
||||
# Match by title
|
||||
windowrule=isnamedscratchpad:1,width:1000,height:700,title:kitty-scratch
|
||||
```
|
||||
|
||||
**2. Bind the Toggle Key**
|
||||
|
||||
Format: `bind=MOD,KEY,toggle_named_scratchpad,appid,title,command`
|
||||
|
||||
Use `none` for whichever field you are not matching on.
|
||||
|
||||
```ini
|
||||
# Match by appid: launch 'st' with class 'st-yazi' running 'yazi'
|
||||
bind=alt,h,toggle_named_scratchpad,st-yazi,none,st -c st-yazi -e yazi
|
||||
|
||||
# Match by title: launch 'kitty' with window title 'kitty-scratch'
|
||||
bind=alt,k,toggle_named_scratchpad,none,kitty-scratch,kitty -T kitty-scratch
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Appearance
|
||||
|
||||
You can customize the size of scratchpad windows relative to the screen.
|
||||
|
||||
```ini
|
||||
scratchpad_width_ratio=0.8
|
||||
scratchpad_height_ratio=0.9
|
||||
scratchpadcolor=0x516c93ff
|
||||
```
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
project('mango', ['c', 'cpp'],
|
||||
version : '0.12.6',
|
||||
version : '0.12.7',
|
||||
)
|
||||
|
||||
subdir('protocols')
|
||||
|
|
|
|||
|
|
@ -10,20 +10,21 @@ void set_rect_size(struct wlr_scene_rect *rect, int32_t width, int32_t height) {
|
|||
|
||||
enum corner_location set_client_corner_location(Client *c) {
|
||||
enum corner_location current_corner_location = CORNER_LOCATION_ALL;
|
||||
struct wlr_box target_geom = animations ? c->animation.current : c->geom;
|
||||
if (target_geom.x + border_radius <= c->mon->m.x) {
|
||||
current_corner_location &= ~CORNER_LOCATION_LEFT; // 清除左标志位
|
||||
struct wlr_box target_geom =
|
||||
config.animations ? c->animation.current : c->geom;
|
||||
if (target_geom.x + config.border_radius <= c->mon->m.x) {
|
||||
current_corner_location &= ~CORNER_LOCATION_LEFT;
|
||||
}
|
||||
if (target_geom.x + target_geom.width - border_radius >=
|
||||
if (target_geom.x + target_geom.width - config.border_radius >=
|
||||
c->mon->m.x + c->mon->m.width) {
|
||||
current_corner_location &= ~CORNER_LOCATION_RIGHT; // 清除右标志位
|
||||
current_corner_location &= ~CORNER_LOCATION_RIGHT;
|
||||
}
|
||||
if (target_geom.y + border_radius <= c->mon->m.y) {
|
||||
current_corner_location &= ~CORNER_LOCATION_TOP; // 清除上标志位
|
||||
if (target_geom.y + config.border_radius <= c->mon->m.y) {
|
||||
current_corner_location &= ~CORNER_LOCATION_TOP;
|
||||
}
|
||||
if (target_geom.y + target_geom.height - border_radius >=
|
||||
if (target_geom.y + target_geom.height - config.border_radius >=
|
||||
c->mon->m.y + c->mon->m.height) {
|
||||
current_corner_location &= ~CORNER_LOCATION_BOTTOM; // 清除下标志位
|
||||
current_corner_location &= ~CORNER_LOCATION_BOTTOM;
|
||||
}
|
||||
return current_corner_location;
|
||||
}
|
||||
|
|
@ -54,15 +55,16 @@ int32_t is_special_animation_rule(Client *c) {
|
|||
} else if (c->mon->visible_tiling_clients == 1 && !c->isfloating) {
|
||||
return DOWN;
|
||||
} else if (c->mon->visible_tiling_clients == 2 && !c->isfloating &&
|
||||
!new_is_master && is_horizontal_stack_layout(c->mon)) {
|
||||
!config.new_is_master && is_horizontal_stack_layout(c->mon)) {
|
||||
return RIGHT;
|
||||
} else if (!c->isfloating && new_is_master &&
|
||||
} else if (!c->isfloating && config.new_is_master &&
|
||||
is_horizontal_stack_layout(c->mon)) {
|
||||
return LEFT;
|
||||
} else if (c->mon->visible_tiling_clients == 2 && !c->isfloating &&
|
||||
!new_is_master && is_horizontal_right_stack_layout(c->mon)) {
|
||||
!config.new_is_master &&
|
||||
is_horizontal_right_stack_layout(c->mon)) {
|
||||
return LEFT;
|
||||
} else if (!c->isfloating && new_is_master &&
|
||||
} else if (!c->isfloating && config.new_is_master &&
|
||||
is_horizontal_right_stack_layout(c->mon)) {
|
||||
return RIGHT;
|
||||
} else {
|
||||
|
|
@ -77,7 +79,8 @@ void set_client_open_animation(Client *c, struct wlr_box geo) {
|
|||
int32_t special_direction;
|
||||
int32_t center_x, center_y;
|
||||
|
||||
if ((!c->animation_type_open && strcmp(animation_type_open, "fade") == 0) ||
|
||||
if ((!c->animation_type_open &&
|
||||
strcmp(config.animation_type_open, "fade") == 0) ||
|
||||
(c->animation_type_open &&
|
||||
strcmp(c->animation_type_open, "fade") == 0)) {
|
||||
c->animainit_geom.width = geo.width;
|
||||
|
|
@ -86,11 +89,11 @@ void set_client_open_animation(Client *c, struct wlr_box geo) {
|
|||
c->animainit_geom.y = geo.y;
|
||||
return;
|
||||
} else if ((!c->animation_type_open &&
|
||||
strcmp(animation_type_open, "zoom") == 0) ||
|
||||
strcmp(config.animation_type_open, "zoom") == 0) ||
|
||||
(c->animation_type_open &&
|
||||
strcmp(c->animation_type_open, "zoom") == 0)) {
|
||||
c->animainit_geom.width = geo.width * zoom_initial_ratio;
|
||||
c->animainit_geom.height = geo.height * zoom_initial_ratio;
|
||||
c->animainit_geom.width = geo.width * config.zoom_initial_ratio;
|
||||
c->animainit_geom.height = geo.height * config.zoom_initial_ratio;
|
||||
c->animainit_geom.x = geo.x + (geo.width - c->animainit_geom.width) / 2;
|
||||
c->animainit_geom.y =
|
||||
geo.y + (geo.height - c->animainit_geom.height) / 2;
|
||||
|
|
@ -223,7 +226,7 @@ void scene_buffer_apply_effect(struct wlr_scene_buffer *buffer, int32_t sx,
|
|||
if (wlr_xdg_popup_try_from_wlr_surface(surface) != NULL)
|
||||
return;
|
||||
|
||||
wlr_scene_buffer_set_corner_radius(buffer, border_radius,
|
||||
wlr_scene_buffer_set_corner_radius(buffer, config.border_radius,
|
||||
buffer_data->corner_location);
|
||||
}
|
||||
|
||||
|
|
@ -241,7 +244,7 @@ void buffer_set_effect(Client *c, BufferData data) {
|
|||
data.should_scale = false;
|
||||
|
||||
if (c->isnoradius || c->isfullscreen ||
|
||||
(no_radius_when_single && c->mon &&
|
||||
(config.no_radius_when_single && c->mon &&
|
||||
c->mon->visible_tiling_clients == 1)) {
|
||||
data.corner_location = CORNER_LOCATION_NONE;
|
||||
}
|
||||
|
|
@ -255,7 +258,7 @@ void client_draw_shadow(Client *c) {
|
|||
if (c->iskilling || !client_surface(c)->mapped || c->isnoshadow)
|
||||
return;
|
||||
|
||||
if (!shadows || (!c->isfloating && shadow_only_floating)) {
|
||||
if (!config.shadows || (!c->isfloating && config.shadow_only_floating)) {
|
||||
if (c->shadow->node.enabled)
|
||||
wlr_scene_node_set_enabled(&c->shadow->node, false);
|
||||
return;
|
||||
|
|
@ -266,7 +269,7 @@ void client_draw_shadow(Client *c) {
|
|||
|
||||
bool hit_no_border = check_hit_no_border(c);
|
||||
enum corner_location current_corner_location =
|
||||
c->isfullscreen || (no_radius_when_single && c->mon &&
|
||||
c->isfullscreen || (config.no_radius_when_single && c->mon &&
|
||||
c->mon->visible_tiling_clients == 1)
|
||||
? CORNER_LOCATION_NONE
|
||||
: CORNER_LOCATION_ALL;
|
||||
|
|
@ -276,9 +279,8 @@ void client_draw_shadow(Client *c) {
|
|||
int32_t width, height;
|
||||
client_actual_size(c, &width, &height);
|
||||
|
||||
int32_t delta = shadows_size + (int32_t)c->bw - bwoffset;
|
||||
int32_t delta = config.shadows_size + (int32_t)c->bw - bwoffset;
|
||||
|
||||
/* we calculate where to clip the shadow */
|
||||
struct wlr_box client_box = {
|
||||
.x = bwoffset,
|
||||
.y = bwoffset,
|
||||
|
|
@ -287,22 +289,20 @@ void client_draw_shadow(Client *c) {
|
|||
};
|
||||
|
||||
struct wlr_box shadow_box = {
|
||||
.x = shadows_position_x + bwoffset,
|
||||
.y = shadows_position_y + bwoffset,
|
||||
.x = config.shadows_position_x + bwoffset,
|
||||
.y = config.shadows_position_y + bwoffset,
|
||||
.width = width + 2 * delta,
|
||||
.height = height + 2 * delta,
|
||||
};
|
||||
|
||||
struct wlr_box intersection_box;
|
||||
wlr_box_intersection(&intersection_box, &client_box, &shadow_box);
|
||||
/* clipped region takes shadow relative coords, so we translate everything
|
||||
* by its position */
|
||||
intersection_box.x -= shadows_position_x + bwoffset;
|
||||
intersection_box.y -= shadows_position_y + bwoffset;
|
||||
intersection_box.x -= config.shadows_position_x + bwoffset;
|
||||
intersection_box.y -= config.shadows_position_y + bwoffset;
|
||||
|
||||
struct clipped_region clipped_region = {
|
||||
.area = intersection_box,
|
||||
.corner_radius = border_radius,
|
||||
.corner_radius = config.border_radius,
|
||||
.corners = current_corner_location,
|
||||
};
|
||||
|
||||
|
|
@ -356,23 +356,23 @@ void apply_border(Client *c) {
|
|||
|
||||
bool hit_no_border = check_hit_no_border(c);
|
||||
enum corner_location current_corner_location;
|
||||
if (c->isfullscreen || (no_radius_when_single && c->mon &&
|
||||
if (c->isfullscreen || (config.no_radius_when_single && c->mon &&
|
||||
c->mon->visible_tiling_clients == 1)) {
|
||||
current_corner_location = CORNER_LOCATION_NONE;
|
||||
} else {
|
||||
current_corner_location = set_client_corner_location(c);
|
||||
}
|
||||
|
||||
if (hit_no_border && smartgaps) {
|
||||
if (hit_no_border && config.smartgaps) {
|
||||
c->bw = 0;
|
||||
c->fake_no_border = true;
|
||||
} else if (hit_no_border && !smartgaps) {
|
||||
} else if (hit_no_border && !config.smartgaps) {
|
||||
wlr_scene_rect_set_size(c->border, 0, 0);
|
||||
wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw);
|
||||
c->fake_no_border = true;
|
||||
return;
|
||||
} else if (!c->isfullscreen && VISIBLEON(c, c->mon)) {
|
||||
c->bw = c->isnoborder ? 0 : borderpx;
|
||||
c->bw = c->isnoborder ? 0 : config.borderpx;
|
||||
c->fake_no_border = false;
|
||||
}
|
||||
|
||||
|
|
@ -434,14 +434,14 @@ void apply_border(Client *c) {
|
|||
struct clipped_region clipped_region = {
|
||||
.area = {inner_surface_x, inner_surface_y, inner_surface_width,
|
||||
inner_surface_height},
|
||||
.corner_radius = border_radius,
|
||||
.corner_radius = config.border_radius,
|
||||
.corners = current_corner_location,
|
||||
};
|
||||
|
||||
wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw);
|
||||
wlr_scene_rect_set_size(c->border, rect_width, rect_height);
|
||||
wlr_scene_node_set_position(&c->border->node, rect_x, rect_y);
|
||||
wlr_scene_rect_set_corner_radius(c->border, border_radius,
|
||||
wlr_scene_rect_set_corner_radius(c->border, config.border_radius,
|
||||
current_corner_location);
|
||||
wlr_scene_rect_set_clipped_region(c->border, clipped_region);
|
||||
}
|
||||
|
|
@ -523,7 +523,7 @@ void client_apply_clip(Client *c, float factor) {
|
|||
enum corner_location current_corner_location =
|
||||
set_client_corner_location(c);
|
||||
|
||||
if (!animations) {
|
||||
if (!config.animations) {
|
||||
c->animation.running = false;
|
||||
c->need_output_flush = false;
|
||||
c->animainit_geom = c->current = c->pending = c->animation.current =
|
||||
|
|
@ -655,19 +655,19 @@ void fadeout_client_animation_next_tick(Client *c) {
|
|||
double opacity_eased_progress =
|
||||
find_animation_curve_at(animation_passed, OPAFADEOUT);
|
||||
|
||||
double percent = fadeout_begin_opacity -
|
||||
(opacity_eased_progress * fadeout_begin_opacity);
|
||||
double percent = config.fadeout_begin_opacity -
|
||||
(opacity_eased_progress * config.fadeout_begin_opacity);
|
||||
|
||||
double opacity = MAX(percent, 0);
|
||||
|
||||
if (animation_fade_out && !c->nofadeout)
|
||||
if (config.animation_fade_out && !c->nofadeout)
|
||||
wlr_scene_node_for_each_buffer(&c->scene->node,
|
||||
scene_buffer_apply_opacity, &opacity);
|
||||
|
||||
if ((c->animation_type_close &&
|
||||
strcmp(c->animation_type_close, "zoom") == 0) ||
|
||||
(!c->animation_type_close &&
|
||||
strcmp(animation_type_close, "zoom") == 0)) {
|
||||
strcmp(config.animation_type_close, "zoom") == 0)) {
|
||||
|
||||
buffer_data.width = width;
|
||||
buffer_data.height = height;
|
||||
|
|
@ -768,14 +768,14 @@ void init_fadeout_client(Client *c) {
|
|||
if ((c->animation_type_close &&
|
||||
strcmp(c->animation_type_close, "none") == 0) ||
|
||||
(!c->animation_type_close &&
|
||||
strcmp(animation_type_close, "none") == 0)) {
|
||||
strcmp(config.animation_type_close, "none") == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Client *fadeout_client = ecalloc(1, sizeof(*fadeout_client));
|
||||
|
||||
wlr_scene_node_set_enabled(&c->scene->node, true);
|
||||
client_set_border_color(c, bordercolor);
|
||||
client_set_border_color(c, config.bordercolor);
|
||||
fadeout_client->scene =
|
||||
wlr_scene_tree_snapshot(&c->scene->node, layers[LyrFadeOut]);
|
||||
wlr_scene_node_set_enabled(&c->scene->node, false);
|
||||
|
|
@ -785,7 +785,7 @@ void init_fadeout_client(Client *c) {
|
|||
return;
|
||||
}
|
||||
|
||||
fadeout_client->animation.duration = animation_duration_close;
|
||||
fadeout_client->animation.duration = config.animation_duration_close;
|
||||
fadeout_client->geom = fadeout_client->current =
|
||||
fadeout_client->animainit_geom = fadeout_client->animation.initial =
|
||||
c->animation.current;
|
||||
|
|
@ -802,7 +802,7 @@ void init_fadeout_client(Client *c) {
|
|||
fadeout_client->animation.initial.y = 0;
|
||||
|
||||
if ((!c->animation_type_close &&
|
||||
strcmp(animation_type_close, "fade") == 0) ||
|
||||
strcmp(config.animation_type_close, "fade") == 0) ||
|
||||
(c->animation_type_close &&
|
||||
strcmp(c->animation_type_close, "fade") == 0)) {
|
||||
fadeout_client->current.x = 0;
|
||||
|
|
@ -812,7 +812,7 @@ void init_fadeout_client(Client *c) {
|
|||
} else if ((c->animation_type_close &&
|
||||
strcmp(c->animation_type_close, "slide") == 0) ||
|
||||
(!c->animation_type_close &&
|
||||
strcmp(animation_type_close, "slide") == 0)) {
|
||||
strcmp(config.animation_type_close, "slide") == 0)) {
|
||||
fadeout_client->current.y =
|
||||
c->geom.y + c->geom.height / 2 > c->mon->m.y + c->mon->m.height / 2
|
||||
? c->mon->m.height -
|
||||
|
|
@ -822,16 +822,16 @@ void init_fadeout_client(Client *c) {
|
|||
} else {
|
||||
fadeout_client->current.y =
|
||||
(fadeout_client->geom.height -
|
||||
fadeout_client->geom.height * zoom_end_ratio) /
|
||||
fadeout_client->geom.height * config.zoom_end_ratio) /
|
||||
2;
|
||||
fadeout_client->current.x =
|
||||
(fadeout_client->geom.width -
|
||||
fadeout_client->geom.width * zoom_end_ratio) /
|
||||
fadeout_client->geom.width * config.zoom_end_ratio) /
|
||||
2;
|
||||
fadeout_client->current.width =
|
||||
fadeout_client->geom.width * zoom_end_ratio;
|
||||
fadeout_client->geom.width * config.zoom_end_ratio;
|
||||
fadeout_client->current.height =
|
||||
fadeout_client->geom.height * zoom_end_ratio;
|
||||
fadeout_client->geom.height * config.zoom_end_ratio;
|
||||
}
|
||||
|
||||
fadeout_client->animation.time_started = get_now_in_ms();
|
||||
|
|
@ -866,12 +866,11 @@ void client_set_pending_state(Client *c) {
|
|||
if (!c || c->iskilling)
|
||||
return;
|
||||
|
||||
// 判断是否需要动画
|
||||
if (!animations) {
|
||||
if (!config.animations) {
|
||||
c->animation.should_animate = false;
|
||||
} else if (animations && c->animation.tagining) {
|
||||
} else if (config.animations && c->animation.tagining) {
|
||||
c->animation.should_animate = true;
|
||||
} else if (!animations || c == grabc ||
|
||||
} else if (!config.animations || c == grabc ||
|
||||
(!c->is_pending_open_animation &&
|
||||
wlr_box_equal(&c->current, &c->pending))) {
|
||||
c->animation.should_animate = false;
|
||||
|
|
@ -882,7 +881,7 @@ void client_set_pending_state(Client *c) {
|
|||
if (((c->animation_type_open &&
|
||||
strcmp(c->animation_type_open, "none") == 0) ||
|
||||
(!c->animation_type_open &&
|
||||
strcmp(animation_type_open, "none") == 0)) &&
|
||||
strcmp(config.animation_type_open, "none") == 0)) &&
|
||||
c->animation.action == OPEN) {
|
||||
c->animation.duration = 0;
|
||||
}
|
||||
|
|
@ -951,16 +950,16 @@ void resize(Client *c, struct wlr_box geo, int32_t interact) {
|
|||
!c->animation.tagouting && wlr_box_equal(&c->geom, &c->current)) {
|
||||
c->animation.action = c->animation.action;
|
||||
} else if (c->animation.tagouting) {
|
||||
c->animation.duration = animation_duration_tag;
|
||||
c->animation.duration = config.animation_duration_tag;
|
||||
c->animation.action = TAG;
|
||||
} else if (c->animation.tagining) {
|
||||
c->animation.duration = animation_duration_tag;
|
||||
c->animation.duration = config.animation_duration_tag;
|
||||
c->animation.action = TAG;
|
||||
} else if (c->is_pending_open_animation) {
|
||||
c->animation.duration = animation_duration_open;
|
||||
c->animation.duration = config.animation_duration_open;
|
||||
c->animation.action = OPEN;
|
||||
} else {
|
||||
c->animation.duration = animation_duration_move;
|
||||
c->animation.duration = config.animation_duration_move;
|
||||
c->animation.action = MOVE;
|
||||
}
|
||||
|
||||
|
|
@ -981,7 +980,7 @@ void resize(Client *c, struct wlr_box geo, int32_t interact) {
|
|||
}
|
||||
|
||||
bool hit_no_border = check_hit_no_border(c);
|
||||
if (hit_no_border && smartgaps) {
|
||||
if (hit_no_border && config.smartgaps) {
|
||||
c->bw = 0;
|
||||
c->fake_no_border = true;
|
||||
}
|
||||
|
|
@ -1048,12 +1047,12 @@ bool client_draw_fadeout_frame(Client *c) {
|
|||
void client_set_focused_opacity_animation(Client *c) {
|
||||
float *border_color = get_border_color(c);
|
||||
|
||||
if (!animations) {
|
||||
if (!config.animations) {
|
||||
setborder_color(c);
|
||||
return;
|
||||
}
|
||||
|
||||
c->opacity_animation.duration = animation_duration_focus;
|
||||
c->opacity_animation.duration = config.animation_duration_focus;
|
||||
memcpy(c->opacity_animation.target_border_color, border_color,
|
||||
sizeof(c->opacity_animation.target_border_color));
|
||||
c->opacity_animation.target_opacity = c->focused_opacity;
|
||||
|
|
@ -1067,15 +1066,14 @@ void client_set_focused_opacity_animation(Client *c) {
|
|||
}
|
||||
|
||||
void client_set_unfocused_opacity_animation(Client *c) {
|
||||
// Start border color animation to unfocused
|
||||
float *border_color = get_border_color(c);
|
||||
|
||||
if (!animations) {
|
||||
if (!config.animations) {
|
||||
setborder_color(c);
|
||||
return;
|
||||
}
|
||||
|
||||
c->opacity_animation.duration = animation_duration_focus;
|
||||
c->opacity_animation.duration = config.animation_duration_focus;
|
||||
memcpy(c->opacity_animation.target_border_color, border_color,
|
||||
sizeof(c->opacity_animation.target_border_color));
|
||||
// Start opacity animation to unfocused
|
||||
|
|
@ -1110,13 +1108,14 @@ bool client_apply_focus_opacity(Client *c) {
|
|||
double opacity_eased_progress =
|
||||
find_animation_curve_at(linear_progress, OPAFADEIN);
|
||||
|
||||
float percent =
|
||||
animation_fade_in && !c->nofadein ? opacity_eased_progress : 1.0;
|
||||
float percent = config.animation_fade_in && !c->nofadein
|
||||
? opacity_eased_progress
|
||||
: 1.0;
|
||||
float opacity =
|
||||
c == selmon->sel ? c->focused_opacity : c->unfocused_opacity;
|
||||
|
||||
float target_opacity =
|
||||
percent * (1.0 - fadein_begin_opacity) + fadein_begin_opacity;
|
||||
float target_opacity = percent * (1.0 - config.fadein_begin_opacity) +
|
||||
config.fadein_begin_opacity;
|
||||
if (target_opacity > opacity) {
|
||||
target_opacity = opacity;
|
||||
}
|
||||
|
|
@ -1126,7 +1125,7 @@ bool client_apply_focus_opacity(Client *c) {
|
|||
c->opacity_animation.current_opacity = target_opacity;
|
||||
client_set_opacity(c, target_opacity);
|
||||
client_set_border_color(c, c->opacity_animation.target_border_color);
|
||||
} else if (animations && c->opacity_animation.running) {
|
||||
} else if (config.animations && c->opacity_animation.running) {
|
||||
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
|
|
@ -1187,7 +1186,7 @@ bool client_draw_frame(Client *c) {
|
|||
return client_apply_focus_opacity(c);
|
||||
}
|
||||
|
||||
if (animations && c->animation.running) {
|
||||
if (config.animations && c->animation.running) {
|
||||
client_animation_next_tick(c);
|
||||
} else {
|
||||
wlr_scene_node_set_position(&c->scene->node, c->pending.x,
|
||||
|
|
|
|||
|
|
@ -2,21 +2,21 @@ struct dvec2 calculate_animation_curve_at(double t, int32_t type) {
|
|||
struct dvec2 point;
|
||||
double *animation_curve;
|
||||
if (type == MOVE) {
|
||||
animation_curve = animation_curve_move;
|
||||
animation_curve = config.animation_curve_move;
|
||||
} else if (type == OPEN) {
|
||||
animation_curve = animation_curve_open;
|
||||
animation_curve = config.animation_curve_open;
|
||||
} else if (type == TAG) {
|
||||
animation_curve = animation_curve_tag;
|
||||
animation_curve = config.animation_curve_tag;
|
||||
} else if (type == CLOSE) {
|
||||
animation_curve = animation_curve_close;
|
||||
animation_curve = config.animation_curve_close;
|
||||
} else if (type == FOCUS) {
|
||||
animation_curve = animation_curve_focus;
|
||||
animation_curve = config.animation_curve_focus;
|
||||
} else if (type == OPAFADEIN) {
|
||||
animation_curve = animation_curve_opafadein;
|
||||
animation_curve = config.animation_curve_opafadein;
|
||||
} else if (type == OPAFADEOUT) {
|
||||
animation_curve = animation_curve_opafadeout;
|
||||
animation_curve = config.animation_curve_opafadeout;
|
||||
} else {
|
||||
animation_curve = animation_curve_move;
|
||||
animation_curve = config.animation_curve_move;
|
||||
}
|
||||
|
||||
point.x = 3 * t * (1 - t) * (1 - t) * animation_curve[0] +
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ void layer_draw_shadow(LayerSurface *l) {
|
|||
if (!l->mapped || !l->shadow)
|
||||
return;
|
||||
|
||||
if (!shadows || !layer_shadows || l->noshadow) {
|
||||
if (!config.shadows || !config.layer_shadows || l->noshadow) {
|
||||
wlr_scene_shadow_set_size(l->shadow, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
|
@ -164,9 +164,8 @@ void layer_draw_shadow(LayerSurface *l) {
|
|||
int32_t width, height;
|
||||
layer_actual_size(l, &width, &height);
|
||||
|
||||
int32_t delta = shadows_size;
|
||||
int32_t delta = config.shadows_size;
|
||||
|
||||
/* we calculate where to clip the shadow */
|
||||
struct wlr_box layer_box = {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
|
|
@ -175,23 +174,21 @@ void layer_draw_shadow(LayerSurface *l) {
|
|||
};
|
||||
|
||||
struct wlr_box shadow_box = {
|
||||
.x = shadows_position_x,
|
||||
.y = shadows_position_y,
|
||||
.x = config.shadows_position_x,
|
||||
.y = config.shadows_position_y,
|
||||
.width = width + 2 * delta,
|
||||
.height = height + 2 * delta,
|
||||
};
|
||||
|
||||
struct wlr_box intersection_box;
|
||||
wlr_box_intersection(&intersection_box, &layer_box, &shadow_box);
|
||||
/* clipped region takes shadow relative coords, so we translate everything
|
||||
* by its position */
|
||||
intersection_box.x -= shadows_position_x;
|
||||
intersection_box.y -= shadows_position_y;
|
||||
intersection_box.x -= config.shadows_position_x;
|
||||
intersection_box.y -= config.shadows_position_y;
|
||||
|
||||
struct clipped_region clipped_region = {
|
||||
.area = intersection_box,
|
||||
.corner_radius = border_radius,
|
||||
.corners = border_radius_location_default,
|
||||
.corner_radius = config.border_radius,
|
||||
.corners = config.border_radius_location_default,
|
||||
};
|
||||
|
||||
wlr_scene_node_set_position(&l->shadow->node, shadow_box.x, shadow_box.y);
|
||||
|
|
@ -261,7 +258,7 @@ void fadeout_layer_animation_next_tick(LayerSurface *l) {
|
|||
buffer_data.height = height;
|
||||
|
||||
if ((!l->animation_type_close &&
|
||||
strcmp(layer_animation_type_close, "zoom") == 0) ||
|
||||
strcmp(config.layer_animation_type_close, "zoom") == 0) ||
|
||||
(l->animation_type_close &&
|
||||
strcmp(l->animation_type_close, "zoom") == 0)) {
|
||||
wlr_scene_node_for_each_buffer(&l->scene->node,
|
||||
|
|
@ -279,12 +276,12 @@ void fadeout_layer_animation_next_tick(LayerSurface *l) {
|
|||
double opacity_eased_progress =
|
||||
find_animation_curve_at(animation_passed, OPAFADEOUT);
|
||||
|
||||
double percent = fadeout_begin_opacity -
|
||||
(opacity_eased_progress * fadeout_begin_opacity);
|
||||
double percent = config.fadeout_begin_opacity -
|
||||
(opacity_eased_progress * config.fadeout_begin_opacity);
|
||||
|
||||
double opacity = MAX(percent, 0.0f);
|
||||
|
||||
if (animation_fade_out)
|
||||
if (config.animation_fade_out)
|
||||
wlr_scene_node_for_each_buffer(&l->scene->node,
|
||||
scene_buffer_apply_opacity, &opacity);
|
||||
|
||||
|
|
@ -327,11 +324,11 @@ void layer_animation_next_tick(LayerSurface *l) {
|
|||
find_animation_curve_at(animation_passed, OPAFADEIN);
|
||||
|
||||
double opacity =
|
||||
MIN(fadein_begin_opacity +
|
||||
opacity_eased_progress * (1.0 - fadein_begin_opacity),
|
||||
MIN(config.fadein_begin_opacity +
|
||||
opacity_eased_progress * (1.0 - config.fadein_begin_opacity),
|
||||
1.0f);
|
||||
|
||||
if (animation_fade_in)
|
||||
if (config.animation_fade_in)
|
||||
wlr_scene_node_for_each_buffer(&l->scene->node,
|
||||
scene_buffer_apply_opacity, &opacity);
|
||||
|
||||
|
|
@ -347,7 +344,7 @@ void layer_animation_next_tick(LayerSurface *l) {
|
|||
}
|
||||
|
||||
if ((!l->animation_type_open &&
|
||||
strcmp(layer_animation_type_open, "zoom") == 0) ||
|
||||
strcmp(config.layer_animation_type_open, "zoom") == 0) ||
|
||||
(l->animation_type_open &&
|
||||
strcmp(l->animation_type_open, "zoom") == 0)) {
|
||||
wlr_scene_node_for_each_buffer(
|
||||
|
|
@ -370,7 +367,7 @@ void layer_animation_next_tick(LayerSurface *l) {
|
|||
|
||||
void init_fadeout_layers(LayerSurface *l) {
|
||||
|
||||
if (!animations || !layer_animations || l->noanim) {
|
||||
if (!config.animations || !config.layer_animations || l->noanim) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -380,7 +377,7 @@ void init_fadeout_layers(LayerSurface *l) {
|
|||
if ((l->animation_type_close &&
|
||||
strcmp(l->animation_type_close, "none") == 0) ||
|
||||
(!l->animation_type_close &&
|
||||
strcmp(layer_animation_type_close, "none") == 0)) {
|
||||
strcmp(config.layer_animation_type_close, "none") == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -403,7 +400,7 @@ void init_fadeout_layers(LayerSurface *l) {
|
|||
return;
|
||||
}
|
||||
|
||||
fadeout_layer->animation.duration = animation_duration_close;
|
||||
fadeout_layer->animation.duration = config.animation_duration_close;
|
||||
fadeout_layer->geom = fadeout_layer->current =
|
||||
fadeout_layer->animainit_geom = fadeout_layer->animation.initial =
|
||||
l->animation.current;
|
||||
|
|
@ -419,14 +416,14 @@ void init_fadeout_layers(LayerSurface *l) {
|
|||
fadeout_layer->animation.initial.y = 0;
|
||||
|
||||
if ((!l->animation_type_close &&
|
||||
strcmp(layer_animation_type_close, "zoom") == 0) ||
|
||||
strcmp(config.layer_animation_type_close, "zoom") == 0) ||
|
||||
(l->animation_type_close &&
|
||||
strcmp(l->animation_type_close, "zoom") == 0)) {
|
||||
// 算出要设置的绝对坐标和大小
|
||||
fadeout_layer->current.width =
|
||||
(float)l->animation.current.width * zoom_end_ratio;
|
||||
(float)l->animation.current.width * config.zoom_end_ratio;
|
||||
fadeout_layer->current.height =
|
||||
(float)l->animation.current.height * zoom_end_ratio;
|
||||
(float)l->animation.current.height * config.zoom_end_ratio;
|
||||
fadeout_layer->current.x = usable_area.x + usable_area.width / 2 -
|
||||
fadeout_layer->current.width / 2;
|
||||
fadeout_layer->current.y = usable_area.y + usable_area.height / 2 -
|
||||
|
|
@ -438,7 +435,7 @@ void init_fadeout_layers(LayerSurface *l) {
|
|||
fadeout_layer->current.y - l->animation.current.y;
|
||||
|
||||
} else if ((!l->animation_type_close &&
|
||||
strcmp(layer_animation_type_close, "slide") == 0) ||
|
||||
strcmp(config.layer_animation_type_close, "slide") == 0) ||
|
||||
(l->animation_type_close &&
|
||||
strcmp(l->animation_type_close, "slide") == 0)) {
|
||||
// 获取slide动画的结束绝对坐标和大小
|
||||
|
|
@ -483,17 +480,18 @@ void layer_set_pending_state(LayerSurface *l) {
|
|||
if (l->animation.action == OPEN && !l->animation.running) {
|
||||
|
||||
if ((!l->animation_type_open &&
|
||||
strcmp(layer_animation_type_open, "zoom") == 0) ||
|
||||
strcmp(config.layer_animation_type_open, "zoom") == 0) ||
|
||||
(l->animation_type_open &&
|
||||
strcmp(l->animation_type_open, "zoom") == 0)) {
|
||||
l->animainit_geom.width = l->geom.width * zoom_initial_ratio;
|
||||
l->animainit_geom.height = l->geom.height * zoom_initial_ratio;
|
||||
l->animainit_geom.width = l->geom.width * config.zoom_initial_ratio;
|
||||
l->animainit_geom.height =
|
||||
l->geom.height * config.zoom_initial_ratio;
|
||||
l->animainit_geom.x = usable_area.x + usable_area.width / 2 -
|
||||
l->animainit_geom.width / 2;
|
||||
l->animainit_geom.y = usable_area.y + usable_area.height / 2 -
|
||||
l->animainit_geom.height / 2;
|
||||
} else if ((!l->animation_type_open &&
|
||||
strcmp(layer_animation_type_open, "slide") == 0) ||
|
||||
strcmp(config.layer_animation_type_open, "slide") == 0) ||
|
||||
(l->animation_type_open &&
|
||||
strcmp(l->animation_type_open, "slide") == 0)) {
|
||||
|
||||
|
|
@ -507,8 +505,7 @@ void layer_set_pending_state(LayerSurface *l) {
|
|||
} else {
|
||||
l->animainit_geom = l->animation.current;
|
||||
}
|
||||
// 判断是否需要动画
|
||||
if (!animations || !layer_animations || l->noanim ||
|
||||
if (!config.animations || !config.layer_animations || l->noanim ||
|
||||
l->layer_surface->current.layer ==
|
||||
ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND ||
|
||||
l->layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM) {
|
||||
|
|
@ -520,7 +517,7 @@ void layer_set_pending_state(LayerSurface *l) {
|
|||
if (((l->animation_type_open &&
|
||||
strcmp(l->animation_type_open, "none") == 0) ||
|
||||
(!l->animation_type_open &&
|
||||
strcmp(layer_animation_type_open, "none") == 0)) &&
|
||||
strcmp(config.layer_animation_type_open, "none") == 0)) &&
|
||||
l->animation.action == OPEN) {
|
||||
l->animation.should_animate = false;
|
||||
}
|
||||
|
|
@ -567,7 +564,8 @@ bool layer_draw_frame(LayerSurface *l) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (animations && layer_animations && l->animation.running && !l->noanim) {
|
||||
if (config.animations && config.layer_animations && l->animation.running &&
|
||||
!l->noanim) {
|
||||
layer_animation_next_tick(l);
|
||||
layer_draw_shadow(l);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ void set_tagin_animation(Monitor *m, Client *c) {
|
|||
|
||||
if (m->pertag->curtag > m->pertag->prevtag) {
|
||||
|
||||
c->animainit_geom.x = tag_animation_direction == VERTICAL
|
||||
c->animainit_geom.x = config.tag_animation_direction == VERTICAL
|
||||
? c->animation.current.x
|
||||
: MAX(c->mon->m.x + c->mon->m.width,
|
||||
c->geom.x + c->mon->m.width);
|
||||
c->animainit_geom.y = tag_animation_direction == VERTICAL
|
||||
c->animainit_geom.y = config.tag_animation_direction == VERTICAL
|
||||
? MAX(c->mon->m.y + c->mon->m.height,
|
||||
c->geom.y + c->mon->m.height)
|
||||
: c->animation.current.y;
|
||||
|
|
@ -19,11 +19,11 @@ void set_tagin_animation(Monitor *m, Client *c) {
|
|||
} else {
|
||||
|
||||
c->animainit_geom.x =
|
||||
tag_animation_direction == VERTICAL
|
||||
config.tag_animation_direction == VERTICAL
|
||||
? c->animation.current.x
|
||||
: MIN(m->m.x - c->geom.width, c->geom.x - c->mon->m.width);
|
||||
c->animainit_geom.y =
|
||||
tag_animation_direction == VERTICAL
|
||||
config.tag_animation_direction == VERTICAL
|
||||
? MIN(m->m.y - c->geom.height, c->geom.y - c->mon->m.height)
|
||||
: c->animation.current.y;
|
||||
}
|
||||
|
|
@ -39,7 +39,8 @@ void set_arrange_visible(Monitor *m, Client *c, bool want_animation) {
|
|||
client_set_suspended(c, false);
|
||||
|
||||
if (!c->animation.tag_from_rule && want_animation &&
|
||||
m->pertag->prevtag != 0 && m->pertag->curtag != 0 && animations) {
|
||||
m->pertag->prevtag != 0 && m->pertag->curtag != 0 &&
|
||||
config.animations) {
|
||||
c->animation.tagining = true;
|
||||
set_tagin_animation(m, c);
|
||||
} else {
|
||||
|
|
@ -57,10 +58,10 @@ void set_tagout_animation(Monitor *m, Client *c) {
|
|||
if (m->pertag->curtag > m->pertag->prevtag) {
|
||||
c->pending = c->geom;
|
||||
c->pending.x =
|
||||
tag_animation_direction == VERTICAL
|
||||
config.tag_animation_direction == VERTICAL
|
||||
? c->animation.current.x
|
||||
: MIN(c->mon->m.x - c->geom.width, c->geom.x - c->mon->m.width);
|
||||
c->pending.y = tag_animation_direction == VERTICAL
|
||||
c->pending.y = config.tag_animation_direction == VERTICAL
|
||||
? MIN(c->mon->m.y - c->geom.height,
|
||||
c->geom.y - c->mon->m.height)
|
||||
: c->animation.current.y;
|
||||
|
|
@ -68,11 +69,11 @@ void set_tagout_animation(Monitor *m, Client *c) {
|
|||
resize(c, c->geom, 0);
|
||||
} else {
|
||||
c->pending = c->geom;
|
||||
c->pending.x = tag_animation_direction == VERTICAL
|
||||
c->pending.x = config.tag_animation_direction == VERTICAL
|
||||
? c->animation.current.x
|
||||
: MAX(c->mon->m.x + c->mon->m.width,
|
||||
c->geom.x + c->mon->m.width);
|
||||
c->pending.y = tag_animation_direction == VERTICAL
|
||||
c->pending.y = config.tag_animation_direction == VERTICAL
|
||||
? MAX(c->mon->m.y + c->mon->m.height,
|
||||
c->geom.y + c->mon->m.height)
|
||||
: c->animation.current.y;
|
||||
|
|
@ -82,7 +83,8 @@ void set_tagout_animation(Monitor *m, Client *c) {
|
|||
|
||||
void set_arrange_hidden(Monitor *m, Client *c, bool want_animation) {
|
||||
if ((c->tags & (1 << (m->pertag->prevtag - 1))) &&
|
||||
m->pertag->prevtag != 0 && m->pertag->curtag != 0 && animations) {
|
||||
m->pertag->prevtag != 0 && m->pertag->curtag != 0 &&
|
||||
config.animations) {
|
||||
c->animation.tagouting = true;
|
||||
c->animation.tagining = false;
|
||||
set_tagout_animation(m, c);
|
||||
|
|
|
|||
|
|
@ -285,6 +285,7 @@ typedef struct {
|
|||
int32_t blur_layer;
|
||||
int32_t blur_optimized;
|
||||
int32_t border_radius;
|
||||
int32_t border_radius_location_default;
|
||||
struct blur_data blur_params;
|
||||
int32_t shadows;
|
||||
int32_t shadow_only_floating;
|
||||
|
|
@ -312,7 +313,8 @@ typedef struct {
|
|||
float globalcolor[4];
|
||||
float overlaycolor[4];
|
||||
|
||||
char autostart[3][256];
|
||||
int32_t log_level;
|
||||
uint32_t capslock;
|
||||
|
||||
ConfigTagRule *tag_rules; // 动态数组
|
||||
int32_t tag_rules_count; // 数量
|
||||
|
|
@ -363,6 +365,11 @@ typedef struct {
|
|||
int32_t allow_lock_transparent;
|
||||
|
||||
struct xkb_rule_names xkb_rules;
|
||||
char xkb_rules_rules[128];
|
||||
char xkb_rules_model[128];
|
||||
char xkb_rules_layout[128];
|
||||
char xkb_rules_variant[128];
|
||||
char xkb_rules_options[128];
|
||||
|
||||
char keymode[28];
|
||||
|
||||
|
|
@ -1428,25 +1435,25 @@ bool parse_option(Config *config, char *key, char *value) {
|
|||
} else if (strcmp(key, "unfocused_opacity") == 0) {
|
||||
config->unfocused_opacity = atof(value);
|
||||
} else if (strcmp(key, "xkb_rules_rules") == 0) {
|
||||
strncpy(xkb_rules_rules, value, sizeof(xkb_rules_rules) - 1);
|
||||
xkb_rules_rules[sizeof(xkb_rules_rules) - 1] =
|
||||
'\0'; // 确保字符串以 null 结尾
|
||||
strncpy(config->xkb_rules_rules, value,
|
||||
sizeof(config->xkb_rules_rules) - 1);
|
||||
config->xkb_rules_rules[sizeof(config->xkb_rules_rules) - 1] = '\0';
|
||||
} else if (strcmp(key, "xkb_rules_model") == 0) {
|
||||
strncpy(xkb_rules_model, value, sizeof(xkb_rules_model) - 1);
|
||||
xkb_rules_model[sizeof(xkb_rules_model) - 1] =
|
||||
'\0'; // 确保字符串以 null 结尾
|
||||
strncpy(config->xkb_rules_model, value,
|
||||
sizeof(config->xkb_rules_model) - 1);
|
||||
config->xkb_rules_model[sizeof(config->xkb_rules_model) - 1] = '\0';
|
||||
} else if (strcmp(key, "xkb_rules_layout") == 0) {
|
||||
strncpy(xkb_rules_layout, value, sizeof(xkb_rules_layout) - 1);
|
||||
xkb_rules_layout[sizeof(xkb_rules_layout) - 1] =
|
||||
'\0'; // 确保字符串以 null 结尾
|
||||
strncpy(config->xkb_rules_layout, value,
|
||||
sizeof(config->xkb_rules_layout) - 1);
|
||||
config->xkb_rules_layout[sizeof(config->xkb_rules_layout) - 1] = '\0';
|
||||
} else if (strcmp(key, "xkb_rules_variant") == 0) {
|
||||
strncpy(xkb_rules_variant, value, sizeof(xkb_rules_variant) - 1);
|
||||
xkb_rules_variant[sizeof(xkb_rules_variant) - 1] =
|
||||
'\0'; // 确保字符串以 null 结尾
|
||||
strncpy(config->xkb_rules_variant, value,
|
||||
sizeof(config->xkb_rules_variant) - 1);
|
||||
config->xkb_rules_variant[sizeof(config->xkb_rules_variant) - 1] = '\0';
|
||||
} else if (strcmp(key, "xkb_rules_options") == 0) {
|
||||
strncpy(xkb_rules_options, value, sizeof(xkb_rules_options) - 1);
|
||||
xkb_rules_options[sizeof(xkb_rules_options) - 1] =
|
||||
'\0'; // 确保字符串以 null 结尾
|
||||
strncpy(config->xkb_rules_options, value,
|
||||
sizeof(config->xkb_rules_options) - 1);
|
||||
config->xkb_rules_options[sizeof(config->xkb_rules_options) - 1] = '\0';
|
||||
} else if (strcmp(key, "scroller_proportion_preset") == 0) {
|
||||
// 1. 统计 value 中有多少个逗号,确定需要解析的浮点数个数
|
||||
int32_t count = 0; // 初始化为 0
|
||||
|
|
@ -3087,363 +3094,347 @@ void free_config(void) {
|
|||
}
|
||||
|
||||
void override_config(void) {
|
||||
// 动画启用
|
||||
animations = CLAMP_INT(config.animations, 0, 1);
|
||||
layer_animations = CLAMP_INT(config.layer_animations, 0, 1);
|
||||
|
||||
// 标签动画方向
|
||||
tag_animation_direction = CLAMP_INT(config.tag_animation_direction, 0, 1);
|
||||
|
||||
// 动画淡入淡出设置
|
||||
animation_fade_in = CLAMP_INT(config.animation_fade_in, 0, 1);
|
||||
animation_fade_out = CLAMP_INT(config.animation_fade_out, 0, 1);
|
||||
zoom_initial_ratio = CLAMP_FLOAT(config.zoom_initial_ratio, 0.1f, 1.0f);
|
||||
zoom_end_ratio = CLAMP_FLOAT(config.zoom_end_ratio, 0.1f, 1.0f);
|
||||
fadein_begin_opacity = CLAMP_FLOAT(config.fadein_begin_opacity, 0.0f, 1.0f);
|
||||
fadeout_begin_opacity =
|
||||
config.animations = CLAMP_INT(config.animations, 0, 1);
|
||||
config.layer_animations = CLAMP_INT(config.layer_animations, 0, 1);
|
||||
config.tag_animation_direction =
|
||||
CLAMP_INT(config.tag_animation_direction, 0, 1);
|
||||
config.animation_fade_in = CLAMP_INT(config.animation_fade_in, 0, 1);
|
||||
config.animation_fade_out = CLAMP_INT(config.animation_fade_out, 0, 1);
|
||||
config.zoom_initial_ratio =
|
||||
CLAMP_FLOAT(config.zoom_initial_ratio, 0.1f, 1.0f);
|
||||
config.zoom_end_ratio = CLAMP_FLOAT(config.zoom_end_ratio, 0.1f, 1.0f);
|
||||
config.fadein_begin_opacity =
|
||||
CLAMP_FLOAT(config.fadein_begin_opacity, 0.0f, 1.0f);
|
||||
config.fadeout_begin_opacity =
|
||||
CLAMP_FLOAT(config.fadeout_begin_opacity, 0.0f, 1.0f);
|
||||
|
||||
// 打开关闭动画类型
|
||||
animation_type_open = config.animation_type_open;
|
||||
animation_type_close = config.animation_type_close;
|
||||
|
||||
// layer打开关闭动画类型
|
||||
layer_animation_type_open = config.layer_animation_type_open;
|
||||
layer_animation_type_close = config.layer_animation_type_close;
|
||||
|
||||
// 动画时间限制在合理范围(1-50000ms)
|
||||
animation_duration_move =
|
||||
config.animation_duration_move =
|
||||
CLAMP_INT(config.animation_duration_move, 1, 50000);
|
||||
animation_duration_open =
|
||||
config.animation_duration_open =
|
||||
CLAMP_INT(config.animation_duration_open, 1, 50000);
|
||||
animation_duration_tag = CLAMP_INT(config.animation_duration_tag, 1, 50000);
|
||||
animation_duration_close =
|
||||
config.animation_duration_tag =
|
||||
CLAMP_INT(config.animation_duration_tag, 1, 50000);
|
||||
config.animation_duration_close =
|
||||
CLAMP_INT(config.animation_duration_close, 1, 50000);
|
||||
animation_duration_focus =
|
||||
config.animation_duration_focus =
|
||||
CLAMP_INT(config.animation_duration_focus, 1, 50000);
|
||||
|
||||
// 滚动布局设置
|
||||
scroller_default_proportion =
|
||||
config.scroller_default_proportion =
|
||||
CLAMP_FLOAT(config.scroller_default_proportion, 0.1f, 1.0f);
|
||||
scroller_default_proportion_single =
|
||||
config.scroller_default_proportion_single =
|
||||
CLAMP_FLOAT(config.scroller_default_proportion_single, 0.1f, 1.0f);
|
||||
scroller_ignore_proportion_single =
|
||||
config.scroller_ignore_proportion_single =
|
||||
CLAMP_INT(config.scroller_ignore_proportion_single, 0, 1);
|
||||
scroller_focus_center = CLAMP_INT(config.scroller_focus_center, 0, 1);
|
||||
scroller_prefer_center = CLAMP_INT(config.scroller_prefer_center, 0, 1);
|
||||
scroller_prefer_overspread =
|
||||
config.scroller_focus_center =
|
||||
CLAMP_INT(config.scroller_focus_center, 0, 1);
|
||||
config.scroller_prefer_center =
|
||||
CLAMP_INT(config.scroller_prefer_center, 0, 1);
|
||||
config.scroller_prefer_overspread =
|
||||
CLAMP_INT(config.scroller_prefer_overspread, 0, 1);
|
||||
edge_scroller_pointer_focus =
|
||||
config.edge_scroller_pointer_focus =
|
||||
CLAMP_INT(config.edge_scroller_pointer_focus, 0, 1);
|
||||
scroller_structs = CLAMP_INT(config.scroller_structs, 0, 1000);
|
||||
|
||||
// 主从布局设置
|
||||
default_mfact = CLAMP_FLOAT(config.default_mfact, 0.1f, 0.9f);
|
||||
default_nmaster = CLAMP_INT(config.default_nmaster, 1, 1000);
|
||||
center_master_overspread = CLAMP_INT(config.center_master_overspread, 0, 1);
|
||||
center_when_single_stack = CLAMP_INT(config.center_when_single_stack, 0, 1);
|
||||
new_is_master = CLAMP_INT(config.new_is_master, 0, 1);
|
||||
|
||||
// 概述模式设置
|
||||
hotarea_size = CLAMP_INT(config.hotarea_size, 1, 1000);
|
||||
hotarea_corner = CLAMP_INT(config.hotarea_corner, 0, 3);
|
||||
enable_hotarea = CLAMP_INT(config.enable_hotarea, 0, 1);
|
||||
ov_tab_mode = CLAMP_INT(config.ov_tab_mode, 0, 1);
|
||||
overviewgappi = CLAMP_INT(config.overviewgappi, 0, 1000);
|
||||
overviewgappo = CLAMP_INT(config.overviewgappo, 0, 1000);
|
||||
|
||||
// 杂项设置
|
||||
xwayland_persistence = CLAMP_INT(config.xwayland_persistence, 0, 1);
|
||||
syncobj_enable = CLAMP_INT(config.syncobj_enable, 0, 1);
|
||||
drag_tile_refresh_interval =
|
||||
config.scroller_structs = CLAMP_INT(config.scroller_structs, 0, 1000);
|
||||
config.default_mfact = CLAMP_FLOAT(config.default_mfact, 0.1f, 0.9f);
|
||||
config.default_nmaster = CLAMP_INT(config.default_nmaster, 1, 1000);
|
||||
config.center_master_overspread =
|
||||
CLAMP_INT(config.center_master_overspread, 0, 1);
|
||||
config.center_when_single_stack =
|
||||
CLAMP_INT(config.center_when_single_stack, 0, 1);
|
||||
config.new_is_master = CLAMP_INT(config.new_is_master, 0, 1);
|
||||
config.hotarea_size = CLAMP_INT(config.hotarea_size, 1, 1000);
|
||||
config.hotarea_corner = CLAMP_INT(config.hotarea_corner, 0, 3);
|
||||
config.enable_hotarea = CLAMP_INT(config.enable_hotarea, 0, 1);
|
||||
config.ov_tab_mode = CLAMP_INT(config.ov_tab_mode, 0, 1);
|
||||
config.overviewgappi = CLAMP_INT(config.overviewgappi, 0, 1000);
|
||||
config.overviewgappo = CLAMP_INT(config.overviewgappo, 0, 1000);
|
||||
config.xwayland_persistence = CLAMP_INT(config.xwayland_persistence, 0, 1);
|
||||
config.syncobj_enable = CLAMP_INT(config.syncobj_enable, 0, 1);
|
||||
config.drag_tile_refresh_interval =
|
||||
CLAMP_FLOAT(config.drag_tile_refresh_interval, 1.0f, 16.0f);
|
||||
drag_floating_refresh_interval =
|
||||
CLAMP_FLOAT(config.drag_floating_refresh_interval, 1.0f, 16.0f);
|
||||
drag_tile_to_tile = CLAMP_INT(config.drag_tile_to_tile, 0, 1);
|
||||
drag_floating_refresh_interval =
|
||||
config.drag_floating_refresh_interval =
|
||||
CLAMP_FLOAT(config.drag_floating_refresh_interval, 0.0f, 1000.0f);
|
||||
allow_tearing = CLAMP_INT(config.allow_tearing, 0, 2);
|
||||
allow_shortcuts_inhibit = CLAMP_INT(config.allow_shortcuts_inhibit, 0, 1);
|
||||
allow_lock_transparent = CLAMP_INT(config.allow_lock_transparent, 0, 1);
|
||||
axis_bind_apply_timeout =
|
||||
config.drag_tile_to_tile = CLAMP_INT(config.drag_tile_to_tile, 0, 1);
|
||||
config.allow_tearing = CLAMP_INT(config.allow_tearing, 0, 2);
|
||||
config.allow_shortcuts_inhibit =
|
||||
CLAMP_INT(config.allow_shortcuts_inhibit, 0, 1);
|
||||
config.allow_lock_transparent =
|
||||
CLAMP_INT(config.allow_lock_transparent, 0, 1);
|
||||
config.axis_bind_apply_timeout =
|
||||
CLAMP_INT(config.axis_bind_apply_timeout, 0, 1000);
|
||||
focus_on_activate = CLAMP_INT(config.focus_on_activate, 0, 1);
|
||||
idleinhibit_ignore_visible =
|
||||
config.focus_on_activate = CLAMP_INT(config.focus_on_activate, 0, 1);
|
||||
config.idleinhibit_ignore_visible =
|
||||
CLAMP_INT(config.idleinhibit_ignore_visible, 0, 1);
|
||||
sloppyfocus = CLAMP_INT(config.sloppyfocus, 0, 1);
|
||||
warpcursor = CLAMP_INT(config.warpcursor, 0, 1);
|
||||
drag_corner = CLAMP_INT(config.drag_corner, 0, 4);
|
||||
drag_warp_cursor = CLAMP_INT(config.drag_warp_cursor, 0, 1);
|
||||
focus_cross_monitor = CLAMP_INT(config.focus_cross_monitor, 0, 1);
|
||||
exchange_cross_monitor = CLAMP_INT(config.exchange_cross_monitor, 0, 1);
|
||||
scratchpad_cross_monitor = CLAMP_INT(config.scratchpad_cross_monitor, 0, 1);
|
||||
focus_cross_tag = CLAMP_INT(config.focus_cross_tag, 0, 1);
|
||||
view_current_to_back = CLAMP_INT(config.view_current_to_back, 0, 1);
|
||||
enable_floating_snap = CLAMP_INT(config.enable_floating_snap, 0, 1);
|
||||
snap_distance = CLAMP_INT(config.snap_distance, 0, 99999);
|
||||
cursor_size = CLAMP_INT(config.cursor_size, 4, 512);
|
||||
no_border_when_single = CLAMP_INT(config.no_border_when_single, 0, 1);
|
||||
no_radius_when_single = CLAMP_INT(config.no_radius_when_single, 0, 1);
|
||||
cursor_hide_timeout =
|
||||
CLAMP_INT(config.cursor_hide_timeout, 0, 36000); // 0-10小时
|
||||
drag_tile_to_tile = CLAMP_INT(config.drag_tile_to_tile, 0, 1);
|
||||
single_scratchpad = CLAMP_INT(config.single_scratchpad, 0, 1);
|
||||
|
||||
// 键盘设置
|
||||
repeat_rate = CLAMP_INT(config.repeat_rate, 1, 1000);
|
||||
repeat_delay = CLAMP_INT(config.repeat_delay, 1, 20000);
|
||||
numlockon = CLAMP_INT(config.numlockon, 0, 1);
|
||||
|
||||
// 触控板设置
|
||||
disable_trackpad = CLAMP_INT(config.disable_trackpad, 0, 1);
|
||||
tap_to_click = CLAMP_INT(config.tap_to_click, 0, 1);
|
||||
tap_and_drag = CLAMP_INT(config.tap_and_drag, 0, 1);
|
||||
drag_lock = CLAMP_INT(config.drag_lock, 0, 1);
|
||||
trackpad_natural_scrolling =
|
||||
config.sloppyfocus = CLAMP_INT(config.sloppyfocus, 0, 1);
|
||||
config.warpcursor = CLAMP_INT(config.warpcursor, 0, 1);
|
||||
config.drag_corner = CLAMP_INT(config.drag_corner, 0, 4);
|
||||
config.drag_warp_cursor = CLAMP_INT(config.drag_warp_cursor, 0, 1);
|
||||
config.focus_cross_monitor = CLAMP_INT(config.focus_cross_monitor, 0, 1);
|
||||
config.exchange_cross_monitor =
|
||||
CLAMP_INT(config.exchange_cross_monitor, 0, 1);
|
||||
config.scratchpad_cross_monitor =
|
||||
CLAMP_INT(config.scratchpad_cross_monitor, 0, 1);
|
||||
config.focus_cross_tag = CLAMP_INT(config.focus_cross_tag, 0, 1);
|
||||
config.view_current_to_back = CLAMP_INT(config.view_current_to_back, 0, 1);
|
||||
config.enable_floating_snap = CLAMP_INT(config.enable_floating_snap, 0, 1);
|
||||
config.snap_distance = CLAMP_INT(config.snap_distance, 0, 99999);
|
||||
config.cursor_size = CLAMP_INT(config.cursor_size, 4, 512);
|
||||
config.no_border_when_single =
|
||||
CLAMP_INT(config.no_border_when_single, 0, 1);
|
||||
config.no_radius_when_single =
|
||||
CLAMP_INT(config.no_radius_when_single, 0, 1);
|
||||
config.cursor_hide_timeout =
|
||||
CLAMP_INT(config.cursor_hide_timeout, 0, 36000);
|
||||
config.single_scratchpad = CLAMP_INT(config.single_scratchpad, 0, 1);
|
||||
config.repeat_rate = CLAMP_INT(config.repeat_rate, 1, 1000);
|
||||
config.repeat_delay = CLAMP_INT(config.repeat_delay, 1, 20000);
|
||||
config.numlockon = CLAMP_INT(config.numlockon, 0, 1);
|
||||
config.disable_trackpad = CLAMP_INT(config.disable_trackpad, 0, 1);
|
||||
config.tap_to_click = CLAMP_INT(config.tap_to_click, 0, 1);
|
||||
config.tap_and_drag = CLAMP_INT(config.tap_and_drag, 0, 1);
|
||||
config.drag_lock = CLAMP_INT(config.drag_lock, 0, 1);
|
||||
config.trackpad_natural_scrolling =
|
||||
CLAMP_INT(config.trackpad_natural_scrolling, 0, 1);
|
||||
disable_while_typing = CLAMP_INT(config.disable_while_typing, 0, 1);
|
||||
left_handed = CLAMP_INT(config.left_handed, 0, 1);
|
||||
middle_button_emulation = CLAMP_INT(config.middle_button_emulation, 0, 1);
|
||||
swipe_min_threshold = CLAMP_INT(config.swipe_min_threshold, 1, 1000);
|
||||
|
||||
// 鼠标设置
|
||||
mouse_natural_scrolling = CLAMP_INT(config.mouse_natural_scrolling, 0, 1);
|
||||
accel_profile = CLAMP_INT(config.accel_profile, 0, 2);
|
||||
accel_speed = CLAMP_FLOAT(config.accel_speed, -1.0f, 1.0f);
|
||||
scroll_method = CLAMP_INT(config.scroll_method, 0, 4);
|
||||
scroll_button = CLAMP_INT(config.scroll_button, 272, 276);
|
||||
click_method = CLAMP_INT(config.click_method, 0, 2);
|
||||
send_events_mode = CLAMP_INT(config.send_events_mode, 0, 2);
|
||||
button_map = CLAMP_INT(config.button_map, 0, 1);
|
||||
axis_scroll_factor = CLAMP_FLOAT(config.axis_scroll_factor, 0.1f, 10.0f);
|
||||
|
||||
// 外观设置
|
||||
gappih = CLAMP_INT(config.gappih, 0, 1000);
|
||||
gappiv = CLAMP_INT(config.gappiv, 0, 1000);
|
||||
gappoh = CLAMP_INT(config.gappoh, 0, 1000);
|
||||
gappov = CLAMP_INT(config.gappov, 0, 1000);
|
||||
scratchpad_width_ratio =
|
||||
config.disable_while_typing = CLAMP_INT(config.disable_while_typing, 0, 1);
|
||||
config.left_handed = CLAMP_INT(config.left_handed, 0, 1);
|
||||
config.middle_button_emulation =
|
||||
CLAMP_INT(config.middle_button_emulation, 0, 1);
|
||||
config.swipe_min_threshold = CLAMP_INT(config.swipe_min_threshold, 1, 1000);
|
||||
config.mouse_natural_scrolling =
|
||||
CLAMP_INT(config.mouse_natural_scrolling, 0, 1);
|
||||
config.accel_profile = CLAMP_INT(config.accel_profile, 0, 2);
|
||||
config.accel_speed = CLAMP_FLOAT(config.accel_speed, -1.0f, 1.0f);
|
||||
config.scroll_method = CLAMP_INT(config.scroll_method, 0, 4);
|
||||
config.scroll_button = CLAMP_INT(config.scroll_button, 272, 276);
|
||||
config.click_method = CLAMP_INT(config.click_method, 0, 2);
|
||||
config.send_events_mode = CLAMP_INT(config.send_events_mode, 0, 2);
|
||||
config.button_map = CLAMP_INT(config.button_map, 0, 1);
|
||||
config.axis_scroll_factor =
|
||||
CLAMP_FLOAT(config.axis_scroll_factor, 0.1f, 10.0f);
|
||||
config.gappih = CLAMP_INT(config.gappih, 0, 1000);
|
||||
config.gappiv = CLAMP_INT(config.gappiv, 0, 1000);
|
||||
config.gappoh = CLAMP_INT(config.gappoh, 0, 1000);
|
||||
config.gappov = CLAMP_INT(config.gappov, 0, 1000);
|
||||
config.scratchpad_width_ratio =
|
||||
CLAMP_FLOAT(config.scratchpad_width_ratio, 0.1f, 1.0f);
|
||||
scratchpad_height_ratio =
|
||||
config.scratchpad_height_ratio =
|
||||
CLAMP_FLOAT(config.scratchpad_height_ratio, 0.1f, 1.0f);
|
||||
borderpx = CLAMP_INT(config.borderpx, 0, 200);
|
||||
smartgaps = CLAMP_INT(config.smartgaps, 0, 1);
|
||||
|
||||
blur = CLAMP_INT(config.blur, 0, 1);
|
||||
blur_layer = CLAMP_INT(config.blur_layer, 0, 1);
|
||||
blur_optimized = CLAMP_INT(config.blur_optimized, 0, 1);
|
||||
border_radius = CLAMP_INT(config.border_radius, 0, 100);
|
||||
blur_params.num_passes = CLAMP_INT(config.blur_params.num_passes, 0, 10);
|
||||
blur_params.radius = CLAMP_INT(config.blur_params.radius, 0, 100);
|
||||
blur_params.noise = CLAMP_FLOAT(config.blur_params.noise, 0, 1);
|
||||
blur_params.brightness = CLAMP_FLOAT(config.blur_params.brightness, 0, 1);
|
||||
blur_params.contrast = CLAMP_FLOAT(config.blur_params.contrast, 0, 1);
|
||||
blur_params.saturation = CLAMP_FLOAT(config.blur_params.saturation, 0, 1);
|
||||
shadows = CLAMP_INT(config.shadows, 0, 1);
|
||||
shadow_only_floating = CLAMP_INT(config.shadow_only_floating, 0, 1);
|
||||
layer_shadows = CLAMP_INT(config.layer_shadows, 0, 1);
|
||||
shadows_size = CLAMP_INT(config.shadows_size, 0, 100);
|
||||
shadows_blur = CLAMP_INT(config.shadows_blur, 0, 100);
|
||||
shadows_position_x = CLAMP_INT(config.shadows_position_x, -1000, 1000);
|
||||
shadows_position_y = CLAMP_INT(config.shadows_position_y, -1000, 1000);
|
||||
focused_opacity = CLAMP_FLOAT(config.focused_opacity, 0.0f, 1.0f);
|
||||
unfocused_opacity = CLAMP_FLOAT(config.unfocused_opacity, 0.0f, 1.0f);
|
||||
memcpy(shadowscolor, config.shadowscolor, sizeof(shadowscolor));
|
||||
|
||||
// 复制颜色数组
|
||||
memcpy(rootcolor, config.rootcolor, sizeof(rootcolor));
|
||||
memcpy(bordercolor, config.bordercolor, sizeof(bordercolor));
|
||||
memcpy(focuscolor, config.focuscolor, sizeof(focuscolor));
|
||||
memcpy(maximizescreencolor, config.maximizescreencolor,
|
||||
sizeof(maximizescreencolor));
|
||||
memcpy(urgentcolor, config.urgentcolor, sizeof(urgentcolor));
|
||||
memcpy(scratchpadcolor, config.scratchpadcolor, sizeof(scratchpadcolor));
|
||||
memcpy(globalcolor, config.globalcolor, sizeof(globalcolor));
|
||||
memcpy(overlaycolor, config.overlaycolor, sizeof(overlaycolor));
|
||||
|
||||
// 复制动画曲线
|
||||
memcpy(animation_curve_move, config.animation_curve_move,
|
||||
sizeof(animation_curve_move));
|
||||
memcpy(animation_curve_open, config.animation_curve_open,
|
||||
sizeof(animation_curve_open));
|
||||
memcpy(animation_curve_tag, config.animation_curve_tag,
|
||||
sizeof(animation_curve_tag));
|
||||
memcpy(animation_curve_close, config.animation_curve_close,
|
||||
sizeof(animation_curve_close));
|
||||
memcpy(animation_curve_focus, config.animation_curve_focus,
|
||||
sizeof(animation_curve_focus));
|
||||
memcpy(animation_curve_opafadein, config.animation_curve_opafadein,
|
||||
sizeof(animation_curve_opafadein));
|
||||
memcpy(animation_curve_opafadeout, config.animation_curve_opafadeout,
|
||||
sizeof(animation_curve_opafadeout));
|
||||
config.borderpx = CLAMP_INT(config.borderpx, 0, 200);
|
||||
config.smartgaps = CLAMP_INT(config.smartgaps, 0, 1);
|
||||
config.blur = CLAMP_INT(config.blur, 0, 1);
|
||||
config.blur_layer = CLAMP_INT(config.blur_layer, 0, 1);
|
||||
config.blur_optimized = CLAMP_INT(config.blur_optimized, 0, 1);
|
||||
config.border_radius = CLAMP_INT(config.border_radius, 0, 100);
|
||||
config.blur_params.num_passes =
|
||||
CLAMP_INT(config.blur_params.num_passes, 0, 10);
|
||||
config.blur_params.radius = CLAMP_INT(config.blur_params.radius, 0, 100);
|
||||
config.blur_params.noise = CLAMP_FLOAT(config.blur_params.noise, 0, 1);
|
||||
config.blur_params.brightness =
|
||||
CLAMP_FLOAT(config.blur_params.brightness, 0, 1);
|
||||
config.blur_params.contrast =
|
||||
CLAMP_FLOAT(config.blur_params.contrast, 0, 1);
|
||||
config.blur_params.saturation =
|
||||
CLAMP_FLOAT(config.blur_params.saturation, 0, 1);
|
||||
config.shadows = CLAMP_INT(config.shadows, 0, 1);
|
||||
config.shadow_only_floating = CLAMP_INT(config.shadow_only_floating, 0, 1);
|
||||
config.layer_shadows = CLAMP_INT(config.layer_shadows, 0, 1);
|
||||
config.shadows_size = CLAMP_INT(config.shadows_size, 0, 100);
|
||||
config.shadows_blur = CLAMP_INT(config.shadows_blur, 0, 100);
|
||||
config.shadows_position_x =
|
||||
CLAMP_INT(config.shadows_position_x, -1000, 1000);
|
||||
config.shadows_position_y =
|
||||
CLAMP_INT(config.shadows_position_y, -1000, 1000);
|
||||
config.focused_opacity = CLAMP_FLOAT(config.focused_opacity, 0.0f, 1.0f);
|
||||
config.unfocused_opacity =
|
||||
CLAMP_FLOAT(config.unfocused_opacity, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
void set_value_default() {
|
||||
/* animaion */
|
||||
config.animations = animations; // 是否启用动画
|
||||
config.layer_animations = layer_animations; // 是否启用layer动画
|
||||
config.animation_fade_in = animation_fade_in; // Enable animation fade in
|
||||
config.animation_fade_out = animation_fade_out; // Enable animation fade out
|
||||
config.tag_animation_direction = tag_animation_direction; // 标签动画方向
|
||||
config.zoom_initial_ratio = zoom_initial_ratio; // 动画起始窗口比例
|
||||
config.zoom_end_ratio = zoom_end_ratio; // 动画结束窗口比例
|
||||
config.fadein_begin_opacity =
|
||||
fadein_begin_opacity; // Begin opac window ratio for animations
|
||||
config.fadeout_begin_opacity = fadeout_begin_opacity;
|
||||
config.animation_duration_move =
|
||||
animation_duration_move; // Animation move speed
|
||||
config.animation_duration_open =
|
||||
animation_duration_open; // Animation open speed
|
||||
config.animation_duration_tag =
|
||||
animation_duration_tag; // Animation tag speed
|
||||
config.animation_duration_close =
|
||||
animation_duration_close; // Animation tag speed
|
||||
config.animation_duration_focus =
|
||||
animation_duration_focus; // Animation focus opacity speed
|
||||
config.animations = 1;
|
||||
config.layer_animations = 0;
|
||||
config.animation_fade_in = 1;
|
||||
config.animation_fade_out = 1;
|
||||
config.tag_animation_direction = HORIZONTAL;
|
||||
config.zoom_initial_ratio = 0.3f;
|
||||
config.zoom_end_ratio = 0.8f;
|
||||
config.fadein_begin_opacity = 0.5f;
|
||||
config.fadeout_begin_opacity = 0.5f;
|
||||
config.animation_duration_move = 500;
|
||||
config.animation_duration_open = 400;
|
||||
config.animation_duration_tag = 300;
|
||||
config.animation_duration_close = 300;
|
||||
config.animation_duration_focus = 0;
|
||||
|
||||
/* appearance */
|
||||
config.axis_bind_apply_timeout =
|
||||
axis_bind_apply_timeout; // 滚轮绑定动作的触发的时间间隔
|
||||
config.focus_on_activate =
|
||||
focus_on_activate; // 收到窗口激活请求是否自动跳转聚焦
|
||||
config.new_is_master = new_is_master; // 新窗口是否插在头部
|
||||
config.default_mfact = default_mfact; // master 窗口比例
|
||||
config.default_nmaster = default_nmaster; // 默认master数量
|
||||
config.center_master_overspread =
|
||||
center_master_overspread; // 中心master时是否铺满
|
||||
config.center_when_single_stack =
|
||||
center_when_single_stack; // 单个stack时是否居中
|
||||
config.axis_bind_apply_timeout = 100;
|
||||
config.focus_on_activate = 1;
|
||||
config.new_is_master = 1;
|
||||
config.default_mfact = 0.55f;
|
||||
config.default_nmaster = 1;
|
||||
config.center_master_overspread = 0;
|
||||
config.center_when_single_stack = 1;
|
||||
|
||||
config.numlockon = numlockon; // 是否打开右边小键盘
|
||||
config.log_level = WLR_ERROR;
|
||||
config.numlockon = 0;
|
||||
config.capslock = 0;
|
||||
|
||||
config.ov_tab_mode = ov_tab_mode; // alt tab切换模式
|
||||
config.hotarea_size = hotarea_size; // 热区大小,10x10
|
||||
config.hotarea_corner = hotarea_corner;
|
||||
config.enable_hotarea = enable_hotarea; // 是否启用鼠标热区
|
||||
config.smartgaps = smartgaps; /* 1 means no outer gap when there is
|
||||
only one window */
|
||||
config.sloppyfocus = sloppyfocus; /* focus follows mouse */
|
||||
config.gappih = gappih; /* horiz inner gap between windows */
|
||||
config.gappiv = gappiv; /* vert inner gap between windows */
|
||||
config.gappoh =
|
||||
gappoh; /* horiz outer gap between windows and screen edge */
|
||||
config.gappov = gappov; /* vert outer gap between windows and screen edge */
|
||||
config.scratchpad_width_ratio = scratchpad_width_ratio;
|
||||
config.scratchpad_height_ratio = scratchpad_height_ratio;
|
||||
config.ov_tab_mode = 0;
|
||||
config.hotarea_size = 10;
|
||||
config.hotarea_corner = BOTTOM_LEFT;
|
||||
config.enable_hotarea = 1;
|
||||
config.smartgaps = 0;
|
||||
config.sloppyfocus = 1;
|
||||
config.gappih = 5;
|
||||
config.gappiv = 5;
|
||||
config.gappoh = 10;
|
||||
config.gappov = 10;
|
||||
config.scratchpad_width_ratio = 0.8f;
|
||||
config.scratchpad_height_ratio = 0.9f;
|
||||
|
||||
config.scroller_structs = scroller_structs;
|
||||
config.scroller_default_proportion = scroller_default_proportion;
|
||||
config.scroller_default_proportion_single =
|
||||
scroller_default_proportion_single;
|
||||
config.scroller_ignore_proportion_single =
|
||||
scroller_ignore_proportion_single;
|
||||
config.scroller_focus_center = scroller_focus_center;
|
||||
config.scroller_prefer_center = scroller_prefer_center;
|
||||
config.scroller_prefer_overspread = scroller_prefer_overspread;
|
||||
config.edge_scroller_pointer_focus = edge_scroller_pointer_focus;
|
||||
config.focus_cross_monitor = focus_cross_monitor;
|
||||
config.exchange_cross_monitor = exchange_cross_monitor;
|
||||
config.scratchpad_cross_monitor = scratchpad_cross_monitor;
|
||||
config.focus_cross_tag = focus_cross_tag;
|
||||
config.axis_scroll_factor = axis_scroll_factor;
|
||||
config.view_current_to_back = view_current_to_back;
|
||||
config.single_scratchpad = single_scratchpad;
|
||||
config.xwayland_persistence = xwayland_persistence;
|
||||
config.syncobj_enable = syncobj_enable;
|
||||
config.drag_tile_refresh_interval = drag_tile_refresh_interval;
|
||||
config.drag_floating_refresh_interval = drag_floating_refresh_interval;
|
||||
config.allow_tearing = allow_tearing;
|
||||
config.allow_shortcuts_inhibit = allow_shortcuts_inhibit;
|
||||
config.allow_lock_transparent = allow_lock_transparent;
|
||||
config.no_border_when_single = no_border_when_single;
|
||||
config.no_radius_when_single = no_radius_when_single;
|
||||
config.snap_distance = snap_distance;
|
||||
config.drag_tile_to_tile = drag_tile_to_tile;
|
||||
config.enable_floating_snap = enable_floating_snap;
|
||||
config.swipe_min_threshold = swipe_min_threshold;
|
||||
config.scroller_structs = 20;
|
||||
config.scroller_default_proportion = 0.9f;
|
||||
config.scroller_default_proportion_single = 1.0f;
|
||||
config.scroller_ignore_proportion_single = 1;
|
||||
config.scroller_focus_center = 0;
|
||||
config.scroller_prefer_center = 0;
|
||||
config.scroller_prefer_overspread = 1;
|
||||
config.edge_scroller_pointer_focus = 1;
|
||||
config.focus_cross_monitor = 0;
|
||||
config.exchange_cross_monitor = 0;
|
||||
config.scratchpad_cross_monitor = 0;
|
||||
config.focus_cross_tag = 0;
|
||||
config.axis_scroll_factor = 1.0;
|
||||
config.view_current_to_back = 0;
|
||||
config.single_scratchpad = 1;
|
||||
config.xwayland_persistence = 1;
|
||||
config.syncobj_enable = 0;
|
||||
config.drag_tile_refresh_interval = 8.0f;
|
||||
config.drag_floating_refresh_interval = 8.0f;
|
||||
config.allow_tearing = TEARING_DISABLED;
|
||||
config.allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE;
|
||||
config.allow_lock_transparent = 0;
|
||||
config.no_border_when_single = 0;
|
||||
config.no_radius_when_single = 0;
|
||||
config.snap_distance = 30;
|
||||
config.drag_tile_to_tile = 0;
|
||||
config.enable_floating_snap = 0;
|
||||
config.swipe_min_threshold = 1;
|
||||
|
||||
config.idleinhibit_ignore_visible =
|
||||
idleinhibit_ignore_visible; /* 1 means idle inhibitors will
|
||||
disable idle tracking even if it's
|
||||
surface isn't visible
|
||||
*/
|
||||
config.idleinhibit_ignore_visible = 0;
|
||||
|
||||
config.borderpx = borderpx;
|
||||
config.overviewgappi = overviewgappi; /* overview时 窗口与边缘 缝隙大小 */
|
||||
config.overviewgappo = overviewgappo; /* overview时 窗口与窗口 缝隙大小 */
|
||||
config.cursor_hide_timeout = cursor_hide_timeout;
|
||||
config.borderpx = 4;
|
||||
config.overviewgappi = 5;
|
||||
config.overviewgappo = 30;
|
||||
config.cursor_hide_timeout = 0;
|
||||
|
||||
config.warpcursor = warpcursor; /* Warp cursor to focused client */
|
||||
config.drag_corner = drag_corner;
|
||||
config.drag_warp_cursor = drag_warp_cursor;
|
||||
config.warpcursor = 1;
|
||||
config.drag_corner = 3;
|
||||
config.drag_warp_cursor = 1;
|
||||
|
||||
config.repeat_rate = repeat_rate;
|
||||
config.repeat_delay = repeat_delay;
|
||||
config.repeat_rate = 25;
|
||||
config.repeat_delay = 600;
|
||||
|
||||
/* Trackpad */
|
||||
config.disable_trackpad = disable_trackpad;
|
||||
config.tap_to_click = tap_to_click;
|
||||
config.tap_and_drag = tap_and_drag;
|
||||
config.drag_lock = drag_lock;
|
||||
config.mouse_natural_scrolling = mouse_natural_scrolling;
|
||||
config.cursor_size = cursor_size;
|
||||
config.trackpad_natural_scrolling = trackpad_natural_scrolling;
|
||||
config.disable_while_typing = disable_while_typing;
|
||||
config.left_handed = left_handed;
|
||||
config.middle_button_emulation = middle_button_emulation;
|
||||
config.accel_profile = accel_profile;
|
||||
config.accel_speed = accel_speed;
|
||||
config.scroll_method = scroll_method;
|
||||
config.scroll_button = scroll_button;
|
||||
config.click_method = click_method;
|
||||
config.send_events_mode = send_events_mode;
|
||||
config.button_map = button_map;
|
||||
config.disable_trackpad = 0;
|
||||
config.tap_to_click = 1;
|
||||
config.tap_and_drag = 1;
|
||||
config.drag_lock = 1;
|
||||
config.mouse_natural_scrolling = 0;
|
||||
config.cursor_size = 24;
|
||||
config.trackpad_natural_scrolling = 0;
|
||||
config.disable_while_typing = 1;
|
||||
config.left_handed = 0;
|
||||
config.middle_button_emulation = 0;
|
||||
config.accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
|
||||
config.accel_speed = 0.0;
|
||||
config.scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
|
||||
config.scroll_button = 274;
|
||||
config.click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
|
||||
config.send_events_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
|
||||
config.button_map = LIBINPUT_CONFIG_TAP_MAP_LRM;
|
||||
|
||||
config.blur = blur;
|
||||
config.blur_layer = blur_layer;
|
||||
config.blur_optimized = blur_optimized;
|
||||
config.border_radius = border_radius;
|
||||
config.blur_params.num_passes = blur_params_num_passes;
|
||||
config.blur_params.radius = blur_params_radius;
|
||||
config.blur_params.noise = blur_params_noise;
|
||||
config.blur_params.brightness = blur_params_brightness;
|
||||
config.blur_params.contrast = blur_params_contrast;
|
||||
config.blur_params.saturation = blur_params_saturation;
|
||||
config.shadows = shadows;
|
||||
config.shadow_only_floating = shadow_only_floating;
|
||||
config.layer_shadows = layer_shadows;
|
||||
config.shadows_size = shadows_size;
|
||||
config.shadows_blur = shadows_blur;
|
||||
config.shadows_position_x = shadows_position_x;
|
||||
config.shadows_position_y = shadows_position_y;
|
||||
config.focused_opacity = focused_opacity;
|
||||
config.unfocused_opacity = unfocused_opacity;
|
||||
memcpy(config.shadowscolor, shadowscolor, sizeof(shadowscolor));
|
||||
config.blur = 0;
|
||||
config.blur_layer = 0;
|
||||
config.blur_optimized = 1;
|
||||
config.border_radius = 0;
|
||||
config.border_radius_location_default = CORNER_LOCATION_ALL;
|
||||
config.blur_params.num_passes = 1;
|
||||
config.blur_params.radius = 5;
|
||||
config.blur_params.noise = 0.02f;
|
||||
config.blur_params.brightness = 0.9f;
|
||||
config.blur_params.contrast = 0.9f;
|
||||
config.blur_params.saturation = 1.2f;
|
||||
config.shadows = 0;
|
||||
config.shadow_only_floating = 1;
|
||||
config.layer_shadows = 0;
|
||||
config.shadows_size = 10;
|
||||
config.shadows_blur = 15.0f;
|
||||
config.shadows_position_x = 0;
|
||||
config.shadows_position_y = 0;
|
||||
config.focused_opacity = 1.0f;
|
||||
config.unfocused_opacity = 1.0f;
|
||||
|
||||
memcpy(config.animation_curve_move, animation_curve_move,
|
||||
sizeof(animation_curve_move));
|
||||
memcpy(config.animation_curve_open, animation_curve_open,
|
||||
sizeof(animation_curve_open));
|
||||
memcpy(config.animation_curve_tag, animation_curve_tag,
|
||||
sizeof(animation_curve_tag));
|
||||
memcpy(config.animation_curve_close, animation_curve_close,
|
||||
sizeof(animation_curve_close));
|
||||
memcpy(config.animation_curve_focus, animation_curve_focus,
|
||||
sizeof(animation_curve_focus));
|
||||
memcpy(config.animation_curve_opafadein, animation_curve_opafadein,
|
||||
sizeof(animation_curve_opafadein));
|
||||
memcpy(config.animation_curve_opafadeout, animation_curve_opafadeout,
|
||||
sizeof(animation_curve_opafadeout));
|
||||
config.shadowscolor[0] = 0.0f;
|
||||
config.shadowscolor[1] = 0.0f;
|
||||
config.shadowscolor[2] = 0.0f;
|
||||
config.shadowscolor[3] = 1.0f;
|
||||
|
||||
memcpy(config.rootcolor, rootcolor, sizeof(rootcolor));
|
||||
memcpy(config.bordercolor, bordercolor, sizeof(bordercolor));
|
||||
memcpy(config.focuscolor, focuscolor, sizeof(focuscolor));
|
||||
memcpy(config.maximizescreencolor, maximizescreencolor,
|
||||
sizeof(maximizescreencolor));
|
||||
memcpy(config.urgentcolor, urgentcolor, sizeof(urgentcolor));
|
||||
memcpy(config.scratchpadcolor, scratchpadcolor, sizeof(scratchpadcolor));
|
||||
memcpy(config.globalcolor, globalcolor, sizeof(globalcolor));
|
||||
memcpy(config.overlaycolor, overlaycolor, sizeof(overlaycolor));
|
||||
config.animation_curve_move[0] = 0.46;
|
||||
config.animation_curve_move[1] = 1.0;
|
||||
config.animation_curve_move[2] = 0.29;
|
||||
config.animation_curve_move[3] = 0.99;
|
||||
config.animation_curve_open[0] = 0.46;
|
||||
config.animation_curve_open[1] = 1.0;
|
||||
config.animation_curve_open[2] = 0.29;
|
||||
config.animation_curve_open[3] = 0.99;
|
||||
config.animation_curve_tag[0] = 0.46;
|
||||
config.animation_curve_tag[1] = 1.0;
|
||||
config.animation_curve_tag[2] = 0.29;
|
||||
config.animation_curve_tag[3] = 0.99;
|
||||
config.animation_curve_close[0] = 0.46;
|
||||
config.animation_curve_close[1] = 1.0;
|
||||
config.animation_curve_close[2] = 0.29;
|
||||
config.animation_curve_close[3] = 0.99;
|
||||
config.animation_curve_focus[0] = 0.46;
|
||||
config.animation_curve_focus[1] = 1.0;
|
||||
config.animation_curve_focus[2] = 0.29;
|
||||
config.animation_curve_focus[3] = 0.99;
|
||||
config.animation_curve_opafadein[0] = 0.46;
|
||||
config.animation_curve_opafadein[1] = 1.0;
|
||||
config.animation_curve_opafadein[2] = 0.29;
|
||||
config.animation_curve_opafadein[3] = 0.99;
|
||||
config.animation_curve_opafadeout[0] = 0.5;
|
||||
config.animation_curve_opafadeout[1] = 0.5;
|
||||
config.animation_curve_opafadeout[2] = 0.5;
|
||||
config.animation_curve_opafadeout[3] = 0.5;
|
||||
|
||||
config.rootcolor[0] = 0x32 / 255.0f;
|
||||
config.rootcolor[1] = 0x32 / 255.0f;
|
||||
config.rootcolor[2] = 0x32 / 255.0f;
|
||||
config.rootcolor[3] = 1.0f;
|
||||
config.bordercolor[0] = 0x44 / 255.0f;
|
||||
config.bordercolor[1] = 0x44 / 255.0f;
|
||||
config.bordercolor[2] = 0x44 / 255.0f;
|
||||
config.bordercolor[3] = 1.0f;
|
||||
config.focuscolor[0] = 0xc6 / 255.0f;
|
||||
config.focuscolor[1] = 0x6b / 255.0f;
|
||||
config.focuscolor[2] = 0x25 / 255.0f;
|
||||
config.focuscolor[3] = 1.0f;
|
||||
config.maximizescreencolor[0] = 0x89 / 255.0f;
|
||||
config.maximizescreencolor[1] = 0xaa / 255.0f;
|
||||
config.maximizescreencolor[2] = 0x61 / 255.0f;
|
||||
config.maximizescreencolor[3] = 1.0f;
|
||||
config.urgentcolor[0] = 0xad / 255.0f;
|
||||
config.urgentcolor[1] = 0x40 / 255.0f;
|
||||
config.urgentcolor[2] = 0x1f / 255.0f;
|
||||
config.urgentcolor[3] = 1.0f;
|
||||
config.scratchpadcolor[0] = 0x51 / 255.0f;
|
||||
config.scratchpadcolor[1] = 0x6c / 255.0f;
|
||||
config.scratchpadcolor[2] = 0x93 / 255.0f;
|
||||
config.scratchpadcolor[3] = 1.0f;
|
||||
config.globalcolor[0] = 0xb1 / 255.0f;
|
||||
config.globalcolor[1] = 0x53 / 255.0f;
|
||||
config.globalcolor[2] = 0xa7 / 255.0f;
|
||||
config.globalcolor[3] = 1.0f;
|
||||
config.overlaycolor[0] = 0x14 / 255.0f;
|
||||
config.overlaycolor[1] = 0xa5 / 255.0f;
|
||||
config.overlaycolor[2] = 0x7c / 255.0f;
|
||||
config.overlaycolor[3] = 1.0f;
|
||||
}
|
||||
|
||||
void set_default_key_bindings(Config *config) {
|
||||
|
|
@ -3479,13 +3470,14 @@ bool parse_config(void) {
|
|||
|
||||
free_config();
|
||||
|
||||
// 重置config结构体,确保所有指针初始化为NULL
|
||||
memset(&config, 0, sizeof(config));
|
||||
memset(&xkb_rules_rules, 0, sizeof(xkb_rules_rules));
|
||||
memset(&xkb_rules_model, 0, sizeof(xkb_rules_model));
|
||||
memset(&xkb_rules_layout, 0, sizeof(xkb_rules_layout));
|
||||
memset(&xkb_rules_variant, 0, sizeof(xkb_rules_variant));
|
||||
memset(&xkb_rules_options, 0, sizeof(xkb_rules_options));
|
||||
|
||||
// 重新将xkb_rules指针指向静态数组
|
||||
config.xkb_rules.layout = config.xkb_rules_layout;
|
||||
config.xkb_rules.variant = config.xkb_rules_variant;
|
||||
config.xkb_rules.options = config.xkb_rules_options;
|
||||
config.xkb_rules.rules = config.xkb_rules_rules;
|
||||
config.xkb_rules.model = config.xkb_rules_model;
|
||||
|
||||
// 初始化动态数组的指针为NULL,避免野指针
|
||||
config.window_rules = NULL;
|
||||
|
|
@ -3549,7 +3541,7 @@ bool parse_config(void) {
|
|||
}
|
||||
|
||||
void reset_blur_params(void) {
|
||||
if (blur) {
|
||||
if (config.blur) {
|
||||
Monitor *m = NULL;
|
||||
wl_list_for_each(m, &mons, link) {
|
||||
if (m->blur != NULL) {
|
||||
|
|
@ -3559,9 +3551,9 @@ void reset_blur_params(void) {
|
|||
wlr_scene_node_reparent(&m->blur->node, layers[LyrBlur]);
|
||||
wlr_scene_optimized_blur_set_size(m->blur, m->m.width, m->m.height);
|
||||
wlr_scene_set_blur_data(
|
||||
scene, blur_params.num_passes, blur_params.radius,
|
||||
blur_params.noise, blur_params.brightness, blur_params.contrast,
|
||||
blur_params.saturation);
|
||||
scene, config.blur_params.num_passes, config.blur_params.radius,
|
||||
config.blur_params.noise, config.blur_params.brightness,
|
||||
config.blur_params.contrast, config.blur_params.saturation);
|
||||
}
|
||||
} else {
|
||||
Monitor *m = NULL;
|
||||
|
|
@ -3612,6 +3604,20 @@ void reapply_monitor_rules(void) {
|
|||
updatemons(NULL, NULL);
|
||||
}
|
||||
|
||||
void set_xcursor_env() {
|
||||
if (config.cursor_size > 0) {
|
||||
char size_str[16];
|
||||
snprintf(size_str, sizeof(size_str), "%d", config.cursor_size);
|
||||
setenv("XCURSOR_SIZE", size_str, 1);
|
||||
} else {
|
||||
setenv("XCURSOR_SIZE", "24", 1);
|
||||
}
|
||||
|
||||
if (config.cursor_theme) {
|
||||
setenv("XCURSOR_THEME", config.cursor_theme, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void reapply_cursor_style(void) {
|
||||
if (hide_cursor_source) {
|
||||
wl_event_source_timer_update(hide_cursor_source, 0);
|
||||
|
|
@ -3628,17 +3634,10 @@ void reapply_cursor_style(void) {
|
|||
cursor_mgr = NULL;
|
||||
}
|
||||
|
||||
cursor_mgr = wlr_xcursor_manager_create(config.cursor_theme, cursor_size);
|
||||
set_xcursor_env();
|
||||
|
||||
if (cursor_size > 0) {
|
||||
char size_str[16];
|
||||
snprintf(size_str, sizeof(size_str), "%d", cursor_size);
|
||||
setenv("XCURSOR_SIZE", size_str, 1);
|
||||
}
|
||||
|
||||
if (config.cursor_theme) {
|
||||
setenv("XCURSOR_THEME", config.cursor_theme, 1);
|
||||
}
|
||||
cursor_mgr =
|
||||
wlr_xcursor_manager_create(config.cursor_theme, config.cursor_size);
|
||||
|
||||
Monitor *m = NULL;
|
||||
wl_list_for_each(m, &mons, link) {
|
||||
|
|
@ -3653,11 +3652,13 @@ void reapply_cursor_style(void) {
|
|||
wlr_cursor_unset_image(cursor);
|
||||
} else {
|
||||
wl_event_source_timer_update(hide_cursor_source,
|
||||
cursor_hide_timeout * 1000);
|
||||
config.cursor_hide_timeout * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
void reapply_rootbg(void) { wlr_scene_rect_set_color(root_bg, rootcolor); }
|
||||
void reapply_rootbg(void) {
|
||||
wlr_scene_rect_set_color(root_bg, config.rootcolor);
|
||||
}
|
||||
|
||||
void reapply_border(void) {
|
||||
Client *c = NULL;
|
||||
|
|
@ -3666,7 +3667,7 @@ void reapply_border(void) {
|
|||
wl_list_for_each(c, &clients, link) {
|
||||
if (c && !c->iskilling) {
|
||||
if (!c->isnoborder && !c->isfullscreen) {
|
||||
c->bw = borderpx;
|
||||
c->bw = config.borderpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3679,7 +3680,7 @@ void reapply_keyboard(void) {
|
|||
continue;
|
||||
}
|
||||
wlr_keyboard_set_repeat_info((struct wlr_keyboard *)id->device_data,
|
||||
repeat_rate, repeat_delay);
|
||||
config.repeat_rate, config.repeat_delay);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3708,12 +3709,12 @@ void reapply_master(void) {
|
|||
if (!m->wlr_output->enabled) {
|
||||
continue;
|
||||
}
|
||||
m->pertag->nmasters[i] = default_nmaster;
|
||||
m->pertag->mfacts[i] = default_mfact;
|
||||
m->gappih = gappih;
|
||||
m->gappiv = gappiv;
|
||||
m->gappoh = gappoh;
|
||||
m->gappov = gappov;
|
||||
m->pertag->nmasters[i] = config.default_nmaster;
|
||||
m->pertag->mfacts[i] = config.default_mfact;
|
||||
m->gappih = config.gappih;
|
||||
m->gappiv = config.gappiv;
|
||||
m->gappoh = config.gappoh;
|
||||
m->gappov = config.gappov;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3725,8 +3726,8 @@ void parse_tagrule(Monitor *m) {
|
|||
bool match_rule = false;
|
||||
|
||||
for (i = 0; i <= LENGTH(tags); i++) {
|
||||
m->pertag->nmasters[i] = default_nmaster;
|
||||
m->pertag->mfacts[i] = default_mfact;
|
||||
m->pertag->nmasters[i] = config.default_nmaster;
|
||||
m->pertag->mfacts[i] = config.default_mfact;
|
||||
}
|
||||
|
||||
for (i = 0; i < config.tag_rules_count; i++) {
|
||||
|
|
|
|||
|
|
@ -1,132 +1,9 @@
|
|||
// TODO: remove this file in the future, replace all global variables with
|
||||
// config.xxx
|
||||
#define MODKEY WLR_MODIFIER_ALT
|
||||
|
||||
/* speedie's mango config */
|
||||
static const char *tags[] = {
|
||||
"1", "2", "3", "4", "5", "6", "7", "8", "9",
|
||||
};
|
||||
|
||||
#define COLOR(hex) \
|
||||
{((hex >> 24) & 0xFF) / 255.0f, ((hex >> 16) & 0xFF) / 255.0f, \
|
||||
((hex >> 8) & 0xFF) / 255.0f, (hex & 0xFF) / 255.0f}
|
||||
|
||||
/* animaion */
|
||||
char *animation_type_open = "slide"; // 是否启用动画 //slide,zoom
|
||||
char *animation_type_close = "slide"; // 是否启用动画 //slide,zoom
|
||||
char *layer_animation_type_open = "slide"; // 是否启用layer动画 //slide,zoom
|
||||
char *layer_animation_type_close = "slide"; // 是否启用layer动画 //slide,zoom
|
||||
int32_t animations = 1; // 是否启用动画
|
||||
int32_t layer_animations = 0; // 是否启用layer动画
|
||||
int32_t tag_animation_direction = HORIZONTAL; // 标签动画方向
|
||||
int32_t animation_fade_in = 1; // Enable animation fade in
|
||||
int32_t animation_fade_out = 1; // Enable animation fade out
|
||||
float zoom_initial_ratio = 0.3; // 动画起始窗口比例
|
||||
float zoom_end_ratio = 0.8; // 动画结束窗口比例
|
||||
float fadein_begin_opacity = 0.5; // Begin opac window ratio for animations
|
||||
float fadeout_begin_opacity = 0.5; // Begin opac window ratio for animations
|
||||
uint32_t animation_duration_move = 500; // Animation move speed
|
||||
uint32_t animation_duration_open = 400; // Animation open speed
|
||||
uint32_t animation_duration_tag = 300; // Animation tag speed
|
||||
uint32_t animation_duration_close = 300; // Animation close speed
|
||||
uint32_t animation_duration_focus = 0; // Animation focus opacity speed
|
||||
double animation_curve_move[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线
|
||||
double animation_curve_open[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线
|
||||
double animation_curve_tag[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线
|
||||
double animation_curve_close[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线
|
||||
double animation_curve_focus[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线
|
||||
double animation_curve_opafadein[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线
|
||||
double animation_curve_opafadeout[4] = {0.5, 0.5, 0.5, 0.5}; // 动画曲线
|
||||
|
||||
/* appearance */
|
||||
uint32_t axis_bind_apply_timeout = 100; // 滚轮绑定动作的触发的时间间隔
|
||||
uint32_t focus_on_activate = 1; // 收到窗口激活请求是否自动跳转聚焦
|
||||
uint32_t new_is_master = 1; // 新窗口是否插在头部
|
||||
double default_mfact = 0.55f; // master 窗口比例
|
||||
uint32_t default_nmaster = 1; // 默认master数量
|
||||
int32_t center_master_overspread = 0; // 中心master时是否铺满
|
||||
int32_t center_when_single_stack = 1; // 单个stack时是否居中
|
||||
/* logging */
|
||||
int32_t log_level = WLR_ERROR;
|
||||
uint32_t numlockon = 0; // 是否打开右边小键盘
|
||||
uint32_t capslock = 0; // 是否启用快捷键
|
||||
|
||||
uint32_t ov_tab_mode = 0; // alt tab切换模式
|
||||
uint32_t hotarea_size = 10; // 热区大小,10x10
|
||||
uint32_t hotarea_corner = BOTTOM_LEFT;
|
||||
uint32_t enable_hotarea = 1; // 是否启用鼠标热区
|
||||
int32_t smartgaps = 0; /* 1 means no outer gap when there is only one window */
|
||||
int32_t sloppyfocus = 1; /* focus follows mouse */
|
||||
uint32_t gappih = 5; /* horiz inner gap between windows */
|
||||
uint32_t gappiv = 5; /* vert inner gap between windows */
|
||||
uint32_t gappoh = 10; /* horiz outer gap between windows and screen edge */
|
||||
uint32_t gappov = 10; /* vert outer gap between windows and screen edge */
|
||||
float scratchpad_width_ratio = 0.8;
|
||||
float scratchpad_height_ratio = 0.9;
|
||||
|
||||
int32_t scroller_structs = 20;
|
||||
float scroller_default_proportion = 0.9;
|
||||
float scroller_default_proportion_single = 1.0;
|
||||
int32_t scroller_ignore_proportion_single = 1;
|
||||
int32_t scroller_focus_center = 0;
|
||||
int32_t scroller_prefer_center = 0;
|
||||
int32_t scroller_prefer_overspread = 1;
|
||||
int32_t focus_cross_monitor = 0;
|
||||
int32_t focus_cross_tag = 0;
|
||||
int32_t exchange_cross_monitor = 0;
|
||||
int32_t scratchpad_cross_monitor = 0;
|
||||
int32_t view_current_to_back = 0;
|
||||
int32_t no_border_when_single = 0;
|
||||
int32_t no_radius_when_single = 0;
|
||||
int32_t snap_distance = 30;
|
||||
int32_t enable_floating_snap = 0;
|
||||
int32_t drag_tile_to_tile = 0;
|
||||
uint32_t cursor_size = 24;
|
||||
uint32_t cursor_hide_timeout = 0;
|
||||
|
||||
uint32_t swipe_min_threshold = 1;
|
||||
|
||||
int32_t idleinhibit_ignore_visible =
|
||||
0; /* 1 means idle inhibitors will disable idle tracking even if it's
|
||||
surface isn't visible */
|
||||
uint32_t borderpx = 4; /* border pixel of windows */
|
||||
float rootcolor[] = COLOR(0x323232ff);
|
||||
float bordercolor[] = COLOR(0x444444ff);
|
||||
float focuscolor[] = COLOR(0xc66b25ff);
|
||||
float maximizescreencolor[] = COLOR(0x89aa61ff);
|
||||
float urgentcolor[] = COLOR(0xad401fff);
|
||||
float scratchpadcolor[] = COLOR(0x516c93ff);
|
||||
float globalcolor[] = COLOR(0xb153a7ff);
|
||||
float overlaycolor[] = COLOR(0x14a57cff);
|
||||
// char *cursor_theme = "Bibata-Modern-Ice";
|
||||
|
||||
int32_t overviewgappi = 5; /* overview时 窗口与边缘 缝隙大小 */
|
||||
int32_t overviewgappo = 30; /* overview时 窗口与窗口 缝隙大小 */
|
||||
|
||||
/* To conform the xdg-protocol, set the alpha to zero to restore the old
|
||||
* behavior */
|
||||
float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0};
|
||||
|
||||
int32_t warpcursor = 1;
|
||||
int32_t drag_corner = 3;
|
||||
int32_t drag_warp_cursor = 1;
|
||||
int32_t xwayland_persistence = 1; /* xwayland persistence */
|
||||
int32_t syncobj_enable = 0;
|
||||
int32_t allow_lock_transparent = 0;
|
||||
double drag_tile_refresh_interval = 8.0;
|
||||
double drag_floating_refresh_interval = 8.0;
|
||||
int32_t allow_tearing = TEARING_DISABLED;
|
||||
int32_t allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE;
|
||||
|
||||
/* keyboard */
|
||||
|
||||
/*
|
||||
only layout can modify after fisrt init
|
||||
other fields change will be ignored.
|
||||
*/
|
||||
char xkb_rules_rules[256];
|
||||
char xkb_rules_model[256];
|
||||
char xkb_rules_layout[256];
|
||||
char xkb_rules_variant[256];
|
||||
char xkb_rules_options[256];
|
||||
|
||||
/* keyboard */
|
||||
static const struct xkb_rule_names xkb_fallback_rules = {
|
||||
.layout = "us",
|
||||
.variant = NULL,
|
||||
|
|
@ -134,106 +11,3 @@ static const struct xkb_rule_names xkb_fallback_rules = {
|
|||
.rules = NULL,
|
||||
.options = NULL,
|
||||
};
|
||||
|
||||
static const struct xkb_rule_names xkb_default_rules = {
|
||||
.options = NULL,
|
||||
};
|
||||
|
||||
struct xkb_rule_names xkb_rules = {
|
||||
/* can specify fields: rules, model, layout, variant, options */
|
||||
/* example:
|
||||
.options = "ctrl:nocaps",
|
||||
*/
|
||||
.rules = xkb_rules_rules, .model = xkb_rules_model,
|
||||
.layout = xkb_rules_layout, .variant = xkb_rules_variant,
|
||||
.options = xkb_rules_options,
|
||||
};
|
||||
|
||||
int32_t repeat_rate = 25;
|
||||
int32_t repeat_delay = 600;
|
||||
|
||||
/* Trackpad */
|
||||
int32_t disable_trackpad = 0;
|
||||
int32_t tap_to_click = 1;
|
||||
int32_t tap_and_drag = 1;
|
||||
int32_t drag_lock = 1;
|
||||
int32_t mouse_natural_scrolling = 0;
|
||||
int32_t trackpad_natural_scrolling = 0;
|
||||
int32_t disable_while_typing = 1;
|
||||
int32_t left_handed = 0;
|
||||
int32_t middle_button_emulation = 0;
|
||||
int32_t single_scratchpad = 1;
|
||||
int32_t edge_scroller_pointer_focus = 1;
|
||||
|
||||
/* You can choose between:
|
||||
LIBINPUT_CONFIG_SCROLL_NO_SCROLL
|
||||
LIBINPUT_CONFIG_SCROLL_2FG
|
||||
LIBINPUT_CONFIG_SCROLL_EDGE
|
||||
LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN
|
||||
*/
|
||||
enum libinput_config_scroll_method scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
|
||||
uint32_t scroll_button = 274;
|
||||
|
||||
/* You can choose between:
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_NONE
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER
|
||||
*/
|
||||
enum libinput_config_click_method click_method =
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
|
||||
|
||||
double axis_scroll_factor = 1.0;
|
||||
|
||||
/* You can choose between:
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_ENABLED
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE
|
||||
*/
|
||||
uint32_t send_events_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
|
||||
|
||||
/* You can choose between:
|
||||
LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT
|
||||
LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE
|
||||
*/
|
||||
enum libinput_config_accel_profile accel_profile =
|
||||
LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
|
||||
double accel_speed = 0.0;
|
||||
/* You can choose between:
|
||||
LIBINPUT_CONFIG_TAP_MAP_LRM -- 1/2/3 finger tap maps to left/right/middle
|
||||
LIBINPUT_CONFIG_TAP_MAP_LMR -- 1/2/3 finger tap maps to left/middle/right
|
||||
*/
|
||||
enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TAP_MAP_LRM;
|
||||
|
||||
/* If you want to use the windows key for MODKEY, use WLR_MODIFIER_LOGO */
|
||||
#define MODKEY WLR_MODIFIER_ALT
|
||||
|
||||
static const char *tags[] = {
|
||||
"1", "2", "3", "4", "5", "6", "7", "8", "9",
|
||||
};
|
||||
|
||||
float focused_opacity = 1.0;
|
||||
float unfocused_opacity = 1.0;
|
||||
|
||||
int32_t border_radius = 0;
|
||||
int32_t border_radius_location_default = CORNER_LOCATION_ALL;
|
||||
int32_t blur = 0;
|
||||
int32_t blur_layer = 0;
|
||||
int32_t blur_optimized = 1;
|
||||
|
||||
struct blur_data blur_params;
|
||||
|
||||
int32_t blur_params_num_passes = 1;
|
||||
int32_t blur_params_radius = 5;
|
||||
float blur_params_noise = 0.02;
|
||||
float blur_params_brightness = 0.9;
|
||||
float blur_params_contrast = 0.9;
|
||||
float blur_params_saturation = 1.2;
|
||||
|
||||
int32_t shadows = 0;
|
||||
int32_t shadow_only_floating = 1;
|
||||
int32_t layer_shadows = 0;
|
||||
uint32_t shadows_size = 10;
|
||||
double shadows_blur = 15;
|
||||
int32_t shadows_position_x = 0;
|
||||
int32_t shadows_position_y = 0;
|
||||
float shadowscolor[] = COLOR(0x000000ff);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ int32_t bind_to_view(const Arg *arg) {
|
|||
return 0;
|
||||
uint32_t target = arg->ui;
|
||||
|
||||
if (view_current_to_back && selmon->pertag->curtag &&
|
||||
if (config.view_current_to_back && selmon->pertag->curtag &&
|
||||
(target & TAGMASK) == (selmon->tagset[selmon->seltags])) {
|
||||
if (selmon->pertag->prevtag)
|
||||
target = 1 << (selmon->pertag->prevtag - 1);
|
||||
|
|
@ -11,13 +11,13 @@ int32_t bind_to_view(const Arg *arg) {
|
|||
target = 0;
|
||||
}
|
||||
|
||||
if (!view_current_to_back &&
|
||||
if (!config.view_current_to_back &&
|
||||
(target & TAGMASK) == (selmon->tagset[selmon->seltags])) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((int32_t)target == INT_MIN && selmon->pertag->curtag == 0) {
|
||||
if (view_current_to_back && selmon->pertag->prevtag)
|
||||
if (config.view_current_to_back && selmon->pertag->prevtag)
|
||||
target = 1 << (selmon->pertag->prevtag - 1);
|
||||
else
|
||||
target = 0;
|
||||
|
|
@ -96,7 +96,7 @@ int32_t destroy_all_virtual_output(const Arg *arg) {
|
|||
}
|
||||
|
||||
int32_t defaultgaps(const Arg *arg) {
|
||||
setgaps(gappoh, gappov, gappih, gappiv);
|
||||
setgaps(config.gappoh, config.gappov, config.gappih, config.gappiv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -140,7 +140,7 @@ int32_t focusdir(const Arg *arg) {
|
|||
c = get_focused_stack_client(c);
|
||||
if (c) {
|
||||
focusclient(c, 1);
|
||||
if (warpcursor)
|
||||
if (config.warpcursor)
|
||||
warp_cursor(c);
|
||||
} else {
|
||||
if (config.focus_cross_tag) {
|
||||
|
|
@ -196,7 +196,7 @@ int32_t focuslast(const Arg *arg) {
|
|||
}
|
||||
|
||||
int32_t toggle_trackpad_enable(const Arg *arg) {
|
||||
disable_trackpad = !disable_trackpad;
|
||||
config.disable_trackpad = !config.disable_trackpad;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -225,7 +225,7 @@ int32_t focusmon(const Arg *arg) {
|
|||
return 0;
|
||||
|
||||
selmon = tm;
|
||||
if (warpcursor) {
|
||||
if (config.warpcursor) {
|
||||
warp_cursor_to_selmon(selmon);
|
||||
}
|
||||
c = focustop(selmon);
|
||||
|
|
@ -258,7 +258,7 @@ int32_t focusstack(const Arg *arg) {
|
|||
return 0;
|
||||
|
||||
focusclient(tc, 1);
|
||||
if (warpcursor)
|
||||
if (config.warpcursor)
|
||||
warp_cursor(tc);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -390,7 +390,7 @@ int32_t moveresize(const Arg *arg) {
|
|||
/* Doesn't work for X11 output - the next absolute motion event
|
||||
* returns the cursor to where it started */
|
||||
if (grabc->isfloating) {
|
||||
rzcorner = drag_corner;
|
||||
rzcorner = config.drag_corner;
|
||||
grabcx = (int)round(cursor->x);
|
||||
grabcy = (int)round(cursor->y);
|
||||
if (rzcorner == 4)
|
||||
|
|
@ -404,7 +404,7 @@ int32_t moveresize(const Arg *arg) {
|
|||
? 0
|
||||
: 2);
|
||||
|
||||
if (drag_warp_cursor) {
|
||||
if (config.drag_warp_cursor) {
|
||||
grabcx = rzcorner & 1 ? grabc->geom.x + grabc->geom.width
|
||||
: grabc->geom.x;
|
||||
grabcy = rzcorner & 2 ? grabc->geom.y + grabc->geom.height
|
||||
|
|
@ -476,9 +476,9 @@ int32_t resizewin(const Arg *arg) {
|
|||
if (!c || c->isfullscreen || c->ismaximizescreen)
|
||||
return 0;
|
||||
|
||||
int32_t animations_state_backup = animations;
|
||||
int32_t animations_state_backup = config.animations;
|
||||
if (!c->isfloating)
|
||||
animations = 0;
|
||||
config.animations = 0;
|
||||
|
||||
if (ISTILED(c)) {
|
||||
switch (arg->ui) {
|
||||
|
|
@ -505,7 +505,7 @@ int32_t resizewin(const Arg *arg) {
|
|||
break;
|
||||
}
|
||||
resize_tile_client(c, false, offsetx, offsety, 0);
|
||||
animations = animations_state_backup;
|
||||
config.animations = animations_state_backup;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -536,7 +536,7 @@ int32_t resizewin(const Arg *arg) {
|
|||
c->iscustomsize = 1;
|
||||
c->float_geom = c->geom;
|
||||
resize(c, c->geom, 0);
|
||||
animations = animations_state_backup;
|
||||
config.animations = animations_state_backup;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -608,7 +608,7 @@ int32_t set_proportion(const Arg *arg) {
|
|||
return 0;
|
||||
|
||||
if (selmon->visible_tiling_clients == 1 &&
|
||||
!scroller_ignore_proportion_single)
|
||||
!config.scroller_ignore_proportion_single)
|
||||
return 0;
|
||||
|
||||
Client *tc = selmon->sel;
|
||||
|
|
@ -616,7 +616,7 @@ int32_t set_proportion(const Arg *arg) {
|
|||
if (tc) {
|
||||
tc = get_scroll_stack_head(tc);
|
||||
uint32_t max_client_width =
|
||||
selmon->w.width - 2 * scroller_structs - gappih;
|
||||
selmon->w.width - 2 * config.scroller_structs - config.gappih;
|
||||
tc->scroller_proportion = arg->f;
|
||||
tc->geom.width = max_client_width * arg->f;
|
||||
arrange(selmon, false, false);
|
||||
|
|
@ -650,7 +650,7 @@ int32_t smartmovewin(const Arg *arg) {
|
|||
if (c->geom.x + c->geom.width < tc->geom.x ||
|
||||
c->geom.x > tc->geom.x + tc->geom.width)
|
||||
continue;
|
||||
buttom = tc->geom.y + tc->geom.height + gappiv;
|
||||
buttom = tc->geom.y + tc->geom.height + config.gappiv;
|
||||
if (top > buttom && ny < buttom) {
|
||||
tar = MAX(tar, buttom);
|
||||
};
|
||||
|
|
@ -670,7 +670,7 @@ int32_t smartmovewin(const Arg *arg) {
|
|||
if (c->geom.x + c->geom.width < tc->geom.x ||
|
||||
c->geom.x > tc->geom.x + tc->geom.width)
|
||||
continue;
|
||||
top = tc->geom.y - gappiv;
|
||||
top = tc->geom.y - config.gappiv;
|
||||
if (buttom < top && (ny + c->geom.height) > top) {
|
||||
tar = MIN(tar, top - c->geom.height);
|
||||
};
|
||||
|
|
@ -690,7 +690,7 @@ int32_t smartmovewin(const Arg *arg) {
|
|||
if (c->geom.y + c->geom.height < tc->geom.y ||
|
||||
c->geom.y > tc->geom.y + tc->geom.height)
|
||||
continue;
|
||||
right = tc->geom.x + tc->geom.width + gappih;
|
||||
right = tc->geom.x + tc->geom.width + config.gappih;
|
||||
if (left > right && nx < right) {
|
||||
tar = MAX(tar, right);
|
||||
};
|
||||
|
|
@ -709,7 +709,7 @@ int32_t smartmovewin(const Arg *arg) {
|
|||
if (c->geom.y + c->geom.height < tc->geom.y ||
|
||||
c->geom.y > tc->geom.y + tc->geom.height)
|
||||
continue;
|
||||
left = tc->geom.x - gappih;
|
||||
left = tc->geom.x - config.gappih;
|
||||
if (right < left && (nx + c->geom.width) > left) {
|
||||
tar = MIN(tar, left - c->geom.width);
|
||||
};
|
||||
|
|
@ -757,14 +757,14 @@ int32_t smartresizewin(const Arg *arg) {
|
|||
if (c->geom.x + c->geom.width < tc->geom.x ||
|
||||
c->geom.x > tc->geom.x + tc->geom.width)
|
||||
continue;
|
||||
top = tc->geom.y - gappiv;
|
||||
top = tc->geom.y - config.gappiv;
|
||||
if (buttom < top && (nh + c->geom.y) > top) {
|
||||
tar = MAX(tar, top - c->geom.y);
|
||||
};
|
||||
}
|
||||
nh = tar == -99999 ? nh : tar;
|
||||
if (c->geom.y + nh + gappov > selmon->w.y + selmon->w.height)
|
||||
nh = selmon->w.y + selmon->w.height - c->geom.y - gappov;
|
||||
if (c->geom.y + nh + config.gappov > selmon->w.y + selmon->w.height)
|
||||
nh = selmon->w.y + selmon->w.height - c->geom.y - config.gappov;
|
||||
break;
|
||||
case LEFT:
|
||||
nw -= selmon->w.width / 16;
|
||||
|
|
@ -780,15 +780,15 @@ int32_t smartresizewin(const Arg *arg) {
|
|||
if (c->geom.y + c->geom.height < tc->geom.y ||
|
||||
c->geom.y > tc->geom.y + tc->geom.height)
|
||||
continue;
|
||||
left = tc->geom.x - gappih;
|
||||
left = tc->geom.x - config.gappih;
|
||||
if (right < left && (nw + c->geom.x) > left) {
|
||||
tar = MIN(tar, left - c->geom.x);
|
||||
};
|
||||
}
|
||||
|
||||
nw = tar == 99999 ? nw : tar;
|
||||
if (c->geom.x + nw + gappoh > selmon->w.x + selmon->w.width)
|
||||
nw = selmon->w.x + selmon->w.width - c->geom.x - gappoh;
|
||||
if (c->geom.x + nw + config.gappoh > selmon->w.x + selmon->w.width)
|
||||
nw = selmon->w.x + selmon->w.width - c->geom.x - config.gappoh;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1046,7 +1046,7 @@ int32_t switch_proportion_preset(const Arg *arg) {
|
|||
return 0;
|
||||
|
||||
if (selmon->visible_tiling_clients == 1 &&
|
||||
!scroller_ignore_proportion_single)
|
||||
!config.scroller_ignore_proportion_single)
|
||||
return 0;
|
||||
|
||||
Client *tc = selmon->sel;
|
||||
|
|
@ -1087,7 +1087,7 @@ int32_t switch_proportion_preset(const Arg *arg) {
|
|||
}
|
||||
|
||||
uint32_t max_client_width =
|
||||
selmon->w.width - 2 * scroller_structs - gappih;
|
||||
selmon->w.width - 2 * config.scroller_structs - config.gappih;
|
||||
tc->scroller_proportion = target_proportion;
|
||||
tc->geom.width = max_client_width * target_proportion;
|
||||
arrange(selmon, false, false);
|
||||
|
|
@ -1170,7 +1170,7 @@ int32_t tagmon(const Arg *arg) {
|
|||
focusclient(c, 1);
|
||||
arrange(selmon, false, false);
|
||||
}
|
||||
if (warpcursor) {
|
||||
if (config.warpcursor) {
|
||||
warp_cursor_to_selmon(c->mon);
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -1257,11 +1257,12 @@ int32_t toggle_scratchpad(const Arg *arg) {
|
|||
return 0;
|
||||
|
||||
wl_list_for_each_safe(c, tmp, &clients, link) {
|
||||
if (!scratchpad_cross_monitor && c->mon != selmon) {
|
||||
if (!config.scratchpad_cross_monitor && c->mon != selmon) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (single_scratchpad && c->isnamedscratchpad && !c->isminimized) {
|
||||
if (config.single_scratchpad && c->isnamedscratchpad &&
|
||||
!c->isminimized) {
|
||||
set_minimized(c);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1662,7 +1663,8 @@ int32_t toggleoverview(const Arg *arg) {
|
|||
if (!selmon)
|
||||
return 0;
|
||||
|
||||
if (selmon->isoverview && ov_tab_mode && arg->i != 1 && selmon->sel) {
|
||||
if (selmon->isoverview && config.ov_tab_mode && arg->i != 1 &&
|
||||
selmon->sel) {
|
||||
focusstack(&(Arg){.i = 1});
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ void handle_tearing_new_object(struct wl_listener *listener, void *data) {
|
|||
|
||||
bool check_tearing_frame_allow(Monitor *m) {
|
||||
/* never allow tearing when disabled */
|
||||
if (!allow_tearing) {
|
||||
if (!config.allow_tearing) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ bool check_tearing_frame_allow(Monitor *m) {
|
|||
}
|
||||
|
||||
/* allow tearing for any window when requested or forced */
|
||||
if (allow_tearing == TEARING_ENABLED) {
|
||||
if (config.allow_tearing == TEARING_ENABLED) {
|
||||
if (c->force_tearing == STATE_UNSPECIFIED) {
|
||||
return c->tearing_hint;
|
||||
} else {
|
||||
|
|
@ -87,7 +87,8 @@ bool check_tearing_frame_allow(Monitor *m) {
|
|||
|
||||
if (c->force_tearing == STATE_UNSPECIFIED) {
|
||||
/* honor the tearing hint or the fullscreen-force preference */
|
||||
return c->tearing_hint || allow_tearing == TEARING_FULLSCREEN_ONLY;
|
||||
return c->tearing_hint ||
|
||||
config.allow_tearing == TEARING_FULLSCREEN_ONLY;
|
||||
}
|
||||
|
||||
/* honor tearing as requested by action */
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ bool check_hit_no_border(Client *c) {
|
|||
}
|
||||
}
|
||||
|
||||
if (no_border_when_single && c && c->mon &&
|
||||
if (config.no_border_when_single && c && c->mon &&
|
||||
((ISSCROLLTILED(c) && c->mon->visible_scroll_tiling_clients == 1) ||
|
||||
c->mon->visible_clients == 1)) {
|
||||
hit_no_border = true;
|
||||
|
|
@ -39,7 +39,7 @@ Client *get_client_by_id_or_title(const char *arg_id, const char *arg_title) {
|
|||
const char *appid, *title;
|
||||
Client *c = NULL;
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (!scratchpad_cross_monitor && c->mon != selmon) {
|
||||
if (!config.scratchpad_cross_monitor && c->mon != selmon) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -167,7 +167,7 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating,
|
|||
// 第一次遍历,计算客户端数量
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (c && (findfloating || !c->isfloating) && !c->isunglobal &&
|
||||
(focus_cross_monitor || c->mon == tc->mon) &&
|
||||
(config.focus_cross_monitor || c->mon == tc->mon) &&
|
||||
(c->tags & c->mon->tagset[c->mon->seltags])) {
|
||||
last++;
|
||||
}
|
||||
|
|
@ -188,7 +188,7 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating,
|
|||
last = -1;
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (c && (findfloating || !c->isfloating) && !c->isunglobal &&
|
||||
(focus_cross_monitor || c->mon == tc->mon) &&
|
||||
(config.focus_cross_monitor || c->mon == tc->mon) &&
|
||||
(c->tags & c->mon->tagset[c->mon->seltags])) {
|
||||
last++;
|
||||
tempClients[last] = c;
|
||||
|
|
@ -511,21 +511,21 @@ Client *get_next_stack_client(Client *c, bool reverse) {
|
|||
float *get_border_color(Client *c) {
|
||||
|
||||
if (c->mon != selmon) {
|
||||
return bordercolor;
|
||||
return config.bordercolor;
|
||||
} else if (c->isurgent) {
|
||||
return urgentcolor;
|
||||
return config.urgentcolor;
|
||||
} else if (c->is_in_scratchpad && selmon && c == selmon->sel) {
|
||||
return scratchpadcolor;
|
||||
return config.scratchpadcolor;
|
||||
} else if (c->isglobal && selmon && c == selmon->sel) {
|
||||
return globalcolor;
|
||||
return config.globalcolor;
|
||||
} else if (c->isoverlay && selmon && c == selmon->sel) {
|
||||
return overlaycolor;
|
||||
return config.overlaycolor;
|
||||
} else if (c->ismaximizescreen && selmon && c == selmon->sel) {
|
||||
return maximizescreencolor;
|
||||
return config.maximizescreencolor;
|
||||
} else if (selmon && c == selmon->sel) {
|
||||
return focuscolor;
|
||||
return config.focuscolor;
|
||||
} else {
|
||||
return bordercolor;
|
||||
return config.bordercolor;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@ void restore_size_per(Monitor *m, Client *c) {
|
|||
if (!m || !c)
|
||||
return;
|
||||
|
||||
if (!m->wlr_output->enabled)
|
||||
return;
|
||||
|
||||
wl_list_for_each(fc, &clients, link) {
|
||||
if (VISIBLEON(fc, m) && ISTILED(fc)) {
|
||||
fc->old_ismaster = fc->ismaster;
|
||||
|
|
@ -309,7 +312,7 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int32_t offsetx,
|
|||
}
|
||||
|
||||
if (last_apply_drap_time == 0 ||
|
||||
time - last_apply_drap_time > drag_tile_refresh_interval) {
|
||||
time - last_apply_drap_time > config.drag_tile_refresh_interval) {
|
||||
arrange(grabc->mon, false, false);
|
||||
last_apply_drap_time = time;
|
||||
}
|
||||
|
|
@ -478,7 +481,7 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int32_t offsetx,
|
|||
}
|
||||
|
||||
if (last_apply_drap_time == 0 ||
|
||||
time - last_apply_drap_time > drag_tile_refresh_interval) {
|
||||
time - last_apply_drap_time > config.drag_tile_refresh_interval) {
|
||||
arrange(grabc->mon, false, false);
|
||||
last_apply_drap_time = time;
|
||||
}
|
||||
|
|
@ -494,7 +497,7 @@ void resize_tile_scroller(Client *grabc, bool isdrag, int32_t offsetx,
|
|||
Client *stack_head = get_scroll_stack_head(grabc);
|
||||
|
||||
if (grabc && grabc->mon->visible_tiling_clients == 1 &&
|
||||
!scroller_ignore_proportion_single)
|
||||
!config.scroller_ignore_proportion_single)
|
||||
return;
|
||||
|
||||
if (!start_drag_window && isdrag) {
|
||||
|
|
@ -670,7 +673,7 @@ void resize_tile_scroller(Client *grabc, bool isdrag, int32_t offsetx,
|
|||
}
|
||||
|
||||
if (last_apply_drap_time == 0 ||
|
||||
time - last_apply_drap_time > drag_tile_refresh_interval) {
|
||||
time - last_apply_drap_time > config.drag_tile_refresh_interval) {
|
||||
arrange(grabc->mon, false, false);
|
||||
last_apply_drap_time = time;
|
||||
}
|
||||
|
|
@ -811,11 +814,6 @@ void pre_caculate_before_arrange(Monitor *m, bool want_animation,
|
|||
int32_t master_num = 0;
|
||||
int32_t stack_num = 0;
|
||||
|
||||
if (!m)
|
||||
return;
|
||||
|
||||
if (!m->wlr_output->enabled)
|
||||
return;
|
||||
m->visible_clients = 0;
|
||||
m->visible_tiling_clients = 0;
|
||||
m->visible_scroll_tiling_clients = 0;
|
||||
|
|
@ -912,6 +910,12 @@ void pre_caculate_before_arrange(Monitor *m, bool want_animation,
|
|||
void // 17
|
||||
arrange(Monitor *m, bool want_animation, bool from_view) {
|
||||
|
||||
if (!m)
|
||||
return;
|
||||
|
||||
if (!m->wlr_output->enabled)
|
||||
return;
|
||||
|
||||
pre_caculate_before_arrange(m, want_animation, from_view, false);
|
||||
|
||||
if (m->isoverview) {
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ void grid(Monitor *m) {
|
|||
Client *c = NULL;
|
||||
n = 0;
|
||||
int32_t target_gappo =
|
||||
enablegaps ? m->isoverview ? overviewgappo : gappoh : 0;
|
||||
enablegaps ? m->isoverview ? config.overviewgappo : config.gappoh : 0;
|
||||
int32_t target_gappi =
|
||||
enablegaps ? m->isoverview ? overviewgappi : gappih : 0;
|
||||
enablegaps ? m->isoverview ? config.overviewgappi : config.gappih : 0;
|
||||
float single_width_ratio = m->isoverview ? 0.7 : 0.9;
|
||||
float single_height_ratio = m->isoverview ? 0.8 : 0.9;
|
||||
|
||||
|
|
@ -123,9 +123,12 @@ void deck(Monitor *m) {
|
|||
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
||||
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
||||
|
||||
cur_gappih = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappih;
|
||||
cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
cur_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
cur_gappih =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappih;
|
||||
cur_gappoh =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
cur_gappov =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
|
||||
n = m->visible_tiling_clients;
|
||||
|
||||
|
|
@ -188,12 +191,15 @@ void horizontal_scroll_adjust_fullandmax(Client *c,
|
|||
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
||||
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
||||
|
||||
cur_gappih =
|
||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappih;
|
||||
cur_gappoh =
|
||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
cur_gappov =
|
||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
cur_gappih = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||
? 0
|
||||
: cur_gappih;
|
||||
cur_gappoh = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||
? 0
|
||||
: cur_gappoh;
|
||||
cur_gappov = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||
? 0
|
||||
: cur_gappov;
|
||||
|
||||
if (c->isfullscreen) {
|
||||
target_geom->height = m->m.height;
|
||||
|
|
@ -289,14 +295,18 @@ void scroller(Monitor *m) {
|
|||
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
||||
int32_t cur_gappiv = enablegaps ? m->gappiv : 0;
|
||||
|
||||
cur_gappih =
|
||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappih;
|
||||
cur_gappoh =
|
||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
cur_gappov =
|
||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
cur_gappih = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||
? 0
|
||||
: cur_gappih;
|
||||
cur_gappoh = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||
? 0
|
||||
: cur_gappoh;
|
||||
cur_gappov = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||
? 0
|
||||
: cur_gappov;
|
||||
|
||||
int32_t max_client_width = m->w.width - 2 * scroller_structs - cur_gappih;
|
||||
int32_t max_client_width =
|
||||
m->w.width - 2 * config.scroller_structs - cur_gappih;
|
||||
|
||||
n = m->visible_scroll_tiling_clients;
|
||||
|
||||
|
|
@ -320,13 +330,13 @@ void scroller(Monitor *m) {
|
|||
}
|
||||
}
|
||||
|
||||
if (n == 1 && !scroller_ignore_proportion_single &&
|
||||
if (n == 1 && !config.scroller_ignore_proportion_single &&
|
||||
!tempClients[0]->isfullscreen && !tempClients[0]->ismaximizescreen) {
|
||||
c = tempClients[0];
|
||||
|
||||
single_proportion = c->scroller_proportion_single > 0.0f
|
||||
? c->scroller_proportion_single
|
||||
: scroller_default_proportion_single;
|
||||
: config.scroller_default_proportion_single;
|
||||
|
||||
target_geom.height = m->w.height - 2 * cur_gappov;
|
||||
target_geom.width = (m->w.width - 2 * cur_gappoh) * single_proportion;
|
||||
|
|
@ -360,9 +370,9 @@ void scroller(Monitor *m) {
|
|||
for (i = 0; i < n; i++) {
|
||||
c = tempClients[i];
|
||||
if (root_client == c) {
|
||||
if (c->geom.x >= m->w.x + scroller_structs &&
|
||||
if (c->geom.x >= m->w.x + config.scroller_structs &&
|
||||
c->geom.x + c->geom.width <=
|
||||
m->w.x + m->w.width - scroller_structs) {
|
||||
m->w.x + m->w.width - config.scroller_structs) {
|
||||
need_scroller = false;
|
||||
} else {
|
||||
need_scroller = true;
|
||||
|
|
@ -373,7 +383,8 @@ void scroller(Monitor *m) {
|
|||
}
|
||||
|
||||
bool need_apply_overspread =
|
||||
scroller_prefer_overspread && m->visible_scroll_tiling_clients > 1 &&
|
||||
config.scroller_prefer_overspread &&
|
||||
m->visible_scroll_tiling_clients > 1 &&
|
||||
(focus_client_index == 0 || focus_client_index == n - 1) &&
|
||||
tempClients[focus_client_index]->scroller_proportion < 1.0f;
|
||||
|
||||
|
|
@ -403,16 +414,16 @@ void scroller(Monitor *m) {
|
|||
}
|
||||
|
||||
bool need_apply_center =
|
||||
scroller_focus_center || m->visible_scroll_tiling_clients == 1 ||
|
||||
(scroller_prefer_center && !need_apply_overspread &&
|
||||
config.scroller_focus_center || m->visible_scroll_tiling_clients == 1 ||
|
||||
(config.scroller_prefer_center && !need_apply_overspread &&
|
||||
(!m->prevsel ||
|
||||
(ISSCROLLTILED(m->prevsel) &&
|
||||
(m->prevsel->scroller_proportion * max_client_width) +
|
||||
(tempClients[focus_client_index]->scroller_proportion *
|
||||
max_client_width) >
|
||||
m->w.width - 2 * scroller_structs - cur_gappih)));
|
||||
m->w.width - 2 * config.scroller_structs - cur_gappih)));
|
||||
|
||||
if (n == 1 && scroller_ignore_proportion_single) {
|
||||
if (n == 1 && config.scroller_ignore_proportion_single) {
|
||||
need_scroller = true;
|
||||
}
|
||||
|
||||
|
|
@ -439,14 +450,14 @@ void scroller(Monitor *m) {
|
|||
target_geom.x = m->w.x + (m->w.width - target_geom.width) / 2;
|
||||
} else if (need_apply_overspread) {
|
||||
if (over_overspread_to_left) {
|
||||
target_geom.x = m->w.x + scroller_structs;
|
||||
target_geom.x = m->w.x + config.scroller_structs;
|
||||
} else {
|
||||
target_geom.x =
|
||||
m->w.x +
|
||||
(m->w.width -
|
||||
tempClients[focus_client_index]->scroller_proportion *
|
||||
max_client_width -
|
||||
scroller_structs);
|
||||
config.scroller_structs);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -456,8 +467,8 @@ void scroller(Monitor *m) {
|
|||
tempClients[focus_client_index]
|
||||
->scroller_proportion *
|
||||
max_client_width -
|
||||
scroller_structs)
|
||||
: m->w.x + scroller_structs;
|
||||
config.scroller_structs)
|
||||
: m->w.x + config.scroller_structs;
|
||||
}
|
||||
horizontal_check_scroller_root_inside_mon(
|
||||
tempClients[focus_client_index], &target_geom);
|
||||
|
|
@ -522,10 +533,14 @@ void center_tile(Monitor *m) {
|
|||
int32_t cur_gappoh = enablegaps ? m->gappoh : 0; // 外部水平间隙
|
||||
|
||||
// 智能间隙处理
|
||||
cur_gappiv = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv;
|
||||
cur_gappih = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappih;
|
||||
cur_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
cur_gappiv =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv;
|
||||
cur_gappih =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappih;
|
||||
cur_gappov =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
cur_gappoh =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
|
||||
int32_t nmasters = m->pertag->nmasters[m->pertag->curtag];
|
||||
mfact = fc->master_mfact_per > 0.0f ? fc->master_mfact_per
|
||||
|
|
@ -538,7 +553,8 @@ void center_tile(Monitor *m) {
|
|||
tw = mw;
|
||||
|
||||
// 判断是否需要主区域铺满
|
||||
int32_t should_overspread = center_master_overspread && (n <= nmasters);
|
||||
int32_t should_overspread =
|
||||
config.center_master_overspread && (n <= nmasters);
|
||||
|
||||
int32_t master_surplus_height =
|
||||
(m->w.height - 2 * cur_gappov - cur_gappiv * ie * (master_num - 1));
|
||||
|
|
@ -564,7 +580,7 @@ void center_tile(Monitor *m) {
|
|||
mx = cur_gappoh + tw + cur_gappih * ie;
|
||||
} else if (n - nmasters == 1) {
|
||||
// 单个堆叠窗口的处理
|
||||
if (center_when_single_stack) {
|
||||
if (config.center_when_single_stack) {
|
||||
// stack在右边,master居中,左边空着
|
||||
tw = (m->w.width - mw) / 2 - cur_gappoh - cur_gappih * ie;
|
||||
mx = cur_gappoh + tw + cur_gappih * ie; // master居中
|
||||
|
|
@ -641,7 +657,7 @@ void center_tile(Monitor *m) {
|
|||
}
|
||||
|
||||
int32_t stack_x;
|
||||
if (center_when_single_stack) {
|
||||
if (config.center_when_single_stack) {
|
||||
// 放在右侧(master居中时,stack在右边)
|
||||
stack_x = m->w.x + mx + mw + cur_gappih * ie;
|
||||
} else {
|
||||
|
|
@ -745,10 +761,14 @@ void tile(Monitor *m) {
|
|||
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
||||
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
||||
|
||||
cur_gappiv = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv;
|
||||
cur_gappih = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappih;
|
||||
cur_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
cur_gappiv =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv;
|
||||
cur_gappih =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappih;
|
||||
cur_gappov =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
cur_gappoh =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
|
||||
wl_list_for_each(fc, &clients, link) {
|
||||
|
||||
|
|
@ -855,10 +875,14 @@ void right_tile(Monitor *m) {
|
|||
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
||||
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
||||
|
||||
cur_gappiv = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv;
|
||||
cur_gappih = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappih;
|
||||
cur_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
cur_gappiv =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv;
|
||||
cur_gappih =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappih;
|
||||
cur_gappov =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
cur_gappoh =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
|
||||
wl_list_for_each(fc, &clients, link) {
|
||||
|
||||
|
|
@ -953,8 +977,10 @@ monocle(Monitor *m) {
|
|||
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
||||
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
||||
|
||||
cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
cur_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
cur_gappoh =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
cur_gappov =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (!VISIBLEON(c, m) || !ISTILED(c))
|
||||
|
|
|
|||
|
|
@ -19,10 +19,14 @@ void vertical_tile(Monitor *m) {
|
|||
int32_t cur_gapoh = enablegaps ? m->gappoh : 0;
|
||||
int32_t cur_gapov = enablegaps ? m->gappov : 0;
|
||||
|
||||
cur_gapih = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapih;
|
||||
cur_gapiv = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapiv;
|
||||
cur_gapoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapoh;
|
||||
cur_gapov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapov;
|
||||
cur_gapih =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapih;
|
||||
cur_gapiv =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapiv;
|
||||
cur_gapoh =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapoh;
|
||||
cur_gapov =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapov;
|
||||
|
||||
wl_list_for_each(fc, &clients, link) {
|
||||
if (VISIBLEON(fc, m) && ISTILED(fc))
|
||||
|
|
@ -116,9 +120,12 @@ void vertical_deck(Monitor *m) {
|
|||
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
||||
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
||||
|
||||
cur_gappiv = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv;
|
||||
cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
cur_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
cur_gappiv =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv;
|
||||
cur_gappoh =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
cur_gappov =
|
||||
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
|
||||
n = m->visible_tiling_clients;
|
||||
|
||||
|
|
@ -175,12 +182,15 @@ void vertical_scroll_adjust_fullandmax(Client *c, struct wlr_box *target_geom) {
|
|||
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
||||
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
||||
|
||||
cur_gappiv =
|
||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappiv;
|
||||
cur_gappov =
|
||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
cur_gappoh =
|
||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
cur_gappiv = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||
? 0
|
||||
: cur_gappiv;
|
||||
cur_gappov = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||
? 0
|
||||
: cur_gappov;
|
||||
cur_gappoh = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||
? 0
|
||||
: cur_gappoh;
|
||||
|
||||
if (c->isfullscreen) {
|
||||
target_geom->width = m->m.width;
|
||||
|
|
@ -276,14 +286,18 @@ void vertical_scroller(Monitor *m) {
|
|||
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
||||
int32_t cur_gappih = enablegaps ? m->gappih : 0;
|
||||
|
||||
cur_gappiv =
|
||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappiv;
|
||||
cur_gappov =
|
||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
cur_gappoh =
|
||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
cur_gappiv = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||
? 0
|
||||
: cur_gappiv;
|
||||
cur_gappov = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||
? 0
|
||||
: cur_gappov;
|
||||
cur_gappoh = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||
? 0
|
||||
: cur_gappoh;
|
||||
|
||||
int32_t max_client_height = m->w.height - 2 * scroller_structs - cur_gappiv;
|
||||
int32_t max_client_height =
|
||||
m->w.height - 2 * config.scroller_structs - cur_gappiv;
|
||||
|
||||
n = m->visible_scroll_tiling_clients;
|
||||
|
||||
|
|
@ -304,13 +318,13 @@ void vertical_scroller(Monitor *m) {
|
|||
}
|
||||
}
|
||||
|
||||
if (n == 1 && !scroller_ignore_proportion_single &&
|
||||
if (n == 1 && !config.scroller_ignore_proportion_single &&
|
||||
!tempClients[0]->isfullscreen && !tempClients[0]->ismaximizescreen) {
|
||||
c = tempClients[0];
|
||||
|
||||
single_proportion = c->scroller_proportion_single > 0.0f
|
||||
? c->scroller_proportion_single
|
||||
: scroller_default_proportion_single;
|
||||
: config.scroller_default_proportion_single;
|
||||
|
||||
target_geom.width = m->w.width - 2 * cur_gappoh;
|
||||
target_geom.height = (m->w.height - 2 * cur_gappov) * single_proportion;
|
||||
|
|
@ -344,9 +358,9 @@ void vertical_scroller(Monitor *m) {
|
|||
for (i = 0; i < n; i++) {
|
||||
c = tempClients[i];
|
||||
if (root_client == c) {
|
||||
if (c->geom.y >= m->w.y + scroller_structs &&
|
||||
if (c->geom.y >= m->w.y + config.scroller_structs &&
|
||||
c->geom.y + c->geom.height <=
|
||||
m->w.y + m->w.height - scroller_structs) {
|
||||
m->w.y + m->w.height - config.scroller_structs) {
|
||||
need_scroller = false;
|
||||
} else {
|
||||
need_scroller = true;
|
||||
|
|
@ -357,7 +371,8 @@ void vertical_scroller(Monitor *m) {
|
|||
}
|
||||
|
||||
bool need_apply_overspread =
|
||||
scroller_prefer_overspread && m->visible_scroll_tiling_clients > 1 &&
|
||||
config.scroller_prefer_overspread &&
|
||||
m->visible_scroll_tiling_clients > 1 &&
|
||||
(focus_client_index == 0 || focus_client_index == n - 1) &&
|
||||
tempClients[focus_client_index]->scroller_proportion < 1.0f;
|
||||
|
||||
|
|
@ -387,16 +402,16 @@ void vertical_scroller(Monitor *m) {
|
|||
}
|
||||
|
||||
bool need_apply_center =
|
||||
scroller_focus_center || m->visible_scroll_tiling_clients == 1 ||
|
||||
(scroller_prefer_center && !need_apply_overspread &&
|
||||
config.scroller_focus_center || m->visible_scroll_tiling_clients == 1 ||
|
||||
(config.scroller_prefer_center && !need_apply_overspread &&
|
||||
(!m->prevsel ||
|
||||
(ISSCROLLTILED(m->prevsel) &&
|
||||
(m->prevsel->scroller_proportion * max_client_height) +
|
||||
(tempClients[focus_client_index]->scroller_proportion *
|
||||
max_client_height) >
|
||||
m->w.height - 2 * scroller_structs - cur_gappiv)));
|
||||
m->w.height - 2 * config.scroller_structs - cur_gappiv)));
|
||||
|
||||
if (n == 1 && scroller_ignore_proportion_single) {
|
||||
if (n == 1 && config.scroller_ignore_proportion_single) {
|
||||
need_scroller = true;
|
||||
}
|
||||
|
||||
|
|
@ -426,14 +441,14 @@ void vertical_scroller(Monitor *m) {
|
|||
target_geom.y = m->w.y + (m->w.height - target_geom.height) / 2;
|
||||
} else if (need_apply_overspread) {
|
||||
if (over_overspread_to_up) {
|
||||
target_geom.y = m->w.y + scroller_structs;
|
||||
target_geom.y = m->w.y + config.scroller_structs;
|
||||
} else {
|
||||
target_geom.y =
|
||||
m->w.y +
|
||||
(m->w.height -
|
||||
tempClients[focus_client_index]->scroller_proportion *
|
||||
max_client_height -
|
||||
scroller_structs);
|
||||
config.scroller_structs);
|
||||
}
|
||||
} else {
|
||||
target_geom.y = root_client->geom.y > m->w.y + (m->w.height) / 2
|
||||
|
|
@ -441,8 +456,8 @@ void vertical_scroller(Monitor *m) {
|
|||
tempClients[focus_client_index]
|
||||
->scroller_proportion *
|
||||
max_client_height -
|
||||
scroller_structs)
|
||||
: m->w.y + scroller_structs;
|
||||
config.scroller_structs)
|
||||
: m->w.y + config.scroller_structs;
|
||||
}
|
||||
vertical_check_scroller_root_inside_mon(tempClients[focus_client_index],
|
||||
&target_geom);
|
||||
|
|
@ -486,9 +501,9 @@ void vertical_grid(Monitor *m) {
|
|||
int32_t rows, cols, overrows;
|
||||
Client *c = NULL;
|
||||
int32_t target_gappo =
|
||||
enablegaps ? m->isoverview ? overviewgappo : gappov : 0;
|
||||
enablegaps ? m->isoverview ? config.overviewgappo : config.gappov : 0;
|
||||
int32_t target_gappi =
|
||||
enablegaps ? m->isoverview ? overviewgappi : gappiv : 0;
|
||||
enablegaps ? m->isoverview ? config.overviewgappi : config.gappiv : 0;
|
||||
float single_width_ratio = m->isoverview ? 0.7 : 0.9;
|
||||
float single_height_ratio = m->isoverview ? 0.8 : 0.9;
|
||||
|
||||
|
|
|
|||
319
src/mango.c
319
src/mango.c
|
|
@ -910,13 +910,19 @@ static struct wl_event_source *keep_idle_inhibit_source;
|
|||
static bool cursor_hidden = false;
|
||||
static bool tag_combo = false;
|
||||
static const char *cli_config_path = NULL;
|
||||
static bool cli_debug_log = false;
|
||||
static KeyMode keymode = {
|
||||
.mode = {'d', 'e', 'f', 'a', 'u', 'l', 't', '\0'},
|
||||
.isdefault = true,
|
||||
};
|
||||
|
||||
static char *env_vars[] = {"DISPLAY", "WAYLAND_DISPLAY", "XDG_CURRENT_DESKTOP",
|
||||
"XDG_SESSION_TYPE", NULL};
|
||||
static char *env_vars[] = {"DISPLAY",
|
||||
"WAYLAND_DISPLAY",
|
||||
"XDG_CURRENT_DESKTOP",
|
||||
"XDG_SESSION_TYPE",
|
||||
"XCURSOR_THEME",
|
||||
"XCURSOR_SIZE",
|
||||
NULL};
|
||||
static struct {
|
||||
enum wp_cursor_shape_device_v1_shape shape;
|
||||
struct wlr_surface *surface;
|
||||
|
|
@ -937,6 +943,8 @@ struct Pertag {
|
|||
*ltidxs[LENGTH(tags) + 1]; /* matrix of tags and layouts indexes */
|
||||
};
|
||||
|
||||
#include "config/parse_config.h"
|
||||
|
||||
static struct wl_signal mango_print_status;
|
||||
|
||||
static struct wl_listener print_status_listener = {.notify =
|
||||
|
|
@ -999,7 +1007,6 @@ static struct wl_event_source *sync_keymap;
|
|||
#include "animation/common.h"
|
||||
#include "animation/layer.h"
|
||||
#include "animation/tag.h"
|
||||
#include "config/parse_config.h"
|
||||
#include "dispatch/bind_define.h"
|
||||
#include "ext-protocol/all.h"
|
||||
#include "fetch/fetch.h"
|
||||
|
|
@ -1064,7 +1071,7 @@ void show_scratchpad(Client *c) {
|
|||
if (c->isfullscreen || c->ismaximizescreen) {
|
||||
c->isfullscreen = 0; // 清除窗口全屏标志
|
||||
c->ismaximizescreen = 0;
|
||||
c->bw = c->isnoborder ? 0 : borderpx;
|
||||
c->bw = c->isnoborder ? 0 : config.borderpx;
|
||||
}
|
||||
|
||||
/* return if fullscreen */
|
||||
|
|
@ -1072,10 +1079,10 @@ void show_scratchpad(Client *c) {
|
|||
setfloating(c, 1);
|
||||
c->geom.width = c->iscustomsize
|
||||
? c->float_geom.width
|
||||
: c->mon->w.width * scratchpad_width_ratio;
|
||||
c->geom.height = c->iscustomsize
|
||||
? c->float_geom.height
|
||||
: c->mon->w.height * scratchpad_height_ratio;
|
||||
: c->mon->w.width * config.scratchpad_width_ratio;
|
||||
c->geom.height =
|
||||
c->iscustomsize ? c->float_geom.height
|
||||
: c->mon->w.height * config.scratchpad_height_ratio;
|
||||
// 重新计算居中的坐标
|
||||
c->float_geom = c->geom = c->animainit_geom = c->animation.current =
|
||||
setclient_coordinate_center(c, c->mon, c->geom, 0, 0);
|
||||
|
|
@ -1143,7 +1150,7 @@ void swallow(Client *c, Client *w) {
|
|||
|
||||
bool switch_scratchpad_client_state(Client *c) {
|
||||
|
||||
if (scratchpad_cross_monitor && selmon && c->mon != selmon &&
|
||||
if (config.scratchpad_cross_monitor && selmon && c->mon != selmon &&
|
||||
c->is_in_scratchpad) {
|
||||
// 保存原始monitor用于尺寸计算
|
||||
Monitor *oldmon = c->mon;
|
||||
|
|
@ -1197,12 +1204,12 @@ void apply_named_scratchpad(Client *target_client) {
|
|||
Client *c = NULL;
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
|
||||
if (!scratchpad_cross_monitor && c->mon != selmon) {
|
||||
if (!config.scratchpad_cross_monitor && c->mon != selmon) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (single_scratchpad && c->is_in_scratchpad && c->is_scratchpad_show &&
|
||||
c != target_client) {
|
||||
if (config.single_scratchpad && c->is_in_scratchpad &&
|
||||
c->is_scratchpad_show && c != target_client) {
|
||||
set_minimized(c);
|
||||
}
|
||||
}
|
||||
|
|
@ -1263,30 +1270,30 @@ void toggle_hotarea(int32_t x_root, int32_t y_root) {
|
|||
// 根据热角位置计算不同的热区坐标
|
||||
unsigned hx, hy;
|
||||
|
||||
switch (hotarea_corner) {
|
||||
switch (config.hotarea_corner) {
|
||||
case BOTTOM_RIGHT: // 右下角
|
||||
hx = selmon->m.x + selmon->m.width - hotarea_size;
|
||||
hy = selmon->m.y + selmon->m.height - hotarea_size;
|
||||
hx = selmon->m.x + selmon->m.width - config.hotarea_size;
|
||||
hy = selmon->m.y + selmon->m.height - config.hotarea_size;
|
||||
break;
|
||||
case TOP_LEFT: // 左上角
|
||||
hx = selmon->m.x + hotarea_size;
|
||||
hy = selmon->m.y + hotarea_size;
|
||||
hx = selmon->m.x + config.hotarea_size;
|
||||
hy = selmon->m.y + config.hotarea_size;
|
||||
break;
|
||||
case TOP_RIGHT: // 右上角
|
||||
hx = selmon->m.x + selmon->m.width - hotarea_size;
|
||||
hy = selmon->m.y + hotarea_size;
|
||||
hx = selmon->m.x + selmon->m.width - config.hotarea_size;
|
||||
hy = selmon->m.y + config.hotarea_size;
|
||||
break;
|
||||
case BOTTOM_LEFT: // 左下角(默认)
|
||||
default:
|
||||
hx = selmon->m.x + hotarea_size;
|
||||
hy = selmon->m.y + selmon->m.height - hotarea_size;
|
||||
hx = selmon->m.x + config.hotarea_size;
|
||||
hy = selmon->m.y + selmon->m.height - config.hotarea_size;
|
||||
break;
|
||||
}
|
||||
|
||||
// 判断鼠标是否在热区内
|
||||
int in_hotarea = 0;
|
||||
|
||||
switch (hotarea_corner) {
|
||||
switch (config.hotarea_corner) {
|
||||
case BOTTOM_RIGHT: // 右下角
|
||||
in_hotarea = (y_root > hy && x_root > hx &&
|
||||
x_root <= (selmon->m.x + selmon->m.width) &&
|
||||
|
|
@ -1308,10 +1315,11 @@ void toggle_hotarea(int32_t x_root, int32_t y_root) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (enable_hotarea == 1 && selmon->is_in_hotarea == 0 && in_hotarea) {
|
||||
if (config.enable_hotarea == 1 && selmon->is_in_hotarea == 0 &&
|
||||
in_hotarea) {
|
||||
toggleoverview(&arg);
|
||||
selmon->is_in_hotarea = 1;
|
||||
} else if (enable_hotarea == 1 && selmon->is_in_hotarea == 1 &&
|
||||
} else if (config.enable_hotarea == 1 && selmon->is_in_hotarea == 1 &&
|
||||
!in_hotarea) {
|
||||
selmon->is_in_hotarea = 0;
|
||||
}
|
||||
|
|
@ -1604,7 +1612,7 @@ void apply_window_snap(Client *c) {
|
|||
int32_t snap_up_mon = 0, snap_down_mon = 0, snap_left_mon = 0,
|
||||
snap_right_mon = 0;
|
||||
|
||||
uint32_t cbw = !render_border || c->fake_no_border ? borderpx : 0;
|
||||
uint32_t cbw = !render_border || c->fake_no_border ? config.borderpx : 0;
|
||||
uint32_t tcbw;
|
||||
uint32_t cx, cy, cw, ch, tcx, tcy, tcw, tch;
|
||||
cx = c->geom.x + cbw;
|
||||
|
|
@ -1616,14 +1624,14 @@ void apply_window_snap(Client *c) {
|
|||
if (!c || !c->mon || !client_surface(c)->mapped || c->iskilling)
|
||||
return;
|
||||
|
||||
if (!c->isfloating || !enable_floating_snap)
|
||||
if (!c->isfloating || !config.enable_floating_snap)
|
||||
return;
|
||||
|
||||
wl_list_for_each(tc, &clients, link) {
|
||||
if (tc && tc->isfloating && !tc->iskilling &&
|
||||
client_surface(tc)->mapped && VISIBLEON(tc, c->mon)) {
|
||||
|
||||
tcbw = !render_border || tc->fake_no_border ? borderpx : 0;
|
||||
tcbw = !render_border || tc->fake_no_border ? config.borderpx : 0;
|
||||
tcx = tc->geom.x + tcbw;
|
||||
tcy = tc->geom.y + tcbw;
|
||||
tcw = tc->geom.width - 2 * tcbw;
|
||||
|
|
@ -1677,19 +1685,19 @@ void apply_window_snap(Client *c) {
|
|||
if (snap_right_screen >= 0 && snap_right_screen < snap_right)
|
||||
snap_right = snap_right_screen;
|
||||
|
||||
if (snap_left < snap_right && snap_left < snap_distance) {
|
||||
if (snap_left < snap_right && snap_left < config.snap_distance) {
|
||||
c->geom.x = c->geom.x - snap_left;
|
||||
}
|
||||
|
||||
if (snap_right <= snap_left && snap_right < snap_distance) {
|
||||
if (snap_right <= snap_left && snap_right < config.snap_distance) {
|
||||
c->geom.x = c->geom.x + snap_right;
|
||||
}
|
||||
|
||||
if (snap_up < snap_down && snap_up < snap_distance) {
|
||||
if (snap_up < snap_down && snap_up < config.snap_distance) {
|
||||
c->geom.y = c->geom.y - snap_up;
|
||||
}
|
||||
|
||||
if (snap_down <= snap_up && snap_down < snap_distance) {
|
||||
if (snap_down <= snap_up && snap_down < config.snap_distance) {
|
||||
c->geom.y = c->geom.y + snap_down;
|
||||
}
|
||||
|
||||
|
|
@ -1819,7 +1827,8 @@ axisnotify(struct wl_listener *listener, void *data) {
|
|||
a = &config.axis_bindings[ji];
|
||||
if (CLEANMASK(mods) == CLEANMASK(a->mod) && // 按键一致
|
||||
adir == a->dir && a->func) { // 滚轮方向判断一致且处理函数存在
|
||||
if (event->time_msec - axis_apply_time > axis_bind_apply_timeout ||
|
||||
if (event->time_msec - axis_apply_time >
|
||||
config.axis_bind_apply_timeout ||
|
||||
axis_apply_dir * event->delta < 0) {
|
||||
a->func(&a->arg);
|
||||
axis_apply_time = event->time_msec;
|
||||
|
|
@ -1839,9 +1848,10 @@ axisnotify(struct wl_listener *listener, void *data) {
|
|||
/* Notify the client with pointer focus of the axis event. */
|
||||
wlr_seat_pointer_notify_axis(
|
||||
seat, // 滚轮事件发送给客户端也就是窗口
|
||||
event->time_msec, event->orientation, event->delta * axis_scroll_factor,
|
||||
roundf(event->delta_discrete * axis_scroll_factor), event->source,
|
||||
event->relative_direction);
|
||||
event->time_msec, event->orientation,
|
||||
event->delta * config.axis_scroll_factor,
|
||||
roundf(event->delta_discrete * config.axis_scroll_factor),
|
||||
event->source, event->relative_direction);
|
||||
}
|
||||
|
||||
int32_t ongesture(struct wlr_pointer_swipe_end_event *event) {
|
||||
|
|
@ -1859,7 +1869,8 @@ int32_t ongesture(struct wlr_pointer_swipe_end_event *event) {
|
|||
}
|
||||
|
||||
// Require absolute distance movement beyond a small thresh-hold
|
||||
if (adx * adx + ady * ady < swipe_min_threshold * swipe_min_threshold) {
|
||||
if (adx * adx + ady * ady <
|
||||
config.swipe_min_threshold * config.swipe_min_threshold) {
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
|
@ -1996,7 +2007,7 @@ void place_drag_tile_client(Client *c) {
|
|||
bool check_trackpad_disabled(struct wlr_pointer *pointer) {
|
||||
struct libinput_device *device;
|
||||
|
||||
if (!disable_trackpad)
|
||||
if (!config.disable_trackpad)
|
||||
return false;
|
||||
|
||||
if (wlr_input_device_is_libinput(&pointer->base) &&
|
||||
|
|
@ -2122,7 +2133,7 @@ bool handle_buttonpress(struct wlr_pointer_button_event *event) {
|
|||
grabc = NULL;
|
||||
start_drag_window = false;
|
||||
last_apply_drap_time = 0;
|
||||
if (tmpc->drag_to_tile && drag_tile_to_tile) {
|
||||
if (tmpc->drag_to_tile && config.drag_tile_to_tile) {
|
||||
place_drag_tile_client(tmpc);
|
||||
} else {
|
||||
apply_window_snap(tmpc);
|
||||
|
|
@ -2153,7 +2164,7 @@ void checkidleinhibitor(struct wlr_surface *exclude) {
|
|||
|
||||
toplevel_from_wlr_surface(inhibitor->surface, &c, NULL);
|
||||
|
||||
if (idleinhibit_ignore_visible) {
|
||||
if (config.idleinhibit_ignore_visible) {
|
||||
inhibited = 1;
|
||||
break;
|
||||
}
|
||||
|
|
@ -2351,7 +2362,7 @@ static void iter_layer_scene_buffers(struct wlr_scene_buffer *buffer,
|
|||
|
||||
wlr_scene_buffer_set_backdrop_blur(buffer, true);
|
||||
wlr_scene_buffer_set_backdrop_blur_ignore_transparent(buffer, true);
|
||||
if (blur_optimized) {
|
||||
if (config.blur_optimized) {
|
||||
wlr_scene_buffer_set_backdrop_blur_optimized(buffer, true);
|
||||
} else {
|
||||
wlr_scene_buffer_set_backdrop_blur_optimized(buffer, false);
|
||||
|
|
@ -2359,7 +2370,7 @@ static void iter_layer_scene_buffers(struct wlr_scene_buffer *buffer,
|
|||
}
|
||||
|
||||
void layer_flush_blur_background(LayerSurface *l) {
|
||||
if (!blur)
|
||||
if (!config.blur)
|
||||
return;
|
||||
|
||||
// 如果背景层发生变化,标记优化的模糊背景缓存需要更新
|
||||
|
|
@ -2415,15 +2426,16 @@ void maplayersurfacenotify(struct wl_listener *listener, void *data) {
|
|||
if (layer_surface->current.exclusive_zone == 0 &&
|
||||
layer_surface->current.layer != ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM &&
|
||||
layer_surface->current.layer != ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND) {
|
||||
l->shadow = wlr_scene_shadow_create(l->scene, 0, 0, border_radius,
|
||||
shadows_blur, shadowscolor);
|
||||
l->shadow =
|
||||
wlr_scene_shadow_create(l->scene, 0, 0, config.border_radius,
|
||||
config.shadows_blur, config.shadowscolor);
|
||||
wlr_scene_node_lower_to_bottom(&l->shadow->node);
|
||||
wlr_scene_node_set_enabled(&l->shadow->node, true);
|
||||
}
|
||||
|
||||
// 初始化动画
|
||||
if (animations && layer_animations && !l->noanim) {
|
||||
l->animation.duration = animation_duration_open;
|
||||
if (config.animations && config.layer_animations && !l->noanim) {
|
||||
l->animation.duration = config.animation_duration_open;
|
||||
l->animation.action = OPEN;
|
||||
layer_set_pending_state(l);
|
||||
}
|
||||
|
|
@ -2469,7 +2481,8 @@ void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
|
|||
|
||||
get_layer_target_geometry(l, &box);
|
||||
|
||||
if (animations && layer_animations && !l->noanim && l->mapped &&
|
||||
if (config.animations && config.layer_animations && !l->noanim &&
|
||||
l->mapped &&
|
||||
layer_surface->current.layer != ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM &&
|
||||
layer_surface->current.layer != ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND &&
|
||||
!wlr_box_equal(&box, &l->geom)) {
|
||||
|
|
@ -2479,13 +2492,12 @@ void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
|
|||
l->geom.width = box.width;
|
||||
l->geom.height = box.height;
|
||||
l->animation.action = MOVE;
|
||||
l->animation.duration = animation_duration_move;
|
||||
l->animation.duration = config.animation_duration_move;
|
||||
l->need_output_flush = true;
|
||||
layer_set_pending_state(l);
|
||||
}
|
||||
|
||||
if (blur && blur_layer) {
|
||||
// 设置非背景layer模糊
|
||||
if (config.blur && config.blur_layer) {
|
||||
|
||||
if (!l->noblur &&
|
||||
layer_surface->current.layer != ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM &&
|
||||
|
|
@ -2763,22 +2775,21 @@ KeyboardGroup *createkeyboardgroup(void) {
|
|||
group->wlr_group = wlr_keyboard_group_create();
|
||||
group->wlr_group->data = group;
|
||||
|
||||
/* Prepare an XKB keymap and assign it to the keyboard group. */
|
||||
context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
if (!(keymap = xkb_keymap_new_from_names(context, &xkb_rules,
|
||||
if (!(keymap = xkb_keymap_new_from_names(context, &config.xkb_rules,
|
||||
XKB_KEYMAP_COMPILE_NO_FLAGS)))
|
||||
die("failed to compile keymap");
|
||||
|
||||
wlr_keyboard_set_keymap(&group->wlr_group->keyboard, keymap);
|
||||
|
||||
if (numlockon) {
|
||||
if (config.numlockon) {
|
||||
xkb_mod_index_t mod_index =
|
||||
xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_NUM);
|
||||
if (mod_index != XKB_MOD_INVALID)
|
||||
locked_mods |= (uint32_t)1 << mod_index;
|
||||
}
|
||||
|
||||
if (capslock) {
|
||||
if (config.capslock) {
|
||||
xkb_mod_index_t mod_index =
|
||||
xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
|
||||
if (mod_index != XKB_MOD_INVALID)
|
||||
|
|
@ -2792,8 +2803,8 @@ KeyboardGroup *createkeyboardgroup(void) {
|
|||
xkb_keymap_unref(keymap);
|
||||
xkb_context_unref(context);
|
||||
|
||||
wlr_keyboard_set_repeat_info(&group->wlr_group->keyboard, repeat_rate,
|
||||
repeat_delay);
|
||||
wlr_keyboard_set_repeat_info(&group->wlr_group->keyboard,
|
||||
config.repeat_rate, config.repeat_delay);
|
||||
|
||||
/* Set up listeners for keyboard events */
|
||||
LISTEN(&group->wlr_group->keyboard.events.key, &group->key, keypress);
|
||||
|
|
@ -2983,11 +2994,10 @@ void createmon(struct wl_listener *listener, void *data) {
|
|||
for (i = 0; i < LENGTH(m->layers); i++)
|
||||
wl_list_init(&m->layers[i]);
|
||||
|
||||
/* Initialize monitor state using configured rules */
|
||||
m->gappih = gappih;
|
||||
m->gappiv = gappiv;
|
||||
m->gappoh = gappoh;
|
||||
m->gappov = gappov;
|
||||
m->gappih = config.gappih;
|
||||
m->gappiv = config.gappiv;
|
||||
m->gappoh = config.gappoh;
|
||||
m->gappov = config.gappov;
|
||||
m->isoverview = 0;
|
||||
m->sel = NULL;
|
||||
m->is_in_hotarea = 0;
|
||||
|
|
@ -3049,8 +3059,8 @@ void createmon(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
|
||||
for (i = 0; i <= LENGTH(tags); i++) {
|
||||
m->pertag->nmasters[i] = default_nmaster;
|
||||
m->pertag->mfacts[i] = default_mfact;
|
||||
m->pertag->nmasters[i] = config.default_nmaster;
|
||||
m->pertag->mfacts[i] = config.default_mfact;
|
||||
m->pertag->ltidxs[i] = &layouts[0];
|
||||
}
|
||||
|
||||
|
|
@ -3078,12 +3088,11 @@ void createmon(struct wl_listener *listener, void *data) {
|
|||
else
|
||||
wlr_output_layout_add(output_layout, wlr_output, m->m.x, m->m.y);
|
||||
|
||||
if (blur) {
|
||||
if (config.blur) {
|
||||
m->blur = wlr_scene_optimized_blur_create(&scene->tree, 0, 0);
|
||||
wlr_scene_node_set_position(&m->blur->node, m->m.x, m->m.y);
|
||||
wlr_scene_node_reparent(&m->blur->node, layers[LyrBlur]);
|
||||
wlr_scene_optimized_blur_set_size(m->blur, m->m.width, m->m.height);
|
||||
// wlr_scene_node_set_enabled(&m->blur->node, 1);
|
||||
}
|
||||
m->ext_group = wlr_ext_workspace_group_handle_v1_create(
|
||||
ext_manager, EXT_WORKSPACE_ENABLE_CAPS);
|
||||
|
|
@ -3109,7 +3118,7 @@ createnotify(struct wl_listener *listener, void *data) {
|
|||
/* Allocate a Client for this surface */
|
||||
c = toplevel->base->data = ecalloc(1, sizeof(*c));
|
||||
c->surface.xdg = toplevel->base;
|
||||
c->bw = borderpx;
|
||||
c->bw = config.borderpx;
|
||||
|
||||
LISTEN(&toplevel->base->surface->events.commit, &c->commit, commitnotify);
|
||||
LISTEN(&toplevel->base->surface->events.map, &c->map, mapnotify);
|
||||
|
|
@ -3155,44 +3164,49 @@ void destroyinputdevice(struct wl_listener *listener, void *data) {
|
|||
|
||||
void configure_pointer(struct libinput_device *device) {
|
||||
if (libinput_device_config_tap_get_finger_count(device)) {
|
||||
libinput_device_config_tap_set_enabled(device, tap_to_click);
|
||||
libinput_device_config_tap_set_drag_enabled(device, tap_and_drag);
|
||||
libinput_device_config_tap_set_drag_lock_enabled(device, drag_lock);
|
||||
libinput_device_config_tap_set_button_map(device, button_map);
|
||||
libinput_device_config_tap_set_enabled(device, config.tap_to_click);
|
||||
libinput_device_config_tap_set_drag_enabled(device,
|
||||
config.tap_and_drag);
|
||||
libinput_device_config_tap_set_drag_lock_enabled(device,
|
||||
config.drag_lock);
|
||||
libinput_device_config_tap_set_button_map(device, config.button_map);
|
||||
libinput_device_config_scroll_set_natural_scroll_enabled(
|
||||
device, trackpad_natural_scrolling);
|
||||
device, config.trackpad_natural_scrolling);
|
||||
} else {
|
||||
libinput_device_config_scroll_set_natural_scroll_enabled(
|
||||
device, mouse_natural_scrolling);
|
||||
device, config.mouse_natural_scrolling);
|
||||
}
|
||||
|
||||
if (libinput_device_config_dwt_is_available(device))
|
||||
libinput_device_config_dwt_set_enabled(device, disable_while_typing);
|
||||
libinput_device_config_dwt_set_enabled(device,
|
||||
config.disable_while_typing);
|
||||
|
||||
if (libinput_device_config_left_handed_is_available(device))
|
||||
libinput_device_config_left_handed_set(device, left_handed);
|
||||
libinput_device_config_left_handed_set(device, config.left_handed);
|
||||
|
||||
if (libinput_device_config_middle_emulation_is_available(device))
|
||||
libinput_device_config_middle_emulation_set_enabled(
|
||||
device, middle_button_emulation);
|
||||
device, config.middle_button_emulation);
|
||||
|
||||
if (libinput_device_config_scroll_get_methods(device) !=
|
||||
LIBINPUT_CONFIG_SCROLL_NO_SCROLL)
|
||||
libinput_device_config_scroll_set_method(device, scroll_method);
|
||||
libinput_device_config_scroll_set_method(device, config.scroll_method);
|
||||
if (libinput_device_config_scroll_get_methods(device) ==
|
||||
LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN)
|
||||
libinput_device_config_scroll_set_button(device, scroll_button);
|
||||
libinput_device_config_scroll_set_button(device, config.scroll_button);
|
||||
|
||||
if (libinput_device_config_click_get_methods(device) !=
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_NONE)
|
||||
libinput_device_config_click_set_method(device, click_method);
|
||||
libinput_device_config_click_set_method(device, config.click_method);
|
||||
|
||||
if (libinput_device_config_send_events_get_modes(device))
|
||||
libinput_device_config_send_events_set_mode(device, send_events_mode);
|
||||
libinput_device_config_send_events_set_mode(device,
|
||||
config.send_events_mode);
|
||||
|
||||
if (accel_profile && libinput_device_config_accel_is_available(device)) {
|
||||
libinput_device_config_accel_set_profile(device, accel_profile);
|
||||
libinput_device_config_accel_set_speed(device, accel_speed);
|
||||
if (config.accel_profile &&
|
||||
libinput_device_config_accel_is_available(device)) {
|
||||
libinput_device_config_accel_set_profile(device, config.accel_profile);
|
||||
libinput_device_config_accel_set_speed(device, config.accel_speed);
|
||||
} else {
|
||||
// profile cannot be directly applied to 0, need to set to 1 first
|
||||
libinput_device_config_accel_set_profile(device, 1);
|
||||
|
|
@ -3850,7 +3864,7 @@ void keypress(struct wl_listener *listener, void *data) {
|
|||
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
||||
|
||||
// ov tab mode detect moe key release
|
||||
if (ov_tab_mode && !locked && group == kb_group &&
|
||||
if (config.ov_tab_mode && !locked && group == kb_group &&
|
||||
event->state == WL_KEYBOARD_KEY_STATE_RELEASED &&
|
||||
(keycode == 133 || keycode == 37 || keycode == 64 || keycode == 50 ||
|
||||
keycode == 134 || keycode == 105 || keycode == 108 || keycode == 62) &&
|
||||
|
|
@ -3934,7 +3948,7 @@ void pending_kill_client(Client *c) {
|
|||
void locksession(struct wl_listener *listener, void *data) {
|
||||
struct wlr_session_lock_v1 *session_lock = data;
|
||||
SessionLock *lock;
|
||||
if (!allow_lock_transparent) {
|
||||
if (!config.allow_lock_transparent) {
|
||||
wlr_scene_node_set_enabled(&locked_bg->node, true);
|
||||
}
|
||||
if (cur_lock) {
|
||||
|
|
@ -3971,10 +3985,10 @@ static void iter_xdg_scene_buffers(struct wlr_scene_buffer *buffer, int32_t sx,
|
|||
if (wlr_subsurface_try_from_wlr_surface(surface) != NULL)
|
||||
return;
|
||||
|
||||
if (blur && c && !c->noblur) {
|
||||
if (config.blur && c && !c->noblur) {
|
||||
wlr_scene_buffer_set_backdrop_blur(buffer, true);
|
||||
wlr_scene_buffer_set_backdrop_blur_ignore_transparent(buffer, false);
|
||||
if (blur_optimized) {
|
||||
if (config.blur_optimized) {
|
||||
wlr_scene_buffer_set_backdrop_blur_optimized(buffer, true);
|
||||
} else {
|
||||
wlr_scene_buffer_set_backdrop_blur_optimized(buffer, false);
|
||||
|
|
@ -4021,13 +4035,13 @@ void init_client_properties(Client *c) {
|
|||
c->is_restoring_from_ov = 0;
|
||||
c->isurgent = 0;
|
||||
c->need_output_flush = 0;
|
||||
c->scroller_proportion = scroller_default_proportion;
|
||||
c->scroller_proportion = config.scroller_default_proportion;
|
||||
c->is_pending_open_animation = true;
|
||||
c->drag_to_tile = false;
|
||||
c->scratchpad_switching_mon = false;
|
||||
c->fake_no_border = false;
|
||||
c->focused_opacity = focused_opacity;
|
||||
c->unfocused_opacity = unfocused_opacity;
|
||||
c->focused_opacity = config.focused_opacity;
|
||||
c->unfocused_opacity = config.unfocused_opacity;
|
||||
c->nofocus = 0;
|
||||
c->nofadein = 0;
|
||||
c->nofadeout = 0;
|
||||
|
|
@ -4062,9 +4076,9 @@ void init_client_properties(Client *c) {
|
|||
c->next_in_stack = NULL;
|
||||
c->prev_in_stack = NULL;
|
||||
memset(c->oldmonname, 0, sizeof(c->oldmonname));
|
||||
memcpy(c->opacity_animation.initial_border_color, bordercolor,
|
||||
memcpy(c->opacity_animation.initial_border_color, config.bordercolor,
|
||||
sizeof(c->opacity_animation.initial_border_color));
|
||||
memcpy(c->opacity_animation.current_border_color, bordercolor,
|
||||
memcpy(c->opacity_animation.current_border_color, config.bordercolor,
|
||||
sizeof(c->opacity_animation.current_border_color));
|
||||
c->opacity_animation.initial_opacity = c->unfocused_opacity;
|
||||
c->opacity_animation.current_opacity = c->unfocused_opacity;
|
||||
|
|
@ -4094,7 +4108,7 @@ mapnotify(struct wl_listener *listener, void *data) {
|
|||
c->bw = 0;
|
||||
c->isnoborder = 1;
|
||||
} else {
|
||||
c->bw = borderpx;
|
||||
c->bw = config.borderpx;
|
||||
}
|
||||
|
||||
if (client_should_global(c)) {
|
||||
|
|
@ -4126,21 +4140,22 @@ mapnotify(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
|
||||
// extra node
|
||||
c->border = wlr_scene_rect_create(c->scene, 0, 0,
|
||||
c->isurgent ? urgentcolor : bordercolor);
|
||||
c->border = wlr_scene_rect_create(
|
||||
c->scene, 0, 0, c->isurgent ? config.urgentcolor : config.bordercolor);
|
||||
wlr_scene_node_lower_to_bottom(&c->border->node);
|
||||
wlr_scene_node_set_position(&c->border->node, 0, 0);
|
||||
wlr_scene_rect_set_corner_radius(c->border, border_radius,
|
||||
border_radius_location_default);
|
||||
wlr_scene_rect_set_corner_radius(c->border, config.border_radius,
|
||||
config.border_radius_location_default);
|
||||
wlr_scene_node_set_enabled(&c->border->node, true);
|
||||
|
||||
c->shadow = wlr_scene_shadow_create(c->scene, 0, 0, border_radius,
|
||||
shadows_blur, shadowscolor);
|
||||
c->shadow =
|
||||
wlr_scene_shadow_create(c->scene, 0, 0, config.border_radius,
|
||||
config.shadows_blur, config.shadowscolor);
|
||||
|
||||
wlr_scene_node_lower_to_bottom(&c->shadow->node);
|
||||
wlr_scene_node_set_enabled(&c->shadow->node, true);
|
||||
|
||||
if (new_is_master && selmon && !is_scroller_layout(selmon))
|
||||
if (config.new_is_master && selmon && !is_scroller_layout(selmon))
|
||||
// tile at the top
|
||||
wl_list_insert(&clients, &c->link); // 新窗口是master,头部入栈
|
||||
else if (selmon && is_scroller_layout(selmon) &&
|
||||
|
|
@ -4353,7 +4368,7 @@ void motionnotify(uint32_t time, struct wlr_input_device *device, double dx,
|
|||
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
||||
|
||||
/* Update selmon (even while dragging a window) */
|
||||
if (sloppyfocus)
|
||||
if (config.sloppyfocus)
|
||||
selmon = xytomon(cursor->x, cursor->y);
|
||||
}
|
||||
|
||||
|
|
@ -4389,7 +4404,8 @@ void motionnotify(uint32_t time, struct wlr_input_device *device, double dx,
|
|||
if (grabc->isfloating) {
|
||||
grabc->iscustomsize = 1;
|
||||
if (last_apply_drap_time == 0 ||
|
||||
time - last_apply_drap_time > drag_floating_refresh_interval) {
|
||||
time - last_apply_drap_time >
|
||||
config.drag_floating_refresh_interval) {
|
||||
resize_floating_window(grabc);
|
||||
last_apply_drap_time = time;
|
||||
}
|
||||
|
|
@ -4415,7 +4431,7 @@ void motionnotify(uint32_t time, struct wlr_input_device *device, double dx,
|
|||
should_lock = true;
|
||||
}
|
||||
|
||||
if (!(!edge_scroller_pointer_focus && c && c->mon &&
|
||||
if (!(!config.edge_scroller_pointer_focus && c && c->mon &&
|
||||
is_scroller_layout(c->mon) && !INSIDEMON(c)))
|
||||
pointerfocus(c, surface, sx, sy, time);
|
||||
|
||||
|
|
@ -4521,7 +4537,7 @@ void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy,
|
|||
uint32_t time) {
|
||||
struct timespec now;
|
||||
|
||||
if (sloppyfocus && !start_drag_window && c && time && c->scene &&
|
||||
if (config.sloppyfocus && !start_drag_window && c && time && c->scene &&
|
||||
c->scene->node.enabled && !c->animation.tagining &&
|
||||
(surface != seat->pointer_state.focused_surface) &&
|
||||
!client_is_unmanaged(c) && VISIBLEON(c, c->mon))
|
||||
|
|
@ -4647,7 +4663,7 @@ void rendermon(struct wl_listener *listener, void *data) {
|
|||
// 绘制客户端
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
need_more_frames = client_draw_frame(c) || need_more_frames;
|
||||
if (!animations && !grabc && c->configure_serial &&
|
||||
if (!config.animations && !grabc && c->configure_serial &&
|
||||
client_is_rendered_on_mon(c, m)) {
|
||||
monitor_check_skip_frame_timeout(m);
|
||||
goto skip;
|
||||
|
|
@ -4659,7 +4675,7 @@ void rendermon(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
|
||||
// 只有在需要帧时才构建和提交状态
|
||||
if (allow_tearing && frame_allow_tearing) {
|
||||
if (config.allow_tearing && frame_allow_tearing) {
|
||||
apply_tear_state(m);
|
||||
} else {
|
||||
wlr_scene_output_commit(m->scene_output, NULL);
|
||||
|
|
@ -4735,7 +4751,7 @@ void exchange_two_client(Client *c1, Client *c2) {
|
|||
float stack_proportion = 0.0f;
|
||||
|
||||
if (c1 == NULL || c2 == NULL ||
|
||||
(!exchange_cross_monitor && c1->mon != c2->mon)) {
|
||||
(!config.exchange_cross_monitor && c1->mon != c2->mon)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -4837,7 +4853,7 @@ void exchange_two_client(Client *c1, Client *c2) {
|
|||
}
|
||||
|
||||
// 处理跨监视器交换
|
||||
if (exchange_cross_monitor) {
|
||||
if (config.exchange_cross_monitor) {
|
||||
tmp_mon = c2->mon;
|
||||
tmp_tags = c2->tags;
|
||||
setmon(c2, c1->mon, c1->tags, false);
|
||||
|
|
@ -5017,7 +5033,7 @@ setfloating(Client *c, int32_t floating) {
|
|||
if (c->isfullscreen || c->ismaximizescreen) {
|
||||
c->isfullscreen = 0; // 清除窗口全屏标志
|
||||
c->ismaximizescreen = 0;
|
||||
c->bw = c->isnoborder ? 0 : borderpx;
|
||||
c->bw = c->isnoborder ? 0 : config.borderpx;
|
||||
}
|
||||
|
||||
exit_scroller_stack(c);
|
||||
|
|
@ -5031,11 +5047,13 @@ setfloating(Client *c, int32_t floating) {
|
|||
|
||||
// restore to the memeroy geom
|
||||
if (c->float_geom.width > 0 && c->float_geom.height > 0) {
|
||||
if (c->mon && c->float_geom.width >= c->mon->w.width - gappoh) {
|
||||
if (c->mon &&
|
||||
c->float_geom.width >= c->mon->w.width - config.gappoh) {
|
||||
c->float_geom.width = c->mon->w.width * 0.9;
|
||||
window_size_outofrange = true;
|
||||
}
|
||||
if (c->mon && c->float_geom.height >= c->mon->w.height - gappov) {
|
||||
if (c->mon &&
|
||||
c->float_geom.height >= c->mon->w.height - config.gappov) {
|
||||
c->float_geom.height = c->mon->w.height * 0.9;
|
||||
window_size_outofrange = true;
|
||||
}
|
||||
|
|
@ -5097,10 +5115,10 @@ setfloating(Client *c, int32_t floating) {
|
|||
}
|
||||
|
||||
void reset_maximizescreen_size(Client *c) {
|
||||
c->geom.x = c->mon->w.x + gappoh;
|
||||
c->geom.y = c->mon->w.y + gappov;
|
||||
c->geom.width = c->mon->w.width - 2 * gappoh;
|
||||
c->geom.height = c->mon->w.height - 2 * gappov;
|
||||
c->geom.x = c->mon->w.x + config.gappoh;
|
||||
c->geom.y = c->mon->w.y + config.gappov;
|
||||
c->geom.width = c->mon->w.width - 2 * config.gappoh;
|
||||
c->geom.height = c->mon->w.height - 2 * config.gappov;
|
||||
resize(c, c->geom, 0);
|
||||
}
|
||||
|
||||
|
|
@ -5146,16 +5164,16 @@ void setmaximizescreen(Client *c, int32_t maximizescreen) {
|
|||
if (c->isfloating)
|
||||
c->float_geom = c->geom;
|
||||
|
||||
maximizescreen_box.x = c->mon->w.x + gappoh;
|
||||
maximizescreen_box.y = c->mon->w.y + gappov;
|
||||
maximizescreen_box.width = c->mon->w.width - 2 * gappoh;
|
||||
maximizescreen_box.height = c->mon->w.height - 2 * gappov;
|
||||
wlr_scene_node_raise_to_top(&c->scene->node); // 将视图提升到顶层
|
||||
maximizescreen_box.x = c->mon->w.x + config.gappoh;
|
||||
maximizescreen_box.y = c->mon->w.y + config.gappov;
|
||||
maximizescreen_box.width = c->mon->w.width - 2 * config.gappoh;
|
||||
maximizescreen_box.height = c->mon->w.height - 2 * config.gappov;
|
||||
wlr_scene_node_raise_to_top(&c->scene->node);
|
||||
if (!is_scroller_layout(c->mon) || c->isfloating)
|
||||
resize(c, maximizescreen_box, 0);
|
||||
c->ismaximizescreen = 1;
|
||||
} else {
|
||||
c->bw = c->isnoborder ? 0 : borderpx;
|
||||
c->bw = c->isnoborder ? 0 : config.borderpx;
|
||||
c->ismaximizescreen = 0;
|
||||
if (c->isfloating)
|
||||
setfloating(c, 1);
|
||||
|
|
@ -5222,7 +5240,7 @@ void setfullscreen(Client *c, int32_t fullscreen) // 用自定义全屏代理自
|
|||
resize(c, c->mon->m, 1);
|
||||
c->isfullscreen = 1;
|
||||
} else {
|
||||
c->bw = c->isnoborder ? 0 : borderpx;
|
||||
c->bw = c->isnoborder ? 0 : config.borderpx;
|
||||
c->isfullscreen = 0;
|
||||
if (c->isfloating)
|
||||
setfloating(c, 1);
|
||||
|
|
@ -5285,9 +5303,8 @@ void reset_keyboard_layout(void) {
|
|||
return;
|
||||
}
|
||||
|
||||
// 现在安全地创建真正的keymap
|
||||
struct xkb_keymap *new_keymap = xkb_keymap_new_from_names(
|
||||
context, &xkb_rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
context, &config.xkb_rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
if (!new_keymap) {
|
||||
// 理论上这里不应该失败,因为前面已经验证过了
|
||||
wlr_log(WLR_ERROR,
|
||||
|
|
@ -5466,10 +5483,13 @@ void handle_print_status(struct wl_listener *listener, void *data) {
|
|||
|
||||
void setup(void) {
|
||||
|
||||
setenv("XCURSOR_SIZE", "24", 1);
|
||||
setenv("XDG_CURRENT_DESKTOP", "mango", 1);
|
||||
setenv("_JAVA_AWT_WM_NONREPARENTING", "1", 1);
|
||||
|
||||
parse_config();
|
||||
if (cli_debug_log) {
|
||||
config.log_level = WLR_DEBUG;
|
||||
}
|
||||
init_baked_points();
|
||||
|
||||
int32_t drm_fd, i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE};
|
||||
|
|
@ -5479,7 +5499,7 @@ void setup(void) {
|
|||
for (i = 0; i < LENGTH(sig); i++)
|
||||
sigaction(sig[i], &sa, NULL);
|
||||
|
||||
wlr_log_init(log_level, NULL);
|
||||
wlr_log_init(config.log_level, NULL);
|
||||
|
||||
/* The Wayland display is managed by libwayland. It handles accepting
|
||||
* clients from the Unix socket, manging Wayland globals, and so on. */
|
||||
|
|
@ -5515,7 +5535,7 @@ void setup(void) {
|
|||
|
||||
/* Initialize the scene graph used to lay out windows */
|
||||
scene = wlr_scene_create();
|
||||
root_bg = wlr_scene_rect_create(&scene->tree, 0, 0, rootcolor);
|
||||
root_bg = wlr_scene_rect_create(&scene->tree, 0, 0, config.rootcolor);
|
||||
for (i = 0; i < NUM_LAYERS; i++)
|
||||
layers[i] = wlr_scene_tree_create(&scene->tree);
|
||||
drag_icon = wlr_scene_tree_create(&scene->tree);
|
||||
|
|
@ -5540,7 +5560,7 @@ void setup(void) {
|
|||
scene, wlr_linux_dmabuf_v1_create_with_renderer(dpy, 4, drw));
|
||||
}
|
||||
|
||||
if (syncobj_enable && (drm_fd = wlr_renderer_get_drm_fd(drw)) >= 0 &&
|
||||
if (config.syncobj_enable && (drm_fd = wlr_renderer_get_drm_fd(drw)) >= 0 &&
|
||||
drw->features.timeline && backend->features.timeline)
|
||||
wlr_linux_drm_syncobj_manager_v1_create(dpy, 1, drm_fd);
|
||||
|
||||
|
|
@ -5659,9 +5679,11 @@ void setup(void) {
|
|||
* cursor images are available at all scale factors on the screen
|
||||
* (necessary for HiDPI support). Scaled cursors will be loaded with
|
||||
* each output. */
|
||||
// cursor_mgr = wlr_xcursor_manager_create(cursor_theme, 24);
|
||||
cursor_mgr = wlr_xcursor_manager_create(config.cursor_theme, cursor_size);
|
||||
|
||||
set_xcursor_env();
|
||||
|
||||
cursor_mgr =
|
||||
wlr_xcursor_manager_create(config.cursor_theme, config.cursor_size);
|
||||
/*
|
||||
* wlr_cursor *only* displays an image on screen. It does not move
|
||||
* around when the pointer moves. However, we can attach input devices
|
||||
|
|
@ -5739,10 +5761,10 @@ void setup(void) {
|
|||
wl_signal_add(&output_mgr->events.apply, &output_mgr_apply);
|
||||
wl_signal_add(&output_mgr->events.test, &output_mgr_test);
|
||||
|
||||
// blur
|
||||
wlr_scene_set_blur_data(scene, blur_params.num_passes, blur_params.radius,
|
||||
blur_params.noise, blur_params.brightness,
|
||||
blur_params.contrast, blur_params.saturation);
|
||||
wlr_scene_set_blur_data(
|
||||
scene, config.blur_params.num_passes, config.blur_params.radius,
|
||||
config.blur_params.noise, config.blur_params.brightness,
|
||||
config.blur_params.contrast, config.blur_params.saturation);
|
||||
|
||||
/* create text_input-, and input_method-protocol relevant globals */
|
||||
input_method_manager = wlr_input_method_manager_v2_create(dpy);
|
||||
|
|
@ -5775,7 +5797,8 @@ void setup(void) {
|
|||
* Initialise the XWayland X server.
|
||||
* It will be started when the first X client is started.
|
||||
*/
|
||||
xwayland = wlr_xwayland_create(dpy, compositor, !xwayland_persistence);
|
||||
xwayland =
|
||||
wlr_xwayland_create(dpy, compositor, !config.xwayland_persistence);
|
||||
if (xwayland) {
|
||||
wl_signal_add(&xwayland->events.ready, &xwayland_ready);
|
||||
wl_signal_add(&xwayland->events.new_surface, &new_xwayland_surface);
|
||||
|
|
@ -5860,7 +5883,7 @@ void overview_backup(Client *c) {
|
|||
c->isfullscreen = 0; // 清除窗口全屏标志
|
||||
c->ismaximizescreen = 0;
|
||||
}
|
||||
c->bw = c->isnoborder ? 0 : borderpx;
|
||||
c->bw = c->isnoborder ? 0 : config.borderpx;
|
||||
|
||||
client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT |
|
||||
WLR_EDGE_RIGHT);
|
||||
|
|
@ -5901,7 +5924,7 @@ void overview_restore(Client *c, const Arg *arg) {
|
|||
|
||||
if (c->bw == 0 &&
|
||||
!c->isfullscreen) { // 如果是在ov模式中创建的窗口,没有bw记录
|
||||
c->bw = c->isnoborder ? 0 : borderpx;
|
||||
c->bw = c->isnoborder ? 0 : config.borderpx;
|
||||
}
|
||||
|
||||
if (c->isfloating && !c->force_tiled_state) {
|
||||
|
|
@ -5911,7 +5934,7 @@ void overview_restore(Client *c, const Arg *arg) {
|
|||
|
||||
void handlecursoractivity(void) {
|
||||
wl_event_source_timer_update(hide_cursor_source,
|
||||
cursor_hide_timeout * 1000);
|
||||
config.cursor_hide_timeout * 1000);
|
||||
|
||||
if (!cursor_hidden)
|
||||
return;
|
||||
|
|
@ -6002,7 +6025,7 @@ void unmapnotify(struct wl_listener *listener, void *data) {
|
|||
Client *prev_in_stack = c->prev_in_stack;
|
||||
c->iskilling = 1;
|
||||
|
||||
if (animations && !c->is_clip_to_hide && !c->isminimized &&
|
||||
if (config.animations && !c->is_clip_to_hide && !c->isminimized &&
|
||||
(!c->mon || VISIBLEON(c, c->mon)))
|
||||
init_fadeout_client(c);
|
||||
|
||||
|
|
@ -6103,7 +6126,7 @@ void updatemons(struct wl_listener *listener, void *data) {
|
|||
* positions, focus, and the stored configuration in wlroots'
|
||||
* output-manager implementation.
|
||||
*/
|
||||
struct wlr_output_configuration_v1 *config =
|
||||
struct wlr_output_configuration_v1 *output_config =
|
||||
wlr_output_configuration_v1_create();
|
||||
Client *c = NULL;
|
||||
struct wlr_output_configuration_head_v1 *config_head;
|
||||
|
|
@ -6114,8 +6137,8 @@ void updatemons(struct wl_listener *listener, void *data) {
|
|||
wl_list_for_each(m, &mons, link) {
|
||||
if (m->wlr_output->enabled || m->asleep)
|
||||
continue;
|
||||
config_head =
|
||||
wlr_output_configuration_head_v1_create(config, m->wlr_output);
|
||||
config_head = wlr_output_configuration_head_v1_create(output_config,
|
||||
m->wlr_output);
|
||||
config_head->state.enabled = 0;
|
||||
/* Remove this output from the layout to avoid cursor enter inside
|
||||
* it */
|
||||
|
|
@ -6143,8 +6166,8 @@ void updatemons(struct wl_listener *listener, void *data) {
|
|||
wl_list_for_each(m, &mons, link) {
|
||||
if (!m->wlr_output->enabled)
|
||||
continue;
|
||||
config_head =
|
||||
wlr_output_configuration_head_v1_create(config, m->wlr_output);
|
||||
config_head = wlr_output_configuration_head_v1_create(output_config,
|
||||
m->wlr_output);
|
||||
|
||||
oldx = m->m.x;
|
||||
oldy = m->m.y;
|
||||
|
|
@ -6177,7 +6200,7 @@ void updatemons(struct wl_listener *listener, void *data) {
|
|||
*/
|
||||
wlr_scene_output_set_position(m->scene_output, m->m.x, m->m.y);
|
||||
|
||||
if (blur && m->blur) {
|
||||
if (config.blur && m->blur) {
|
||||
wlr_scene_node_set_position(&m->blur->node, m->m.x, m->m.y);
|
||||
wlr_scene_optimized_blur_set_size(m->blur, m->m.width, m->m.height);
|
||||
}
|
||||
|
|
@ -6230,7 +6253,7 @@ void updatemons(struct wl_listener *listener, void *data) {
|
|||
* it's at the wrong position after all. */
|
||||
wlr_cursor_move(cursor, NULL, 0, 0);
|
||||
|
||||
wlr_output_manager_v1_set_configuration(output_mgr, config);
|
||||
wlr_output_manager_v1_set_configuration(output_mgr, output_config);
|
||||
}
|
||||
|
||||
void updatetitle(struct wl_listener *listener, void *data) {
|
||||
|
|
@ -6256,7 +6279,7 @@ urgent(struct wl_listener *listener, void *data) {
|
|||
if (!c || !c->foreign_toplevel)
|
||||
return;
|
||||
|
||||
if (focus_on_activate && !c->istagsilent && c != selmon->sel) {
|
||||
if (config.focus_on_activate && !c->istagsilent && c != selmon->sel) {
|
||||
if (!(c->mon == selmon && c->tags & c->mon->tagset[c->mon->seltags]))
|
||||
view_in_mon(&(Arg){.ui = c->tags}, true, c->mon, true);
|
||||
focusclient(c, 1);
|
||||
|
|
@ -6355,7 +6378,7 @@ void handle_keyboard_shortcuts_inhibit_new_inhibitor(
|
|||
|
||||
struct wlr_keyboard_shortcuts_inhibitor_v1 *inhibitor = data;
|
||||
|
||||
if (allow_shortcuts_inhibit == SHORTCUTS_INHIBIT_DISABLE) {
|
||||
if (config.allow_shortcuts_inhibit == SHORTCUTS_INHIBIT_DISABLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -6475,7 +6498,7 @@ void activatex11(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
}
|
||||
|
||||
if (focus_on_activate && !c->istagsilent && c != selmon->sel) {
|
||||
if (config.focus_on_activate && !c->istagsilent && c != selmon->sel) {
|
||||
if (!(c->mon == selmon && c->tags & c->mon->tagset[c->mon->seltags]))
|
||||
view_in_mon(&(Arg){.ui = c->tags}, true, c->mon, true);
|
||||
wlr_xwayland_surface_activate(c->surface.xwayland, 1);
|
||||
|
|
@ -6621,7 +6644,7 @@ int32_t main(int32_t argc, char *argv[]) {
|
|||
if (c == 's') {
|
||||
startup_cmd = optarg;
|
||||
} else if (c == 'd') {
|
||||
log_level = WLR_DEBUG;
|
||||
cli_debug_log = true;
|
||||
} else if (c == 'v') {
|
||||
printf("mango " VERSION "\n");
|
||||
return EXIT_SUCCESS;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue