mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-05-19 10:16:59 +02:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2dbf7da249 |
@@ -1 +0,0 @@
|
|||||||
*.json text diff
|
|
||||||
@@ -65,7 +65,7 @@ jobs:
|
|||||||
- run: |
|
- run: |
|
||||||
cargo install cargo-wix
|
cargo install cargo-wix
|
||||||
cargo wix --no-build -p komorebi --nocapture -I .\wix\main.wxs --target ${{ matrix.platform.target }}
|
cargo wix --no-build -p komorebi --nocapture -I .\wix\main.wxs --target ${{ matrix.platform.target }}
|
||||||
- uses: actions/upload-artifact@v6
|
- uses: actions/upload-artifact@v5
|
||||||
with:
|
with:
|
||||||
name: komorebi-${{ matrix.platform.target }}-${{ github.sha }}
|
name: komorebi-${{ matrix.platform.target }}-${{ github.sha }}
|
||||||
path: |
|
path: |
|
||||||
@@ -87,7 +87,7 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- shell: bash
|
- shell: bash
|
||||||
run: echo "VERSION=nightly" >> $GITHUB_ENV
|
run: echo "VERSION=nightly" >> $GITHUB_ENV
|
||||||
- uses: actions/download-artifact@v7
|
- uses: actions/download-artifact@v6
|
||||||
- run: |
|
- run: |
|
||||||
Compress-Archive -Force ./komorebi-x86_64-pc-windows-msvc-${{ github.sha }}/x86_64-pc-windows-msvc/release/*.exe komorebi-$Env:VERSION-x86_64-pc-windows-msvc.zip
|
Compress-Archive -Force ./komorebi-x86_64-pc-windows-msvc-${{ github.sha }}/x86_64-pc-windows-msvc/release/*.exe komorebi-$Env:VERSION-x86_64-pc-windows-msvc.zip
|
||||||
Copy-Item ./komorebi-x86_64-pc-windows-msvc-${{ github.sha }}/wix/*x86_64.msi -Destination ./komorebi-$Env:VERSION-x86_64.msi
|
Copy-Item ./komorebi-x86_64-pc-windows-msvc-${{ github.sha }}/wix/*x86_64.msi -Destination ./komorebi-$Env:VERSION-x86_64.msi
|
||||||
@@ -136,7 +136,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
TAG=${{ github.event.release.tag_name }}
|
TAG=${{ github.event.release.tag_name }}
|
||||||
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
|
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
|
||||||
- uses: actions/download-artifact@v7
|
- uses: actions/download-artifact@v6
|
||||||
- run: |
|
- run: |
|
||||||
Compress-Archive -Force ./komorebi-x86_64-pc-windows-msvc-${{ github.sha }}/x86_64-pc-windows-msvc/release/*.exe komorebi-$Env:VERSION-x86_64-pc-windows-msvc.zip
|
Compress-Archive -Force ./komorebi-x86_64-pc-windows-msvc-${{ github.sha }}/x86_64-pc-windows-msvc/release/*.exe komorebi-$Env:VERSION-x86_64-pc-windows-msvc.zip
|
||||||
Copy-Item ./komorebi-x86_64-pc-windows-msvc-${{ github.sha }}/wix/*x86_64.msi -Destination ./komorebi-$Env:VERSION-x86_64.msi
|
Copy-Item ./komorebi-x86_64-pc-windows-msvc-${{ github.sha }}/wix/*x86_64.msi -Destination ./komorebi-$Env:VERSION-x86_64.msi
|
||||||
@@ -178,7 +178,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
TAG=${{ github.ref_name }}
|
TAG=${{ github.ref_name }}
|
||||||
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
|
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
|
||||||
- uses: actions/download-artifact@v7
|
- uses: actions/download-artifact@v6
|
||||||
- run: |
|
- run: |
|
||||||
Compress-Archive -Force ./komorebi-x86_64-pc-windows-msvc-${{ github.sha }}/x86_64-pc-windows-msvc/release/*.exe komorebi-$Env:VERSION-x86_64-pc-windows-msvc.zip
|
Compress-Archive -Force ./komorebi-x86_64-pc-windows-msvc-${{ github.sha }}/x86_64-pc-windows-msvc/release/*.exe komorebi-$Env:VERSION-x86_64-pc-windows-msvc.zip
|
||||||
Copy-Item ./komorebi-x86_64-pc-windows-msvc-${{ github.sha }}/wix/*x86_64.msi -Destination ./komorebi-$Env:VERSION-x86_64.msi
|
Copy-Item ./komorebi-x86_64-pc-windows-msvc-${{ github.sha }}/wix/*x86_64.msi -Destination ./komorebi-$Env:VERSION-x86_64.msi
|
||||||
|
|||||||
Generated
+439
-582
File diff suppressed because it is too large
Load Diff
+1
-2
@@ -5,7 +5,6 @@ members = [
|
|||||||
"komorebi",
|
"komorebi",
|
||||||
"komorebi-client",
|
"komorebi-client",
|
||||||
"komorebi-gui",
|
"komorebi-gui",
|
||||||
"komorebi-layouts",
|
|
||||||
"komorebic",
|
"komorebic",
|
||||||
"komorebic-no-console",
|
"komorebic-no-console",
|
||||||
"komorebi-bar",
|
"komorebi-bar",
|
||||||
@@ -36,7 +35,7 @@ tracing-appender = "0.2"
|
|||||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
parking_lot = "0.12"
|
parking_lot = "0.12"
|
||||||
paste = "1"
|
paste = "1"
|
||||||
sysinfo = "0.38"
|
sysinfo = "0.37"
|
||||||
uds_windows = "1"
|
uds_windows = "1"
|
||||||
win32-display-data = { git = "https://github.com/LGUG2Z/win32-display-data", rev = "8c42d8db257d30fe95bc98c2e5cd8f75da861021" }
|
win32-display-data = { git = "https://github.com/LGUG2Z/win32-display-data", rev = "8c42d8db257d30fe95bc98c2e5cd8f75da861021" }
|
||||||
windows-numerics = { version = "0.3" }
|
windows-numerics = { version = "0.3" }
|
||||||
|
|||||||
@@ -57,7 +57,17 @@ If you need help doing this you can ask on Discord.
|
|||||||
|
|
||||||
## Note: komorebi for Mac
|
## Note: komorebi for Mac
|
||||||
|
|
||||||
komorebi for Mac lives [here](https://github.com/LGUG2Z/komorebi-for-mac) :)
|
If you made your way to this repo looking for [komorebi for
|
||||||
|
Mac](https://github.com/KomoCorp/komorebi-for-mac), the project is currently
|
||||||
|
being developed in private with [early access available to GitHub
|
||||||
|
Sponsors](https://github.com/sponsors/LGUG2Z).
|
||||||
|
|
||||||
|
If you want to see how far along development is before signing up for early
|
||||||
|
access (spoiler: it's very far along!) there is an overview video you can watch
|
||||||
|
[here](https://www.youtube.com/watch?v=u3eJcsa_MJk).
|
||||||
|
|
||||||
|
Sponsors with early access can install komorebi for Mac either by compiling
|
||||||
|
from source, by using Homebrew, or by using the project's Nix Flake.
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
@@ -424,7 +434,7 @@ every `WindowManagerEvent` and `SocketMessage` handled by `komorebi` in a Rust c
|
|||||||
Below is a simple example of how to use `komorebi-client` in a basic Rust application.
|
Below is a simple example of how to use `komorebi-client` in a basic Rust application.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
// komorebi-client = { git = "https://github.com/LGUG2Z/komorebi" }
|
// komorebi-client = { git = "https://github.com/LGUG2Z/komorebi", tag = "v0.1.39"}
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use komorebi_client::Notification;
|
use komorebi_client::Notification;
|
||||||
|
|||||||
@@ -50,11 +50,6 @@ crate = "komorebi-client"
|
|||||||
expression = "LicenseRef-Komorebi-2.0"
|
expression = "LicenseRef-Komorebi-2.0"
|
||||||
license-files = []
|
license-files = []
|
||||||
|
|
||||||
[[licenses.clarify]]
|
|
||||||
crate = "komorebi-layouts"
|
|
||||||
expression = "LicenseRef-Komorebi-2.0"
|
|
||||||
license-files = []
|
|
||||||
|
|
||||||
[[licenses.clarify]]
|
[[licenses.clarify]]
|
||||||
crate = "komorebic"
|
crate = "komorebic"
|
||||||
expression = "LicenseRef-Komorebi-2.0"
|
expression = "LicenseRef-Komorebi-2.0"
|
||||||
|
|||||||
+118
-120
@@ -27,7 +27,7 @@
|
|||||||
"anstyle-parse 0.2.7 registry+https://github.com/rust-lang/crates.io-index",
|
"anstyle-parse 0.2.7 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"anstyle-query 1.1.5 registry+https://github.com/rust-lang/crates.io-index",
|
"anstyle-query 1.1.5 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"anstyle-wincon 3.0.11 registry+https://github.com/rust-lang/crates.io-index",
|
"anstyle-wincon 3.0.11 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"anyhow 1.0.101 registry+https://github.com/rust-lang/crates.io-index",
|
"anyhow 1.0.100 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"approx 0.3.2 registry+https://github.com/rust-lang/crates.io-index",
|
"approx 0.3.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"arboard 3.6.1 registry+https://github.com/rust-lang/crates.io-index",
|
"arboard 3.6.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"arrayvec 0.7.6 registry+https://github.com/rust-lang/crates.io-index",
|
"arrayvec 0.7.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -41,20 +41,20 @@
|
|||||||
"beef 0.5.2 registry+https://github.com/rust-lang/crates.io-index",
|
"beef 0.5.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"bit_field 0.10.3 registry+https://github.com/rust-lang/crates.io-index",
|
"bit_field 0.10.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"bitflags 1.3.2 registry+https://github.com/rust-lang/crates.io-index",
|
"bitflags 1.3.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"bitflags 2.11.0 registry+https://github.com/rust-lang/crates.io-index",
|
"bitflags 2.10.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"bitstream-io 4.9.0 registry+https://github.com/rust-lang/crates.io-index",
|
"bitstream-io 4.9.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"block-buffer 0.10.4 registry+https://github.com/rust-lang/crates.io-index",
|
"block-buffer 0.10.4 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"bytemuck 1.25.0 registry+https://github.com/rust-lang/crates.io-index",
|
"bytemuck 1.24.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"bytemuck_derive 1.10.2 registry+https://github.com/rust-lang/crates.io-index",
|
"bytemuck_derive 1.10.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"cc 1.2.56 registry+https://github.com/rust-lang/crates.io-index",
|
"cc 1.2.51 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"cfg-if 0.1.10 registry+https://github.com/rust-lang/crates.io-index",
|
"cfg-if 0.1.10 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"cfg-if 1.0.4 registry+https://github.com/rust-lang/crates.io-index",
|
"cfg-if 1.0.4 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"chrono 0.4.43 registry+https://github.com/rust-lang/crates.io-index",
|
"chrono 0.4.42 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"chrono-tz 0.10.4 registry+https://github.com/rust-lang/crates.io-index",
|
"chrono-tz 0.10.4 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"clap 4.5.58 registry+https://github.com/rust-lang/crates.io-index",
|
"clap 4.5.54 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"clap_builder 4.5.58 registry+https://github.com/rust-lang/crates.io-index",
|
"clap_builder 4.5.54 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"clap_derive 4.5.55 registry+https://github.com/rust-lang/crates.io-index",
|
"clap_derive 4.5.49 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"clap_lex 1.0.0 registry+https://github.com/rust-lang/crates.io-index",
|
"clap_lex 0.7.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"color-eyre 0.6.5 registry+https://github.com/rust-lang/crates.io-index",
|
"color-eyre 0.6.5 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"color-spantrace 0.3.0 registry+https://github.com/rust-lang/crates.io-index",
|
"color-spantrace 0.3.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"colorchoice 1.0.4 registry+https://github.com/rust-lang/crates.io-index",
|
"colorchoice 1.0.4 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
"cursor-icon 1.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
"cursor-icon 1.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"curve25519-dalek-derive 0.1.1 registry+https://github.com/rust-lang/crates.io-index",
|
"curve25519-dalek-derive 0.1.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"deflate 0.8.6 registry+https://github.com/rust-lang/crates.io-index",
|
"deflate 0.8.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"deranged 0.5.6 registry+https://github.com/rust-lang/crates.io-index",
|
"deranged 0.5.5 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"digest 0.10.7 registry+https://github.com/rust-lang/crates.io-index",
|
"digest 0.10.7 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"dirs 3.0.2 registry+https://github.com/rust-lang/crates.io-index",
|
"dirs 3.0.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"dirs 4.0.0 registry+https://github.com/rust-lang/crates.io-index",
|
"dirs 4.0.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -102,9 +102,9 @@
|
|||||||
"eyre 0.6.12 registry+https://github.com/rust-lang/crates.io-index",
|
"eyre 0.6.12 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"fastrand 2.3.0 registry+https://github.com/rust-lang/crates.io-index",
|
"fastrand 2.3.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"fdeflate 0.3.7 registry+https://github.com/rust-lang/crates.io-index",
|
"fdeflate 0.3.7 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"filetime 0.2.27 registry+https://github.com/rust-lang/crates.io-index",
|
"filetime 0.2.26 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"find-msvc-tools 0.1.9 registry+https://github.com/rust-lang/crates.io-index",
|
"find-msvc-tools 0.1.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"flate2 1.1.9 registry+https://github.com/rust-lang/crates.io-index",
|
"flate2 1.1.5 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"fnv 1.0.7 registry+https://github.com/rust-lang/crates.io-index",
|
"fnv 1.0.7 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"form_urlencoded 1.2.2 registry+https://github.com/rust-lang/crates.io-index",
|
"form_urlencoded 1.2.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"futures 0.3.31 registry+https://github.com/rust-lang/crates.io-index",
|
"futures 0.3.31 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -117,12 +117,11 @@
|
|||||||
"futures-task 0.3.31 registry+https://github.com/rust-lang/crates.io-index",
|
"futures-task 0.3.31 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"futures-util 0.3.31 registry+https://github.com/rust-lang/crates.io-index",
|
"futures-util 0.3.31 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"getrandom 0.1.16 registry+https://github.com/rust-lang/crates.io-index",
|
"getrandom 0.1.16 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"getrandom 0.2.17 registry+https://github.com/rust-lang/crates.io-index",
|
"getrandom 0.2.16 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"getrandom 0.3.4 registry+https://github.com/rust-lang/crates.io-index",
|
"getrandom 0.3.4 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"getrandom 0.4.1 registry+https://github.com/rust-lang/crates.io-index",
|
|
||||||
"gif 0.11.4 registry+https://github.com/rust-lang/crates.io-index",
|
"gif 0.11.4 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"gif 0.14.1 registry+https://github.com/rust-lang/crates.io-index",
|
"gif 0.14.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"git2 0.20.4 registry+https://github.com/rust-lang/crates.io-index",
|
"git2 0.20.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"gl_generator 0.14.0 registry+https://github.com/rust-lang/crates.io-index",
|
"gl_generator 0.14.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"glob 0.3.3 registry+https://github.com/rust-lang/crates.io-index",
|
"glob 0.3.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"glow 0.16.0 registry+https://github.com/rust-lang/crates.io-index",
|
"glow 0.16.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -141,7 +140,7 @@
|
|||||||
"http 1.4.0 registry+https://github.com/rust-lang/crates.io-index",
|
"http 1.4.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"httparse 1.10.1 registry+https://github.com/rust-lang/crates.io-index",
|
"httparse 1.10.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"hyper-tls 0.6.0 registry+https://github.com/rust-lang/crates.io-index",
|
"hyper-tls 0.6.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"iana-time-zone 0.1.65 registry+https://github.com/rust-lang/crates.io-index",
|
"iana-time-zone 0.1.64 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"ident_case 1.0.1 registry+https://github.com/rust-lang/crates.io-index",
|
"ident_case 1.0.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"idna 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
"idna 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"idna_adapter 1.2.1 registry+https://github.com/rust-lang/crates.io-index",
|
"idna_adapter 1.2.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -161,7 +160,7 @@
|
|||||||
"jpeg-decoder 0.1.22 registry+https://github.com/rust-lang/crates.io-index",
|
"jpeg-decoder 0.1.22 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"khronos_api 3.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
"khronos_api 3.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"lazy_static 1.5.0 registry+https://github.com/rust-lang/crates.io-index",
|
"lazy_static 1.5.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"libc 0.2.182 registry+https://github.com/rust-lang/crates.io-index",
|
"libc 0.2.180 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"libgit2-sys 0.18.3+1.9.2 registry+https://github.com/rust-lang/crates.io-index",
|
"libgit2-sys 0.18.3+1.9.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"libz-sys 1.1.23 registry+https://github.com/rust-lang/crates.io-index",
|
"libz-sys 1.1.23 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"linked-hash-map 0.5.6 registry+https://github.com/rust-lang/crates.io-index",
|
"linked-hash-map 0.5.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -179,21 +178,21 @@
|
|||||||
"miniz_oxide 0.8.9 registry+https://github.com/rust-lang/crates.io-index",
|
"miniz_oxide 0.8.9 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"miow 0.6.1 registry+https://github.com/rust-lang/crates.io-index",
|
"miow 0.6.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"moxcms 0.7.11 registry+https://github.com/rust-lang/crates.io-index",
|
"moxcms 0.7.11 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"native-tls 0.2.16 registry+https://github.com/rust-lang/crates.io-index",
|
"native-tls 0.2.14 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"net2 0.2.39 registry+https://github.com/rust-lang/crates.io-index",
|
"net2 0.2.39 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"nohash-hasher 0.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
"nohash-hasher 0.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"ntapi 0.4.3 registry+https://github.com/rust-lang/crates.io-index",
|
"ntapi 0.4.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"num 0.4.3 registry+https://github.com/rust-lang/crates.io-index",
|
"num 0.4.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"num-bigint 0.4.6 registry+https://github.com/rust-lang/crates.io-index",
|
"num-bigint 0.4.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"num-complex 0.4.6 registry+https://github.com/rust-lang/crates.io-index",
|
"num-complex 0.4.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"num-conv 0.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
"num-conv 0.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"num-derive 0.4.2 registry+https://github.com/rust-lang/crates.io-index",
|
"num-derive 0.4.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"num-integer 0.1.46 registry+https://github.com/rust-lang/crates.io-index",
|
"num-integer 0.1.46 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"num-iter 0.1.45 registry+https://github.com/rust-lang/crates.io-index",
|
"num-iter 0.1.45 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"num-rational 0.3.2 registry+https://github.com/rust-lang/crates.io-index",
|
"num-rational 0.3.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"num-rational 0.4.2 registry+https://github.com/rust-lang/crates.io-index",
|
"num-rational 0.4.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"num-traits 0.2.19 registry+https://github.com/rust-lang/crates.io-index",
|
"num-traits 0.2.19 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"object 0.37.3 registry+https://github.com/rust-lang/crates.io-index",
|
"object 0.32.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"once_cell 1.21.3 registry+https://github.com/rust-lang/crates.io-index",
|
"once_cell 1.21.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"once_cell_polyfill 1.70.2 registry+https://github.com/rust-lang/crates.io-index",
|
"once_cell_polyfill 1.70.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"owned_ttf_parser 0.25.1 registry+https://github.com/rust-lang/crates.io-index",
|
"owned_ttf_parser 0.25.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -208,17 +207,17 @@
|
|||||||
"pin-utils 0.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
"pin-utils 0.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"pkg-config 0.3.32 registry+https://github.com/rust-lang/crates.io-index",
|
"pkg-config 0.3.32 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"png 0.16.8 registry+https://github.com/rust-lang/crates.io-index",
|
"png 0.16.8 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"png 0.18.1 registry+https://github.com/rust-lang/crates.io-index",
|
"png 0.18.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"powerfmt 0.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
"powerfmt 0.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"ppv-lite86 0.2.21 registry+https://github.com/rust-lang/crates.io-index",
|
"ppv-lite86 0.2.21 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"proc-macro2 1.0.106 registry+https://github.com/rust-lang/crates.io-index",
|
"proc-macro2 1.0.105 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"profiling 1.0.17 registry+https://github.com/rust-lang/crates.io-index",
|
"profiling 1.0.17 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"profiling-procmacros 1.0.17 registry+https://github.com/rust-lang/crates.io-index",
|
"profiling-procmacros 1.0.17 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"psm 0.1.30 registry+https://github.com/rust-lang/crates.io-index",
|
"psm 0.1.28 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"pxfm 0.1.27 registry+https://github.com/rust-lang/crates.io-index",
|
"pxfm 0.1.27 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"qoi 0.4.1 registry+https://github.com/rust-lang/crates.io-index",
|
"qoi 0.4.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"quick-error 2.0.1 registry+https://github.com/rust-lang/crates.io-index",
|
"quick-error 2.0.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"quote 1.0.44 registry+https://github.com/rust-lang/crates.io-index",
|
"quote 1.0.43 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rand 0.7.3 registry+https://github.com/rust-lang/crates.io-index",
|
"rand 0.7.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rand 0.8.5 registry+https://github.com/rust-lang/crates.io-index",
|
"rand 0.8.5 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rand 0.9.2 registry+https://github.com/rust-lang/crates.io-index",
|
"rand 0.9.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -227,22 +226,22 @@
|
|||||||
"rand_chacha 0.9.0 registry+https://github.com/rust-lang/crates.io-index",
|
"rand_chacha 0.9.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rand_core 0.5.1 registry+https://github.com/rust-lang/crates.io-index",
|
"rand_core 0.5.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rand_core 0.6.4 registry+https://github.com/rust-lang/crates.io-index",
|
"rand_core 0.6.4 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rand_core 0.9.5 registry+https://github.com/rust-lang/crates.io-index",
|
"rand_core 0.9.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rand_pcg 0.2.1 registry+https://github.com/rust-lang/crates.io-index",
|
"rand_pcg 0.2.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"raw-window-handle 0.6.2 registry+https://github.com/rust-lang/crates.io-index",
|
"raw-window-handle 0.6.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rayon 1.11.0 registry+https://github.com/rust-lang/crates.io-index",
|
"rayon 1.11.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rayon-core 1.13.0 registry+https://github.com/rust-lang/crates.io-index",
|
"rayon-core 1.13.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"ref-cast 1.0.25 registry+https://github.com/rust-lang/crates.io-index",
|
"ref-cast 1.0.25 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"ref-cast-impl 1.0.25 registry+https://github.com/rust-lang/crates.io-index",
|
"ref-cast-impl 1.0.25 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"regex 1.12.3 registry+https://github.com/rust-lang/crates.io-index",
|
"regex 1.12.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"regex-automata 0.4.14 registry+https://github.com/rust-lang/crates.io-index",
|
"regex-automata 0.4.13 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"regex-syntax 0.8.9 registry+https://github.com/rust-lang/crates.io-index",
|
"regex-syntax 0.8.8 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"reqwest 0.12.28 registry+https://github.com/rust-lang/crates.io-index",
|
"reqwest 0.12.28 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"roxmltree 0.20.0 registry+https://github.com/rust-lang/crates.io-index",
|
"roxmltree 0.20.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rustc-demangle 0.1.27 registry+https://github.com/rust-lang/crates.io-index",
|
"rustc-demangle 0.1.26 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rustc_version 0.4.1 registry+https://github.com/rust-lang/crates.io-index",
|
"rustc_version 0.4.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rustls-pki-types 1.14.0 registry+https://github.com/rust-lang/crates.io-index",
|
"rustls-pki-types 1.13.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"ryu 1.0.23 registry+https://github.com/rust-lang/crates.io-index",
|
"ryu 1.0.22 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"scopeguard 1.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
"scopeguard 1.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"semver 1.0.27 registry+https://github.com/rust-lang/crates.io-index",
|
"semver 1.0.27 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"serde 1.0.228 registry+https://github.com/rust-lang/crates.io-index",
|
"serde 1.0.228 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -258,40 +257,40 @@
|
|||||||
"serde_yaml 0.8.26 registry+https://github.com/rust-lang/crates.io-index",
|
"serde_yaml 0.8.26 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"serde_yaml 0.9.34+deprecated registry+https://github.com/rust-lang/crates.io-index",
|
"serde_yaml 0.9.34+deprecated registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"sha2 0.10.9 registry+https://github.com/rust-lang/crates.io-index",
|
"sha2 0.10.9 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"shadow-rs 1.7.0 registry+https://github.com/rust-lang/crates.io-index",
|
"shadow-rs 1.5.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"shell-words 1.1.1 registry+https://github.com/rust-lang/crates.io-index",
|
"shell-words 1.1.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"shellexpand 2.1.2 registry+https://github.com/rust-lang/crates.io-index",
|
"shellexpand 2.1.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"shlex 1.3.0 registry+https://github.com/rust-lang/crates.io-index",
|
"shlex 1.3.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"signature 2.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
"signature 2.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"siphasher 0.3.11 registry+https://github.com/rust-lang/crates.io-index",
|
"siphasher 0.3.11 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"siphasher 1.0.2 registry+https://github.com/rust-lang/crates.io-index",
|
"siphasher 1.0.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"smallvec 1.15.1 registry+https://github.com/rust-lang/crates.io-index",
|
"smallvec 1.15.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"smol_str 0.2.2 registry+https://github.com/rust-lang/crates.io-index",
|
"smol_str 0.2.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"socket2 0.6.2 registry+https://github.com/rust-lang/crates.io-index",
|
"socket2 0.6.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"stable_deref_trait 1.2.1 registry+https://github.com/rust-lang/crates.io-index",
|
"stable_deref_trait 1.2.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"stacker 0.1.23 registry+https://github.com/rust-lang/crates.io-index",
|
"stacker 0.1.22 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"static_assertions 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
"static_assertions 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"supports-color 3.0.2 registry+https://github.com/rust-lang/crates.io-index",
|
"supports-color 3.0.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"supports-hyperlinks 3.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
"supports-hyperlinks 3.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"supports-unicode 3.0.0 registry+https://github.com/rust-lang/crates.io-index",
|
"supports-unicode 3.0.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"syn 1.0.109 registry+https://github.com/rust-lang/crates.io-index",
|
"syn 1.0.109 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"syn 2.0.115 registry+https://github.com/rust-lang/crates.io-index",
|
"syn 2.0.114 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"sync_wrapper 1.0.2 registry+https://github.com/rust-lang/crates.io-index",
|
"sync_wrapper 1.0.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"tempfile 3.25.0 registry+https://github.com/rust-lang/crates.io-index",
|
"tempfile 3.24.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"terminal_size 0.4.3 registry+https://github.com/rust-lang/crates.io-index",
|
"terminal_size 0.4.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"thiserror 2.0.18 registry+https://github.com/rust-lang/crates.io-index",
|
"thiserror 2.0.17 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"thiserror-impl 2.0.18 registry+https://github.com/rust-lang/crates.io-index",
|
"thiserror-impl 2.0.17 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"thread_local 1.1.9 registry+https://github.com/rust-lang/crates.io-index",
|
"thread_local 1.1.9 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"time 0.3.47 registry+https://github.com/rust-lang/crates.io-index",
|
"time 0.3.44 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"time-core 0.1.8 registry+https://github.com/rust-lang/crates.io-index",
|
"time-core 0.1.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"toml 0.5.11 registry+https://github.com/rust-lang/crates.io-index",
|
"toml 0.5.11 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"ttf-parser 0.25.1 registry+https://github.com/rust-lang/crates.io-index",
|
"ttf-parser 0.25.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"typenum 1.19.0 registry+https://github.com/rust-lang/crates.io-index",
|
"typenum 1.19.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"tz-rs 0.7.3 registry+https://github.com/rust-lang/crates.io-index",
|
"tz-rs 0.7.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"tzdb 0.7.3 registry+https://github.com/rust-lang/crates.io-index",
|
"tzdb 0.7.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"tzdb_data 0.2.3 registry+https://github.com/rust-lang/crates.io-index",
|
"tzdb_data 0.2.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"unicase 2.9.0 registry+https://github.com/rust-lang/crates.io-index",
|
"unicase 2.9.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"unicode-ident 1.0.23 registry+https://github.com/rust-lang/crates.io-index",
|
"unicode-ident 1.0.22 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"unicode-linebreak 0.1.5 registry+https://github.com/rust-lang/crates.io-index",
|
"unicode-linebreak 0.1.5 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"unicode-segmentation 1.12.0 registry+https://github.com/rust-lang/crates.io-index",
|
"unicode-segmentation 1.12.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"unicode-width 0.1.14 registry+https://github.com/rust-lang/crates.io-index",
|
"unicode-width 0.1.14 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -304,9 +303,9 @@
|
|||||||
"vcpkg 0.2.15 registry+https://github.com/rust-lang/crates.io-index",
|
"vcpkg 0.2.15 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"version_check 0.9.5 registry+https://github.com/rust-lang/crates.io-index",
|
"version_check 0.9.5 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"web-time 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
"web-time 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"webbrowser 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
"webbrowser 1.0.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"weezl 0.1.12 registry+https://github.com/rust-lang/crates.io-index",
|
"weezl 0.1.12 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"win-msgbox 0.2.2 registry+https://github.com/rust-lang/crates.io-index",
|
"win-msgbox 0.2.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"winapi 0.3.9 registry+https://github.com/rust-lang/crates.io-index",
|
"winapi 0.3.9 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"windows 0.57.0 registry+https://github.com/rust-lang/crates.io-index",
|
"windows 0.57.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"windows 0.58.0 registry+https://github.com/rust-lang/crates.io-index",
|
"windows 0.58.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -367,20 +366,20 @@
|
|||||||
"winit 0.30.12 registry+https://github.com/rust-lang/crates.io-index",
|
"winit 0.30.12 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"wmi 0.15.2 registry+https://github.com/rust-lang/crates.io-index",
|
"wmi 0.15.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"yaml-rust 0.4.5 registry+https://github.com/rust-lang/crates.io-index",
|
"yaml-rust 0.4.5 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zerocopy 0.8.39 registry+https://github.com/rust-lang/crates.io-index",
|
"zerocopy 0.8.33 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zerocopy-derive 0.8.39 registry+https://github.com/rust-lang/crates.io-index",
|
"zerocopy-derive 0.8.33 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zeroize 1.8.2 registry+https://github.com/rust-lang/crates.io-index",
|
"zeroize 1.8.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zune-core 0.4.12 registry+https://github.com/rust-lang/crates.io-index",
|
"zune-core 0.4.12 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zune-core 0.5.1 registry+https://github.com/rust-lang/crates.io-index",
|
"zune-core 0.5.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zune-inflate 0.2.54 registry+https://github.com/rust-lang/crates.io-index",
|
"zune-inflate 0.2.54 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zune-jpeg 0.4.21 registry+https://github.com/rust-lang/crates.io-index",
|
"zune-jpeg 0.4.21 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zune-jpeg 0.5.12 registry+https://github.com/rust-lang/crates.io-index"
|
"zune-jpeg 0.5.8 registry+https://github.com/rust-lang/crates.io-index"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"Apache-2.0 WITH LLVM-exception",
|
"Apache-2.0 WITH LLVM-exception",
|
||||||
[
|
[
|
||||||
"ar_archive_writer 0.5.1 registry+https://github.com/rust-lang/crates.io-index"
|
"ar_archive_writer 0.2.0 registry+https://github.com/rust-lang/crates.io-index"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -396,8 +395,8 @@
|
|||||||
"av1-grain 0.2.5 registry+https://github.com/rust-lang/crates.io-index",
|
"av1-grain 0.2.5 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rav1e 0.8.1 registry+https://github.com/rust-lang/crates.io-index",
|
"rav1e 0.8.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"v_frame 0.3.9 registry+https://github.com/rust-lang/crates.io-index",
|
"v_frame 0.3.9 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zerocopy 0.8.39 registry+https://github.com/rust-lang/crates.io-index",
|
"zerocopy 0.8.33 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zerocopy-derive 0.8.39 registry+https://github.com/rust-lang/crates.io-index"
|
"zerocopy-derive 0.8.33 registry+https://github.com/rust-lang/crates.io-index"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -405,7 +404,7 @@
|
|||||||
[
|
[
|
||||||
"alloc-no-stdlib 2.0.4 registry+https://github.com/rust-lang/crates.io-index",
|
"alloc-no-stdlib 2.0.4 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"alloc-stdlib 0.2.2 registry+https://github.com/rust-lang/crates.io-index",
|
"alloc-stdlib 0.2.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"avif-serialize 0.8.8 registry+https://github.com/rust-lang/crates.io-index",
|
"avif-serialize 0.8.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"brotli 8.0.2 registry+https://github.com/rust-lang/crates.io-index",
|
"brotli 8.0.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"brotli-decompressor 5.0.0 registry+https://github.com/rust-lang/crates.io-index",
|
"brotli-decompressor 5.0.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"curve25519-dalek 4.1.3 registry+https://github.com/rust-lang/crates.io-index",
|
"curve25519-dalek 4.1.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -424,7 +423,7 @@
|
|||||||
[
|
[
|
||||||
"clipboard-win 5.4.1 registry+https://github.com/rust-lang/crates.io-index",
|
"clipboard-win 5.4.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"error-code 3.3.2 registry+https://github.com/rust-lang/crates.io-index",
|
"error-code 3.3.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"ryu 1.0.23 registry+https://github.com/rust-lang/crates.io-index"
|
"ryu 1.0.22 registry+https://github.com/rust-lang/crates.io-index"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -463,7 +462,7 @@
|
|||||||
"anstyle-parse 0.2.7 registry+https://github.com/rust-lang/crates.io-index",
|
"anstyle-parse 0.2.7 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"anstyle-query 1.1.5 registry+https://github.com/rust-lang/crates.io-index",
|
"anstyle-query 1.1.5 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"anstyle-wincon 3.0.11 registry+https://github.com/rust-lang/crates.io-index",
|
"anstyle-wincon 3.0.11 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"anyhow 1.0.101 registry+https://github.com/rust-lang/crates.io-index",
|
"anyhow 1.0.100 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"arboard 3.6.1 registry+https://github.com/rust-lang/crates.io-index",
|
"arboard 3.6.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"arg_enum_proc_macro 0.3.4 registry+https://github.com/rust-lang/crates.io-index",
|
"arg_enum_proc_macro 0.3.4 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"arrayvec 0.7.6 registry+https://github.com/rust-lang/crates.io-index",
|
"arrayvec 0.7.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -478,31 +477,31 @@
|
|||||||
"beef 0.5.2 registry+https://github.com/rust-lang/crates.io-index",
|
"beef 0.5.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"bit_field 0.10.3 registry+https://github.com/rust-lang/crates.io-index",
|
"bit_field 0.10.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"bitflags 1.3.2 registry+https://github.com/rust-lang/crates.io-index",
|
"bitflags 1.3.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"bitflags 2.11.0 registry+https://github.com/rust-lang/crates.io-index",
|
"bitflags 2.10.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"bitstream-io 4.9.0 registry+https://github.com/rust-lang/crates.io-index",
|
"bitstream-io 4.9.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"block-buffer 0.10.4 registry+https://github.com/rust-lang/crates.io-index",
|
"block-buffer 0.10.4 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"brotli 8.0.2 registry+https://github.com/rust-lang/crates.io-index",
|
"brotli 8.0.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"brotli-decompressor 5.0.0 registry+https://github.com/rust-lang/crates.io-index",
|
"brotli-decompressor 5.0.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"built 0.8.0 registry+https://github.com/rust-lang/crates.io-index",
|
"built 0.8.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"bytemuck 1.25.0 registry+https://github.com/rust-lang/crates.io-index",
|
"bytemuck 1.24.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"bytemuck_derive 1.10.2 registry+https://github.com/rust-lang/crates.io-index",
|
"bytemuck_derive 1.10.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"byteorder 1.5.0 registry+https://github.com/rust-lang/crates.io-index",
|
"byteorder 1.5.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"byteorder-lite 0.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
"byteorder-lite 0.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"bytes 1.11.1 registry+https://github.com/rust-lang/crates.io-index",
|
"bytes 1.11.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"calm_io 0.1.1 registry+https://github.com/rust-lang/crates.io-index",
|
"calm_io 0.1.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"calmio_filters 0.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
"calmio_filters 0.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"catppuccin-egui 5.6.0 git+https://github.com/LGUG2Z/catppuccin-egui?rev=b2f95cbf441d1dd99f3c955ef10dcb84ce23c20a",
|
"catppuccin-egui 5.6.0 git+https://github.com/LGUG2Z/catppuccin-egui?rev=b2f95cbf441d1dd99f3c955ef10dcb84ce23c20a",
|
||||||
"cc 1.2.56 registry+https://github.com/rust-lang/crates.io-index",
|
"cc 1.2.51 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"cfg-if 0.1.10 registry+https://github.com/rust-lang/crates.io-index",
|
"cfg-if 0.1.10 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"cfg-if 1.0.4 registry+https://github.com/rust-lang/crates.io-index",
|
"cfg-if 1.0.4 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"cfg_aliases 0.2.1 registry+https://github.com/rust-lang/crates.io-index",
|
"cfg_aliases 0.2.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"chrono 0.4.43 registry+https://github.com/rust-lang/crates.io-index",
|
"chrono 0.4.42 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"chrono-tz 0.10.4 registry+https://github.com/rust-lang/crates.io-index",
|
"chrono-tz 0.10.4 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"chumsky 0.9.3 registry+https://github.com/rust-lang/crates.io-index",
|
"chumsky 0.9.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"clap 4.5.58 registry+https://github.com/rust-lang/crates.io-index",
|
"clap 4.5.54 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"clap_builder 4.5.58 registry+https://github.com/rust-lang/crates.io-index",
|
"clap_builder 4.5.54 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"clap_derive 4.5.55 registry+https://github.com/rust-lang/crates.io-index",
|
"clap_derive 4.5.49 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"clap_lex 1.0.0 registry+https://github.com/rust-lang/crates.io-index",
|
"clap_lex 0.7.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"color-eyre 0.6.5 registry+https://github.com/rust-lang/crates.io-index",
|
"color-eyre 0.6.5 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"color-spantrace 0.3.0 registry+https://github.com/rust-lang/crates.io-index",
|
"color-spantrace 0.3.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"color-thief 0.2.2 registry+https://github.com/rust-lang/crates.io-index",
|
"color-thief 0.2.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -523,7 +522,7 @@
|
|||||||
"darling_core 0.21.3 registry+https://github.com/rust-lang/crates.io-index",
|
"darling_core 0.21.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"darling_macro 0.21.3 registry+https://github.com/rust-lang/crates.io-index",
|
"darling_macro 0.21.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"deflate 0.8.6 registry+https://github.com/rust-lang/crates.io-index",
|
"deflate 0.8.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"deranged 0.5.6 registry+https://github.com/rust-lang/crates.io-index",
|
"deranged 0.5.5 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"digest 0.10.7 registry+https://github.com/rust-lang/crates.io-index",
|
"digest 0.10.7 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"dirs 3.0.2 registry+https://github.com/rust-lang/crates.io-index",
|
"dirs 3.0.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"dirs 4.0.0 registry+https://github.com/rust-lang/crates.io-index",
|
"dirs 4.0.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -558,9 +557,9 @@
|
|||||||
"fax 0.2.6 registry+https://github.com/rust-lang/crates.io-index",
|
"fax 0.2.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"fax_derive 0.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
"fax_derive 0.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"fdeflate 0.3.7 registry+https://github.com/rust-lang/crates.io-index",
|
"fdeflate 0.3.7 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"filetime 0.2.27 registry+https://github.com/rust-lang/crates.io-index",
|
"filetime 0.2.26 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"find-msvc-tools 0.1.9 registry+https://github.com/rust-lang/crates.io-index",
|
"find-msvc-tools 0.1.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"flate2 1.1.9 registry+https://github.com/rust-lang/crates.io-index",
|
"flate2 1.1.5 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"flavours 0.7.2 git+https://github.com/LGUG2Z/flavours",
|
"flavours 0.7.2 git+https://github.com/LGUG2Z/flavours",
|
||||||
"fnv 1.0.7 registry+https://github.com/rust-lang/crates.io-index",
|
"fnv 1.0.7 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"font-loader 0.11.0 registry+https://github.com/rust-lang/crates.io-index",
|
"font-loader 0.11.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -577,12 +576,11 @@
|
|||||||
"futures-util 0.3.31 registry+https://github.com/rust-lang/crates.io-index",
|
"futures-util 0.3.31 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"generic-array 0.14.7 registry+https://github.com/rust-lang/crates.io-index",
|
"generic-array 0.14.7 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"getrandom 0.1.16 registry+https://github.com/rust-lang/crates.io-index",
|
"getrandom 0.1.16 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"getrandom 0.2.17 registry+https://github.com/rust-lang/crates.io-index",
|
"getrandom 0.2.16 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"getrandom 0.3.4 registry+https://github.com/rust-lang/crates.io-index",
|
"getrandom 0.3.4 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"getrandom 0.4.1 registry+https://github.com/rust-lang/crates.io-index",
|
|
||||||
"gif 0.11.4 registry+https://github.com/rust-lang/crates.io-index",
|
"gif 0.11.4 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"gif 0.14.1 registry+https://github.com/rust-lang/crates.io-index",
|
"gif 0.14.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"git2 0.20.4 registry+https://github.com/rust-lang/crates.io-index",
|
"git2 0.20.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"glob 0.3.3 registry+https://github.com/rust-lang/crates.io-index",
|
"glob 0.3.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"glow 0.16.0 registry+https://github.com/rust-lang/crates.io-index",
|
"glow 0.16.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"glutin-winit 0.5.0 registry+https://github.com/rust-lang/crates.io-index",
|
"glutin-winit 0.5.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -602,8 +600,8 @@
|
|||||||
"httparse 1.10.1 registry+https://github.com/rust-lang/crates.io-index",
|
"httparse 1.10.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"hyper 1.8.1 registry+https://github.com/rust-lang/crates.io-index",
|
"hyper 1.8.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"hyper-tls 0.6.0 registry+https://github.com/rust-lang/crates.io-index",
|
"hyper-tls 0.6.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"hyper-util 0.1.20 registry+https://github.com/rust-lang/crates.io-index",
|
"hyper-util 0.1.19 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"iana-time-zone 0.1.65 registry+https://github.com/rust-lang/crates.io-index",
|
"iana-time-zone 0.1.64 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"ident_case 1.0.1 registry+https://github.com/rust-lang/crates.io-index",
|
"ident_case 1.0.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"idna 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
"idna 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"idna_adapter 1.2.1 registry+https://github.com/rust-lang/crates.io-index",
|
"idna_adapter 1.2.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -622,7 +620,7 @@
|
|||||||
"jobserver 0.1.34 registry+https://github.com/rust-lang/crates.io-index",
|
"jobserver 0.1.34 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"jpeg-decoder 0.1.22 registry+https://github.com/rust-lang/crates.io-index",
|
"jpeg-decoder 0.1.22 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"lazy_static 1.5.0 registry+https://github.com/rust-lang/crates.io-index",
|
"lazy_static 1.5.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"libc 0.2.182 registry+https://github.com/rust-lang/crates.io-index",
|
"libc 0.2.180 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"libgit2-sys 0.18.3+1.9.2 registry+https://github.com/rust-lang/crates.io-index",
|
"libgit2-sys 0.18.3+1.9.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"libz-sys 1.1.23 registry+https://github.com/rust-lang/crates.io-index",
|
"libz-sys 1.1.23 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"linked-hash-map 0.5.6 registry+https://github.com/rust-lang/crates.io-index",
|
"linked-hash-map 0.5.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -636,7 +634,7 @@
|
|||||||
"mac-addr 0.3.0 registry+https://github.com/rust-lang/crates.io-index",
|
"mac-addr 0.3.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"matchers 0.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
"matchers 0.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"maybe-rayon 0.1.1 registry+https://github.com/rust-lang/crates.io-index",
|
"maybe-rayon 0.1.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"memchr 2.8.0 registry+https://github.com/rust-lang/crates.io-index",
|
"memchr 2.7.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"memoffset 0.9.1 registry+https://github.com/rust-lang/crates.io-index",
|
"memoffset 0.9.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"mime 0.3.17 registry+https://github.com/rust-lang/crates.io-index",
|
"mime 0.3.17 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"mime_guess2 2.3.1 registry+https://github.com/rust-lang/crates.io-index",
|
"mime_guess2 2.3.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -647,7 +645,7 @@
|
|||||||
"mio 1.1.1 registry+https://github.com/rust-lang/crates.io-index",
|
"mio 1.1.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"miow 0.6.1 registry+https://github.com/rust-lang/crates.io-index",
|
"miow 0.6.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"nanoid 0.4.0 registry+https://github.com/rust-lang/crates.io-index",
|
"nanoid 0.4.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"native-tls 0.2.16 registry+https://github.com/rust-lang/crates.io-index",
|
"native-tls 0.2.14 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"net2 0.2.39 registry+https://github.com/rust-lang/crates.io-index",
|
"net2 0.2.39 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"netdev 0.40.0 registry+https://github.com/rust-lang/crates.io-index",
|
"netdev 0.40.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"new_debug_unreachable 1.0.6 registry+https://github.com/rust-lang/crates.io-index",
|
"new_debug_unreachable 1.0.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -655,19 +653,19 @@
|
|||||||
"nom 7.1.3 registry+https://github.com/rust-lang/crates.io-index",
|
"nom 7.1.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"nom 8.0.0 registry+https://github.com/rust-lang/crates.io-index",
|
"nom 8.0.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"noop_proc_macro 0.3.0 registry+https://github.com/rust-lang/crates.io-index",
|
"noop_proc_macro 0.3.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"ntapi 0.4.3 registry+https://github.com/rust-lang/crates.io-index",
|
"ntapi 0.4.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"nu-ansi-term 0.50.3 registry+https://github.com/rust-lang/crates.io-index",
|
"nu-ansi-term 0.50.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"num 0.4.3 registry+https://github.com/rust-lang/crates.io-index",
|
"num 0.4.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"num-bigint 0.4.6 registry+https://github.com/rust-lang/crates.io-index",
|
"num-bigint 0.4.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"num-complex 0.4.6 registry+https://github.com/rust-lang/crates.io-index",
|
"num-complex 0.4.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"num-conv 0.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
"num-conv 0.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"num-derive 0.4.2 registry+https://github.com/rust-lang/crates.io-index",
|
"num-derive 0.4.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"num-integer 0.1.46 registry+https://github.com/rust-lang/crates.io-index",
|
"num-integer 0.1.46 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"num-iter 0.1.45 registry+https://github.com/rust-lang/crates.io-index",
|
"num-iter 0.1.45 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"num-rational 0.3.2 registry+https://github.com/rust-lang/crates.io-index",
|
"num-rational 0.3.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"num-rational 0.4.2 registry+https://github.com/rust-lang/crates.io-index",
|
"num-rational 0.4.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"num-traits 0.2.19 registry+https://github.com/rust-lang/crates.io-index",
|
"num-traits 0.2.19 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"object 0.37.3 registry+https://github.com/rust-lang/crates.io-index",
|
"object 0.32.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"once_cell 1.21.3 registry+https://github.com/rust-lang/crates.io-index",
|
"once_cell 1.21.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"once_cell_polyfill 1.70.2 registry+https://github.com/rust-lang/crates.io-index",
|
"once_cell_polyfill 1.70.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"open 5.3.3 registry+https://github.com/rust-lang/crates.io-index",
|
"open 5.3.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -692,17 +690,17 @@
|
|||||||
"pin-utils 0.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
"pin-utils 0.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"pkg-config 0.3.32 registry+https://github.com/rust-lang/crates.io-index",
|
"pkg-config 0.3.32 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"png 0.16.8 registry+https://github.com/rust-lang/crates.io-index",
|
"png 0.16.8 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"png 0.18.1 registry+https://github.com/rust-lang/crates.io-index",
|
"png 0.18.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"powerfmt 0.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
"powerfmt 0.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"powershell_script 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
"powershell_script 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"ppv-lite86 0.2.21 registry+https://github.com/rust-lang/crates.io-index",
|
"ppv-lite86 0.2.21 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"proc-macro2 1.0.106 registry+https://github.com/rust-lang/crates.io-index",
|
"proc-macro2 1.0.105 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"profiling 1.0.17 registry+https://github.com/rust-lang/crates.io-index",
|
"profiling 1.0.17 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"profiling-procmacros 1.0.17 registry+https://github.com/rust-lang/crates.io-index",
|
"profiling-procmacros 1.0.17 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"psm 0.1.30 registry+https://github.com/rust-lang/crates.io-index",
|
"psm 0.1.28 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"qoi 0.4.1 registry+https://github.com/rust-lang/crates.io-index",
|
"qoi 0.4.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"quick-error 2.0.1 registry+https://github.com/rust-lang/crates.io-index",
|
"quick-error 2.0.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"quote 1.0.44 registry+https://github.com/rust-lang/crates.io-index",
|
"quote 1.0.43 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rand 0.7.3 registry+https://github.com/rust-lang/crates.io-index",
|
"rand 0.7.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rand 0.8.5 registry+https://github.com/rust-lang/crates.io-index",
|
"rand 0.8.5 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rand 0.9.2 registry+https://github.com/rust-lang/crates.io-index",
|
"rand 0.9.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -711,7 +709,7 @@
|
|||||||
"rand_chacha 0.9.0 registry+https://github.com/rust-lang/crates.io-index",
|
"rand_chacha 0.9.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rand_core 0.5.1 registry+https://github.com/rust-lang/crates.io-index",
|
"rand_core 0.5.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rand_core 0.6.4 registry+https://github.com/rust-lang/crates.io-index",
|
"rand_core 0.6.4 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rand_core 0.9.5 registry+https://github.com/rust-lang/crates.io-index",
|
"rand_core 0.9.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rand_pcg 0.2.1 registry+https://github.com/rust-lang/crates.io-index",
|
"rand_pcg 0.2.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"random_word 0.5.2 registry+https://github.com/rust-lang/crates.io-index",
|
"random_word 0.5.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"raw-window-handle 0.6.2 registry+https://github.com/rust-lang/crates.io-index",
|
"raw-window-handle 0.6.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -719,19 +717,19 @@
|
|||||||
"rayon-core 1.13.0 registry+https://github.com/rust-lang/crates.io-index",
|
"rayon-core 1.13.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"ref-cast 1.0.25 registry+https://github.com/rust-lang/crates.io-index",
|
"ref-cast 1.0.25 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"ref-cast-impl 1.0.25 registry+https://github.com/rust-lang/crates.io-index",
|
"ref-cast-impl 1.0.25 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"regex 1.12.3 registry+https://github.com/rust-lang/crates.io-index",
|
"regex 1.12.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"regex-automata 0.4.14 registry+https://github.com/rust-lang/crates.io-index",
|
"regex-automata 0.4.13 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"regex-syntax 0.8.9 registry+https://github.com/rust-lang/crates.io-index",
|
"regex-syntax 0.8.8 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"reqwest 0.12.28 registry+https://github.com/rust-lang/crates.io-index",
|
"reqwest 0.12.28 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rgb 0.8.52 registry+https://github.com/rust-lang/crates.io-index",
|
"rgb 0.8.52 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"roxmltree 0.20.0 registry+https://github.com/rust-lang/crates.io-index",
|
"roxmltree 0.20.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rustc-demangle 0.1.27 registry+https://github.com/rust-lang/crates.io-index",
|
"rustc-demangle 0.1.26 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rustc_version 0.4.1 registry+https://github.com/rust-lang/crates.io-index",
|
"rustc_version 0.4.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"rustls-pki-types 1.14.0 registry+https://github.com/rust-lang/crates.io-index",
|
"rustls-pki-types 1.13.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"same-file 1.0.6 registry+https://github.com/rust-lang/crates.io-index",
|
"same-file 1.0.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"schannel 0.1.28 registry+https://github.com/rust-lang/crates.io-index",
|
"schannel 0.1.28 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"schemars 1.2.1 registry+https://github.com/rust-lang/crates.io-index",
|
"schemars 1.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"schemars_derive 1.2.1 registry+https://github.com/rust-lang/crates.io-index",
|
"schemars_derive 1.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"scoped_threadpool 0.1.9 registry+https://github.com/rust-lang/crates.io-index",
|
"scoped_threadpool 0.1.9 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"scopeguard 1.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
"scopeguard 1.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"semver 1.0.27 registry+https://github.com/rust-lang/crates.io-index",
|
"semver 1.0.27 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -748,7 +746,7 @@
|
|||||||
"serde_yaml 0.8.26 registry+https://github.com/rust-lang/crates.io-index",
|
"serde_yaml 0.8.26 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"serde_yaml 0.9.34+deprecated registry+https://github.com/rust-lang/crates.io-index",
|
"serde_yaml 0.9.34+deprecated registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"sha2 0.10.9 registry+https://github.com/rust-lang/crates.io-index",
|
"sha2 0.10.9 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"shadow-rs 1.7.0 registry+https://github.com/rust-lang/crates.io-index",
|
"shadow-rs 1.5.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"sharded-slab 0.1.7 registry+https://github.com/rust-lang/crates.io-index",
|
"sharded-slab 0.1.7 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"shell-words 1.1.1 registry+https://github.com/rust-lang/crates.io-index",
|
"shell-words 1.1.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"shellexpand 2.1.2 registry+https://github.com/rust-lang/crates.io-index",
|
"shellexpand 2.1.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -757,37 +755,37 @@
|
|||||||
"simd-adler32 0.3.8 registry+https://github.com/rust-lang/crates.io-index",
|
"simd-adler32 0.3.8 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"simd_helpers 0.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
"simd_helpers 0.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"siphasher 0.3.11 registry+https://github.com/rust-lang/crates.io-index",
|
"siphasher 0.3.11 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"siphasher 1.0.2 registry+https://github.com/rust-lang/crates.io-index",
|
"siphasher 1.0.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"slab 0.4.12 registry+https://github.com/rust-lang/crates.io-index",
|
"slab 0.4.11 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"smallvec 1.15.1 registry+https://github.com/rust-lang/crates.io-index",
|
"smallvec 1.15.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"smol_str 0.2.2 registry+https://github.com/rust-lang/crates.io-index",
|
"smol_str 0.2.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"socket2 0.6.2 registry+https://github.com/rust-lang/crates.io-index",
|
"socket2 0.6.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"stable_deref_trait 1.2.1 registry+https://github.com/rust-lang/crates.io-index",
|
"stable_deref_trait 1.2.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"stacker 0.1.23 registry+https://github.com/rust-lang/crates.io-index",
|
"stacker 0.1.22 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"static_assertions 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
"static_assertions 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"strsim 0.11.1 registry+https://github.com/rust-lang/crates.io-index",
|
"strsim 0.11.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"strum 0.27.2 registry+https://github.com/rust-lang/crates.io-index",
|
"strum 0.27.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"strum_macros 0.27.2 registry+https://github.com/rust-lang/crates.io-index",
|
"strum_macros 0.27.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"syn 1.0.109 registry+https://github.com/rust-lang/crates.io-index",
|
"syn 1.0.109 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"syn 2.0.115 registry+https://github.com/rust-lang/crates.io-index",
|
"syn 2.0.114 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"synstructure 0.13.2 registry+https://github.com/rust-lang/crates.io-index",
|
"synstructure 0.13.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"sysinfo 0.33.1 registry+https://github.com/rust-lang/crates.io-index",
|
"sysinfo 0.33.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"sysinfo 0.38.1 registry+https://github.com/rust-lang/crates.io-index",
|
"sysinfo 0.37.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"tempfile 3.25.0 registry+https://github.com/rust-lang/crates.io-index",
|
"tempfile 3.24.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"terminal_size 0.4.3 registry+https://github.com/rust-lang/crates.io-index",
|
"terminal_size 0.4.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"textwrap 0.16.2 registry+https://github.com/rust-lang/crates.io-index",
|
"textwrap 0.16.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"thiserror 2.0.18 registry+https://github.com/rust-lang/crates.io-index",
|
"thiserror 2.0.17 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"thiserror-impl 2.0.18 registry+https://github.com/rust-lang/crates.io-index",
|
"thiserror-impl 2.0.17 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"thread_local 1.1.9 registry+https://github.com/rust-lang/crates.io-index",
|
"thread_local 1.1.9 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"tiff 0.10.3 registry+https://github.com/rust-lang/crates.io-index",
|
"tiff 0.10.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"tiff 0.6.1 registry+https://github.com/rust-lang/crates.io-index",
|
"tiff 0.6.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"time 0.3.47 registry+https://github.com/rust-lang/crates.io-index",
|
"time 0.3.44 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"time-core 0.1.8 registry+https://github.com/rust-lang/crates.io-index",
|
"time-core 0.1.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"tokio 1.49.0 registry+https://github.com/rust-lang/crates.io-index",
|
"tokio 1.49.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"tokio-native-tls 0.3.1 registry+https://github.com/rust-lang/crates.io-index",
|
"tokio-native-tls 0.3.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"tokio-util 0.7.18 registry+https://github.com/rust-lang/crates.io-index",
|
"tokio-util 0.7.18 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"toml 0.5.11 registry+https://github.com/rust-lang/crates.io-index",
|
"toml 0.5.11 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"tower 0.5.3 registry+https://github.com/rust-lang/crates.io-index",
|
"tower 0.5.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"tower-http 0.6.8 registry+https://github.com/rust-lang/crates.io-index",
|
"tower-http 0.6.8 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"tower-layer 0.3.3 registry+https://github.com/rust-lang/crates.io-index",
|
"tower-layer 0.3.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"tower-service 0.3.3 registry+https://github.com/rust-lang/crates.io-index",
|
"tower-service 0.3.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -801,11 +799,11 @@
|
|||||||
"try-lock 0.2.5 registry+https://github.com/rust-lang/crates.io-index",
|
"try-lock 0.2.5 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"ttf-parser 0.25.1 registry+https://github.com/rust-lang/crates.io-index",
|
"ttf-parser 0.25.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"typenum 1.19.0 registry+https://github.com/rust-lang/crates.io-index",
|
"typenum 1.19.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"tz-rs 0.7.3 registry+https://github.com/rust-lang/crates.io-index",
|
"tz-rs 0.7.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"tzdb_data 0.2.3 registry+https://github.com/rust-lang/crates.io-index",
|
"tzdb_data 0.2.3 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"uds_windows 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
"uds_windows 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"unicase 2.9.0 registry+https://github.com/rust-lang/crates.io-index",
|
"unicase 2.9.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"unicode-ident 1.0.23 registry+https://github.com/rust-lang/crates.io-index",
|
"unicode-ident 1.0.22 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"unicode-segmentation 1.12.0 registry+https://github.com/rust-lang/crates.io-index",
|
"unicode-segmentation 1.12.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"unicode-width 0.1.14 registry+https://github.com/rust-lang/crates.io-index",
|
"unicode-width 0.1.14 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"unicode-width 0.2.2 registry+https://github.com/rust-lang/crates.io-index",
|
"unicode-width 0.2.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -820,10 +818,10 @@
|
|||||||
"walkdir 2.5.0 registry+https://github.com/rust-lang/crates.io-index",
|
"walkdir 2.5.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"want 0.3.1 registry+https://github.com/rust-lang/crates.io-index",
|
"want 0.3.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"web-time 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
"web-time 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"webbrowser 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
"webbrowser 1.0.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"weezl 0.1.12 registry+https://github.com/rust-lang/crates.io-index",
|
"weezl 0.1.12 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"which 8.0.0 registry+https://github.com/rust-lang/crates.io-index",
|
"which 8.0.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"win-msgbox 0.2.2 registry+https://github.com/rust-lang/crates.io-index",
|
"win-msgbox 0.2.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"winapi 0.3.9 registry+https://github.com/rust-lang/crates.io-index",
|
"winapi 0.3.9 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"winapi-util 0.1.11 registry+https://github.com/rust-lang/crates.io-index",
|
"winapi-util 0.1.11 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"windows 0.57.0 registry+https://github.com/rust-lang/crates.io-index",
|
"windows 0.57.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -891,15 +889,15 @@
|
|||||||
"xml-rs 0.8.28 registry+https://github.com/rust-lang/crates.io-index",
|
"xml-rs 0.8.28 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"y4m 0.8.0 registry+https://github.com/rust-lang/crates.io-index",
|
"y4m 0.8.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"yaml-rust 0.4.5 registry+https://github.com/rust-lang/crates.io-index",
|
"yaml-rust 0.4.5 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zerocopy 0.8.39 registry+https://github.com/rust-lang/crates.io-index",
|
"zerocopy 0.8.33 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zerocopy-derive 0.8.39 registry+https://github.com/rust-lang/crates.io-index",
|
"zerocopy-derive 0.8.33 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zeroize 1.8.2 registry+https://github.com/rust-lang/crates.io-index",
|
"zeroize 1.8.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zmij 1.0.21 registry+https://github.com/rust-lang/crates.io-index",
|
"zmij 1.0.12 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zune-core 0.4.12 registry+https://github.com/rust-lang/crates.io-index",
|
"zune-core 0.4.12 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zune-core 0.5.1 registry+https://github.com/rust-lang/crates.io-index",
|
"zune-core 0.5.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zune-inflate 0.2.54 registry+https://github.com/rust-lang/crates.io-index",
|
"zune-inflate 0.2.54 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zune-jpeg 0.4.21 registry+https://github.com/rust-lang/crates.io-index",
|
"zune-jpeg 0.4.21 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zune-jpeg 0.5.12 registry+https://github.com/rust-lang/crates.io-index"
|
"zune-jpeg 0.5.8 registry+https://github.com/rust-lang/crates.io-index"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -941,7 +939,7 @@
|
|||||||
"litemap 0.8.1 registry+https://github.com/rust-lang/crates.io-index",
|
"litemap 0.8.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"potential_utf 0.1.4 registry+https://github.com/rust-lang/crates.io-index",
|
"potential_utf 0.1.4 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"tinystr 0.8.2 registry+https://github.com/rust-lang/crates.io-index",
|
"tinystr 0.8.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"unicode-ident 1.0.23 registry+https://github.com/rust-lang/crates.io-index",
|
"unicode-ident 1.0.22 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"writeable 0.6.2 registry+https://github.com/rust-lang/crates.io-index",
|
"writeable 0.6.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"yoke 0.8.1 registry+https://github.com/rust-lang/crates.io-index",
|
"yoke 0.8.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"yoke-derive 0.8.1 registry+https://github.com/rust-lang/crates.io-index",
|
"yoke-derive 0.8.1 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -958,7 +956,7 @@
|
|||||||
"aho-corasick 1.1.4 registry+https://github.com/rust-lang/crates.io-index",
|
"aho-corasick 1.1.4 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"byteorder 1.5.0 registry+https://github.com/rust-lang/crates.io-index",
|
"byteorder 1.5.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"byteorder-lite 0.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
"byteorder-lite 0.1.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"memchr 2.8.0 registry+https://github.com/rust-lang/crates.io-index",
|
"memchr 2.7.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"same-file 1.0.6 registry+https://github.com/rust-lang/crates.io-index",
|
"same-file 1.0.6 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"walkdir 2.5.0 registry+https://github.com/rust-lang/crates.io-index",
|
"walkdir 2.5.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"winapi-util 0.1.11 registry+https://github.com/rust-lang/crates.io-index"
|
"winapi-util 0.1.11 registry+https://github.com/rust-lang/crates.io-index"
|
||||||
@@ -968,7 +966,7 @@
|
|||||||
"Zlib",
|
"Zlib",
|
||||||
[
|
[
|
||||||
"adler32 1.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
"adler32 1.2.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"bytemuck 1.25.0 registry+https://github.com/rust-lang/crates.io-index",
|
"bytemuck 1.24.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"bytemuck_derive 1.10.2 registry+https://github.com/rust-lang/crates.io-index",
|
"bytemuck_derive 1.10.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"const_format 0.2.35 registry+https://github.com/rust-lang/crates.io-index",
|
"const_format 0.2.35 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"const_format_proc_macros 0.2.34 registry+https://github.com/rust-lang/crates.io-index",
|
"const_format_proc_macros 0.2.34 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
@@ -979,10 +977,10 @@
|
|||||||
"miniz_oxide 0.8.9 registry+https://github.com/rust-lang/crates.io-index",
|
"miniz_oxide 0.8.9 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"raw-window-handle 0.6.2 registry+https://github.com/rust-lang/crates.io-index",
|
"raw-window-handle 0.6.2 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zune-core 0.4.12 registry+https://github.com/rust-lang/crates.io-index",
|
"zune-core 0.4.12 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zune-core 0.5.1 registry+https://github.com/rust-lang/crates.io-index",
|
"zune-core 0.5.0 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zune-inflate 0.2.54 registry+https://github.com/rust-lang/crates.io-index",
|
"zune-inflate 0.2.54 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zune-jpeg 0.4.21 registry+https://github.com/rust-lang/crates.io-index",
|
"zune-jpeg 0.4.21 registry+https://github.com/rust-lang/crates.io-index",
|
||||||
"zune-jpeg 0.5.12 registry+https://github.com/rust-lang/crates.io-index"
|
"zune-jpeg 0.5.8 registry+https://github.com/rust-lang/crates.io-index"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.2 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.9 MiB |
@@ -1,200 +0,0 @@
|
|||||||
# Layout Ratios
|
|
||||||
|
|
||||||
With `komorebi` you can customize the split ratios for various layouts using
|
|
||||||
`column_ratios` and `row_ratios` in the `layout_options` configuration.
|
|
||||||
|
|
||||||
## Before and After
|
|
||||||
|
|
||||||
BSP layout example:
|
|
||||||
|
|
||||||
**Before** (default 50/50 splits):
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
**After** (with `column_ratios: [0.7]` and `row_ratios: [0.6]`):
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"monitors": [
|
|
||||||
{
|
|
||||||
"workspaces": [
|
|
||||||
{
|
|
||||||
"name": "main",
|
|
||||||
"layout_options": {
|
|
||||||
"column_ratios": [0.3, 0.4],
|
|
||||||
"row_ratios": [0.4, 0.3]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
You can specify up to 5 ratio values (defined by `MAX_RATIOS` constant). Each value should be between 0.1 and 0.9
|
|
||||||
(defined by `MIN_RATIO` and `MAX_RATIO` constants). Values outside this range are automatically clamped.
|
|
||||||
Columns or rows without a specified ratio will share the remaining space equally.
|
|
||||||
|
|
||||||
## Usage by Layout
|
|
||||||
|
|
||||||
| Layout | `column_ratios` | `row_ratios` |
|
|
||||||
|--------|-----------------|--------------|
|
|
||||||
| **Columns** | Width of each column | - |
|
|
||||||
| **Rows** | - | Height of each row |
|
|
||||||
| **Grid** | Width of each column (rows are equal height) | - |
|
|
||||||
| **BSP** | `[0]` as horizontal split ratio | `[0]` as vertical split ratio |
|
|
||||||
| **VerticalStack** | `[0]` as primary column width | Stack row heights |
|
|
||||||
| **RightMainVerticalStack** | `[0]` as primary column width | Stack row heights |
|
|
||||||
| **HorizontalStack** | Stack column widths | `[0]` as primary row height |
|
|
||||||
| **UltrawideVerticalStack** | `[0]` center, `[1]` left column | Tertiary stack row heights |
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
### Columns Layout with Custom Widths
|
|
||||||
|
|
||||||
Create 3 columns with 30%, 40%, and 30% widths:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"layout_options": {
|
|
||||||
"column_ratios": [0.3, 0.4]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Note: The third column automatically gets the remaining 30%.
|
|
||||||
|
|
||||||
### Rows Layout with Custom Heights
|
|
||||||
|
|
||||||
Create 3 rows with 20%, 50%, and 30% heights:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"layout_options": {
|
|
||||||
"row_ratios": [0.2, 0.5]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Note: The third row automatically gets the remaining 30%.
|
|
||||||
|
|
||||||
### Grid Layout with Custom Column Widths
|
|
||||||
|
|
||||||
Grid with custom column widths (rows within each column are always equal height):
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"layout_options": {
|
|
||||||
"column_ratios": [0.4, 0.6]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Note: The Grid layout only supports `column_ratios`. Rows within each column are always
|
|
||||||
divided equally because the number of rows per column varies dynamically based on window count.
|
|
||||||
|
|
||||||
### VerticalStack with Custom Ratios
|
|
||||||
|
|
||||||
Primary column takes 60% width, and the stack rows are split 30%/70%:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"layout_options": {
|
|
||||||
"column_ratios": [0.6],
|
|
||||||
"row_ratios": [0.3]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Note: The second row automatically gets the remaining 70%.
|
|
||||||
|
|
||||||
### HorizontalStack with Custom Ratios
|
|
||||||
|
|
||||||
Primary row takes 70% height, and the stack columns are split 40%/60%:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"layout_options": {
|
|
||||||
"row_ratios": [0.7],
|
|
||||||
"column_ratios": [0.4]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Note: The second column automatically gets the remaining 60%.
|
|
||||||
|
|
||||||
### UltrawideVerticalStack with Custom Ratios
|
|
||||||
|
|
||||||
Center column at 50%, left column at 25% (remaining 25% goes to tertiary stack),
|
|
||||||
with tertiary rows split 40%/60%:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"layout_options": {
|
|
||||||
"column_ratios": [0.5, 0.25],
|
|
||||||
"row_ratios": [0.4]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Note: The second row automatically gets the remaining 60%.
|
|
||||||
|
|
||||||
### BSP Layout with Custom Split Ratios
|
|
||||||
|
|
||||||
Use separate ratios for horizontal (left/right) and vertical (top/bottom) splits:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"layout_options": {
|
|
||||||
"column_ratios": [0.6],
|
|
||||||
"row_ratios": [0.3]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- `column_ratios[0]`: Controls all horizontal splits (left window gets 60%, right gets 40%)
|
|
||||||
- `row_ratios[0]`: Controls all vertical splits (top window gets 30%, bottom gets 70%)
|
|
||||||
|
|
||||||
Note: BSP only uses the first value (`[0]`) from each ratio array. This single ratio is applied
|
|
||||||
consistently to all splits of that type throughout the layout. Additional values in the arrays are ignored.
|
|
||||||
|
|
||||||
## Notes
|
|
||||||
|
|
||||||
- Ratios are clamped between 0.1 and 0.9 (prevents zero-sized windows and ensures space for other windows)
|
|
||||||
- Default ratio is 0.5 (50%) when not specified, except for UltrawideVerticalStack secondary column which defaults to 0.25 (25%)
|
|
||||||
- Ratios are applied **progressively** - a ratio is only used when there are more windows to place after the current one
|
|
||||||
- The **last window always takes the remaining space**, regardless of defined ratios
|
|
||||||
- **Ratios that would sum to 100% or more are automatically truncated** at config load time to ensure there's always space for additional windows
|
|
||||||
- Unspecified ratios default to sharing the remaining space equally
|
|
||||||
- You only need to specify the ratios you want to customize; trailing values can be omitted
|
|
||||||
|
|
||||||
## Progressive Ratio Behavior
|
|
||||||
|
|
||||||
Ratios are applied progressively as windows are added. For example, with `row_ratios: [0.3, 0.5]` in a VerticalStack:
|
|
||||||
|
|
||||||
| Windows in Stack | Row Heights |
|
|
||||||
|------------------|-------------|
|
|
||||||
| 1 | 100% |
|
|
||||||
| 2 | 30%, 70% (remainder) |
|
|
||||||
| 3 | 30%, 50%, 20% (remainder) |
|
|
||||||
| 4 | 30%, 50%, 10%, 10% (remainder split equally) |
|
|
||||||
| 5 | 30%, 50%, 6.67%, 6.67%, 6.67% |
|
|
||||||
|
|
||||||
## Automatic Ratio Truncation
|
|
||||||
|
|
||||||
When ratios sum to 100% (or more), they are automatically truncated at config load time.
|
|
||||||
|
|
||||||
For example, if you configure `column_ratios: [0.4, 0.3, 0.3]` (sums to 100%), the last ratio (0.3) is automatically removed, resulting in effectively `[0.4, 0.3]`. This ensures there's always remaining space for the last window.
|
|
||||||
|
|
||||||
| Configured Ratios | Effective Ratios | Reason |
|
|
||||||
|-------------------|------------------|--------|
|
|
||||||
| `[0.3, 0.4]` | `[0.3, 0.4]` | Sum is 0.7, below 1.0 |
|
|
||||||
| `[0.4, 0.3, 0.3]` | `[0.4, 0.3]` | Sum would be 1.0, last ratio truncated |
|
|
||||||
| `[0.5, 0.5]` | `[0.5]` | Sum would be 1.0, last ratio truncated |
|
|
||||||
| `[0.6, 0.5]` | `[0.6]` | Sum would exceed 1.0, last ratio truncated |
|
|
||||||
|
|
||||||
This ensures the layout always fills 100% of the available space and new windows are never placed outside the visible area.
|
|
||||||
@@ -31,22 +31,22 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Media": {
|
"Media": {
|
||||||
"enable": false
|
"enable": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Storage": {
|
"Storage": {
|
||||||
"enable": false
|
"enable": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Memory": {
|
"Memory": {
|
||||||
"enable": false
|
"enable": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Network": {
|
"Network": {
|
||||||
"enable": false,
|
"enable": true,
|
||||||
"show_activity": true,
|
"show_activity": true,
|
||||||
"show_total_activity": true
|
"show_total_activity": true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use std::path::PathBuf;
|
|||||||
/// The `komorebi.bar.json` configuration file reference for `v0.1.40`
|
/// The `komorebi.bar.json` configuration file reference for `v0.1.40`
|
||||||
pub struct KomobarConfig {
|
pub struct KomobarConfig {
|
||||||
/// Bar height
|
/// Bar height
|
||||||
#[cfg_attr(feature = "schemars", schemars(extend("default" = 50)))]
|
#[cfg_attr(feature = "schemars", schemars(extend("default" = 50.0)))]
|
||||||
pub height: Option<f32>,
|
pub height: Option<f32>,
|
||||||
/// Bar padding. Use one value for all sides or use a grouped padding for horizontal and/or
|
/// Bar padding. Use one value for all sides or use a grouped padding for horizontal and/or
|
||||||
/// vertical definition which can each take a single value for a symmetric padding or two
|
/// vertical definition which can each take a single value for a symmetric padding or two
|
||||||
@@ -621,26 +621,6 @@ extend_enum!(
|
|||||||
AllIconsAndTextOnSelected,
|
AllIconsAndTextOnSelected,
|
||||||
});
|
});
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq)]
|
|
||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
|
||||||
/// Media widget display format
|
|
||||||
pub enum MediaDisplayFormat {
|
|
||||||
/// Show only the media info icon
|
|
||||||
Icon,
|
|
||||||
/// Show only the media info text (artist - title)
|
|
||||||
Text,
|
|
||||||
/// Show both icon and text
|
|
||||||
IconAndText,
|
|
||||||
/// Show only the control buttons (previous, play/pause, next)
|
|
||||||
ControlsOnly,
|
|
||||||
/// Show icon with control buttons
|
|
||||||
IconAndControls,
|
|
||||||
/// Show text with control buttons
|
|
||||||
TextAndControls,
|
|
||||||
/// Show icon, text, and control buttons
|
|
||||||
Full,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
use crate::MAX_LABEL_WIDTH;
|
use crate::MAX_LABEL_WIDTH;
|
||||||
use crate::bar::Alignment;
|
|
||||||
use crate::config::MediaDisplayFormat;
|
|
||||||
use crate::render::RenderConfig;
|
use crate::render::RenderConfig;
|
||||||
use crate::selected_frame::SelectableFrame;
|
use crate::selected_frame::SelectableFrame;
|
||||||
use crate::ui::CustomUi;
|
use crate::ui::CustomUi;
|
||||||
@@ -16,7 +14,6 @@ use serde::Deserialize;
|
|||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use windows::Media::Control::GlobalSystemMediaTransportControlsSessionManager;
|
use windows::Media::Control::GlobalSystemMediaTransportControlsSessionManager;
|
||||||
use windows::Media::Control::GlobalSystemMediaTransportControlsSessionPlaybackStatus;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
@@ -24,31 +21,24 @@ use windows::Media::Control::GlobalSystemMediaTransportControlsSessionPlaybackSt
|
|||||||
pub struct MediaConfig {
|
pub struct MediaConfig {
|
||||||
/// Enable the Media widget
|
/// Enable the Media widget
|
||||||
pub enable: bool,
|
pub enable: bool,
|
||||||
/// Display format of the media widget (defaults to IconAndText)
|
|
||||||
pub display: Option<MediaDisplayFormat>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<MediaConfig> for Media {
|
impl From<MediaConfig> for Media {
|
||||||
fn from(value: MediaConfig) -> Self {
|
fn from(value: MediaConfig) -> Self {
|
||||||
Self::new(
|
Self::new(value.enable)
|
||||||
value.enable,
|
|
||||||
value.display.unwrap_or(MediaDisplayFormat::IconAndText),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Media {
|
pub struct Media {
|
||||||
pub enable: bool,
|
pub enable: bool,
|
||||||
pub display: MediaDisplayFormat,
|
|
||||||
pub session_manager: GlobalSystemMediaTransportControlsSessionManager,
|
pub session_manager: GlobalSystemMediaTransportControlsSessionManager,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Media {
|
impl Media {
|
||||||
pub fn new(enable: bool, display: MediaDisplayFormat) -> Self {
|
pub fn new(enable: bool) -> Self {
|
||||||
Self {
|
Self {
|
||||||
enable,
|
enable,
|
||||||
display,
|
|
||||||
session_manager: GlobalSystemMediaTransportControlsSessionManager::RequestAsync()
|
session_manager: GlobalSystemMediaTransportControlsSessionManager::RequestAsync()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.join()
|
.join()
|
||||||
@@ -64,58 +54,6 @@ impl Media {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn previous(&self) {
|
|
||||||
if let Ok(session) = self.session_manager.GetCurrentSession()
|
|
||||||
&& let Ok(op) = session.TrySkipPreviousAsync()
|
|
||||||
{
|
|
||||||
op.join().unwrap_or_default();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next(&self) {
|
|
||||||
if let Ok(session) = self.session_manager.GetCurrentSession()
|
|
||||||
&& let Ok(op) = session.TrySkipNextAsync()
|
|
||||||
{
|
|
||||||
op.join().unwrap_or_default();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_playing(&self) -> bool {
|
|
||||||
if let Ok(session) = self.session_manager.GetCurrentSession()
|
|
||||||
&& let Ok(info) = session.GetPlaybackInfo()
|
|
||||||
&& let Ok(status) = info.PlaybackStatus()
|
|
||||||
{
|
|
||||||
return status == GlobalSystemMediaTransportControlsSessionPlaybackStatus::Playing;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_previous_enabled(&self) -> bool {
|
|
||||||
if let Ok(session) = self.session_manager.GetCurrentSession()
|
|
||||||
&& let Ok(info) = session.GetPlaybackInfo()
|
|
||||||
&& let Ok(controls) = info.Controls()
|
|
||||||
&& let Ok(enabled) = controls.IsPreviousEnabled()
|
|
||||||
{
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_next_enabled(&self) -> bool {
|
|
||||||
if let Ok(session) = self.session_manager.GetCurrentSession()
|
|
||||||
&& let Ok(info) = session.GetPlaybackInfo()
|
|
||||||
&& let Ok(controls) = info.Controls()
|
|
||||||
&& let Ok(enabled) = controls.IsNextEnabled()
|
|
||||||
{
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn has_session(&self) -> bool {
|
|
||||||
self.session_manager.GetCurrentSession().is_ok()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn output(&mut self) -> String {
|
fn output(&mut self) -> String {
|
||||||
if let Ok(session) = self.session_manager.GetCurrentSession()
|
if let Ok(session) = self.session_manager.GetCurrentSession()
|
||||||
&& let Ok(operation) = session.TryGetMediaPropertiesAsync()
|
&& let Ok(operation) = session.TryGetMediaPropertiesAsync()
|
||||||
@@ -140,96 +78,28 @@ impl Media {
|
|||||||
impl BarWidget for Media {
|
impl BarWidget for Media {
|
||||||
fn render(&mut self, ctx: &Context, ui: &mut Ui, config: &mut RenderConfig) {
|
fn render(&mut self, ctx: &Context, ui: &mut Ui, config: &mut RenderConfig) {
|
||||||
if self.enable {
|
if self.enable {
|
||||||
// Don't render if there's no active media session
|
|
||||||
if !self.has_session() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let output = self.output();
|
let output = self.output();
|
||||||
|
if !output.is_empty() {
|
||||||
let show_icon = matches!(
|
let mut layout_job = LayoutJob::simple(
|
||||||
self.display,
|
|
||||||
MediaDisplayFormat::Icon
|
|
||||||
| MediaDisplayFormat::IconAndText
|
|
||||||
| MediaDisplayFormat::IconAndControls
|
|
||||||
| MediaDisplayFormat::Full
|
|
||||||
);
|
|
||||||
let show_text = matches!(
|
|
||||||
self.display,
|
|
||||||
MediaDisplayFormat::Text
|
|
||||||
| MediaDisplayFormat::IconAndText
|
|
||||||
| MediaDisplayFormat::TextAndControls
|
|
||||||
| MediaDisplayFormat::Full
|
|
||||||
);
|
|
||||||
let show_controls = matches!(
|
|
||||||
self.display,
|
|
||||||
MediaDisplayFormat::ControlsOnly
|
|
||||||
| MediaDisplayFormat::IconAndControls
|
|
||||||
| MediaDisplayFormat::TextAndControls
|
|
||||||
| MediaDisplayFormat::Full
|
|
||||||
);
|
|
||||||
|
|
||||||
// Don't render if there's no media info and we're not showing controls-only
|
|
||||||
if output.is_empty() && !show_controls {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let icon_font_id = config.icon_font_id.clone();
|
|
||||||
let text_font_id = config.text_font_id.clone();
|
|
||||||
let icon_color = ctx.style().visuals.selection.stroke.color;
|
|
||||||
let text_color = ctx.style().visuals.text_color();
|
|
||||||
|
|
||||||
let mut layout_job = LayoutJob::default();
|
|
||||||
|
|
||||||
if show_icon {
|
|
||||||
layout_job = LayoutJob::simple(
|
|
||||||
egui_phosphor::regular::HEADPHONES.to_string(),
|
egui_phosphor::regular::HEADPHONES.to_string(),
|
||||||
icon_font_id.clone(),
|
config.icon_font_id.clone(),
|
||||||
icon_color,
|
ctx.style().visuals.selection.stroke.color,
|
||||||
100.0,
|
100.0,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
if show_text {
|
|
||||||
layout_job.append(
|
layout_job.append(
|
||||||
&output,
|
&output,
|
||||||
if show_icon { 10.0 } else { 0.0 },
|
10.0,
|
||||||
TextFormat {
|
TextFormat {
|
||||||
font_id: text_font_id,
|
font_id: config.text_font_id.clone(),
|
||||||
color: text_color,
|
color: ctx.style().visuals.text_color(),
|
||||||
valign: Align::Center,
|
valign: Align::Center,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
let is_playing = self.is_playing();
|
config.apply_on_widget(false, ui, |ui| {
|
||||||
let is_previous_enabled = self.is_previous_enabled();
|
if SelectableFrame::new(false)
|
||||||
let is_next_enabled = self.is_next_enabled();
|
|
||||||
let disabled_color = text_color.gamma_multiply(0.5);
|
|
||||||
let is_reversed = matches!(config.alignment, Some(Alignment::Right));
|
|
||||||
|
|
||||||
let prev_color = if is_previous_enabled {
|
|
||||||
text_color
|
|
||||||
} else {
|
|
||||||
disabled_color
|
|
||||||
};
|
|
||||||
|
|
||||||
let next_color = if is_next_enabled {
|
|
||||||
text_color
|
|
||||||
} else {
|
|
||||||
disabled_color
|
|
||||||
};
|
|
||||||
|
|
||||||
let play_pause_icon = if is_playing {
|
|
||||||
egui_phosphor::regular::PAUSE
|
|
||||||
} else {
|
|
||||||
egui_phosphor::regular::PLAY
|
|
||||||
};
|
|
||||||
|
|
||||||
let show_label = |ui: &mut Ui| {
|
|
||||||
if (show_icon || show_text)
|
|
||||||
&& SelectableFrame::new(false)
|
|
||||||
.show(ui, |ui| {
|
.show(ui, |ui| {
|
||||||
let available_height = ui.available_height();
|
let available_height = ui.available_height();
|
||||||
let mut custom_ui = CustomUi(ui);
|
let mut custom_ui = CustomUi(ui);
|
||||||
@@ -239,95 +109,15 @@ impl BarWidget for Media {
|
|||||||
MAX_LABEL_WIDTH.load(Ordering::SeqCst) as f32,
|
MAX_LABEL_WIDTH.load(Ordering::SeqCst) as f32,
|
||||||
available_height,
|
available_height,
|
||||||
),
|
),
|
||||||
Label::new(layout_job.clone()).selectable(false).truncate(),
|
Label::new(layout_job).selectable(false).truncate(),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.on_hover_text(&output)
|
|
||||||
.clicked()
|
.clicked()
|
||||||
{
|
{
|
||||||
self.toggle();
|
self.toggle();
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
let show_previous = |ui: &mut Ui| {
|
|
||||||
if SelectableFrame::new(false)
|
|
||||||
.show(ui, |ui| {
|
|
||||||
ui.add(
|
|
||||||
Label::new(LayoutJob::simple(
|
|
||||||
egui_phosphor::regular::SKIP_BACK.to_string(),
|
|
||||||
icon_font_id.clone(),
|
|
||||||
prev_color,
|
|
||||||
100.0,
|
|
||||||
))
|
|
||||||
.selectable(false),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.clicked()
|
|
||||||
&& is_previous_enabled
|
|
||||||
{
|
|
||||||
self.previous();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let show_play_pause = |ui: &mut Ui| {
|
|
||||||
if SelectableFrame::new(false)
|
|
||||||
.show(ui, |ui| {
|
|
||||||
ui.add(
|
|
||||||
Label::new(LayoutJob::simple(
|
|
||||||
play_pause_icon.to_string(),
|
|
||||||
icon_font_id.clone(),
|
|
||||||
text_color,
|
|
||||||
100.0,
|
|
||||||
))
|
|
||||||
.selectable(false),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.on_hover_text(&output)
|
|
||||||
.clicked()
|
|
||||||
{
|
|
||||||
self.toggle();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let show_next = |ui: &mut Ui| {
|
|
||||||
if SelectableFrame::new(false)
|
|
||||||
.show(ui, |ui| {
|
|
||||||
ui.add(
|
|
||||||
Label::new(LayoutJob::simple(
|
|
||||||
egui_phosphor::regular::SKIP_FORWARD.to_string(),
|
|
||||||
icon_font_id.clone(),
|
|
||||||
next_color,
|
|
||||||
100.0,
|
|
||||||
))
|
|
||||||
.selectable(false),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.clicked()
|
|
||||||
&& is_next_enabled
|
|
||||||
{
|
|
||||||
self.next();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
config.apply_on_widget(false, ui, |ui| {
|
|
||||||
if is_reversed {
|
|
||||||
// Right panel renders right-to-left, so reverse order
|
|
||||||
if show_controls {
|
|
||||||
show_next(ui);
|
|
||||||
show_play_pause(ui);
|
|
||||||
show_previous(ui);
|
|
||||||
}
|
|
||||||
show_label(ui);
|
|
||||||
} else {
|
|
||||||
// Left/center panel renders left-to-right, normal order
|
|
||||||
show_label(ui);
|
|
||||||
if show_controls {
|
|
||||||
show_previous(ui);
|
|
||||||
show_play_pause(ui);
|
|
||||||
show_next(ui);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "komorebi-layouts"
|
|
||||||
version = "0.1.40"
|
|
||||||
edition = "2024"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
clap = { workspace = true }
|
|
||||||
color-eyre = { workspace = true }
|
|
||||||
serde = { workspace = true }
|
|
||||||
serde_json = { workspace = true }
|
|
||||||
serde_yaml = { workspace = true }
|
|
||||||
strum = { workspace = true }
|
|
||||||
tracing = { workspace = true }
|
|
||||||
|
|
||||||
# Optional dependencies
|
|
||||||
schemars = { workspace = true, optional = true }
|
|
||||||
windows = { workspace = true, optional = true }
|
|
||||||
objc2-core-foundation = { version = "0.3", default-features = false, features = [
|
|
||||||
"std",
|
|
||||||
"CFCGTypes",
|
|
||||||
], optional = true }
|
|
||||||
|
|
||||||
[features]
|
|
||||||
schemars = ["dep:schemars"]
|
|
||||||
win32 = ["dep:windows"]
|
|
||||||
darwin = ["dep:objc2-core-foundation"]
|
|
||||||
@@ -1,785 +0,0 @@
|
|||||||
use clap::ValueEnum;
|
|
||||||
use serde::Deserialize;
|
|
||||||
use serde::Serialize;
|
|
||||||
use strum::Display;
|
|
||||||
use strum::EnumString;
|
|
||||||
|
|
||||||
use super::OperationDirection;
|
|
||||||
use super::Rect;
|
|
||||||
use super::Sizing;
|
|
||||||
|
|
||||||
/// Maximum number of ratio values that can be specified for column_ratios and row_ratios
|
|
||||||
pub const MAX_RATIOS: usize = 5;
|
|
||||||
|
|
||||||
/// Minimum allowed ratio value (prevents zero-sized windows)
|
|
||||||
pub const MIN_RATIO: f32 = 0.1;
|
|
||||||
|
|
||||||
/// Maximum allowed ratio value (ensures space for remaining windows)
|
|
||||||
pub const MAX_RATIO: f32 = 0.9;
|
|
||||||
|
|
||||||
/// Default ratio value when none is specified
|
|
||||||
pub const DEFAULT_RATIO: f32 = 0.5;
|
|
||||||
|
|
||||||
/// Default secondary ratio value for UltrawideVerticalStack layout
|
|
||||||
pub const DEFAULT_SECONDARY_RATIO: f32 = 0.25;
|
|
||||||
|
|
||||||
/// Validates and converts a Vec of ratios into a fixed-size array.
|
|
||||||
/// - Clamps values to MIN_RATIO..MAX_RATIO range
|
|
||||||
/// - Truncates when cumulative sum reaches or exceeds 1.0
|
|
||||||
/// - Limits to MAX_RATIOS values
|
|
||||||
#[must_use]
|
|
||||||
pub fn validate_ratios(ratios: &[f32]) -> [Option<f32>; MAX_RATIOS] {
|
|
||||||
let mut arr = [None; MAX_RATIOS];
|
|
||||||
let mut cumulative_sum = 0.0_f32;
|
|
||||||
|
|
||||||
for (i, &val) in ratios.iter().take(MAX_RATIOS).enumerate() {
|
|
||||||
let clamped_val = val.clamp(MIN_RATIO, MAX_RATIO);
|
|
||||||
|
|
||||||
// Only add this ratio if cumulative sum stays below 1.0
|
|
||||||
if cumulative_sum + clamped_val < 1.0 {
|
|
||||||
arr[i] = Some(clamped_val);
|
|
||||||
cumulative_sum += clamped_val;
|
|
||||||
} else {
|
|
||||||
// Stop adding ratios - cumulative sum would reach or exceed 1.0
|
|
||||||
tracing::debug!(
|
|
||||||
"Truncating ratios at index {} - cumulative sum {} + {} would reach/exceed 1.0",
|
|
||||||
i,
|
|
||||||
cumulative_sum,
|
|
||||||
clamped_val
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
arr
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(
|
|
||||||
Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq, Display, EnumString, ValueEnum,
|
|
||||||
)]
|
|
||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
|
||||||
/// A predefined komorebi layout
|
|
||||||
pub enum DefaultLayout {
|
|
||||||
/// BSP Layout
|
|
||||||
///
|
|
||||||
/// ```text
|
|
||||||
/// +-------+-----+
|
|
||||||
/// | | |
|
|
||||||
/// | +--+--+
|
|
||||||
/// | | |--|
|
|
||||||
/// +-------+--+--+
|
|
||||||
/// ```
|
|
||||||
BSP,
|
|
||||||
/// Columns Layout
|
|
||||||
///
|
|
||||||
/// ```text
|
|
||||||
/// +--+--+--+--+
|
|
||||||
/// | | | | |
|
|
||||||
/// | | | | |
|
|
||||||
/// | | | | |
|
|
||||||
/// +--+--+--+--+
|
|
||||||
/// ```
|
|
||||||
Columns,
|
|
||||||
/// Rows Layout
|
|
||||||
///
|
|
||||||
/// ```text
|
|
||||||
/// +-----------+
|
|
||||||
/// |-----------|
|
|
||||||
/// |-----------|
|
|
||||||
/// |-----------|
|
|
||||||
/// +-----------+
|
|
||||||
/// ```
|
|
||||||
Rows,
|
|
||||||
/// Vertical Stack Layout
|
|
||||||
///
|
|
||||||
/// ```text
|
|
||||||
/// +-------+-----+
|
|
||||||
/// | | |
|
|
||||||
/// | +-----+
|
|
||||||
/// | | |
|
|
||||||
/// +-------+-----+
|
|
||||||
/// ```
|
|
||||||
VerticalStack,
|
|
||||||
/// Horizontal Stack Layout
|
|
||||||
///
|
|
||||||
/// ```text
|
|
||||||
/// +------+------+
|
|
||||||
/// | |
|
|
||||||
/// |------+------+
|
|
||||||
/// | | |
|
|
||||||
/// +------+------+
|
|
||||||
/// ```
|
|
||||||
HorizontalStack,
|
|
||||||
/// Ultrawide Vertical Stack Layout
|
|
||||||
///
|
|
||||||
/// ```text
|
|
||||||
/// +-----+-----------+-----+
|
|
||||||
/// | | | |
|
|
||||||
/// | | +-----+
|
|
||||||
/// | | | |
|
|
||||||
/// | | +-----+
|
|
||||||
/// | | | |
|
|
||||||
/// +-----+-----------+-----+
|
|
||||||
/// ```
|
|
||||||
UltrawideVerticalStack,
|
|
||||||
/// Grid Layout
|
|
||||||
///
|
|
||||||
/// ```text
|
|
||||||
/// +-----+-----+ +---+---+---+ +---+---+---+ +---+---+---+
|
|
||||||
/// | | | | | | | | | | | | | | |
|
|
||||||
/// | | | | | | | | | | | | | +---+
|
|
||||||
/// +-----+-----+ | +---+---+ +---+---+---+ +---+---| |
|
|
||||||
/// | | | | | | | | | | | | | +---+
|
|
||||||
/// | | | | | | | | | | | | | | |
|
|
||||||
/// +-----+-----+ +---+---+---+ +---+---+---+ +---+---+---+
|
|
||||||
/// 4 windows 5 windows 6 windows 7 windows
|
|
||||||
/// ```
|
|
||||||
Grid,
|
|
||||||
/// Right Main Vertical Stack Layout
|
|
||||||
///
|
|
||||||
/// ```text
|
|
||||||
/// +-----+-------+
|
|
||||||
/// | | |
|
|
||||||
/// +-----+ |
|
|
||||||
/// | | |
|
|
||||||
/// +-----+-------+
|
|
||||||
/// ```
|
|
||||||
RightMainVerticalStack,
|
|
||||||
/// Scrolling Layout
|
|
||||||
///
|
|
||||||
/// ```text
|
|
||||||
/// +--+--+--+--+--+--+
|
|
||||||
/// | | | |
|
|
||||||
/// | | | |
|
|
||||||
/// | | | |
|
|
||||||
/// +--+--+--+--+--+--+
|
|
||||||
/// ```
|
|
||||||
Scrolling,
|
|
||||||
// NOTE: If any new layout is added, please make sure to register the same in `DefaultLayout::cycle`
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Helper to deserialize a variable-length array into a fixed [Option<f32>; MAX_RATIOS]
|
|
||||||
/// Ratios are truncated when their cumulative sum reaches or exceeds 1.0 to ensure
|
|
||||||
/// there's always remaining space for additional windows.
|
|
||||||
fn deserialize_ratios<'de, D>(
|
|
||||||
deserializer: D,
|
|
||||||
) -> Result<Option<[Option<f32>; MAX_RATIOS]>, D::Error>
|
|
||||||
where
|
|
||||||
D: serde::Deserializer<'de>,
|
|
||||||
{
|
|
||||||
let opt: Option<Vec<f32>> = Option::deserialize(deserializer)?;
|
|
||||||
Ok(opt.map(|vec| validate_ratios(&vec)))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Helper to serialize [Option<f32>; MAX_RATIOS] as a compact array (without trailing nulls)
|
|
||||||
fn serialize_ratios<S>(
|
|
||||||
value: &Option<[Option<f32>; MAX_RATIOS]>,
|
|
||||||
serializer: S,
|
|
||||||
) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: serde::Serializer,
|
|
||||||
{
|
|
||||||
match value {
|
|
||||||
None => serializer.serialize_none(),
|
|
||||||
Some(arr) => {
|
|
||||||
// Find last non-None index
|
|
||||||
let last_idx = arr
|
|
||||||
.iter()
|
|
||||||
.rposition(|x| x.is_some())
|
|
||||||
.map(|i| i + 1)
|
|
||||||
.unwrap_or(0);
|
|
||||||
let vec: Vec<f32> = arr.iter().take(last_idx).filter_map(|&x| x).collect();
|
|
||||||
serializer.serialize_some(&vec)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)]
|
|
||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
|
||||||
/// Options for specific layouts
|
|
||||||
pub struct LayoutOptions {
|
|
||||||
/// Options related to the Scrolling layout
|
|
||||||
pub scrolling: Option<ScrollingLayoutOptions>,
|
|
||||||
/// Options related to the Grid layout
|
|
||||||
pub grid: Option<GridLayoutOptions>,
|
|
||||||
/// Column width ratios (up to MAX_RATIOS values between 0.1 and 0.9)
|
|
||||||
///
|
|
||||||
/// - Used by Columns layout: ratios for each column width
|
|
||||||
/// - Used by Grid layout: ratios for column widths
|
|
||||||
/// - Used by BSP, VerticalStack, RightMainVerticalStack: column_ratios[0] as primary split ratio
|
|
||||||
/// - Used by HorizontalStack: column_ratios[0] as primary split ratio (top area height)
|
|
||||||
/// - Used by UltrawideVerticalStack: column_ratios[0] as center ratio, column_ratios[1] as left ratio
|
|
||||||
///
|
|
||||||
/// Columns without a ratio share remaining space equally.
|
|
||||||
/// Example: `[0.3, 0.4, 0.3]` for 30%-40%-30% columns
|
|
||||||
#[serde(
|
|
||||||
default,
|
|
||||||
deserialize_with = "deserialize_ratios",
|
|
||||||
serialize_with = "serialize_ratios"
|
|
||||||
)]
|
|
||||||
pub column_ratios: Option<[Option<f32>; MAX_RATIOS]>,
|
|
||||||
/// Row height ratios (up to MAX_RATIOS values between 0.1 and 0.9)
|
|
||||||
///
|
|
||||||
/// - Used by Rows layout: ratios for each row height
|
|
||||||
/// - Used by Grid layout: ratios for row heights
|
|
||||||
///
|
|
||||||
/// Rows without a ratio share remaining space equally.
|
|
||||||
/// Example: `[0.5, 0.5]` for 50%-50% rows
|
|
||||||
#[serde(
|
|
||||||
default,
|
|
||||||
deserialize_with = "deserialize_ratios",
|
|
||||||
serialize_with = "serialize_ratios"
|
|
||||||
)]
|
|
||||||
pub row_ratios: Option<[Option<f32>; MAX_RATIOS]>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq)]
|
|
||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
|
||||||
/// Options for the Scrolling layout
|
|
||||||
pub struct ScrollingLayoutOptions {
|
|
||||||
/// Desired number of visible columns (default: 3)
|
|
||||||
pub columns: usize,
|
|
||||||
/// With an odd number of visible columns, keep the focused window column centered
|
|
||||||
pub center_focused_column: Option<bool>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq)]
|
|
||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
|
||||||
/// Options for the Grid layout
|
|
||||||
pub struct GridLayoutOptions {
|
|
||||||
/// Maximum number of rows per grid column
|
|
||||||
pub rows: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DefaultLayout {
|
|
||||||
pub fn leftmost_index(&self, len: usize) -> usize {
|
|
||||||
match self {
|
|
||||||
Self::UltrawideVerticalStack | Self::RightMainVerticalStack => match len {
|
|
||||||
n if n > 1 => 1,
|
|
||||||
_ => 0,
|
|
||||||
},
|
|
||||||
Self::Scrolling => 0,
|
|
||||||
DefaultLayout::BSP
|
|
||||||
| DefaultLayout::Columns
|
|
||||||
| DefaultLayout::Rows
|
|
||||||
| DefaultLayout::VerticalStack
|
|
||||||
| DefaultLayout::HorizontalStack
|
|
||||||
| DefaultLayout::Grid => 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn rightmost_index(&self, len: usize) -> usize {
|
|
||||||
match self {
|
|
||||||
DefaultLayout::BSP
|
|
||||||
| DefaultLayout::Columns
|
|
||||||
| DefaultLayout::Rows
|
|
||||||
| DefaultLayout::VerticalStack
|
|
||||||
| DefaultLayout::HorizontalStack
|
|
||||||
| DefaultLayout::Grid => len.saturating_sub(1),
|
|
||||||
DefaultLayout::UltrawideVerticalStack => match len {
|
|
||||||
2 => 0,
|
|
||||||
_ => len.saturating_sub(1),
|
|
||||||
},
|
|
||||||
DefaultLayout::RightMainVerticalStack => 0,
|
|
||||||
DefaultLayout::Scrolling => len.saturating_sub(1),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
#[allow(clippy::cast_precision_loss, clippy::only_used_in_recursion)]
|
|
||||||
pub fn resize(
|
|
||||||
&self,
|
|
||||||
unaltered: &Rect,
|
|
||||||
resize: &Option<Rect>,
|
|
||||||
edge: OperationDirection,
|
|
||||||
sizing: Sizing,
|
|
||||||
delta: i32,
|
|
||||||
) -> Option<Rect> {
|
|
||||||
if !matches!(
|
|
||||||
self,
|
|
||||||
Self::BSP
|
|
||||||
| Self::Columns
|
|
||||||
| Self::Rows
|
|
||||||
| Self::VerticalStack
|
|
||||||
| Self::RightMainVerticalStack
|
|
||||||
| Self::HorizontalStack
|
|
||||||
| Self::UltrawideVerticalStack
|
|
||||||
| Self::Scrolling
|
|
||||||
) {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut r = resize.unwrap_or_default();
|
|
||||||
|
|
||||||
let resize_delta = delta;
|
|
||||||
|
|
||||||
match edge {
|
|
||||||
OperationDirection::Left => match sizing {
|
|
||||||
Sizing::Increase => {
|
|
||||||
// Some final checks to make sure the user can't infinitely resize to
|
|
||||||
// the point of pushing other windows out of bounds
|
|
||||||
|
|
||||||
// Note: These checks cannot take into account the changes made to the
|
|
||||||
// edges of adjacent windows at operation time, so it is still possible
|
|
||||||
// to push windows out of bounds by maxing out an Increase Left on a
|
|
||||||
// Window with index 1, and then maxing out a Decrease Right on a Window
|
|
||||||
// with index 0. I don't think it's worth trying to defensively program
|
|
||||||
// against this; if people end up in this situation they are better off
|
|
||||||
// just hitting the retile command
|
|
||||||
let diff = ((r.left + -resize_delta) as f32).abs();
|
|
||||||
if diff < unaltered.right as f32 {
|
|
||||||
r.left += -resize_delta;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Sizing::Decrease => {
|
|
||||||
let diff = ((r.left - -resize_delta) as f32).abs();
|
|
||||||
if diff < unaltered.right as f32 {
|
|
||||||
r.left -= -resize_delta;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
OperationDirection::Up => match sizing {
|
|
||||||
Sizing::Increase => {
|
|
||||||
let diff = ((r.top + resize_delta) as f32).abs();
|
|
||||||
if diff < unaltered.bottom as f32 {
|
|
||||||
r.top += -resize_delta;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Sizing::Decrease => {
|
|
||||||
let diff = ((r.top - resize_delta) as f32).abs();
|
|
||||||
if diff < unaltered.bottom as f32 {
|
|
||||||
r.top -= -resize_delta;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
OperationDirection::Right => match sizing {
|
|
||||||
Sizing::Increase => {
|
|
||||||
let diff = ((r.right + resize_delta) as f32).abs();
|
|
||||||
if diff < unaltered.right as f32 {
|
|
||||||
r.right += resize_delta;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Sizing::Decrease => {
|
|
||||||
let diff = ((r.right - resize_delta) as f32).abs();
|
|
||||||
if diff < unaltered.right as f32 {
|
|
||||||
r.right -= resize_delta;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
OperationDirection::Down => match sizing {
|
|
||||||
Sizing::Increase => {
|
|
||||||
let diff = ((r.bottom + resize_delta) as f32).abs();
|
|
||||||
if diff < unaltered.bottom as f32 {
|
|
||||||
r.bottom += resize_delta;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Sizing::Decrease => {
|
|
||||||
let diff = ((r.bottom - resize_delta) as f32).abs();
|
|
||||||
if diff < unaltered.bottom as f32 {
|
|
||||||
r.bottom -= resize_delta;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if r.eq(&Rect::default()) {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Option::from(r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub const fn cycle_next(self) -> Self {
|
|
||||||
match self {
|
|
||||||
Self::BSP => Self::Columns,
|
|
||||||
Self::Columns => Self::Rows,
|
|
||||||
Self::Rows => Self::VerticalStack,
|
|
||||||
Self::VerticalStack => Self::HorizontalStack,
|
|
||||||
Self::HorizontalStack => Self::UltrawideVerticalStack,
|
|
||||||
Self::UltrawideVerticalStack => Self::Grid,
|
|
||||||
Self::Grid => Self::RightMainVerticalStack,
|
|
||||||
Self::RightMainVerticalStack => Self::Scrolling,
|
|
||||||
Self::Scrolling => Self::BSP,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub const fn cycle_previous(self) -> Self {
|
|
||||||
match self {
|
|
||||||
Self::Scrolling => Self::RightMainVerticalStack,
|
|
||||||
Self::RightMainVerticalStack => Self::Grid,
|
|
||||||
Self::Grid => Self::UltrawideVerticalStack,
|
|
||||||
Self::UltrawideVerticalStack => Self::HorizontalStack,
|
|
||||||
Self::HorizontalStack => Self::VerticalStack,
|
|
||||||
Self::VerticalStack => Self::Rows,
|
|
||||||
Self::Rows => Self::Columns,
|
|
||||||
Self::Columns => Self::BSP,
|
|
||||||
Self::BSP => Self::RightMainVerticalStack,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
// Helper to create LayoutOptions with column ratios
|
|
||||||
fn layout_options_with_column_ratios(ratios: &[f32]) -> LayoutOptions {
|
|
||||||
let mut arr = [None; MAX_RATIOS];
|
|
||||||
for (i, &r) in ratios.iter().take(MAX_RATIOS).enumerate() {
|
|
||||||
arr[i] = Some(r);
|
|
||||||
}
|
|
||||||
LayoutOptions {
|
|
||||||
scrolling: None,
|
|
||||||
grid: None,
|
|
||||||
column_ratios: Some(arr),
|
|
||||||
row_ratios: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper to create LayoutOptions with row ratios
|
|
||||||
fn layout_options_with_row_ratios(ratios: &[f32]) -> LayoutOptions {
|
|
||||||
let mut arr = [None; MAX_RATIOS];
|
|
||||||
for (i, &r) in ratios.iter().take(MAX_RATIOS).enumerate() {
|
|
||||||
arr[i] = Some(r);
|
|
||||||
}
|
|
||||||
LayoutOptions {
|
|
||||||
scrolling: None,
|
|
||||||
grid: None,
|
|
||||||
column_ratios: None,
|
|
||||||
row_ratios: Some(arr),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper to create LayoutOptions with both column and row ratios
|
|
||||||
fn layout_options_with_ratios(column_ratios: &[f32], row_ratios: &[f32]) -> LayoutOptions {
|
|
||||||
let mut col_arr = [None; MAX_RATIOS];
|
|
||||||
for (i, &r) in column_ratios.iter().take(MAX_RATIOS).enumerate() {
|
|
||||||
col_arr[i] = Some(r);
|
|
||||||
}
|
|
||||||
let mut row_arr = [None; MAX_RATIOS];
|
|
||||||
for (i, &r) in row_ratios.iter().take(MAX_RATIOS).enumerate() {
|
|
||||||
row_arr[i] = Some(r);
|
|
||||||
}
|
|
||||||
LayoutOptions {
|
|
||||||
scrolling: None,
|
|
||||||
grid: None,
|
|
||||||
column_ratios: Some(col_arr),
|
|
||||||
row_ratios: Some(row_arr),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod deserialize_ratios_tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_deserialize_valid_ratios() {
|
|
||||||
let json = r#"{"column_ratios": [0.3, 0.4, 0.2]}"#;
|
|
||||||
let opts: LayoutOptions = serde_json::from_str(json).unwrap();
|
|
||||||
|
|
||||||
let ratios = opts.column_ratios.unwrap();
|
|
||||||
assert_eq!(ratios[0], Some(0.3));
|
|
||||||
assert_eq!(ratios[1], Some(0.4));
|
|
||||||
assert_eq!(ratios[2], Some(0.2));
|
|
||||||
assert_eq!(ratios[3], None);
|
|
||||||
assert_eq!(ratios[4], None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_deserialize_clamps_values_to_min() {
|
|
||||||
// Values below MIN_RATIO should be clamped
|
|
||||||
let json = r#"{"column_ratios": [0.05]}"#;
|
|
||||||
let opts: LayoutOptions = serde_json::from_str(json).unwrap();
|
|
||||||
|
|
||||||
let ratios = opts.column_ratios.unwrap();
|
|
||||||
assert_eq!(ratios[0], Some(MIN_RATIO)); // Clamped to 0.1
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_deserialize_clamps_values_to_max() {
|
|
||||||
// Values above MAX_RATIO should be clamped
|
|
||||||
let json = r#"{"column_ratios": [0.95]}"#;
|
|
||||||
let opts: LayoutOptions = serde_json::from_str(json).unwrap();
|
|
||||||
|
|
||||||
let ratios = opts.column_ratios.unwrap();
|
|
||||||
// 0.9 is the max, so it should be clamped
|
|
||||||
assert!(ratios[0].unwrap() <= MAX_RATIO);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_deserialize_truncates_when_sum_exceeds_one() {
|
|
||||||
// Sum of ratios should not reach 1.0
|
|
||||||
// [0.5, 0.4] = 0.9, then 0.3 would make it 1.2, so it should be truncated
|
|
||||||
let json = r#"{"column_ratios": [0.5, 0.4, 0.3]}"#;
|
|
||||||
let opts: LayoutOptions = serde_json::from_str(json).unwrap();
|
|
||||||
|
|
||||||
let ratios = opts.column_ratios.unwrap();
|
|
||||||
assert_eq!(ratios[0], Some(0.5));
|
|
||||||
assert_eq!(ratios[1], Some(0.4));
|
|
||||||
// Third ratio should be truncated because 0.5 + 0.4 + 0.3 >= 1.0
|
|
||||||
assert_eq!(ratios[2], None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_deserialize_truncates_at_max_ratios() {
|
|
||||||
// More than MAX_RATIOS values should be truncated
|
|
||||||
let json = r#"{"column_ratios": [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]}"#;
|
|
||||||
let opts: LayoutOptions = serde_json::from_str(json).unwrap();
|
|
||||||
|
|
||||||
let ratios = opts.column_ratios.unwrap();
|
|
||||||
// Only MAX_RATIOS (5) values should be stored
|
|
||||||
for i in 0..MAX_RATIOS {
|
|
||||||
assert_eq!(ratios[i], Some(0.1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_deserialize_empty_array() {
|
|
||||||
let json = r#"{"column_ratios": []}"#;
|
|
||||||
let opts: LayoutOptions = serde_json::from_str(json).unwrap();
|
|
||||||
|
|
||||||
let ratios = opts.column_ratios.unwrap();
|
|
||||||
for i in 0..MAX_RATIOS {
|
|
||||||
assert_eq!(ratios[i], None);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_deserialize_null() {
|
|
||||||
let json = r#"{"column_ratios": null}"#;
|
|
||||||
let opts: LayoutOptions = serde_json::from_str(json).unwrap();
|
|
||||||
assert!(opts.column_ratios.is_none());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_deserialize_row_ratios() {
|
|
||||||
let json = r#"{"row_ratios": [0.3, 0.5]}"#;
|
|
||||||
let opts: LayoutOptions = serde_json::from_str(json).unwrap();
|
|
||||||
|
|
||||||
let ratios = opts.row_ratios.unwrap();
|
|
||||||
assert_eq!(ratios[0], Some(0.3));
|
|
||||||
assert_eq!(ratios[1], Some(0.5));
|
|
||||||
assert_eq!(ratios[2], None);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod serialize_ratios_tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_serialize_ratios_compact() {
|
|
||||||
let opts = layout_options_with_column_ratios(&[0.3, 0.4]);
|
|
||||||
let json = serde_json::to_string(&opts).unwrap();
|
|
||||||
|
|
||||||
// Should serialize ratios as compact array without trailing nulls in the ratios array
|
|
||||||
assert!(json.contains("0.3") && json.contains("0.4"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_serialize_none_ratios() {
|
|
||||||
let opts = LayoutOptions {
|
|
||||||
scrolling: None,
|
|
||||||
grid: None,
|
|
||||||
column_ratios: None,
|
|
||||||
row_ratios: None,
|
|
||||||
};
|
|
||||||
let json = serde_json::to_string(&opts).unwrap();
|
|
||||||
|
|
||||||
// None values should serialize as null or be omitted
|
|
||||||
assert!(!json.contains("["));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_roundtrip_serialization() {
|
|
||||||
let original = layout_options_with_column_ratios(&[0.3, 0.4, 0.2]);
|
|
||||||
let json = serde_json::to_string(&original).unwrap();
|
|
||||||
let deserialized: LayoutOptions = serde_json::from_str(&json).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(original.column_ratios, deserialized.column_ratios);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_serialize_row_ratios() {
|
|
||||||
let opts = layout_options_with_row_ratios(&[0.3, 0.5]);
|
|
||||||
let json = serde_json::to_string(&opts).unwrap();
|
|
||||||
|
|
||||||
assert!(json.contains("row_ratios"));
|
|
||||||
assert!(json.contains("0.3") && json.contains("0.5"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_roundtrip_row_ratios() {
|
|
||||||
let original = layout_options_with_row_ratios(&[0.4, 0.3]);
|
|
||||||
let json = serde_json::to_string(&original).unwrap();
|
|
||||||
let deserialized: LayoutOptions = serde_json::from_str(&json).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(original.row_ratios, deserialized.row_ratios);
|
|
||||||
assert!(original.column_ratios.is_none());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_roundtrip_both_ratios() {
|
|
||||||
let original = layout_options_with_ratios(&[0.3, 0.4], &[0.5, 0.3]);
|
|
||||||
let json = serde_json::to_string(&original).unwrap();
|
|
||||||
let deserialized: LayoutOptions = serde_json::from_str(&json).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(original.column_ratios, deserialized.column_ratios);
|
|
||||||
assert_eq!(original.row_ratios, deserialized.row_ratios);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod ratio_constants_tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_constants_valid_ranges() {
|
|
||||||
assert!(MIN_RATIO > 0.0);
|
|
||||||
assert!(MIN_RATIO < MAX_RATIO);
|
|
||||||
assert!(MAX_RATIO < 1.0);
|
|
||||||
assert!(DEFAULT_RATIO >= MIN_RATIO && DEFAULT_RATIO <= MAX_RATIO);
|
|
||||||
assert!(DEFAULT_SECONDARY_RATIO >= MIN_RATIO && DEFAULT_SECONDARY_RATIO <= MAX_RATIO);
|
|
||||||
assert!(MAX_RATIOS >= 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_default_ratio_is_half() {
|
|
||||||
assert_eq!(DEFAULT_RATIO, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_max_ratios_is_five() {
|
|
||||||
assert_eq!(MAX_RATIOS, 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod layout_options_tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_layout_options_default_values() {
|
|
||||||
let json = r#"{}"#;
|
|
||||||
let opts: LayoutOptions = serde_json::from_str(json).unwrap();
|
|
||||||
|
|
||||||
assert!(opts.scrolling.is_none());
|
|
||||||
assert!(opts.grid.is_none());
|
|
||||||
assert!(opts.column_ratios.is_none());
|
|
||||||
assert!(opts.row_ratios.is_none());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_layout_options_with_all_fields() {
|
|
||||||
let json = r#"{
|
|
||||||
"scrolling": {"columns": 3},
|
|
||||||
"grid": {"rows": 2},
|
|
||||||
"column_ratios": [0.3, 0.4],
|
|
||||||
"row_ratios": [0.5]
|
|
||||||
}"#;
|
|
||||||
let opts: LayoutOptions = serde_json::from_str(json).unwrap();
|
|
||||||
|
|
||||||
assert!(opts.scrolling.is_some());
|
|
||||||
assert_eq!(opts.scrolling.unwrap().columns, 3);
|
|
||||||
assert!(opts.grid.is_some());
|
|
||||||
assert_eq!(opts.grid.unwrap().rows, 2);
|
|
||||||
assert!(opts.column_ratios.is_some());
|
|
||||||
assert!(opts.row_ratios.is_some());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod default_layout_tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_cycle_next_covers_all_layouts() {
|
|
||||||
let start = DefaultLayout::BSP;
|
|
||||||
let mut current = start;
|
|
||||||
let mut visited = vec![current];
|
|
||||||
|
|
||||||
loop {
|
|
||||||
current = current.cycle_next();
|
|
||||||
if current == start {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
assert!(
|
|
||||||
!visited.contains(¤t),
|
|
||||||
"Cycle contains duplicate: {:?}",
|
|
||||||
current
|
|
||||||
);
|
|
||||||
visited.push(current);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Should have visited all layouts
|
|
||||||
assert_eq!(visited.len(), 9); // 9 layouts total
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_cycle_previous_is_inverse_of_next() {
|
|
||||||
// Note: cycle_previous has some inconsistencies in the current implementation
|
|
||||||
// This test documents the expected behavior for most layouts
|
|
||||||
let layouts_with_correct_inverse = [
|
|
||||||
DefaultLayout::Columns,
|
|
||||||
DefaultLayout::Rows,
|
|
||||||
DefaultLayout::VerticalStack,
|
|
||||||
DefaultLayout::HorizontalStack,
|
|
||||||
DefaultLayout::UltrawideVerticalStack,
|
|
||||||
DefaultLayout::Grid,
|
|
||||||
DefaultLayout::RightMainVerticalStack,
|
|
||||||
];
|
|
||||||
|
|
||||||
for layout in layouts_with_correct_inverse {
|
|
||||||
let next = layout.cycle_next();
|
|
||||||
assert_eq!(
|
|
||||||
next.cycle_previous(),
|
|
||||||
layout,
|
|
||||||
"cycle_previous should be inverse of cycle_next for {:?}",
|
|
||||||
layout
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_leftmost_index_standard_layouts() {
|
|
||||||
assert_eq!(DefaultLayout::BSP.leftmost_index(5), 0);
|
|
||||||
assert_eq!(DefaultLayout::Columns.leftmost_index(5), 0);
|
|
||||||
assert_eq!(DefaultLayout::Rows.leftmost_index(5), 0);
|
|
||||||
assert_eq!(DefaultLayout::VerticalStack.leftmost_index(5), 0);
|
|
||||||
assert_eq!(DefaultLayout::HorizontalStack.leftmost_index(5), 0);
|
|
||||||
assert_eq!(DefaultLayout::Grid.leftmost_index(5), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_leftmost_index_ultrawide() {
|
|
||||||
assert_eq!(DefaultLayout::UltrawideVerticalStack.leftmost_index(1), 0);
|
|
||||||
assert_eq!(DefaultLayout::UltrawideVerticalStack.leftmost_index(2), 1);
|
|
||||||
assert_eq!(DefaultLayout::UltrawideVerticalStack.leftmost_index(5), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_leftmost_index_right_main() {
|
|
||||||
assert_eq!(DefaultLayout::RightMainVerticalStack.leftmost_index(1), 0);
|
|
||||||
assert_eq!(DefaultLayout::RightMainVerticalStack.leftmost_index(2), 1);
|
|
||||||
assert_eq!(DefaultLayout::RightMainVerticalStack.leftmost_index(5), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_rightmost_index_standard_layouts() {
|
|
||||||
assert_eq!(DefaultLayout::BSP.rightmost_index(5), 4);
|
|
||||||
assert_eq!(DefaultLayout::Columns.rightmost_index(5), 4);
|
|
||||||
assert_eq!(DefaultLayout::Rows.rightmost_index(5), 4);
|
|
||||||
assert_eq!(DefaultLayout::VerticalStack.rightmost_index(5), 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_rightmost_index_right_main() {
|
|
||||||
assert_eq!(DefaultLayout::RightMainVerticalStack.rightmost_index(1), 0);
|
|
||||||
assert_eq!(DefaultLayout::RightMainVerticalStack.rightmost_index(5), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_rightmost_index_ultrawide() {
|
|
||||||
assert_eq!(DefaultLayout::UltrawideVerticalStack.rightmost_index(1), 0);
|
|
||||||
assert_eq!(DefaultLayout::UltrawideVerticalStack.rightmost_index(2), 0);
|
|
||||||
assert_eq!(DefaultLayout::UltrawideVerticalStack.rightmost_index(3), 2);
|
|
||||||
assert_eq!(DefaultLayout::UltrawideVerticalStack.rightmost_index(5), 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
#![warn(clippy::all)]
|
|
||||||
#![allow(clippy::missing_errors_doc, clippy::use_self, clippy::doc_markdown)]
|
|
||||||
|
|
||||||
//! Layout system for the komorebi window manager.
|
|
||||||
//!
|
|
||||||
//! This crate provides the core layout algorithms and types for arranging windows
|
|
||||||
//! in various configurations. It includes optional Windows-specific functionality
|
|
||||||
//! behind the `win32` feature flag.
|
|
||||||
|
|
||||||
pub mod arrangement;
|
|
||||||
#[cfg(feature = "win32")]
|
|
||||||
pub mod custom_layout;
|
|
||||||
pub mod cycle_direction;
|
|
||||||
pub mod default_layout;
|
|
||||||
pub mod direction;
|
|
||||||
pub mod layout;
|
|
||||||
pub mod operation_direction;
|
|
||||||
pub mod rect;
|
|
||||||
pub mod sizing;
|
|
||||||
|
|
||||||
pub use arrangement::*;
|
|
||||||
#[cfg(feature = "win32")]
|
|
||||||
pub use custom_layout::*;
|
|
||||||
pub use cycle_direction::*;
|
|
||||||
pub use default_layout::*;
|
|
||||||
pub use direction::*;
|
|
||||||
pub use layout::*;
|
|
||||||
pub use operation_direction::*;
|
|
||||||
pub use rect::*;
|
|
||||||
pub use sizing::*;
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
use clap::ValueEnum;
|
|
||||||
use serde::Deserialize;
|
|
||||||
use serde::Serialize;
|
|
||||||
use strum::Display;
|
|
||||||
use strum::EnumString;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum)]
|
|
||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
|
||||||
/// Sizing
|
|
||||||
pub enum Sizing {
|
|
||||||
/// Increase
|
|
||||||
Increase,
|
|
||||||
/// Decrease
|
|
||||||
Decrease,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Sizing {
|
|
||||||
#[must_use]
|
|
||||||
pub const fn adjust_by(&self, value: i32, adjustment: i32) -> i32 {
|
|
||||||
match self {
|
|
||||||
Self::Increase => value + adjustment,
|
|
||||||
Self::Decrease => {
|
|
||||||
if value > 0 && value - adjustment >= 0 {
|
|
||||||
value - adjustment
|
|
||||||
} else {
|
|
||||||
value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
-2
@@ -8,7 +8,6 @@ edition = "2024"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
komorebi-layouts = { path = "../komorebi-layouts", features = ["win32"] }
|
|
||||||
komorebi-themes = { path = "../komorebi-themes" }
|
komorebi-themes = { path = "../komorebi-themes" }
|
||||||
|
|
||||||
base64 = "0.22"
|
base64 = "0.22"
|
||||||
@@ -64,4 +63,4 @@ uuid = { version = "1", features = ["v4"] }
|
|||||||
[features]
|
[features]
|
||||||
default = ["schemars"]
|
default = ["schemars"]
|
||||||
deadlock_detection = ["parking_lot/deadlock_detection"]
|
deadlock_detection = ["parking_lot/deadlock_detection"]
|
||||||
schemars = ["dep:schemars", "komorebi-layouts/schemars"]
|
schemars = ["dep:schemars"]
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ use crate::core::Rect;
|
|||||||
use crate::windows_api;
|
use crate::windows_api;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::Arc;
|
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
use std::sync::atomic::AtomicBool;
|
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use windows::Win32::Foundation::FALSE;
|
use windows::Win32::Foundation::FALSE;
|
||||||
@@ -128,7 +126,6 @@ pub struct Border {
|
|||||||
pub brush_properties: D2D1_BRUSH_PROPERTIES,
|
pub brush_properties: D2D1_BRUSH_PROPERTIES,
|
||||||
pub rounded_rect: D2D1_ROUNDED_RECT,
|
pub rounded_rect: D2D1_ROUNDED_RECT,
|
||||||
pub brushes: HashMap<WindowKind, ID2D1SolidColorBrush>,
|
pub brushes: HashMap<WindowKind, ID2D1SolidColorBrush>,
|
||||||
pub is_destroying: Arc<AtomicBool>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<isize> for Border {
|
impl From<isize> for Border {
|
||||||
@@ -147,7 +144,6 @@ impl From<isize> for Border {
|
|||||||
brush_properties: D2D1_BRUSH_PROPERTIES::default(),
|
brush_properties: D2D1_BRUSH_PROPERTIES::default(),
|
||||||
rounded_rect: D2D1_ROUNDED_RECT::default(),
|
rounded_rect: D2D1_ROUNDED_RECT::default(),
|
||||||
brushes: HashMap::new(),
|
brushes: HashMap::new(),
|
||||||
is_destroying: Arc::new(AtomicBool::new(false)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,7 +192,6 @@ impl Border {
|
|||||||
brush_properties: Default::default(),
|
brush_properties: Default::default(),
|
||||||
rounded_rect: Default::default(),
|
rounded_rect: Default::default(),
|
||||||
brushes: HashMap::new(),
|
brushes: HashMap::new(),
|
||||||
is_destroying: Arc::new(AtomicBool::new(false)),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let border_pointer = &raw mut border;
|
let border_pointer = &raw mut border;
|
||||||
@@ -318,12 +313,6 @@ impl Border {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn destroy(&self) -> color_eyre::Result<()> {
|
pub fn destroy(&self) -> color_eyre::Result<()> {
|
||||||
// signal that we're destroying - prevents new render operations
|
|
||||||
self.is_destroying.store(true, Ordering::Release);
|
|
||||||
|
|
||||||
// small delay to allow in-flight render operations to complete
|
|
||||||
std::thread::sleep(std::time::Duration::from_millis(10));
|
|
||||||
|
|
||||||
// clear user data **BEFORE** closing window
|
// clear user data **BEFORE** closing window
|
||||||
// pending messages will see a null pointer and exit early
|
// pending messages will see a null pointer and exit early
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -397,10 +386,6 @@ impl Border {
|
|||||||
return LRESULT(0);
|
return LRESULT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*border_pointer).is_destroying.load(Ordering::Acquire) {
|
|
||||||
return LRESULT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
let reference_hwnd = (*border_pointer).tracking_hwnd;
|
let reference_hwnd = (*border_pointer).tracking_hwnd;
|
||||||
|
|
||||||
let old_rect = (*border_pointer).window_rect;
|
let old_rect = (*border_pointer).window_rect;
|
||||||
@@ -415,11 +400,6 @@ impl Border {
|
|||||||
if (!rect.is_same_size_as(&old_rect) || !rect.has_same_position_as(&old_rect))
|
if (!rect.is_same_size_as(&old_rect) || !rect.has_same_position_as(&old_rect))
|
||||||
&& let Some(render_target) = (*border_pointer).render_target.as_ref()
|
&& let Some(render_target) = (*border_pointer).render_target.as_ref()
|
||||||
{
|
{
|
||||||
// double-check destruction flag before rendering
|
|
||||||
if (*border_pointer).is_destroying.load(Ordering::Acquire) {
|
|
||||||
return LRESULT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
let border_width = (*border_pointer).width;
|
let border_width = (*border_pointer).width;
|
||||||
let border_offset = (*border_pointer).offset;
|
let border_offset = (*border_pointer).offset;
|
||||||
|
|
||||||
@@ -488,10 +468,6 @@ impl Border {
|
|||||||
return LRESULT(0);
|
return LRESULT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*border_pointer).is_destroying.load(Ordering::Acquire) {
|
|
||||||
return LRESULT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
let reference_hwnd = (*border_pointer).tracking_hwnd;
|
let reference_hwnd = (*border_pointer).tracking_hwnd;
|
||||||
|
|
||||||
// Update position to update the ZOrder
|
// Update position to update the ZOrder
|
||||||
@@ -505,11 +481,6 @@ impl Border {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(render_target) = (*border_pointer).render_target.as_ref() {
|
if let Some(render_target) = (*border_pointer).render_target.as_ref() {
|
||||||
// double-check destruction flag before rendering
|
|
||||||
if (*border_pointer).is_destroying.load(Ordering::Acquire) {
|
|
||||||
return LRESULT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
(*border_pointer).width = BORDER_WIDTH.load(Ordering::Relaxed);
|
(*border_pointer).width = BORDER_WIDTH.load(Ordering::Relaxed);
|
||||||
(*border_pointer).offset = BORDER_OFFSET.load(Ordering::Relaxed);
|
(*border_pointer).offset = BORDER_OFFSET.load(Ordering::Relaxed);
|
||||||
|
|
||||||
@@ -577,12 +548,7 @@ impl Border {
|
|||||||
LRESULT(0)
|
LRESULT(0)
|
||||||
}
|
}
|
||||||
WM_DESTROY => {
|
WM_DESTROY => {
|
||||||
let border_pointer: *mut Border = GetWindowLongPtrW(window, GWLP_USERDATA) as _;
|
|
||||||
if !border_pointer.is_null() {
|
|
||||||
(*border_pointer).render_target = None;
|
|
||||||
(*border_pointer).brushes.clear();
|
|
||||||
SetWindowLongPtrW(window, GWLP_USERDATA, 0);
|
SetWindowLongPtrW(window, GWLP_USERDATA, 0);
|
||||||
}
|
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
LRESULT(0)
|
LRESULT(0)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -767,6 +767,12 @@ fn remove_border(
|
|||||||
fn destroy_border(border: Box<Border>) -> color_eyre::Result<()> {
|
fn destroy_border(border: Box<Border>) -> color_eyre::Result<()> {
|
||||||
let raw_pointer = Box::into_raw(border);
|
let raw_pointer = Box::into_raw(border);
|
||||||
unsafe {
|
unsafe {
|
||||||
|
// release d2d resources **BEFORE** destroying window
|
||||||
|
// this drops render_target and brushes while HWND is still valid
|
||||||
|
// prevents EndDraw() from accessing freed HWND resources
|
||||||
|
(*raw_pointer).render_target = None;
|
||||||
|
(*raw_pointer).brushes.clear();
|
||||||
|
|
||||||
// Now safe to destroy window
|
// Now safe to destroy window
|
||||||
(*raw_pointer).destroy()?;
|
(*raw_pointer).destroy()?;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,327 @@
|
|||||||
|
use clap::ValueEnum;
|
||||||
|
use core::str::FromStr;
|
||||||
|
use serde::Deserialize;
|
||||||
|
use serde::Serialize;
|
||||||
|
use strum::Display;
|
||||||
|
use strum::EnumString;
|
||||||
|
|
||||||
|
use super::OperationDirection;
|
||||||
|
use super::Rect;
|
||||||
|
use super::Sizing;
|
||||||
|
|
||||||
|
pub fn deserialize_option_none_default_layout<'de, D>(
|
||||||
|
deserializer: D,
|
||||||
|
) -> Result<Option<DefaultLayout>, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let s = String::deserialize(deserializer)?;
|
||||||
|
if s == "None" {
|
||||||
|
Ok(None)
|
||||||
|
} else {
|
||||||
|
<DefaultLayout as FromStr>::from_str(&s)
|
||||||
|
.map(Some)
|
||||||
|
.map_err(serde::de::Error::custom)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq, Display, EnumString, ValueEnum,
|
||||||
|
)]
|
||||||
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
|
/// A predefined komorebi layout
|
||||||
|
pub enum DefaultLayout {
|
||||||
|
/// BSP Layout
|
||||||
|
///
|
||||||
|
/// ```text
|
||||||
|
/// +-------+-----+
|
||||||
|
/// | | |
|
||||||
|
/// | +--+--+
|
||||||
|
/// | | |--|
|
||||||
|
/// +-------+--+--+
|
||||||
|
/// ```
|
||||||
|
BSP,
|
||||||
|
/// Columns Layout
|
||||||
|
///
|
||||||
|
/// ```text
|
||||||
|
/// +--+--+--+--+
|
||||||
|
/// | | | | |
|
||||||
|
/// | | | | |
|
||||||
|
/// | | | | |
|
||||||
|
/// +--+--+--+--+
|
||||||
|
/// ```
|
||||||
|
Columns,
|
||||||
|
/// Rows Layout
|
||||||
|
///
|
||||||
|
/// ```text
|
||||||
|
/// +-----------+
|
||||||
|
/// |-----------|
|
||||||
|
/// |-----------|
|
||||||
|
/// |-----------|
|
||||||
|
/// +-----------+
|
||||||
|
/// ```
|
||||||
|
Rows,
|
||||||
|
/// Vertical Stack Layout
|
||||||
|
///
|
||||||
|
/// ```text
|
||||||
|
/// +-------+-----+
|
||||||
|
/// | | |
|
||||||
|
/// | +-----+
|
||||||
|
/// | | |
|
||||||
|
/// +-------+-----+
|
||||||
|
/// ```
|
||||||
|
VerticalStack,
|
||||||
|
/// Horizontal Stack Layout
|
||||||
|
///
|
||||||
|
/// ```text
|
||||||
|
/// +------+------+
|
||||||
|
/// | |
|
||||||
|
/// |------+------+
|
||||||
|
/// | | |
|
||||||
|
/// +------+------+
|
||||||
|
/// ```
|
||||||
|
HorizontalStack,
|
||||||
|
/// Ultrawide Vertical Stack Layout
|
||||||
|
///
|
||||||
|
/// ```text
|
||||||
|
/// +-----+-----------+-----+
|
||||||
|
/// | | | |
|
||||||
|
/// | | +-----+
|
||||||
|
/// | | | |
|
||||||
|
/// | | +-----+
|
||||||
|
/// | | | |
|
||||||
|
/// +-----+-----------+-----+
|
||||||
|
/// ```
|
||||||
|
UltrawideVerticalStack,
|
||||||
|
/// Grid Layout
|
||||||
|
///
|
||||||
|
/// ```text
|
||||||
|
/// +-----+-----+ +---+---+---+ +---+---+---+ +---+---+---+
|
||||||
|
/// | | | | | | | | | | | | | | |
|
||||||
|
/// | | | | | | | | | | | | | +---+
|
||||||
|
/// +-----+-----+ | +---+---+ +---+---+---+ +---+---| |
|
||||||
|
/// | | | | | | | | | | | | | +---+
|
||||||
|
/// | | | | | | | | | | | | | | |
|
||||||
|
/// +-----+-----+ +---+---+---+ +---+---+---+ +---+---+---+
|
||||||
|
/// 4 windows 5 windows 6 windows 7 windows
|
||||||
|
/// ```
|
||||||
|
Grid,
|
||||||
|
/// Right Main Vertical Stack Layout
|
||||||
|
///
|
||||||
|
/// ```text
|
||||||
|
/// +-----+-------+
|
||||||
|
/// | | |
|
||||||
|
/// +-----+ |
|
||||||
|
/// | | |
|
||||||
|
/// +-----+-------+
|
||||||
|
/// ```
|
||||||
|
RightMainVerticalStack,
|
||||||
|
/// Scrolling Layout
|
||||||
|
///
|
||||||
|
/// ```text
|
||||||
|
/// +--+--+--+--+--+--+
|
||||||
|
/// | | | |
|
||||||
|
/// | | | |
|
||||||
|
/// | | | |
|
||||||
|
/// +--+--+--+--+--+--+
|
||||||
|
/// ```
|
||||||
|
Scrolling,
|
||||||
|
// NOTE: If any new layout is added, please make sure to register the same in `DefaultLayout::cycle`
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq)]
|
||||||
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
|
/// Options for specific layouts
|
||||||
|
pub struct LayoutOptions {
|
||||||
|
/// Options related to the Scrolling layout
|
||||||
|
pub scrolling: Option<ScrollingLayoutOptions>,
|
||||||
|
/// Options related to the Grid layout
|
||||||
|
pub grid: Option<GridLayoutOptions>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq)]
|
||||||
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
|
/// Options for the Scrolling layout
|
||||||
|
pub struct ScrollingLayoutOptions {
|
||||||
|
/// Desired number of visible columns (default: 3)
|
||||||
|
pub columns: usize,
|
||||||
|
/// With an odd number of visible columns, keep the focused window column centered
|
||||||
|
pub center_focused_column: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq)]
|
||||||
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
|
/// Options for the Grid layout
|
||||||
|
pub struct GridLayoutOptions {
|
||||||
|
/// Maximum number of rows per grid column
|
||||||
|
pub rows: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DefaultLayout {
|
||||||
|
pub fn leftmost_index(&self, len: usize) -> usize {
|
||||||
|
match self {
|
||||||
|
Self::UltrawideVerticalStack | Self::RightMainVerticalStack => match len {
|
||||||
|
n if n > 1 => 1,
|
||||||
|
_ => 0,
|
||||||
|
},
|
||||||
|
Self::Scrolling => 0,
|
||||||
|
DefaultLayout::BSP
|
||||||
|
| DefaultLayout::Columns
|
||||||
|
| DefaultLayout::Rows
|
||||||
|
| DefaultLayout::VerticalStack
|
||||||
|
| DefaultLayout::HorizontalStack
|
||||||
|
| DefaultLayout::Grid => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn rightmost_index(&self, len: usize) -> usize {
|
||||||
|
match self {
|
||||||
|
DefaultLayout::BSP
|
||||||
|
| DefaultLayout::Columns
|
||||||
|
| DefaultLayout::Rows
|
||||||
|
| DefaultLayout::VerticalStack
|
||||||
|
| DefaultLayout::HorizontalStack
|
||||||
|
| DefaultLayout::Grid => len.saturating_sub(1),
|
||||||
|
DefaultLayout::UltrawideVerticalStack => match len {
|
||||||
|
2 => 0,
|
||||||
|
_ => len.saturating_sub(1),
|
||||||
|
},
|
||||||
|
DefaultLayout::RightMainVerticalStack => 0,
|
||||||
|
DefaultLayout::Scrolling => len.saturating_sub(1),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
#[allow(clippy::cast_precision_loss, clippy::only_used_in_recursion)]
|
||||||
|
pub fn resize(
|
||||||
|
&self,
|
||||||
|
unaltered: &Rect,
|
||||||
|
resize: &Option<Rect>,
|
||||||
|
edge: OperationDirection,
|
||||||
|
sizing: Sizing,
|
||||||
|
delta: i32,
|
||||||
|
) -> Option<Rect> {
|
||||||
|
if !matches!(
|
||||||
|
self,
|
||||||
|
Self::BSP
|
||||||
|
| Self::Columns
|
||||||
|
| Self::Rows
|
||||||
|
| Self::VerticalStack
|
||||||
|
| Self::RightMainVerticalStack
|
||||||
|
| Self::HorizontalStack
|
||||||
|
| Self::UltrawideVerticalStack
|
||||||
|
| Self::Scrolling
|
||||||
|
) {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut r = resize.unwrap_or_default();
|
||||||
|
|
||||||
|
let resize_delta = delta;
|
||||||
|
|
||||||
|
match edge {
|
||||||
|
OperationDirection::Left => match sizing {
|
||||||
|
Sizing::Increase => {
|
||||||
|
// Some final checks to make sure the user can't infinitely resize to
|
||||||
|
// the point of pushing other windows out of bounds
|
||||||
|
|
||||||
|
// Note: These checks cannot take into account the changes made to the
|
||||||
|
// edges of adjacent windows at operation time, so it is still possible
|
||||||
|
// to push windows out of bounds by maxing out an Increase Left on a
|
||||||
|
// Window with index 1, and then maxing out a Decrease Right on a Window
|
||||||
|
// with index 0. I don't think it's worth trying to defensively program
|
||||||
|
// against this; if people end up in this situation they are better off
|
||||||
|
// just hitting the retile command
|
||||||
|
let diff = ((r.left + -resize_delta) as f32).abs();
|
||||||
|
if diff < unaltered.right as f32 {
|
||||||
|
r.left += -resize_delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sizing::Decrease => {
|
||||||
|
let diff = ((r.left - -resize_delta) as f32).abs();
|
||||||
|
if diff < unaltered.right as f32 {
|
||||||
|
r.left -= -resize_delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
OperationDirection::Up => match sizing {
|
||||||
|
Sizing::Increase => {
|
||||||
|
let diff = ((r.top + resize_delta) as f32).abs();
|
||||||
|
if diff < unaltered.bottom as f32 {
|
||||||
|
r.top += -resize_delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sizing::Decrease => {
|
||||||
|
let diff = ((r.top - resize_delta) as f32).abs();
|
||||||
|
if diff < unaltered.bottom as f32 {
|
||||||
|
r.top -= -resize_delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
OperationDirection::Right => match sizing {
|
||||||
|
Sizing::Increase => {
|
||||||
|
let diff = ((r.right + resize_delta) as f32).abs();
|
||||||
|
if diff < unaltered.right as f32 {
|
||||||
|
r.right += resize_delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sizing::Decrease => {
|
||||||
|
let diff = ((r.right - resize_delta) as f32).abs();
|
||||||
|
if diff < unaltered.right as f32 {
|
||||||
|
r.right -= resize_delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
OperationDirection::Down => match sizing {
|
||||||
|
Sizing::Increase => {
|
||||||
|
let diff = ((r.bottom + resize_delta) as f32).abs();
|
||||||
|
if diff < unaltered.bottom as f32 {
|
||||||
|
r.bottom += resize_delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sizing::Decrease => {
|
||||||
|
let diff = ((r.bottom - resize_delta) as f32).abs();
|
||||||
|
if diff < unaltered.bottom as f32 {
|
||||||
|
r.bottom -= resize_delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if r.eq(&Rect::default()) {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Option::from(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub const fn cycle_next(self) -> Self {
|
||||||
|
match self {
|
||||||
|
Self::BSP => Self::Columns,
|
||||||
|
Self::Columns => Self::Rows,
|
||||||
|
Self::Rows => Self::VerticalStack,
|
||||||
|
Self::VerticalStack => Self::HorizontalStack,
|
||||||
|
Self::HorizontalStack => Self::UltrawideVerticalStack,
|
||||||
|
Self::UltrawideVerticalStack => Self::Grid,
|
||||||
|
Self::Grid => Self::RightMainVerticalStack,
|
||||||
|
Self::RightMainVerticalStack => Self::Scrolling,
|
||||||
|
Self::Scrolling => Self::BSP,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub const fn cycle_previous(self) -> Self {
|
||||||
|
match self {
|
||||||
|
Self::Scrolling => Self::RightMainVerticalStack,
|
||||||
|
Self::RightMainVerticalStack => Self::Grid,
|
||||||
|
Self::Grid => Self::UltrawideVerticalStack,
|
||||||
|
Self::UltrawideVerticalStack => Self::HorizontalStack,
|
||||||
|
Self::HorizontalStack => Self::VerticalStack,
|
||||||
|
Self::VerticalStack => Self::Rows,
|
||||||
|
Self::Rows => Self::Columns,
|
||||||
|
Self::Columns => Self::BSP,
|
||||||
|
Self::BSP => Self::RightMainVerticalStack,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,8 @@
|
|||||||
use super::DefaultLayout;
|
use super::DefaultLayout;
|
||||||
use super::OperationDirection;
|
use super::OperationDirection;
|
||||||
#[cfg(feature = "win32")]
|
|
||||||
use super::custom_layout::Column;
|
use super::custom_layout::Column;
|
||||||
#[cfg(feature = "win32")]
|
|
||||||
use super::custom_layout::ColumnSplit;
|
use super::custom_layout::ColumnSplit;
|
||||||
#[cfg(feature = "win32")]
|
|
||||||
use super::custom_layout::ColumnSplitWithCapacity;
|
use super::custom_layout::ColumnSplitWithCapacity;
|
||||||
#[cfg(feature = "win32")]
|
|
||||||
use super::custom_layout::CustomLayout;
|
use super::custom_layout::CustomLayout;
|
||||||
use crate::default_layout::LayoutOptions;
|
use crate::default_layout::LayoutOptions;
|
||||||
|
|
||||||
@@ -404,7 +400,6 @@ fn grid_neighbor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "win32")]
|
|
||||||
impl Direction for CustomLayout {
|
impl Direction for CustomLayout {
|
||||||
fn index_in_direction(
|
fn index_in_direction(
|
||||||
&self,
|
&self,
|
||||||
@@ -2,7 +2,6 @@ use serde::Deserialize;
|
|||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use super::Arrangement;
|
use super::Arrangement;
|
||||||
#[cfg(feature = "win32")]
|
|
||||||
use super::CustomLayout;
|
use super::CustomLayout;
|
||||||
use super::DefaultLayout;
|
use super::DefaultLayout;
|
||||||
use super::Direction;
|
use super::Direction;
|
||||||
@@ -11,7 +10,6 @@ use super::Direction;
|
|||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
pub enum Layout {
|
pub enum Layout {
|
||||||
Default(DefaultLayout),
|
Default(DefaultLayout),
|
||||||
#[cfg(feature = "win32")]
|
|
||||||
Custom(CustomLayout),
|
Custom(CustomLayout),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,7 +18,6 @@ impl Layout {
|
|||||||
pub fn as_boxed_direction(&self) -> Box<dyn Direction> {
|
pub fn as_boxed_direction(&self) -> Box<dyn Direction> {
|
||||||
match self {
|
match self {
|
||||||
Layout::Default(layout) => Box::new(*layout),
|
Layout::Default(layout) => Box::new(*layout),
|
||||||
#[cfg(feature = "win32")]
|
|
||||||
Layout::Custom(layout) => Box::new(layout.clone()),
|
Layout::Custom(layout) => Box::new(layout.clone()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,7 +26,6 @@ impl Layout {
|
|||||||
pub fn as_boxed_arrangement(&self) -> Box<dyn Arrangement> {
|
pub fn as_boxed_arrangement(&self) -> Box<dyn Arrangement> {
|
||||||
match self {
|
match self {
|
||||||
Layout::Default(layout) => Box::new(*layout),
|
Layout::Default(layout) => Box::new(*layout),
|
||||||
#[cfg(feature = "win32")]
|
|
||||||
Layout::Custom(layout) => Box::new(layout.clone()),
|
Layout::Custom(layout) => Box::new(layout.clone()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+47
-28
@@ -15,43 +15,37 @@ use strum::EnumString;
|
|||||||
|
|
||||||
use crate::KomorebiTheme;
|
use crate::KomorebiTheme;
|
||||||
use crate::animation::prefix::AnimationPrefix;
|
use crate::animation::prefix::AnimationPrefix;
|
||||||
|
|
||||||
// Re-export everything from komorebi-layouts
|
|
||||||
pub use komorebi_layouts::Arrangement;
|
|
||||||
pub use komorebi_layouts::Axis;
|
|
||||||
pub use komorebi_layouts::Column;
|
|
||||||
pub use komorebi_layouts::ColumnSplit;
|
|
||||||
pub use komorebi_layouts::ColumnSplitWithCapacity;
|
|
||||||
pub use komorebi_layouts::ColumnWidth;
|
|
||||||
pub use komorebi_layouts::CustomLayout;
|
|
||||||
pub use komorebi_layouts::CycleDirection;
|
|
||||||
pub use komorebi_layouts::DEFAULT_RATIO;
|
|
||||||
pub use komorebi_layouts::DEFAULT_SECONDARY_RATIO;
|
|
||||||
pub use komorebi_layouts::DefaultLayout;
|
|
||||||
pub use komorebi_layouts::Direction;
|
|
||||||
pub use komorebi_layouts::GridLayoutOptions;
|
|
||||||
pub use komorebi_layouts::Layout;
|
|
||||||
pub use komorebi_layouts::LayoutOptions;
|
|
||||||
pub use komorebi_layouts::MAX_RATIO;
|
|
||||||
pub use komorebi_layouts::MAX_RATIOS;
|
|
||||||
pub use komorebi_layouts::MIN_RATIO;
|
|
||||||
pub use komorebi_layouts::OperationDirection;
|
|
||||||
pub use komorebi_layouts::Rect;
|
|
||||||
pub use komorebi_layouts::ScrollingLayoutOptions;
|
|
||||||
pub use komorebi_layouts::Sizing;
|
|
||||||
pub use komorebi_layouts::validate_ratios;
|
|
||||||
|
|
||||||
// Local modules and exports
|
|
||||||
pub use animation::AnimationStyle;
|
pub use animation::AnimationStyle;
|
||||||
|
pub use arrangement::Arrangement;
|
||||||
|
pub use arrangement::Axis;
|
||||||
|
pub use custom_layout::Column;
|
||||||
|
pub use custom_layout::ColumnSplit;
|
||||||
|
pub use custom_layout::ColumnSplitWithCapacity;
|
||||||
|
pub use custom_layout::ColumnWidth;
|
||||||
|
pub use custom_layout::CustomLayout;
|
||||||
|
pub use cycle_direction::CycleDirection;
|
||||||
|
pub use default_layout::*;
|
||||||
|
pub use direction::Direction;
|
||||||
|
pub use layout::Layout;
|
||||||
|
pub use operation_direction::OperationDirection;
|
||||||
pub use pathext::PathExt;
|
pub use pathext::PathExt;
|
||||||
pub use pathext::ResolvedPathBuf;
|
pub use pathext::ResolvedPathBuf;
|
||||||
pub use pathext::replace_env_in_path;
|
pub use pathext::replace_env_in_path;
|
||||||
pub use pathext::resolve_option_hashmap_usize_path;
|
pub use pathext::resolve_option_hashmap_usize_path;
|
||||||
|
pub use rect::Rect;
|
||||||
|
|
||||||
pub mod animation;
|
pub mod animation;
|
||||||
|
pub mod arrangement;
|
||||||
pub mod asc;
|
pub mod asc;
|
||||||
pub mod config_generation;
|
pub mod config_generation;
|
||||||
|
pub mod custom_layout;
|
||||||
|
pub mod cycle_direction;
|
||||||
|
pub mod default_layout;
|
||||||
|
pub mod direction;
|
||||||
|
pub mod layout;
|
||||||
|
pub mod operation_direction;
|
||||||
pub mod pathext;
|
pub mod pathext;
|
||||||
|
pub mod rect;
|
||||||
|
|
||||||
// serde_as must be before derive
|
// serde_as must be before derive
|
||||||
#[serde_with::serde_as]
|
#[serde_with::serde_as]
|
||||||
@@ -119,7 +113,6 @@ pub enum SocketMessage {
|
|||||||
AdjustWorkspacePadding(Sizing, i32),
|
AdjustWorkspacePadding(Sizing, i32),
|
||||||
ChangeLayout(DefaultLayout),
|
ChangeLayout(DefaultLayout),
|
||||||
CycleLayout(CycleDirection),
|
CycleLayout(CycleDirection),
|
||||||
LayoutRatios(Option<Vec<f32>>, Option<Vec<f32>>),
|
|
||||||
ScrollingLayoutColumns(NonZeroUsize),
|
ScrollingLayoutColumns(NonZeroUsize),
|
||||||
ChangeLayoutCustom(#[serde_as(as = "ResolvedPathBuf")] PathBuf),
|
ChangeLayoutCustom(#[serde_as(as = "ResolvedPathBuf")] PathBuf),
|
||||||
FlipLayout(Axis),
|
FlipLayout(Axis),
|
||||||
@@ -552,6 +545,32 @@ pub enum OperationBehaviour {
|
|||||||
NoOp,
|
NoOp,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum)]
|
||||||
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
|
/// Sizing
|
||||||
|
pub enum Sizing {
|
||||||
|
/// Increase
|
||||||
|
Increase,
|
||||||
|
/// Decrease
|
||||||
|
Decrease,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sizing {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn adjust_by(&self, value: i32, adjustment: i32) -> i32 {
|
||||||
|
match self {
|
||||||
|
Self::Increase => value + adjustment,
|
||||||
|
Self::Decrease => {
|
||||||
|
if value > 0 && value - adjustment >= 0 {
|
||||||
|
value - adjustment
|
||||||
|
} else {
|
||||||
|
value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Copy, Debug, Default, Serialize, Deserialize, Display, EnumString, ValueEnum, PartialEq,
|
Clone, Copy, Debug, Default, Serialize, Deserialize, Display, EnumString, ValueEnum, PartialEq,
|
||||||
)]
|
)]
|
||||||
|
|||||||
@@ -1,18 +1,7 @@
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
#[cfg(feature = "win32")]
|
|
||||||
use windows::Win32::Foundation::RECT;
|
use windows::Win32::Foundation::RECT;
|
||||||
|
|
||||||
#[cfg(feature = "darwin")]
|
|
||||||
use objc2_core_foundation::CGFloat;
|
|
||||||
#[cfg(feature = "darwin")]
|
|
||||||
use objc2_core_foundation::CGPoint;
|
|
||||||
#[cfg(feature = "darwin")]
|
|
||||||
use objc2_core_foundation::CGRect;
|
|
||||||
#[cfg(feature = "darwin")]
|
|
||||||
use objc2_core_foundation::CGSize;
|
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, Eq, PartialEq)]
|
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, Eq, PartialEq)]
|
||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
/// Rectangle dimensions
|
/// Rectangle dimensions
|
||||||
@@ -27,7 +16,6 @@ pub struct Rect {
|
|||||||
pub bottom: i32,
|
pub bottom: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "win32")]
|
|
||||||
impl From<RECT> for Rect {
|
impl From<RECT> for Rect {
|
||||||
fn from(rect: RECT) -> Self {
|
fn from(rect: RECT) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -39,7 +27,6 @@ impl From<RECT> for Rect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "win32")]
|
|
||||||
impl From<Rect> for RECT {
|
impl From<Rect> for RECT {
|
||||||
fn from(rect: Rect) -> Self {
|
fn from(rect: Rect) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -51,53 +38,6 @@ impl From<Rect> for RECT {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "darwin")]
|
|
||||||
impl From<CGSize> for Rect {
|
|
||||||
fn from(value: CGSize) -> Self {
|
|
||||||
Self {
|
|
||||||
left: 0,
|
|
||||||
top: 0,
|
|
||||||
right: value.width as i32,
|
|
||||||
bottom: value.height as i32,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "darwin")]
|
|
||||||
impl From<CGRect> for Rect {
|
|
||||||
fn from(value: CGRect) -> Self {
|
|
||||||
Self {
|
|
||||||
left: value.origin.x as i32,
|
|
||||||
top: value.origin.y as i32,
|
|
||||||
right: value.size.width as i32,
|
|
||||||
bottom: value.size.height as i32,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "darwin")]
|
|
||||||
impl From<&Rect> for CGRect {
|
|
||||||
fn from(value: &Rect) -> Self {
|
|
||||||
Self {
|
|
||||||
origin: CGPoint {
|
|
||||||
x: value.left as CGFloat,
|
|
||||||
y: value.top as CGFloat,
|
|
||||||
},
|
|
||||||
size: CGSize {
|
|
||||||
width: value.right as CGFloat,
|
|
||||||
height: value.bottom as CGFloat,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "darwin")]
|
|
||||||
impl From<Rect> for CGRect {
|
|
||||||
fn from(value: Rect) -> Self {
|
|
||||||
CGRect::from(&value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Rect {
|
impl Rect {
|
||||||
pub fn is_same_size_as(&self, rhs: &Self) -> bool {
|
pub fn is_same_size_as(&self, rhs: &Self) -> bool {
|
||||||
self.right == rhs.right && self.bottom == rhs.bottom
|
self.right == rhs.right && self.bottom == rhs.bottom
|
||||||
@@ -156,7 +96,6 @@ impl Rect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "win32")]
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn rect(&self) -> RECT {
|
pub const fn rect(&self) -> RECT {
|
||||||
RECT {
|
RECT {
|
||||||
@@ -166,19 +105,4 @@ impl Rect {
|
|||||||
bottom: self.top + self.bottom,
|
bottom: self.top + self.bottom,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "darwin")]
|
|
||||||
#[must_use]
|
|
||||||
pub fn percentage_within_horizontal_bounds(&self, other: &Rect) -> f64 {
|
|
||||||
let overlap_left = self.left.max(other.left);
|
|
||||||
let overlap_right = (self.left + self.right).min(other.left + other.right);
|
|
||||||
|
|
||||||
let overlap_width = overlap_right - overlap_left;
|
|
||||||
|
|
||||||
if overlap_width <= 0 {
|
|
||||||
0.0
|
|
||||||
} else {
|
|
||||||
(overlap_width as f64) / (other.right as f64) * 100.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -240,6 +240,8 @@ lazy_static! {
|
|||||||
static ref CURRENT_VIRTUAL_DESKTOP: Arc<Mutex<Option<Vec<u8>>>> = Arc::new(Mutex::new(None));
|
static ref CURRENT_VIRTUAL_DESKTOP: Arc<Mutex<Option<Vec<u8>>>> = Arc::new(Mutex::new(None));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub static DEFAULT_WORKSPACE_LAYOUT: AtomicCell<Option<DefaultLayout>> =
|
||||||
|
AtomicCell::new(Some(DefaultLayout::BSP));
|
||||||
pub static DEFAULT_WORKSPACE_PADDING: AtomicI32 = AtomicI32::new(10);
|
pub static DEFAULT_WORKSPACE_PADDING: AtomicI32 = AtomicI32::new(10);
|
||||||
pub static DEFAULT_CONTAINER_PADDING: AtomicI32 = AtomicI32::new(10);
|
pub static DEFAULT_CONTAINER_PADDING: AtomicI32 = AtomicI32::new(10);
|
||||||
pub static DEFAULT_RESIZE_DELTA: i32 = 50;
|
pub static DEFAULT_RESIZE_DELTA: i32 = 50;
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ use std::collections::HashMap;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::sync::atomic::AtomicI64;
|
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
pub mod hidden;
|
pub mod hidden;
|
||||||
@@ -45,10 +44,6 @@ pub enum MonitorNotification {
|
|||||||
|
|
||||||
static ACTIVE: AtomicBool = AtomicBool::new(true);
|
static ACTIVE: AtomicBool = AtomicBool::new(true);
|
||||||
|
|
||||||
/// Timestamp (epoch millis) of the last DisplayConnectionChange notification.
|
|
||||||
/// Used to suppress OS-initiated window minimizes during transient display events.
|
|
||||||
static LAST_DISPLAY_CHANGE_TIMESTAMP: AtomicI64 = AtomicI64::new(0);
|
|
||||||
|
|
||||||
static CHANNEL: OnceLock<(Sender<MonitorNotification>, Receiver<MonitorNotification>)> =
|
static CHANNEL: OnceLock<(Sender<MonitorNotification>, Receiver<MonitorNotification>)> =
|
||||||
OnceLock::new();
|
OnceLock::new();
|
||||||
|
|
||||||
@@ -67,40 +62,11 @@ fn event_rx() -> Receiver<MonitorNotification> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_notification(notification: MonitorNotification) {
|
pub fn send_notification(notification: MonitorNotification) {
|
||||||
if matches!(
|
|
||||||
notification,
|
|
||||||
MonitorNotification::DisplayConnectionChange
|
|
||||||
| MonitorNotification::ResumingFromSuspendedState
|
|
||||||
| MonitorNotification::SessionUnlocked
|
|
||||||
) {
|
|
||||||
let now = std::time::SystemTime::now()
|
|
||||||
.duration_since(std::time::UNIX_EPOCH)
|
|
||||||
.unwrap_or_default()
|
|
||||||
.as_millis() as i64;
|
|
||||||
LAST_DISPLAY_CHANGE_TIMESTAMP.store(now, Ordering::SeqCst);
|
|
||||||
}
|
|
||||||
|
|
||||||
if event_tx().try_send(notification).is_err() {
|
if event_tx().try_send(notification).is_err() {
|
||||||
tracing::warn!("channel is full; dropping notification")
|
tracing::warn!("channel is full; dropping notification")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if a display connection change event was received within the
|
|
||||||
/// last `grace_period` duration. This is used by the event processor to avoid
|
|
||||||
/// treating OS-initiated minimizes (caused by transient monitor disconnects)
|
|
||||||
/// as user-initiated minimizes.
|
|
||||||
pub fn display_change_in_progress(grace_period: std::time::Duration) -> bool {
|
|
||||||
let last = LAST_DISPLAY_CHANGE_TIMESTAMP.load(Ordering::SeqCst);
|
|
||||||
if last == 0 {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
let now = std::time::SystemTime::now()
|
|
||||||
.duration_since(std::time::UNIX_EPOCH)
|
|
||||||
.unwrap_or_default()
|
|
||||||
.as_millis() as i64;
|
|
||||||
(now - last) < grace_period.as_millis() as i64
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_in_monitor_cache(serial_or_device_id: &str, monitor: Monitor) {
|
pub fn insert_in_monitor_cache(serial_or_device_id: &str, monitor: Monitor) {
|
||||||
let dip = DISPLAY_INDEX_PREFERENCES.read();
|
let dip = DISPLAY_INDEX_PREFERENCES.read();
|
||||||
let mut dip_ids = dip.values();
|
let mut dip_ids = dip.values();
|
||||||
@@ -123,41 +89,7 @@ where
|
|||||||
F: Fn() -> I + Copy,
|
F: Fn() -> I + Copy,
|
||||||
I: Iterator<Item = Result<win32_display_data::Device, win32_display_data::Error>>,
|
I: Iterator<Item = Result<win32_display_data::Device, win32_display_data::Error>>,
|
||||||
{
|
{
|
||||||
let mut attempts = 0;
|
let all_displays = display_provider().flatten().collect::<Vec<_>>();
|
||||||
|
|
||||||
let (displays, errors) = loop {
|
|
||||||
let (displays, errors): (Vec<_>, Vec<_>) = display_provider().partition(Result::is_ok);
|
|
||||||
|
|
||||||
if errors.is_empty() {
|
|
||||||
break (displays, errors);
|
|
||||||
}
|
|
||||||
|
|
||||||
for err in &errors {
|
|
||||||
if let Err(e) = err {
|
|
||||||
tracing::warn!(
|
|
||||||
"enumerating display in reconciliator (attempt {}): {:?}",
|
|
||||||
attempts + 1,
|
|
||||||
e
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if attempts < 5 {
|
|
||||||
attempts += 1;
|
|
||||||
std::thread::sleep(std::time::Duration::from_millis(150));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
break (displays, errors);
|
|
||||||
};
|
|
||||||
|
|
||||||
if !errors.is_empty() {
|
|
||||||
return Err(color_eyre::eyre::eyre!(
|
|
||||||
"could not successfully enumerate all displays"
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let all_displays = displays.into_iter().map(Result::unwrap).collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let mut serial_id_map = HashMap::new();
|
let mut serial_id_map = HashMap::new();
|
||||||
|
|
||||||
@@ -271,8 +203,6 @@ where
|
|||||||
border_manager::send_notification(None);
|
border_manager::send_notification(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep reference to Arc for potential re-locking
|
|
||||||
let wm_arc = Arc::clone(&wm);
|
|
||||||
let mut wm = wm.lock();
|
let mut wm = wm.lock();
|
||||||
|
|
||||||
let initial_state = State::from(wm.as_ref());
|
let initial_state = State::from(wm.as_ref());
|
||||||
@@ -416,180 +346,12 @@ where
|
|||||||
continue 'receiver;
|
continue 'receiver;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle potential monitor removal with verification
|
if initial_monitor_count > attached_devices.len() {
|
||||||
let attached_devices = if initial_monitor_count > attached_devices.len() {
|
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
"potential monitor removal detected ({initial_monitor_count} vs {}), verifying in 3s",
|
"monitor count mismatch ({initial_monitor_count} vs {}), removing disconnected monitors",
|
||||||
attached_devices.len()
|
attached_devices.len()
|
||||||
);
|
);
|
||||||
|
|
||||||
// Release locks before waiting
|
|
||||||
drop(wm);
|
|
||||||
drop(monitor_cache);
|
|
||||||
|
|
||||||
// Wait 3 seconds for display state to stabilize
|
|
||||||
std::thread::sleep(std::time::Duration::from_secs(3));
|
|
||||||
|
|
||||||
// Re-query the Win32 display APIs
|
|
||||||
let re_queried_devices = match attached_display_devices(display_provider) {
|
|
||||||
Ok(devices) => devices,
|
|
||||||
Err(e) => {
|
|
||||||
tracing::error!("failed to re-query display devices: {}", e);
|
|
||||||
continue 'receiver;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
tracing::debug!(
|
|
||||||
"after verification: wm had {} monitors, initial query found {}, re-query found {}",
|
|
||||||
initial_monitor_count,
|
|
||||||
attached_devices.len(),
|
|
||||||
re_queried_devices.len()
|
|
||||||
);
|
|
||||||
|
|
||||||
// If monitors are back, the removal was transient (spurious event)
|
|
||||||
// Still try to restore state since windows might have been minimized
|
|
||||||
if re_queried_devices.len() >= initial_monitor_count {
|
|
||||||
tracing::info!(
|
|
||||||
"monitor removal was transient (spurious event), attempting state restoration. Initial: {}, Re-queried: {}",
|
|
||||||
initial_monitor_count,
|
|
||||||
re_queried_devices.len()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Re-acquire locks for state restoration
|
|
||||||
wm = wm_arc.lock();
|
|
||||||
|
|
||||||
// Update Win32 data for all monitors
|
|
||||||
for monitor in wm.monitors_mut() {
|
|
||||||
for attached in &re_queried_devices {
|
|
||||||
let serial_number_ids_match =
|
|
||||||
if let (Some(attached_snid), Some(m_snid)) =
|
|
||||||
(&attached.serial_number_id, &monitor.serial_number_id)
|
|
||||||
{
|
|
||||||
attached_snid.eq(m_snid)
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
};
|
|
||||||
|
|
||||||
if serial_number_ids_match
|
|
||||||
|| attached.device_id.eq(&monitor.device_id)
|
|
||||||
{
|
|
||||||
monitor.id = attached.id;
|
|
||||||
monitor.device = attached.device.clone();
|
|
||||||
monitor.device_id = attached.device_id.clone();
|
|
||||||
monitor.serial_number_id = attached.serial_number_id.clone();
|
|
||||||
monitor.name = attached.name.clone();
|
|
||||||
monitor.size = attached.size;
|
|
||||||
monitor.work_area_size = attached.work_area_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to restore windows that might have been minimized
|
|
||||||
let offset = wm.work_area_offset;
|
|
||||||
for monitor in wm.monitors_mut() {
|
|
||||||
let focused_workspace_idx = monitor.focused_workspace_idx();
|
|
||||||
|
|
||||||
for (idx, workspace) in monitor.workspaces_mut().iter_mut().enumerate()
|
|
||||||
{
|
|
||||||
let is_focused_workspace = idx == focused_workspace_idx;
|
|
||||||
|
|
||||||
if is_focused_workspace {
|
|
||||||
// Restore containers
|
|
||||||
for container in workspace.containers_mut() {
|
|
||||||
if let Some(window) = container.focused_window()
|
|
||||||
&& WindowsApi::is_window(window.hwnd)
|
|
||||||
{
|
|
||||||
tracing::debug!(
|
|
||||||
"restoring window after transient removal: {}",
|
|
||||||
window.hwnd
|
|
||||||
);
|
|
||||||
WindowsApi::restore_window(window.hwnd);
|
|
||||||
} else if let Some(window) = container.focused_window() {
|
|
||||||
tracing::debug!(
|
|
||||||
"skipping restore of invalid window: {}",
|
|
||||||
window.hwnd
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore maximized window
|
|
||||||
if let Some(window) = &workspace.maximized_window
|
|
||||||
&& WindowsApi::is_window(window.hwnd)
|
|
||||||
{
|
|
||||||
WindowsApi::restore_window(window.hwnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore monocle container
|
|
||||||
if let Some(container) = &workspace.monocle_container
|
|
||||||
&& let Some(window) = container.focused_window()
|
|
||||||
&& WindowsApi::is_window(window.hwnd)
|
|
||||||
{
|
|
||||||
WindowsApi::restore_window(window.hwnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore floating windows
|
|
||||||
for window in workspace.floating_windows() {
|
|
||||||
if WindowsApi::is_window(window.hwnd) {
|
|
||||||
WindowsApi::restore_window(window.hwnd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
monitor.update_focused_workspace(offset)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
border_manager::send_notification(None);
|
|
||||||
continue 'receiver;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If monitors are still missing, proceed with actual removal logic
|
|
||||||
tracing::info!(
|
|
||||||
"verified monitor removal ({initial_monitor_count} vs {}), removing disconnected monitors",
|
|
||||||
re_queried_devices.len()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Re-acquire locks for removal processing
|
|
||||||
wm = wm_arc.lock();
|
|
||||||
monitor_cache = MONITOR_CACHE
|
|
||||||
.get_or_init(|| Mutex::new(HashMap::new()))
|
|
||||||
.lock();
|
|
||||||
|
|
||||||
// Make sure that in our state any attached displays have the latest Win32 data
|
|
||||||
// We must do this again because we dropped the lock and are working with new data
|
|
||||||
for monitor in wm.monitors_mut() {
|
|
||||||
for attached in &re_queried_devices {
|
|
||||||
let serial_number_ids_match =
|
|
||||||
if let (Some(attached_snid), Some(m_snid)) =
|
|
||||||
(&attached.serial_number_id, &monitor.serial_number_id)
|
|
||||||
{
|
|
||||||
attached_snid.eq(m_snid)
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
};
|
|
||||||
|
|
||||||
if serial_number_ids_match || attached.device_id.eq(&monitor.device_id)
|
|
||||||
{
|
|
||||||
monitor.id = attached.id;
|
|
||||||
monitor.device = attached.device.clone();
|
|
||||||
monitor.device_id = attached.device_id.clone();
|
|
||||||
monitor.serial_number_id = attached.serial_number_id.clone();
|
|
||||||
monitor.name = attached.name.clone();
|
|
||||||
monitor.size = attached.size;
|
|
||||||
monitor.work_area_size = attached.work_area_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use re-queried devices for remaining logic
|
|
||||||
re_queried_devices
|
|
||||||
} else {
|
|
||||||
attached_devices
|
|
||||||
};
|
|
||||||
|
|
||||||
if initial_monitor_count > attached_devices.len() {
|
|
||||||
tracing::info!("removing disconnected monitors");
|
|
||||||
|
|
||||||
// Windows to remove from `known_hwnds`
|
// Windows to remove from `known_hwnds`
|
||||||
let mut windows_to_remove = Vec::new();
|
let mut windows_to_remove = Vec::new();
|
||||||
|
|
||||||
@@ -822,9 +584,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
if is_focused_workspace {
|
if is_focused_workspace {
|
||||||
if let Some(window) = container.focused_window()
|
if let Some(window) = container.focused_window() {
|
||||||
&& WindowsApi::is_window(window.hwnd)
|
|
||||||
{
|
|
||||||
tracing::debug!(
|
tracing::debug!(
|
||||||
"restoring window: {}",
|
"restoring window: {}",
|
||||||
window.hwnd
|
window.hwnd
|
||||||
@@ -836,9 +596,7 @@ where
|
|||||||
// first window and show that one
|
// first window and show that one
|
||||||
container.focus_window(0);
|
container.focus_window(0);
|
||||||
|
|
||||||
if let Some(window) = container.focused_window()
|
if let Some(window) = container.focused_window() {
|
||||||
&& WindowsApi::is_window(window.hwnd)
|
|
||||||
{
|
|
||||||
WindowsApi::restore_window(window.hwnd);
|
WindowsApi::restore_window(window.hwnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -859,9 +617,7 @@ where
|
|||||||
|| known_hwnds.contains_key(&window.hwnd)
|
|| known_hwnds.contains_key(&window.hwnd)
|
||||||
{
|
{
|
||||||
workspace.maximized_window = None;
|
workspace.maximized_window = None;
|
||||||
} else if is_focused_workspace
|
} else if is_focused_workspace {
|
||||||
&& WindowsApi::is_window(window.hwnd)
|
|
||||||
{
|
|
||||||
WindowsApi::restore_window(window.hwnd);
|
WindowsApi::restore_window(window.hwnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -875,9 +631,7 @@ where
|
|||||||
if container.windows().is_empty() {
|
if container.windows().is_empty() {
|
||||||
workspace.monocle_container = None;
|
workspace.monocle_container = None;
|
||||||
} else if is_focused_workspace {
|
} else if is_focused_workspace {
|
||||||
if let Some(window) = container.focused_window()
|
if let Some(window) = container.focused_window() {
|
||||||
&& WindowsApi::is_window(window.hwnd)
|
|
||||||
{
|
|
||||||
WindowsApi::restore_window(window.hwnd);
|
WindowsApi::restore_window(window.hwnd);
|
||||||
} else {
|
} else {
|
||||||
// If the focused window was moved or removed by
|
// If the focused window was moved or removed by
|
||||||
@@ -885,9 +639,7 @@ where
|
|||||||
// first window and show that one
|
// first window and show that one
|
||||||
container.focus_window(0);
|
container.focus_window(0);
|
||||||
|
|
||||||
if let Some(window) = container.focused_window()
|
if let Some(window) = container.focused_window() {
|
||||||
&& WindowsApi::is_window(window.hwnd)
|
|
||||||
{
|
|
||||||
WindowsApi::restore_window(window.hwnd);
|
WindowsApi::restore_window(window.hwnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -901,11 +653,9 @@ where
|
|||||||
|
|
||||||
if is_focused_workspace {
|
if is_focused_workspace {
|
||||||
for window in workspace.floating_windows() {
|
for window in workspace.floating_windows() {
|
||||||
if WindowsApi::is_window(window.hwnd) {
|
|
||||||
WindowsApi::restore_window(window.hwnd);
|
WindowsApi::restore_window(window.hwnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Apply workspace rules
|
// Apply workspace rules
|
||||||
let mut workspace_matching_rules =
|
let mut workspace_matching_rules =
|
||||||
|
|||||||
@@ -60,11 +60,9 @@ use crate::core::Axis;
|
|||||||
use crate::core::BorderImplementation;
|
use crate::core::BorderImplementation;
|
||||||
use crate::core::FocusFollowsMouseImplementation;
|
use crate::core::FocusFollowsMouseImplementation;
|
||||||
use crate::core::Layout;
|
use crate::core::Layout;
|
||||||
use crate::core::LayoutOptions;
|
|
||||||
use crate::core::MoveBehaviour;
|
use crate::core::MoveBehaviour;
|
||||||
use crate::core::OperationDirection;
|
use crate::core::OperationDirection;
|
||||||
use crate::core::Rect;
|
use crate::core::Rect;
|
||||||
use crate::core::ScrollingLayoutOptions;
|
|
||||||
use crate::core::Sizing;
|
use crate::core::Sizing;
|
||||||
use crate::core::SocketMessage;
|
use crate::core::SocketMessage;
|
||||||
use crate::core::StateQuery;
|
use crate::core::StateQuery;
|
||||||
@@ -74,6 +72,8 @@ use crate::core::config_generation::IdWithIdentifier;
|
|||||||
use crate::core::config_generation::MatchingRule;
|
use crate::core::config_generation::MatchingRule;
|
||||||
use crate::core::config_generation::MatchingStrategy;
|
use crate::core::config_generation::MatchingStrategy;
|
||||||
use crate::current_virtual_desktop;
|
use crate::current_virtual_desktop;
|
||||||
|
use crate::default_layout::LayoutOptions;
|
||||||
|
use crate::default_layout::ScrollingLayoutOptions;
|
||||||
use crate::monitor::MonitorInformation;
|
use crate::monitor::MonitorInformation;
|
||||||
use crate::notify_subscribers;
|
use crate::notify_subscribers;
|
||||||
use crate::stackbar_manager;
|
use crate::stackbar_manager;
|
||||||
@@ -947,8 +947,6 @@ impl WindowManager {
|
|||||||
center_focused_column: Default::default(),
|
center_focused_column: Default::default(),
|
||||||
}),
|
}),
|
||||||
grid: None,
|
grid: None,
|
||||||
column_ratios: None,
|
|
||||||
row_ratios: None,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -957,29 +955,6 @@ impl WindowManager {
|
|||||||
}
|
}
|
||||||
SocketMessage::ChangeLayout(layout) => self.change_workspace_layout_default(layout)?,
|
SocketMessage::ChangeLayout(layout) => self.change_workspace_layout_default(layout)?,
|
||||||
SocketMessage::CycleLayout(direction) => self.cycle_layout(direction)?,
|
SocketMessage::CycleLayout(direction) => self.cycle_layout(direction)?,
|
||||||
SocketMessage::LayoutRatios(ref columns, ref rows) => {
|
|
||||||
use crate::core::validate_ratios;
|
|
||||||
|
|
||||||
let focused_workspace = self.focused_workspace_mut()?;
|
|
||||||
|
|
||||||
let mut options = focused_workspace.layout_options.unwrap_or(LayoutOptions {
|
|
||||||
scrolling: None,
|
|
||||||
grid: None,
|
|
||||||
column_ratios: None,
|
|
||||||
row_ratios: None,
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Some(cols) = columns {
|
|
||||||
options.column_ratios = Some(validate_ratios(cols));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(rws) = rows {
|
|
||||||
options.row_ratios = Some(validate_ratios(rws));
|
|
||||||
}
|
|
||||||
|
|
||||||
focused_workspace.layout_options = Some(options);
|
|
||||||
self.update_focused_workspace(false, false)?;
|
|
||||||
}
|
|
||||||
SocketMessage::ChangeLayoutCustom(ref path) => {
|
SocketMessage::ChangeLayoutCustom(ref path) => {
|
||||||
self.change_workspace_custom_layout(path)?;
|
self.change_workspace_custom_layout(path)?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -266,20 +266,6 @@ impl WindowManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
WindowManagerEvent::Minimize(_, window) => {
|
WindowManagerEvent::Minimize(_, window) => {
|
||||||
// During transient display connection changes (e.g. monitor
|
|
||||||
// briefly disconnecting and reconnecting), Windows may fire
|
|
||||||
// SystemMinimizeStart for windows on the affected monitor.
|
|
||||||
// We must not treat these OS-initiated minimizes as user
|
|
||||||
// actions, otherwise the window gets removed from the
|
|
||||||
// workspace and the reconciliator cannot restore it.
|
|
||||||
if crate::monitor_reconciliator::display_change_in_progress(
|
|
||||||
std::time::Duration::from_secs(10),
|
|
||||||
) {
|
|
||||||
tracing::debug!(
|
|
||||||
"ignoring minimize during display connection change for hwnd: {}",
|
|
||||||
window.hwnd
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
let mut hide = false;
|
let mut hide = false;
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -294,7 +280,6 @@ impl WindowManager {
|
|||||||
self.update_focused_workspace(false, false)?;
|
self.update_focused_workspace(false, false)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
WindowManagerEvent::Hide(_, window) => {
|
WindowManagerEvent::Hide(_, window) => {
|
||||||
let mut hide = false;
|
let mut hide = false;
|
||||||
// Some major applications unfortunately send the HIDE signal when they are being
|
// Some major applications unfortunately send the HIDE signal when they are being
|
||||||
@@ -446,24 +431,6 @@ impl WindowManager {
|
|||||||
proceed = false;
|
proceed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// after enforce_workspace_rules() has run, check if window exists in ANY workspace
|
|
||||||
// to prevent duplication when workspace rules move windows across workspaces
|
|
||||||
if proceed {
|
|
||||||
let window_already_managed = self
|
|
||||||
.monitors()
|
|
||||||
.iter()
|
|
||||||
.flat_map(|m| m.workspaces())
|
|
||||||
.any(|ws| ws.contains_window(window.hwnd));
|
|
||||||
|
|
||||||
if window_already_managed {
|
|
||||||
tracing::debug!(
|
|
||||||
"skipping window addition, already managed after workspace rule enforcement"
|
|
||||||
);
|
|
||||||
|
|
||||||
proceed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if proceed {
|
if proceed {
|
||||||
let behaviour = self.window_management_behaviour(
|
let behaviour = self.window_management_behaviour(
|
||||||
focused_monitor_idx,
|
focused_monitor_idx,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use crate::DATA_DIR;
|
|||||||
use crate::DEFAULT_CONTAINER_PADDING;
|
use crate::DEFAULT_CONTAINER_PADDING;
|
||||||
use crate::DEFAULT_MOUSE_FOLLOWS_FOCUS;
|
use crate::DEFAULT_MOUSE_FOLLOWS_FOCUS;
|
||||||
use crate::DEFAULT_RESIZE_DELTA;
|
use crate::DEFAULT_RESIZE_DELTA;
|
||||||
|
use crate::DEFAULT_WORKSPACE_LAYOUT;
|
||||||
use crate::DEFAULT_WORKSPACE_PADDING;
|
use crate::DEFAULT_WORKSPACE_PADDING;
|
||||||
use crate::DISPLAY_INDEX_PREFERENCES;
|
use crate::DISPLAY_INDEX_PREFERENCES;
|
||||||
use crate::FLOATING_APPLICATIONS;
|
use crate::FLOATING_APPLICATIONS;
|
||||||
@@ -53,7 +54,6 @@ use crate::core::DefaultLayout;
|
|||||||
use crate::core::FocusFollowsMouseImplementation;
|
use crate::core::FocusFollowsMouseImplementation;
|
||||||
use crate::core::HidingBehaviour;
|
use crate::core::HidingBehaviour;
|
||||||
use crate::core::Layout;
|
use crate::core::Layout;
|
||||||
use crate::core::LayoutOptions;
|
|
||||||
use crate::core::MoveBehaviour;
|
use crate::core::MoveBehaviour;
|
||||||
use crate::core::OperationBehaviour;
|
use crate::core::OperationBehaviour;
|
||||||
use crate::core::Rect;
|
use crate::core::Rect;
|
||||||
@@ -68,6 +68,7 @@ use crate::core::config_generation::ApplicationOptions;
|
|||||||
use crate::core::config_generation::MatchingRule;
|
use crate::core::config_generation::MatchingRule;
|
||||||
use crate::core::config_generation::MatchingStrategy;
|
use crate::core::config_generation::MatchingStrategy;
|
||||||
use crate::current_virtual_desktop;
|
use crate::current_virtual_desktop;
|
||||||
|
use crate::default_layout::LayoutOptions;
|
||||||
use crate::monitor;
|
use crate::monitor;
|
||||||
use crate::monitor::Monitor;
|
use crate::monitor::Monitor;
|
||||||
use crate::monitor_reconciliator;
|
use crate::monitor_reconciliator;
|
||||||
@@ -325,13 +326,7 @@ impl From<&Workspace> for WorkspaceConfig {
|
|||||||
Layout::Custom(_) => None,
|
Layout::Custom(_) => None,
|
||||||
})
|
})
|
||||||
.flatten(),
|
.flatten(),
|
||||||
layout_options: {
|
layout_options: value.layout_options,
|
||||||
tracing::debug!(
|
|
||||||
"Parsing workspace config - layout_options: {:?}",
|
|
||||||
value.layout_options
|
|
||||||
);
|
|
||||||
value.layout_options
|
|
||||||
},
|
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
custom_layout: value
|
custom_layout: value
|
||||||
.workspace_config
|
.workspace_config
|
||||||
@@ -563,6 +558,11 @@ pub struct StaticConfig {
|
|||||||
/// Individual window transparency ignore rules
|
/// Individual window transparency ignore rules
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub transparency_ignore_rules: Option<Vec<MatchingRule>>,
|
pub transparency_ignore_rules: Option<Vec<MatchingRule>>,
|
||||||
|
/// Global default workspace layout for new workspaces
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
#[cfg_attr(feature = "schemars", schemars(extend("default" = DefaultLayout::BSP)))]
|
||||||
|
#[serde(deserialize_with = "crate::default_layout::deserialize_option_none_default_layout")]
|
||||||
|
pub default_workspace_layout: Option<DefaultLayout>,
|
||||||
/// Global default workspace padding
|
/// Global default workspace padding
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
#[cfg_attr(feature = "schemars", schemars(extend("default" = DEFAULT_WORKSPACE_PADDING)))]
|
#[cfg_attr(feature = "schemars", schemars(extend("default" = DEFAULT_WORKSPACE_PADDING)))]
|
||||||
@@ -913,6 +913,7 @@ impl From<&WindowManager> for StaticConfig {
|
|||||||
remove_titlebar_applications: Option::from(NO_TITLEBAR.lock().clone()),
|
remove_titlebar_applications: Option::from(NO_TITLEBAR.lock().clone()),
|
||||||
floating_window_aspect_ratio: Option::from(*FLOATING_WINDOW_TOGGLE_ASPECT_RATIO.lock()),
|
floating_window_aspect_ratio: Option::from(*FLOATING_WINDOW_TOGGLE_ASPECT_RATIO.lock()),
|
||||||
window_handling_behaviour: Option::from(WINDOW_HANDLING_BEHAVIOUR.load()),
|
window_handling_behaviour: Option::from(WINDOW_HANDLING_BEHAVIOUR.load()),
|
||||||
|
default_workspace_layout: DEFAULT_WORKSPACE_LAYOUT.load(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -991,6 +992,8 @@ impl StaticConfig {
|
|||||||
DEFAULT_CONTAINER_PADDING.store(container, Ordering::SeqCst);
|
DEFAULT_CONTAINER_PADDING.store(container, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFAULT_WORKSPACE_LAYOUT.store(self.default_workspace_layout);
|
||||||
|
|
||||||
if let Some(workspace) = self.default_workspace_padding {
|
if let Some(workspace) = self.default_workspace_padding {
|
||||||
DEFAULT_WORKSPACE_PADDING.store(workspace, Ordering::SeqCst);
|
DEFAULT_WORKSPACE_PADDING.store(workspace, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
@@ -1919,7 +1922,7 @@ mod tests {
|
|||||||
let docs = vec![
|
let docs = vec![
|
||||||
"0.1.20", "0.1.21", "0.1.22", "0.1.23", "0.1.24", "0.1.25", "0.1.26", "0.1.27",
|
"0.1.20", "0.1.21", "0.1.22", "0.1.23", "0.1.24", "0.1.25", "0.1.26", "0.1.27",
|
||||||
"0.1.28", "0.1.29", "0.1.30", "0.1.31", "0.1.32", "0.1.33", "0.1.34", "0.1.35",
|
"0.1.28", "0.1.29", "0.1.30", "0.1.31", "0.1.32", "0.1.33", "0.1.34", "0.1.35",
|
||||||
"0.1.36", "0.1.37", "0.1.38", "0.1.39",
|
"0.1.36", "0.1.37", "0.1.38",
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut versions = vec![];
|
let mut versions = vec![];
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ use crate::animation::AnimationEngine;
|
|||||||
use crate::core::Arrangement;
|
use crate::core::Arrangement;
|
||||||
use crate::core::Axis;
|
use crate::core::Axis;
|
||||||
use crate::core::BorderImplementation;
|
use crate::core::BorderImplementation;
|
||||||
use crate::core::CustomLayout;
|
|
||||||
use crate::core::CycleDirection;
|
use crate::core::CycleDirection;
|
||||||
use crate::core::DefaultLayout;
|
use crate::core::DefaultLayout;
|
||||||
use crate::core::FocusFollowsMouseImplementation;
|
use crate::core::FocusFollowsMouseImplementation;
|
||||||
@@ -41,6 +40,7 @@ use crate::core::Sizing;
|
|||||||
use crate::core::WindowContainerBehaviour;
|
use crate::core::WindowContainerBehaviour;
|
||||||
use crate::core::WindowManagementBehaviour;
|
use crate::core::WindowManagementBehaviour;
|
||||||
use crate::core::config_generation::MatchingRule;
|
use crate::core::config_generation::MatchingRule;
|
||||||
|
use crate::core::custom_layout::CustomLayout;
|
||||||
|
|
||||||
use crate::CrossBoundaryBehaviour;
|
use crate::CrossBoundaryBehaviour;
|
||||||
use crate::DATA_DIR;
|
use crate::DATA_DIR;
|
||||||
@@ -243,16 +243,14 @@ impl WindowManager {
|
|||||||
if let Some(state_monitor) = state.monitors.elements().get(monitor_idx)
|
if let Some(state_monitor) = state.monitors.elements().get(monitor_idx)
|
||||||
&& let Some(state_workspace) = state_monitor.workspaces().get(workspace_idx)
|
&& let Some(state_workspace) = state_monitor.workspaces().get(workspace_idx)
|
||||||
{
|
{
|
||||||
// to make sure padding and layout_options changes get applied for users after a quick restart
|
// to make sure padding changes get applied for users after a quick restart
|
||||||
let container_padding = workspace.container_padding;
|
let container_padding = workspace.container_padding;
|
||||||
let workspace_padding = workspace.workspace_padding;
|
let workspace_padding = workspace.workspace_padding;
|
||||||
let layout_options = workspace.layout_options;
|
|
||||||
|
|
||||||
*workspace = state_workspace.clone();
|
*workspace = state_workspace.clone();
|
||||||
|
|
||||||
workspace.container_padding = container_padding;
|
workspace.container_padding = container_padding;
|
||||||
workspace.workspace_padding = workspace_padding;
|
workspace.workspace_padding = workspace_padding;
|
||||||
workspace.layout_options = layout_options;
|
|
||||||
|
|
||||||
if state_monitor.focused_workspace_idx() == workspace_idx {
|
if state_monitor.focused_workspace_idx() == workspace_idx {
|
||||||
focused_workspace = workspace_idx;
|
focused_workspace = workspace_idx;
|
||||||
@@ -3878,6 +3876,7 @@ impl WindowManager {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::DEFAULT_WORKSPACE_LAYOUT;
|
||||||
use crate::monitor;
|
use crate::monitor;
|
||||||
use crossbeam_channel::Sender;
|
use crossbeam_channel::Sender;
|
||||||
use crossbeam_channel::bounded;
|
use crossbeam_channel::bounded;
|
||||||
@@ -5204,6 +5203,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_toggle_tiling() {
|
fn test_toggle_tiling() {
|
||||||
let (mut wm, _context) = setup_window_manager();
|
let (mut wm, _context) = setup_window_manager();
|
||||||
|
DEFAULT_WORKSPACE_LAYOUT.store(Some(DefaultLayout::BSP));
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut m = monitor::new(
|
let mut m = monitor::new(
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use std::sync::atomic::Ordering;
|
|||||||
|
|
||||||
use crate::DATA_DIR;
|
use crate::DATA_DIR;
|
||||||
use crate::DEFAULT_CONTAINER_PADDING;
|
use crate::DEFAULT_CONTAINER_PADDING;
|
||||||
|
use crate::DEFAULT_WORKSPACE_LAYOUT;
|
||||||
use crate::DEFAULT_WORKSPACE_PADDING;
|
use crate::DEFAULT_WORKSPACE_PADDING;
|
||||||
use crate::FloatingLayerBehaviour;
|
use crate::FloatingLayerBehaviour;
|
||||||
use crate::INITIAL_CONFIGURATION_LOADED;
|
use crate::INITIAL_CONFIGURATION_LOADED;
|
||||||
@@ -25,9 +26,9 @@ use crate::core::CustomLayout;
|
|||||||
use crate::core::CycleDirection;
|
use crate::core::CycleDirection;
|
||||||
use crate::core::DefaultLayout;
|
use crate::core::DefaultLayout;
|
||||||
use crate::core::Layout;
|
use crate::core::Layout;
|
||||||
use crate::core::LayoutOptions;
|
|
||||||
use crate::core::OperationDirection;
|
use crate::core::OperationDirection;
|
||||||
use crate::core::Rect;
|
use crate::core::Rect;
|
||||||
|
use crate::default_layout::LayoutOptions;
|
||||||
use crate::lockable_sequence::LockableSequence;
|
use crate::lockable_sequence::LockableSequence;
|
||||||
use crate::ring::Ring;
|
use crate::ring::Ring;
|
||||||
use crate::should_act;
|
use crate::should_act;
|
||||||
@@ -107,6 +108,8 @@ impl_ring_elements!(Workspace, Window, "floating_window");
|
|||||||
|
|
||||||
impl Default for Workspace {
|
impl Default for Workspace {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
let default_layout = DEFAULT_WORKSPACE_LAYOUT.load();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
name: None,
|
name: None,
|
||||||
containers: Ring::default(),
|
containers: Ring::default(),
|
||||||
@@ -115,7 +118,7 @@ impl Default for Workspace {
|
|||||||
maximized_window_restore_idx: None,
|
maximized_window_restore_idx: None,
|
||||||
monocle_container_restore_idx: None,
|
monocle_container_restore_idx: None,
|
||||||
floating_windows: Ring::default(),
|
floating_windows: Ring::default(),
|
||||||
layout: Layout::Default(DefaultLayout::BSP),
|
layout: Layout::Default(default_layout.unwrap_or(DefaultLayout::BSP)),
|
||||||
layout_options: None,
|
layout_options: None,
|
||||||
layout_rules: vec![],
|
layout_rules: vec![],
|
||||||
layout_flip: None,
|
layout_flip: None,
|
||||||
@@ -123,7 +126,7 @@ impl Default for Workspace {
|
|||||||
container_padding: Option::from(DEFAULT_CONTAINER_PADDING.load(Ordering::SeqCst)),
|
container_padding: Option::from(DEFAULT_CONTAINER_PADDING.load(Ordering::SeqCst)),
|
||||||
latest_layout: vec![],
|
latest_layout: vec![],
|
||||||
resize_dimensions: vec![],
|
resize_dimensions: vec![],
|
||||||
tile: true,
|
tile: default_layout.is_some(),
|
||||||
work_area_offset: None,
|
work_area_offset: None,
|
||||||
apply_window_based_work_area_offset: true,
|
apply_window_based_work_area_offset: true,
|
||||||
window_container_behaviour: None,
|
window_container_behaviour: None,
|
||||||
@@ -242,12 +245,6 @@ impl Workspace {
|
|||||||
self.wallpaper = config.wallpaper.clone();
|
self.wallpaper = config.wallpaper.clone();
|
||||||
self.layout_options = config.layout_options;
|
self.layout_options = config.layout_options;
|
||||||
|
|
||||||
tracing::debug!(
|
|
||||||
"Workspace '{}' loaded layout_options: {:?}",
|
|
||||||
self.name.as_deref().unwrap_or("unnamed"),
|
|
||||||
self.layout_options
|
|
||||||
);
|
|
||||||
|
|
||||||
self.workspace_config = Some(config.clone());
|
self.workspace_config = Some(config.clone());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -556,11 +553,6 @@ impl Workspace {
|
|||||||
} else if let Some(window) = &mut self.maximized_window {
|
} else if let Some(window) = &mut self.maximized_window {
|
||||||
window.maximize();
|
window.maximize();
|
||||||
} else if !self.containers().is_empty() {
|
} else if !self.containers().is_empty() {
|
||||||
tracing::debug!(
|
|
||||||
"Workspace '{}' update() - self.layout_options before calculate: {:?}",
|
|
||||||
self.name.as_deref().unwrap_or("unnamed"),
|
|
||||||
self.layout_options
|
|
||||||
);
|
|
||||||
let mut layouts = self.layout.as_boxed_arrangement().calculate(
|
let mut layouts = self.layout.as_boxed_arrangement().calculate(
|
||||||
&adjusted_work_area,
|
&adjusted_work_area,
|
||||||
NonZeroUsize::new(self.containers().len()).ok_or_eyre(
|
NonZeroUsize::new(self.containers().len()).ok_or_eyre(
|
||||||
|
|||||||
@@ -1001,16 +1001,6 @@ struct ScrollingLayoutColumns {
|
|||||||
count: NonZeroUsize,
|
count: NonZeroUsize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Parser)]
|
|
||||||
struct LayoutRatios {
|
|
||||||
/// Column width ratios (space-separated values between 0.1 and 0.9)
|
|
||||||
#[clap(short, long, num_args = 1..)]
|
|
||||||
columns: Option<Vec<f32>>,
|
|
||||||
/// Row height ratios (space-separated values between 0.1 and 0.9)
|
|
||||||
#[clap(short, long, num_args = 1..)]
|
|
||||||
rows: Option<Vec<f32>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
struct License {
|
struct License {
|
||||||
/// Email address associated with an Individual Commercial Use License
|
/// Email address associated with an Individual Commercial Use License
|
||||||
@@ -1277,8 +1267,6 @@ enum SubCommand {
|
|||||||
/// Set the number of visible columns for the Scrolling layout on the focused workspace
|
/// Set the number of visible columns for the Scrolling layout on the focused workspace
|
||||||
#[clap(arg_required_else_help = true)]
|
#[clap(arg_required_else_help = true)]
|
||||||
ScrollingLayoutColumns(ScrollingLayoutColumns),
|
ScrollingLayoutColumns(ScrollingLayoutColumns),
|
||||||
/// Set the layout column and row ratios for the focused workspace
|
|
||||||
LayoutRatios(LayoutRatios),
|
|
||||||
/// Load a custom layout from file for the focused workspace
|
/// Load a custom layout from file for the focused workspace
|
||||||
#[clap(hide = true)]
|
#[clap(hide = true)]
|
||||||
#[clap(arg_required_else_help = true)]
|
#[clap(arg_required_else_help = true)]
|
||||||
@@ -2946,15 +2934,6 @@ if (Get-Command Get-CimInstance -ErrorAction SilentlyContinue) {
|
|||||||
SubCommand::ScrollingLayoutColumns(args) => {
|
SubCommand::ScrollingLayoutColumns(args) => {
|
||||||
send_message(&SocketMessage::ScrollingLayoutColumns(args.count))?;
|
send_message(&SocketMessage::ScrollingLayoutColumns(args.count))?;
|
||||||
}
|
}
|
||||||
SubCommand::LayoutRatios(args) => {
|
|
||||||
if args.columns.is_none() && args.rows.is_none() {
|
|
||||||
println!(
|
|
||||||
"No ratios provided, nothing to change. Use --columns or --rows to specify ratios."
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
send_message(&SocketMessage::LayoutRatios(args.columns, args.rows))?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SubCommand::LoadCustomLayout(args) => {
|
SubCommand::LoadCustomLayout(args) => {
|
||||||
send_message(&SocketMessage::ChangeLayoutCustom(args.path))?;
|
send_message(&SocketMessage::ChangeLayoutCustom(args.path))?;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-92
@@ -59,7 +59,7 @@
|
|||||||
"null"
|
"null"
|
||||||
],
|
],
|
||||||
"format": "float",
|
"format": "float",
|
||||||
"default": 50
|
"default": 50.0
|
||||||
},
|
},
|
||||||
"icon_scale": {
|
"icon_scale": {
|
||||||
"description": "Scale of the icons relative to the font_size [[1.0-2.0]]",
|
"description": "Scale of the icons relative to the font_size [[1.0-2.0]]",
|
||||||
@@ -3863,17 +3863,6 @@
|
|||||||
"description": "Media widget configuration",
|
"description": "Media widget configuration",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"display": {
|
|
||||||
"description": "Display format of the media widget (defaults to IconAndText)",
|
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/$defs/MediaDisplayFormat"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enable": {
|
"enable": {
|
||||||
"description": "Enable the Media widget",
|
"description": "Enable the Media widget",
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
@@ -3883,46 +3872,6 @@
|
|||||||
"enable"
|
"enable"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"MediaDisplayFormat": {
|
|
||||||
"description": "Media widget display format",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"description": "Show only the media info icon",
|
|
||||||
"type": "string",
|
|
||||||
"const": "Icon"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Show only the media info text (artist - title)",
|
|
||||||
"type": "string",
|
|
||||||
"const": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Show both icon and text",
|
|
||||||
"type": "string",
|
|
||||||
"const": "IconAndText"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Show only the control buttons (previous, play/pause, next)",
|
|
||||||
"type": "string",
|
|
||||||
"const": "ControlsOnly"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Show icon with control buttons",
|
|
||||||
"type": "string",
|
|
||||||
"const": "IconAndControls"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Show text with control buttons",
|
|
||||||
"type": "string",
|
|
||||||
"const": "TextAndControls"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Show icon, text, and control buttons",
|
|
||||||
"type": "string",
|
|
||||||
"const": "Full"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"MemoryConfig": {
|
"MemoryConfig": {
|
||||||
"description": "Memory widget configuration",
|
"description": "Memory widget configuration",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@@ -5417,46 +5366,6 @@
|
|||||||
"content"
|
"content"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"content": {
|
|
||||||
"type": "array",
|
|
||||||
"maxItems": 2,
|
|
||||||
"minItems": 2,
|
|
||||||
"prefixItems": [
|
|
||||||
{
|
|
||||||
"type": [
|
|
||||||
"array",
|
|
||||||
"null"
|
|
||||||
],
|
|
||||||
"items": {
|
|
||||||
"type": "number",
|
|
||||||
"format": "float"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": [
|
|
||||||
"array",
|
|
||||||
"null"
|
|
||||||
],
|
|
||||||
"items": {
|
|
||||||
"type": "number",
|
|
||||||
"format": "float"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"type": "string",
|
|
||||||
"const": "LayoutRatios"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"type",
|
|
||||||
"content"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|||||||
+12
-34
@@ -152,6 +152,18 @@
|
|||||||
"format": "int32",
|
"format": "int32",
|
||||||
"default": 10
|
"default": 10
|
||||||
},
|
},
|
||||||
|
"default_workspace_layout": {
|
||||||
|
"description": "Global default workspace layout for new workspaces",
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/DefaultLayout"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": "BSP"
|
||||||
|
},
|
||||||
"default_workspace_padding": {
|
"default_workspace_padding": {
|
||||||
"description": "Global default workspace padding",
|
"description": "Global default workspace padding",
|
||||||
"type": [
|
"type": [
|
||||||
@@ -3294,23 +3306,6 @@
|
|||||||
"description": "Options for specific layouts",
|
"description": "Options for specific layouts",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"column_ratios": {
|
|
||||||
"description": "Column width ratios (up to MAX_RATIOS values between 0.1 and 0.9)\n\n- Used by Columns layout: ratios for each column width\n- Used by Grid layout: ratios for column widths\n- Used by BSP, VerticalStack, RightMainVerticalStack: column_ratios[0] as primary split ratio\n- Used by HorizontalStack: column_ratios[0] as primary split ratio (top area height)\n- Used by UltrawideVerticalStack: column_ratios[0] as center ratio, column_ratios[1] as left ratio\n\nColumns without a ratio share remaining space equally.\nExample: `[0.3, 0.4, 0.3]` for 30%-40%-30% columns",
|
|
||||||
"type": [
|
|
||||||
"array",
|
|
||||||
"null"
|
|
||||||
],
|
|
||||||
"default": null,
|
|
||||||
"items": {
|
|
||||||
"type": [
|
|
||||||
"number",
|
|
||||||
"null"
|
|
||||||
],
|
|
||||||
"format": "float"
|
|
||||||
},
|
|
||||||
"maxItems": 5,
|
|
||||||
"minItems": 5
|
|
||||||
},
|
|
||||||
"grid": {
|
"grid": {
|
||||||
"description": "Options related to the Grid layout",
|
"description": "Options related to the Grid layout",
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
@@ -3322,23 +3317,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"row_ratios": {
|
|
||||||
"description": "Row height ratios (up to MAX_RATIOS values between 0.1 and 0.9)\n\n- Used by Rows layout: ratios for each row height\n- Used by Grid layout: ratios for row heights\n\nRows without a ratio share remaining space equally.\nExample: `[0.5, 0.5]` for 50%-50% rows",
|
|
||||||
"type": [
|
|
||||||
"array",
|
|
||||||
"null"
|
|
||||||
],
|
|
||||||
"default": null,
|
|
||||||
"items": {
|
|
||||||
"type": [
|
|
||||||
"number",
|
|
||||||
"null"
|
|
||||||
],
|
|
||||||
"format": "float"
|
|
||||||
},
|
|
||||||
"maxItems": 5,
|
|
||||||
"minItems": 5
|
|
||||||
},
|
|
||||||
"scrolling": {
|
"scrolling": {
|
||||||
"description": "Options related to the Scrolling layout",
|
"description": "Options related to the Scrolling layout",
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
|
|||||||
Reference in New Issue
Block a user