mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-05-03 06:46:38 -04:00
Merge branch 'mangowm:main' into main
This commit is contained in:
commit
1d10f08ca0
25 changed files with 261 additions and 89 deletions
2
.github/workflows/sync-website.yml
vendored
2
.github/workflows/sync-website.yml
vendored
|
|
@ -40,5 +40,5 @@ jobs:
|
||||||
git add apps/web/content/docs
|
git add apps/web/content/docs
|
||||||
git diff --staged --quiet || git commit \
|
git diff --staged --quiet || git commit \
|
||||||
-m "docs: content update from mangowm/mango" \
|
-m "docs: content update from mangowm/mango" \
|
||||||
-m "${{ github.event.head_commit.message }}\nSource: ${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}"
|
-m "${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}"
|
||||||
git push
|
git push
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ And then rebuild your system.
|
||||||
## Other
|
## Other
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone -b 0.19.2 https://gitlab.freedesktop.org/wlroots/wlroots.git
|
git clone -b 0.19.3 https://gitlab.freedesktop.org/wlroots/wlroots.git
|
||||||
cd wlroots
|
cd wlroots
|
||||||
meson build -Dprefix=/usr
|
meson build -Dprefix=/usr
|
||||||
sudo ninja -C build install
|
sudo ninja -C build install
|
||||||
|
|
|
||||||
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>
|
||||||
|
|
@ -90,6 +90,7 @@ bindr=Super,Super_L,spawn,rofi -show run
|
||||||
| :--- | :--- | :--- |
|
| :--- | :--- | :--- |
|
||||||
| `killclient` | - | Close the focused window. |
|
| `killclient` | - | Close the focused window. |
|
||||||
| `togglefloating` | - | Toggle floating state. |
|
| `togglefloating` | - | Toggle floating state. |
|
||||||
|
| `toggle_all_floating` | - | Toggle all visible clients floating state. |
|
||||||
| `togglefullscreen` | - | Toggle fullscreen. |
|
| `togglefullscreen` | - | Toggle fullscreen. |
|
||||||
| `togglefakefullscreen` | - | Toggle "fake" fullscreen (remains constrained). |
|
| `togglefakefullscreen` | - | Toggle "fake" fullscreen (remains constrained). |
|
||||||
| `togglemaximizescreen` | - | Maximize window (keep decoration/bar). |
|
| `togglemaximizescreen` | - | Maximize window (keep decoration/bar). |
|
||||||
|
|
@ -194,6 +195,16 @@ bind=NONE,XF86AudioMute,spawn,wpctl set-mute @DEFAULT_SINK@ toggle
|
||||||
bind=SHIFT,XF86AudioMute,spawn,wpctl set-mute @DEFAULT_SOURCE@ toggle
|
bind=SHIFT,XF86AudioMute,spawn,wpctl set-mute @DEFAULT_SOURCE@ toggle
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Playback
|
||||||
|
|
||||||
|
Requires: `playerctl`
|
||||||
|
|
||||||
|
```ini
|
||||||
|
bind=NONE,XF86AudioNext,spawn,playerctl next
|
||||||
|
bind=NONE,XF86AudioPrev,spawn,playerctl previous
|
||||||
|
bind=NONE,XF86AudioPlay,spawn,playerctl play-pause
|
||||||
|
```
|
||||||
|
|
||||||
### Floating Window Movement
|
### Floating Window Movement
|
||||||
|
|
||||||
| Command | Param | Description |
|
| Command | Param | Description |
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ source-optional=~/.config/mango/optional.conf
|
||||||
You can check your configuration for errors without starting mangowm:
|
You can check your configuration for errors without starting mangowm:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mango -p /path/to/config.conf
|
mango -c /path/to/config.conf -p
|
||||||
```
|
```
|
||||||
|
|
||||||
Use with `source-optional` for shared configs across different setups.
|
Use with `source-optional` for shared configs across different setups.
|
||||||
|
|
@ -60,8 +60,8 @@ You can define environment variables directly within your config file. These are
|
||||||
> **Warning:** Environment variables defined here will be **reset** every time you reload the configuration.
|
> **Warning:** Environment variables defined here will be **reset** every time you reload the configuration.
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
env=GTK_THEME,Adwaita:dark
|
env=QT_IM_MODULES,wayland;fcitx
|
||||||
env=XCURSOR_SIZE,24
|
env=XMODIFIERS,@im=fcitx
|
||||||
```
|
```
|
||||||
|
|
||||||
## Autostart
|
## Autostart
|
||||||
|
|
|
||||||
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>
|
||||||
|
|
@ -136,6 +136,7 @@ To use Fcitx5 or IBus, set these environment variables in your config file.
|
||||||
```ini
|
```ini
|
||||||
env=GTK_IM_MODULE,fcitx
|
env=GTK_IM_MODULE,fcitx
|
||||||
env=QT_IM_MODULE,fcitx
|
env=QT_IM_MODULE,fcitx
|
||||||
|
env=QT_IM_MODULES,wayland;fcitx
|
||||||
env=SDL_IM_MODULE,fcitx
|
env=SDL_IM_MODULE,fcitx
|
||||||
env=XMODIFIERS,@im=fcitx
|
env=XMODIFIERS,@im=fcitx
|
||||||
env=GLFW_IM_MODULE,ibus
|
env=GLFW_IM_MODULE,ibus
|
||||||
|
|
|
||||||
|
|
@ -48,11 +48,13 @@ monitorrule=name:Values,Parameter:Values,Parameter:Values
|
||||||
|
|
||||||
> **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.
|
> **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
|
### Examples
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
# Laptop display: 1080p, 60Hz, positioned at origin
|
# Laptop display: 1080p, 60Hz, positioned at origin
|
||||||
monitorrule=name:eDP-1,width:1920,height:1080,refresh:60,x:0,y:10
|
monitorrule=name:^eDP-1$,width:1920,height:1080,refresh:60,x:0,y:10
|
||||||
|
|
||||||
# Match by make and model instead of name
|
# 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
|
monitorrule=make:Chimei Innolux Corporation,model:0x15F5,width:1920,height:1080,refresh:60,x:0,y:0
|
||||||
|
|
@ -241,7 +243,7 @@ yay -S xwayland-satellite
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
env=DISPLAY,:2
|
env=DISPLAY,:2
|
||||||
exec=xwayland-satellite :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
|
monitorrule=name:eDP-1,width:1920,height:1080,refresh:60,x:0,y:0,scale:1.4,vrr:0,rr:0
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
title: Installation
|
title: Installation
|
||||||
description: Install mangowm on Arch, Fedora, Gentoo, Guix System, NixOS, PikaOS, or build from source.
|
description: Install mangowm on AerynOS, Arch, Fedora, Gentoo, Guix System, NixOS, PikaOS, or build from source.
|
||||||
---
|
---
|
||||||
|
|
||||||
## Package Installation
|
## Package Installation
|
||||||
|
|
@ -9,6 +9,18 @@ mangowm is available as a pre-built package on several distributions. Choose you
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### 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
|
### Arch Linux
|
||||||
|
|
||||||
mangowm is available in the **Arch User Repository (AUR)**.
|
mangowm is available in the **Arch User Repository (AUR)**.
|
||||||
|
|
@ -202,7 +214,7 @@ You will need to build `wlroots` and `scenefx` manually as well.
|
||||||
1. **Build wlroots**
|
1. **Build wlroots**
|
||||||
Clone and install the specific version required (check README for latest version).
|
Clone and install the specific version required (check README for latest version).
|
||||||
```bash
|
```bash
|
||||||
git clone -b 0.19.2 https://gitlab.freedesktop.org/wlroots/wlroots.git
|
git clone -b 0.19.3 https://gitlab.freedesktop.org/wlroots/wlroots.git
|
||||||
cd wlroots
|
cd wlroots
|
||||||
meson build -Dprefix=/usr
|
meson build -Dprefix=/usr
|
||||||
sudo ninja -C build install
|
sudo ninja -C build install
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
{
|
{
|
||||||
"title": "mangowm",
|
"title": "mangowm",
|
||||||
"pages": [
|
"pages": [
|
||||||
|
"---Getting Started---",
|
||||||
"index",
|
"index",
|
||||||
"installation",
|
"installation",
|
||||||
"quick-start",
|
"quick-start",
|
||||||
|
"---Configuration---",
|
||||||
"configuration",
|
"configuration",
|
||||||
"visuals",
|
"visuals",
|
||||||
"window-management",
|
"window-management",
|
||||||
"bindings",
|
"bindings",
|
||||||
|
"---Reference---",
|
||||||
"ipc",
|
"ipc",
|
||||||
"faq"
|
"faq"
|
||||||
]
|
]
|
||||||
|
|
|
||||||
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>
|
||||||
|
|
@ -54,6 +54,3 @@ Set the size and theme of your mouse cursor.
|
||||||
cursor_size=24
|
cursor_size=24
|
||||||
cursor_theme=Adwaita
|
cursor_theme=Adwaita
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Tip:** You may also want to set the `XCURSOR_SIZE` environment variable to match:
|
|
||||||
> `env=XCURSOR_SIZE,24`
|
|
||||||
|
|
|
||||||
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>
|
||||||
|
|
@ -27,10 +27,3 @@ When in overview mode:
|
||||||
|
|
||||||
- **Left mouse button** — Jump to (focus) a window.
|
- **Left mouse button** — Jump to (focus) a window.
|
||||||
- **Right mouse button** — Close a window.
|
- **Right mouse button** — Close a window.
|
||||||
|
|
||||||
To enable this behavior, add the following mouse bindings to your config:
|
|
||||||
|
|
||||||
```ini
|
|
||||||
mousebind=NONE,btn_left,toggleoverview,1
|
|
||||||
mousebind=NONE,btn_right,killclient,0
|
|
||||||
```
|
|
||||||
|
|
|
||||||
|
|
@ -179,6 +179,7 @@ tagrule=id:Values,monitor_make:xxx,monitor_model:xxx,Parameter:Values
|
||||||
| `monitor_serial` | string | monitor serial | Match by monitor serial number |
|
| `monitor_serial` | string | monitor serial | Match by monitor serial number |
|
||||||
| `layout_name` | string | layout name | Layout name to set |
|
| `layout_name` | string | layout name | Layout name to set |
|
||||||
| `no_render_border` | integer | `0` / `1` | Disable render border |
|
| `no_render_border` | integer | `0` / `1` | Disable render border |
|
||||||
|
| `open_as_floating` | integer | `0` / `1` | New open window will be floating|
|
||||||
| `no_hide` | integer | `0` / `1` | Not hide even if the tag is empty |
|
| `no_hide` | integer | `0` / `1` | Not hide even if the tag is empty |
|
||||||
| `nmaster` | integer | 0, 99 | Number of master windows |
|
| `nmaster` | integer | 0, 99 | Number of master windows |
|
||||||
| `mfact` | float | 0.1–0.9 | Master area factor |
|
| `mfact` | float | 0.1–0.9 | Master area factor |
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
project('mango', ['c', 'cpp'],
|
project('mango', ['c', 'cpp'],
|
||||||
version : '0.12.6',
|
version : '0.12.7',
|
||||||
)
|
)
|
||||||
|
|
||||||
subdir('protocols')
|
subdir('protocols')
|
||||||
|
|
|
||||||
|
|
@ -569,12 +569,12 @@ int32_t main(int32_t argc, char *argv[]) {
|
||||||
mode = WATCH;
|
mode = WATCH;
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
if (mode == SET)
|
if (mode == GET || mode == WATCH)
|
||||||
|
oflag = 1;
|
||||||
|
else if (mode == SET)
|
||||||
output_name = EARGF(usage());
|
output_name = EARGF(usage());
|
||||||
else
|
else
|
||||||
output_name = ARGF();
|
output_name = ARGF();
|
||||||
if (!output_name)
|
|
||||||
oflag = 1;
|
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
tflag = 1;
|
tflag = 1;
|
||||||
|
|
|
||||||
|
|
@ -67,8 +67,8 @@ stdenv.mkDerivation {
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
mainProgram = "mango";
|
mainProgram = "mango";
|
||||||
description = "A streamlined but feature-rich Wayland compositor";
|
description = "Practical and Powerful wayland compositor (dwm but wayland)";
|
||||||
homepage = "https://github.com/DreamMaoMao/mango";
|
homepage = "https://github.com/mangowm/mango";
|
||||||
license = lib.licenses.gpl3Plus;
|
license = lib.licenses.gpl3Plus;
|
||||||
maintainers = [];
|
maintainers = [];
|
||||||
platforms = lib.platforms.unix;
|
platforms = lib.platforms.unix;
|
||||||
|
|
|
||||||
|
|
@ -723,6 +723,8 @@ void client_animation_next_tick(Client *c) {
|
||||||
|
|
||||||
c->is_pending_open_animation = false;
|
c->is_pending_open_animation = false;
|
||||||
|
|
||||||
|
client_apply_clip(c, factor);
|
||||||
|
|
||||||
if (animation_passed >= 1.0) {
|
if (animation_passed >= 1.0) {
|
||||||
|
|
||||||
// clear the open action state
|
// clear the open action state
|
||||||
|
|
@ -752,8 +754,6 @@ void client_animation_next_tick(Client *c) {
|
||||||
// end flush in next frame, not the current frame
|
// end flush in next frame, not the current frame
|
||||||
c->need_output_flush = false;
|
c->need_output_flush = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
client_apply_clip(c, factor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_fadeout_client(Client *c) {
|
void init_fadeout_client(Client *c) {
|
||||||
|
|
|
||||||
|
|
@ -168,6 +168,7 @@ typedef struct {
|
||||||
float mfact;
|
float mfact;
|
||||||
int32_t nmaster;
|
int32_t nmaster;
|
||||||
int32_t no_render_border;
|
int32_t no_render_border;
|
||||||
|
int32_t open_as_floating;
|
||||||
int32_t no_hide;
|
int32_t no_hide;
|
||||||
} ConfigTagRule;
|
} ConfigTagRule;
|
||||||
|
|
||||||
|
|
@ -634,9 +635,14 @@ uint32_t parse_mod(const char *mod_str) {
|
||||||
// 分割处理每个部分
|
// 分割处理每个部分
|
||||||
token = strtok_r(input_copy, "+", &saveptr);
|
token = strtok_r(input_copy, "+", &saveptr);
|
||||||
while (token != NULL) {
|
while (token != NULL) {
|
||||||
// 去除空白
|
// 去除前后空白
|
||||||
while (*token == ' ' || *token == '\t')
|
trim_whitespace(token);
|
||||||
token++;
|
|
||||||
|
// 如果 token 变成空字符串则跳过
|
||||||
|
if (*token == '\0') {
|
||||||
|
token = strtok_r(NULL, "+", &saveptr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (strncmp(token, "code:", 5) == 0) {
|
if (strncmp(token, "code:", 5) == 0) {
|
||||||
// 处理 code: 形式
|
// 处理 code: 形式
|
||||||
|
|
@ -1197,6 +1203,8 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value,
|
||||||
} else if (strcmp(func_name, "scroller_stack") == 0) {
|
} else if (strcmp(func_name, "scroller_stack") == 0) {
|
||||||
func = scroller_stack;
|
func = scroller_stack;
|
||||||
(*arg).i = parse_direction(arg_value);
|
(*arg).i = parse_direction(arg_value);
|
||||||
|
} else if (strcmp(func_name, "toggle_all_floating") == 0) {
|
||||||
|
func = toggle_all_floating;
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -1900,6 +1908,7 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
rule->nmaster = 0;
|
rule->nmaster = 0;
|
||||||
rule->mfact = 0.0f;
|
rule->mfact = 0.0f;
|
||||||
rule->no_render_border = 0;
|
rule->no_render_border = 0;
|
||||||
|
rule->open_as_floating = 0;
|
||||||
rule->no_hide = 0;
|
rule->no_hide = 0;
|
||||||
|
|
||||||
bool parse_error = false;
|
bool parse_error = false;
|
||||||
|
|
@ -1928,6 +1937,8 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
rule->monitor_serial = strdup(val);
|
rule->monitor_serial = strdup(val);
|
||||||
} else if (strcmp(key, "no_render_border") == 0) {
|
} else if (strcmp(key, "no_render_border") == 0) {
|
||||||
rule->no_render_border = CLAMP_INT(atoi(val), 0, 1);
|
rule->no_render_border = CLAMP_INT(atoi(val), 0, 1);
|
||||||
|
} else if (strcmp(key, "open_as_floating") == 0) {
|
||||||
|
rule->open_as_floating = CLAMP_INT(atoi(val), 0, 1);
|
||||||
} else if (strcmp(key, "no_hide") == 0) {
|
} else if (strcmp(key, "no_hide") == 0) {
|
||||||
rule->no_hide = CLAMP_INT(atoi(val), 0, 1);
|
rule->no_hide = CLAMP_INT(atoi(val), 0, 1);
|
||||||
} else if (strcmp(key, "nmaster") == 0) {
|
} else if (strcmp(key, "nmaster") == 0) {
|
||||||
|
|
@ -3605,6 +3616,20 @@ void reapply_monitor_rules(void) {
|
||||||
updatemons(NULL, NULL);
|
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) {
|
void reapply_cursor_style(void) {
|
||||||
if (hide_cursor_source) {
|
if (hide_cursor_source) {
|
||||||
wl_event_source_timer_update(hide_cursor_source, 0);
|
wl_event_source_timer_update(hide_cursor_source, 0);
|
||||||
|
|
@ -3621,19 +3646,11 @@ void reapply_cursor_style(void) {
|
||||||
cursor_mgr = NULL;
|
cursor_mgr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_xcursor_env();
|
||||||
|
|
||||||
cursor_mgr =
|
cursor_mgr =
|
||||||
wlr_xcursor_manager_create(config.cursor_theme, config.cursor_size);
|
wlr_xcursor_manager_create(config.cursor_theme, config.cursor_size);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.cursor_theme) {
|
|
||||||
setenv("XCURSOR_THEME", config.cursor_theme, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Monitor *m = NULL;
|
Monitor *m = NULL;
|
||||||
wl_list_for_each(m, &mons, link) {
|
wl_list_for_each(m, &mons, link) {
|
||||||
wlr_xcursor_manager_load(cursor_mgr, m->wlr_output->scale);
|
wlr_xcursor_manager_load(cursor_mgr, m->wlr_output->scale);
|
||||||
|
|
@ -3775,6 +3792,8 @@ void parse_tagrule(Monitor *m) {
|
||||||
m->pertag->mfacts[tr.id] = tr.mfact;
|
m->pertag->mfacts[tr.id] = tr.mfact;
|
||||||
if (tr.no_render_border >= 0)
|
if (tr.no_render_border >= 0)
|
||||||
m->pertag->no_render_border[tr.id] = tr.no_render_border;
|
m->pertag->no_render_border[tr.id] = tr.no_render_border;
|
||||||
|
if (tr.open_as_floating >= 0)
|
||||||
|
m->pertag->open_as_floating[tr.id] = tr.open_as_floating;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,3 +70,4 @@ int32_t disable_monitor(const Arg *arg);
|
||||||
int32_t enable_monitor(const Arg *arg);
|
int32_t enable_monitor(const Arg *arg);
|
||||||
int32_t toggle_monitor(const Arg *arg);
|
int32_t toggle_monitor(const Arg *arg);
|
||||||
int32_t scroller_stack(const Arg *arg);
|
int32_t scroller_stack(const Arg *arg);
|
||||||
|
int32_t toggle_all_floating(const Arg *arg);
|
||||||
|
|
@ -1870,3 +1870,27 @@ int32_t scroller_stack(const Arg *arg) {
|
||||||
arrange(selmon, false, false);
|
arrange(selmon, false, false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t toggle_all_floating(const Arg *arg) {
|
||||||
|
if (!selmon || !selmon->sel)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Client *c = NULL;
|
||||||
|
bool should_floating = !selmon->sel->isfloating;
|
||||||
|
|
||||||
|
wl_list_for_each(c, &clients, link) {
|
||||||
|
if (VISIBLEON(c, selmon)) {
|
||||||
|
|
||||||
|
if (c->isfloating && !should_floating) {
|
||||||
|
c->old_master_inner_per = 0.0f;
|
||||||
|
c->old_stack_inner_per = 0.0f;
|
||||||
|
set_size_per(selmon, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->isfloating != should_floating) {
|
||||||
|
setfloating(c, should_floating);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,12 @@
|
||||||
bool check_hit_no_border(Client *c) {
|
bool check_hit_no_border(Client *c) {
|
||||||
int32_t i;
|
|
||||||
bool hit_no_border = false;
|
bool hit_no_border = false;
|
||||||
if (!render_border) {
|
if (!render_border) {
|
||||||
hit_no_border = true;
|
hit_no_border = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < config.tag_rules_count; i++) {
|
if (c->mon && !c->mon->isoverview &&
|
||||||
if (c->tags & (1 << (config.tag_rules[i].id - 1)) &&
|
c->mon->pertag->no_render_border[get_tags_first_tag_num(c->tags)]) {
|
||||||
config.tag_rules[i].no_render_border) {
|
hit_no_border = true;
|
||||||
hit_no_border = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.no_border_when_single && c && c->mon &&
|
if (config.no_border_when_single && c && c->mon &&
|
||||||
|
|
@ -19,6 +16,7 @@ bool check_hit_no_border(Client *c) {
|
||||||
}
|
}
|
||||||
return hit_no_border;
|
return hit_no_border;
|
||||||
}
|
}
|
||||||
|
|
||||||
Client *termforwin(Client *w) {
|
Client *termforwin(Client *w) {
|
||||||
Client *c = NULL;
|
Client *c = NULL;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,9 @@ void restore_size_per(Monitor *m, Client *c) {
|
||||||
if (!m || !c)
|
if (!m || !c)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!m->wlr_output->enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
wl_list_for_each(fc, &clients, link) {
|
wl_list_for_each(fc, &clients, link) {
|
||||||
if (VISIBLEON(fc, m) && ISTILED(fc)) {
|
if (VISIBLEON(fc, m) && ISTILED(fc)) {
|
||||||
fc->old_ismaster = fc->ismaster;
|
fc->old_ismaster = fc->ismaster;
|
||||||
|
|
@ -811,11 +814,6 @@ void pre_caculate_before_arrange(Monitor *m, bool want_animation,
|
||||||
int32_t master_num = 0;
|
int32_t master_num = 0;
|
||||||
int32_t stack_num = 0;
|
int32_t stack_num = 0;
|
||||||
|
|
||||||
if (!m)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!m->wlr_output->enabled)
|
|
||||||
return;
|
|
||||||
m->visible_clients = 0;
|
m->visible_clients = 0;
|
||||||
m->visible_tiling_clients = 0;
|
m->visible_tiling_clients = 0;
|
||||||
m->visible_scroll_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
|
void // 17
|
||||||
arrange(Monitor *m, bool want_animation, bool from_view) {
|
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);
|
pre_caculate_before_arrange(m, want_animation, from_view, false);
|
||||||
|
|
||||||
if (m->isoverview) {
|
if (m->isoverview) {
|
||||||
|
|
|
||||||
104
src/mango.c
104
src/mango.c
|
|
@ -913,8 +913,13 @@ static KeyMode keymode = {
|
||||||
.isdefault = true,
|
.isdefault = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
static char *env_vars[] = {"DISPLAY", "WAYLAND_DISPLAY", "XDG_CURRENT_DESKTOP",
|
static char *env_vars[] = {"DISPLAY",
|
||||||
"XDG_SESSION_TYPE", NULL};
|
"WAYLAND_DISPLAY",
|
||||||
|
"XDG_CURRENT_DESKTOP",
|
||||||
|
"XDG_SESSION_TYPE",
|
||||||
|
"XCURSOR_THEME",
|
||||||
|
"XCURSOR_SIZE",
|
||||||
|
NULL};
|
||||||
static struct {
|
static struct {
|
||||||
enum wp_cursor_shape_device_v1_shape shape;
|
enum wp_cursor_shape_device_v1_shape shape;
|
||||||
struct wlr_surface *surface;
|
struct wlr_surface *surface;
|
||||||
|
|
@ -929,8 +934,9 @@ struct Pertag {
|
||||||
uint32_t curtag, prevtag; /* current and previous tag */
|
uint32_t curtag, prevtag; /* current and previous tag */
|
||||||
int32_t nmasters[LENGTH(tags) + 1]; /* number of windows in master area */
|
int32_t nmasters[LENGTH(tags) + 1]; /* number of windows in master area */
|
||||||
float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */
|
float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */
|
||||||
bool no_hide[LENGTH(tags) + 1]; /* no_hide per tag */
|
int32_t no_hide[LENGTH(tags) + 1]; /* no_hide per tag */
|
||||||
bool no_render_border[LENGTH(tags) + 1]; /* no_render_border per tag */
|
int32_t no_render_border[LENGTH(tags) + 1]; /* no_render_border per tag */
|
||||||
|
int32_t open_as_floating[LENGTH(tags) + 1]; /* open_as_floating per tag */
|
||||||
const Layout
|
const Layout
|
||||||
*ltidxs[LENGTH(tags) + 1]; /* matrix of tags and layouts indexes */
|
*ltidxs[LENGTH(tags) + 1]; /* matrix of tags and layouts indexes */
|
||||||
};
|
};
|
||||||
|
|
@ -1398,6 +1404,25 @@ void set_float_malposition(Client *tc) {
|
||||||
tc->float_geom.y = tc->geom.y = y;
|
tc->float_geom.y = tc->geom.y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void client_reset_mon_tags(Client *c, Monitor *mon, uint32_t newtags) {
|
||||||
|
if (!newtags && mon && !mon->isoverview) {
|
||||||
|
c->tags = mon->tagset[mon->seltags];
|
||||||
|
} else if (!newtags && mon && mon->isoverview) {
|
||||||
|
c->tags = mon->ovbk_current_tagset;
|
||||||
|
} else if (newtags) {
|
||||||
|
c->tags = newtags;
|
||||||
|
} else {
|
||||||
|
c->tags = mon->tagset[mon->seltags];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_match_tag_floating_rule(Client *c, Monitor *mon) {
|
||||||
|
if (c->tags && !c->isfloating && mon && !c->swallowedby &&
|
||||||
|
mon->pertag->open_as_floating[get_tags_first_tag_num(c->tags)]) {
|
||||||
|
c->isfloating = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void applyrules(Client *c) {
|
void applyrules(Client *c) {
|
||||||
/* rule matching */
|
/* rule matching */
|
||||||
const char *appid, *title;
|
const char *appid, *title;
|
||||||
|
|
@ -1522,6 +1547,7 @@ void applyrules(Client *c) {
|
||||||
|
|
||||||
int32_t fullscreen_state_backup =
|
int32_t fullscreen_state_backup =
|
||||||
c->isfullscreen || client_wants_fullscreen(c);
|
c->isfullscreen || client_wants_fullscreen(c);
|
||||||
|
|
||||||
setmon(c, mon, newtags,
|
setmon(c, mon, newtags,
|
||||||
!c->isopensilent &&
|
!c->isopensilent &&
|
||||||
!(client_is_x11_popup(c) && client_should_ignore_focus(c)) &&
|
!(client_is_x11_popup(c) && client_should_ignore_focus(c)) &&
|
||||||
|
|
@ -1529,6 +1555,11 @@ void applyrules(Client *c) {
|
||||||
(!c->istagsilent || !newtags ||
|
(!c->istagsilent || !newtags ||
|
||||||
newtags & mon->tagset[mon->seltags]));
|
newtags & mon->tagset[mon->seltags]));
|
||||||
|
|
||||||
|
if (!c->isfloating) {
|
||||||
|
c->old_stack_inner_per = c->stack_inner_per;
|
||||||
|
c->old_master_inner_per = c->master_inner_per;
|
||||||
|
}
|
||||||
|
|
||||||
if (c->mon &&
|
if (c->mon &&
|
||||||
!(c->mon == selmon && c->tags & c->mon->tagset[c->mon->seltags]) &&
|
!(c->mon == selmon && c->tags & c->mon->tagset[c->mon->seltags]) &&
|
||||||
!c->isopensilent && !c->istagsilent) {
|
!c->isopensilent && !c->istagsilent) {
|
||||||
|
|
@ -4045,9 +4076,9 @@ void init_client_properties(Client *c) {
|
||||||
c->master_mfact_per = 0.0f;
|
c->master_mfact_per = 0.0f;
|
||||||
c->master_inner_per = 0.0f;
|
c->master_inner_per = 0.0f;
|
||||||
c->stack_inner_per = 0.0f;
|
c->stack_inner_per = 0.0f;
|
||||||
c->old_stack_inner_per = 1.0f;
|
c->old_stack_inner_per = 0.0f;
|
||||||
c->old_master_inner_per = 1.0f;
|
c->old_master_inner_per = 0.0f;
|
||||||
c->old_master_mfact_per = 1.0f;
|
c->old_master_mfact_per = 0.0f;
|
||||||
c->isterm = 0;
|
c->isterm = 0;
|
||||||
c->allow_csd = 0;
|
c->allow_csd = 0;
|
||||||
c->force_maximize = 0;
|
c->force_maximize = 0;
|
||||||
|
|
@ -5018,12 +5049,12 @@ setfloating(Client *c, int32_t floating) {
|
||||||
|
|
||||||
if (floating == 1 && c != grabc) {
|
if (floating == 1 && c != grabc) {
|
||||||
|
|
||||||
if (c->isfullscreen || c->ismaximizescreen) {
|
if (c->isfullscreen) {
|
||||||
c->isfullscreen = 0; // 清除窗口全屏标志
|
c->isfullscreen = 0;
|
||||||
c->ismaximizescreen = 0;
|
client_set_fullscreen(c, 0);
|
||||||
c->bw = c->isnoborder ? 0 : config.borderpx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c->ismaximizescreen = 0;
|
||||||
exit_scroller_stack(c);
|
exit_scroller_stack(c);
|
||||||
|
|
||||||
// 重新计算居中的坐标
|
// 重新计算居中的坐标
|
||||||
|
|
@ -5065,7 +5096,8 @@ setfloating(Client *c, int32_t floating) {
|
||||||
// 让当前tag中的全屏窗口退出全屏参与平铺
|
// 让当前tag中的全屏窗口退出全屏参与平铺
|
||||||
wl_list_for_each(fc, &clients,
|
wl_list_for_each(fc, &clients,
|
||||||
link) if (fc && fc != c && VISIBLEON(fc, c->mon) &&
|
link) if (fc && fc != c && VISIBLEON(fc, c->mon) &&
|
||||||
c->tags & fc->tags && ISFULLSCREEN(fc)) {
|
c->tags & fc->tags && ISFULLSCREEN(fc) &&
|
||||||
|
old_floating_state) {
|
||||||
clear_fullscreen_flag(fc);
|
clear_fullscreen_flag(fc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5079,7 +5111,8 @@ setfloating(Client *c, int32_t floating) {
|
||||||
layers[c->isfloating ? LyrTop : LyrTile]);
|
layers[c->isfloating ? LyrTop : LyrTile]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!c->isfloating && old_floating_state) {
|
if (!c->isfloating && old_floating_state &&
|
||||||
|
(c->old_stack_inner_per > 0.0f || c->old_master_inner_per > 0.0f)) {
|
||||||
restore_size_per(c->mon, c);
|
restore_size_per(c->mon, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5098,6 +5131,12 @@ setfloating(Client *c, int32_t floating) {
|
||||||
}
|
}
|
||||||
|
|
||||||
arrange(c->mon, false, false);
|
arrange(c->mon, false, false);
|
||||||
|
|
||||||
|
if (!c->isfloating) {
|
||||||
|
c->old_master_inner_per = c->master_inner_per;
|
||||||
|
c->old_stack_inner_per = c->stack_inner_per;
|
||||||
|
}
|
||||||
|
|
||||||
setborder_color(c);
|
setborder_color(c);
|
||||||
printstatus();
|
printstatus();
|
||||||
}
|
}
|
||||||
|
|
@ -5144,14 +5183,13 @@ void setmaximizescreen(Client *c, int32_t maximizescreen) {
|
||||||
|
|
||||||
if (maximizescreen) {
|
if (maximizescreen) {
|
||||||
|
|
||||||
if (c->isfullscreen)
|
if (c->isfullscreen) {
|
||||||
setfullscreen(c, 0);
|
c->isfullscreen = 0;
|
||||||
|
client_set_fullscreen(c, 0);
|
||||||
|
}
|
||||||
|
|
||||||
exit_scroller_stack(c);
|
exit_scroller_stack(c);
|
||||||
|
|
||||||
if (c->isfloating)
|
|
||||||
c->float_geom = c->geom;
|
|
||||||
|
|
||||||
maximizescreen_box.x = c->mon->w.x + config.gappoh;
|
maximizescreen_box.x = c->mon->w.x + config.gappoh;
|
||||||
maximizescreen_box.y = c->mon->w.y + config.gappov;
|
maximizescreen_box.y = c->mon->w.y + config.gappov;
|
||||||
maximizescreen_box.width = c->mon->w.width - 2 * config.gappoh;
|
maximizescreen_box.width = c->mon->w.width - 2 * config.gappoh;
|
||||||
|
|
@ -5212,14 +5250,14 @@ void setfullscreen(Client *c, int32_t fullscreen) // 用自定义全屏代理自
|
||||||
client_set_fullscreen(c, fullscreen);
|
client_set_fullscreen(c, fullscreen);
|
||||||
|
|
||||||
if (fullscreen) {
|
if (fullscreen) {
|
||||||
if (c->ismaximizescreen)
|
|
||||||
setmaximizescreen(c, 0);
|
if (c->ismaximizescreen && !c->force_maximize) {
|
||||||
|
client_set_maximized(c, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
c->ismaximizescreen = 0;
|
||||||
|
|
||||||
exit_scroller_stack(c);
|
exit_scroller_stack(c);
|
||||||
|
|
||||||
if (c->isfloating)
|
|
||||||
c->float_geom = c->geom;
|
|
||||||
|
|
||||||
c->isfakefullscreen = 0;
|
c->isfakefullscreen = 0;
|
||||||
|
|
||||||
c->bw = 0;
|
c->bw = 0;
|
||||||
|
|
@ -5378,15 +5416,8 @@ void setmon(Client *c, Monitor *m, uint32_t newtags, bool focus) {
|
||||||
/* Make sure window actually overlaps with the monitor */
|
/* Make sure window actually overlaps with the monitor */
|
||||||
reset_foreign_tolevel(c);
|
reset_foreign_tolevel(c);
|
||||||
resize(c, c->geom, 0);
|
resize(c, c->geom, 0);
|
||||||
if (!newtags && !m->isoverview) {
|
client_reset_mon_tags(c, m, newtags);
|
||||||
c->tags = m->tagset[m->seltags];
|
check_match_tag_floating_rule(c, m);
|
||||||
} else if (!newtags && m->isoverview) {
|
|
||||||
c->tags = m->ovbk_current_tagset;
|
|
||||||
} else if (newtags) {
|
|
||||||
c->tags = newtags;
|
|
||||||
} else {
|
|
||||||
c->tags = m->tagset[m->seltags];
|
|
||||||
}
|
|
||||||
setfloating(c, c->isfloating);
|
setfloating(c, c->isfloating);
|
||||||
setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */
|
setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */
|
||||||
}
|
}
|
||||||
|
|
@ -5471,8 +5502,8 @@ void handle_print_status(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
void setup(void) {
|
void setup(void) {
|
||||||
|
|
||||||
setenv("XCURSOR_SIZE", "24", 1);
|
|
||||||
setenv("XDG_CURRENT_DESKTOP", "mango", 1);
|
setenv("XDG_CURRENT_DESKTOP", "mango", 1);
|
||||||
|
setenv("_JAVA_AWT_WM_NONREPARENTING", "1", 1);
|
||||||
|
|
||||||
parse_config();
|
parse_config();
|
||||||
if (cli_debug_log) {
|
if (cli_debug_log) {
|
||||||
|
|
@ -5657,10 +5688,11 @@ void setup(void) {
|
||||||
* cursor images are available at all scale factors on the screen
|
* cursor images are available at all scale factors on the screen
|
||||||
* (necessary for HiDPI support). Scaled cursors will be loaded with
|
* (necessary for HiDPI support). Scaled cursors will be loaded with
|
||||||
* each output. */
|
* each output. */
|
||||||
// cursor_mgr = wlr_xcursor_manager_create(cursor_theme, 24);
|
|
||||||
|
set_xcursor_env();
|
||||||
|
|
||||||
cursor_mgr =
|
cursor_mgr =
|
||||||
wlr_xcursor_manager_create(config.cursor_theme, config.cursor_size);
|
wlr_xcursor_manager_create(config.cursor_theme, config.cursor_size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* wlr_cursor *only* displays an image on screen. It does not move
|
* wlr_cursor *only* displays an image on screen. It does not move
|
||||||
* around when the pointer moves. However, we can attach input devices
|
* around when the pointer moves. However, we can attach input devices
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue