Compare commits

..

1 Commits

Author SHA1 Message Date
LGUG2Z
7a02b4e28c feat(wm): remove scrolling layout column fallbacks
This commit removes the fallback to the columns layout when the number
of columns on the scrolling layout is less than 3.
2025-10-13 14:56:34 -07:00
33 changed files with 938 additions and 1759 deletions

View File

@@ -13,8 +13,8 @@ on:
- hotfix/*
tags:
- v*
# schedule:
# - cron: "30 0 * * 0" # Every day at 00:30 UTC
schedule:
- cron: "30 0 * * 0" # Every day at 00:30 UTC
workflow_dispatch:
jobs:
@@ -65,7 +65,7 @@ jobs:
- run: |
cargo install cargo-wix
cargo wix --no-build -p komorebi --nocapture -I .\wix\main.wxs --target ${{ matrix.platform.target }}
- uses: actions/upload-artifact@v5
- uses: actions/upload-artifact@v4
with:
name: komorebi-${{ matrix.platform.target }}-${{ github.sha }}
path: |
@@ -87,7 +87,7 @@ jobs:
fetch-depth: 0
- shell: bash
run: echo "VERSION=nightly" >> $GITHUB_ENV
- uses: actions/download-artifact@v6
- uses: actions/download-artifact@v5
- 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
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: |
TAG=${{ github.event.release.tag_name }}
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
- uses: actions/download-artifact@v6
- uses: actions/download-artifact@v5
- 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
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: |
TAG=${{ github.ref_name }}
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
- uses: actions/download-artifact@v6
- uses: actions/download-artifact@v5
- 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
Copy-Item ./komorebi-x86_64-pc-windows-msvc-${{ github.sha }}/wix/*x86_64.msi -Destination ./komorebi-$Env:VERSION-x86_64.msi

1026
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -22,7 +22,6 @@ ignore = [
allow = [
"0BSD",
"Apache-2.0",
"Apache-2.0 WITH LLVM-exception",
"Artistic-2.0",
"BSD-2-Clause",
"BSD-3-Clause",

View File

@@ -35,53 +35,46 @@
"backtrace 0.3.76 registry+https://github.com/rust-lang/crates.io-index",
"backtrace-ext 0.2.1 registry+https://github.com/rust-lang/crates.io-index",
"base16_color_scheme 0.3.2 git+https://github.com/LGUG2Z/base16_color_scheme",
"base64 0.21.7 registry+https://github.com/rust-lang/crates.io-index",
"base64 0.22.1 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",
"bitflags 1.3.2 registry+https://github.com/rust-lang/crates.io-index",
"bitflags 2.10.0 registry+https://github.com/rust-lang/crates.io-index",
"bitflags 2.9.4 registry+https://github.com/rust-lang/crates.io-index",
"bitstream-io 2.6.0 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.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",
"cc 1.2.43 registry+https://github.com/rust-lang/crates.io-index",
"cc 1.2.40 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.3 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",
"clap 4.5.50 registry+https://github.com/rust-lang/crates.io-index",
"clap_builder 4.5.50 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 0.7.6 registry+https://github.com/rust-lang/crates.io-index",
"clap 4.5.48 registry+https://github.com/rust-lang/crates.io-index",
"clap_builder 4.5.48 registry+https://github.com/rust-lang/crates.io-index",
"clap_derive 4.5.47 registry+https://github.com/rust-lang/crates.io-index",
"clap_lex 0.7.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",
"colorchoice 1.0.4 registry+https://github.com/rust-lang/crates.io-index",
"cpufeatures 0.2.17 registry+https://github.com/rust-lang/crates.io-index",
"crc32fast 1.5.0 registry+https://github.com/rust-lang/crates.io-index",
"crossbeam-channel 0.5.15 registry+https://github.com/rust-lang/crates.io-index",
"crossbeam-deque 0.8.6 registry+https://github.com/rust-lang/crates.io-index",
"crossbeam-epoch 0.9.18 registry+https://github.com/rust-lang/crates.io-index",
"crossbeam-utils 0.8.21 registry+https://github.com/rust-lang/crates.io-index",
"crypto-common 0.1.6 registry+https://github.com/rust-lang/crates.io-index",
"ctrlc 3.5.1 registry+https://github.com/rust-lang/crates.io-index",
"ctrlc 3.5.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",
"deflate 0.8.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",
"deranged 0.5.4 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 6.0.0 registry+https://github.com/rust-lang/crates.io-index",
"dirs-sys 0.3.7 registry+https://github.com/rust-lang/crates.io-index",
"dirs-sys 0.5.0 registry+https://github.com/rust-lang/crates.io-index",
"displaydoc 0.2.5 registry+https://github.com/rust-lang/crates.io-index",
"document-features 0.2.12 registry+https://github.com/rust-lang/crates.io-index",
"document-features 0.2.11 registry+https://github.com/rust-lang/crates.io-index",
"dpi 0.1.2 registry+https://github.com/rust-lang/crates.io-index",
"dunce 1.0.5 registry+https://github.com/rust-lang/crates.io-index",
"dyn-clone 1.0.20 registry+https://github.com/rust-lang/crates.io-index",
"ecolor 0.32.3 registry+https://github.com/rust-lang/crates.io-index",
"ed25519 2.2.3 registry+https://github.com/rust-lang/crates.io-index",
"eframe 0.32.3 registry+https://github.com/rust-lang/crates.io-index",
"egui 0.32.3 registry+https://github.com/rust-lang/crates.io-index",
"egui-phosphor 0.10.0 registry+https://github.com/rust-lang/crates.io-index",
@@ -101,8 +94,8 @@
"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",
"filetime 0.2.26 registry+https://github.com/rust-lang/crates.io-index",
"find-msvc-tools 0.1.4 registry+https://github.com/rust-lang/crates.io-index",
"flate2 1.1.5 registry+https://github.com/rust-lang/crates.io-index",
"find-msvc-tools 0.1.3 registry+https://github.com/rust-lang/crates.io-index",
"flate2 1.1.4 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",
"futures 0.3.31 registry+https://github.com/rust-lang/crates.io-index",
@@ -116,7 +109,7 @@
"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.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.3 registry+https://github.com/rust-lang/crates.io-index",
"gif 0.11.4 registry+https://github.com/rust-lang/crates.io-index",
"gif 0.13.3 registry+https://github.com/rust-lang/crates.io-index",
"git2 0.20.2 registry+https://github.com/rust-lang/crates.io-index",
@@ -126,7 +119,7 @@
"glutin 0.32.3 registry+https://github.com/rust-lang/crates.io-index",
"glutin_egl_sys 0.7.1 registry+https://github.com/rust-lang/crates.io-index",
"glutin_wgl_sys 0.6.1 registry+https://github.com/rust-lang/crates.io-index",
"half 2.7.1 registry+https://github.com/rust-lang/crates.io-index",
"half 2.6.0 registry+https://github.com/rust-lang/crates.io-index",
"hashbrown 0.12.3 registry+https://github.com/rust-lang/crates.io-index",
"hashbrown 0.14.5 registry+https://github.com/rust-lang/crates.io-index",
"hashbrown 0.15.5 registry+https://github.com/rust-lang/crates.io-index",
@@ -147,11 +140,11 @@
"imgref 1.12.0 registry+https://github.com/rust-lang/crates.io-index",
"indenter 0.3.4 registry+https://github.com/rust-lang/crates.io-index",
"indexmap 1.9.3 registry+https://github.com/rust-lang/crates.io-index",
"indexmap 2.12.0 registry+https://github.com/rust-lang/crates.io-index",
"indexmap 2.11.4 registry+https://github.com/rust-lang/crates.io-index",
"ipnet 2.11.0 registry+https://github.com/rust-lang/crates.io-index",
"iri-string 0.7.8 registry+https://github.com/rust-lang/crates.io-index",
"is_debug 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
"is_terminal_polyfill 1.70.2 registry+https://github.com/rust-lang/crates.io-index",
"is_terminal_polyfill 1.70.1 registry+https://github.com/rust-lang/crates.io-index",
"itertools 0.12.1 registry+https://github.com/rust-lang/crates.io-index",
"itertools 0.14.0 registry+https://github.com/rust-lang/crates.io-index",
"itoa 1.0.15 registry+https://github.com/rust-lang/crates.io-index",
@@ -159,11 +152,11 @@
"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",
"lazy_static 1.5.0 registry+https://github.com/rust-lang/crates.io-index",
"libc 0.2.177 registry+https://github.com/rust-lang/crates.io-index",
"libc 0.2.176 registry+https://github.com/rust-lang/crates.io-index",
"libgit2-sys 0.18.2+1.9.1 registry+https://github.com/rust-lang/crates.io-index",
"libz-sys 1.1.22 registry+https://github.com/rust-lang/crates.io-index",
"linked-hash-map 0.5.6 registry+https://github.com/rust-lang/crates.io-index",
"litrs 1.0.0 registry+https://github.com/rust-lang/crates.io-index",
"litrs 0.4.2 registry+https://github.com/rust-lang/crates.io-index",
"lock_api 0.4.14 registry+https://github.com/rust-lang/crates.io-index",
"log 0.4.28 registry+https://github.com/rust-lang/crates.io-index",
"logos 0.14.4 registry+https://github.com/rust-lang/crates.io-index",
@@ -176,7 +169,7 @@
"miniz_oxide 0.4.4 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",
"moxcms 0.7.9 registry+https://github.com/rust-lang/crates.io-index",
"moxcms 0.7.6 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",
"nohash-hasher 0.2.0 registry+https://github.com/rust-lang/crates.io-index",
@@ -191,9 +184,8 @@
"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-traits 0.2.19 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_polyfill 1.70.2 registry+https://github.com/rust-lang/crates.io-index",
"once_cell_polyfill 1.70.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",
"palette 0.5.0 registry+https://github.com/rust-lang/crates.io-index",
"palette_derive 0.5.0 registry+https://github.com/rust-lang/crates.io-index",
@@ -208,11 +200,11 @@
"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",
"ppv-lite86 0.2.21 registry+https://github.com/rust-lang/crates.io-index",
"proc-macro2 1.0.103 registry+https://github.com/rust-lang/crates.io-index",
"proc-macro2 1.0.101 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",
"psm 0.1.28 registry+https://github.com/rust-lang/crates.io-index",
"pxfm 0.1.25 registry+https://github.com/rust-lang/crates.io-index",
"psm 0.1.27 registry+https://github.com/rust-lang/crates.io-index",
"pxfm 0.1.24 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",
"quote 1.0.41 registry+https://github.com/rust-lang/crates.io-index",
@@ -229,17 +221,15 @@
"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-core 1.13.0 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.13 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.24 registry+https://github.com/rust-lang/crates.io-index",
"regex 1.11.3 registry+https://github.com/rust-lang/crates.io-index",
"regex-automata 0.4.11 registry+https://github.com/rust-lang/crates.io-index",
"regex-syntax 0.8.6 registry+https://github.com/rust-lang/crates.io-index",
"reqwest 0.12.23 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.26 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.13.0 registry+https://github.com/rust-lang/crates.io-index",
"rustls-pki-types 1.12.0 registry+https://github.com/rust-lang/crates.io-index",
"ryu 1.0.20 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",
"serde 1.0.228 registry+https://github.com/rust-lang/crates.io-index",
"serde_core 1.0.228 registry+https://github.com/rust-lang/crates.io-index",
"serde_derive 1.0.228 registry+https://github.com/rust-lang/crates.io-index",
@@ -248,29 +238,27 @@
"serde_json_lenient 0.2.4 registry+https://github.com/rust-lang/crates.io-index",
"serde_urlencoded 0.7.1 registry+https://github.com/rust-lang/crates.io-index",
"serde_variant 0.1.3 registry+https://github.com/rust-lang/crates.io-index",
"serde_with 3.15.1 registry+https://github.com/rust-lang/crates.io-index",
"serde_with_macros 3.15.1 registry+https://github.com/rust-lang/crates.io-index",
"serde_with 3.15.0 registry+https://github.com/rust-lang/crates.io-index",
"serde_with_macros 3.15.0 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",
"sha2 0.10.9 registry+https://github.com/rust-lang/crates.io-index",
"shadow-rs 1.4.0 registry+https://github.com/rust-lang/crates.io-index",
"shell-words 1.1.0 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",
"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 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",
"smol_str 0.2.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",
"socket2 0.6.0 registry+https://github.com/rust-lang/crates.io-index",
"stable_deref_trait 1.2.0 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",
"supports-color 3.0.2 registry+https://github.com/rust-lang/crates.io-index",
"supports-hyperlinks 3.1.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 2.0.108 registry+https://github.com/rust-lang/crates.io-index",
"syn 2.0.106 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.23.0 registry+https://github.com/rust-lang/crates.io-index",
"terminal_size 0.4.3 registry+https://github.com/rust-lang/crates.io-index",
@@ -284,11 +272,11 @@
"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",
"typenum 1.19.0 registry+https://github.com/rust-lang/crates.io-index",
"tz-rs 0.7.1 registry+https://github.com/rust-lang/crates.io-index",
"tz-rs 0.7.0 registry+https://github.com/rust-lang/crates.io-index",
"tzdb 0.7.2 registry+https://github.com/rust-lang/crates.io-index",
"tzdb_data 0.2.2 registry+https://github.com/rust-lang/crates.io-index",
"unicase 2.8.1 registry+https://github.com/rust-lang/crates.io-index",
"unicode-ident 1.0.20 registry+https://github.com/rust-lang/crates.io-index",
"unicode-ident 1.0.19 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-width 0.1.14 registry+https://github.com/rust-lang/crates.io-index",
@@ -301,9 +289,8 @@
"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",
"web-time 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",
"webbrowser 1.0.5 registry+https://github.com/rust-lang/crates.io-index",
"weezl 0.1.10 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",
"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",
@@ -365,19 +352,12 @@
"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",
"zerocopy 0.8.27 registry+https://github.com/rust-lang/crates.io-index",
"zerocopy-derive 0.8.27 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-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"
]
],
[
"Apache-2.0 WITH LLVM-exception",
[
"ar_archive_writer 0.2.0 registry+https://github.com/rust-lang/crates.io-index"
]
],
[
"Artistic-2.0",
[
@@ -388,11 +368,10 @@
[
"BSD-2-Clause",
[
"av1-grain 0.2.5 registry+https://github.com/rust-lang/crates.io-index",
"av1-grain 0.2.4 registry+https://github.com/rust-lang/crates.io-index",
"rav1e 0.7.1 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.27 registry+https://github.com/rust-lang/crates.io-index",
"zerocopy-derive 0.8.27 registry+https://github.com/rust-lang/crates.io-index"
"zerocopy 0.8.27 registry+https://github.com/rust-lang/crates.io-index"
]
],
[
@@ -403,15 +382,12 @@
"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-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",
"ed25519-dalek 2.2.0 registry+https://github.com/rust-lang/crates.io-index",
"encoding_rs 0.8.35 registry+https://github.com/rust-lang/crates.io-index",
"exr 1.73.0 registry+https://github.com/rust-lang/crates.io-index",
"lebe 0.5.3 registry+https://github.com/rust-lang/crates.io-index",
"moxcms 0.7.9 registry+https://github.com/rust-lang/crates.io-index",
"pxfm 0.1.25 registry+https://github.com/rust-lang/crates.io-index",
"ravif 0.11.20 registry+https://github.com/rust-lang/crates.io-index",
"subtle 2.6.1 registry+https://github.com/rust-lang/crates.io-index"
"moxcms 0.7.6 registry+https://github.com/rust-lang/crates.io-index",
"pxfm 0.1.24 registry+https://github.com/rust-lang/crates.io-index",
"ravif 0.11.20 registry+https://github.com/rust-lang/crates.io-index"
]
],
[
@@ -437,7 +413,7 @@
[
"is_ci 1.2.0 registry+https://github.com/rust-lang/crates.io-index",
"libloading 0.8.9 registry+https://github.com/rust-lang/crates.io-index",
"starship-battery 0.10.3 registry+https://github.com/rust-lang/crates.io-index"
"starship-battery 0.10.2 registry+https://github.com/rust-lang/crates.io-index"
]
],
[
@@ -449,7 +425,7 @@
"adler 1.0.2 registry+https://github.com/rust-lang/crates.io-index",
"adler2 2.0.1 registry+https://github.com/rust-lang/crates.io-index",
"ahash 0.8.12 registry+https://github.com/rust-lang/crates.io-index",
"aho-corasick 1.1.4 registry+https://github.com/rust-lang/crates.io-index",
"aho-corasick 1.1.3 registry+https://github.com/rust-lang/crates.io-index",
"aligned-vec 0.6.4 registry+https://github.com/rust-lang/crates.io-index",
"allocator-api2 0.2.21 registry+https://github.com/rust-lang/crates.io-index",
"anstream 0.6.21 registry+https://github.com/rust-lang/crates.io-index",
@@ -466,14 +442,12 @@
"backtrace 0.3.76 registry+https://github.com/rust-lang/crates.io-index",
"backtrace-ext 0.2.1 registry+https://github.com/rust-lang/crates.io-index",
"base16_color_scheme 0.3.2 git+https://github.com/LGUG2Z/base16_color_scheme",
"base64 0.21.7 registry+https://github.com/rust-lang/crates.io-index",
"base64 0.22.1 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",
"bitflags 1.3.2 registry+https://github.com/rust-lang/crates.io-index",
"bitflags 2.10.0 registry+https://github.com/rust-lang/crates.io-index",
"bitflags 2.9.4 registry+https://github.com/rust-lang/crates.io-index",
"bitstream-io 2.6.0 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-decompressor 5.0.0 registry+https://github.com/rust-lang/crates.io-index",
"built 0.7.7 registry+https://github.com/rust-lang/crates.io-index",
@@ -485,49 +459,44 @@
"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",
"catppuccin-egui 5.6.0 registry+https://github.com/rust-lang/crates.io-index",
"cc 1.2.43 registry+https://github.com/rust-lang/crates.io-index",
"cc 1.2.40 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.3 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.42 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",
"clap 4.5.50 registry+https://github.com/rust-lang/crates.io-index",
"clap_builder 4.5.50 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 0.7.6 registry+https://github.com/rust-lang/crates.io-index",
"clap 4.5.48 registry+https://github.com/rust-lang/crates.io-index",
"clap_builder 4.5.48 registry+https://github.com/rust-lang/crates.io-index",
"clap_derive 4.5.47 registry+https://github.com/rust-lang/crates.io-index",
"clap_lex 0.7.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-thief 0.2.2 registry+https://github.com/rust-lang/crates.io-index",
"color_quant 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
"colorchoice 1.0.4 registry+https://github.com/rust-lang/crates.io-index",
"cpufeatures 0.2.17 registry+https://github.com/rust-lang/crates.io-index",
"crc32fast 1.5.0 registry+https://github.com/rust-lang/crates.io-index",
"crossbeam-channel 0.5.15 registry+https://github.com/rust-lang/crates.io-index",
"crossbeam-deque 0.8.6 registry+https://github.com/rust-lang/crates.io-index",
"crossbeam-epoch 0.9.18 registry+https://github.com/rust-lang/crates.io-index",
"crossbeam-utils 0.8.21 registry+https://github.com/rust-lang/crates.io-index",
"crypto-common 0.1.6 registry+https://github.com/rust-lang/crates.io-index",
"ctrlc 3.5.1 registry+https://github.com/rust-lang/crates.io-index",
"ctrlc 3.5.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",
"darling 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",
"deflate 0.8.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",
"deranged 0.5.4 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 6.0.0 registry+https://github.com/rust-lang/crates.io-index",
"dirs-sys 0.3.7 registry+https://github.com/rust-lang/crates.io-index",
"dirs-sys 0.5.0 registry+https://github.com/rust-lang/crates.io-index",
"displaydoc 0.2.5 registry+https://github.com/rust-lang/crates.io-index",
"document-features 0.2.12 registry+https://github.com/rust-lang/crates.io-index",
"document-features 0.2.11 registry+https://github.com/rust-lang/crates.io-index",
"dpi 0.1.2 registry+https://github.com/rust-lang/crates.io-index",
"dyn-clone 1.0.20 registry+https://github.com/rust-lang/crates.io-index",
"ecolor 0.32.3 registry+https://github.com/rust-lang/crates.io-index",
"ed25519 2.2.3 registry+https://github.com/rust-lang/crates.io-index",
"eframe 0.32.3 registry+https://github.com/rust-lang/crates.io-index",
"egui 0.32.3 registry+https://github.com/rust-lang/crates.io-index",
"egui-phosphor 0.10.0 registry+https://github.com/rust-lang/crates.io-index",
@@ -551,8 +520,8 @@
"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",
"filetime 0.2.26 registry+https://github.com/rust-lang/crates.io-index",
"find-msvc-tools 0.1.4 registry+https://github.com/rust-lang/crates.io-index",
"flate2 1.1.5 registry+https://github.com/rust-lang/crates.io-index",
"find-msvc-tools 0.1.3 registry+https://github.com/rust-lang/crates.io-index",
"flate2 1.1.4 registry+https://github.com/rust-lang/crates.io-index",
"flavours 0.7.2 git+https://github.com/LGUG2Z/flavours",
"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",
@@ -567,10 +536,9 @@
"futures-sink 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",
"generic-array 0.14.9 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.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.3 registry+https://github.com/rust-lang/crates.io-index",
"gif 0.11.4 registry+https://github.com/rust-lang/crates.io-index",
"gif 0.13.3 registry+https://github.com/rust-lang/crates.io-index",
"git2 0.20.2 registry+https://github.com/rust-lang/crates.io-index",
@@ -578,7 +546,7 @@
"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",
"h2 0.4.12 registry+https://github.com/rust-lang/crates.io-index",
"half 2.7.1 registry+https://github.com/rust-lang/crates.io-index",
"half 2.6.0 registry+https://github.com/rust-lang/crates.io-index",
"hashbrown 0.12.3 registry+https://github.com/rust-lang/crates.io-index",
"hashbrown 0.14.5 registry+https://github.com/rust-lang/crates.io-index",
"hashbrown 0.15.5 registry+https://github.com/rust-lang/crates.io-index",
@@ -603,22 +571,22 @@
"image-webp 0.2.4 registry+https://github.com/rust-lang/crates.io-index",
"indenter 0.3.4 registry+https://github.com/rust-lang/crates.io-index",
"indexmap 1.9.3 registry+https://github.com/rust-lang/crates.io-index",
"indexmap 2.12.0 registry+https://github.com/rust-lang/crates.io-index",
"indexmap 2.11.4 registry+https://github.com/rust-lang/crates.io-index",
"ipnet 2.11.0 registry+https://github.com/rust-lang/crates.io-index",
"iri-string 0.7.8 registry+https://github.com/rust-lang/crates.io-index",
"is_debug 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
"is_terminal_polyfill 1.70.2 registry+https://github.com/rust-lang/crates.io-index",
"is_terminal_polyfill 1.70.1 registry+https://github.com/rust-lang/crates.io-index",
"itertools 0.12.1 registry+https://github.com/rust-lang/crates.io-index",
"itertools 0.14.0 registry+https://github.com/rust-lang/crates.io-index",
"itoa 1.0.15 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",
"lazy_static 1.5.0 registry+https://github.com/rust-lang/crates.io-index",
"libc 0.2.177 registry+https://github.com/rust-lang/crates.io-index",
"libc 0.2.176 registry+https://github.com/rust-lang/crates.io-index",
"libgit2-sys 0.18.2+1.9.1 registry+https://github.com/rust-lang/crates.io-index",
"libz-sys 1.1.22 registry+https://github.com/rust-lang/crates.io-index",
"linked-hash-map 0.5.6 registry+https://github.com/rust-lang/crates.io-index",
"litrs 1.0.0 registry+https://github.com/rust-lang/crates.io-index",
"litrs 0.4.2 registry+https://github.com/rust-lang/crates.io-index",
"lock_api 0.4.14 registry+https://github.com/rust-lang/crates.io-index",
"log 0.4.28 registry+https://github.com/rust-lang/crates.io-index",
"logos 0.14.4 registry+https://github.com/rust-lang/crates.io-index",
@@ -635,7 +603,7 @@
"miniz_oxide 0.3.7 registry+https://github.com/rust-lang/crates.io-index",
"miniz_oxide 0.4.4 registry+https://github.com/rust-lang/crates.io-index",
"miniz_oxide 0.8.9 registry+https://github.com/rust-lang/crates.io-index",
"mio 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
"mio 1.0.4 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",
"native-tls 0.2.14 registry+https://github.com/rust-lang/crates.io-index",
@@ -644,10 +612,9 @@
"new_debug_unreachable 1.0.6 registry+https://github.com/rust-lang/crates.io-index",
"nohash-hasher 0.2.0 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",
"noop_proc_macro 0.3.0 registry+https://github.com/rust-lang/crates.io-index",
"ntapi 0.4.1 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.1 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-complex 0.4.6 registry+https://github.com/rust-lang/crates.io-index",
@@ -658,10 +625,8 @@
"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-traits 0.2.19 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_polyfill 1.70.2 registry+https://github.com/rust-lang/crates.io-index",
"open 5.3.2 registry+https://github.com/rust-lang/crates.io-index",
"once_cell_polyfill 1.70.1 registry+https://github.com/rust-lang/crates.io-index",
"os_info 3.12.0 registry+https://github.com/rust-lang/crates.io-index",
"owo-colors 4.2.3 registry+https://github.com/rust-lang/crates.io-index",
"palette 0.5.0 registry+https://github.com/rust-lang/crates.io-index",
@@ -686,10 +651,10 @@
"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",
"ppv-lite86 0.2.21 registry+https://github.com/rust-lang/crates.io-index",
"proc-macro2 1.0.103 registry+https://github.com/rust-lang/crates.io-index",
"proc-macro2 1.0.101 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",
"psm 0.1.28 registry+https://github.com/rust-lang/crates.io-index",
"psm 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",
"quick-error 2.0.1 registry+https://github.com/rust-lang/crates.io-index",
"quote 1.0.41 registry+https://github.com/rust-lang/crates.io-index",
@@ -707,22 +672,20 @@
"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-core 1.13.0 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.13 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.24 registry+https://github.com/rust-lang/crates.io-index",
"regex 1.11.3 registry+https://github.com/rust-lang/crates.io-index",
"regex-automata 0.4.11 registry+https://github.com/rust-lang/crates.io-index",
"regex-syntax 0.8.6 registry+https://github.com/rust-lang/crates.io-index",
"reqwest 0.12.23 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",
"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",
"rustls-pki-types 1.13.0 registry+https://github.com/rust-lang/crates.io-index",
"rustls-pki-types 1.12.0 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",
"schemars 0.8.22 registry+https://github.com/rust-lang/crates.io-index",
"schemars_derive 0.8.22 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",
"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_core 1.0.228 registry+https://github.com/rust-lang/crates.io-index",
"serde_derive 1.0.228 registry+https://github.com/rust-lang/crates.io-index",
@@ -731,17 +694,15 @@
"serde_json_lenient 0.2.4 registry+https://github.com/rust-lang/crates.io-index",
"serde_urlencoded 0.7.1 registry+https://github.com/rust-lang/crates.io-index",
"serde_variant 0.1.3 registry+https://github.com/rust-lang/crates.io-index",
"serde_with 3.15.1 registry+https://github.com/rust-lang/crates.io-index",
"serde_with_macros 3.15.1 registry+https://github.com/rust-lang/crates.io-index",
"serde_with 3.15.0 registry+https://github.com/rust-lang/crates.io-index",
"serde_with_macros 3.15.0 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",
"sha2 0.10.9 registry+https://github.com/rust-lang/crates.io-index",
"shadow-rs 1.4.0 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.0 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",
"signature 2.2.0 registry+https://github.com/rust-lang/crates.io-index",
"simd-adler32 0.3.7 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",
@@ -749,15 +710,15 @@
"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",
"smol_str 0.2.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",
"socket2 0.6.0 registry+https://github.com/rust-lang/crates.io-index",
"stable_deref_trait 1.2.0 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",
"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_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 2.0.108 registry+https://github.com/rust-lang/crates.io-index",
"syn 2.0.106 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.37.2 registry+https://github.com/rust-lang/crates.io-index",
@@ -773,7 +734,7 @@
"tiff 0.6.1 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.6 registry+https://github.com/rust-lang/crates.io-index",
"tokio 1.48.0 registry+https://github.com/rust-lang/crates.io-index",
"tokio 1.47.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.16 registry+https://github.com/rust-lang/crates.io-index",
"toml 0.5.11 registry+https://github.com/rust-lang/crates.io-index",
@@ -791,11 +752,11 @@
"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",
"typenum 1.19.0 registry+https://github.com/rust-lang/crates.io-index",
"tz-rs 0.7.1 registry+https://github.com/rust-lang/crates.io-index",
"tz-rs 0.7.0 registry+https://github.com/rust-lang/crates.io-index",
"tzdb_data 0.2.2 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.8.1 registry+https://github.com/rust-lang/crates.io-index",
"unicode-ident 1.0.20 registry+https://github.com/rust-lang/crates.io-index",
"unicode-ident 1.0.19 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.2.2 registry+https://github.com/rust-lang/crates.io-index",
@@ -810,10 +771,9 @@
"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",
"web-time 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",
"webbrowser 1.0.5 registry+https://github.com/rust-lang/crates.io-index",
"weezl 0.1.10 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.1 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",
"windows 0.57.0 registry+https://github.com/rust-lang/crates.io-index",
@@ -878,10 +838,9 @@
"winreg 0.55.0 registry+https://github.com/rust-lang/crates.io-index",
"winsafe 0.0.19 registry+https://github.com/rust-lang/crates.io-index",
"wmi 0.15.2 registry+https://github.com/rust-lang/crates.io-index",
"xml-rs 0.8.28 registry+https://github.com/rust-lang/crates.io-index",
"xml-rs 0.8.27 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.27 registry+https://github.com/rust-lang/crates.io-index",
"zerocopy-derive 0.8.27 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-inflate 0.2.54 registry+https://github.com/rust-lang/crates.io-index",
@@ -917,31 +876,31 @@
[
"Unicode-3.0",
[
"icu_collections 2.1.1 registry+https://github.com/rust-lang/crates.io-index",
"icu_locale_core 2.1.1 registry+https://github.com/rust-lang/crates.io-index",
"icu_normalizer 2.1.1 registry+https://github.com/rust-lang/crates.io-index",
"icu_normalizer_data 2.1.1 registry+https://github.com/rust-lang/crates.io-index",
"icu_properties 2.1.1 registry+https://github.com/rust-lang/crates.io-index",
"icu_properties_data 2.1.1 registry+https://github.com/rust-lang/crates.io-index",
"icu_provider 2.1.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",
"tinystr 0.8.2 registry+https://github.com/rust-lang/crates.io-index",
"unicode-ident 1.0.20 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-derive 0.8.1 registry+https://github.com/rust-lang/crates.io-index",
"icu_collections 2.0.0 registry+https://github.com/rust-lang/crates.io-index",
"icu_locale_core 2.0.0 registry+https://github.com/rust-lang/crates.io-index",
"icu_normalizer 2.0.0 registry+https://github.com/rust-lang/crates.io-index",
"icu_normalizer_data 2.0.0 registry+https://github.com/rust-lang/crates.io-index",
"icu_properties 2.0.1 registry+https://github.com/rust-lang/crates.io-index",
"icu_properties_data 2.0.1 registry+https://github.com/rust-lang/crates.io-index",
"icu_provider 2.0.0 registry+https://github.com/rust-lang/crates.io-index",
"litemap 0.8.0 registry+https://github.com/rust-lang/crates.io-index",
"potential_utf 0.1.3 registry+https://github.com/rust-lang/crates.io-index",
"tinystr 0.8.1 registry+https://github.com/rust-lang/crates.io-index",
"unicode-ident 1.0.19 registry+https://github.com/rust-lang/crates.io-index",
"writeable 0.6.1 registry+https://github.com/rust-lang/crates.io-index",
"yoke 0.8.0 registry+https://github.com/rust-lang/crates.io-index",
"yoke-derive 0.8.0 registry+https://github.com/rust-lang/crates.io-index",
"zerofrom 0.1.6 registry+https://github.com/rust-lang/crates.io-index",
"zerofrom-derive 0.1.6 registry+https://github.com/rust-lang/crates.io-index",
"zerotrie 0.2.3 registry+https://github.com/rust-lang/crates.io-index",
"zerovec 0.11.5 registry+https://github.com/rust-lang/crates.io-index",
"zerovec-derive 0.11.2 registry+https://github.com/rust-lang/crates.io-index"
"zerotrie 0.2.2 registry+https://github.com/rust-lang/crates.io-index",
"zerovec 0.11.4 registry+https://github.com/rust-lang/crates.io-index",
"zerovec-derive 0.11.1 registry+https://github.com/rust-lang/crates.io-index"
]
],
[
"Unlicense",
[
"aho-corasick 1.1.4 registry+https://github.com/rust-lang/crates.io-index",
"aho-corasick 1.1.3 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",
"memchr 2.7.6 registry+https://github.com/rust-lang/crates.io-index",

View File

@@ -10,8 +10,8 @@ Options:
Desired ease function for animation
[default: linear]
[possible values: linear, ease-in-sine, ease-out-sine, ease-in-out-sine, ease-in-quad, ease-out-quad, ease-in-out-quad, ease-in-cubic, ease-in-out-cubic, ease-in-quart, ease-out-quart, ease-in-out-quart, ease-in-quint, ease-out-quint, ease-in-out-quint, ease-in-expo,
ease-out-expo, ease-in-out-expo, ease-in-circ, ease-out-circ, ease-in-out-circ, ease-in-back, ease-out-back, ease-in-out-back, ease-in-elastic, ease-out-elastic, ease-in-out-elastic, ease-in-bounce, ease-out-bounce, ease-in-out-bounce]
[possible values: linear, ease-in-sine, ease-out-sine, ease-in-out-sine, ease-in-quad, ease-out-quad, ease-in-out-quad, ease-in-cubic, ease-in-out-cubic, ease-in-quart, ease-out-quart, ease-in-out-quart, ease-in-quint, ease-out-quint, ease-in-out-quint,
ease-in-expo, ease-out-expo, ease-in-out-expo, ease-in-circ, ease-out-circ, ease-in-out-circ, ease-in-back, ease-out-back, ease-in-out-back, ease-in-elastic, ease-out-elastic, ease-in-out-elastic, ease-in-bounce, ease-out-bounce, ease-in-out-bounce]
-a, --animation-type <ANIMATION_TYPE>
Animation type to apply the style to. If not specified, sets global style

View File

@@ -12,6 +12,9 @@ Options:
--whkd
Enable autostart of whkd
--ahk
Enable autostart of ahk
--bar
Enable autostart of komorebi-bar

View File

@@ -9,6 +9,9 @@ Options:
--whkd
Kill whkd if it is running as a background process
--ahk
Kill ahk if it is running as a background process
--bar
Kill komorebi-bar if it is running as a background process

View File

@@ -1,16 +0,0 @@
# license
```
Specify an email associated with an Individual Commercial Use License
Usage: komorebic.exe license <EMAIL>
Arguments:
<EMAIL>
Email address associated with an Individual Commercial Use License
Options:
-h, --help
Print help
```

View File

@@ -18,6 +18,9 @@ Options:
--whkd
Start whkd in a background process
--ahk
Start autohotkey configuration file
--bar
Start komorebi-bar in a background process

View File

@@ -9,6 +9,9 @@ Options:
--whkd
Stop whkd if it is running as a background process
--ahk
Stop ahk if it is running as a background process
--bar
Stop komorebi-bar if it is running as a background process

View File

@@ -16,19 +16,6 @@ the example files have been downloaded. For most new users this will be in the
komorebic quickstart
```
## Corporate Devices Enrolled in MDM
If you are using `komorebi` on a corporate device enrolled in mobile device
management, you will receive a pop-up when you run `komorebic start` reminding
you that the [Komorebi License](https://github.com/LGUG2Z/komorebi-license) does
not permit any kind of commercial use.
You can remove this pop-up by running `komorebic license <email>` with the email
associated with your Individual Commercial Use License. A single HTTP request
will be sent with the given email address to verify license validity.
## Starting komorebi
With the example configurations downloaded, you can now start `komorebi`,
`komorebi-bar` and `whkd`.
@@ -36,9 +23,6 @@ With the example configurations downloaded, you can now start `komorebi`,
komorebic start --whkd --bar
```
If you don't want to use the komorebi status bar, you can remove the `--bar` option
from the above command.
## komorebi.json
The example window manager configuration sets some sane defaults and provides

View File

@@ -15,9 +15,6 @@ fmt:
prettier --write .github/FUNDING.yml
prettier --write .github/workflows/windows.yaml
fix:
cargo clippy --fix --allow-dirty
install-targets *targets:
"{{ targets }}" -split ' ' | ForEach-Object { just install-target $_ }
@@ -93,5 +90,4 @@ schemagen:
mv ./bar-config-docs/schema.bar.html ./bar-config-docs/schema.html
depgen:
cargo deny check
cargo deny list --format json | jq 'del(.unlicensed)' > dependencies.json

View File

@@ -103,7 +103,7 @@ fn process_hwnd() -> Option<isize> {
}
pub enum KomorebiEvent {
Notification(Box<komorebi_client::Notification>),
Notification(komorebi_client::Notification),
Reconnect,
}
@@ -381,7 +381,7 @@ fn main() -> color_eyre::Result<()> {
Ok(notification) => {
tracing::debug!("received notification from komorebi");
if let Err(error) = tx_gui.send(KomorebiEvent::Notification(Box::new(notification))) {
if let Err(error) = tx_gui.send(KomorebiEvent::Notification(notification)) {
tracing::error!("could not send komorebi notification update to gui thread: {error}")
}

View File

@@ -7,6 +7,7 @@ pub use komorebi::AspectRatio;
pub use komorebi::BorderColours;
pub use komorebi::Colour;
pub use komorebi::CrossBoundaryBehaviour;
pub use komorebi::GlobalState;
pub use komorebi::KomorebiTheme;
pub use komorebi::MonitorConfig;
pub use komorebi::Notification;
@@ -15,6 +16,7 @@ pub use komorebi::PredefinedAspectRatio;
pub use komorebi::Rgb;
pub use komorebi::RuleDebug;
pub use komorebi::StackbarConfig;
pub use komorebi::State;
pub use komorebi::StaticConfig;
pub use komorebi::SubscribeOptions;
pub use komorebi::TabsConfig;
@@ -66,9 +68,6 @@ pub use komorebi::core::replace_env_in_path;
pub use komorebi::monitor::Monitor;
pub use komorebi::monitor_reconciliator::MonitorNotification;
pub use komorebi::ring::Ring;
pub use komorebi::splash;
pub use komorebi::state::GlobalState;
pub use komorebi::state::State;
pub use komorebi::win32_display_data;
pub use komorebi::window::Window;
pub use komorebi::window_manager_event::WindowManagerEvent;

View File

@@ -10,16 +10,13 @@ edition = "2024"
[dependencies]
komorebi-themes = { path = "../komorebi-themes" }
base64 = "0.21"
bitflags = { version = "2", features = ["serde"] }
clap = { workspace = true }
chrono = { workspace = true }
color-eyre = { workspace = true }
crossbeam-channel = { workspace = true }
crossbeam-utils = { workspace = true }
ctrlc = { version = "3", features = ["termination"] }
dirs = { workspace = true }
ed25519-dalek = "2"
hotwatch = { workspace = true }
lazy_static = { workspace = true }
miow = "0.6"
@@ -30,10 +27,9 @@ parking_lot = { workspace = true }
paste = { workspace = true }
powershell_script = "1.0"
regex = "1"
reqwest = { version = "0.12", features = ["blocking"] }
schemars = { workspace = true, optional = true }
serde = { workspace = true }
serde_json = { workspace = true, features = ["preserve_order"] }
serde_json = { workspace = true }
serde_yaml = { workspace = true }
shadow-rs = { workspace = true }
strum = { workspace = true }

View File

@@ -52,111 +52,83 @@ impl Arrangement for DefaultLayout {
let column_width = area.right / column_count as i32;
let mut layouts = Vec::with_capacity(len);
match len {
// treat < 3 windows the same as the columns layout
len if len < 3 => {
layouts = columns(area, len);
let visible_columns = area.right / column_width;
let keep_centered = layout_options
.and_then(|o| {
o.scrolling
.map(|s| s.center_focused_column.unwrap_or_default())
})
.unwrap_or(false);
let adjustment = calculate_columns_adjustment(resize_dimensions);
layouts.iter_mut().zip(adjustment.iter()).for_each(
|(layout, adjustment)| {
layout.top += adjustment.top;
layout.bottom += adjustment.bottom;
layout.left += adjustment.left;
layout.right += adjustment.right;
},
);
let first_visible: isize = if focused_idx == 0 {
// if focused idx is 0, we are at the beginning of the scrolling strip
0
} else {
let previous_first_visible = if latest_layout.is_empty() {
0
} else {
// previous first_visible based on the left position of the first visible window
let left_edge = area.left;
latest_layout
.iter()
.position(|rect| rect.left >= left_edge)
.unwrap_or(0) as isize
};
if matches!(
layout_flip,
Some(Axis::Horizontal | Axis::HorizontalAndVertical)
) && let 2.. = len
{
columns_reverse(&mut layouts);
}
}
// treat >= column_count as scrolling
len => {
let visible_columns = area.right / column_width;
let keep_centered = layout_options
.and_then(|o| {
o.scrolling
.map(|s| s.center_focused_column.unwrap_or_default())
})
.unwrap_or(false);
let focused_idx = focused_idx as isize;
let first_visible: isize = if focused_idx == 0 {
// if focused idx is 0, we are at the beginning of the scrolling strip
0
// if center_focused_column is enabled, and we have an odd number of visible columns,
// center the focused window column
if keep_centered && visible_columns % 2 == 1 {
let center_offset = visible_columns as isize / 2;
(focused_idx - center_offset).max(0).min(
(len as isize)
.saturating_sub(visible_columns as isize)
.max(0),
)
} else {
if focused_idx < previous_first_visible {
// focused window is off the left edge, we need to scroll left
focused_idx
} else if focused_idx >= previous_first_visible + visible_columns as isize {
// focused window is off the right edge, we need to scroll right
// and make sure it's the last visible window
(focused_idx + 1 - visible_columns as isize).max(0)
} else {
let previous_first_visible = if latest_layout.is_empty() {
0
} else {
// previous first_visible based on the left position of the first visible window
let left_edge = area.left;
latest_layout
.iter()
.position(|rect| rect.left >= left_edge)
.unwrap_or(0) as isize
};
let focused_idx = focused_idx as isize;
// if center_focused_column is enabled, and we have an odd number of visible columns,
// center the focused window column
if keep_centered && visible_columns % 2 == 1 {
let center_offset = visible_columns as isize / 2;
(focused_idx - center_offset).max(0).min(
(len as isize)
.saturating_sub(visible_columns as isize)
.max(0),
)
} else {
if focused_idx < previous_first_visible {
// focused window is off the left edge, we need to scroll left
focused_idx
} else if focused_idx
>= previous_first_visible + visible_columns as isize
{
// focused window is off the right edge, we need to scroll right
// and make sure it's the last visible window
(focused_idx + 1 - visible_columns as isize).max(0)
} else {
// focused window is already visible, we don't need to scroll
previous_first_visible
}
.min(
(len as isize)
.saturating_sub(visible_columns as isize)
.max(0),
)
}
};
for i in 0..len {
let position = (i as isize) - first_visible;
let left = area.left + (position as i32 * column_width);
layouts.push(Rect {
left,
top: area.top,
right: column_width,
bottom: area.bottom,
});
// focused window is already visible, we don't need to scroll
previous_first_visible
}
let adjustment = calculate_scrolling_adjustment(resize_dimensions);
layouts.iter_mut().zip(adjustment.iter()).for_each(
|(layout, adjustment)| {
layout.top += adjustment.top;
layout.bottom += adjustment.bottom;
layout.left += adjustment.left;
layout.right += adjustment.right;
},
);
.min(
(len as isize)
.saturating_sub(visible_columns as isize)
.max(0),
)
}
};
for i in 0..len {
let position = (i as isize) - first_visible;
let left = area.left + (position as i32 * column_width);
layouts.push(Rect {
left,
top: area.top,
right: column_width,
bottom: area.bottom,
});
}
let adjustment = calculate_scrolling_adjustment(resize_dimensions);
layouts
.iter_mut()
.zip(adjustment.iter())
.for_each(|(layout, adjustment)| {
layout.top += adjustment.top;
layout.bottom += adjustment.bottom;
layout.left += adjustment.left;
layout.right += adjustment.right;
});
layouts
}
Self::BSP => recursive_fibonacci(
@@ -542,25 +514,14 @@ impl Arrangement for DefaultLayout {
let len = len as i32;
let row_constraint = layout_options.and_then(|o| o.grid.map(|g| g.rows));
let num_cols = if let Some(rows) = row_constraint {
((len as f32) / (rows as f32)).ceil() as i32
} else {
(len as f32).sqrt().ceil() as i32
};
let num_cols = (len as f32).sqrt().ceil() as i32;
let mut iter = layouts.iter_mut().enumerate().peekable();
for col in 0..num_cols {
let iter_peek = iter.peek().map(|x| x.0).unwrap_or_default() as i32;
let remaining_windows = len - iter_peek;
let remaining_columns = num_cols - col;
let num_rows_in_this_col = if let Some(rows) = row_constraint {
(remaining_windows / remaining_columns).min(rows as i32)
} else {
remaining_windows / remaining_columns
};
let num_rows_in_this_col = remaining_windows / remaining_columns;
let win_height = area.bottom / num_rows_in_this_col;
let win_width = area.right / num_cols;

View File

@@ -30,8 +30,6 @@ pub enum DefaultLayout {
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)]
@@ -43,13 +41,6 @@ pub struct ScrollingLayoutOptions {
pub center_focused_column: Option<bool>,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
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 {

View File

@@ -4,7 +4,6 @@ use super::custom_layout::Column;
use super::custom_layout::ColumnSplit;
use super::custom_layout::ColumnSplitWithCapacity;
use super::custom_layout::CustomLayout;
use crate::default_layout::LayoutOptions;
pub trait Direction {
fn index_in_direction(
@@ -12,7 +11,6 @@ pub trait Direction {
op_direction: OperationDirection,
idx: usize,
count: usize,
layout_options: Option<LayoutOptions>,
) -> Option<usize>;
fn is_valid_direction(
@@ -20,35 +18,30 @@ pub trait Direction {
op_direction: OperationDirection,
idx: usize,
count: usize,
layout_options: Option<LayoutOptions>,
) -> bool;
fn up_index(
&self,
op_direction: Option<OperationDirection>,
idx: usize,
count: Option<usize>,
layout_options: Option<LayoutOptions>,
) -> usize;
fn down_index(
&self,
op_direction: Option<OperationDirection>,
idx: usize,
count: Option<usize>,
layout_options: Option<LayoutOptions>,
) -> usize;
fn left_index(
&self,
op_direction: Option<OperationDirection>,
idx: usize,
count: Option<usize>,
layout_options: Option<LayoutOptions>,
) -> usize;
fn right_index(
&self,
op_direction: Option<OperationDirection>,
idx: usize,
count: Option<usize>,
layout_options: Option<LayoutOptions>,
) -> usize;
}
@@ -58,53 +51,32 @@ impl Direction for DefaultLayout {
op_direction: OperationDirection,
idx: usize,
count: usize,
layout_options: Option<LayoutOptions>,
) -> Option<usize> {
match op_direction {
OperationDirection::Left => {
if self.is_valid_direction(op_direction, idx, count, layout_options) {
Option::from(self.left_index(
Some(op_direction),
idx,
Some(count),
layout_options,
))
if self.is_valid_direction(op_direction, idx, count) {
Option::from(self.left_index(Some(op_direction), idx, Some(count)))
} else {
None
}
}
OperationDirection::Right => {
if self.is_valid_direction(op_direction, idx, count, layout_options) {
Option::from(self.right_index(
Some(op_direction),
idx,
Some(count),
layout_options,
))
if self.is_valid_direction(op_direction, idx, count) {
Option::from(self.right_index(Some(op_direction), idx, Some(count)))
} else {
None
}
}
OperationDirection::Up => {
if self.is_valid_direction(op_direction, idx, count, layout_options) {
Option::from(self.up_index(
Some(op_direction),
idx,
Some(count),
layout_options,
))
if self.is_valid_direction(op_direction, idx, count) {
Option::from(self.up_index(Some(op_direction), idx, Some(count)))
} else {
None
}
}
OperationDirection::Down => {
if self.is_valid_direction(op_direction, idx, count, layout_options) {
Option::from(self.down_index(
Some(op_direction),
idx,
Some(count),
layout_options,
))
if self.is_valid_direction(op_direction, idx, count) {
Option::from(self.down_index(Some(op_direction), idx, Some(count)))
} else {
None
}
@@ -117,7 +89,6 @@ impl Direction for DefaultLayout {
op_direction: OperationDirection,
idx: usize,
count: usize,
layout_options: Option<LayoutOptions>,
) -> bool {
if count < 2 {
return false;
@@ -130,7 +101,7 @@ impl Direction for DefaultLayout {
Self::Rows | Self::HorizontalStack => idx != 0,
Self::VerticalStack | Self::RightMainVerticalStack => idx != 0 && idx != 1,
Self::UltrawideVerticalStack => idx > 2,
Self::Grid => !is_grid_edge(op_direction, idx, count, layout_options),
Self::Grid => !is_grid_edge(op_direction, idx, count),
Self::Scrolling => false,
},
OperationDirection::Down => match self {
@@ -140,7 +111,7 @@ impl Direction for DefaultLayout {
Self::VerticalStack | Self::RightMainVerticalStack => idx != 0 && idx != count - 1,
Self::HorizontalStack => idx == 0,
Self::UltrawideVerticalStack => idx > 1 && idx != count - 1,
Self::Grid => !is_grid_edge(op_direction, idx, count, layout_options),
Self::Grid => !is_grid_edge(op_direction, idx, count),
Self::Scrolling => false,
},
OperationDirection::Left => match self {
@@ -150,7 +121,7 @@ impl Direction for DefaultLayout {
Self::Rows => false,
Self::HorizontalStack => idx != 0 && idx != 1,
Self::UltrawideVerticalStack => idx != 1,
Self::Grid => !is_grid_edge(op_direction, idx, count, layout_options),
Self::Grid => !is_grid_edge(op_direction, idx, count),
Self::Scrolling => idx != 0,
},
OperationDirection::Right => match self {
@@ -164,7 +135,7 @@ impl Direction for DefaultLayout {
2 => idx != 0,
_ => idx < 2,
},
Self::Grid => !is_grid_edge(op_direction, idx, count, layout_options),
Self::Grid => !is_grid_edge(op_direction, idx, count),
Self::Scrolling => idx != count - 1,
},
}
@@ -175,7 +146,6 @@ impl Direction for DefaultLayout {
op_direction: Option<OperationDirection>,
idx: usize,
count: Option<usize>,
layout_options: Option<LayoutOptions>,
) -> usize {
match self {
Self::BSP => {
@@ -191,7 +161,7 @@ impl Direction for DefaultLayout {
| Self::UltrawideVerticalStack
| Self::RightMainVerticalStack => idx - 1,
Self::HorizontalStack => 0,
Self::Grid => grid_neighbor(op_direction, idx, count, layout_options),
Self::Grid => grid_neighbor(op_direction, idx, count),
Self::Scrolling => unreachable!(),
}
}
@@ -201,7 +171,6 @@ impl Direction for DefaultLayout {
op_direction: Option<OperationDirection>,
idx: usize,
count: Option<usize>,
layout_options: Option<LayoutOptions>,
) -> usize {
match self {
Self::BSP
@@ -211,7 +180,7 @@ impl Direction for DefaultLayout {
| Self::RightMainVerticalStack => idx + 1,
Self::Columns => unreachable!(),
Self::HorizontalStack => 1,
Self::Grid => grid_neighbor(op_direction, idx, count, layout_options),
Self::Grid => grid_neighbor(op_direction, idx, count),
Self::Scrolling => unreachable!(),
}
}
@@ -221,7 +190,6 @@ impl Direction for DefaultLayout {
op_direction: Option<OperationDirection>,
idx: usize,
count: Option<usize>,
layout_options: Option<LayoutOptions>,
) -> usize {
match self {
Self::BSP => {
@@ -240,7 +208,7 @@ impl Direction for DefaultLayout {
1 => unreachable!(),
_ => 0,
},
Self::Grid => grid_neighbor(op_direction, idx, count, layout_options),
Self::Grid => grid_neighbor(op_direction, idx, count),
Self::Scrolling => idx - 1,
}
}
@@ -250,7 +218,6 @@ impl Direction for DefaultLayout {
op_direction: Option<OperationDirection>,
idx: usize,
count: Option<usize>,
layout_options: Option<LayoutOptions>,
) -> usize {
match self {
Self::BSP | Self::Columns | Self::HorizontalStack => idx + 1,
@@ -262,7 +229,7 @@ impl Direction for DefaultLayout {
0 => 2,
_ => unreachable!(),
},
Self::Grid => grid_neighbor(op_direction, idx, count, layout_options),
Self::Grid => grid_neighbor(op_direction, idx, count),
Self::Scrolling => idx + 1,
}
}
@@ -293,32 +260,21 @@ struct GridTouchingEdges {
clippy::cast_precision_loss,
clippy::cast_sign_loss
)]
fn get_grid_item(idx: usize, count: usize, layout_options: Option<LayoutOptions>) -> GridItem {
let row_constraint = layout_options.and_then(|o| o.grid.map(|g| g.rows));
let num_cols = if let Some(rows) = row_constraint {
((count as f32) / (rows as f32)).ceil() as i32
} else {
(count as f32).sqrt().ceil() as i32
};
fn get_grid_item(idx: usize, count: usize) -> GridItem {
let num_cols = (count as f32).sqrt().ceil() as usize;
let mut iter = 0;
for col in 0..num_cols {
let remaining_windows = (count - iter) as i32;
let remaining_windows = count - iter;
let remaining_columns = num_cols - col;
let num_rows_in_this_col = if let Some(rows) = row_constraint {
(remaining_windows / remaining_columns).min(rows as i32)
} else {
remaining_windows / remaining_columns
};
let num_rows_in_this_col = remaining_windows / remaining_columns;
for row in 0..num_rows_in_this_col {
if iter == idx {
return GridItem {
state: GridItemState::Valid,
row: (row + 1) as usize,
num_rows: num_rows_in_this_col as usize,
row: row + 1,
num_rows: num_rows_in_this_col,
touching_edges: GridTouchingEdges {
left: col == 0,
right: col == num_cols - 1,
@@ -345,13 +301,8 @@ fn get_grid_item(idx: usize, count: usize, layout_options: Option<LayoutOptions>
}
}
fn is_grid_edge(
op_direction: OperationDirection,
idx: usize,
count: usize,
layout_options: Option<LayoutOptions>,
) -> bool {
let item = get_grid_item(idx, count, layout_options);
fn is_grid_edge(op_direction: OperationDirection, idx: usize, count: usize) -> bool {
let item = get_grid_item(idx, count);
match item.state {
GridItemState::Invalid => false,
@@ -368,7 +319,6 @@ fn grid_neighbor(
op_direction: Option<OperationDirection>,
idx: usize,
count: Option<usize>,
layout_options: Option<LayoutOptions>,
) -> usize {
let Some(op_direction) = op_direction else {
return 0;
@@ -378,11 +328,11 @@ fn grid_neighbor(
return 0;
};
let item = get_grid_item(idx, count, layout_options);
let item = get_grid_item(idx, count);
match op_direction {
OperationDirection::Left => {
let item_from_prev_col = get_grid_item(idx - item.row, count, layout_options);
let item_from_prev_col = get_grid_item(idx - item.row, count);
if item.touching_edges.up && item.num_rows != item_from_prev_col.num_rows {
return idx - (item.num_rows - 1);
@@ -406,42 +356,36 @@ impl Direction for CustomLayout {
op_direction: OperationDirection,
idx: usize,
count: usize,
layout_options: Option<LayoutOptions>,
) -> Option<usize> {
if count <= self.len() {
return DefaultLayout::Columns.index_in_direction(
op_direction,
idx,
count,
layout_options,
);
return DefaultLayout::Columns.index_in_direction(op_direction, idx, count);
}
match op_direction {
OperationDirection::Left => {
if self.is_valid_direction(op_direction, idx, count, layout_options) {
Option::from(self.left_index(None, idx, None, layout_options))
if self.is_valid_direction(op_direction, idx, count) {
Option::from(self.left_index(None, idx, None))
} else {
None
}
}
OperationDirection::Right => {
if self.is_valid_direction(op_direction, idx, count, layout_options) {
Option::from(self.right_index(None, idx, None, layout_options))
if self.is_valid_direction(op_direction, idx, count) {
Option::from(self.right_index(None, idx, None))
} else {
None
}
}
OperationDirection::Up => {
if self.is_valid_direction(op_direction, idx, count, layout_options) {
Option::from(self.up_index(None, idx, None, layout_options))
if self.is_valid_direction(op_direction, idx, count) {
Option::from(self.up_index(None, idx, None))
} else {
None
}
}
OperationDirection::Down => {
if self.is_valid_direction(op_direction, idx, count, layout_options) {
Option::from(self.down_index(None, idx, None, layout_options))
if self.is_valid_direction(op_direction, idx, count) {
Option::from(self.down_index(None, idx, None))
} else {
None
}
@@ -454,15 +398,9 @@ impl Direction for CustomLayout {
op_direction: OperationDirection,
idx: usize,
count: usize,
layout_options: Option<LayoutOptions>,
) -> bool {
if count <= self.len() {
return DefaultLayout::Columns.is_valid_direction(
op_direction,
idx,
count,
layout_options,
);
return DefaultLayout::Columns.is_valid_direction(op_direction, idx, count);
}
match op_direction {
@@ -506,7 +444,6 @@ impl Direction for CustomLayout {
_op_direction: Option<OperationDirection>,
idx: usize,
_count: Option<usize>,
_layout_options: Option<LayoutOptions>,
) -> usize {
idx - 1
}
@@ -516,7 +453,6 @@ impl Direction for CustomLayout {
_op_direction: Option<OperationDirection>,
idx: usize,
_count: Option<usize>,
_layout_options: Option<LayoutOptions>,
) -> usize {
idx + 1
}
@@ -526,7 +462,6 @@ impl Direction for CustomLayout {
_op_direction: Option<OperationDirection>,
idx: usize,
_count: Option<usize>,
_layout_options: Option<LayoutOptions>,
) -> usize {
let column_idx = self.column_for_container_idx(idx);
if column_idx - 1 == 0 {
@@ -541,7 +476,6 @@ impl Direction for CustomLayout {
_op_direction: Option<OperationDirection>,
idx: usize,
_count: Option<usize>,
_layout_options: Option<LayoutOptions>,
) -> usize {
let column_idx = self.column_for_container_idx(idx);
self.first_container_idx(column_idx + 1)

View File

@@ -1,14 +1,14 @@
use std::num::NonZeroUsize;
use super::Axis;
use super::direction::Direction;
use crate::default_layout::LayoutOptions;
use clap::ValueEnum;
use serde::Deserialize;
use serde::Serialize;
use strum::Display;
use strum::EnumString;
use super::Axis;
use super::direction::Direction;
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum OperationDirection {
@@ -57,8 +57,7 @@ impl OperationDirection {
layout_flip: Option<Axis>,
idx: usize,
len: NonZeroUsize,
layout_options: Option<LayoutOptions>,
) -> Option<usize> {
layout.index_in_direction(self.flip(layout_flip), idx, len.get(), layout_options)
layout.index_in_direction(self.flip(layout_flip), idx, len.get())
}
}

View File

@@ -16,9 +16,7 @@ pub mod process_event;
pub mod process_movement;
pub mod reaper;
pub mod set_window_position;
pub mod splash;
pub mod stackbar_manager;
pub mod state;
pub mod static_config;
pub mod styles;
pub mod theme_manager;
@@ -72,7 +70,6 @@ use parking_lot::RwLock;
use regex::Regex;
use serde::Deserialize;
use serde::Serialize;
use state::State;
use uds_windows::UnixStream;
use which::which;
use winreg::RegKey;
@@ -256,21 +253,6 @@ pub static WINDOW_HANDLING_BEHAVIOUR: AtomicCell<WindowHandlingBehaviour> =
shadow_rs::shadow!(build);
pub const PUBLIC_KEY: [u8; 32] = [
0x5a, 0x69, 0x4a, 0xe1, 0x3c, 0x4b, 0xc8, 0x4e, 0xc3, 0x79, 0x0f, 0xab, 0x27, 0x6b, 0x7e, 0xdd,
0x6b, 0x39, 0x6f, 0xa2, 0xc3, 0x9f, 0x3d, 0x48, 0xf2, 0x72, 0x56, 0x41, 0x1b, 0xc8, 0x08, 0xdb,
];
#[derive(Default, Debug, Clone, PartialEq, Deserialize)]
pub struct License {
#[serde(rename = "hasValidSubscription")]
pub has_valid_subscription: bool,
pub timestamp: i64,
#[serde(rename = "currentEndPeriod")]
pub current_end_period: Option<i64>,
pub signature: String,
}
/// A trait for types that can be marked as locked or unlocked.
pub trait Lockable {
/// Returns `true` if the item is locked.

View File

@@ -50,10 +50,10 @@ use komorebi::process_event::listen_for_events;
use komorebi::process_movement::listen_for_movements;
use komorebi::reaper;
use komorebi::stackbar_manager;
use komorebi::state::State;
use komorebi::static_config::StaticConfig;
use komorebi::theme_manager;
use komorebi::transparency_manager;
use komorebi::window_manager::State;
use komorebi::window_manager::WindowManager;
use komorebi::windows_api::WindowsApi;
use komorebi::winevent_listener;

View File

@@ -4,6 +4,7 @@ use crate::DISPLAY_INDEX_PREFERENCES;
use crate::DUPLICATE_MONITOR_SERIAL_IDS;
use crate::Notification;
use crate::NotificationEvent;
use crate::State;
use crate::WORKSPACE_MATCHING_RULES;
use crate::WindowManager;
use crate::WindowsApi;
@@ -14,7 +15,6 @@ use crate::monitor;
use crate::monitor::Monitor;
use crate::monitor_reconciliator::hidden::Hidden;
use crate::notify_subscribers;
use crate::state::State;
use crossbeam_channel::Receiver;
use crossbeam_channel::Sender;
use crossbeam_utils::atomic::AtomicConsume;

View File

@@ -24,6 +24,7 @@ use crate::CUSTOM_FFM;
use crate::DATA_DIR;
use crate::DISPLAY_INDEX_PREFERENCES;
use crate::FLOATING_APPLICATIONS;
use crate::GlobalState;
use crate::HIDING_BEHAVIOUR;
use crate::IGNORE_IDENTIFIERS;
use crate::INITIAL_CONFIGURATION_LOADED;
@@ -39,6 +40,7 @@ use crate::SESSION_FLOATING_APPLICATIONS;
use crate::SUBSCRIPTION_PIPES;
use crate::SUBSCRIPTION_SOCKET_OPTIONS;
use crate::SUBSCRIPTION_SOCKETS;
use crate::State;
use crate::TCP_CONNECTIONS;
use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS;
use crate::WINDOWS_11;
@@ -79,14 +81,12 @@ use crate::notify_subscribers;
use crate::stackbar_manager;
use crate::stackbar_manager::STACKBAR_FONT_FAMILY;
use crate::stackbar_manager::STACKBAR_FONT_SIZE;
use crate::state;
use crate::state::GlobalState;
use crate::state::State;
use crate::static_config::StaticConfig;
use crate::theme_manager;
use crate::transparency_manager;
use crate::window::RuleDebug;
use crate::window::Window;
use crate::window_manager;
use crate::window_manager::WindowManager;
use crate::windows_api::WindowsApi;
use crate::winevent_listener;
@@ -923,7 +923,6 @@ impl WindowManager {
columns: count.into(),
center_focused_column: Default::default(),
}),
grid: None,
},
};
@@ -1359,7 +1358,8 @@ impl WindowManager {
self.set_workspace_name(monitor_idx, workspace_idx, name.to_string())?;
}
SocketMessage::State => {
let state = match serde_json::to_string_pretty(&state::State::from(&*self)) {
let state = match serde_json::to_string_pretty(&window_manager::State::from(&*self))
{
Ok(state) => state,
Err(error) => error.to_string(),
};

View File

@@ -1,4 +1,3 @@
use std::process::Command;
use std::sync::Arc;
use std::sync::atomic::Ordering;
@@ -20,6 +19,7 @@ use crate::Layout;
use crate::Notification;
use crate::NotificationEvent;
use crate::REGEX_IDENTIFIERS;
use crate::State;
use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS;
use crate::VirtualDesktopNotification;
use crate::Window;
@@ -28,10 +28,7 @@ use crate::border_manager::BORDER_OFFSET;
use crate::border_manager::BORDER_WIDTH;
use crate::current_virtual_desktop;
use crate::notify_subscribers;
use crate::splash;
use crate::splash::mdm_enrollment;
use crate::stackbar_manager;
use crate::state::State;
use crate::transparency_manager;
use crate::window::RuleDebug;
use crate::window::should_act;
@@ -45,24 +42,6 @@ use crate::workspace::WorkspaceLayer;
pub fn listen_for_events(wm: Arc<Mutex<WindowManager>>) {
let receiver = wm.lock().incoming_events.clone();
std::thread::spawn(|| {
loop {
if let Ok((mdm, server)) = mdm_enrollment() {
#[allow(clippy::collapsible_if)]
if mdm && splash::should().map(|f| f.into()).unwrap_or(true) {
let mut args = vec!["splash".to_string()];
if let Some(server) = server {
args.push(server);
}
let _ = Command::new("komorebic").args(&args).spawn();
}
}
std::thread::sleep(std::time::Duration::from_secs(14400));
}
});
std::thread::spawn(move || {
tracing::info!("listening");
loop {

View File

@@ -1,154 +0,0 @@
use crate::DATA_DIR;
use crate::License;
use crate::PUBLIC_KEY;
use base64::Engine;
use base64::engine::general_purpose;
use chrono::Duration;
use chrono::TimeZone;
use chrono::Utc;
use color_eyre::eyre;
use color_eyre::eyre::OptionExt;
use ed25519_dalek::Verifier;
use ed25519_dalek::VerifyingKey;
use std::path::PathBuf;
use std::process::Command;
pub fn mdm_enrollment() -> eyre::Result<(bool, Option<String>)> {
let mut command = Command::new("dsregcmd");
command.args(["/status"]);
let stdout = command.output()?.stdout;
let output = std::str::from_utf8(&stdout)?;
if !output.contains("MdmUrl") {
return Ok((false, None));
}
let mut server = None;
for line in output.lines() {
if line.contains("MdmUrl") {
let line = line.trim().to_string();
server = Some(line.trim_start_matches("MdmUrl : ").to_string())
}
}
Ok((true, server))
}
fn is_valid_payload(raw: &str, fresh: bool) -> eyre::Result<bool> {
let mut validation_successful = false;
let payload = serde_json::from_str::<License>(raw)?;
let signature = ed25519_dalek::Signature::from_slice(
general_purpose::STANDARD
.decode(&payload.signature)?
.as_slice(),
)?;
let mut value: serde_json::Value = serde_json::from_str(raw)?;
if let serde_json::Value::Object(ref mut map) = value {
map.remove("signature");
}
let message_to_verify = serde_json::to_string(&value)?;
let verifying_key = VerifyingKey::from_bytes(&PUBLIC_KEY)?;
if verifying_key
.verify(message_to_verify.as_bytes(), &signature)
.is_ok()
{
if fresh {
let timestamp = Utc
.timestamp_opt(payload.timestamp, 0)
.single()
.ok_or_eyre("invalid timestamp")?;
let valid_duration = Utc::now() - Duration::minutes(5);
if timestamp <= valid_duration {
tracing::debug!("individual commercial use license verification payload was stale");
return Ok(true);
}
}
if payload.has_valid_subscription
&& let Some(current_end_period) = payload.current_end_period
{
let subscription_valid_until = Utc
.timestamp_opt(current_end_period, 0)
.single()
.ok_or_eyre("invalid timestamp")?;
if Utc::now() <= subscription_valid_until {
tracing::debug!(
"individual commercial use license verification - subscription valid until: {subscription_valid_until}",
);
validation_successful = true;
}
}
}
Ok(validation_successful)
}
pub enum ValidationFeedback {
Successful(PathBuf),
Unsuccessful(String),
NoEmail,
NoConnectivity,
}
impl From<ValidationFeedback> for bool {
fn from(value: ValidationFeedback) -> Self {
match value {
ValidationFeedback::Successful(_) => false,
ValidationFeedback::Unsuccessful(_)
| ValidationFeedback::NoEmail
| ValidationFeedback::NoConnectivity => true,
}
}
}
pub fn should() -> eyre::Result<ValidationFeedback> {
let icul_validation = DATA_DIR.join("icul.validation");
if icul_validation.exists() {
tracing::debug!("found local individual commercial use license validation payload");
let raw_payload = std::fs::read_to_string(&icul_validation)?;
if is_valid_payload(&raw_payload, false)? {
return Ok(ValidationFeedback::Successful(icul_validation));
} else {
std::fs::remove_file(&icul_validation)?;
}
}
let icul = DATA_DIR.join("icul");
if !icul.exists() {
return Ok(ValidationFeedback::NoEmail);
}
let email = std::fs::read_to_string(icul)?;
tracing::debug!("found individual commercial use license email: {}", email);
let client = reqwest::blocking::Client::new();
let response = match client
.get("https://kw-icul.lgug2z.com")
.query(&[("email", email.trim())])
.send()
{
Ok(response) => response,
Err(error) => {
tracing::error!("{error}");
return Ok(ValidationFeedback::NoConnectivity);
}
};
let raw_payload = response.text()?;
if is_valid_payload(&raw_payload, true)? {
std::fs::write(&icul_validation, &raw_payload)?;
Ok(ValidationFeedback::Successful(icul_validation))
} else {
Ok(ValidationFeedback::Unsuccessful(raw_payload))
}
}

View File

@@ -1,306 +0,0 @@
use crate::BorderColours;
use crate::BorderStyle;
use crate::CURRENT_VIRTUAL_DESKTOP;
use crate::CUSTOM_FFM;
use crate::DATA_DIR;
use crate::DISPLAY_INDEX_PREFERENCES;
use crate::DUPLICATE_MONITOR_SERIAL_IDS;
use crate::FocusFollowsMouseImplementation;
use crate::HIDING_BEHAVIOUR;
use crate::HOME_DIR;
use crate::HidingBehaviour;
use crate::IGNORE_IDENTIFIERS;
use crate::LAYERED_WHITELIST;
use crate::MANAGE_IDENTIFIERS;
use crate::MONITOR_INDEX_PREFERENCES;
use crate::MoveBehaviour;
use crate::OBJECT_NAME_CHANGE_ON_LAUNCH;
use crate::OperationBehaviour;
use crate::REMOVE_TITLEBARS;
use crate::Rect;
use crate::StackbarLabel;
use crate::StackbarMode;
use crate::TRANSPARENCY_BLACKLIST;
use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS;
use crate::WORKSPACE_MATCHING_RULES;
use crate::WindowContainerBehaviour;
use crate::WindowManager;
use crate::border_manager;
use crate::border_manager::STYLE;
use crate::config_generation::MatchingRule;
use crate::config_generation::WorkspaceMatchingRule;
use crate::monitor::Monitor;
use crate::ring::Ring;
use crate::stackbar_manager::STACKBAR_FOCUSED_TEXT_COLOUR;
use crate::stackbar_manager::STACKBAR_LABEL;
use crate::stackbar_manager::STACKBAR_MODE;
use crate::stackbar_manager::STACKBAR_TAB_BACKGROUND_COLOUR;
use crate::stackbar_manager::STACKBAR_TAB_HEIGHT;
use crate::stackbar_manager::STACKBAR_TAB_WIDTH;
use crate::stackbar_manager::STACKBAR_UNFOCUSED_TEXT_COLOUR;
use crate::transparency_manager::TRANSPARENCY_ALPHA;
use crate::transparency_manager::TRANSPARENCY_ENABLED;
use crate::workspace::Workspace;
use komorebi_themes::colour::Colour;
use komorebi_themes::colour::Rgb;
use serde::Deserialize;
use serde::Serialize;
use std::collections::HashMap;
use std::collections::VecDeque;
use std::path::PathBuf;
use std::sync::atomic::Ordering;
#[allow(clippy::struct_excessive_bools)]
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct State {
pub monitors: Ring<Monitor>,
pub monitor_usr_idx_map: HashMap<usize, usize>,
pub is_paused: bool,
pub resize_delta: i32,
pub new_window_behaviour: WindowContainerBehaviour,
pub float_override: bool,
pub cross_monitor_move_behaviour: MoveBehaviour,
pub unmanaged_window_operation_behaviour: OperationBehaviour,
pub work_area_offset: Option<Rect>,
pub focus_follows_mouse: Option<FocusFollowsMouseImplementation>,
pub mouse_follows_focus: bool,
pub has_pending_raise_op: bool,
pub virtual_desktop_id: Option<Vec<u8>>,
}
impl State {
pub fn has_been_modified(&self, wm: &WindowManager) -> bool {
let new = Self::from(wm);
if self.monitors != new.monitors {
return true;
}
if self.is_paused != new.is_paused {
return true;
}
if self.new_window_behaviour != new.new_window_behaviour {
return true;
}
if self.float_override != new.float_override {
return true;
}
if self.cross_monitor_move_behaviour != new.cross_monitor_move_behaviour {
return true;
}
if self.unmanaged_window_operation_behaviour != new.unmanaged_window_operation_behaviour {
return true;
}
if self.work_area_offset != new.work_area_offset {
return true;
}
if self.focus_follows_mouse != new.focus_follows_mouse {
return true;
}
if self.mouse_follows_focus != new.mouse_follows_focus {
return true;
}
if self.has_pending_raise_op != new.has_pending_raise_op {
return true;
}
false
}
}
#[allow(clippy::struct_excessive_bools)]
#[derive(Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct GlobalState {
pub border_enabled: bool,
pub border_colours: BorderColours,
pub border_style: BorderStyle,
pub border_offset: i32,
pub border_width: i32,
pub stackbar_mode: StackbarMode,
pub stackbar_label: StackbarLabel,
pub stackbar_focused_text_colour: Colour,
pub stackbar_unfocused_text_colour: Colour,
pub stackbar_tab_background_colour: Colour,
pub stackbar_tab_width: i32,
pub stackbar_height: i32,
pub transparency_enabled: bool,
pub transparency_alpha: u8,
pub transparency_blacklist: Vec<MatchingRule>,
pub remove_titlebars: bool,
#[serde(alias = "float_identifiers")]
pub ignore_identifiers: Vec<MatchingRule>,
pub manage_identifiers: Vec<MatchingRule>,
pub layered_whitelist: Vec<MatchingRule>,
pub tray_and_multi_window_identifiers: Vec<MatchingRule>,
pub name_change_on_launch_identifiers: Vec<MatchingRule>,
pub monitor_index_preferences: HashMap<usize, Rect>,
pub display_index_preferences: HashMap<usize, String>,
pub ignored_duplicate_monitor_serial_ids: Vec<String>,
pub workspace_rules: Vec<WorkspaceMatchingRule>,
pub window_hiding_behaviour: HidingBehaviour,
pub configuration_dir: PathBuf,
pub data_dir: PathBuf,
pub custom_ffm: bool,
pub current_virtual_desktop_id: Option<Vec<u8>>,
}
impl Default for GlobalState {
fn default() -> Self {
Self {
border_enabled: border_manager::BORDER_ENABLED.load(Ordering::SeqCst),
border_colours: BorderColours {
single: Option::from(Colour::Rgb(Rgb::from(
border_manager::FOCUSED.load(Ordering::SeqCst),
))),
stack: Option::from(Colour::Rgb(Rgb::from(
border_manager::STACK.load(Ordering::SeqCst),
))),
monocle: Option::from(Colour::Rgb(Rgb::from(
border_manager::MONOCLE.load(Ordering::SeqCst),
))),
floating: Option::from(Colour::Rgb(Rgb::from(
border_manager::FLOATING.load(Ordering::SeqCst),
))),
unfocused: Option::from(Colour::Rgb(Rgb::from(
border_manager::UNFOCUSED.load(Ordering::SeqCst),
))),
unfocused_locked: Option::from(Colour::Rgb(Rgb::from(
border_manager::UNFOCUSED_LOCKED.load(Ordering::SeqCst),
))),
},
border_style: STYLE.load(),
border_offset: border_manager::BORDER_OFFSET.load(Ordering::SeqCst),
border_width: border_manager::BORDER_WIDTH.load(Ordering::SeqCst),
stackbar_mode: STACKBAR_MODE.load(),
stackbar_label: STACKBAR_LABEL.load(),
stackbar_focused_text_colour: Colour::Rgb(Rgb::from(
STACKBAR_FOCUSED_TEXT_COLOUR.load(Ordering::SeqCst),
)),
stackbar_unfocused_text_colour: Colour::Rgb(Rgb::from(
STACKBAR_UNFOCUSED_TEXT_COLOUR.load(Ordering::SeqCst),
)),
stackbar_tab_background_colour: Colour::Rgb(Rgb::from(
STACKBAR_TAB_BACKGROUND_COLOUR.load(Ordering::SeqCst),
)),
stackbar_tab_width: STACKBAR_TAB_WIDTH.load(Ordering::SeqCst),
stackbar_height: STACKBAR_TAB_HEIGHT.load(Ordering::SeqCst),
transparency_enabled: TRANSPARENCY_ENABLED.load(Ordering::SeqCst),
transparency_alpha: TRANSPARENCY_ALPHA.load(Ordering::SeqCst),
transparency_blacklist: TRANSPARENCY_BLACKLIST.lock().clone(),
remove_titlebars: REMOVE_TITLEBARS.load(Ordering::SeqCst),
ignore_identifiers: IGNORE_IDENTIFIERS.lock().clone(),
manage_identifiers: MANAGE_IDENTIFIERS.lock().clone(),
layered_whitelist: LAYERED_WHITELIST.lock().clone(),
tray_and_multi_window_identifiers: TRAY_AND_MULTI_WINDOW_IDENTIFIERS.lock().clone(),
name_change_on_launch_identifiers: OBJECT_NAME_CHANGE_ON_LAUNCH.lock().clone(),
monitor_index_preferences: MONITOR_INDEX_PREFERENCES.lock().clone(),
display_index_preferences: DISPLAY_INDEX_PREFERENCES.read().clone(),
ignored_duplicate_monitor_serial_ids: DUPLICATE_MONITOR_SERIAL_IDS.read().clone(),
workspace_rules: WORKSPACE_MATCHING_RULES.lock().clone(),
window_hiding_behaviour: *HIDING_BEHAVIOUR.lock(),
configuration_dir: HOME_DIR.clone(),
data_dir: DATA_DIR.clone(),
custom_ffm: CUSTOM_FFM.load(Ordering::SeqCst),
current_virtual_desktop_id: CURRENT_VIRTUAL_DESKTOP.lock().clone(),
}
}
}
impl From<&WindowManager> for State {
fn from(wm: &WindowManager) -> Self {
// This is used to remove any information that doesn't need to be passed on to subscribers
// or to be shown with the `komorebic state` command. Currently it is only removing the
// `workspace_config` field from every workspace, but more stripping can be added later if
// needed.
let mut stripped_monitors = Ring::default();
*stripped_monitors.elements_mut() = wm
.monitors()
.iter()
.map(|monitor| Monitor {
id: monitor.id,
name: monitor.name.clone(),
device: monitor.device.clone(),
device_id: monitor.device_id.clone(),
serial_number_id: monitor.serial_number_id.clone(),
size: monitor.size,
work_area_size: monitor.work_area_size,
work_area_offset: monitor.work_area_offset,
window_based_work_area_offset: monitor.window_based_work_area_offset,
window_based_work_area_offset_limit: monitor.window_based_work_area_offset_limit,
workspaces: {
let mut ws = Ring::default();
*ws.elements_mut() = monitor
.workspaces()
.iter()
.map(|workspace| Workspace {
name: workspace.name.clone(),
containers: workspace.containers.clone(),
monocle_container: workspace.monocle_container.clone(),
monocle_container_restore_idx: workspace.monocle_container_restore_idx,
maximized_window: workspace.maximized_window,
maximized_window_restore_idx: workspace.maximized_window_restore_idx,
floating_windows: workspace.floating_windows.clone(),
layout: workspace.layout.clone(),
layout_options: workspace.layout_options,
layout_rules: workspace.layout_rules.clone(),
layout_flip: workspace.layout_flip,
workspace_padding: workspace.workspace_padding,
container_padding: workspace.container_padding,
latest_layout: workspace.latest_layout.clone(),
resize_dimensions: workspace.resize_dimensions.clone(),
tile: workspace.tile,
work_area_offset: workspace.work_area_offset,
apply_window_based_work_area_offset: workspace
.apply_window_based_work_area_offset,
window_container_behaviour: workspace.window_container_behaviour,
window_container_behaviour_rules: workspace
.window_container_behaviour_rules
.clone(),
float_override: workspace.float_override,
layer: workspace.layer,
floating_layer_behaviour: workspace.floating_layer_behaviour,
globals: workspace.globals,
wallpaper: workspace.wallpaper.clone(),
workspace_config: None,
})
.collect::<VecDeque<_>>();
ws.focus(monitor.workspaces.focused_idx());
ws
},
last_focused_workspace: monitor.last_focused_workspace,
workspace_names: monitor.workspace_names.clone(),
container_padding: monitor.container_padding,
workspace_padding: monitor.workspace_padding,
wallpaper: monitor.wallpaper.clone(),
floating_layer_behaviour: monitor.floating_layer_behaviour,
})
.collect::<VecDeque<_>>();
stripped_monitors.focus(wm.monitors.focused_idx());
Self {
monitors: stripped_monitors,
monitor_usr_idx_map: wm.monitor_usr_idx_map.clone(),
is_paused: wm.is_paused,
work_area_offset: wm.work_area_offset,
resize_delta: wm.resize_delta,
new_window_behaviour: wm.window_management_behaviour.current_behaviour,
float_override: wm.window_management_behaviour.float_override,
cross_monitor_move_behaviour: wm.cross_monitor_move_behaviour,
focus_follows_mouse: wm.focus_follows_mouse,
mouse_follows_focus: wm.mouse_follows_focus,
has_pending_raise_op: wm.has_pending_raise_op,
unmanaged_window_operation_behaviour: wm.unmanaged_window_operation_behaviour,
virtual_desktop_id: wm.virtual_desktop_id.clone(),
}
}
}

View File

@@ -17,7 +17,6 @@ use crate::WindowsApi;
use crate::should_act;
pub static TRANSPARENCY_ENABLED: AtomicBool = AtomicBool::new(false);
pub static TRANSPARENCY_ENABLED_OVERRIDE: AtomicBool = AtomicBool::new(false);
pub static TRANSPARENCY_ALPHA: AtomicU8 = AtomicU8::new(200);
static KNOWN_HWNDS: OnceLock<Mutex<Vec<isize>>> = OnceLock::new();

View File

@@ -19,6 +19,8 @@ use hotwatch::EventKind;
use hotwatch::Hotwatch;
use hotwatch::notify::ErrorKind as NotifyErrorKind;
use parking_lot::Mutex;
use serde::Deserialize;
use serde::Serialize;
use uds_windows::UnixListener;
use uds_windows::UnixStream;
@@ -28,40 +30,69 @@ use crate::animation::AnimationEngine;
use crate::core::Arrangement;
use crate::core::Axis;
use crate::core::BorderImplementation;
use crate::core::BorderStyle;
use crate::core::CycleDirection;
use crate::core::DefaultLayout;
use crate::core::FocusFollowsMouseImplementation;
use crate::core::HidingBehaviour;
use crate::core::Layout;
use crate::core::MoveBehaviour;
use crate::core::OperationBehaviour;
use crate::core::OperationDirection;
use crate::core::Rect;
use crate::core::Sizing;
use crate::core::StackbarLabel;
use crate::core::WindowContainerBehaviour;
use crate::core::WindowManagementBehaviour;
use crate::core::config_generation::MatchingRule;
use crate::core::custom_layout::CustomLayout;
use crate::BorderColours;
use crate::CUSTOM_FFM;
use crate::Colour;
use crate::CrossBoundaryBehaviour;
use crate::DATA_DIR;
use crate::DISPLAY_INDEX_PREFERENCES;
use crate::DUPLICATE_MONITOR_SERIAL_IDS;
use crate::HIDING_BEHAVIOUR;
use crate::HOME_DIR;
use crate::IGNORE_IDENTIFIERS;
use crate::LAYERED_WHITELIST;
use crate::MANAGE_IDENTIFIERS;
use crate::MONITOR_INDEX_PREFERENCES;
use crate::NO_TITLEBAR;
use crate::OBJECT_NAME_CHANGE_ON_LAUNCH;
use crate::REGEX_IDENTIFIERS;
use crate::REMOVE_TITLEBARS;
use crate::Rgb;
use crate::SUBSCRIPTION_SOCKETS;
use crate::TRANSPARENCY_BLACKLIST;
use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS;
use crate::WORKSPACE_MATCHING_RULES;
use crate::border_manager;
use crate::border_manager::BORDER_OFFSET;
use crate::border_manager::BORDER_WIDTH;
use crate::border_manager::STYLE;
use crate::config_generation::WorkspaceMatchingRule;
use crate::container::Container;
use crate::core::StackbarMode;
use crate::current_virtual_desktop;
use crate::load_configuration;
use crate::monitor::Monitor;
use crate::ring::Ring;
use crate::should_act;
use crate::should_act_individual;
use crate::state::State;
use crate::stackbar_manager::STACKBAR_FOCUSED_TEXT_COLOUR;
use crate::stackbar_manager::STACKBAR_LABEL;
use crate::stackbar_manager::STACKBAR_MODE;
use crate::stackbar_manager::STACKBAR_TAB_BACKGROUND_COLOUR;
use crate::stackbar_manager::STACKBAR_TAB_HEIGHT;
use crate::stackbar_manager::STACKBAR_TAB_WIDTH;
use crate::stackbar_manager::STACKBAR_UNFOCUSED_TEXT_COLOUR;
use crate::static_config::StaticConfig;
use crate::transparency_manager;
use crate::transparency_manager::TRANSPARENCY_ALPHA;
use crate::transparency_manager::TRANSPARENCY_ENABLED;
use crate::window::Window;
use crate::window_manager_event::WindowManagerEvent;
use crate::windows_api::WindowsApi;
@@ -94,12 +125,263 @@ pub struct WindowManager {
pub known_hwnds: HashMap<isize, (usize, usize)>,
}
#[allow(clippy::struct_excessive_bools)]
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct State {
pub monitors: Ring<Monitor>,
pub monitor_usr_idx_map: HashMap<usize, usize>,
pub is_paused: bool,
pub resize_delta: i32,
pub new_window_behaviour: WindowContainerBehaviour,
pub float_override: bool,
pub cross_monitor_move_behaviour: MoveBehaviour,
pub unmanaged_window_operation_behaviour: OperationBehaviour,
pub work_area_offset: Option<Rect>,
pub focus_follows_mouse: Option<FocusFollowsMouseImplementation>,
pub mouse_follows_focus: bool,
pub has_pending_raise_op: bool,
}
impl State {
pub fn has_been_modified(&self, wm: &WindowManager) -> bool {
let new = Self::from(wm);
if self.monitors != new.monitors {
return true;
}
if self.is_paused != new.is_paused {
return true;
}
if self.new_window_behaviour != new.new_window_behaviour {
return true;
}
if self.float_override != new.float_override {
return true;
}
if self.cross_monitor_move_behaviour != new.cross_monitor_move_behaviour {
return true;
}
if self.unmanaged_window_operation_behaviour != new.unmanaged_window_operation_behaviour {
return true;
}
if self.work_area_offset != new.work_area_offset {
return true;
}
if self.focus_follows_mouse != new.focus_follows_mouse {
return true;
}
if self.mouse_follows_focus != new.mouse_follows_focus {
return true;
}
if self.has_pending_raise_op != new.has_pending_raise_op {
return true;
}
false
}
}
#[allow(clippy::struct_excessive_bools)]
#[derive(Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct GlobalState {
pub border_enabled: bool,
pub border_colours: BorderColours,
pub border_style: BorderStyle,
pub border_offset: i32,
pub border_width: i32,
pub stackbar_mode: StackbarMode,
pub stackbar_label: StackbarLabel,
pub stackbar_focused_text_colour: Colour,
pub stackbar_unfocused_text_colour: Colour,
pub stackbar_tab_background_colour: Colour,
pub stackbar_tab_width: i32,
pub stackbar_height: i32,
pub transparency_enabled: bool,
pub transparency_alpha: u8,
pub transparency_blacklist: Vec<MatchingRule>,
pub remove_titlebars: bool,
#[serde(alias = "float_identifiers")]
pub ignore_identifiers: Vec<MatchingRule>,
pub manage_identifiers: Vec<MatchingRule>,
pub layered_whitelist: Vec<MatchingRule>,
pub tray_and_multi_window_identifiers: Vec<MatchingRule>,
pub name_change_on_launch_identifiers: Vec<MatchingRule>,
pub monitor_index_preferences: HashMap<usize, Rect>,
pub display_index_preferences: HashMap<usize, String>,
pub ignored_duplicate_monitor_serial_ids: Vec<String>,
pub workspace_rules: Vec<WorkspaceMatchingRule>,
pub window_hiding_behaviour: HidingBehaviour,
pub configuration_dir: PathBuf,
pub data_dir: PathBuf,
pub custom_ffm: bool,
}
impl Default for GlobalState {
fn default() -> Self {
Self {
border_enabled: border_manager::BORDER_ENABLED.load(Ordering::SeqCst),
border_colours: BorderColours {
single: Option::from(Colour::Rgb(Rgb::from(
border_manager::FOCUSED.load(Ordering::SeqCst),
))),
stack: Option::from(Colour::Rgb(Rgb::from(
border_manager::STACK.load(Ordering::SeqCst),
))),
monocle: Option::from(Colour::Rgb(Rgb::from(
border_manager::MONOCLE.load(Ordering::SeqCst),
))),
floating: Option::from(Colour::Rgb(Rgb::from(
border_manager::FLOATING.load(Ordering::SeqCst),
))),
unfocused: Option::from(Colour::Rgb(Rgb::from(
border_manager::UNFOCUSED.load(Ordering::SeqCst),
))),
unfocused_locked: Option::from(Colour::Rgb(Rgb::from(
border_manager::UNFOCUSED_LOCKED.load(Ordering::SeqCst),
))),
},
border_style: STYLE.load(),
border_offset: border_manager::BORDER_OFFSET.load(Ordering::SeqCst),
border_width: border_manager::BORDER_WIDTH.load(Ordering::SeqCst),
stackbar_mode: STACKBAR_MODE.load(),
stackbar_label: STACKBAR_LABEL.load(),
stackbar_focused_text_colour: Colour::Rgb(Rgb::from(
STACKBAR_FOCUSED_TEXT_COLOUR.load(Ordering::SeqCst),
)),
stackbar_unfocused_text_colour: Colour::Rgb(Rgb::from(
STACKBAR_UNFOCUSED_TEXT_COLOUR.load(Ordering::SeqCst),
)),
stackbar_tab_background_colour: Colour::Rgb(Rgb::from(
STACKBAR_TAB_BACKGROUND_COLOUR.load(Ordering::SeqCst),
)),
stackbar_tab_width: STACKBAR_TAB_WIDTH.load(Ordering::SeqCst),
stackbar_height: STACKBAR_TAB_HEIGHT.load(Ordering::SeqCst),
transparency_enabled: TRANSPARENCY_ENABLED.load(Ordering::SeqCst),
transparency_alpha: TRANSPARENCY_ALPHA.load(Ordering::SeqCst),
transparency_blacklist: TRANSPARENCY_BLACKLIST.lock().clone(),
remove_titlebars: REMOVE_TITLEBARS.load(Ordering::SeqCst),
ignore_identifiers: IGNORE_IDENTIFIERS.lock().clone(),
manage_identifiers: MANAGE_IDENTIFIERS.lock().clone(),
layered_whitelist: LAYERED_WHITELIST.lock().clone(),
tray_and_multi_window_identifiers: TRAY_AND_MULTI_WINDOW_IDENTIFIERS.lock().clone(),
name_change_on_launch_identifiers: OBJECT_NAME_CHANGE_ON_LAUNCH.lock().clone(),
monitor_index_preferences: MONITOR_INDEX_PREFERENCES.lock().clone(),
display_index_preferences: DISPLAY_INDEX_PREFERENCES.read().clone(),
ignored_duplicate_monitor_serial_ids: DUPLICATE_MONITOR_SERIAL_IDS.read().clone(),
workspace_rules: WORKSPACE_MATCHING_RULES.lock().clone(),
window_hiding_behaviour: *HIDING_BEHAVIOUR.lock(),
configuration_dir: HOME_DIR.clone(),
data_dir: DATA_DIR.clone(),
custom_ffm: CUSTOM_FFM.load(Ordering::SeqCst),
}
}
}
impl AsRef<Self> for WindowManager {
fn as_ref(&self) -> &Self {
self
}
}
impl From<&WindowManager> for State {
fn from(wm: &WindowManager) -> Self {
// This is used to remove any information that doesn't need to be passed on to subscribers
// or to be shown with the `komorebic state` command. Currently it is only removing the
// `workspace_config` field from every workspace, but more stripping can be added later if
// needed.
let mut stripped_monitors = Ring::default();
*stripped_monitors.elements_mut() = wm
.monitors()
.iter()
.map(|monitor| Monitor {
id: monitor.id,
name: monitor.name.clone(),
device: monitor.device.clone(),
device_id: monitor.device_id.clone(),
serial_number_id: monitor.serial_number_id.clone(),
size: monitor.size,
work_area_size: monitor.work_area_size,
work_area_offset: monitor.work_area_offset,
window_based_work_area_offset: monitor.window_based_work_area_offset,
window_based_work_area_offset_limit: monitor.window_based_work_area_offset_limit,
workspaces: {
let mut ws = Ring::default();
*ws.elements_mut() = monitor
.workspaces()
.iter()
.map(|workspace| Workspace {
name: workspace.name.clone(),
containers: workspace.containers.clone(),
monocle_container: workspace.monocle_container.clone(),
monocle_container_restore_idx: workspace.monocle_container_restore_idx,
maximized_window: workspace.maximized_window,
maximized_window_restore_idx: workspace.maximized_window_restore_idx,
floating_windows: workspace.floating_windows.clone(),
layout: workspace.layout.clone(),
layout_options: workspace.layout_options,
layout_rules: workspace.layout_rules.clone(),
layout_flip: workspace.layout_flip,
workspace_padding: workspace.workspace_padding,
container_padding: workspace.container_padding,
latest_layout: workspace.latest_layout.clone(),
resize_dimensions: workspace.resize_dimensions.clone(),
tile: workspace.tile,
work_area_offset: workspace.work_area_offset,
apply_window_based_work_area_offset: workspace
.apply_window_based_work_area_offset,
window_container_behaviour: workspace.window_container_behaviour,
window_container_behaviour_rules: workspace
.window_container_behaviour_rules
.clone(),
float_override: workspace.float_override,
layer: workspace.layer,
floating_layer_behaviour: workspace.floating_layer_behaviour,
globals: workspace.globals,
wallpaper: workspace.wallpaper.clone(),
workspace_config: None,
})
.collect::<VecDeque<_>>();
ws.focus(monitor.workspaces.focused_idx());
ws
},
last_focused_workspace: monitor.last_focused_workspace,
workspace_names: monitor.workspace_names.clone(),
container_padding: monitor.container_padding,
workspace_padding: monitor.workspace_padding,
wallpaper: monitor.wallpaper.clone(),
floating_layer_behaviour: monitor.floating_layer_behaviour,
})
.collect::<VecDeque<_>>();
stripped_monitors.focus(wm.monitors.focused_idx());
Self {
monitors: stripped_monitors,
monitor_usr_idx_map: wm.monitor_usr_idx_map.clone(),
is_paused: wm.is_paused,
work_area_offset: wm.work_area_offset,
resize_delta: wm.resize_delta,
new_window_behaviour: wm.window_management_behaviour.current_behaviour,
float_override: wm.window_management_behaviour.float_override,
cross_monitor_move_behaviour: wm.cross_monitor_move_behaviour,
focus_follows_mouse: wm.focus_follows_mouse,
mouse_follows_focus: wm.mouse_follows_focus,
has_pending_raise_op: wm.has_pending_raise_op,
unmanaged_window_operation_behaviour: wm.unmanaged_window_operation_behaviour,
}
}
}
impl_ring_elements!(WindowManager, Monitor);
#[derive(Debug, Clone, Copy)]
@@ -1275,7 +1557,6 @@ impl WindowManager {
workspace.layout_flip,
focused_idx,
len,
workspace.layout_options,
)
.is_some()
{
@@ -2682,10 +2963,7 @@ impl WindowManager {
#[tracing::instrument(skip(self))]
pub fn stack_all(&mut self) -> eyre::Result<()> {
if transparency_manager::TRANSPARENCY_ENABLED.load(Ordering::SeqCst) {
transparency_manager::TRANSPARENCY_ENABLED.store(false, Ordering::SeqCst);
transparency_manager::TRANSPARENCY_ENABLED_OVERRIDE.store(true, Ordering::SeqCst);
}
self.unstack_all(false)?;
self.handle_unmanaged_window_behaviour()?;
tracing::info!("stacking all windows on workspace");
@@ -2699,27 +2977,16 @@ impl WindowManager {
focused_hwnd = Some(window.hwnd);
}
let workspace_hwnds =
workspace
.containers()
.iter()
.fold(VecDeque::new(), |mut hwnds, c| {
hwnds.extend(c.windows().clone());
hwnds
});
let mut container = Container::default();
*container.windows_mut() = workspace_hwnds;
*workspace.containers_mut() = VecDeque::from([container]);
workspace.focus_container(0);
if let Some(hwnd) = focused_hwnd
&& let Some(c) = workspace.focused_container_mut()
&& let Some(w_idx_to_focus) = c.idx_for_window(hwnd)
{
c.focus_window(w_idx_to_focus);
c.load_focused_window();
workspace.focus_container(workspace.containers().len().saturating_sub(1));
while workspace.focused_container_idx() > 0 {
workspace.move_window_to_container(0)?;
workspace.focus_container(workspace.containers().len().saturating_sub(1));
}
if let Some(hwnd) = focused_hwnd {
workspace.focus_container_by_window(hwnd)?;
}
self.update_focused_workspace(self.mouse_follows_focus, true)
}
@@ -2754,11 +3021,6 @@ impl WindowManager {
workspace.focus_container_by_window(hwnd)?;
}
if transparency_manager::TRANSPARENCY_ENABLED_OVERRIDE.load(Ordering::SeqCst) {
transparency_manager::TRANSPARENCY_ENABLED.store(true, Ordering::SeqCst);
transparency_manager::TRANSPARENCY_ENABLED_OVERRIDE.store(false, Ordering::SeqCst);
}
if update_workspace {
self.update_focused_workspace(self.mouse_follows_focus, true)?;
}
@@ -2783,7 +3045,6 @@ impl WindowManager {
workspace.layout_flip,
workspace.focused_container_idx(),
len,
workspace.layout_options,
)
.is_some();

View File

@@ -984,7 +984,6 @@ impl Workspace {
self.layout_flip,
self.focused_container_idx(),
len,
self.layout_options,
)
}

View File

@@ -18,7 +18,6 @@ dunce = { workspace = true }
fs-tail = "0.1"
lazy_static = { workspace = true }
miette = { version = "7", features = ["fancy"] }
open = "5"
paste = { workspace = true }
powershell_script = "1.0"
reqwest = { version = "0.12", features = ["blocking"] }
@@ -29,7 +28,6 @@ shadow-rs = { workspace = true }
sysinfo = { workspace = true }
thiserror = "2"
which = { workspace = true }
win-msgbox = "0.2"
windows = { workspace = true }
[build-dependencies]

View File

@@ -4,7 +4,6 @@
use chrono::Utc;
use komorebi_client::PathExt;
use komorebi_client::replace_env_in_path;
use komorebi_client::splash;
use std::fs::File;
use std::fs::OpenOptions;
use std::io;
@@ -39,7 +38,6 @@ use paste::paste;
use serde::Deserialize;
use sysinfo::ProcessesToUpdate;
use which::which;
use win_msgbox::OkayCancel;
use windows::Win32::Foundation::HWND;
use windows::Win32::UI::WindowsAndMessaging::SHOW_WINDOW_CMD;
use windows::Win32::UI::WindowsAndMessaging::SW_RESTORE;
@@ -61,7 +59,6 @@ use komorebi_client::SocketMessage;
use komorebi_client::StateQuery;
use komorebi_client::StaticConfig;
use komorebi_client::WindowKind;
use komorebi_client::splash::ValidationFeedback;
lazy_static! {
static ref HAS_CUSTOM_CONFIG_HOME: AtomicBool = AtomicBool::new(false);
@@ -805,7 +802,6 @@ struct Start {
#[clap(long)]
whkd: bool,
/// Start autohotkey configuration file
#[clap(hide = true)]
#[clap(long)]
ahk: bool,
/// Start komorebi-bar in a background process
@@ -825,7 +821,6 @@ struct Stop {
#[clap(long)]
whkd: bool,
/// Stop ahk if it is running as a background process
#[clap(hide = true)]
#[clap(long)]
ahk: bool,
/// Stop komorebi-bar if it is running as a background process
@@ -845,7 +840,6 @@ struct Kill {
#[clap(long)]
whkd: bool,
/// Kill ahk if it is running as a background process
#[clap(hide = true)]
#[clap(long)]
ahk: bool,
/// Kill komorebi-bar if it is running as a background process
@@ -955,7 +949,6 @@ struct EnableAutostart {
#[clap(long)]
whkd: bool,
/// Enable autostart of ahk
#[clap(hide = true)]
#[clap(long)]
ahk: bool,
/// Enable autostart of komorebi-bar
@@ -993,17 +986,6 @@ struct ScrollingLayoutColumns {
count: NonZeroUsize,
}
#[derive(Parser)]
struct License {
/// Email address associated with an Individual Commercial Use License
email: String,
}
#[derive(Parser)]
struct Splash {
mdm_server: Option<String>,
}
#[derive(Parser)]
#[clap(author, about, version = build::CLAP_LONG_VERSION)]
struct Opts {
@@ -1015,13 +997,8 @@ struct Opts {
enum SubCommand {
#[clap(hide = true)]
Docgen,
#[clap(hide = true)]
Splash(Splash),
/// Gather example configurations for a new-user quickstart
Quickstart,
/// Specify an email associated with an Individual Commercial Use License
#[clap(arg_required_else_help = true)]
License(License),
/// Start komorebi.exe as a background process
Start(Start),
/// Stop the komorebi.exe process and restore all hidden windows
@@ -1580,7 +1557,6 @@ fn main() -> eyre::Result<()> {
let ignore = [
"docgen",
"splash",
"alt-focus-hack",
"identify-border-overflow-application",
"load-custom-layout",
@@ -1604,72 +1580,6 @@ fn main() -> eyre::Result<()> {
}
}
}
SubCommand::Splash(arg) => {
let informative_text = match arg.mdm_server {
None => {
"It looks like you are using a corporate device enrolled in mobile device management\n\n\
The Komorebi License does not permit any kind of commercial use\n\n\
A dedicated Individual Commercial Use License is available if you wish to use this software at work\n\n\
You are strongly encouraged to make your employer pay for your license, either directly or via reimbursement\n\n\
To remove this popup in the future, run \"komorebic license <email>\" using the email address associated with your license".to_string()
}
Some(server) => {
format!(
"It looks like you are using a corporate device enrolled in mobile device management ({server})\n\n\
The Komorebi License does not permit any kind of commercial use\n\n\
A dedicated Individual Commercial Use License is available if you wish to use this software at work\n\n\
You are strongly encouraged to make your employer pay for your license, either directly or via reimbursement\n\n\
To remove this popup in the future you can run \"komorebic license <email>\" using the email address associated with your license"
)
}
};
if let Ok(response) = win_msgbox::error::<OkayCancel>(&informative_text)
.title("MDM Enrollment Detected")
.topmost()
.icon(win_msgbox::Icon::Warning)
.set_foreground()
.show()
{
match response {
OkayCancel::Okay => {
open::that("https://lgug2z.com/software/komorebi")?;
}
OkayCancel::Cancel => {}
}
}
}
SubCommand::License(arg) => {
let _ = std::fs::remove_file(DATA_DIR.join("icul.validation"));
std::fs::write(DATA_DIR.join("icul"), &arg.email)?;
match splash::should()? {
ValidationFeedback::Successful(icul_validation) => {
println!("Individual commercial use license validation successful");
println!(
"Local validation file saved to {}",
icul_validation.display()
);
println!("\n{}", std::fs::read_to_string(&icul_validation)?);
}
ValidationFeedback::Unsuccessful(invalid_payload) => {
println!(
"No active individual commercial use license found for {}",
arg.email
);
println!("\n{invalid_payload}");
println!(
"\nYou can purchase an individual commercial use license at https://lgug2z.com/software/komorebi"
);
}
ValidationFeedback::NoEmail => {}
ValidationFeedback::NoConnectivity => {
println!(
"Could not make a connection to validate an individual commercial use license for {}",
arg.email
);
}
}
}
SubCommand::Quickstart => {
fn write_file_with_prompt(
path: &PathBuf,
@@ -1736,40 +1646,9 @@ fn main() -> eyre::Result<()> {
written_files.join("\n")
);
}
if let Ok((mdm, server)) = splash::mdm_enrollment()
&& mdm
{
if let Some(server) = server {
println!(
"\nIt looks like you are using a corporate device enrolled in mobile device management ({server})"
);
} else {
println!(
"\nIt looks like you are using a corporate device enrolled in mobile device management"
);
}
println!("The Komorebi License does not permit any kind of commercial use");
println!(
"A dedicated Individual Commercial Use License is available if you wish to use this software at work"
);
println!(
"You are strongly encouraged to make your employer pay for your license, either directly or via reimbursement"
);
println!(
"If you already have a license, you can run \"komorebic license <email>\" with the email address your license is associated with"
);
}
println!("\nYou can now run komorebic start --whkd --bar");
}
SubCommand::EnableAutostart(arg) => {
if arg.ahk {
println!(
"EOL: The --ahk flag is now end-of-life and will not receive any further updates or bug fixes"
);
}
SubCommand::EnableAutostart(args) => {
let mut current_exe = std::env::current_exe().expect("unable to get exec path");
current_exe.pop();
let komorebic_exe = current_exe.join("komorebic-no-console.exe");
@@ -1781,26 +1660,26 @@ fn main() -> eyre::Result<()> {
let mut arguments = String::from("start");
if let Some(config) = arg.config {
if let Some(config) = args.config {
arguments.push_str(" --config ");
arguments.push_str(&config.to_string_lossy());
}
if arg.ffm {
if args.ffm {
arguments.push_str(" --ffm");
}
if arg.bar {
if args.bar {
arguments.push_str(" --bar");
}
if arg.whkd {
if args.whkd {
arguments.push_str(" --whkd");
} else if arg.ahk {
} else if args.ahk {
arguments.push_str(" --ahk");
}
if arg.masir {
if args.masir {
arguments.push_str(" --masir");
}
@@ -2301,12 +2180,6 @@ fn main() -> eyre::Result<()> {
))?;
}
SubCommand::Start(arg) => {
if arg.ahk {
println!(
"EOL: The --ahk flag is now end-of-life and will not receive any further updates or bug fixes"
);
}
let mut ahk: String = String::from("autohotkey.exe");
if let Ok(komorebi_ahk_exe) = std::env::var("KOMOREBI_AHK_EXE")
@@ -2612,12 +2485,6 @@ if (!(Get-Process masir -ErrorAction SilentlyContinue))
}
}
SubCommand::Stop(arg) => {
if arg.ahk {
println!(
"EOL: The --ahk flag is now end-of-life and will not receive any further updates or bug fixes"
);
}
if arg.whkd {
let script = r"
Stop-Process -Name:whkd -ErrorAction SilentlyContinue
@@ -2724,12 +2591,6 @@ Stop-Process -Name:komorebi -ErrorAction SilentlyContinue
}
}
SubCommand::Kill(arg) => {
if arg.ahk {
println!(
"EOL: The --ahk flag is now end-of-life and will not receive any further updates or bug fixes"
);
}
if arg.whkd {
let script = r"
Stop-Process -Name:whkd -ErrorAction SilentlyContinue

View File

@@ -84,7 +84,6 @@ nav:
- common-workflows/multi-monitor-setup.md
- CLI reference:
- cli/quickstart.md
- cli/license.md
- cli/start.md
- cli/stop.md
- cli/kill.md
@@ -256,4 +255,4 @@ nav:
- cli/static-config-schema.md
- cli/generate-static-config.md
- cli/enable-autostart.md
- cli/disable-autostart.md
- cli/disable-autostart.md

View File

@@ -1807,21 +1807,6 @@
"description": "Layout-specific options (default: None)",
"type": "object",
"properties": {
"grid": {
"description": "Options related to the Grid layout",
"type": "object",
"required": [
"rows"
],
"properties": {
"rows": {
"description": "Maximum number of rows per grid column",
"type": "integer",
"format": "uint",
"minimum": 0.0
}
}
},
"scrolling": {
"description": "Options related to the Scrolling layout",
"type": "object",