mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-03-13 05:34:08 -04:00
Compare commits
143 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d38197d7c3 | ||
|
|
a7461d9d5b | ||
|
|
1fc89d01eb | ||
|
|
db30977196 | ||
|
|
d441ca22f4 | ||
|
|
a607d63ae7 | ||
|
|
36fb9c017d | ||
|
|
a4ad8d0d19 | ||
|
|
89a0f7e315 | ||
|
|
cfe492fbc4 | ||
|
|
31284b4b5d | ||
|
|
09c1707931 | ||
|
|
d0eb7d7114 | ||
|
|
636060972d | ||
|
|
b1d744ad1f | ||
|
|
75c888bbe4 | ||
|
|
89a4ec83a0 | ||
|
|
fd68f188c6 | ||
|
|
63b9ffb1a4 | ||
|
|
95481623cb | ||
|
|
10d7e5c6e3 | ||
|
|
9a17a0279c | ||
|
|
11b4bb03bf | ||
|
|
6522e18d08 | ||
|
|
9df273cdf9 | ||
|
|
0f68187cd0 | ||
|
|
bf10fabfc2 | ||
|
|
7f99b5ff48 | ||
|
|
1e1d41e626 | ||
|
|
9aa2d3cd33 | ||
|
|
46e867deb9 | ||
|
|
ad754167b7 | ||
|
|
0673a9241d | ||
|
|
20dbffdfaf | ||
|
|
263b1845bb | ||
|
|
c403a47894 | ||
|
|
6cc7d16281 | ||
|
|
9922ed26c7 | ||
|
|
8c8d8025c7 | ||
|
|
008cb9726e | ||
|
|
243848f43e | ||
|
|
755ffe06af | ||
|
|
811610e481 | ||
|
|
e935af07c1 | ||
|
|
43965a1155 | ||
|
|
94380a3e07 | ||
|
|
835269f86b | ||
|
|
43114bbf8d | ||
|
|
b338391984 | ||
|
|
4787402b12 | ||
|
|
cbc344ab88 | ||
|
|
1dac96b426 | ||
|
|
6667708d9a | ||
|
|
43d0f0f54a | ||
|
|
bc5cf2c7d7 | ||
|
|
c344dfe7a2 | ||
|
|
e1c038ae08 | ||
|
|
6894a36019 | ||
|
|
5412bbe3b6 | ||
|
|
564df864bf | ||
|
|
a28647585f | ||
|
|
2f630c950e | ||
|
|
f8fa7a856c | ||
|
|
6b2d694b23 | ||
|
|
cad564ba56 | ||
|
|
ee8a7b5961 | ||
|
|
d1fd128981 | ||
|
|
3d680523d6 | ||
|
|
07aed60245 | ||
|
|
4620bc691f | ||
|
|
722f9f6876 | ||
|
|
595f9e3432 | ||
|
|
f0259c6285 | ||
|
|
2f12f46919 | ||
|
|
68075c0044 | ||
|
|
23d7b11e27 | ||
|
|
6924ca8512 | ||
|
|
259fdb3a87 | ||
|
|
c3dcee2c8e | ||
|
|
15729db193 | ||
|
|
fa88ebace0 | ||
|
|
112fb5c007 | ||
|
|
1158fb2e3c | ||
|
|
26a616e3d5 | ||
|
|
933638d1b8 | ||
|
|
f75efa1312 | ||
|
|
62ab00a7a3 | ||
|
|
7ccbeae8b8 | ||
|
|
49cb5a9d7e | ||
|
|
0696fe964d | ||
|
|
842b45b584 | ||
|
|
02067e3b1e | ||
|
|
fdd54afb7e | ||
|
|
91110efe0e | ||
|
|
89413aacf5 | ||
|
|
0fe87e6286 | ||
|
|
c05eec7f53 | ||
|
|
8a924494c6 | ||
|
|
711498490b | ||
|
|
f251615524 | ||
|
|
5ae8975b11 | ||
|
|
313adefd10 | ||
|
|
17acdae69c | ||
|
|
bc52b95c1e | ||
|
|
53ee82a726 | ||
|
|
8484093e32 | ||
|
|
b5a157038c | ||
|
|
783cb86c56 | ||
|
|
c7f90cbc69 | ||
|
|
b05bc1ce65 | ||
|
|
6b79a432a4 | ||
|
|
454145f6e0 | ||
|
|
6970315822 | ||
|
|
e8bf6380fb | ||
|
|
4820b7a8ab | ||
|
|
faf2e1e9da | ||
|
|
acf8363714 | ||
|
|
241afb4b97 | ||
|
|
5de87db8ca | ||
|
|
9b92f139c0 | ||
|
|
e658f5c90d | ||
|
|
3db2ac58b4 | ||
|
|
f8dfeedff1 | ||
|
|
2ca2ab739d | ||
|
|
9e5bccb457 | ||
|
|
2734d91e6a | ||
|
|
818652d20f | ||
|
|
4586319bef | ||
|
|
080dfaa3ae | ||
|
|
00a7e579c9 | ||
|
|
8e898417a7 | ||
|
|
65fcd58949 | ||
|
|
2bda8e3bf1 | ||
|
|
a4faf2c494 | ||
|
|
b0f839468c | ||
|
|
8ba259fbb7 | ||
|
|
16e361e1ca | ||
|
|
336f873d83 | ||
|
|
50b67ac539 | ||
|
|
0546a2d4c4 | ||
|
|
eb0607501d | ||
|
|
bcee63fa76 | ||
|
|
c2a7146168 |
30 changed files with 2881 additions and 1577 deletions
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
|
|
@ -16,7 +16,7 @@ jobs:
|
||||||
days-before-issue-stale: -1
|
days-before-issue-stale: -1
|
||||||
# 手动标记后,14 天后关闭
|
# 手动标记后,14 天后关闭
|
||||||
days-before-issue-close: 7
|
days-before-issue-close: 7
|
||||||
# 使用的标签(必须和你手动添加的标签一致)
|
# 使用的标签
|
||||||
stale-issue-label: "stale"
|
stale-issue-label: "stale"
|
||||||
# 自动关闭时自动加上的标签
|
# 自动关闭时自动加上的标签
|
||||||
close-issue-label: "automatic-closing"
|
close-issue-label: "automatic-closing"
|
||||||
|
|
|
||||||
81
README.md
81
README.md
|
|
@ -1,6 +1,6 @@
|
||||||
# Mango Wayland Compositor
|
# Mango Wayland Compositor
|
||||||
<div>
|
<div>
|
||||||
<img src="https://github.com/DreamMaoMao/mangowc/blob/main/assets/mango-transparency-256.png" alt="MangoWC Logo" width="120"/>
|
<img src="https://github.com/mangowm/mango/blob/main/assets/mango-transparency-256.png" alt="MangoWM Logo" width="120"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
This project's development is based on [dwl](https://codeberg.org/dwl/dwl/).
|
This project's development is based on [dwl](https://codeberg.org/dwl/dwl/).
|
||||||
|
|
@ -23,25 +23,22 @@ This project's development is based on [dwl](https://codeberg.org/dwl/dwl/).
|
||||||
- Ipc support(get/send message from/to compositor by external program)
|
- Ipc support(get/send message from/to compositor by external program)
|
||||||
- Hycov-like overview
|
- Hycov-like overview
|
||||||
- Window effects from scenefx (blur, shadow, corner radius, opacity)
|
- Window effects from scenefx (blur, shadow, corner radius, opacity)
|
||||||
|
- Zero flickering - every frame is perfect.
|
||||||
|
|
||||||
Master-Stack Layout
|
https://github.com/user-attachments/assets/bb83004a-0563-4b48-ad89-6461a9b78b1f
|
||||||
|
|
||||||
https://github.com/user-attachments/assets/a9d4776e-b50b-48fb-94ce-651d8a749b8a
|
# Mango's Vision
|
||||||
|
|
||||||
Scroller Layout
|
**Mango's primary goal is stability**: After months of testing and development—and aside from a few lingering GPU compatibility issues—it should now be stable enough. I don't plan on making many breaking changes.
|
||||||
|
|
||||||
https://github.com/user-attachments/assets/c9bf9415-fad1-4400-bcdc-3ad2d76de85a
|
**Mango's preference is practicality**: I tend to add features that genuinely help with daily workflows—things that make our work more convenient.
|
||||||
|
|
||||||
Layer animation
|
|
||||||
|
|
||||||
https://github.com/user-attachments/assets/014c893f-115c-4ae9-8342-f9ae3e9a0df0
|
|
||||||
|
|
||||||
|
**Mango won't cater to every user preference**: For niche feature requests, I'll take a wait-and-see approach. I'll only consider adding them if they get a significant number of upvotes.
|
||||||
|
|
||||||
# Our discord
|
# Our discord
|
||||||
[mangowc](https://discord.gg/CPjbDxesh5)
|
[mangowm](https://discord.gg/CPjbDxesh5)
|
||||||
|
|
||||||
# Supported layouts
|
# Supported layouts
|
||||||
|
|
||||||
- tile
|
- tile
|
||||||
- scroller
|
- scroller
|
||||||
- monocle
|
- monocle
|
||||||
|
|
@ -51,21 +48,20 @@ https://github.com/user-attachments/assets/014c893f-115c-4ae9-8342-f9ae3e9a0df0
|
||||||
- vertical_tile
|
- vertical_tile
|
||||||
- vertical_grid
|
- vertical_grid
|
||||||
- vertical_scroller
|
- vertical_scroller
|
||||||
|
- tgmix
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
|
[](https://repology.org/project/mangowm/versions)
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
- glibc
|
|
||||||
- wayland
|
- wayland
|
||||||
- wayland-protocols
|
- wayland-protocols
|
||||||
- libinput
|
- libinput
|
||||||
- libdrm
|
- libdrm
|
||||||
- libxkbcommon
|
- libxkbcommon
|
||||||
- pixman
|
- pixman
|
||||||
- git
|
|
||||||
- meson
|
|
||||||
- ninja
|
|
||||||
- libdisplay-info
|
- libdisplay-info
|
||||||
- libliftoff
|
- libliftoff
|
||||||
- hwdata
|
- hwdata
|
||||||
|
|
@ -75,9 +71,9 @@ https://github.com/user-attachments/assets/014c893f-115c-4ae9-8342-f9ae3e9a0df0
|
||||||
- libxcb
|
- libxcb
|
||||||
|
|
||||||
## Arch Linux
|
## Arch Linux
|
||||||
The package is in the Arch User Repository and is availble for manual download [here](https://aur.archlinux.org/packages/mangowc-git) or through a AUR helper like yay:
|
The package is in the Arch User Repository and is available for manual download [here](https://aur.archlinux.org/packages/mangowm-git) or through a AUR helper like yay:
|
||||||
```bash
|
```bash
|
||||||
yay -S mangowc-git
|
yay -S mangowm-git
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -91,12 +87,12 @@ eselect repository enable guru
|
||||||
emerge --sync guru
|
emerge --sync guru
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, add `gui-libs/scenefx` and `gui-wm/mangowc` to the `package.accept_keywords`.
|
Then, add `gui-libs/scenefx` and `gui-wm/mangowm` to the `package.accept_keywords`.
|
||||||
|
|
||||||
Finally, install the package:
|
Finally, install the package:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
emerge --ask --verbose gui-wm/mangowc
|
emerge --ask --verbose gui-wm/mangowm
|
||||||
```
|
```
|
||||||
|
|
||||||
## Fedora Linux
|
## Fedora Linux
|
||||||
|
|
@ -106,9 +102,38 @@ First, add the [Terra Repository](https://terra.fyralabs.com/).
|
||||||
Then, install the package:
|
Then, install the package:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
dnf install mangowc
|
dnf install mangowm
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Guix System
|
||||||
|
The package definition is described in the source repository.
|
||||||
|
First, add `mangowm` channel to `channels.scm` file:
|
||||||
|
|
||||||
|
```scheme
|
||||||
|
;; In $HOME/.config/guix/channels.scm
|
||||||
|
(cons (channel
|
||||||
|
(name 'mangowm)
|
||||||
|
(url "https://github.com/mangowm/mango.git")
|
||||||
|
(branch "main"))
|
||||||
|
... ;; Your other channels
|
||||||
|
%default-channels)
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, run `guix pull` and after update you can either run
|
||||||
|
`guix install mangowm` or add it to your configuration via:
|
||||||
|
|
||||||
|
```scheme
|
||||||
|
(use-modules (mangowm)) ;; Add mangowm module
|
||||||
|
|
||||||
|
;; Add mangowm to packages list
|
||||||
|
(packages (cons*
|
||||||
|
mangowm-git
|
||||||
|
... ;; Other packages you specified
|
||||||
|
%base-packages))
|
||||||
|
```
|
||||||
|
|
||||||
|
And then rebuild your system.
|
||||||
|
|
||||||
## Other
|
## Other
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -122,8 +147,8 @@ cd scenefx
|
||||||
meson build -Dprefix=/usr
|
meson build -Dprefix=/usr
|
||||||
sudo ninja -C build install
|
sudo ninja -C build install
|
||||||
|
|
||||||
git clone https://github.com/DreamMaoMao/mangowc.git
|
git clone https://github.com/mangowm/mango.git
|
||||||
cd mangowc
|
cd mangowm
|
||||||
meson build -Dprefix=/usr
|
meson build -Dprefix=/usr
|
||||||
sudo ninja -C build install
|
sudo ninja -C build install
|
||||||
```
|
```
|
||||||
|
|
@ -181,9 +206,9 @@ git clone https://github.com/DreamMaoMao/mango-config.git ~/.config/mango
|
||||||
|
|
||||||
## Config Documentation
|
## Config Documentation
|
||||||
|
|
||||||
Refer to the repo wiki [wiki](https://github.com/DreamMaoMao/mango/wiki/)
|
Refer to the repo wiki [wiki](https://github.com/mangowm/mango/wiki/)
|
||||||
|
|
||||||
or the website docs [docs](https://mangowc.vercel.app/docs)
|
or the website docs [docs](https://mangowm.github.io/)
|
||||||
|
|
||||||
# NixOS + Home-manager
|
# NixOS + Home-manager
|
||||||
|
|
||||||
|
|
@ -203,7 +228,7 @@ Here's an example of using the modules in a flake:
|
||||||
};
|
};
|
||||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||||
mango = {
|
mango = {
|
||||||
url = "github:DreamMaoMao/mango";
|
url = "github:mangowm/mango";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -265,9 +290,9 @@ Here's an example of using the modules in a flake:
|
||||||
|
|
||||||
To package mango for other distributions, you can check the reference setup for:
|
To package mango for other distributions, you can check the reference setup for:
|
||||||
|
|
||||||
- [nix](https://github.com/DreamMaoMao/mangowc/blob/main/nix/default.nix)
|
- [nix](https://github.com/mangowm/mango/blob/main/nix/default.nix)
|
||||||
- [arch](https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=mangowc-git).
|
- [arch](https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=mangowm-git).
|
||||||
- [gentoo](https://data.gpo.zugaina.org/guru/gui-wm/mangowc)
|
- [gentoo](https://data.gpo.zugaina.org/guru/gui-wm/mangowm)
|
||||||
|
|
||||||
You might need to package `scenefx` for your distribution, check availability [here](https://github.com/wlrfx/scenefx.git).
|
You might need to package `scenefx` for your distribution, check availability [here](https://github.com/wlrfx/scenefx.git).
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -240,12 +240,11 @@ bind=CTRL+ALT,Left,resizewin,-50,+0
|
||||||
bind=CTRL+ALT,Right,resizewin,+50,+0
|
bind=CTRL+ALT,Right,resizewin,+50,+0
|
||||||
|
|
||||||
# Mouse Button Bindings
|
# Mouse Button Bindings
|
||||||
# NONE mode key only work in ov mode
|
# btn_left and btn_right can't bind none mod key
|
||||||
mousebind=SUPER,btn_left,moveresize,curmove
|
mousebind=SUPER,btn_left,moveresize,curmove
|
||||||
mousebind=NONE,btn_middle,togglemaximizescreen,0
|
mousebind=NONE,btn_middle,togglemaximizescreen,0
|
||||||
mousebind=SUPER,btn_right,moveresize,curresize
|
mousebind=SUPER,btn_right,moveresize,curresize
|
||||||
mousebind=NONE,btn_left,toggleoverview,1
|
|
||||||
mousebind=NONE,btn_right,killclient,0
|
|
||||||
|
|
||||||
# Axis Bindings
|
# Axis Bindings
|
||||||
axisbind=SUPER,UP,viewtoleft_have_client
|
axisbind=SUPER,UP,viewtoleft_have_client
|
||||||
5
assets/mango-portals.conf
Normal file
5
assets/mango-portals.conf
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
[preferred]
|
||||||
|
default=gtk
|
||||||
|
org.freedesktop.impl.portal.ScreenCast=wlr
|
||||||
|
org.freedesktop.impl.portal.Screenshot=wlr
|
||||||
|
org.freedesktop.impl.portal.Inhibit=none
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Encoding=UTF-8
|
Encoding=UTF-8
|
||||||
Name=Mango
|
Name=Mango
|
||||||
|
DesktopNames=mango;wlroots
|
||||||
Comment=mango WM
|
Comment=mango WM
|
||||||
Exec=mango
|
Exec=mango
|
||||||
Icon=mango
|
Icon=mango
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
(define-module (mangowc)
|
(define-module (mangowm)
|
||||||
#:use-module (guix download)
|
#:use-module (guix download)
|
||||||
#:use-module (guix git-download)
|
#:use-module (guix git-download)
|
||||||
#:use-module (guix gexp)
|
#:use-module (guix gexp)
|
||||||
|
|
@ -18,11 +18,11 @@
|
||||||
#:use-module (guix licenses))
|
#:use-module (guix licenses))
|
||||||
|
|
||||||
|
|
||||||
(define-public mangowc-git
|
(define-public mangowm-git
|
||||||
(package
|
(package
|
||||||
(name "mangowc")
|
(name "mangowm")
|
||||||
(version "git")
|
(version "git")
|
||||||
(source (local-file "." "mangowc-checkout"
|
(source (local-file "." "mangowm-checkout"
|
||||||
#:recursive? #t
|
#:recursive? #t
|
||||||
#:select? (or (git-predicate (current-source-directory))
|
#:select? (or (git-predicate (current-source-directory))
|
||||||
(const #t))))
|
(const #t))))
|
||||||
|
|
@ -55,10 +55,13 @@
|
||||||
wlroots
|
wlroots
|
||||||
scenefx))
|
scenefx))
|
||||||
(native-inputs (list pkg-config wayland-protocols))
|
(native-inputs (list pkg-config wayland-protocols))
|
||||||
(home-page "https://github.com/DreamMaoMao/mangowc")
|
(home-page "https://github.com/DreamMaoMao/mangowm")
|
||||||
(synopsis "Wayland compositor based on wlroots and scenefx")
|
(synopsis "Wayland compositor based on wlroots and scenefx")
|
||||||
(description "A Wayland compositor based on wlroots and scenefx,
|
(description "A Wayland compositor based on wlroots and scenefx,
|
||||||
inspired by dwl but aiming to be more feature-rich.")
|
inspired by dwl but aiming to be more feature-rich.")
|
||||||
(license gpl3)))
|
(license gpl3)))
|
||||||
|
|
||||||
mangowc-git
|
(define-deprecated-package mangowc
|
||||||
|
mangowm-git)
|
||||||
|
|
||||||
|
mangowm-git
|
||||||
10
meson.build
10
meson.build
|
|
@ -1,5 +1,5 @@
|
||||||
project('mango', ['c', 'cpp'],
|
project('mango', ['c', 'cpp'],
|
||||||
version : '0.12.0',
|
version : '0.12.6',
|
||||||
)
|
)
|
||||||
|
|
||||||
subdir('protocols')
|
subdir('protocols')
|
||||||
|
|
@ -56,7 +56,7 @@ endif
|
||||||
if is_git_repo
|
if is_git_repo
|
||||||
# 如果是 Git 目录,获取 Commit Hash 和最新的 tag
|
# 如果是 Git 目录,获取 Commit Hash 和最新的 tag
|
||||||
commit_hash = run_command(git, 'rev-parse', '--short', 'HEAD', check : false).stdout().strip()
|
commit_hash = run_command(git, 'rev-parse', '--short', 'HEAD', check : false).stdout().strip()
|
||||||
latest_tag = run_command(git, 'describe', '--tags', '--abbrev=0', check : false).stdout().strip()
|
latest_tag = meson.project_version()
|
||||||
version_with_hash = '@0@(@1@)'.format(latest_tag, commit_hash)
|
version_with_hash = '@0@(@1@)'.format(latest_tag, commit_hash)
|
||||||
else
|
else
|
||||||
# 如果不是 Git 目录,使用项目版本号和 "release" 字符串
|
# 如果不是 Git 目录,使用项目版本号和 "release" 字符串
|
||||||
|
|
@ -147,5 +147,7 @@ executable('mmsg',
|
||||||
)
|
)
|
||||||
|
|
||||||
desktop_install_dir = join_paths(prefix, 'share/wayland-sessions')
|
desktop_install_dir = join_paths(prefix, 'share/wayland-sessions')
|
||||||
install_data('mango.desktop', install_dir : desktop_install_dir)
|
portal_install_dir = join_paths(prefix, 'share/xdg-desktop-portal')
|
||||||
install_data('config.conf', install_dir : join_paths(sysconfdir, 'mango'))
|
install_data('assets/mango.desktop', install_dir : desktop_install_dir)
|
||||||
|
install_data('assets/mango-portals.conf', install_dir : portal_install_dir)
|
||||||
|
install_data('assets/config.conf', install_dir : join_paths(sysconfdir, 'mango'))
|
||||||
|
|
|
||||||
46
mmsg/mmsg.c
46
mmsg/mmsg.c
|
|
@ -500,12 +500,48 @@ static const struct wl_registry_listener registry_listener = {
|
||||||
|
|
||||||
static void usage(void) {
|
static void usage(void) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"usage:"
|
"mmsg - MangoWM IPC\n"
|
||||||
"\t%s [-OTLq]\n"
|
"\n"
|
||||||
"\t%s [-o <output>] -s [-t <tags>] [-l <layout>] [-c <tags>] [-d "
|
"SYNOPSIS:\n"
|
||||||
|
"\tmmsg [-OTLq]\n"
|
||||||
|
"\tmmsg [-o <output>] -s [-t <tags>] [-l <layout>] [-c <tags>] [-d "
|
||||||
"<cmd>,<arg1>,<arg2>,<arg3>,<arg4>,<arg5>]\n"
|
"<cmd>,<arg1>,<arg2>,<arg3>,<arg4>,<arg5>]\n"
|
||||||
"\t%s [-o <output>] (-g | -w) [-OotlcvmfxekbA]\n",
|
"\tmmsg [-o <output>] (-g | -w) [-OotlcvmfxekbA]\n"
|
||||||
argv0, argv0, argv0);
|
"\n"
|
||||||
|
"OPERATION MODES:\n"
|
||||||
|
"\t-g Get values (tags, layout, focused client)\n"
|
||||||
|
"\t-s Set values (switch tags, layouts)\n"
|
||||||
|
"\t-w Watch mode (stream events)\n"
|
||||||
|
"\n"
|
||||||
|
"GENERAL OPTIONS:\n"
|
||||||
|
"\t-O Get all output (monitor) information\n"
|
||||||
|
"\t-T Get number of tags\n"
|
||||||
|
"\t-L Get all available layouts\n"
|
||||||
|
"\t-q Quit mango\n"
|
||||||
|
"\t-o <output> Select output (monitor)\n"
|
||||||
|
"\n"
|
||||||
|
"GET OPTIONS (used with -g or -w):\n"
|
||||||
|
"\t-O Get output name\n"
|
||||||
|
"\t-o Get output (monitor) focus information\n"
|
||||||
|
"\t-t Get selected tags\n"
|
||||||
|
"\t-l Get current layout\n"
|
||||||
|
"\t-c Get title and appid of focused clients\n"
|
||||||
|
"\t-v Get visibility of statusbar\n"
|
||||||
|
"\t-m Get fullscreen status\n"
|
||||||
|
"\t-f Get floating status\n"
|
||||||
|
"\t-x Get focused client geometry\n"
|
||||||
|
"\t-e Get name of last focused layer\n"
|
||||||
|
"\t-k Get current keyboard layout\n"
|
||||||
|
"\t-b Get current keybind mode\n"
|
||||||
|
"\t-A Get scale factor of monitor\n"
|
||||||
|
"\n"
|
||||||
|
"SET OPTIONS (used with -s):\n"
|
||||||
|
"\t-o <output> Select output (monitor)\n"
|
||||||
|
"\t-t <tags> Set selected tags (can be used with [+-^.] "
|
||||||
|
"modifiers)\n"
|
||||||
|
"\t-l <layout> Set current layout\n"
|
||||||
|
"\t-c <tags> Get title and appid of focused client\n"
|
||||||
|
"\t-d <cmd>,<args...> Dispatch internal command (max 5 args)\n");
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
wayland,
|
wayland,
|
||||||
wayland-protocols,
|
wayland-protocols,
|
||||||
wayland-scanner,
|
wayland-scanner,
|
||||||
xcbutilwm,
|
libxcb-wm,
|
||||||
xwayland,
|
xwayland,
|
||||||
meson,
|
meson,
|
||||||
ninja,
|
ninja,
|
||||||
|
|
@ -57,7 +57,7 @@ stdenv.mkDerivation {
|
||||||
]
|
]
|
||||||
++ lib.optionals enableXWayland [
|
++ lib.optionals enableXWayland [
|
||||||
libX11
|
libX11
|
||||||
xcbutilwm
|
libxcb-wm
|
||||||
xwayland
|
xwayland
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
wayland_scanner = find_program('wayland-scanner')
|
wayland_scanner = find_program('wayland-scanner')
|
||||||
wayland_protos_dep = dependency('wayland-protocols')
|
wayland_protos_dep = dependency('wayland-protocols')
|
||||||
wl_protocol_dir = wayland_protos_dep.get_pkgconfig_variable('pkgdatadir')
|
wl_protocol_dir = wayland_protos_dep.get_variable(pkgconfig:'pkgdatadir')
|
||||||
wayland_scanner_code = generator(
|
wayland_scanner_code = generator(
|
||||||
wayland_scanner,
|
wayland_scanner,
|
||||||
output: '@BASENAME@-protocol.c',
|
output: '@BASENAME@-protocol.c',
|
||||||
|
|
|
||||||
|
|
@ -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 set_client_corner_location(Client *c) {
|
||||||
enum corner_location current_corner_location = CORNER_LOCATION_ALL;
|
enum corner_location current_corner_location = CORNER_LOCATION_ALL;
|
||||||
struct wlr_box target_geom = animations ? c->animation.current : c->geom;
|
struct wlr_box target_geom =
|
||||||
if (target_geom.x + border_radius <= c->mon->m.x) {
|
config.animations ? c->animation.current : c->geom;
|
||||||
current_corner_location &= ~CORNER_LOCATION_LEFT; // 清除左标志位
|
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) {
|
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) {
|
if (target_geom.y + config.border_radius <= c->mon->m.y) {
|
||||||
current_corner_location &= ~CORNER_LOCATION_TOP; // 清除上标志位
|
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) {
|
c->mon->m.y + c->mon->m.height) {
|
||||||
current_corner_location &= ~CORNER_LOCATION_BOTTOM; // 清除下标志位
|
current_corner_location &= ~CORNER_LOCATION_BOTTOM;
|
||||||
}
|
}
|
||||||
return current_corner_location;
|
return current_corner_location;
|
||||||
}
|
}
|
||||||
|
|
@ -47,22 +48,23 @@ bool is_horizontal_right_stack_layout(Monitor *m) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t is_special_animaiton_rule(Client *c) {
|
int32_t is_special_animation_rule(Client *c) {
|
||||||
|
|
||||||
if (is_scroller_layout(c->mon) && !c->isfloating) {
|
if (is_scroller_layout(c->mon) && !c->isfloating) {
|
||||||
return DOWN;
|
return DOWN;
|
||||||
} else if (c->mon->visible_tiling_clients == 1 && !c->isfloating) {
|
} else if (c->mon->visible_tiling_clients == 1 && !c->isfloating) {
|
||||||
return DOWN;
|
return DOWN;
|
||||||
} else if (c->mon->visible_tiling_clients == 2 && !c->isfloating &&
|
} 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;
|
return RIGHT;
|
||||||
} else if (!c->isfloating && new_is_master &&
|
} else if (!c->isfloating && config.new_is_master &&
|
||||||
is_horizontal_stack_layout(c->mon)) {
|
is_horizontal_stack_layout(c->mon)) {
|
||||||
return LEFT;
|
return LEFT;
|
||||||
} else if (c->mon->visible_tiling_clients == 2 && !c->isfloating &&
|
} 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;
|
return LEFT;
|
||||||
} else if (!c->isfloating && new_is_master &&
|
} else if (!c->isfloating && config.new_is_master &&
|
||||||
is_horizontal_right_stack_layout(c->mon)) {
|
is_horizontal_right_stack_layout(c->mon)) {
|
||||||
return RIGHT;
|
return RIGHT;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -70,14 +72,15 @@ int32_t is_special_animaiton_rule(Client *c) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_client_open_animaiton(Client *c, struct wlr_box geo) {
|
void set_client_open_animation(Client *c, struct wlr_box geo) {
|
||||||
int32_t slide_direction;
|
int32_t slide_direction;
|
||||||
int32_t horizontal, horizontal_value;
|
int32_t horizontal, horizontal_value;
|
||||||
int32_t vertical, vertical_value;
|
int32_t vertical, vertical_value;
|
||||||
int32_t special_direction;
|
int32_t special_direction;
|
||||||
int32_t center_x, center_y;
|
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 &&
|
(c->animation_type_open &&
|
||||||
strcmp(c->animation_type_open, "fade") == 0)) {
|
strcmp(c->animation_type_open, "fade") == 0)) {
|
||||||
c->animainit_geom.width = geo.width;
|
c->animainit_geom.width = geo.width;
|
||||||
|
|
@ -86,17 +89,17 @@ void set_client_open_animaiton(Client *c, struct wlr_box geo) {
|
||||||
c->animainit_geom.y = geo.y;
|
c->animainit_geom.y = geo.y;
|
||||||
return;
|
return;
|
||||||
} else if ((!c->animation_type_open &&
|
} else if ((!c->animation_type_open &&
|
||||||
strcmp(animation_type_open, "zoom") == 0) ||
|
strcmp(config.animation_type_open, "zoom") == 0) ||
|
||||||
(c->animation_type_open &&
|
(c->animation_type_open &&
|
||||||
strcmp(c->animation_type_open, "zoom") == 0)) {
|
strcmp(c->animation_type_open, "zoom") == 0)) {
|
||||||
c->animainit_geom.width = geo.width * zoom_initial_ratio;
|
c->animainit_geom.width = geo.width * config.zoom_initial_ratio;
|
||||||
c->animainit_geom.height = geo.height * 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.x = geo.x + (geo.width - c->animainit_geom.width) / 2;
|
||||||
c->animainit_geom.y =
|
c->animainit_geom.y =
|
||||||
geo.y + (geo.height - c->animainit_geom.height) / 2;
|
geo.y + (geo.height - c->animainit_geom.height) / 2;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
special_direction = is_special_animaiton_rule(c);
|
special_direction = is_special_animation_rule(c);
|
||||||
center_x = c->geom.x + c->geom.width / 2;
|
center_x = c->geom.x + c->geom.width / 2;
|
||||||
center_y = c->geom.y + c->geom.height / 2;
|
center_y = c->geom.y + c->geom.height / 2;
|
||||||
if (special_direction == UNDIR) {
|
if (special_direction == UNDIR) {
|
||||||
|
|
@ -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)
|
if (wlr_xdg_popup_try_from_wlr_surface(surface) != NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wlr_scene_buffer_set_corner_radius(buffer, border_radius,
|
wlr_scene_buffer_set_corner_radius(buffer, config.border_radius,
|
||||||
buffer_data->corner_location);
|
buffer_data->corner_location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -241,7 +244,7 @@ void buffer_set_effect(Client *c, BufferData data) {
|
||||||
data.should_scale = false;
|
data.should_scale = false;
|
||||||
|
|
||||||
if (c->isnoradius || c->isfullscreen ||
|
if (c->isnoradius || c->isfullscreen ||
|
||||||
(no_radius_when_single && c->mon &&
|
(config.no_radius_when_single && c->mon &&
|
||||||
c->mon->visible_tiling_clients == 1)) {
|
c->mon->visible_tiling_clients == 1)) {
|
||||||
data.corner_location = CORNER_LOCATION_NONE;
|
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)
|
if (c->iskilling || !client_surface(c)->mapped || c->isnoshadow)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!shadows || (!c->isfloating && shadow_only_floating)) {
|
if (!config.shadows || (!c->isfloating && config.shadow_only_floating)) {
|
||||||
if (c->shadow->node.enabled)
|
if (c->shadow->node.enabled)
|
||||||
wlr_scene_node_set_enabled(&c->shadow->node, false);
|
wlr_scene_node_set_enabled(&c->shadow->node, false);
|
||||||
return;
|
return;
|
||||||
|
|
@ -266,7 +269,7 @@ void client_draw_shadow(Client *c) {
|
||||||
|
|
||||||
bool hit_no_border = check_hit_no_border(c);
|
bool hit_no_border = check_hit_no_border(c);
|
||||||
enum corner_location current_corner_location =
|
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)
|
c->mon->visible_tiling_clients == 1)
|
||||||
? CORNER_LOCATION_NONE
|
? CORNER_LOCATION_NONE
|
||||||
: CORNER_LOCATION_ALL;
|
: CORNER_LOCATION_ALL;
|
||||||
|
|
@ -276,9 +279,8 @@ void client_draw_shadow(Client *c) {
|
||||||
int32_t width, height;
|
int32_t width, height;
|
||||||
client_actual_size(c, &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 = {
|
struct wlr_box client_box = {
|
||||||
.x = bwoffset,
|
.x = bwoffset,
|
||||||
.y = bwoffset,
|
.y = bwoffset,
|
||||||
|
|
@ -287,22 +289,20 @@ void client_draw_shadow(Client *c) {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_box shadow_box = {
|
struct wlr_box shadow_box = {
|
||||||
.x = shadows_position_x + bwoffset,
|
.x = config.shadows_position_x + bwoffset,
|
||||||
.y = shadows_position_y + bwoffset,
|
.y = config.shadows_position_y + bwoffset,
|
||||||
.width = width + 2 * delta,
|
.width = width + 2 * delta,
|
||||||
.height = height + 2 * delta,
|
.height = height + 2 * delta,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_box intersection_box;
|
struct wlr_box intersection_box;
|
||||||
wlr_box_intersection(&intersection_box, &client_box, &shadow_box);
|
wlr_box_intersection(&intersection_box, &client_box, &shadow_box);
|
||||||
/* clipped region takes shadow relative coords, so we translate everything
|
intersection_box.x -= config.shadows_position_x + bwoffset;
|
||||||
* by its position */
|
intersection_box.y -= config.shadows_position_y + bwoffset;
|
||||||
intersection_box.x -= shadows_position_x + bwoffset;
|
|
||||||
intersection_box.y -= shadows_position_y + bwoffset;
|
|
||||||
|
|
||||||
struct clipped_region clipped_region = {
|
struct clipped_region clipped_region = {
|
||||||
.area = intersection_box,
|
.area = intersection_box,
|
||||||
.corner_radius = border_radius,
|
.corner_radius = config.border_radius,
|
||||||
.corners = current_corner_location,
|
.corners = current_corner_location,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -356,23 +356,23 @@ void apply_border(Client *c) {
|
||||||
|
|
||||||
bool hit_no_border = check_hit_no_border(c);
|
bool hit_no_border = check_hit_no_border(c);
|
||||||
enum corner_location current_corner_location;
|
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)) {
|
c->mon->visible_tiling_clients == 1)) {
|
||||||
current_corner_location = CORNER_LOCATION_NONE;
|
current_corner_location = CORNER_LOCATION_NONE;
|
||||||
} else {
|
} else {
|
||||||
current_corner_location = set_client_corner_location(c);
|
current_corner_location = set_client_corner_location(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hit_no_border && smartgaps) {
|
if (hit_no_border && config.smartgaps) {
|
||||||
c->bw = 0;
|
c->bw = 0;
|
||||||
c->fake_no_border = true;
|
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_rect_set_size(c->border, 0, 0);
|
||||||
wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw);
|
wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw);
|
||||||
c->fake_no_border = true;
|
c->fake_no_border = true;
|
||||||
return;
|
return;
|
||||||
} else if (!c->isfullscreen && VISIBLEON(c, c->mon)) {
|
} 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;
|
c->fake_no_border = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -434,14 +434,14 @@ void apply_border(Client *c) {
|
||||||
struct clipped_region clipped_region = {
|
struct clipped_region clipped_region = {
|
||||||
.area = {inner_surface_x, inner_surface_y, inner_surface_width,
|
.area = {inner_surface_x, inner_surface_y, inner_surface_width,
|
||||||
inner_surface_height},
|
inner_surface_height},
|
||||||
.corner_radius = border_radius,
|
.corner_radius = config.border_radius,
|
||||||
.corners = current_corner_location,
|
.corners = current_corner_location,
|
||||||
};
|
};
|
||||||
|
|
||||||
wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw);
|
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_rect_set_size(c->border, rect_width, rect_height);
|
||||||
wlr_scene_node_set_position(&c->border->node, rect_x, rect_y);
|
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);
|
current_corner_location);
|
||||||
wlr_scene_rect_set_clipped_region(c->border, clipped_region);
|
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 =
|
enum corner_location current_corner_location =
|
||||||
set_client_corner_location(c);
|
set_client_corner_location(c);
|
||||||
|
|
||||||
if (!animations) {
|
if (!config.animations) {
|
||||||
c->animation.running = false;
|
c->animation.running = false;
|
||||||
c->need_output_flush = false;
|
c->need_output_flush = false;
|
||||||
c->animainit_geom = c->current = c->pending = c->animation.current =
|
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 =
|
double opacity_eased_progress =
|
||||||
find_animation_curve_at(animation_passed, OPAFADEOUT);
|
find_animation_curve_at(animation_passed, OPAFADEOUT);
|
||||||
|
|
||||||
double percent = fadeout_begin_opacity -
|
double percent = config.fadeout_begin_opacity -
|
||||||
(opacity_eased_progress * fadeout_begin_opacity);
|
(opacity_eased_progress * config.fadeout_begin_opacity);
|
||||||
|
|
||||||
double opacity = MAX(percent, 0);
|
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,
|
wlr_scene_node_for_each_buffer(&c->scene->node,
|
||||||
scene_buffer_apply_opacity, &opacity);
|
scene_buffer_apply_opacity, &opacity);
|
||||||
|
|
||||||
if ((c->animation_type_close &&
|
if ((c->animation_type_close &&
|
||||||
strcmp(c->animation_type_close, "zoom") == 0) ||
|
strcmp(c->animation_type_close, "zoom") == 0) ||
|
||||||
(!c->animation_type_close &&
|
(!c->animation_type_close &&
|
||||||
strcmp(animation_type_close, "zoom") == 0)) {
|
strcmp(config.animation_type_close, "zoom") == 0)) {
|
||||||
|
|
||||||
buffer_data.width = width;
|
buffer_data.width = width;
|
||||||
buffer_data.height = height;
|
buffer_data.height = height;
|
||||||
|
|
@ -768,75 +768,75 @@ void init_fadeout_client(Client *c) {
|
||||||
if ((c->animation_type_close &&
|
if ((c->animation_type_close &&
|
||||||
strcmp(c->animation_type_close, "none") == 0) ||
|
strcmp(c->animation_type_close, "none") == 0) ||
|
||||||
(!c->animation_type_close &&
|
(!c->animation_type_close &&
|
||||||
strcmp(animation_type_close, "none") == 0)) {
|
strcmp(config.animation_type_close, "none") == 0)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Client *fadeout_cient = ecalloc(1, sizeof(*fadeout_cient));
|
Client *fadeout_client = ecalloc(1, sizeof(*fadeout_client));
|
||||||
|
|
||||||
wlr_scene_node_set_enabled(&c->scene->node, true);
|
wlr_scene_node_set_enabled(&c->scene->node, true);
|
||||||
client_set_border_color(c, bordercolor);
|
client_set_border_color(c, config.bordercolor);
|
||||||
fadeout_cient->scene =
|
fadeout_client->scene =
|
||||||
wlr_scene_tree_snapshot(&c->scene->node, layers[LyrFadeOut]);
|
wlr_scene_tree_snapshot(&c->scene->node, layers[LyrFadeOut]);
|
||||||
wlr_scene_node_set_enabled(&c->scene->node, false);
|
wlr_scene_node_set_enabled(&c->scene->node, false);
|
||||||
|
|
||||||
if (!fadeout_cient->scene) {
|
if (!fadeout_client->scene) {
|
||||||
free(fadeout_cient);
|
free(fadeout_client);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fadeout_cient->animation.duration = animation_duration_close;
|
fadeout_client->animation.duration = config.animation_duration_close;
|
||||||
fadeout_cient->geom = fadeout_cient->current =
|
fadeout_client->geom = fadeout_client->current =
|
||||||
fadeout_cient->animainit_geom = fadeout_cient->animation.initial =
|
fadeout_client->animainit_geom = fadeout_client->animation.initial =
|
||||||
c->animation.current;
|
c->animation.current;
|
||||||
fadeout_cient->mon = c->mon;
|
fadeout_client->mon = c->mon;
|
||||||
fadeout_cient->animation_type_close = c->animation_type_close;
|
fadeout_client->animation_type_close = c->animation_type_close;
|
||||||
fadeout_cient->animation.action = CLOSE;
|
fadeout_client->animation.action = CLOSE;
|
||||||
fadeout_cient->bw = c->bw;
|
fadeout_client->bw = c->bw;
|
||||||
fadeout_cient->nofadeout = c->nofadeout;
|
fadeout_client->nofadeout = c->nofadeout;
|
||||||
|
|
||||||
// 这里snap节点的坐标设置是使用的相对坐标,所以不能加上原来坐标
|
// 这里snap节点的坐标设置是使用的相对坐标,所以不能加上原来坐标
|
||||||
// 这跟普通node有区别
|
// 这跟普通node有区别
|
||||||
|
|
||||||
fadeout_cient->animation.initial.x = 0;
|
fadeout_client->animation.initial.x = 0;
|
||||||
fadeout_cient->animation.initial.y = 0;
|
fadeout_client->animation.initial.y = 0;
|
||||||
|
|
||||||
if ((!c->animation_type_close &&
|
if ((!c->animation_type_close &&
|
||||||
strcmp(animation_type_close, "fade") == 0) ||
|
strcmp(config.animation_type_close, "fade") == 0) ||
|
||||||
(c->animation_type_close &&
|
(c->animation_type_close &&
|
||||||
strcmp(c->animation_type_close, "fade") == 0)) {
|
strcmp(c->animation_type_close, "fade") == 0)) {
|
||||||
fadeout_cient->current.x = 0;
|
fadeout_client->current.x = 0;
|
||||||
fadeout_cient->current.y = 0;
|
fadeout_client->current.y = 0;
|
||||||
fadeout_cient->current.width = 0;
|
fadeout_client->current.width = 0;
|
||||||
fadeout_cient->current.height = 0;
|
fadeout_client->current.height = 0;
|
||||||
} else if ((c->animation_type_close &&
|
} else if ((c->animation_type_close &&
|
||||||
strcmp(c->animation_type_close, "slide") == 0) ||
|
strcmp(c->animation_type_close, "slide") == 0) ||
|
||||||
(!c->animation_type_close &&
|
(!c->animation_type_close &&
|
||||||
strcmp(animation_type_close, "slide") == 0)) {
|
strcmp(config.animation_type_close, "slide") == 0)) {
|
||||||
fadeout_cient->current.y =
|
fadeout_client->current.y =
|
||||||
c->geom.y + c->geom.height / 2 > c->mon->m.y + c->mon->m.height / 2
|
c->geom.y + c->geom.height / 2 > c->mon->m.y + c->mon->m.height / 2
|
||||||
? c->mon->m.height -
|
? c->mon->m.height -
|
||||||
(c->animation.current.y - c->mon->m.y) // down out
|
(c->animation.current.y - c->mon->m.y) // down out
|
||||||
: c->mon->m.y - c->geom.height; // up out
|
: c->mon->m.y - c->geom.height; // up out
|
||||||
fadeout_cient->current.x = 0; // x无偏差,垂直划出
|
fadeout_client->current.x = 0; // x无偏差,垂直划出
|
||||||
} else {
|
} else {
|
||||||
fadeout_cient->current.y =
|
fadeout_client->current.y =
|
||||||
(fadeout_cient->geom.height -
|
(fadeout_client->geom.height -
|
||||||
fadeout_cient->geom.height * zoom_end_ratio) /
|
fadeout_client->geom.height * config.zoom_end_ratio) /
|
||||||
2;
|
2;
|
||||||
fadeout_cient->current.x =
|
fadeout_client->current.x =
|
||||||
(fadeout_cient->geom.width -
|
(fadeout_client->geom.width -
|
||||||
fadeout_cient->geom.width * zoom_end_ratio) /
|
fadeout_client->geom.width * config.zoom_end_ratio) /
|
||||||
2;
|
2;
|
||||||
fadeout_cient->current.width =
|
fadeout_client->current.width =
|
||||||
fadeout_cient->geom.width * zoom_end_ratio;
|
fadeout_client->geom.width * config.zoom_end_ratio;
|
||||||
fadeout_cient->current.height =
|
fadeout_client->current.height =
|
||||||
fadeout_cient->geom.height * zoom_end_ratio;
|
fadeout_client->geom.height * config.zoom_end_ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
fadeout_cient->animation.time_started = get_now_in_ms();
|
fadeout_client->animation.time_started = get_now_in_ms();
|
||||||
wlr_scene_node_set_enabled(&fadeout_cient->scene->node, true);
|
wlr_scene_node_set_enabled(&fadeout_client->scene->node, true);
|
||||||
wl_list_insert(&fadeout_clients, &fadeout_cient->fadeout_link);
|
wl_list_insert(&fadeout_clients, &fadeout_client->fadeout_link);
|
||||||
|
|
||||||
// 请求刷新屏幕
|
// 请求刷新屏幕
|
||||||
request_fresh_all_monitors();
|
request_fresh_all_monitors();
|
||||||
|
|
@ -866,12 +866,11 @@ void client_set_pending_state(Client *c) {
|
||||||
if (!c || c->iskilling)
|
if (!c || c->iskilling)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// 判断是否需要动画
|
if (!config.animations) {
|
||||||
if (!animations) {
|
|
||||||
c->animation.should_animate = false;
|
c->animation.should_animate = false;
|
||||||
} else if (animations && c->animation.tagining) {
|
} else if (config.animations && c->animation.tagining) {
|
||||||
c->animation.should_animate = true;
|
c->animation.should_animate = true;
|
||||||
} else if (!animations || c == grabc ||
|
} else if (!config.animations || c == grabc ||
|
||||||
(!c->is_pending_open_animation &&
|
(!c->is_pending_open_animation &&
|
||||||
wlr_box_equal(&c->current, &c->pending))) {
|
wlr_box_equal(&c->current, &c->pending))) {
|
||||||
c->animation.should_animate = false;
|
c->animation.should_animate = false;
|
||||||
|
|
@ -882,7 +881,7 @@ void client_set_pending_state(Client *c) {
|
||||||
if (((c->animation_type_open &&
|
if (((c->animation_type_open &&
|
||||||
strcmp(c->animation_type_open, "none") == 0) ||
|
strcmp(c->animation_type_open, "none") == 0) ||
|
||||||
(!c->animation_type_open &&
|
(!c->animation_type_open &&
|
||||||
strcmp(animation_type_open, "none") == 0)) &&
|
strcmp(config.animation_type_open, "none") == 0)) &&
|
||||||
c->animation.action == OPEN) {
|
c->animation.action == OPEN) {
|
||||||
c->animation.duration = 0;
|
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.tagouting && wlr_box_equal(&c->geom, &c->current)) {
|
||||||
c->animation.action = c->animation.action;
|
c->animation.action = c->animation.action;
|
||||||
} else if (c->animation.tagouting) {
|
} else if (c->animation.tagouting) {
|
||||||
c->animation.duration = animation_duration_tag;
|
c->animation.duration = config.animation_duration_tag;
|
||||||
c->animation.action = TAG;
|
c->animation.action = TAG;
|
||||||
} else if (c->animation.tagining) {
|
} else if (c->animation.tagining) {
|
||||||
c->animation.duration = animation_duration_tag;
|
c->animation.duration = config.animation_duration_tag;
|
||||||
c->animation.action = TAG;
|
c->animation.action = TAG;
|
||||||
} else if (c->is_pending_open_animation) {
|
} else if (c->is_pending_open_animation) {
|
||||||
c->animation.duration = animation_duration_open;
|
c->animation.duration = config.animation_duration_open;
|
||||||
c->animation.action = OPEN;
|
c->animation.action = OPEN;
|
||||||
} else {
|
} else {
|
||||||
c->animation.duration = animation_duration_move;
|
c->animation.duration = config.animation_duration_move;
|
||||||
c->animation.action = MOVE;
|
c->animation.action = MOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -971,7 +970,7 @@ void resize(Client *c, struct wlr_box geo, int32_t interact) {
|
||||||
c->animainit_geom.height = c->animation.current.height;
|
c->animainit_geom.height = c->animation.current.height;
|
||||||
c->animainit_geom.width = c->animation.current.width;
|
c->animainit_geom.width = c->animation.current.width;
|
||||||
} else if (c->is_pending_open_animation) {
|
} else if (c->is_pending_open_animation) {
|
||||||
set_client_open_animaiton(c, c->geom);
|
set_client_open_animation(c, c->geom);
|
||||||
} else {
|
} else {
|
||||||
c->animainit_geom = c->animation.current;
|
c->animainit_geom = c->animation.current;
|
||||||
}
|
}
|
||||||
|
|
@ -981,7 +980,7 @@ void resize(Client *c, struct wlr_box geo, int32_t interact) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hit_no_border = check_hit_no_border(c);
|
bool hit_no_border = check_hit_no_border(c);
|
||||||
if (hit_no_border && smartgaps) {
|
if (hit_no_border && config.smartgaps) {
|
||||||
c->bw = 0;
|
c->bw = 0;
|
||||||
c->fake_no_border = true;
|
c->fake_no_border = true;
|
||||||
}
|
}
|
||||||
|
|
@ -990,6 +989,10 @@ void resize(Client *c, struct wlr_box geo, int32_t interact) {
|
||||||
c->configure_serial = client_set_size(c, c->geom.width - 2 * c->bw,
|
c->configure_serial = client_set_size(c, c->geom.width - 2 * c->bw,
|
||||||
c->geom.height - 2 * c->bw);
|
c->geom.height - 2 * c->bw);
|
||||||
|
|
||||||
|
if (c->configure_serial != 0) {
|
||||||
|
c->mon->resizing_count_pending++;
|
||||||
|
}
|
||||||
|
|
||||||
if (c == grabc) {
|
if (c == grabc) {
|
||||||
c->animation.running = false;
|
c->animation.running = false;
|
||||||
c->need_output_flush = false;
|
c->need_output_flush = false;
|
||||||
|
|
@ -1044,63 +1047,43 @@ bool client_draw_fadeout_frame(Client *c) {
|
||||||
void client_set_focused_opacity_animation(Client *c) {
|
void client_set_focused_opacity_animation(Client *c) {
|
||||||
float *border_color = get_border_color(c);
|
float *border_color = get_border_color(c);
|
||||||
|
|
||||||
if (!animations) {
|
if (!config.animations) {
|
||||||
setborder_color(c);
|
setborder_color(c);
|
||||||
return;
|
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,
|
memcpy(c->opacity_animation.target_border_color, border_color,
|
||||||
sizeof(c->opacity_animation.target_border_color));
|
sizeof(c->opacity_animation.target_border_color));
|
||||||
c->opacity_animation.target_opacity = c->focused_opacity;
|
c->opacity_animation.target_opacity = c->focused_opacity;
|
||||||
c->opacity_animation.time_started = get_now_in_ms();
|
c->opacity_animation.time_started = get_now_in_ms();
|
||||||
if (c->opacity_animation.running) {
|
|
||||||
memcpy(c->opacity_animation.initial_border_color,
|
memcpy(c->opacity_animation.initial_border_color,
|
||||||
c->opacity_animation.current_border_color,
|
c->opacity_animation.current_border_color,
|
||||||
sizeof(c->opacity_animation.initial_border_color));
|
sizeof(c->opacity_animation.initial_border_color));
|
||||||
c->opacity_animation.initial_opacity =
|
c->opacity_animation.initial_opacity = c->opacity_animation.current_opacity;
|
||||||
c->opacity_animation.current_opacity;
|
|
||||||
} else {
|
|
||||||
memcpy(c->opacity_animation.initial_border_color, bordercolor,
|
|
||||||
sizeof(c->opacity_animation.initial_border_color));
|
|
||||||
memcpy(c->opacity_animation.current_border_color, bordercolor,
|
|
||||||
sizeof(c->opacity_animation.current_border_color));
|
|
||||||
c->opacity_animation.initial_opacity = c->unfocused_opacity;
|
|
||||||
c->opacity_animation.current_opacity = c->unfocused_opacity;
|
|
||||||
}
|
|
||||||
c->opacity_animation.running = true;
|
c->opacity_animation.running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_set_unfocused_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);
|
float *border_color = get_border_color(c);
|
||||||
|
|
||||||
if (!animations) {
|
if (!config.animations) {
|
||||||
setborder_color(c);
|
setborder_color(c);
|
||||||
return;
|
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,
|
memcpy(c->opacity_animation.target_border_color, border_color,
|
||||||
sizeof(c->opacity_animation.target_border_color));
|
sizeof(c->opacity_animation.target_border_color));
|
||||||
// Start opacity animation to unfocused
|
// Start opacity animation to unfocused
|
||||||
c->opacity_animation.target_opacity = c->unfocused_opacity;
|
c->opacity_animation.target_opacity = c->unfocused_opacity;
|
||||||
c->opacity_animation.time_started = get_now_in_ms();
|
c->opacity_animation.time_started = get_now_in_ms();
|
||||||
|
|
||||||
if (c->opacity_animation.running) {
|
|
||||||
memcpy(c->opacity_animation.initial_border_color,
|
memcpy(c->opacity_animation.initial_border_color,
|
||||||
c->opacity_animation.current_border_color,
|
c->opacity_animation.current_border_color,
|
||||||
sizeof(c->opacity_animation.initial_border_color));
|
sizeof(c->opacity_animation.initial_border_color));
|
||||||
c->opacity_animation.initial_opacity =
|
c->opacity_animation.initial_opacity = c->opacity_animation.current_opacity;
|
||||||
c->opacity_animation.current_opacity;
|
|
||||||
} else {
|
|
||||||
memcpy(c->opacity_animation.initial_border_color, border_color,
|
|
||||||
sizeof(c->opacity_animation.initial_border_color));
|
|
||||||
memcpy(c->opacity_animation.current_border_color, border_color,
|
|
||||||
sizeof(c->opacity_animation.current_border_color));
|
|
||||||
c->opacity_animation.initial_opacity = c->focused_opacity;
|
|
||||||
c->opacity_animation.current_opacity = c->focused_opacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
c->opacity_animation.running = true;
|
c->opacity_animation.running = true;
|
||||||
}
|
}
|
||||||
|
|
@ -1125,19 +1108,24 @@ bool client_apply_focus_opacity(Client *c) {
|
||||||
double opacity_eased_progress =
|
double opacity_eased_progress =
|
||||||
find_animation_curve_at(linear_progress, OPAFADEIN);
|
find_animation_curve_at(linear_progress, OPAFADEIN);
|
||||||
|
|
||||||
float percent =
|
float percent = config.animation_fade_in && !c->nofadein
|
||||||
animation_fade_in && !c->nofadein ? opacity_eased_progress : 1.0;
|
? opacity_eased_progress
|
||||||
|
: 1.0;
|
||||||
float opacity =
|
float opacity =
|
||||||
c == selmon->sel ? c->focused_opacity : c->unfocused_opacity;
|
c == selmon->sel ? c->focused_opacity : c->unfocused_opacity;
|
||||||
|
|
||||||
float target_opacity =
|
float target_opacity = percent * (1.0 - config.fadein_begin_opacity) +
|
||||||
percent * (1.0 - fadein_begin_opacity) + fadein_begin_opacity;
|
config.fadein_begin_opacity;
|
||||||
if (target_opacity > opacity) {
|
if (target_opacity > opacity) {
|
||||||
target_opacity = opacity;
|
target_opacity = opacity;
|
||||||
}
|
}
|
||||||
|
memcpy(c->opacity_animation.current_border_color,
|
||||||
|
c->opacity_animation.target_border_color,
|
||||||
|
sizeof(c->opacity_animation.current_border_color));
|
||||||
|
c->opacity_animation.current_opacity = target_opacity;
|
||||||
client_set_opacity(c, target_opacity);
|
client_set_opacity(c, target_opacity);
|
||||||
client_set_border_color(c, c->opacity_animation.target_border_color);
|
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;
|
struct timespec now;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
|
@ -1198,7 +1186,7 @@ bool client_draw_frame(Client *c) {
|
||||||
return client_apply_focus_opacity(c);
|
return client_apply_focus_opacity(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (animations && c->animation.running) {
|
if (config.animations && c->animation.running) {
|
||||||
client_animation_next_tick(c);
|
client_animation_next_tick(c);
|
||||||
} else {
|
} else {
|
||||||
wlr_scene_node_set_position(&c->scene->node, c->pending.x,
|
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;
|
struct dvec2 point;
|
||||||
double *animation_curve;
|
double *animation_curve;
|
||||||
if (type == MOVE) {
|
if (type == MOVE) {
|
||||||
animation_curve = animation_curve_move;
|
animation_curve = config.animation_curve_move;
|
||||||
} else if (type == OPEN) {
|
} else if (type == OPEN) {
|
||||||
animation_curve = animation_curve_open;
|
animation_curve = config.animation_curve_open;
|
||||||
} else if (type == TAG) {
|
} else if (type == TAG) {
|
||||||
animation_curve = animation_curve_tag;
|
animation_curve = config.animation_curve_tag;
|
||||||
} else if (type == CLOSE) {
|
} else if (type == CLOSE) {
|
||||||
animation_curve = animation_curve_close;
|
animation_curve = config.animation_curve_close;
|
||||||
} else if (type == FOCUS) {
|
} else if (type == FOCUS) {
|
||||||
animation_curve = animation_curve_focus;
|
animation_curve = config.animation_curve_focus;
|
||||||
} else if (type == OPAFADEIN) {
|
} else if (type == OPAFADEIN) {
|
||||||
animation_curve = animation_curve_opafadein;
|
animation_curve = config.animation_curve_opafadein;
|
||||||
} else if (type == OPAFADEOUT) {
|
} else if (type == OPAFADEOUT) {
|
||||||
animation_curve = animation_curve_opafadeout;
|
animation_curve = config.animation_curve_opafadeout;
|
||||||
} else {
|
} else {
|
||||||
animation_curve = animation_curve_move;
|
animation_curve = config.animation_curve_move;
|
||||||
}
|
}
|
||||||
|
|
||||||
point.x = 3 * t * (1 - t) * (1 - t) * animation_curve[0] +
|
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)
|
if (!l->mapped || !l->shadow)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!shadows || !layer_shadows || l->noshadow) {
|
if (!config.shadows || !config.layer_shadows || l->noshadow) {
|
||||||
wlr_scene_shadow_set_size(l->shadow, 0, 0);
|
wlr_scene_shadow_set_size(l->shadow, 0, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -164,9 +164,8 @@ void layer_draw_shadow(LayerSurface *l) {
|
||||||
int32_t width, height;
|
int32_t width, height;
|
||||||
layer_actual_size(l, &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 = {
|
struct wlr_box layer_box = {
|
||||||
.x = 0,
|
.x = 0,
|
||||||
.y = 0,
|
.y = 0,
|
||||||
|
|
@ -175,23 +174,21 @@ void layer_draw_shadow(LayerSurface *l) {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_box shadow_box = {
|
struct wlr_box shadow_box = {
|
||||||
.x = shadows_position_x,
|
.x = config.shadows_position_x,
|
||||||
.y = shadows_position_y,
|
.y = config.shadows_position_y,
|
||||||
.width = width + 2 * delta,
|
.width = width + 2 * delta,
|
||||||
.height = height + 2 * delta,
|
.height = height + 2 * delta,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_box intersection_box;
|
struct wlr_box intersection_box;
|
||||||
wlr_box_intersection(&intersection_box, &layer_box, &shadow_box);
|
wlr_box_intersection(&intersection_box, &layer_box, &shadow_box);
|
||||||
/* clipped region takes shadow relative coords, so we translate everything
|
intersection_box.x -= config.shadows_position_x;
|
||||||
* by its position */
|
intersection_box.y -= config.shadows_position_y;
|
||||||
intersection_box.x -= shadows_position_x;
|
|
||||||
intersection_box.y -= shadows_position_y;
|
|
||||||
|
|
||||||
struct clipped_region clipped_region = {
|
struct clipped_region clipped_region = {
|
||||||
.area = intersection_box,
|
.area = intersection_box,
|
||||||
.corner_radius = border_radius,
|
.corner_radius = config.border_radius,
|
||||||
.corners = border_radius_location_default,
|
.corners = config.border_radius_location_default,
|
||||||
};
|
};
|
||||||
|
|
||||||
wlr_scene_node_set_position(&l->shadow->node, shadow_box.x, shadow_box.y);
|
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;
|
buffer_data.height = height;
|
||||||
|
|
||||||
if ((!l->animation_type_close &&
|
if ((!l->animation_type_close &&
|
||||||
strcmp(layer_animation_type_close, "zoom") == 0) ||
|
strcmp(config.layer_animation_type_close, "zoom") == 0) ||
|
||||||
(l->animation_type_close &&
|
(l->animation_type_close &&
|
||||||
strcmp(l->animation_type_close, "zoom") == 0)) {
|
strcmp(l->animation_type_close, "zoom") == 0)) {
|
||||||
wlr_scene_node_for_each_buffer(&l->scene->node,
|
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 =
|
double opacity_eased_progress =
|
||||||
find_animation_curve_at(animation_passed, OPAFADEOUT);
|
find_animation_curve_at(animation_passed, OPAFADEOUT);
|
||||||
|
|
||||||
double percent = fadeout_begin_opacity -
|
double percent = config.fadeout_begin_opacity -
|
||||||
(opacity_eased_progress * fadeout_begin_opacity);
|
(opacity_eased_progress * config.fadeout_begin_opacity);
|
||||||
|
|
||||||
double opacity = MAX(percent, 0.0f);
|
double opacity = MAX(percent, 0.0f);
|
||||||
|
|
||||||
if (animation_fade_out)
|
if (config.animation_fade_out)
|
||||||
wlr_scene_node_for_each_buffer(&l->scene->node,
|
wlr_scene_node_for_each_buffer(&l->scene->node,
|
||||||
scene_buffer_apply_opacity, &opacity);
|
scene_buffer_apply_opacity, &opacity);
|
||||||
|
|
||||||
|
|
@ -327,11 +324,11 @@ void layer_animation_next_tick(LayerSurface *l) {
|
||||||
find_animation_curve_at(animation_passed, OPAFADEIN);
|
find_animation_curve_at(animation_passed, OPAFADEIN);
|
||||||
|
|
||||||
double opacity =
|
double opacity =
|
||||||
MIN(fadein_begin_opacity +
|
MIN(config.fadein_begin_opacity +
|
||||||
opacity_eased_progress * (1.0 - fadein_begin_opacity),
|
opacity_eased_progress * (1.0 - config.fadein_begin_opacity),
|
||||||
1.0f);
|
1.0f);
|
||||||
|
|
||||||
if (animation_fade_in)
|
if (config.animation_fade_in)
|
||||||
wlr_scene_node_for_each_buffer(&l->scene->node,
|
wlr_scene_node_for_each_buffer(&l->scene->node,
|
||||||
scene_buffer_apply_opacity, &opacity);
|
scene_buffer_apply_opacity, &opacity);
|
||||||
|
|
||||||
|
|
@ -347,7 +344,7 @@ void layer_animation_next_tick(LayerSurface *l) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!l->animation_type_open &&
|
if ((!l->animation_type_open &&
|
||||||
strcmp(layer_animation_type_open, "zoom") == 0) ||
|
strcmp(config.layer_animation_type_open, "zoom") == 0) ||
|
||||||
(l->animation_type_open &&
|
(l->animation_type_open &&
|
||||||
strcmp(l->animation_type_open, "zoom") == 0)) {
|
strcmp(l->animation_type_open, "zoom") == 0)) {
|
||||||
wlr_scene_node_for_each_buffer(
|
wlr_scene_node_for_each_buffer(
|
||||||
|
|
@ -370,7 +367,7 @@ void layer_animation_next_tick(LayerSurface *l) {
|
||||||
|
|
||||||
void init_fadeout_layers(LayerSurface *l) {
|
void init_fadeout_layers(LayerSurface *l) {
|
||||||
|
|
||||||
if (!animations || !layer_animations || l->noanim) {
|
if (!config.animations || !config.layer_animations || l->noanim) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -380,7 +377,7 @@ void init_fadeout_layers(LayerSurface *l) {
|
||||||
if ((l->animation_type_close &&
|
if ((l->animation_type_close &&
|
||||||
strcmp(l->animation_type_close, "none") == 0) ||
|
strcmp(l->animation_type_close, "none") == 0) ||
|
||||||
(!l->animation_type_close &&
|
(!l->animation_type_close &&
|
||||||
strcmp(layer_animation_type_close, "none") == 0)) {
|
strcmp(config.layer_animation_type_close, "none") == 0)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -403,7 +400,7 @@ void init_fadeout_layers(LayerSurface *l) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fadeout_layer->animation.duration = animation_duration_close;
|
fadeout_layer->animation.duration = config.animation_duration_close;
|
||||||
fadeout_layer->geom = fadeout_layer->current =
|
fadeout_layer->geom = fadeout_layer->current =
|
||||||
fadeout_layer->animainit_geom = fadeout_layer->animation.initial =
|
fadeout_layer->animainit_geom = fadeout_layer->animation.initial =
|
||||||
l->animation.current;
|
l->animation.current;
|
||||||
|
|
@ -419,14 +416,14 @@ void init_fadeout_layers(LayerSurface *l) {
|
||||||
fadeout_layer->animation.initial.y = 0;
|
fadeout_layer->animation.initial.y = 0;
|
||||||
|
|
||||||
if ((!l->animation_type_close &&
|
if ((!l->animation_type_close &&
|
||||||
strcmp(layer_animation_type_close, "zoom") == 0) ||
|
strcmp(config.layer_animation_type_close, "zoom") == 0) ||
|
||||||
(l->animation_type_close &&
|
(l->animation_type_close &&
|
||||||
strcmp(l->animation_type_close, "zoom") == 0)) {
|
strcmp(l->animation_type_close, "zoom") == 0)) {
|
||||||
// 算出要设置的绝对坐标和大小
|
// 算出要设置的绝对坐标和大小
|
||||||
fadeout_layer->current.width =
|
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 =
|
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.x = usable_area.x + usable_area.width / 2 -
|
||||||
fadeout_layer->current.width / 2;
|
fadeout_layer->current.width / 2;
|
||||||
fadeout_layer->current.y = usable_area.y + usable_area.height / 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;
|
fadeout_layer->current.y - l->animation.current.y;
|
||||||
|
|
||||||
} else if ((!l->animation_type_close &&
|
} 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 &&
|
(l->animation_type_close &&
|
||||||
strcmp(l->animation_type_close, "slide") == 0)) {
|
strcmp(l->animation_type_close, "slide") == 0)) {
|
||||||
// 获取slide动画的结束绝对坐标和大小
|
// 获取slide动画的结束绝对坐标和大小
|
||||||
|
|
@ -483,17 +480,18 @@ void layer_set_pending_state(LayerSurface *l) {
|
||||||
if (l->animation.action == OPEN && !l->animation.running) {
|
if (l->animation.action == OPEN && !l->animation.running) {
|
||||||
|
|
||||||
if ((!l->animation_type_open &&
|
if ((!l->animation_type_open &&
|
||||||
strcmp(layer_animation_type_open, "zoom") == 0) ||
|
strcmp(config.layer_animation_type_open, "zoom") == 0) ||
|
||||||
(l->animation_type_open &&
|
(l->animation_type_open &&
|
||||||
strcmp(l->animation_type_open, "zoom") == 0)) {
|
strcmp(l->animation_type_open, "zoom") == 0)) {
|
||||||
l->animainit_geom.width = l->geom.width * zoom_initial_ratio;
|
l->animainit_geom.width = l->geom.width * config.zoom_initial_ratio;
|
||||||
l->animainit_geom.height = l->geom.height * 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.x = usable_area.x + usable_area.width / 2 -
|
||||||
l->animainit_geom.width / 2;
|
l->animainit_geom.width / 2;
|
||||||
l->animainit_geom.y = usable_area.y + usable_area.height / 2 -
|
l->animainit_geom.y = usable_area.y + usable_area.height / 2 -
|
||||||
l->animainit_geom.height / 2;
|
l->animainit_geom.height / 2;
|
||||||
} else if ((!l->animation_type_open &&
|
} 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 &&
|
(l->animation_type_open &&
|
||||||
strcmp(l->animation_type_open, "slide") == 0)) {
|
strcmp(l->animation_type_open, "slide") == 0)) {
|
||||||
|
|
||||||
|
|
@ -507,8 +505,7 @@ void layer_set_pending_state(LayerSurface *l) {
|
||||||
} else {
|
} else {
|
||||||
l->animainit_geom = l->animation.current;
|
l->animainit_geom = l->animation.current;
|
||||||
}
|
}
|
||||||
// 判断是否需要动画
|
if (!config.animations || !config.layer_animations || l->noanim ||
|
||||||
if (!animations || !layer_animations || l->noanim ||
|
|
||||||
l->layer_surface->current.layer ==
|
l->layer_surface->current.layer ==
|
||||||
ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND ||
|
ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND ||
|
||||||
l->layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM) {
|
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 &&
|
if (((l->animation_type_open &&
|
||||||
strcmp(l->animation_type_open, "none") == 0) ||
|
strcmp(l->animation_type_open, "none") == 0) ||
|
||||||
(!l->animation_type_open &&
|
(!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.action == OPEN) {
|
||||||
l->animation.should_animate = false;
|
l->animation.should_animate = false;
|
||||||
}
|
}
|
||||||
|
|
@ -567,7 +564,8 @@ bool layer_draw_frame(LayerSurface *l) {
|
||||||
return false;
|
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_animation_next_tick(l);
|
||||||
layer_draw_shadow(l);
|
layer_draw_shadow(l);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,11 @@ void set_tagin_animation(Monitor *m, Client *c) {
|
||||||
|
|
||||||
if (m->pertag->curtag > m->pertag->prevtag) {
|
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
|
? c->animation.current.x
|
||||||
: MAX(c->mon->m.x + c->mon->m.width,
|
: MAX(c->mon->m.x + c->mon->m.width,
|
||||||
c->geom.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,
|
? MAX(c->mon->m.y + c->mon->m.height,
|
||||||
c->geom.y + c->mon->m.height)
|
c->geom.y + c->mon->m.height)
|
||||||
: c->animation.current.y;
|
: c->animation.current.y;
|
||||||
|
|
@ -19,11 +19,11 @@ void set_tagin_animation(Monitor *m, Client *c) {
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
c->animainit_geom.x =
|
c->animainit_geom.x =
|
||||||
tag_animation_direction == VERTICAL
|
config.tag_animation_direction == VERTICAL
|
||||||
? c->animation.current.x
|
? c->animation.current.x
|
||||||
: MIN(m->m.x - c->geom.width, c->geom.x - c->mon->m.width);
|
: MIN(m->m.x - c->geom.width, c->geom.x - c->mon->m.width);
|
||||||
c->animainit_geom.y =
|
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)
|
? MIN(m->m.y - c->geom.height, c->geom.y - c->mon->m.height)
|
||||||
: c->animation.current.y;
|
: c->animation.current.y;
|
||||||
}
|
}
|
||||||
|
|
@ -39,7 +39,8 @@ void set_arrange_visible(Monitor *m, Client *c, bool want_animation) {
|
||||||
client_set_suspended(c, false);
|
client_set_suspended(c, false);
|
||||||
|
|
||||||
if (!c->animation.tag_from_rule && want_animation &&
|
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;
|
c->animation.tagining = true;
|
||||||
set_tagin_animation(m, c);
|
set_tagin_animation(m, c);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -57,10 +58,10 @@ void set_tagout_animation(Monitor *m, Client *c) {
|
||||||
if (m->pertag->curtag > m->pertag->prevtag) {
|
if (m->pertag->curtag > m->pertag->prevtag) {
|
||||||
c->pending = c->geom;
|
c->pending = c->geom;
|
||||||
c->pending.x =
|
c->pending.x =
|
||||||
tag_animation_direction == VERTICAL
|
config.tag_animation_direction == VERTICAL
|
||||||
? c->animation.current.x
|
? c->animation.current.x
|
||||||
: MIN(c->mon->m.x - c->geom.width, c->geom.x - c->mon->m.width);
|
: 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,
|
? MIN(c->mon->m.y - c->geom.height,
|
||||||
c->geom.y - c->mon->m.height)
|
c->geom.y - c->mon->m.height)
|
||||||
: c->animation.current.y;
|
: c->animation.current.y;
|
||||||
|
|
@ -68,11 +69,11 @@ void set_tagout_animation(Monitor *m, Client *c) {
|
||||||
resize(c, c->geom, 0);
|
resize(c, c->geom, 0);
|
||||||
} else {
|
} else {
|
||||||
c->pending = c->geom;
|
c->pending = c->geom;
|
||||||
c->pending.x = tag_animation_direction == VERTICAL
|
c->pending.x = config.tag_animation_direction == VERTICAL
|
||||||
? c->animation.current.x
|
? c->animation.current.x
|
||||||
: MAX(c->mon->m.x + c->mon->m.width,
|
: MAX(c->mon->m.x + c->mon->m.width,
|
||||||
c->geom.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,
|
? MAX(c->mon->m.y + c->mon->m.height,
|
||||||
c->geom.y + c->mon->m.height)
|
c->geom.y + c->mon->m.height)
|
||||||
: c->animation.current.y;
|
: 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) {
|
void set_arrange_hidden(Monitor *m, Client *c, bool want_animation) {
|
||||||
if ((c->tags & (1 << (m->pertag->prevtag - 1))) &&
|
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.tagouting = true;
|
||||||
c->animation.tagining = false;
|
c->animation.tagining = false;
|
||||||
set_tagout_animation(m, c);
|
set_tagout_animation(m, c);
|
||||||
|
|
|
||||||
|
|
@ -243,31 +243,6 @@ static inline int32_t client_is_rendered_on_mon(Client *c, Monitor *m) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int32_t client_is_stopped(Client *c) {
|
|
||||||
int32_t pid;
|
|
||||||
siginfo_t in = {0};
|
|
||||||
#ifdef XWAYLAND
|
|
||||||
if (client_is_x11(c))
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
wl_client_get_credentials(c->surface.xdg->client->client, &pid, NULL, NULL);
|
|
||||||
if (waitid(P_PID, pid, &in, WNOHANG | WCONTINUED | WSTOPPED | WNOWAIT) <
|
|
||||||
0) {
|
|
||||||
/* This process is not our child process, while is very unluckely that
|
|
||||||
* it is stopped, in order to do not skip frames assume that it is. */
|
|
||||||
if (errno == ECHILD)
|
|
||||||
return 1;
|
|
||||||
} else if (in.si_pid) {
|
|
||||||
if (in.si_code == CLD_STOPPED || in.si_code == CLD_TRAPPED)
|
|
||||||
return 1;
|
|
||||||
if (in.si_code == CLD_CONTINUED)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int32_t client_is_unmanaged(Client *c) {
|
static inline int32_t client_is_unmanaged(Client *c) {
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
if (client_is_x11(c))
|
if (client_is_x11(c))
|
||||||
|
|
@ -319,9 +294,24 @@ static inline uint32_t client_set_size(Client *c, uint32_t width,
|
||||||
uint32_t height) {
|
uint32_t height) {
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
if (client_is_x11(c)) {
|
if (client_is_x11(c)) {
|
||||||
|
|
||||||
|
struct wlr_surface_state *state =
|
||||||
|
&c->surface.xwayland->surface->current;
|
||||||
|
|
||||||
|
if ((int32_t)c->geom.width - 2 * (int32_t)c->bw ==
|
||||||
|
(int32_t)state->width &&
|
||||||
|
(int32_t)c->geom.height - 2 * (int32_t)c->bw ==
|
||||||
|
(int32_t)state->height &&
|
||||||
|
(int32_t)c->surface.xwayland->x ==
|
||||||
|
(int32_t)c->geom.x + (int32_t)c->bw &&
|
||||||
|
(int32_t)c->surface.xwayland->y ==
|
||||||
|
(int32_t)c->geom.y + (int32_t)c->bw) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
wlr_xwayland_surface_configure(c->surface.xwayland, c->geom.x + c->bw,
|
wlr_xwayland_surface_configure(c->surface.xwayland, c->geom.x + c->bw,
|
||||||
c->geom.y + c->bw, width, height);
|
c->geom.y + c->bw, width, height);
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if ((int32_t)width == c->surface.xdg->toplevel->current.width &&
|
if ((int32_t)width == c->surface.xdg->toplevel->current.width &&
|
||||||
|
|
|
||||||
|
|
@ -92,3 +92,85 @@ uint32_t get_now_in_ms(void) {
|
||||||
uint32_t timespec_to_ms(struct timespec *ts) {
|
uint32_t timespec_to_ms(struct timespec *ts) {
|
||||||
return (uint32_t)ts->tv_sec * 1000 + (uint32_t)ts->tv_nsec / 1000000;
|
return (uint32_t)ts->tv_sec * 1000 + (uint32_t)ts->tv_nsec / 1000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *join_strings(char *arr[], const char *sep) {
|
||||||
|
if (!arr || !arr[0]) {
|
||||||
|
char *empty = malloc(1);
|
||||||
|
if (empty)
|
||||||
|
empty[0] = '\0';
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t total_len = 0;
|
||||||
|
int count = 0;
|
||||||
|
for (int i = 0; arr[i] != NULL; i++) {
|
||||||
|
total_len += strlen(arr[i]);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
if (count > 0) {
|
||||||
|
total_len += strlen(sep) * (count - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *result = malloc(total_len + 1);
|
||||||
|
if (!result)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
result[0] = '\0';
|
||||||
|
for (int i = 0; arr[i] != NULL; i++) {
|
||||||
|
if (i > 0)
|
||||||
|
strcat(result, sep);
|
||||||
|
strcat(result, arr[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *join_strings_with_suffix(char *arr[], const char *suffix,
|
||||||
|
const char *sep) {
|
||||||
|
if (!arr || !arr[0]) {
|
||||||
|
char *empty = malloc(1);
|
||||||
|
if (empty)
|
||||||
|
empty[0] = '\0';
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t total_len = 0;
|
||||||
|
int count = 0;
|
||||||
|
for (int i = 0; arr[i] != NULL; i++) {
|
||||||
|
total_len += strlen(arr[i]) + strlen(suffix);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
if (count > 0) {
|
||||||
|
total_len += strlen(sep) * (count - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *result = malloc(total_len + 1);
|
||||||
|
if (!result)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
result[0] = '\0';
|
||||||
|
for (int i = 0; arr[i] != NULL; i++) {
|
||||||
|
if (i > 0)
|
||||||
|
strcat(result, sep);
|
||||||
|
strcat(result, arr[i]);
|
||||||
|
strcat(result, suffix);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *string_printf(const char *fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
int len = vsnprintf(NULL, 0, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
if (len < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
char *str = malloc(len + 1);
|
||||||
|
if (!str)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
vsnprintf(str, len + 1, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,3 +8,7 @@ int32_t regex_match(const char *pattern_mb, const char *str_mb);
|
||||||
void wl_list_append(struct wl_list *list, struct wl_list *object);
|
void wl_list_append(struct wl_list *list, struct wl_list *object);
|
||||||
uint32_t get_now_in_ms(void);
|
uint32_t get_now_in_ms(void);
|
||||||
uint32_t timespec_to_ms(struct timespec *ts);
|
uint32_t timespec_to_ms(struct timespec *ts);
|
||||||
|
char *join_strings(char *arr[], const char *sep);
|
||||||
|
char *join_strings_with_suffix(char *arr[], const char *suffix,
|
||||||
|
const char *sep);
|
||||||
|
char *string_printf(const char *fmt, ...);
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,130 +1,9 @@
|
||||||
// TODO: remove this file in the future, replace all global variables with
|
#define MODKEY WLR_MODIFIER_ALT
|
||||||
// config.xxx
|
|
||||||
|
|
||||||
/* 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 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_refresh_interval = 16.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 = {
|
static const struct xkb_rule_names xkb_fallback_rules = {
|
||||||
.layout = "us",
|
.layout = "us",
|
||||||
.variant = NULL,
|
.variant = NULL,
|
||||||
|
|
@ -132,106 +11,3 @@ static const struct xkb_rule_names xkb_fallback_rules = {
|
||||||
.rules = NULL,
|
.rules = NULL,
|
||||||
.options = 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);
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
int32_t bind_to_view(const Arg *arg) {
|
int32_t bind_to_view(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
uint32_t target = arg->ui;
|
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])) {
|
(target & TAGMASK) == (selmon->tagset[selmon->seltags])) {
|
||||||
if (selmon->pertag->prevtag)
|
if (selmon->pertag->prevtag)
|
||||||
target = 1 << (selmon->pertag->prevtag - 1);
|
target = 1 << (selmon->pertag->prevtag - 1);
|
||||||
|
|
@ -10,13 +11,13 @@ int32_t bind_to_view(const Arg *arg) {
|
||||||
target = 0;
|
target = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!view_current_to_back &&
|
if (!config.view_current_to_back &&
|
||||||
(target & TAGMASK) == (selmon->tagset[selmon->seltags])) {
|
(target & TAGMASK) == (selmon->tagset[selmon->seltags])) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((int32_t)target == INT_MIN && selmon->pertag->curtag == 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);
|
target = 1 << (selmon->pertag->prevtag - 1);
|
||||||
else
|
else
|
||||||
target = 0;
|
target = 0;
|
||||||
|
|
@ -95,11 +96,13 @@ int32_t destroy_all_virtual_output(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t defaultgaps(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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t exchange_client(const Arg *arg) {
|
int32_t exchange_client(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
Client *c = selmon->sel;
|
Client *c = selmon->sel;
|
||||||
if (!c || c->isfloating)
|
if (!c || c->isfloating)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -107,11 +110,16 @@ int32_t exchange_client(const Arg *arg) {
|
||||||
if ((c->isfullscreen || c->ismaximizescreen) && !is_scroller_layout(c->mon))
|
if ((c->isfullscreen || c->ismaximizescreen) && !is_scroller_layout(c->mon))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
exchange_two_client(c, direction_select(arg));
|
Client *tc = direction_select(arg);
|
||||||
|
tc = get_focused_stack_client(tc);
|
||||||
|
exchange_two_client(c, tc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t exchange_stack_client(const Arg *arg) {
|
int32_t exchange_stack_client(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
Client *c = selmon->sel;
|
Client *c = selmon->sel;
|
||||||
Client *tc = NULL;
|
Client *tc = NULL;
|
||||||
if (!c || c->isfloating || c->isfullscreen || c->ismaximizescreen)
|
if (!c || c->isfloating || c->isfullscreen || c->ismaximizescreen)
|
||||||
|
|
@ -132,7 +140,7 @@ int32_t focusdir(const Arg *arg) {
|
||||||
c = get_focused_stack_client(c);
|
c = get_focused_stack_client(c);
|
||||||
if (c) {
|
if (c) {
|
||||||
focusclient(c, 1);
|
focusclient(c, 1);
|
||||||
if (warpcursor)
|
if (config.warpcursor)
|
||||||
warp_cursor(c);
|
warp_cursor(c);
|
||||||
} else {
|
} else {
|
||||||
if (config.focus_cross_tag) {
|
if (config.focus_cross_tag) {
|
||||||
|
|
@ -188,7 +196,7 @@ int32_t focuslast(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t toggle_trackpad_enable(const Arg *arg) {
|
int32_t toggle_trackpad_enable(const Arg *arg) {
|
||||||
disable_trackpad = !disable_trackpad;
|
config.disable_trackpad = !config.disable_trackpad;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -204,7 +212,7 @@ int32_t focusmon(const Arg *arg) {
|
||||||
if (!m->wlr_output->enabled) {
|
if (!m->wlr_output->enabled) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (regex_match(arg->v, m->wlr_output->name)) {
|
if (match_monitor_spec(arg->v, m)) {
|
||||||
tm = m;
|
tm = m;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -217,7 +225,7 @@ int32_t focusmon(const Arg *arg) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
selmon = tm;
|
selmon = tm;
|
||||||
if (warpcursor) {
|
if (config.warpcursor) {
|
||||||
warp_cursor_to_selmon(selmon);
|
warp_cursor_to_selmon(selmon);
|
||||||
}
|
}
|
||||||
c = focustop(selmon);
|
c = focustop(selmon);
|
||||||
|
|
@ -250,7 +258,7 @@ int32_t focusstack(const Arg *arg) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
focusclient(tc, 1);
|
focusclient(tc, 1);
|
||||||
if (warpcursor)
|
if (config.warpcursor)
|
||||||
warp_cursor(tc);
|
warp_cursor(tc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -265,42 +273,56 @@ int32_t incnmaster(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t incgaps(const Arg *arg) {
|
int32_t incgaps(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
setgaps(selmon->gappoh + arg->i, selmon->gappov + arg->i,
|
setgaps(selmon->gappoh + arg->i, selmon->gappov + arg->i,
|
||||||
selmon->gappih + arg->i, selmon->gappiv + arg->i);
|
selmon->gappih + arg->i, selmon->gappiv + arg->i);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t incigaps(const Arg *arg) {
|
int32_t incigaps(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
setgaps(selmon->gappoh, selmon->gappov, selmon->gappih + arg->i,
|
setgaps(selmon->gappoh, selmon->gappov, selmon->gappih + arg->i,
|
||||||
selmon->gappiv + arg->i);
|
selmon->gappiv + arg->i);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t incogaps(const Arg *arg) {
|
int32_t incogaps(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
setgaps(selmon->gappoh + arg->i, selmon->gappov + arg->i, selmon->gappih,
|
setgaps(selmon->gappoh + arg->i, selmon->gappov + arg->i, selmon->gappih,
|
||||||
selmon->gappiv);
|
selmon->gappiv);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t incihgaps(const Arg *arg) {
|
int32_t incihgaps(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
setgaps(selmon->gappoh, selmon->gappov, selmon->gappih + arg->i,
|
setgaps(selmon->gappoh, selmon->gappov, selmon->gappih + arg->i,
|
||||||
selmon->gappiv);
|
selmon->gappiv);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t incivgaps(const Arg *arg) {
|
int32_t incivgaps(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
setgaps(selmon->gappoh, selmon->gappov, selmon->gappih,
|
setgaps(selmon->gappoh, selmon->gappov, selmon->gappih,
|
||||||
selmon->gappiv + arg->i);
|
selmon->gappiv + arg->i);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t incohgaps(const Arg *arg) {
|
int32_t incohgaps(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
setgaps(selmon->gappoh + arg->i, selmon->gappov, selmon->gappih,
|
setgaps(selmon->gappoh + arg->i, selmon->gappov, selmon->gappih,
|
||||||
selmon->gappiv);
|
selmon->gappiv);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t incovgaps(const Arg *arg) {
|
int32_t incovgaps(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
setgaps(selmon->gappoh, selmon->gappov + arg->i, selmon->gappih,
|
setgaps(selmon->gappoh, selmon->gappov + arg->i, selmon->gappih,
|
||||||
selmon->gappiv);
|
selmon->gappiv);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -330,6 +352,8 @@ int32_t setmfact(const Arg *arg) {
|
||||||
|
|
||||||
int32_t killclient(const Arg *arg) {
|
int32_t killclient(const Arg *arg) {
|
||||||
Client *c = NULL;
|
Client *c = NULL;
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
c = selmon->sel;
|
c = selmon->sel;
|
||||||
if (c) {
|
if (c) {
|
||||||
pending_kill_client(c);
|
pending_kill_client(c);
|
||||||
|
|
@ -366,7 +390,7 @@ int32_t moveresize(const Arg *arg) {
|
||||||
/* Doesn't work for X11 output - the next absolute motion event
|
/* Doesn't work for X11 output - the next absolute motion event
|
||||||
* returns the cursor to where it started */
|
* returns the cursor to where it started */
|
||||||
if (grabc->isfloating) {
|
if (grabc->isfloating) {
|
||||||
rzcorner = drag_corner;
|
rzcorner = config.drag_corner;
|
||||||
grabcx = (int)round(cursor->x);
|
grabcx = (int)round(cursor->x);
|
||||||
grabcy = (int)round(cursor->y);
|
grabcy = (int)round(cursor->y);
|
||||||
if (rzcorner == 4)
|
if (rzcorner == 4)
|
||||||
|
|
@ -380,7 +404,7 @@ int32_t moveresize(const Arg *arg) {
|
||||||
? 0
|
? 0
|
||||||
: 2);
|
: 2);
|
||||||
|
|
||||||
if (drag_warp_cursor) {
|
if (config.drag_warp_cursor) {
|
||||||
grabcx = rzcorner & 1 ? grabc->geom.x + grabc->geom.width
|
grabcx = rzcorner & 1 ? grabc->geom.x + grabc->geom.width
|
||||||
: grabc->geom.x;
|
: grabc->geom.x;
|
||||||
grabcy = rzcorner & 2 ? grabc->geom.y + grabc->geom.height
|
grabcy = rzcorner & 2 ? grabc->geom.y + grabc->geom.height
|
||||||
|
|
@ -399,6 +423,8 @@ int32_t moveresize(const Arg *arg) {
|
||||||
|
|
||||||
int32_t movewin(const Arg *arg) {
|
int32_t movewin(const Arg *arg) {
|
||||||
Client *c = NULL;
|
Client *c = NULL;
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
c = selmon->sel;
|
c = selmon->sel;
|
||||||
if (!c || c->isfullscreen)
|
if (!c || c->isfullscreen)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -442,15 +468,17 @@ int32_t quit(const Arg *arg) {
|
||||||
|
|
||||||
int32_t resizewin(const Arg *arg) {
|
int32_t resizewin(const Arg *arg) {
|
||||||
Client *c = NULL;
|
Client *c = NULL;
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
c = selmon->sel;
|
c = selmon->sel;
|
||||||
int32_t offsetx = 0, offsety = 0;
|
int32_t offsetx = 0, offsety = 0;
|
||||||
|
|
||||||
if (!c || c->isfullscreen || c->ismaximizescreen)
|
if (!c || c->isfullscreen || c->ismaximizescreen)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int32_t animations_state_backup = animations;
|
int32_t animations_state_backup = config.animations;
|
||||||
if (!c->isfloating)
|
if (!c->isfloating)
|
||||||
animations = 0;
|
config.animations = 0;
|
||||||
|
|
||||||
if (ISTILED(c)) {
|
if (ISTILED(c)) {
|
||||||
switch (arg->ui) {
|
switch (arg->ui) {
|
||||||
|
|
@ -477,7 +505,7 @@ int32_t resizewin(const Arg *arg) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
resize_tile_client(c, false, offsetx, offsety, 0);
|
resize_tile_client(c, false, offsetx, offsety, 0);
|
||||||
animations = animations_state_backup;
|
config.animations = animations_state_backup;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -508,7 +536,7 @@ int32_t resizewin(const Arg *arg) {
|
||||||
c->iscustomsize = 1;
|
c->iscustomsize = 1;
|
||||||
c->float_geom = c->geom;
|
c->float_geom = c->geom;
|
||||||
resize(c, c->geom, 0);
|
resize(c, c->geom, 0);
|
||||||
animations = animations_state_backup;
|
config.animations = animations_state_backup;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -546,6 +574,8 @@ int32_t restore_minimized(const Arg *arg) {
|
||||||
|
|
||||||
int32_t setlayout(const Arg *arg) {
|
int32_t setlayout(const Arg *arg) {
|
||||||
int32_t jk;
|
int32_t jk;
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
for (jk = 0; jk < LENGTH(layouts); jk++) {
|
for (jk = 0; jk < LENGTH(layouts); jk++) {
|
||||||
if (strcmp(layouts[jk].name, arg->v) == 0) {
|
if (strcmp(layouts[jk].name, arg->v) == 0) {
|
||||||
|
|
@ -571,12 +601,14 @@ int32_t setkeymode(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t set_proportion(const Arg *arg) {
|
int32_t set_proportion(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (selmon->isoverview || !is_scroller_layout(selmon))
|
if (selmon->isoverview || !is_scroller_layout(selmon))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (selmon->visible_tiling_clients == 1 &&
|
if (selmon->visible_tiling_clients == 1 &&
|
||||||
!scroller_ignore_proportion_single)
|
!config.scroller_ignore_proportion_single)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
Client *tc = selmon->sel;
|
Client *tc = selmon->sel;
|
||||||
|
|
@ -584,7 +616,7 @@ int32_t set_proportion(const Arg *arg) {
|
||||||
if (tc) {
|
if (tc) {
|
||||||
tc = get_scroll_stack_head(tc);
|
tc = get_scroll_stack_head(tc);
|
||||||
uint32_t max_client_width =
|
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->scroller_proportion = arg->f;
|
||||||
tc->geom.width = max_client_width * arg->f;
|
tc->geom.width = max_client_width * arg->f;
|
||||||
arrange(selmon, false, false);
|
arrange(selmon, false, false);
|
||||||
|
|
@ -596,6 +628,8 @@ int32_t smartmovewin(const Arg *arg) {
|
||||||
Client *c = NULL, *tc = NULL;
|
Client *c = NULL, *tc = NULL;
|
||||||
int32_t nx, ny;
|
int32_t nx, ny;
|
||||||
int32_t buttom, top, left, right, tar;
|
int32_t buttom, top, left, right, tar;
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
c = selmon->sel;
|
c = selmon->sel;
|
||||||
if (!c || c->isfullscreen)
|
if (!c || c->isfullscreen)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -616,7 +650,7 @@ int32_t smartmovewin(const Arg *arg) {
|
||||||
if (c->geom.x + c->geom.width < tc->geom.x ||
|
if (c->geom.x + c->geom.width < tc->geom.x ||
|
||||||
c->geom.x > tc->geom.x + tc->geom.width)
|
c->geom.x > tc->geom.x + tc->geom.width)
|
||||||
continue;
|
continue;
|
||||||
buttom = tc->geom.y + tc->geom.height + gappiv;
|
buttom = tc->geom.y + tc->geom.height + config.gappiv;
|
||||||
if (top > buttom && ny < buttom) {
|
if (top > buttom && ny < buttom) {
|
||||||
tar = MAX(tar, buttom);
|
tar = MAX(tar, buttom);
|
||||||
};
|
};
|
||||||
|
|
@ -636,7 +670,7 @@ int32_t smartmovewin(const Arg *arg) {
|
||||||
if (c->geom.x + c->geom.width < tc->geom.x ||
|
if (c->geom.x + c->geom.width < tc->geom.x ||
|
||||||
c->geom.x > tc->geom.x + tc->geom.width)
|
c->geom.x > tc->geom.x + tc->geom.width)
|
||||||
continue;
|
continue;
|
||||||
top = tc->geom.y - gappiv;
|
top = tc->geom.y - config.gappiv;
|
||||||
if (buttom < top && (ny + c->geom.height) > top) {
|
if (buttom < top && (ny + c->geom.height) > top) {
|
||||||
tar = MIN(tar, top - c->geom.height);
|
tar = MIN(tar, top - c->geom.height);
|
||||||
};
|
};
|
||||||
|
|
@ -656,7 +690,7 @@ int32_t smartmovewin(const Arg *arg) {
|
||||||
if (c->geom.y + c->geom.height < tc->geom.y ||
|
if (c->geom.y + c->geom.height < tc->geom.y ||
|
||||||
c->geom.y > tc->geom.y + tc->geom.height)
|
c->geom.y > tc->geom.y + tc->geom.height)
|
||||||
continue;
|
continue;
|
||||||
right = tc->geom.x + tc->geom.width + gappih;
|
right = tc->geom.x + tc->geom.width + config.gappih;
|
||||||
if (left > right && nx < right) {
|
if (left > right && nx < right) {
|
||||||
tar = MAX(tar, right);
|
tar = MAX(tar, right);
|
||||||
};
|
};
|
||||||
|
|
@ -675,7 +709,7 @@ int32_t smartmovewin(const Arg *arg) {
|
||||||
if (c->geom.y + c->geom.height < tc->geom.y ||
|
if (c->geom.y + c->geom.height < tc->geom.y ||
|
||||||
c->geom.y > tc->geom.y + tc->geom.height)
|
c->geom.y > tc->geom.y + tc->geom.height)
|
||||||
continue;
|
continue;
|
||||||
left = tc->geom.x - gappih;
|
left = tc->geom.x - config.gappih;
|
||||||
if (right < left && (nx + c->geom.width) > left) {
|
if (right < left && (nx + c->geom.width) > left) {
|
||||||
tar = MIN(tar, left - c->geom.width);
|
tar = MIN(tar, left - c->geom.width);
|
||||||
};
|
};
|
||||||
|
|
@ -697,6 +731,8 @@ int32_t smartresizewin(const Arg *arg) {
|
||||||
Client *c = NULL, *tc = NULL;
|
Client *c = NULL, *tc = NULL;
|
||||||
int32_t nw, nh;
|
int32_t nw, nh;
|
||||||
int32_t buttom, top, left, right, tar;
|
int32_t buttom, top, left, right, tar;
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
c = selmon->sel;
|
c = selmon->sel;
|
||||||
if (!c || c->isfullscreen)
|
if (!c || c->isfullscreen)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -721,14 +757,14 @@ int32_t smartresizewin(const Arg *arg) {
|
||||||
if (c->geom.x + c->geom.width < tc->geom.x ||
|
if (c->geom.x + c->geom.width < tc->geom.x ||
|
||||||
c->geom.x > tc->geom.x + tc->geom.width)
|
c->geom.x > tc->geom.x + tc->geom.width)
|
||||||
continue;
|
continue;
|
||||||
top = tc->geom.y - gappiv;
|
top = tc->geom.y - config.gappiv;
|
||||||
if (buttom < top && (nh + c->geom.y) > top) {
|
if (buttom < top && (nh + c->geom.y) > top) {
|
||||||
tar = MAX(tar, top - c->geom.y);
|
tar = MAX(tar, top - c->geom.y);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
nh = tar == -99999 ? nh : tar;
|
nh = tar == -99999 ? nh : tar;
|
||||||
if (c->geom.y + nh + gappov > selmon->w.y + selmon->w.height)
|
if (c->geom.y + nh + config.gappov > selmon->w.y + selmon->w.height)
|
||||||
nh = selmon->w.y + selmon->w.height - c->geom.y - gappov;
|
nh = selmon->w.y + selmon->w.height - c->geom.y - config.gappov;
|
||||||
break;
|
break;
|
||||||
case LEFT:
|
case LEFT:
|
||||||
nw -= selmon->w.width / 16;
|
nw -= selmon->w.width / 16;
|
||||||
|
|
@ -744,15 +780,15 @@ int32_t smartresizewin(const Arg *arg) {
|
||||||
if (c->geom.y + c->geom.height < tc->geom.y ||
|
if (c->geom.y + c->geom.height < tc->geom.y ||
|
||||||
c->geom.y > tc->geom.y + tc->geom.height)
|
c->geom.y > tc->geom.y + tc->geom.height)
|
||||||
continue;
|
continue;
|
||||||
left = tc->geom.x - gappih;
|
left = tc->geom.x - config.gappih;
|
||||||
if (right < left && (nw + c->geom.x) > left) {
|
if (right < left && (nw + c->geom.x) > left) {
|
||||||
tar = MIN(tar, left - c->geom.x);
|
tar = MIN(tar, left - c->geom.x);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
nw = tar == 99999 ? nw : tar;
|
nw = tar == 99999 ? nw : tar;
|
||||||
if (c->geom.x + nw + gappoh > selmon->w.x + selmon->w.width)
|
if (c->geom.x + nw + config.gappoh > selmon->w.x + selmon->w.width)
|
||||||
nw = selmon->w.x + selmon->w.width - c->geom.x - gappoh;
|
nw = selmon->w.x + selmon->w.width - c->geom.x - config.gappoh;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -765,6 +801,8 @@ int32_t smartresizewin(const Arg *arg) {
|
||||||
|
|
||||||
int32_t centerwin(const Arg *arg) {
|
int32_t centerwin(const Arg *arg) {
|
||||||
Client *c = NULL;
|
Client *c = NULL;
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
c = selmon->sel;
|
c = selmon->sel;
|
||||||
|
|
||||||
if (!c || c->isfullscreen || c->ismaximizescreen)
|
if (!c || c->isfullscreen || c->ismaximizescreen)
|
||||||
|
|
@ -812,7 +850,7 @@ int32_t spawn_shell(const Arg *arg) {
|
||||||
execlp("bash", "bash", "-c", arg->v, (char *)NULL);
|
execlp("bash", "bash", "-c", arg->v, (char *)NULL);
|
||||||
|
|
||||||
// if execlp fails, we should not reach here
|
// if execlp fails, we should not reach here
|
||||||
wlr_log(WLR_ERROR,
|
wlr_log(WLR_DEBUG,
|
||||||
"mango: failed to execute command '%s' with shell: %s\n",
|
"mango: failed to execute command '%s' with shell: %s\n",
|
||||||
arg->v, strerror(errno));
|
arg->v, strerror(errno));
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
|
|
@ -853,7 +891,7 @@ int32_t spawn(const Arg *arg) {
|
||||||
execvp(argv[0], argv);
|
execvp(argv[0], argv);
|
||||||
|
|
||||||
// 4. execvp 失败时:打印错误并直接退出(避免 coredump)
|
// 4. execvp 失败时:打印错误并直接退出(避免 coredump)
|
||||||
wlr_log(WLR_ERROR, "mango: execvp '%s' failed: %s\n", argv[0],
|
wlr_log(WLR_DEBUG, "mango: execvp '%s' failed: %s\n", argv[0],
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
_exit(EXIT_FAILURE); // 使用 _exit 避免缓冲区刷新等操作
|
_exit(EXIT_FAILURE); // 使用 _exit 避免缓冲区刷新等操作
|
||||||
}
|
}
|
||||||
|
|
@ -900,16 +938,20 @@ int32_t switch_keyboard_layout(const Arg *arg) {
|
||||||
wlr_log(WLR_INFO, "Only one layout available");
|
wlr_log(WLR_INFO, "Only one layout available");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
xkb_layout_index_t next = (current + 1) % num_layouts;
|
|
||||||
|
xkb_layout_index_t next = 0;
|
||||||
|
if (arg->i > 0 && arg->i <= num_layouts) {
|
||||||
|
next = arg->i - 1;
|
||||||
|
} else {
|
||||||
|
next = (current + 1) % num_layouts;
|
||||||
|
}
|
||||||
|
|
||||||
// 6. 应用新 keymap
|
// 6. 应用新 keymap
|
||||||
uint32_t depressed = keyboard->modifiers.depressed;
|
uint32_t depressed = keyboard->modifiers.depressed;
|
||||||
uint32_t latched = keyboard->modifiers.latched;
|
uint32_t latched = keyboard->modifiers.latched;
|
||||||
uint32_t locked = keyboard->modifiers.locked;
|
uint32_t locked = keyboard->modifiers.locked;
|
||||||
|
|
||||||
wlr_keyboard_set_keymap(keyboard, keyboard->keymap);
|
|
||||||
wlr_keyboard_notify_modifiers(keyboard, depressed, latched, locked, next);
|
wlr_keyboard_notify_modifiers(keyboard, depressed, latched, locked, next);
|
||||||
keyboard->modifiers.group = 0;
|
|
||||||
|
|
||||||
// 7. 更新 seat
|
// 7. 更新 seat
|
||||||
wlr_seat_set_keyboard(seat, keyboard);
|
wlr_seat_set_keyboard(seat, keyboard);
|
||||||
|
|
@ -923,10 +965,7 @@ int32_t switch_keyboard_layout(const Arg *arg) {
|
||||||
|
|
||||||
struct wlr_keyboard *tkb = (struct wlr_keyboard *)id->device_data;
|
struct wlr_keyboard *tkb = (struct wlr_keyboard *)id->device_data;
|
||||||
|
|
||||||
wlr_keyboard_set_keymap(tkb, keyboard->keymap);
|
|
||||||
wlr_keyboard_notify_modifiers(tkb, depressed, latched, locked, next);
|
wlr_keyboard_notify_modifiers(tkb, depressed, latched, locked, next);
|
||||||
tkb->modifiers.group = 0;
|
|
||||||
|
|
||||||
// 7. 更新 seat
|
// 7. 更新 seat
|
||||||
wlr_seat_set_keyboard(seat, tkb);
|
wlr_seat_set_keyboard(seat, tkb);
|
||||||
wlr_seat_keyboard_notify_modifiers(seat, &tkb->modifiers);
|
wlr_seat_keyboard_notify_modifiers(seat, &tkb->modifiers);
|
||||||
|
|
@ -942,6 +981,9 @@ int32_t switch_layout(const Arg *arg) {
|
||||||
char *target_layout_name = NULL;
|
char *target_layout_name = NULL;
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
|
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (config.circle_layout_count != 0) {
|
if (config.circle_layout_count != 0) {
|
||||||
for (jk = 0; jk < config.circle_layout_count; jk++) {
|
for (jk = 0; jk < config.circle_layout_count; jk++) {
|
||||||
|
|
||||||
|
|
@ -993,6 +1035,8 @@ int32_t switch_layout(const Arg *arg) {
|
||||||
|
|
||||||
int32_t switch_proportion_preset(const Arg *arg) {
|
int32_t switch_proportion_preset(const Arg *arg) {
|
||||||
float target_proportion = 0;
|
float target_proportion = 0;
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (config.scroller_proportion_preset_count == 0) {
|
if (config.scroller_proportion_preset_count == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1002,7 +1046,7 @@ int32_t switch_proportion_preset(const Arg *arg) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (selmon->visible_tiling_clients == 1 &&
|
if (selmon->visible_tiling_clients == 1 &&
|
||||||
!scroller_ignore_proportion_single)
|
!config.scroller_ignore_proportion_single)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
Client *tc = selmon->sel;
|
Client *tc = selmon->sel;
|
||||||
|
|
@ -1012,14 +1056,29 @@ int32_t switch_proportion_preset(const Arg *arg) {
|
||||||
for (int32_t i = 0; i < config.scroller_proportion_preset_count; i++) {
|
for (int32_t i = 0; i < config.scroller_proportion_preset_count; i++) {
|
||||||
if (config.scroller_proportion_preset[i] ==
|
if (config.scroller_proportion_preset[i] ==
|
||||||
tc->scroller_proportion) {
|
tc->scroller_proportion) {
|
||||||
|
|
||||||
|
if (arg->i == NEXT) {
|
||||||
if (i == config.scroller_proportion_preset_count - 1) {
|
if (i == config.scroller_proportion_preset_count - 1) {
|
||||||
target_proportion = config.scroller_proportion_preset[0];
|
target_proportion =
|
||||||
|
config.scroller_proportion_preset[0];
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
target_proportion =
|
target_proportion =
|
||||||
config.scroller_proportion_preset[i + 1];
|
config.scroller_proportion_preset[i + 1];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (i == 0) {
|
||||||
|
target_proportion =
|
||||||
|
config.scroller_proportion_preset
|
||||||
|
[config.scroller_proportion_preset_count - 1];
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
target_proportion =
|
||||||
|
config.scroller_proportion_preset[i - 1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1028,7 +1087,7 @@ int32_t switch_proportion_preset(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t max_client_width =
|
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->scroller_proportion = target_proportion;
|
||||||
tc->geom.width = max_client_width * target_proportion;
|
tc->geom.width = max_client_width * target_proportion;
|
||||||
arrange(selmon, false, false);
|
arrange(selmon, false, false);
|
||||||
|
|
@ -1037,6 +1096,8 @@ int32_t switch_proportion_preset(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tag(const Arg *arg) {
|
int32_t tag(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
Client *target_client = selmon->sel;
|
Client *target_client = selmon->sel;
|
||||||
tag_client(arg, target_client);
|
tag_client(arg, target_client);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1044,6 +1105,8 @@ int32_t tag(const Arg *arg) {
|
||||||
|
|
||||||
int32_t tagmon(const Arg *arg) {
|
int32_t tagmon(const Arg *arg) {
|
||||||
Monitor *m = NULL, *cm = NULL;
|
Monitor *m = NULL, *cm = NULL;
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
Client *c = focustop(selmon);
|
Client *c = focustop(selmon);
|
||||||
|
|
||||||
if (!c)
|
if (!c)
|
||||||
|
|
@ -1056,7 +1119,7 @@ int32_t tagmon(const Arg *arg) {
|
||||||
if (!cm->wlr_output->enabled) {
|
if (!cm->wlr_output->enabled) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (regex_match(arg->v, cm->wlr_output->name)) {
|
if (match_monitor_spec(arg->v, cm)) {
|
||||||
m = cm;
|
m = cm;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1107,7 +1170,7 @@ int32_t tagmon(const Arg *arg) {
|
||||||
focusclient(c, 1);
|
focusclient(c, 1);
|
||||||
arrange(selmon, false, false);
|
arrange(selmon, false, false);
|
||||||
}
|
}
|
||||||
if (warpcursor) {
|
if (config.warpcursor) {
|
||||||
warp_cursor_to_selmon(c->mon);
|
warp_cursor_to_selmon(c->mon);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1135,6 +1198,9 @@ int32_t tagsilent(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tagtoleft(const Arg *arg) {
|
int32_t tagtoleft(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (selmon->sel != NULL &&
|
if (selmon->sel != NULL &&
|
||||||
__builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 &&
|
__builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 &&
|
||||||
selmon->tagset[selmon->seltags] > 1) {
|
selmon->tagset[selmon->seltags] > 1) {
|
||||||
|
|
@ -1144,6 +1210,9 @@ int32_t tagtoleft(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tagtoright(const Arg *arg) {
|
int32_t tagtoright(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (selmon->sel != NULL &&
|
if (selmon->sel != NULL &&
|
||||||
__builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 &&
|
__builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 &&
|
||||||
selmon->tagset[selmon->seltags] & (TAGMASK >> 1)) {
|
selmon->tagset[selmon->seltags] & (TAGMASK >> 1)) {
|
||||||
|
|
@ -1172,6 +1241,8 @@ int32_t toggle_named_scratchpad(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t toggle_render_border(const Arg *arg) {
|
int32_t toggle_render_border(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
render_border = !render_border;
|
render_border = !render_border;
|
||||||
arrange(selmon, false, false);
|
arrange(selmon, false, false);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1186,11 +1257,12 @@ int32_t toggle_scratchpad(const Arg *arg) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
wl_list_for_each_safe(c, tmp, &clients, link) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (single_scratchpad && c->isnamedscratchpad && !c->isminimized) {
|
if (config.single_scratchpad && c->isnamedscratchpad &&
|
||||||
|
!c->isminimized) {
|
||||||
set_minimized(c);
|
set_minimized(c);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -1207,6 +1279,8 @@ int32_t toggle_scratchpad(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t togglefakefullscreen(const Arg *arg) {
|
int32_t togglefakefullscreen(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
Client *sel = focustop(selmon);
|
Client *sel = focustop(selmon);
|
||||||
if (sel)
|
if (sel)
|
||||||
setfakefullscreen(sel, !sel->isfakefullscreen);
|
setfakefullscreen(sel, !sel->isfakefullscreen);
|
||||||
|
|
@ -1214,6 +1288,9 @@ int32_t togglefakefullscreen(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t togglefloating(const Arg *arg) {
|
int32_t togglefloating(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
Client *sel = focustop(selmon);
|
Client *sel = focustop(selmon);
|
||||||
|
|
||||||
if (selmon && selmon->isoverview)
|
if (selmon && selmon->isoverview)
|
||||||
|
|
@ -1222,17 +1299,22 @@ int32_t togglefloating(const Arg *arg) {
|
||||||
if (!sel)
|
if (!sel)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
bool isfloating = sel->isfloating;
|
||||||
|
|
||||||
if ((sel->isfullscreen || sel->ismaximizescreen)) {
|
if ((sel->isfullscreen || sel->ismaximizescreen)) {
|
||||||
sel->isfloating = 1;
|
isfloating = 1;
|
||||||
} else {
|
} else {
|
||||||
sel->isfloating = !sel->isfloating;
|
isfloating = !sel->isfloating;
|
||||||
}
|
}
|
||||||
|
|
||||||
setfloating(sel, sel->isfloating);
|
setfloating(sel, isfloating);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t togglefullscreen(const Arg *arg) {
|
int32_t togglefullscreen(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
Client *sel = focustop(selmon);
|
Client *sel = focustop(selmon);
|
||||||
if (!sel)
|
if (!sel)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1249,6 +1331,9 @@ int32_t togglefullscreen(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t toggleglobal(const Arg *arg) {
|
int32_t toggleglobal(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!selmon->sel)
|
if (!selmon->sel)
|
||||||
return 0;
|
return 0;
|
||||||
if (selmon->sel->is_in_scratchpad) {
|
if (selmon->sel->is_in_scratchpad) {
|
||||||
|
|
@ -1267,12 +1352,18 @@ int32_t toggleglobal(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t togglegaps(const Arg *arg) {
|
int32_t togglegaps(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
enablegaps ^= 1;
|
enablegaps ^= 1;
|
||||||
arrange(selmon, false, false);
|
arrange(selmon, false, false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t togglemaximizescreen(const Arg *arg) {
|
int32_t togglemaximizescreen(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
Client *sel = focustop(selmon);
|
Client *sel = focustop(selmon);
|
||||||
if (!sel)
|
if (!sel)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1291,6 +1382,9 @@ int32_t togglemaximizescreen(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t toggleoverlay(const Arg *arg) {
|
int32_t toggleoverlay(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!selmon->sel || !selmon->sel->mon || selmon->sel->isfullscreen) {
|
if (!selmon->sel || !selmon->sel->mon || selmon->sel->isfullscreen) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1312,6 +1406,9 @@ int32_t toggleoverlay(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t toggletag(const Arg *arg) {
|
int32_t toggletag(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
uint32_t newtags;
|
uint32_t newtags;
|
||||||
Client *sel = focustop(selmon);
|
Client *sel = focustop(selmon);
|
||||||
if (!sel)
|
if (!sel)
|
||||||
|
|
@ -1335,17 +1432,25 @@ int32_t toggletag(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t toggleview(const Arg *arg) {
|
int32_t toggleview(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
uint32_t newtagset;
|
uint32_t newtagset;
|
||||||
uint32_t target;
|
uint32_t target;
|
||||||
|
Client *c = NULL;
|
||||||
|
|
||||||
target = arg->ui == 0 ? ~0 & TAGMASK : arg->ui;
|
target = arg->ui == 0 ? ~0 & TAGMASK : arg->ui;
|
||||||
|
|
||||||
newtagset =
|
newtagset = selmon->tagset[selmon->seltags] ^ (target & TAGMASK);
|
||||||
selmon ? selmon->tagset[selmon->seltags] ^ (target & TAGMASK) : 0;
|
|
||||||
|
|
||||||
if (newtagset) {
|
if (newtagset) {
|
||||||
selmon->tagset[selmon->seltags] = newtagset;
|
selmon->tagset[selmon->seltags] = newtagset;
|
||||||
focusclient(focustop(selmon), 1);
|
focusclient(focustop(selmon), 1);
|
||||||
|
wl_list_for_each(c, &clients, link) {
|
||||||
|
if (VISIBLEON(c, selmon) && ISTILED(c)) {
|
||||||
|
set_size_per(selmon, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
arrange(selmon, false, false);
|
arrange(selmon, false, false);
|
||||||
}
|
}
|
||||||
printstatus();
|
printstatus();
|
||||||
|
|
@ -1353,6 +1458,9 @@ int32_t toggleview(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t viewtoleft(const Arg *arg) {
|
int32_t viewtoleft(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
uint32_t target = selmon->tagset[selmon->seltags];
|
uint32_t target = selmon->tagset[selmon->seltags];
|
||||||
|
|
||||||
if (selmon->isoverview || selmon->pertag->curtag == 0) {
|
if (selmon->isoverview || selmon->pertag->curtag == 0) {
|
||||||
|
|
@ -1373,6 +1481,9 @@ int32_t viewtoleft(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t viewtoright(const Arg *arg) {
|
int32_t viewtoright(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (selmon->isoverview || selmon->pertag->curtag == 0) {
|
if (selmon->isoverview || selmon->pertag->curtag == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1390,6 +1501,9 @@ int32_t viewtoright(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t viewtoleft_have_client(const Arg *arg) {
|
int32_t viewtoleft_have_client(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
uint32_t n;
|
uint32_t n;
|
||||||
uint32_t current = get_tags_first_tag_num(selmon->tagset[selmon->seltags]);
|
uint32_t current = get_tags_first_tag_num(selmon->tagset[selmon->seltags]);
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
@ -1414,6 +1528,9 @@ int32_t viewtoleft_have_client(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t viewtoright_have_client(const Arg *arg) {
|
int32_t viewtoright_have_client(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
uint32_t n;
|
uint32_t n;
|
||||||
uint32_t current = get_tags_first_tag_num(selmon->tagset[selmon->seltags]);
|
uint32_t current = get_tags_first_tag_num(selmon->tagset[selmon->seltags]);
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
@ -1438,6 +1555,9 @@ int32_t viewtoright_have_client(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t viewcrossmon(const Arg *arg) {
|
int32_t viewcrossmon(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
focusmon(&(Arg){.v = arg->v, .i = UNDIR});
|
focusmon(&(Arg){.v = arg->v, .i = UNDIR});
|
||||||
view_in_mon(arg, true, selmon, true);
|
view_in_mon(arg, true, selmon, true);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1447,7 +1567,7 @@ int32_t tagcrossmon(const Arg *arg) {
|
||||||
if (!selmon || !selmon->sel)
|
if (!selmon || !selmon->sel)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (regex_match(selmon->wlr_output->name, arg->v)) {
|
if (match_monitor_spec(arg->v, selmon)) {
|
||||||
tag_client(arg, selmon->sel);
|
tag_client(arg, selmon->sel);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1516,6 +1636,8 @@ int32_t setoption(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t minimized(const Arg *arg) {
|
int32_t minimized(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (selmon && selmon->isoverview)
|
if (selmon && selmon->isoverview)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1526,10 +1648,23 @@ int32_t minimized(const Arg *arg) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fix_mon_tagset_from_overview(Monitor *m) {
|
||||||
|
if (m->tagset[m->seltags] == (m->ovbk_prev_tagset & TAGMASK)) {
|
||||||
|
m->tagset[m->seltags ^ 1] = m->ovbk_current_tagset;
|
||||||
|
m->pertag->prevtag = get_tags_first_tag_num(m->ovbk_current_tagset);
|
||||||
|
} else {
|
||||||
|
m->tagset[m->seltags ^ 1] = m->ovbk_prev_tagset;
|
||||||
|
m->pertag->prevtag = get_tags_first_tag_num(m->ovbk_prev_tagset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int32_t toggleoverview(const Arg *arg) {
|
int32_t toggleoverview(const Arg *arg) {
|
||||||
Client *c = NULL;
|
Client *c = NULL;
|
||||||
|
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});
|
focusstack(&(Arg){.i = 1});
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1547,6 +1682,8 @@ int32_t toggleoverview(const Arg *arg) {
|
||||||
visible_client_number++;
|
visible_client_number++;
|
||||||
}
|
}
|
||||||
if (visible_client_number > 0) {
|
if (visible_client_number > 0) {
|
||||||
|
selmon->ovbk_current_tagset = selmon->tagset[selmon->seltags];
|
||||||
|
selmon->ovbk_prev_tagset = selmon->tagset[selmon->seltags ^ 1];
|
||||||
target = ~0 & TAGMASK;
|
target = ~0 & TAGMASK;
|
||||||
} else {
|
} else {
|
||||||
selmon->isoverview ^= 1;
|
selmon->isoverview ^= 1;
|
||||||
|
|
@ -1557,6 +1694,7 @@ int32_t toggleoverview(const Arg *arg) {
|
||||||
} else if (!selmon->isoverview && !selmon->sel) {
|
} else if (!selmon->isoverview && !selmon->sel) {
|
||||||
target = (1 << (selmon->pertag->prevtag - 1));
|
target = (1 << (selmon->pertag->prevtag - 1));
|
||||||
view(&(Arg){.ui = target}, false);
|
view(&(Arg){.ui = target}, false);
|
||||||
|
fix_mon_tagset_from_overview(selmon);
|
||||||
refresh_monitors_workspaces_status(selmon);
|
refresh_monitors_workspaces_status(selmon);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1579,7 +1717,7 @@ int32_t toggleoverview(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
view(&(Arg){.ui = target}, false);
|
view(&(Arg){.ui = target}, false);
|
||||||
|
fix_mon_tagset_from_overview(selmon);
|
||||||
refresh_monitors_workspaces_status(selmon);
|
refresh_monitors_workspaces_status(selmon);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1588,7 +1726,7 @@ int32_t disable_monitor(const Arg *arg) {
|
||||||
Monitor *m = NULL;
|
Monitor *m = NULL;
|
||||||
struct wlr_output_state state = {0};
|
struct wlr_output_state state = {0};
|
||||||
wl_list_for_each(m, &mons, link) {
|
wl_list_for_each(m, &mons, link) {
|
||||||
if (regex_match(arg->v, m->wlr_output->name)) {
|
if (match_monitor_spec(arg->v, m)) {
|
||||||
wlr_output_state_set_enabled(&state, false);
|
wlr_output_state_set_enabled(&state, false);
|
||||||
wlr_output_commit_state(m->wlr_output, &state);
|
wlr_output_commit_state(m->wlr_output, &state);
|
||||||
m->asleep = 1;
|
m->asleep = 1;
|
||||||
|
|
@ -1603,7 +1741,7 @@ int32_t enable_monitor(const Arg *arg) {
|
||||||
Monitor *m = NULL;
|
Monitor *m = NULL;
|
||||||
struct wlr_output_state state = {0};
|
struct wlr_output_state state = {0};
|
||||||
wl_list_for_each(m, &mons, link) {
|
wl_list_for_each(m, &mons, link) {
|
||||||
if (regex_match(arg->v, m->wlr_output->name)) {
|
if (match_monitor_spec(arg->v, m)) {
|
||||||
wlr_output_state_set_enabled(&state, true);
|
wlr_output_state_set_enabled(&state, true);
|
||||||
wlr_output_commit_state(m->wlr_output, &state);
|
wlr_output_commit_state(m->wlr_output, &state);
|
||||||
m->asleep = 0;
|
m->asleep = 0;
|
||||||
|
|
@ -1618,7 +1756,7 @@ int32_t toggle_monitor(const Arg *arg) {
|
||||||
Monitor *m = NULL;
|
Monitor *m = NULL;
|
||||||
struct wlr_output_state state = {0};
|
struct wlr_output_state state = {0};
|
||||||
wl_list_for_each(m, &mons, link) {
|
wl_list_for_each(m, &mons, link) {
|
||||||
if (regex_match(arg->v, m->wlr_output->name)) {
|
if (match_monitor_spec(arg->v, m)) {
|
||||||
wlr_output_state_set_enabled(&state, !m->wlr_output->enabled);
|
wlr_output_state_set_enabled(&state, !m->wlr_output->enabled);
|
||||||
wlr_output_commit_state(m->wlr_output, &state);
|
wlr_output_commit_state(m->wlr_output, &state);
|
||||||
m->asleep = !m->wlr_output->enabled;
|
m->asleep = !m->wlr_output->enabled;
|
||||||
|
|
@ -1630,34 +1768,27 @@ int32_t toggle_monitor(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t scroller_stack(const Arg *arg) {
|
int32_t scroller_stack(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
Client *c = selmon->sel;
|
Client *c = selmon->sel;
|
||||||
Client *stack_head = NULL;
|
Client *stack_head = NULL;
|
||||||
Client *source_stack_head = NULL;
|
Client *source_stack_head = NULL;
|
||||||
if (!c || !c->mon || c->isfloating || !is_scroller_layout(selmon))
|
if (!c || !c->mon || c->isfloating || !is_scroller_layout(selmon))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (c && (!client_only_in_one_tag(c) || c->isglobal || c->isunglobal))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
bool is_horizontal_layout =
|
bool is_horizontal_layout =
|
||||||
c->mon->pertag->ltidxs[c->mon->pertag->curtag]->id == SCROLLER ? true
|
c->mon->pertag->ltidxs[c->mon->pertag->curtag]->id == SCROLLER ? true
|
||||||
: false;
|
: false;
|
||||||
|
|
||||||
Client *target_client = find_client_by_direction(c, arg, false, true);
|
Client *target_client = find_client_by_direction(c, arg, false, true);
|
||||||
|
|
||||||
if (target_client && (!client_only_in_one_tag(target_client) ||
|
|
||||||
target_client->isglobal || target_client->isunglobal))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (target_client) {
|
if (target_client) {
|
||||||
stack_head = get_scroll_stack_head(target_client);
|
stack_head = get_scroll_stack_head(target_client);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c) {
|
|
||||||
source_stack_head = get_scroll_stack_head(c);
|
source_stack_head = get_scroll_stack_head(c);
|
||||||
}
|
|
||||||
|
|
||||||
if (stack_head == source_stack_head) {
|
if (source_stack_head == stack_head) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1705,6 +1836,10 @@ int32_t scroller_stack(const Arg *arg) {
|
||||||
|
|
||||||
if (!target_client || target_client->mon != c->mon) {
|
if (!target_client || target_client->mon != c->mon) {
|
||||||
return 0;
|
return 0;
|
||||||
|
} else {
|
||||||
|
c->isglobal = target_client->isglobal = 0;
|
||||||
|
c->isunglobal = target_client->isglobal = 0;
|
||||||
|
c->tags = target_client->tags = get_tags_first_tag(target_client->tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit_scroller_stack(c);
|
exit_scroller_stack(c);
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ void handle_tearing_new_object(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
bool check_tearing_frame_allow(Monitor *m) {
|
bool check_tearing_frame_allow(Monitor *m) {
|
||||||
/* never allow tearing when disabled */
|
/* never allow tearing when disabled */
|
||||||
if (!allow_tearing) {
|
if (!config.allow_tearing) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,7 +72,7 @@ bool check_tearing_frame_allow(Monitor *m) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allow tearing for any window when requested or forced */
|
/* 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) {
|
if (c->force_tearing == STATE_UNSPECIFIED) {
|
||||||
return c->tearing_hint;
|
return c->tearing_hint;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -87,7 +87,8 @@ bool check_tearing_frame_allow(Monitor *m) {
|
||||||
|
|
||||||
if (c->force_tearing == STATE_UNSPECIFIED) {
|
if (c->force_tearing == STATE_UNSPECIFIED) {
|
||||||
/* honor the tearing hint or the fullscreen-force preference */
|
/* 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 */
|
/* honor tearing as requested by action */
|
||||||
|
|
|
||||||
|
|
@ -77,15 +77,6 @@ Monitor *output_from_wlr_output(struct wlr_output *wlr_output) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Monitor *output_nearest_to(int32_t lx, int32_t ly) {
|
|
||||||
double closest_x, closest_y;
|
|
||||||
wlr_output_layout_closest_point(output_layout, NULL, lx, ly, &closest_x,
|
|
||||||
&closest_y);
|
|
||||||
|
|
||||||
return output_from_wlr_output(
|
|
||||||
wlr_output_layout_output_at(output_layout, closest_x, closest_y));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool output_is_usable(Monitor *m) { return m && m->wlr_output->enabled; }
|
bool output_is_usable(Monitor *m) { return m && m->wlr_output->enabled; }
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
@ -255,7 +246,7 @@ static void update_popup_position(struct dwl_input_method_popup *popup) {
|
||||||
cursor_rect = (struct wlr_box){0};
|
cursor_rect = (struct wlr_box){0};
|
||||||
}
|
}
|
||||||
|
|
||||||
output = output_nearest_to(cursor_rect.x, cursor_rect.y);
|
output = get_monitor_nearest_to(cursor_rect.x, cursor_rect.y);
|
||||||
if (!output_is_usable(output)) {
|
if (!output_is_usable(output)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) ||
|
((ISSCROLLTILED(c) && c->mon->visible_scroll_tiling_clients == 1) ||
|
||||||
c->mon->visible_clients == 1)) {
|
c->mon->visible_clients == 1)) {
|
||||||
hit_no_border = true;
|
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;
|
const char *appid, *title;
|
||||||
Client *c = NULL;
|
Client *c = NULL;
|
||||||
wl_list_for_each(c, &clients, link) {
|
wl_list_for_each(c, &clients, link) {
|
||||||
if (!scratchpad_cross_monitor && c->mon != selmon) {
|
if (!config.scratchpad_cross_monitor && c->mon != selmon) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,6 +83,9 @@ setclient_coordinate_center(Client *c, Monitor *tm, struct wlr_box geom,
|
||||||
int32_t len = 0;
|
int32_t len = 0;
|
||||||
Monitor *m = tm ? tm : selmon;
|
Monitor *m = tm ? tm : selmon;
|
||||||
|
|
||||||
|
if (!m)
|
||||||
|
return geom;
|
||||||
|
|
||||||
uint32_t cbw = check_hit_no_border(c) ? c->bw : 0;
|
uint32_t cbw = check_hit_no_border(c) ? c->bw : 0;
|
||||||
|
|
||||||
if (!c->no_force_center && m) {
|
if (!c->no_force_center && m) {
|
||||||
|
|
@ -164,7 +167,7 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating,
|
||||||
// 第一次遍历,计算客户端数量
|
// 第一次遍历,计算客户端数量
|
||||||
wl_list_for_each(c, &clients, link) {
|
wl_list_for_each(c, &clients, link) {
|
||||||
if (c && (findfloating || !c->isfloating) && !c->isunglobal &&
|
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])) {
|
(c->tags & c->mon->tagset[c->mon->seltags])) {
|
||||||
last++;
|
last++;
|
||||||
}
|
}
|
||||||
|
|
@ -185,7 +188,7 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating,
|
||||||
last = -1;
|
last = -1;
|
||||||
wl_list_for_each(c, &clients, link) {
|
wl_list_for_each(c, &clients, link) {
|
||||||
if (c && (findfloating || !c->isfloating) && !c->isunglobal &&
|
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])) {
|
(c->tags & c->mon->tagset[c->mon->seltags])) {
|
||||||
last++;
|
last++;
|
||||||
tempClients[last] = c;
|
tempClients[last] = c;
|
||||||
|
|
@ -508,21 +511,21 @@ Client *get_next_stack_client(Client *c, bool reverse) {
|
||||||
float *get_border_color(Client *c) {
|
float *get_border_color(Client *c) {
|
||||||
|
|
||||||
if (c->mon != selmon) {
|
if (c->mon != selmon) {
|
||||||
return bordercolor;
|
return config.bordercolor;
|
||||||
} else if (c->isurgent) {
|
} else if (c->isurgent) {
|
||||||
return urgentcolor;
|
return config.urgentcolor;
|
||||||
} else if (c->is_in_scratchpad && selmon && c == selmon->sel) {
|
} else if (c->is_in_scratchpad && selmon && c == selmon->sel) {
|
||||||
return scratchpadcolor;
|
return config.scratchpadcolor;
|
||||||
} else if (c->isglobal && selmon && c == selmon->sel) {
|
} else if (c->isglobal && selmon && c == selmon->sel) {
|
||||||
return globalcolor;
|
return config.globalcolor;
|
||||||
} else if (c->isoverlay && selmon && c == selmon->sel) {
|
} else if (c->isoverlay && selmon && c == selmon->sel) {
|
||||||
return overlaycolor;
|
return config.overlaycolor;
|
||||||
} else if (c->ismaximizescreen && selmon && c == selmon->sel) {
|
} else if (c->ismaximizescreen && selmon && c == selmon->sel) {
|
||||||
return maximizescreencolor;
|
return config.maximizescreencolor;
|
||||||
} else if (selmon && c == selmon->sel) {
|
} else if (selmon && c == selmon->sel) {
|
||||||
return focuscolor;
|
return config.focuscolor;
|
||||||
} else {
|
} else {
|
||||||
return bordercolor;
|
return config.bordercolor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -574,23 +577,29 @@ bool client_is_in_same_stack(Client *sc, Client *tc, Client *fc) {
|
||||||
|
|
||||||
if (id == TILE || id == VERTICAL_TILE || id == DECK ||
|
if (id == TILE || id == VERTICAL_TILE || id == DECK ||
|
||||||
id == VERTICAL_DECK || id == RIGHT_TILE) {
|
id == VERTICAL_DECK || id == RIGHT_TILE) {
|
||||||
if (fc && !fc->ismaster)
|
if (tc->ismaster ^ sc->ismaster)
|
||||||
return false;
|
return false;
|
||||||
else if (!sc->ismaster)
|
if (fc && !(fc->ismaster ^ sc->ismaster))
|
||||||
|
return false;
|
||||||
|
else
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id == TGMIX) {
|
if (id == TGMIX) {
|
||||||
if (fc && !fc->ismaster)
|
if (tc->ismaster ^ sc->ismaster)
|
||||||
|
return false;
|
||||||
|
if (fc && !(fc->ismaster ^ sc->ismaster))
|
||||||
return false;
|
return false;
|
||||||
if (!sc->ismaster && sc->mon->visible_tiling_clients <= 3)
|
if (!sc->ismaster && sc->mon->visible_tiling_clients <= 3)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id == CENTER_TILE) {
|
if (id == CENTER_TILE) {
|
||||||
if (fc && !fc->ismaster)
|
if (tc->ismaster ^ sc->ismaster)
|
||||||
return false;
|
return false;
|
||||||
if (!sc->ismaster && sc->geom.x == tc->geom.x)
|
if (fc && !(fc->ismaster ^ sc->ismaster))
|
||||||
|
return false;
|
||||||
|
if (sc->geom.x == tc->geom.x)
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -100,10 +100,6 @@ void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc,
|
||||||
surface = wlr_scene_surface_try_from_buffer(
|
surface = wlr_scene_surface_try_from_buffer(
|
||||||
wlr_scene_buffer_from_node(node))
|
wlr_scene_buffer_from_node(node))
|
||||||
->surface;
|
->surface;
|
||||||
else if (node->type == WLR_SCENE_NODE_RECT) {
|
|
||||||
surface = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* start from the topmost layer,
|
/* start from the topmost layer,
|
||||||
find a sureface that can be focused by pointer,
|
find a sureface that can be focused by pointer,
|
||||||
|
|
@ -119,6 +115,13 @@ void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc,
|
||||||
l = pnode->data;
|
l = pnode->data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (node->type == WLR_SCENE_NODE_RECT) {
|
||||||
|
if (c) {
|
||||||
|
surface = client_surface(c);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (psurface)
|
if (psurface)
|
||||||
|
|
|
||||||
|
|
@ -96,3 +96,81 @@ Monitor *xytomon(double x, double y) {
|
||||||
struct wlr_output *o = wlr_output_layout_output_at(output_layout, x, y);
|
struct wlr_output *o = wlr_output_layout_output_at(output_layout, x, y);
|
||||||
return o ? o->data : NULL;
|
return o ? o->data : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Monitor *get_monitor_nearest_to(int32_t lx, int32_t ly) {
|
||||||
|
double closest_x, closest_y;
|
||||||
|
wlr_output_layout_closest_point(output_layout, NULL, lx, ly, &closest_x,
|
||||||
|
&closest_y);
|
||||||
|
|
||||||
|
return output_from_wlr_output(
|
||||||
|
wlr_output_layout_output_at(output_layout, closest_x, closest_y));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool match_monitor_spec(char *spec, Monitor *m) {
|
||||||
|
if (!spec || !m)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// if the spec does not contain a colon, treat it as a match on the monitor
|
||||||
|
// name
|
||||||
|
if (strchr(spec, ':') == NULL) {
|
||||||
|
return regex_match(spec, m->wlr_output->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *spec_copy = strdup(spec);
|
||||||
|
if (!spec_copy)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
char *name_rule = NULL;
|
||||||
|
char *make_rule = NULL;
|
||||||
|
char *model_rule = NULL;
|
||||||
|
char *serial_rule = NULL;
|
||||||
|
|
||||||
|
char *token = strtok(spec_copy, "&&");
|
||||||
|
while (token) {
|
||||||
|
char *colon = strchr(token, ':');
|
||||||
|
if (colon) {
|
||||||
|
*colon = '\0';
|
||||||
|
char *key = token;
|
||||||
|
char *value = colon + 1;
|
||||||
|
|
||||||
|
if (strcmp(key, "name") == 0)
|
||||||
|
name_rule = strdup(value);
|
||||||
|
else if (strcmp(key, "make") == 0)
|
||||||
|
make_rule = strdup(value);
|
||||||
|
else if (strcmp(key, "model") == 0)
|
||||||
|
model_rule = strdup(value);
|
||||||
|
else if (strcmp(key, "serial") == 0)
|
||||||
|
serial_rule = strdup(value);
|
||||||
|
}
|
||||||
|
token = strtok(NULL, "&&");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool match = true;
|
||||||
|
|
||||||
|
if (name_rule) {
|
||||||
|
if (!regex_match(name_rule, m->wlr_output->name))
|
||||||
|
match = false;
|
||||||
|
}
|
||||||
|
if (make_rule) {
|
||||||
|
if (!m->wlr_output->make || strcmp(make_rule, m->wlr_output->make) != 0)
|
||||||
|
match = false;
|
||||||
|
}
|
||||||
|
if (model_rule) {
|
||||||
|
if (!m->wlr_output->model ||
|
||||||
|
strcmp(model_rule, m->wlr_output->model) != 0)
|
||||||
|
match = false;
|
||||||
|
}
|
||||||
|
if (serial_rule) {
|
||||||
|
if (!m->wlr_output->serial ||
|
||||||
|
strcmp(serial_rule, m->wlr_output->serial) != 0)
|
||||||
|
match = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(spec_copy);
|
||||||
|
free(name_rule);
|
||||||
|
free(make_rule);
|
||||||
|
free(model_rule);
|
||||||
|
free(serial_rule);
|
||||||
|
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,82 @@
|
||||||
|
void save_old_size_per(Monitor *m) {
|
||||||
|
Client *c = NULL;
|
||||||
|
|
||||||
|
wl_list_for_each(c, &clients, link) {
|
||||||
|
if (VISIBLEON(c, m) && ISTILED(c)) {
|
||||||
|
c->old_master_inner_per = c->master_inner_per;
|
||||||
|
c->old_stack_inner_per = c->stack_inner_per;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void restore_size_per(Monitor *m, Client *c) {
|
||||||
|
Client *fc = NULL;
|
||||||
|
|
||||||
|
if (!m || !c)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wl_list_for_each(fc, &clients, link) {
|
||||||
|
if (VISIBLEON(fc, m) && ISTILED(fc)) {
|
||||||
|
fc->old_ismaster = fc->ismaster;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c->old_master_inner_per = c->master_inner_per;
|
||||||
|
c->old_stack_inner_per = c->stack_inner_per;
|
||||||
|
|
||||||
|
pre_caculate_before_arrange(m, false, false, true);
|
||||||
|
|
||||||
|
const Layout *current_layout = m->pertag->ltidxs[m->pertag->curtag];
|
||||||
|
|
||||||
|
if (current_layout->id == SCROLLER ||
|
||||||
|
current_layout->id == VERTICAL_SCROLLER || current_layout->id == GRID ||
|
||||||
|
current_layout->id == VERTICAL_GRID || current_layout->id == DECK ||
|
||||||
|
current_layout->id == VERTICAL_DECK || current_layout->id == MONOCLE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_layout->id == CENTER_TILE) {
|
||||||
|
wl_list_for_each(fc, &clients, link) {
|
||||||
|
if (VISIBLEON(fc, m) && ISTILED(fc) && !c->ismaster) {
|
||||||
|
set_size_per(m, fc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// it is possible that the current floating window is moved to another tag,
|
||||||
|
// but the tag has not executed save_old_size_per
|
||||||
|
// so it must be judged whether their old size values are initial values
|
||||||
|
|
||||||
|
if (!c->ismaster && c->old_stack_inner_per < 1.0 &&
|
||||||
|
c->old_stack_inner_per > 0.0f && c->stack_inner_per < 1.0 &&
|
||||||
|
c->stack_inner_per > 0.0f) {
|
||||||
|
c->stack_inner_per = (1.0 - c->stack_inner_per) *
|
||||||
|
c->old_stack_inner_per /
|
||||||
|
(1.0 - c->old_stack_inner_per);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->ismaster && c->old_master_inner_per < 1.0 &&
|
||||||
|
c->old_master_inner_per > 0.0f && c->master_inner_per < 1.0 &&
|
||||||
|
c->master_inner_per > 0.0f) {
|
||||||
|
c->master_inner_per = (1.0 - c->master_inner_per) *
|
||||||
|
c->old_master_inner_per /
|
||||||
|
(1.0 - c->old_master_inner_per);
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_list_for_each(fc, &clients, link) {
|
||||||
|
if (VISIBLEON(fc, m) && ISTILED(fc) && fc != c && !fc->ismaster &&
|
||||||
|
fc->old_ismaster && fc->old_stack_inner_per < 1.0 &&
|
||||||
|
fc->old_stack_inner_per > 0.0f && fc->stack_inner_per < 1.0 &&
|
||||||
|
fc->stack_inner_per > 0.0f) {
|
||||||
|
fc->stack_inner_per = (1.0 - fc->stack_inner_per) *
|
||||||
|
fc->old_stack_inner_per /
|
||||||
|
(1.0 - fc->old_stack_inner_per);
|
||||||
|
fc->old_ismaster = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void set_size_per(Monitor *m, Client *c) {
|
void set_size_per(Monitor *m, Client *c) {
|
||||||
Client *fc = NULL;
|
Client *fc = NULL;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
@ -5,8 +84,13 @@ void set_size_per(Monitor *m, Client *c) {
|
||||||
if (!m || !c)
|
if (!m || !c)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const Layout *current_layout = m->pertag->ltidxs[m->pertag->curtag];
|
||||||
|
|
||||||
wl_list_for_each(fc, &clients, link) {
|
wl_list_for_each(fc, &clients, link) {
|
||||||
if (VISIBLEON(fc, m) && ISTILED(fc) && fc != c) {
|
if (VISIBLEON(fc, m) && ISTILED(fc) && fc != c) {
|
||||||
|
if (current_layout->id == CENTER_TILE &&
|
||||||
|
(fc->isleftstack ^ c->isleftstack))
|
||||||
|
continue;
|
||||||
c->master_mfact_per = fc->master_mfact_per;
|
c->master_mfact_per = fc->master_mfact_per;
|
||||||
c->master_inner_per = fc->master_inner_per;
|
c->master_inner_per = fc->master_inner_per;
|
||||||
c->stack_inner_per = fc->stack_inner_per;
|
c->stack_inner_per = fc->stack_inner_per;
|
||||||
|
|
@ -43,8 +127,7 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!begin_find_nextnext && VISIBLEON(tc, grabc->mon) &&
|
if (!begin_find_nextnext && VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
||||||
ISTILED(tc)) { // 根据你的实际字段名调整
|
|
||||||
next = tc;
|
next = tc;
|
||||||
begin_find_nextnext = true;
|
begin_find_nextnext = true;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -60,8 +143,7 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!begin_find_prevprev && VISIBLEON(tc, grabc->mon) &&
|
if (!begin_find_prevprev && VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
||||||
ISTILED(tc)) { // 根据你的实际字段名调整
|
|
||||||
prev = tc;
|
prev = tc;
|
||||||
begin_find_prevprev = true;
|
begin_find_prevprev = true;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -197,6 +279,23 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
// 应用到所有平铺窗口
|
// 应用到所有平铺窗口
|
||||||
wl_list_for_each(tc, &clients, link) {
|
wl_list_for_each(tc, &clients, link) {
|
||||||
if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
||||||
|
|
||||||
|
if (!isdrag && tc != grabc) {
|
||||||
|
if (!tc->ismaster && new_stack_inner_per != 1.0f &&
|
||||||
|
grabc->old_stack_inner_per != 1.0f &&
|
||||||
|
(type != CENTER_TILE ||
|
||||||
|
!(grabc->isleftstack ^ tc->isleftstack)))
|
||||||
|
tc->stack_inner_per = (1 - new_stack_inner_per) /
|
||||||
|
(1 - grabc->old_stack_inner_per) *
|
||||||
|
tc->stack_inner_per;
|
||||||
|
if (tc->ismaster && new_master_inner_per != 1.0f &&
|
||||||
|
grabc->old_master_inner_per != 1.0f)
|
||||||
|
tc->master_inner_per =
|
||||||
|
(1.0f - new_master_inner_per) /
|
||||||
|
(1.0f - grabc->old_master_inner_per) *
|
||||||
|
tc->master_inner_per;
|
||||||
|
}
|
||||||
|
|
||||||
tc->master_mfact_per = new_master_mfact_per;
|
tc->master_mfact_per = new_master_mfact_per;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -210,7 +309,7 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_apply_drap_time == 0 ||
|
if (last_apply_drap_time == 0 ||
|
||||||
time - last_apply_drap_time > drag_refresh_interval) {
|
time - last_apply_drap_time > config.drag_tile_refresh_interval) {
|
||||||
arrange(grabc->mon, false, false);
|
arrange(grabc->mon, false, false);
|
||||||
last_apply_drap_time = time;
|
last_apply_drap_time = time;
|
||||||
}
|
}
|
||||||
|
|
@ -229,8 +328,7 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
for (node = grabc->link.next; node != &clients; node = node->next) {
|
for (node = grabc->link.next; node != &clients; node = node->next) {
|
||||||
tc = wl_container_of(node, tc, link);
|
tc = wl_container_of(node, tc, link);
|
||||||
|
|
||||||
if (VISIBLEON(tc, grabc->mon) &&
|
if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
||||||
ISTILED(tc)) { // 根据你的实际字段名调整
|
|
||||||
next = tc;
|
next = tc;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -240,8 +338,7 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
for (node = grabc->link.prev; node != &clients; node = node->prev) {
|
for (node = grabc->link.prev; node != &clients; node = node->prev) {
|
||||||
tc = wl_container_of(node, tc, link);
|
tc = wl_container_of(node, tc, link);
|
||||||
|
|
||||||
if (VISIBLEON(tc, grabc->mon) &&
|
if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
||||||
ISTILED(tc)) { // 根据你的实际字段名调整
|
|
||||||
prev = tc;
|
prev = tc;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -354,6 +451,20 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
// 应用到所有平铺窗口
|
// 应用到所有平铺窗口
|
||||||
wl_list_for_each(tc, &clients, link) {
|
wl_list_for_each(tc, &clients, link) {
|
||||||
if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
||||||
|
if (!isdrag && tc != grabc && type != CENTER_TILE) {
|
||||||
|
if (!tc->ismaster && new_stack_inner_per != 1.0f &&
|
||||||
|
grabc->old_stack_inner_per != 1.0f)
|
||||||
|
tc->stack_inner_per = (1 - new_stack_inner_per) /
|
||||||
|
(1 - grabc->old_stack_inner_per) *
|
||||||
|
tc->stack_inner_per;
|
||||||
|
if (tc->ismaster && new_master_inner_per != 1.0f &&
|
||||||
|
grabc->old_master_inner_per != 1.0f)
|
||||||
|
tc->master_inner_per =
|
||||||
|
(1.0f - new_master_inner_per) /
|
||||||
|
(1.0f - grabc->old_master_inner_per) *
|
||||||
|
tc->master_inner_per;
|
||||||
|
}
|
||||||
|
|
||||||
tc->master_mfact_per = new_master_mfact_per;
|
tc->master_mfact_per = new_master_mfact_per;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -367,7 +478,7 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_apply_drap_time == 0 ||
|
if (last_apply_drap_time == 0 ||
|
||||||
time - last_apply_drap_time > drag_refresh_interval) {
|
time - last_apply_drap_time > config.drag_tile_refresh_interval) {
|
||||||
arrange(grabc->mon, false, false);
|
arrange(grabc->mon, false, false);
|
||||||
last_apply_drap_time = time;
|
last_apply_drap_time = time;
|
||||||
}
|
}
|
||||||
|
|
@ -376,13 +487,14 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
|
|
||||||
void resize_tile_scroller(Client *grabc, bool isdrag, int32_t offsetx,
|
void resize_tile_scroller(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
int32_t offsety, uint32_t time, bool isvertical) {
|
int32_t offsety, uint32_t time, bool isvertical) {
|
||||||
|
Client *tc = NULL;
|
||||||
float delta_x, delta_y;
|
float delta_x, delta_y;
|
||||||
float new_scroller_proportion;
|
float new_scroller_proportion;
|
||||||
float new_stack_proportion;
|
float new_stack_proportion;
|
||||||
Client *stack_head = get_scroll_stack_head(grabc);
|
Client *stack_head = get_scroll_stack_head(grabc);
|
||||||
|
|
||||||
if (grabc && grabc->mon->visible_tiling_clients == 1 &&
|
if (grabc && grabc->mon->visible_tiling_clients == 1 &&
|
||||||
!scroller_ignore_proportion_single)
|
!config.scroller_ignore_proportion_single)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!start_drag_window && isdrag) {
|
if (!start_drag_window && isdrag) {
|
||||||
|
|
@ -536,19 +648,29 @@ void resize_tile_scroller(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
// 应用限制,确保比例在合理范围内
|
// 应用限制,确保比例在合理范围内
|
||||||
new_scroller_proportion =
|
new_scroller_proportion =
|
||||||
fmaxf(0.1f, fminf(1.0f, new_scroller_proportion));
|
fmaxf(0.1f, fminf(1.0f, new_scroller_proportion));
|
||||||
new_stack_proportion = fmaxf(0.1f, fminf(1.0f, new_stack_proportion));
|
new_stack_proportion = fmaxf(0.1f, fminf(0.9f, new_stack_proportion));
|
||||||
|
|
||||||
grabc->stack_proportion = new_stack_proportion;
|
grabc->stack_proportion = new_stack_proportion;
|
||||||
|
|
||||||
stack_head->scroller_proportion = new_scroller_proportion;
|
stack_head->scroller_proportion = new_scroller_proportion;
|
||||||
|
|
||||||
|
wl_list_for_each(tc, &clients, link) {
|
||||||
|
if (!isdrag && new_stack_proportion != 1.0f &&
|
||||||
|
grabc->old_stack_proportion != 1.0f && tc != grabc &&
|
||||||
|
ISTILED(tc) && get_scroll_stack_head(tc) == stack_head) {
|
||||||
|
tc->stack_proportion = (1.0f - new_stack_proportion) /
|
||||||
|
(1.0f - grabc->old_stack_proportion) *
|
||||||
|
tc->stack_proportion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!isdrag) {
|
if (!isdrag) {
|
||||||
arrange(grabc->mon, false, false);
|
arrange(grabc->mon, false, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_apply_drap_time == 0 ||
|
if (last_apply_drap_time == 0 ||
|
||||||
time - last_apply_drap_time > drag_refresh_interval) {
|
time - last_apply_drap_time > config.drag_tile_refresh_interval) {
|
||||||
arrange(grabc->mon, false, false);
|
arrange(grabc->mon, false, false);
|
||||||
last_apply_drap_time = time;
|
last_apply_drap_time = time;
|
||||||
}
|
}
|
||||||
|
|
@ -584,6 +706,18 @@ void resize_tile_client(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If there are no calculation omissions,
|
||||||
|
these two functions will never be triggered.
|
||||||
|
Just in case to facilitate the final investigation*/
|
||||||
|
|
||||||
|
void check_size_per_valid(Client *c) {
|
||||||
|
if (c->ismaster) {
|
||||||
|
assert(c->master_inner_per > 0.0f && c->master_inner_per <= 1.0f);
|
||||||
|
} else {
|
||||||
|
assert(c->stack_inner_per > 0.0f && c->stack_inner_per <= 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void reset_size_per_mon(Monitor *m, int32_t tile_cilent_num,
|
void reset_size_per_mon(Monitor *m, int32_t tile_cilent_num,
|
||||||
double total_left_stack_hight_percent,
|
double total_left_stack_hight_percent,
|
||||||
double total_right_stack_hight_percent,
|
double total_right_stack_hight_percent,
|
||||||
|
|
@ -599,6 +733,7 @@ void reset_size_per_mon(Monitor *m, int32_t tile_cilent_num,
|
||||||
|
|
||||||
wl_list_for_each(c, &clients, link) {
|
wl_list_for_each(c, &clients, link) {
|
||||||
if (VISIBLEON(c, m) && ISTILED(c)) {
|
if (VISIBLEON(c, m) && ISTILED(c)) {
|
||||||
|
|
||||||
if (total_master_inner_percent > 0.0 && i < nmasters) {
|
if (total_master_inner_percent > 0.0 && i < nmasters) {
|
||||||
c->ismaster = true;
|
c->ismaster = true;
|
||||||
c->stack_inner_per = stack_num ? 1.0f / stack_num : 1.0f;
|
c->stack_inner_per = stack_num ? 1.0f / stack_num : 1.0f;
|
||||||
|
|
@ -614,17 +749,20 @@ void reset_size_per_mon(Monitor *m, int32_t tile_cilent_num,
|
||||||
: 1.0f;
|
: 1.0f;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
|
check_size_per_valid(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
wl_list_for_each(c, &clients, link) {
|
wl_list_for_each(c, &clients, link) {
|
||||||
if (VISIBLEON(c, m) && ISTILED(c)) {
|
if (VISIBLEON(c, m) && ISTILED(c)) {
|
||||||
|
|
||||||
if (total_master_inner_percent > 0.0 && i < nmasters) {
|
if (total_master_inner_percent > 0.0 && i < nmasters) {
|
||||||
c->ismaster = true;
|
c->ismaster = true;
|
||||||
if ((stack_index % 2) ^ (tile_cilent_num % 2 == 0)) {
|
if ((stack_index % 2) ^ (tile_cilent_num % 2 == 0)) {
|
||||||
c->stack_inner_per =
|
c->stack_inner_per =
|
||||||
stack_num > 1 ? 1.0f / ((stack_num - 1) / 2) : 1.0f;
|
stack_num > 1 ? 1.0f / ((stack_num - 1) / 2.0f)
|
||||||
|
: 1.0f;
|
||||||
} else {
|
} else {
|
||||||
c->stack_inner_per =
|
c->stack_inner_per =
|
||||||
stack_num > 1 ? 2.0f / stack_num : 1.0f;
|
stack_num > 1 ? 2.0f / stack_num : 1.0f;
|
||||||
|
|
@ -653,13 +791,15 @@ void reset_size_per_mon(Monitor *m, int32_t tile_cilent_num,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
|
check_size_per_valid(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void // 17
|
void pre_caculate_before_arrange(Monitor *m, bool want_animation,
|
||||||
arrange(Monitor *m, bool want_animation, bool from_view) {
|
bool from_view, bool only_caculate) {
|
||||||
Client *c = NULL;
|
Client *c = NULL;
|
||||||
double total_stack_inner_percent = 0;
|
double total_stack_inner_percent = 0;
|
||||||
double total_master_inner_percent = 0;
|
double total_master_inner_percent = 0;
|
||||||
|
|
@ -748,14 +888,17 @@ arrange(Monitor *m, bool want_animation, bool from_view) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!only_caculate)
|
||||||
set_arrange_visible(m, c, want_animation);
|
set_arrange_visible(m, c, want_animation);
|
||||||
} else {
|
} else {
|
||||||
|
if (!only_caculate)
|
||||||
set_arrange_hidden(m, c, want_animation);
|
set_arrange_hidden(m, c, want_animation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->mon == m && c->ismaximizescreen && !c->animation.tagouted &&
|
if (!only_caculate && c->mon == m && c->ismaximizescreen &&
|
||||||
!c->animation.tagouting && VISIBLEON(c, m)) {
|
!c->animation.tagouted && !c->animation.tagouting &&
|
||||||
|
VISIBLEON(c, m)) {
|
||||||
reset_maximizescreen_size(c);
|
reset_maximizescreen_size(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -764,6 +907,12 @@ arrange(Monitor *m, bool want_animation, bool from_view) {
|
||||||
m, m->visible_tiling_clients, total_left_stack_hight_percent,
|
m, m->visible_tiling_clients, total_left_stack_hight_percent,
|
||||||
total_right_stack_hight_percent, total_stack_inner_percent,
|
total_right_stack_hight_percent, total_stack_inner_percent,
|
||||||
total_master_inner_percent, master_num, stack_num);
|
total_master_inner_percent, master_num, stack_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
void // 17
|
||||||
|
arrange(Monitor *m, bool want_animation, bool from_view) {
|
||||||
|
|
||||||
|
pre_caculate_before_arrange(m, want_animation, from_view, false);
|
||||||
|
|
||||||
if (m->isoverview) {
|
if (m->isoverview) {
|
||||||
overviewlayout.arrange(m);
|
overviewlayout.arrange(m);
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@ void grid(Monitor *m) {
|
||||||
Client *c = NULL;
|
Client *c = NULL;
|
||||||
n = 0;
|
n = 0;
|
||||||
int32_t target_gappo =
|
int32_t target_gappo =
|
||||||
enablegaps ? m->isoverview ? overviewgappo : gappoh : 0;
|
enablegaps ? m->isoverview ? config.overviewgappo : config.gappoh : 0;
|
||||||
int32_t target_gappi =
|
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_width_ratio = m->isoverview ? 0.7 : 0.9;
|
||||||
float single_height_ratio = m->isoverview ? 0.8 : 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_gappoh = enablegaps ? m->gappoh : 0;
|
||||||
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
||||||
|
|
||||||
cur_gappih = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappih;
|
cur_gappih =
|
||||||
cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappih;
|
||||||
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;
|
||||||
|
|
||||||
n = m->visible_tiling_clients;
|
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_gappoh = enablegaps ? m->gappoh : 0;
|
||||||
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
||||||
|
|
||||||
cur_gappih =
|
cur_gappih = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappih;
|
? 0
|
||||||
cur_gappoh =
|
: cur_gappih;
|
||||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappoh;
|
cur_gappoh = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||||
cur_gappov =
|
? 0
|
||||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappov;
|
: cur_gappoh;
|
||||||
|
cur_gappov = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||||
|
? 0
|
||||||
|
: cur_gappov;
|
||||||
|
|
||||||
if (c->isfullscreen) {
|
if (c->isfullscreen) {
|
||||||
target_geom->height = m->m.height;
|
target_geom->height = m->m.height;
|
||||||
|
|
@ -283,19 +289,24 @@ void scroller(Monitor *m) {
|
||||||
struct wlr_box target_geom;
|
struct wlr_box target_geom;
|
||||||
int32_t focus_client_index = 0;
|
int32_t focus_client_index = 0;
|
||||||
bool need_scroller = false;
|
bool need_scroller = false;
|
||||||
|
bool over_overspread_to_left = false;
|
||||||
int32_t cur_gappih = enablegaps ? m->gappih : 0;
|
int32_t cur_gappih = enablegaps ? m->gappih : 0;
|
||||||
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
||||||
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
||||||
int32_t cur_gappiv = enablegaps ? m->gappiv : 0;
|
int32_t cur_gappiv = enablegaps ? m->gappiv : 0;
|
||||||
|
|
||||||
cur_gappih =
|
cur_gappih = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappih;
|
? 0
|
||||||
cur_gappoh =
|
: cur_gappih;
|
||||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappoh;
|
cur_gappoh = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||||
cur_gappov =
|
? 0
|
||||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappov;
|
: 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;
|
n = m->visible_scroll_tiling_clients;
|
||||||
|
|
||||||
|
|
@ -319,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) {
|
!tempClients[0]->isfullscreen && !tempClients[0]->ismaximizescreen) {
|
||||||
c = tempClients[0];
|
c = tempClients[0];
|
||||||
|
|
||||||
single_proportion = c->scroller_proportion_single > 0.0f
|
single_proportion = c->scroller_proportion_single > 0.0f
|
||||||
? c->scroller_proportion_single
|
? c->scroller_proportion_single
|
||||||
: scroller_default_proportion_single;
|
: config.scroller_default_proportion_single;
|
||||||
|
|
||||||
target_geom.height = m->w.height - 2 * cur_gappov;
|
target_geom.height = m->w.height - 2 * cur_gappov;
|
||||||
target_geom.width = (m->w.width - 2 * cur_gappoh) * single_proportion;
|
target_geom.width = (m->w.width - 2 * cur_gappoh) * single_proportion;
|
||||||
|
|
@ -359,9 +370,9 @@ void scroller(Monitor *m) {
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
c = tempClients[i];
|
c = tempClients[i];
|
||||||
if (root_client == c) {
|
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 <=
|
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;
|
need_scroller = false;
|
||||||
} else {
|
} else {
|
||||||
need_scroller = true;
|
need_scroller = true;
|
||||||
|
|
@ -371,7 +382,48 @@ void scroller(Monitor *m) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n == 1 && scroller_ignore_proportion_single) {
|
bool need_apply_overspread =
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (need_apply_overspread) {
|
||||||
|
|
||||||
|
if (focus_client_index == 0) {
|
||||||
|
over_overspread_to_left = true;
|
||||||
|
} else {
|
||||||
|
over_overspread_to_left = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (over_overspread_to_left &&
|
||||||
|
(!INSIDEMON(tempClients[1]) ||
|
||||||
|
(tempClients[1]->scroller_proportion +
|
||||||
|
tempClients[focus_client_index]->scroller_proportion >=
|
||||||
|
1.0f))) {
|
||||||
|
need_scroller = true;
|
||||||
|
} else if (!over_overspread_to_left &&
|
||||||
|
(!INSIDEMON(tempClients[focus_client_index - 1]) ||
|
||||||
|
(tempClients[focus_client_index - 1]->scroller_proportion +
|
||||||
|
tempClients[focus_client_index]->scroller_proportion >=
|
||||||
|
1.0f))) {
|
||||||
|
need_scroller = true;
|
||||||
|
} else {
|
||||||
|
need_apply_overspread = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool need_apply_center =
|
||||||
|
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 * config.scroller_structs - cur_gappih)));
|
||||||
|
|
||||||
|
if (n == 1 && config.scroller_ignore_proportion_single) {
|
||||||
need_scroller = true;
|
need_scroller = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -394,21 +446,29 @@ void scroller(Monitor *m) {
|
||||||
tempClients[focus_client_index], &target_geom);
|
tempClients[focus_client_index], &target_geom);
|
||||||
arrange_stack(tempClients[focus_client_index], target_geom, cur_gappiv);
|
arrange_stack(tempClients[focus_client_index], target_geom, cur_gappiv);
|
||||||
} else if (need_scroller) {
|
} else if (need_scroller) {
|
||||||
if (scroller_focus_center ||
|
if (need_apply_center) {
|
||||||
((!m->prevsel ||
|
|
||||||
(ISSCROLLTILED(m->prevsel) &&
|
|
||||||
(m->prevsel->scroller_proportion * max_client_width) +
|
|
||||||
(root_client->scroller_proportion * max_client_width) >
|
|
||||||
m->w.width - 2 * scroller_structs - cur_gappih)) &&
|
|
||||||
scroller_prefer_center)) {
|
|
||||||
target_geom.x = m->w.x + (m->w.width - target_geom.width) / 2;
|
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 + config.scroller_structs;
|
||||||
} else {
|
} else {
|
||||||
target_geom.x = root_client->geom.x > m->w.x + (m->w.width) / 2
|
target_geom.x =
|
||||||
? m->w.x + (m->w.width -
|
m->w.x +
|
||||||
root_client->scroller_proportion *
|
(m->w.width -
|
||||||
|
tempClients[focus_client_index]->scroller_proportion *
|
||||||
max_client_width -
|
max_client_width -
|
||||||
scroller_structs)
|
config.scroller_structs);
|
||||||
: m->w.x + scroller_structs;
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
target_geom.x = tempClients[focus_client_index]->geom.x >
|
||||||
|
m->w.x + (m->w.width) / 2
|
||||||
|
? m->w.x + (m->w.width -
|
||||||
|
tempClients[focus_client_index]
|
||||||
|
->scroller_proportion *
|
||||||
|
max_client_width -
|
||||||
|
config.scroller_structs)
|
||||||
|
: m->w.x + config.scroller_structs;
|
||||||
}
|
}
|
||||||
horizontal_check_scroller_root_inside_mon(
|
horizontal_check_scroller_root_inside_mon(
|
||||||
tempClients[focus_client_index], &target_geom);
|
tempClients[focus_client_index], &target_geom);
|
||||||
|
|
@ -473,10 +533,14 @@ void center_tile(Monitor *m) {
|
||||||
int32_t cur_gappoh = enablegaps ? m->gappoh : 0; // 外部水平间隙
|
int32_t cur_gappoh = enablegaps ? m->gappoh : 0; // 外部水平间隙
|
||||||
|
|
||||||
// 智能间隙处理
|
// 智能间隙处理
|
||||||
cur_gappiv = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv;
|
cur_gappiv =
|
||||||
cur_gappih = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappih;
|
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv;
|
||||||
cur_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
cur_gappih =
|
||||||
cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
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];
|
int32_t nmasters = m->pertag->nmasters[m->pertag->curtag];
|
||||||
mfact = fc->master_mfact_per > 0.0f ? fc->master_mfact_per
|
mfact = fc->master_mfact_per > 0.0f ? fc->master_mfact_per
|
||||||
|
|
@ -489,7 +553,8 @@ void center_tile(Monitor *m) {
|
||||||
tw = mw;
|
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 =
|
int32_t master_surplus_height =
|
||||||
(m->w.height - 2 * cur_gappov - cur_gappiv * ie * (master_num - 1));
|
(m->w.height - 2 * cur_gappov - cur_gappiv * ie * (master_num - 1));
|
||||||
|
|
@ -515,7 +580,7 @@ void center_tile(Monitor *m) {
|
||||||
mx = cur_gappoh + tw + cur_gappih * ie;
|
mx = cur_gappoh + tw + cur_gappih * ie;
|
||||||
} else if (n - nmasters == 1) {
|
} else if (n - nmasters == 1) {
|
||||||
// 单个堆叠窗口的处理
|
// 单个堆叠窗口的处理
|
||||||
if (center_when_single_stack) {
|
if (config.center_when_single_stack) {
|
||||||
// stack在右边,master居中,左边空着
|
// stack在右边,master居中,左边空着
|
||||||
tw = (m->w.width - mw) / 2 - cur_gappoh - cur_gappih * ie;
|
tw = (m->w.width - mw) / 2 - cur_gappoh - cur_gappih * ie;
|
||||||
mx = cur_gappoh + tw + cur_gappih * ie; // master居中
|
mx = cur_gappoh + tw + cur_gappih * ie; // master居中
|
||||||
|
|
@ -592,7 +657,7 @@ void center_tile(Monitor *m) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t stack_x;
|
int32_t stack_x;
|
||||||
if (center_when_single_stack) {
|
if (config.center_when_single_stack) {
|
||||||
// 放在右侧(master居中时,stack在右边)
|
// 放在右侧(master居中时,stack在右边)
|
||||||
stack_x = m->w.x + mx + mw + cur_gappih * ie;
|
stack_x = m->w.x + mx + mw + cur_gappih * ie;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -696,10 +761,14 @@ void tile(Monitor *m) {
|
||||||
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
||||||
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
||||||
|
|
||||||
cur_gappiv = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv;
|
cur_gappiv =
|
||||||
cur_gappih = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappih;
|
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv;
|
||||||
cur_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
cur_gappih =
|
||||||
cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
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) {
|
wl_list_for_each(fc, &clients, link) {
|
||||||
|
|
||||||
|
|
@ -806,10 +875,14 @@ void right_tile(Monitor *m) {
|
||||||
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
||||||
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
||||||
|
|
||||||
cur_gappiv = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv;
|
cur_gappiv =
|
||||||
cur_gappih = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappih;
|
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv;
|
||||||
cur_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
cur_gappih =
|
||||||
cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
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) {
|
wl_list_for_each(fc, &clients, link) {
|
||||||
|
|
||||||
|
|
@ -904,8 +977,10 @@ monocle(Monitor *m) {
|
||||||
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
||||||
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
||||||
|
|
||||||
cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
cur_gappoh =
|
||||||
cur_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
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) {
|
wl_list_for_each(c, &clients, link) {
|
||||||
if (!VISIBLEON(c, m) || !ISTILED(c))
|
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_gapoh = enablegaps ? m->gappoh : 0;
|
||||||
int32_t cur_gapov = enablegaps ? m->gappov : 0;
|
int32_t cur_gapov = enablegaps ? m->gappov : 0;
|
||||||
|
|
||||||
cur_gapih = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapih;
|
cur_gapih =
|
||||||
cur_gapiv = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapiv;
|
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapih;
|
||||||
cur_gapoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapoh;
|
cur_gapiv =
|
||||||
cur_gapov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapov;
|
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) {
|
wl_list_for_each(fc, &clients, link) {
|
||||||
if (VISIBLEON(fc, m) && ISTILED(fc))
|
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_gappoh = enablegaps ? m->gappoh : 0;
|
||||||
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
||||||
|
|
||||||
cur_gappiv = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv;
|
cur_gappiv =
|
||||||
cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
config.smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv;
|
||||||
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;
|
||||||
|
|
||||||
n = m->visible_tiling_clients;
|
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_gappov = enablegaps ? m->gappov : 0;
|
||||||
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
||||||
|
|
||||||
cur_gappiv =
|
cur_gappiv = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappiv;
|
? 0
|
||||||
cur_gappov =
|
: cur_gappiv;
|
||||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappov;
|
cur_gappov = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||||
cur_gappoh =
|
? 0
|
||||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappoh;
|
: cur_gappov;
|
||||||
|
cur_gappoh = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||||
|
? 0
|
||||||
|
: cur_gappoh;
|
||||||
|
|
||||||
if (c->isfullscreen) {
|
if (c->isfullscreen) {
|
||||||
target_geom->width = m->m.width;
|
target_geom->width = m->m.width;
|
||||||
|
|
@ -270,19 +280,24 @@ void vertical_scroller(Monitor *m) {
|
||||||
struct wlr_box target_geom;
|
struct wlr_box target_geom;
|
||||||
int32_t focus_client_index = 0;
|
int32_t focus_client_index = 0;
|
||||||
bool need_scroller = false;
|
bool need_scroller = false;
|
||||||
|
bool over_overspread_to_up = false;
|
||||||
int32_t cur_gappiv = enablegaps ? m->gappiv : 0;
|
int32_t cur_gappiv = enablegaps ? m->gappiv : 0;
|
||||||
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
||||||
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
||||||
int32_t cur_gappih = enablegaps ? m->gappih : 0;
|
int32_t cur_gappih = enablegaps ? m->gappih : 0;
|
||||||
|
|
||||||
cur_gappiv =
|
cur_gappiv = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappiv;
|
? 0
|
||||||
cur_gappov =
|
: cur_gappiv;
|
||||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappov;
|
cur_gappov = config.smartgaps && m->visible_scroll_tiling_clients == 1
|
||||||
cur_gappoh =
|
? 0
|
||||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappoh;
|
: 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;
|
n = m->visible_scroll_tiling_clients;
|
||||||
|
|
||||||
|
|
@ -303,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) {
|
!tempClients[0]->isfullscreen && !tempClients[0]->ismaximizescreen) {
|
||||||
c = tempClients[0];
|
c = tempClients[0];
|
||||||
|
|
||||||
single_proportion = c->scroller_proportion_single > 0.0f
|
single_proportion = c->scroller_proportion_single > 0.0f
|
||||||
? c->scroller_proportion_single
|
? c->scroller_proportion_single
|
||||||
: scroller_default_proportion_single;
|
: config.scroller_default_proportion_single;
|
||||||
|
|
||||||
target_geom.width = m->w.width - 2 * cur_gappoh;
|
target_geom.width = m->w.width - 2 * cur_gappoh;
|
||||||
target_geom.height = (m->w.height - 2 * cur_gappov) * single_proportion;
|
target_geom.height = (m->w.height - 2 * cur_gappov) * single_proportion;
|
||||||
|
|
@ -343,9 +358,9 @@ void vertical_scroller(Monitor *m) {
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
c = tempClients[i];
|
c = tempClients[i];
|
||||||
if (root_client == c) {
|
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 <=
|
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;
|
need_scroller = false;
|
||||||
} else {
|
} else {
|
||||||
need_scroller = true;
|
need_scroller = true;
|
||||||
|
|
@ -355,7 +370,48 @@ void vertical_scroller(Monitor *m) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n == 1 && scroller_ignore_proportion_single) {
|
bool need_apply_overspread =
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (need_apply_overspread) {
|
||||||
|
|
||||||
|
if (focus_client_index == 0) {
|
||||||
|
over_overspread_to_up = true;
|
||||||
|
} else {
|
||||||
|
over_overspread_to_up = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (over_overspread_to_up &&
|
||||||
|
(!INSIDEMON(tempClients[1]) ||
|
||||||
|
(tempClients[1]->scroller_proportion +
|
||||||
|
tempClients[focus_client_index]->scroller_proportion >=
|
||||||
|
1.0f))) {
|
||||||
|
need_scroller = true;
|
||||||
|
} else if (!over_overspread_to_up &&
|
||||||
|
(!INSIDEMON(tempClients[focus_client_index - 1]) ||
|
||||||
|
(tempClients[focus_client_index - 1]->scroller_proportion +
|
||||||
|
tempClients[focus_client_index]->scroller_proportion >=
|
||||||
|
1.0f))) {
|
||||||
|
need_scroller = true;
|
||||||
|
} else {
|
||||||
|
need_apply_overspread = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool need_apply_center =
|
||||||
|
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 * config.scroller_structs - cur_gappiv)));
|
||||||
|
|
||||||
|
if (n == 1 && config.scroller_ignore_proportion_single) {
|
||||||
need_scroller = true;
|
need_scroller = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -381,21 +437,27 @@ void vertical_scroller(Monitor *m) {
|
||||||
arrange_stack_vertical(tempClients[focus_client_index], target_geom,
|
arrange_stack_vertical(tempClients[focus_client_index], target_geom,
|
||||||
cur_gappih);
|
cur_gappih);
|
||||||
} else if (need_scroller) {
|
} else if (need_scroller) {
|
||||||
if (scroller_focus_center ||
|
if (need_apply_center) {
|
||||||
((!m->prevsel ||
|
|
||||||
(ISSCROLLTILED(m->prevsel) &&
|
|
||||||
(m->prevsel->scroller_proportion * max_client_height) +
|
|
||||||
(root_client->scroller_proportion * max_client_height) >
|
|
||||||
m->w.height - 2 * scroller_structs - cur_gappiv)) &&
|
|
||||||
scroller_prefer_center)) {
|
|
||||||
target_geom.y = m->w.y + (m->w.height - target_geom.height) / 2;
|
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 + config.scroller_structs;
|
||||||
|
} else {
|
||||||
|
target_geom.y =
|
||||||
|
m->w.y +
|
||||||
|
(m->w.height -
|
||||||
|
tempClients[focus_client_index]->scroller_proportion *
|
||||||
|
max_client_height -
|
||||||
|
config.scroller_structs);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
target_geom.y = root_client->geom.y > m->w.y + (m->w.height) / 2
|
target_geom.y = root_client->geom.y > m->w.y + (m->w.height) / 2
|
||||||
? m->w.y + (m->w.height -
|
? m->w.y + (m->w.height -
|
||||||
root_client->scroller_proportion *
|
tempClients[focus_client_index]
|
||||||
|
->scroller_proportion *
|
||||||
max_client_height -
|
max_client_height -
|
||||||
scroller_structs)
|
config.scroller_structs)
|
||||||
: m->w.y + scroller_structs;
|
: m->w.y + config.scroller_structs;
|
||||||
}
|
}
|
||||||
vertical_check_scroller_root_inside_mon(tempClients[focus_client_index],
|
vertical_check_scroller_root_inside_mon(tempClients[focus_client_index],
|
||||||
&target_geom);
|
&target_geom);
|
||||||
|
|
@ -439,9 +501,9 @@ void vertical_grid(Monitor *m) {
|
||||||
int32_t rows, cols, overrows;
|
int32_t rows, cols, overrows;
|
||||||
Client *c = NULL;
|
Client *c = NULL;
|
||||||
int32_t target_gappo =
|
int32_t target_gappo =
|
||||||
enablegaps ? m->isoverview ? overviewgappo : gappov : 0;
|
enablegaps ? m->isoverview ? config.overviewgappo : config.gappov : 0;
|
||||||
int32_t target_gappi =
|
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_width_ratio = m->isoverview ? 0.7 : 0.9;
|
||||||
float single_height_ratio = m->isoverview ? 0.8 : 0.9;
|
float single_height_ratio = m->isoverview ? 0.8 : 0.9;
|
||||||
|
|
||||||
|
|
|
||||||
1127
src/mango.c
1127
src/mango.c
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue