mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-02-15 17:57:40 +01:00
Compare commits
5 Commits
v0.1.35
...
feature/lo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
072a62c314 | ||
|
|
a95e6e9644 | ||
|
|
6ba19d3ea2 | ||
|
|
edf1943157 | ||
|
|
d0c847e5bc |
226
Cargo.lock
generated
226
Cargo.lock
generated
@@ -468,9 +468,9 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.87"
|
||||
version = "0.1.88"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d556ec1359574147ec0c4fc5eb525f3f23263a592b1a9c07e0a75b427de55c97"
|
||||
checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -728,9 +728,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck_derive"
|
||||
version = "1.8.1"
|
||||
version = "1.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a"
|
||||
checksum = "2ff22c2722516255d1823ce3cc4bc0b154dbc9364be5c905d6baa6eccbbc8774"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -791,9 +791,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.16"
|
||||
version = "1.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c"
|
||||
checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
"libc",
|
||||
@@ -1187,9 +1187,9 @@ checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991"
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.11"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||
checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"
|
||||
dependencies = [
|
||||
"powerfmt",
|
||||
]
|
||||
@@ -1678,9 +1678,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "foldhash"
|
||||
version = "0.1.4"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
|
||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||
|
||||
[[package]]
|
||||
name = "font-loader"
|
||||
@@ -1910,14 +1910,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.1"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
|
||||
checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"wasi 0.13.3+wasi-0.2.2",
|
||||
"windows-targets 0.52.6",
|
||||
"r-efi",
|
||||
"wasi 0.14.2+wasi-0.2.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1950,9 +1950,9 @@ checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||
|
||||
[[package]]
|
||||
name = "git2"
|
||||
version = "0.20.0"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fda788993cc341f69012feba8bf45c0ba4f3291fcc08e214b4d5a7332d88aff"
|
||||
checksum = "5220b8ba44c68a9a7f7a7659e864dd73692e417ef0211bea133c7b74e031eeb9"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"libc",
|
||||
@@ -2110,9 +2110,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "2.4.1"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888"
|
||||
checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crunchy",
|
||||
@@ -2184,9 +2184,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "1.2.0"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea"
|
||||
checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
@@ -2205,12 +2205,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "http-body-util"
|
||||
version = "0.1.2"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
|
||||
checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"futures-core",
|
||||
"http",
|
||||
"http-body",
|
||||
"pin-project-lite",
|
||||
@@ -2665,7 +2665,7 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
|
||||
|
||||
[[package]]
|
||||
name = "komorebi"
|
||||
version = "0.1.35"
|
||||
version = "0.1.36"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"clap",
|
||||
@@ -2702,7 +2702,7 @@ dependencies = [
|
||||
"uuid",
|
||||
"which",
|
||||
"win32-display-data",
|
||||
"windows 0.61.0",
|
||||
"windows 0.61.1",
|
||||
"windows-core 0.61.0",
|
||||
"windows-implement 0.60.0",
|
||||
"windows-interface 0.59.1",
|
||||
@@ -2713,7 +2713,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "komorebi-bar"
|
||||
version = "0.1.35"
|
||||
version = "0.1.36"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"chrono-tz",
|
||||
@@ -2743,14 +2743,14 @@ dependencies = [
|
||||
"sysinfo",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"windows 0.61.0",
|
||||
"windows 0.61.1",
|
||||
"windows-core 0.61.0",
|
||||
"windows-icons",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "komorebi-client"
|
||||
version = "0.1.35"
|
||||
version = "0.1.36"
|
||||
dependencies = [
|
||||
"komorebi",
|
||||
"serde_json_lenient",
|
||||
@@ -2759,20 +2759,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "komorebi-gui"
|
||||
version = "0.1.35"
|
||||
version = "0.1.36"
|
||||
dependencies = [
|
||||
"eframe",
|
||||
"egui_extras",
|
||||
"komorebi-client",
|
||||
"random_word",
|
||||
"serde_json_lenient",
|
||||
"windows 0.61.0",
|
||||
"windows 0.61.1",
|
||||
"windows-core 0.61.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "komorebi-themes"
|
||||
version = "0.1.35"
|
||||
version = "0.1.36"
|
||||
dependencies = [
|
||||
"base16-egui-themes",
|
||||
"catppuccin-egui",
|
||||
@@ -2785,7 +2785,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "komorebic"
|
||||
version = "0.1.35"
|
||||
version = "0.1.36"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
@@ -2806,12 +2806,12 @@ dependencies = [
|
||||
"sysinfo",
|
||||
"thiserror 2.0.12",
|
||||
"which",
|
||||
"windows 0.61.0",
|
||||
"windows 0.61.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "komorebic-no-console"
|
||||
version = "0.1.35"
|
||||
version = "0.1.36"
|
||||
|
||||
[[package]]
|
||||
name = "kqueue"
|
||||
@@ -2853,9 +2853,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.170"
|
||||
version = "0.2.171"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828"
|
||||
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
|
||||
|
||||
[[package]]
|
||||
name = "libfuzzer-sys"
|
||||
@@ -2869,9 +2869,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libgit2-sys"
|
||||
version = "0.18.0+1.9.0"
|
||||
version = "0.18.1+1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1a117465e7e1597e8febea8bb0c410f1c7fb93b1e1cddf34363f8390367ffec"
|
||||
checksum = "e1dcb20f84ffcdd825c7a311ae347cce604a6f084a767dec4a4929829645290e"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
@@ -2902,9 +2902,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libz-sys"
|
||||
version = "1.1.21"
|
||||
version = "1.1.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df9b68e50e6e0b26f672573834882eb57759f6db9b3be2ea3c35c91188bb4eaa"
|
||||
checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
@@ -2920,9 +2920,9 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.9.2"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db9c683daf087dc577b7506e9695b3d556a9f3849903fa28186283afd6809e9"
|
||||
checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413"
|
||||
|
||||
[[package]]
|
||||
name = "litemap"
|
||||
@@ -3759,9 +3759,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.0"
|
||||
version = "1.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cde51589ab56b20a6f686b2c68f7a0bd6add753d697abf720d63f8db3ab7b1ad"
|
||||
checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
@@ -4088,7 +4088,7 @@ version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
||||
dependencies = [
|
||||
"zerocopy 0.8.23",
|
||||
"zerocopy 0.8.24",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4195,13 +4195,19 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.39"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801"
|
||||
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "5.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
@@ -4403,9 +4409,9 @@ checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.12.14"
|
||||
version = "0.12.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "989e327e510263980e231de548a33e63d34962d29ae61b467389a1a09627a254"
|
||||
checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
@@ -4454,9 +4460,9 @@ checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a"
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.17.13"
|
||||
version = "0.17.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ac5d832aa16abd7d1def883a8545280c20a60f523a370aa3a9617c2b8550ee"
|
||||
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cfg-if 1.0.0",
|
||||
@@ -4493,22 +4499,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.0.2"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7178faa4b75a30e269c71e61c353ce2748cf3d76f0c44c393f4e60abf49b825"
|
||||
checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.9.2",
|
||||
"linux-raw-sys 0.9.3",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.23.23"
|
||||
version = "0.23.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395"
|
||||
checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"rustls-pki-types",
|
||||
@@ -4534,9 +4540,9 @@ checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c"
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.102.8"
|
||||
version = "0.103.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
|
||||
checksum = "0aa4eeac2588ffff23e9d7a7e9b3f971c5fb5b7ebc9452745e0c232c64f83b2f"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
@@ -4788,9 +4794,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "shadow-rs"
|
||||
version = "1.0.1"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3672eb035a31ac62bf171765d04e3f1f01659920847384d08ac979ca6bb56763"
|
||||
checksum = "6d5625ed609cf66d7e505e7d487aca815626dc4ebb6c0dd07637ca61a44651a6"
|
||||
dependencies = [
|
||||
"const_format",
|
||||
"git2",
|
||||
@@ -5132,15 +5138,14 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.18.0"
|
||||
version = "3.19.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c317e0a526ee6120d8dabad239c8dadca62b24b6f168914bbbc8e2fb1f0e567"
|
||||
checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"fastrand",
|
||||
"getrandom 0.3.1",
|
||||
"getrandom 0.3.2",
|
||||
"once_cell",
|
||||
"rustix 1.0.2",
|
||||
"rustix 1.0.3",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
@@ -5159,7 +5164,7 @@ version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45c6481c4829e4cc63825e62c49186a34538b7b2750b73b266581ffb612fb5ed"
|
||||
dependencies = [
|
||||
"rustix 1.0.2",
|
||||
"rustix 1.0.3",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
@@ -5246,9 +5251,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.39"
|
||||
version = "0.3.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dad298b01a40a23aac4580b67e3dbedb7cc8402f3592d7f49469de2ea4aecdd8"
|
||||
checksum = "9d9c75b47bdff86fa3334a3db91356b8d7d86a9b839dab7d0bdc5c3d3a077618"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
@@ -5263,15 +5268,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.3"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "765c97a5b985b7c11d7bc27fa927dc4fe6af3a6dfb021d28deb60d3bf51e76ef"
|
||||
checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.20"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8093bc3e81c3bc5f7879de09619d06c9a5a5e45ca44dfeeb7225bae38005c5c"
|
||||
checksum = "29aa485584182073ed57fd5004aa09c371f021325014694e432313345865fd04"
|
||||
dependencies = [
|
||||
"num-conv",
|
||||
"time-core",
|
||||
@@ -5314,9 +5319,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.44.0"
|
||||
version = "1.44.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9975ea0f48b5aa3972bf2d888c238182458437cc2a19374b81b25cdf1023fb3a"
|
||||
checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
@@ -5349,9 +5354,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.13"
|
||||
version = "0.7.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078"
|
||||
checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
@@ -5667,7 +5672,7 @@ version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9"
|
||||
dependencies = [
|
||||
"getrandom 0.3.1",
|
||||
"getrandom 0.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5732,9 +5737,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.13.3+wasi-0.2.2"
|
||||
version = "0.14.2+wasi-0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
|
||||
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
|
||||
dependencies = [
|
||||
"wit-bindgen-rt",
|
||||
]
|
||||
@@ -5964,9 +5969,9 @@ checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082"
|
||||
|
||||
[[package]]
|
||||
name = "wgpu"
|
||||
version = "24.0.1"
|
||||
version = "24.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47f55718f85c2fa756edffa0e7f0e0a60aba463d1362b57e23123c58f035e4b6"
|
||||
checksum = "35904fb00ba2d2e0a4d002fcbbb6e1b89b574d272a50e5fc95f6e81cf281c245"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bitflags 2.9.0",
|
||||
@@ -6085,7 +6090,7 @@ dependencies = [
|
||||
"itertools 0.14.0",
|
||||
"serde",
|
||||
"thiserror 2.0.12",
|
||||
"windows 0.61.0",
|
||||
"windows 0.61.1",
|
||||
"windows-core 0.60.1",
|
||||
"wmi",
|
||||
]
|
||||
@@ -6147,31 +6152,40 @@ version = "0.60.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddf874e74c7a99773e62b1c671427abf01a425e77c3d3fb9fb1e4883ea934529"
|
||||
dependencies = [
|
||||
"windows-collections",
|
||||
"windows-collections 0.1.1",
|
||||
"windows-core 0.60.1",
|
||||
"windows-future",
|
||||
"windows-future 0.1.1",
|
||||
"windows-link",
|
||||
"windows-numerics 0.1.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.61.0"
|
||||
version = "0.61.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b76779b1008b2bafb6cdf5e299dfe7f5780d604349fe68d9476c08feb448e98f"
|
||||
checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419"
|
||||
dependencies = [
|
||||
"windows-collections",
|
||||
"windows-collections 0.2.0",
|
||||
"windows-core 0.61.0",
|
||||
"windows-future",
|
||||
"windows-future 0.2.0",
|
||||
"windows-link",
|
||||
"windows-numerics 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-collections"
|
||||
version = "0.1.2"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b095389c0f7a1e16ba4927c17478dca870938c7bbeb31e7f77eab4e86dc8fd1a"
|
||||
checksum = "5467f79cc1ba3f52ebb2ed41dbb459b8e7db636cc3429458d9a852e15bc24dec"
|
||||
dependencies = [
|
||||
"windows-core 0.60.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-collections"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
|
||||
dependencies = [
|
||||
"windows-core 0.61.0",
|
||||
]
|
||||
@@ -6238,9 +6252,19 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windows-future"
|
||||
version = "0.1.2"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbb86813135724d122c524095d1e55a72f2844b0ce6b77ef05e782dff1e6abfc"
|
||||
checksum = "a787db4595e7eb80239b74ce8babfb1363d8e343ab072f2ffe901400c03349f0"
|
||||
dependencies = [
|
||||
"windows-core 0.60.1",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-future"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a1d6bbefcb7b60acd19828e1bc965da6fcf18a7e39490c5f8be71e54a19ba32"
|
||||
dependencies = [
|
||||
"windows-core 0.61.0",
|
||||
"windows-link",
|
||||
@@ -6758,9 +6782,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.3"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1"
|
||||
checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
@@ -6792,9 +6816,9 @@ checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904"
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rt"
|
||||
version = "0.33.0"
|
||||
version = "0.39.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
|
||||
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
]
|
||||
@@ -7033,11 +7057,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.23"
|
||||
version = "0.8.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6"
|
||||
checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879"
|
||||
dependencies = [
|
||||
"zerocopy-derive 0.8.23",
|
||||
"zerocopy-derive 0.8.24",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7053,9 +7077,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.23"
|
||||
version = "0.8.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154"
|
||||
checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
||||
@@ -56,4 +56,4 @@ alt + 3 : komorebic focus-workspaces 2
|
||||
```
|
||||
|
||||
The last focused workspace on the focused monitor can be re-focused using the [
|
||||
`komorebic focus-last-workspace`](../cli/focus-last-workspace) command.
|
||||
`komorebic focus-last-workspace`](../cli/focus-last-workspace.md) command.
|
||||
|
||||
@@ -47,7 +47,7 @@ alt + shift + oem_6 : komorebic cycle-send-to-workspace next # oem_6 is ]
|
||||
```
|
||||
|
||||
Windows can be moved or sent to the focused workspace on a another monitor using the [
|
||||
`komorebic move-to-monitor`](../cli/move-to-monitor.md) and [`komorebic send-to-monitor`](../cli/send-to-monitor)
|
||||
`komorebic move-to-monitor`](../cli/move-to-monitor.md) and [`komorebic send-to-monitor`](../cli/send-to-monitor.md)
|
||||
commands.
|
||||
|
||||
Windows can be moved or sent to the focused workspace on a monitor in a cycle direction (previous, next) using the [
|
||||
@@ -56,4 +56,4 @@ Windows can be moved or sent to the focused workspace on a monitor in a cycle di
|
||||
|
||||
Windows can be moved or sent to a named workspace on any monitor (given that all workspace names across all monitors are
|
||||
unique) using the [`komorebic move-to-named-workspace`](../cli/move-to-named-workspace.md) and [
|
||||
`komorebic send-to-named-workspace`](../cli/send-to-named-workspace.md) commands
|
||||
`komorebic send-to-named-workspace`](../cli/send-to-named-workspace.md) commands
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "komorebi-bar"
|
||||
version = "0.1.35"
|
||||
version = "0.1.36"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
@@ -13,7 +13,7 @@ use std::path::PathBuf;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
/// The `komorebi.bar.json` configuration file reference for `v0.1.35`
|
||||
/// The `komorebi.bar.json` configuration file reference for `v0.1.36`
|
||||
pub struct KomobarConfig {
|
||||
/// Bar height (default: 50)
|
||||
pub height: Option<f32>,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "komorebi-client"
|
||||
version = "0.1.35"
|
||||
version = "0.1.36"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "komorebi-gui"
|
||||
version = "0.1.35"
|
||||
version = "0.1.36"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "komorebi-themes"
|
||||
version = "0.1.35"
|
||||
version = "0.1.36"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "komorebi"
|
||||
version = "0.1.35"
|
||||
version = "0.1.36"
|
||||
description = "A tiling window manager for Windows"
|
||||
repository = "https://github.com/LGUG2Z/komorebi"
|
||||
edition = "2021"
|
||||
|
||||
@@ -272,6 +272,7 @@ impl Border {
|
||||
WindowKind::Monocle,
|
||||
WindowKind::Unfocused,
|
||||
WindowKind::Floating,
|
||||
WindowKind::UnfocusedLocked,
|
||||
] {
|
||||
let color = window_kind_colour(window_kind);
|
||||
let color = D2D1_COLOR_F {
|
||||
|
||||
@@ -48,6 +48,8 @@ lazy_static! {
|
||||
AtomicU32::new(u32::from(Colour::Rgb(Rgb::new(66, 165, 245))));
|
||||
pub static ref UNFOCUSED: AtomicU32 =
|
||||
AtomicU32::new(u32::from(Colour::Rgb(Rgb::new(128, 128, 128))));
|
||||
pub static ref UNFOCUSED_LOCKED: AtomicU32 =
|
||||
AtomicU32::new(u32::from(Colour::Rgb(Rgb::new(158, 8, 8))));
|
||||
pub static ref MONOCLE: AtomicU32 =
|
||||
AtomicU32::new(u32::from(Colour::Rgb(Rgb::new(255, 51, 153))));
|
||||
pub static ref STACK: AtomicU32 = AtomicU32::new(u32::from(Colour::Rgb(Rgb::new(0, 165, 66))));
|
||||
@@ -149,6 +151,7 @@ pub fn destroy_all_borders() -> color_eyre::Result<()> {
|
||||
fn window_kind_colour(focus_kind: WindowKind) -> u32 {
|
||||
match focus_kind {
|
||||
WindowKind::Unfocused => UNFOCUSED.load(Ordering::Relaxed),
|
||||
WindowKind::UnfocusedLocked => UNFOCUSED_LOCKED.load(Ordering::Relaxed),
|
||||
WindowKind::Single => FOCUSED.load(Ordering::Relaxed),
|
||||
WindowKind::Stack => STACK.load(Ordering::Relaxed),
|
||||
WindowKind::Monocle => MONOCLE.load(Ordering::Relaxed),
|
||||
@@ -229,7 +232,11 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
||||
let window_kind = if idx != ws.focused_container_idx()
|
||||
|| monitor_idx != focused_monitor_idx
|
||||
{
|
||||
WindowKind::Unfocused
|
||||
if ws.locked_containers().contains(&idx) {
|
||||
WindowKind::UnfocusedLocked
|
||||
} else {
|
||||
WindowKind::Unfocused
|
||||
}
|
||||
} else if c.windows().len() > 1 {
|
||||
WindowKind::Stack
|
||||
} else {
|
||||
@@ -493,7 +500,11 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
||||
|| monitor_idx != focused_monitor_idx
|
||||
|| focused_window_hwnd != foreground_window
|
||||
{
|
||||
WindowKind::Unfocused
|
||||
if ws.locked_containers().contains(&idx) {
|
||||
WindowKind::UnfocusedLocked
|
||||
} else {
|
||||
WindowKind::Unfocused
|
||||
}
|
||||
} else if c.windows().len() > 1 {
|
||||
WindowKind::Stack
|
||||
} else {
|
||||
|
||||
@@ -84,6 +84,9 @@ pub enum SocketMessage {
|
||||
PromoteFocus,
|
||||
PromoteWindow(OperationDirection),
|
||||
EagerFocus(String),
|
||||
LockMonitorWorkspaceContainer(usize, usize, usize),
|
||||
UnlockMonitorWorkspaceContainer(usize, usize, usize),
|
||||
ToggleLock,
|
||||
ToggleFloat,
|
||||
ToggleMonocle,
|
||||
ToggleMaximize,
|
||||
@@ -312,6 +315,7 @@ pub enum WindowKind {
|
||||
Monocle,
|
||||
#[default]
|
||||
Unfocused,
|
||||
UnfocusedLocked,
|
||||
Floating,
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ pub mod colour;
|
||||
pub mod container;
|
||||
pub mod core;
|
||||
pub mod focus_manager;
|
||||
pub mod locked_deque;
|
||||
pub mod monitor;
|
||||
pub mod monitor_reconciliator;
|
||||
pub mod process_command;
|
||||
|
||||
316
komorebi/src/locked_deque.rs
Normal file
316
komorebi/src/locked_deque.rs
Normal file
@@ -0,0 +1,316 @@
|
||||
use std::collections::BTreeSet;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
pub struct LockedDeque<'a, T> {
|
||||
deque: &'a mut VecDeque<T>,
|
||||
locked_indices: &'a mut BTreeSet<usize>,
|
||||
}
|
||||
|
||||
impl<'a, T: PartialEq> LockedDeque<'a, T> {
|
||||
pub fn new(deque: &'a mut VecDeque<T>, locked_indices: &'a mut BTreeSet<usize>) -> Self {
|
||||
Self {
|
||||
deque,
|
||||
locked_indices,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, index: usize, value: T) -> usize {
|
||||
insert_respecting_locks(self.deque, self.locked_indices, index, value)
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, index: usize) -> Option<T> {
|
||||
remove_respecting_locks(self.deque, self.locked_indices, index)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_respecting_locks<T>(
|
||||
deque: &mut VecDeque<T>,
|
||||
locked_idx: &mut BTreeSet<usize>,
|
||||
idx: usize,
|
||||
value: T,
|
||||
) -> usize {
|
||||
if idx == deque.len() {
|
||||
deque.push_back(value);
|
||||
return idx;
|
||||
}
|
||||
|
||||
let mut new_deque = VecDeque::with_capacity(deque.len() + 1);
|
||||
let mut temp_locked_deque = VecDeque::new();
|
||||
let mut j = 0;
|
||||
let mut corrected_idx = idx;
|
||||
|
||||
for (i, el) in deque.drain(..).enumerate() {
|
||||
if i == idx {
|
||||
corrected_idx = j;
|
||||
}
|
||||
if locked_idx.contains(&i) {
|
||||
temp_locked_deque.push_back(el);
|
||||
} else {
|
||||
new_deque.push_back(el);
|
||||
j += 1;
|
||||
}
|
||||
}
|
||||
|
||||
new_deque.insert(corrected_idx, value);
|
||||
|
||||
for (locked_el, locked_idx) in temp_locked_deque.into_iter().zip(locked_idx.iter()) {
|
||||
new_deque.insert(*locked_idx, locked_el);
|
||||
if *locked_idx <= corrected_idx {
|
||||
corrected_idx += 1;
|
||||
}
|
||||
}
|
||||
|
||||
*deque = new_deque;
|
||||
|
||||
corrected_idx
|
||||
}
|
||||
|
||||
pub fn remove_respecting_locks<T>(
|
||||
deque: &mut VecDeque<T>,
|
||||
locked_idx: &mut BTreeSet<usize>,
|
||||
idx: usize,
|
||||
) -> Option<T> {
|
||||
if idx >= deque.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let final_size = deque.len() - 1;
|
||||
|
||||
let mut new_deque = VecDeque::with_capacity(final_size);
|
||||
let mut temp_locked_deque = VecDeque::new();
|
||||
let mut removed = None;
|
||||
let mut removed_locked_idx = None;
|
||||
|
||||
for (i, el) in deque.drain(..).enumerate() {
|
||||
if i == idx {
|
||||
removed = Some(el);
|
||||
removed_locked_idx = locked_idx.contains(&i).then_some(i);
|
||||
} else if locked_idx.contains(&i) {
|
||||
temp_locked_deque.push_back(el);
|
||||
} else {
|
||||
new_deque.push_back(el);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(i) = removed_locked_idx {
|
||||
let mut above = locked_idx.split_off(&i);
|
||||
above.pop_first();
|
||||
locked_idx.extend(above.into_iter().map(|i| i - 1));
|
||||
}
|
||||
|
||||
while locked_idx.last().is_some_and(|i| *i >= final_size) {
|
||||
locked_idx.pop_last();
|
||||
}
|
||||
|
||||
let extra_invalid_idx = (new_deque.len()
|
||||
..(new_deque.len() + temp_locked_deque.len() - locked_idx.len()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for (locked_el, locked_idx) in temp_locked_deque
|
||||
.into_iter()
|
||||
.zip(locked_idx.iter().chain(extra_invalid_idx.iter()))
|
||||
{
|
||||
new_deque.insert(*locked_idx, locked_el);
|
||||
}
|
||||
|
||||
*deque = new_deque;
|
||||
|
||||
removed
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::collections::BTreeSet;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
#[test]
|
||||
fn test_insert_respecting_locks() {
|
||||
// Test case 1: Basic insertion with locked index
|
||||
{
|
||||
let mut deque = VecDeque::from(vec![0, 1, 2, 3, 4]);
|
||||
let mut locked = BTreeSet::new();
|
||||
locked.insert(2); // Lock index 2
|
||||
|
||||
// Insert at index 0, should shift elements while keeping index 2 locked
|
||||
insert_respecting_locks(&mut deque, &mut locked, 0, 99);
|
||||
assert_eq!(deque, VecDeque::from(vec![99, 0, 2, 1, 3, 4]));
|
||||
// Element '2' remains at index 2, element '1' that was at index 1 is now at index 3
|
||||
}
|
||||
|
||||
// Test case 2: Insert at a locked index
|
||||
{
|
||||
let mut deque = VecDeque::from(vec![0, 1, 2, 3, 4]);
|
||||
let mut locked = BTreeSet::new();
|
||||
locked.insert(2); // Lock index 2
|
||||
|
||||
// Try to insert at locked index 2, should insert at index 3 instead
|
||||
let actual_index = insert_respecting_locks(&mut deque, &mut locked, 2, 99);
|
||||
assert_eq!(actual_index, 3);
|
||||
assert_eq!(deque, VecDeque::from(vec![0, 1, 2, 99, 3, 4]));
|
||||
}
|
||||
|
||||
// Test case 3: Multiple locked indices
|
||||
{
|
||||
let mut deque = VecDeque::from(vec![0, 1, 2, 3, 4]);
|
||||
let mut locked = BTreeSet::new();
|
||||
locked.insert(1); // Lock index 1
|
||||
locked.insert(3); // Lock index 3
|
||||
|
||||
// Insert at index 0, should maintain locked indices
|
||||
insert_respecting_locks(&mut deque, &mut locked, 0, 99);
|
||||
assert_eq!(deque, VecDeque::from(vec![99, 1, 0, 3, 2, 4]));
|
||||
// Elements '1' and '3' remain at indices 1 and 3
|
||||
}
|
||||
|
||||
// Test case 4: Insert at end
|
||||
{
|
||||
let mut deque = VecDeque::from(vec![0, 1, 2, 3, 4]);
|
||||
let mut locked = BTreeSet::new();
|
||||
locked.insert(2); // Lock index 2
|
||||
|
||||
// Insert at end of deque
|
||||
let actual_index = insert_respecting_locks(&mut deque, &mut locked, 5, 99);
|
||||
assert_eq!(actual_index, 5);
|
||||
assert_eq!(deque, VecDeque::from(vec![0, 1, 2, 3, 4, 99]));
|
||||
}
|
||||
|
||||
// Test case 5: Empty deque
|
||||
{
|
||||
let mut deque = VecDeque::new();
|
||||
let mut locked = BTreeSet::new();
|
||||
|
||||
// Insert into empty deque
|
||||
let actual_index = insert_respecting_locks(&mut deque, &mut locked, 0, 99);
|
||||
assert_eq!(actual_index, 0);
|
||||
assert_eq!(deque, VecDeque::from(vec![99]));
|
||||
}
|
||||
|
||||
// Test case 6: All indices locked
|
||||
{
|
||||
let mut deque = VecDeque::from(vec![0, 1, 2, 3, 4]);
|
||||
let mut locked = BTreeSet::new();
|
||||
for i in 0..5 {
|
||||
locked.insert(i); // Lock all indices
|
||||
}
|
||||
|
||||
// Try to insert at index 2, should insert at the end
|
||||
let actual_index = insert_respecting_locks(&mut deque, &mut locked, 2, 99);
|
||||
assert_eq!(actual_index, 5);
|
||||
assert_eq!(deque, VecDeque::from(vec![0, 1, 2, 3, 4, 99]));
|
||||
}
|
||||
|
||||
// Test case 7: Consecutive locked indices
|
||||
{
|
||||
let mut deque = VecDeque::from(vec![0, 1, 2, 3, 4]);
|
||||
let mut locked = BTreeSet::new();
|
||||
locked.insert(2); // Lock index 2
|
||||
locked.insert(3); // Lock index 3
|
||||
|
||||
// Insert at index 1, should maintain consecutive locked indices
|
||||
insert_respecting_locks(&mut deque, &mut locked, 1, 99);
|
||||
assert_eq!(deque, VecDeque::from(vec![0, 99, 2, 3, 1, 4]));
|
||||
// Elements '2' and '3' remain at indices 2 and 3
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_remove_respecting_locks() {
|
||||
// Test case 1: Remove a non-locked index before a locked index
|
||||
{
|
||||
let mut deque = VecDeque::from(vec![0, 1, 2, 3, 4]);
|
||||
let mut locked = BTreeSet::new();
|
||||
locked.insert(2); // Lock index 2
|
||||
|
||||
let removed = remove_respecting_locks(&mut deque, &mut locked, 0);
|
||||
assert_eq!(removed, Some(0));
|
||||
assert_eq!(deque, VecDeque::from(vec![1, 3, 2, 4]));
|
||||
assert!(locked.contains(&2)); // Index 2 should still be locked
|
||||
}
|
||||
|
||||
// Test case 2: Remove a locked index
|
||||
{
|
||||
let mut deque = VecDeque::from(vec![0, 1, 2, 3, 4]);
|
||||
let mut locked = BTreeSet::new();
|
||||
locked.insert(2); // Lock index 2
|
||||
|
||||
let removed = remove_respecting_locks(&mut deque, &mut locked, 2);
|
||||
assert_eq!(removed, Some(2));
|
||||
assert_eq!(deque, VecDeque::from(vec![0, 1, 3, 4]));
|
||||
assert!(!locked.contains(&2)); // Index 2 should be unlocked
|
||||
}
|
||||
|
||||
// Test case 3: Remove an index after a locked index
|
||||
{
|
||||
let mut deque = VecDeque::from(vec![0, 1, 2, 3, 4]);
|
||||
let mut locked = BTreeSet::new();
|
||||
locked.insert(1); // Lock index 1
|
||||
|
||||
let removed = remove_respecting_locks(&mut deque, &mut locked, 3);
|
||||
assert_eq!(removed, Some(3));
|
||||
assert_eq!(deque, VecDeque::from(vec![0, 1, 2, 4]));
|
||||
assert!(locked.contains(&1)); // Index 1 should still be locked
|
||||
}
|
||||
|
||||
// Test case 4: Multiple locked indices
|
||||
{
|
||||
let mut deque = VecDeque::from(vec![0, 1, 2, 3, 4]);
|
||||
let mut locked = BTreeSet::new();
|
||||
locked.insert(1); // Lock index 1
|
||||
locked.insert(3); // Lock index 3
|
||||
|
||||
let removed = remove_respecting_locks(&mut deque, &mut locked, 0);
|
||||
assert_eq!(removed, Some(0));
|
||||
assert_eq!(deque, VecDeque::from(vec![2, 1, 4, 3]));
|
||||
assert!(locked.contains(&1) && locked.contains(&3)); // Both indices should still be locked
|
||||
}
|
||||
|
||||
// Test case 5: Remove the last element
|
||||
{
|
||||
let mut deque = VecDeque::from(vec![0, 1, 2, 3, 4]);
|
||||
let mut locked = BTreeSet::new();
|
||||
locked.insert(2); // Lock index 2
|
||||
|
||||
let removed = remove_respecting_locks(&mut deque, &mut locked, 4);
|
||||
assert_eq!(removed, Some(4));
|
||||
assert_eq!(deque, VecDeque::from(vec![0, 1, 2, 3]));
|
||||
assert!(locked.contains(&2)); // Index 2 should still be locked
|
||||
}
|
||||
|
||||
// Test case 6: Invalid index
|
||||
{
|
||||
let mut deque = VecDeque::from(vec![0, 1, 2, 3, 4]);
|
||||
let mut locked = BTreeSet::new();
|
||||
locked.insert(2); // Lock index 2
|
||||
|
||||
let removed = remove_respecting_locks(&mut deque, &mut locked, 10);
|
||||
assert_eq!(removed, None);
|
||||
assert_eq!(deque, VecDeque::from(vec![0, 1, 2, 3, 4])); // Deque unchanged
|
||||
assert!(locked.contains(&2)); // Lock unchanged
|
||||
}
|
||||
|
||||
// Test case 7: Remove enough elements to make a locked index invalid
|
||||
{
|
||||
let mut deque = VecDeque::from(vec![0, 1, 2]);
|
||||
let mut locked = BTreeSet::new();
|
||||
locked.insert(2); // Lock index 2
|
||||
|
||||
remove_respecting_locks(&mut deque, &mut locked, 0);
|
||||
assert_eq!(deque, VecDeque::from(vec![1, 2]));
|
||||
assert!(!locked.contains(&2)); // Index 2 should now be invalid
|
||||
}
|
||||
|
||||
// Test case 8: Removing an element before multiple locked indices
|
||||
{
|
||||
let mut deque = VecDeque::from(vec![0, 1, 2, 3, 4, 5]);
|
||||
let mut locked = BTreeSet::new();
|
||||
locked.insert(2); // Lock index 2
|
||||
locked.insert(4); // Lock index 4
|
||||
|
||||
let removed = remove_respecting_locks(&mut deque, &mut locked, 1);
|
||||
assert_eq!(removed, Some(1));
|
||||
assert_eq!(deque, VecDeque::from(vec![0, 3, 2, 5, 4]));
|
||||
assert!(locked.contains(&2) && locked.contains(&4)); // Both indices should still be locked
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
use color_eyre::eyre::anyhow;
|
||||
use color_eyre::eyre::OptionExt;
|
||||
use color_eyre::Result;
|
||||
use miow::pipe::connect;
|
||||
use net2::TcpStreamExt;
|
||||
@@ -359,6 +360,41 @@ impl WindowManager {
|
||||
SocketMessage::Minimize => {
|
||||
Window::from(WindowsApi::foreground_window()?).minimize();
|
||||
}
|
||||
SocketMessage::LockMonitorWorkspaceContainer(
|
||||
monitor_idx,
|
||||
workspace_idx,
|
||||
container_idx,
|
||||
) => {
|
||||
let monitor = self
|
||||
.monitors_mut()
|
||||
.get_mut(monitor_idx)
|
||||
.ok_or_eyre("no monitor at the given index")?;
|
||||
|
||||
let workspace = monitor
|
||||
.workspaces_mut()
|
||||
.get_mut(workspace_idx)
|
||||
.ok_or_eyre("no workspace at the given index")?;
|
||||
|
||||
workspace.locked_containers.insert(container_idx);
|
||||
}
|
||||
SocketMessage::UnlockMonitorWorkspaceContainer(
|
||||
monitor_idx,
|
||||
workspace_idx,
|
||||
container_idx,
|
||||
) => {
|
||||
let monitor = self
|
||||
.monitors_mut()
|
||||
.get_mut(monitor_idx)
|
||||
.ok_or_eyre("no monitor at the given index")?;
|
||||
|
||||
let workspace = monitor
|
||||
.workspaces_mut()
|
||||
.get_mut(workspace_idx)
|
||||
.ok_or_eyre("no workspace at the given index")?;
|
||||
|
||||
workspace.locked_containers.remove(&container_idx);
|
||||
}
|
||||
SocketMessage::ToggleLock => self.toggle_lock()?,
|
||||
SocketMessage::ToggleFloat => self.toggle_float()?,
|
||||
SocketMessage::ToggleMonocle => self.toggle_monocle()?,
|
||||
SocketMessage::ToggleMaximize => self.toggle_maximize()?,
|
||||
@@ -1783,6 +1819,10 @@ impl WindowManager {
|
||||
WindowKind::Unfocused => {
|
||||
border_manager::UNFOCUSED.store(Rgb::new(r, g, b).into(), Ordering::SeqCst);
|
||||
}
|
||||
WindowKind::UnfocusedLocked => {
|
||||
border_manager::UNFOCUSED_LOCKED
|
||||
.store(Rgb::new(r, g, b).into(), Ordering::SeqCst);
|
||||
}
|
||||
WindowKind::Floating => {
|
||||
border_manager::FLOATING.store(Rgb::new(r, g, b).into(), Ordering::SeqCst);
|
||||
}
|
||||
|
||||
@@ -314,7 +314,7 @@ pub enum AppSpecificConfigurationPath {
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
/// The `komorebi.json` static configuration file reference for `v0.1.35`
|
||||
/// The `komorebi.json` static configuration file reference for `v0.1.36`
|
||||
pub struct StaticConfig {
|
||||
/// DEPRECATED from v0.1.22: no longer required
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
@@ -500,6 +500,9 @@ pub enum KomorebiTheme {
|
||||
/// Border colour when the container is unfocused (default: Base)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
unfocused_border: Option<komorebi_themes::CatppuccinValue>,
|
||||
/// Border colour when the container is unfocused and locked (default: Red)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
unfocused_locked_border: Option<komorebi_themes::CatppuccinValue>,
|
||||
/// Stackbar focused tab text colour (default: Green)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
stackbar_focused_text: Option<komorebi_themes::CatppuccinValue>,
|
||||
@@ -532,6 +535,9 @@ pub enum KomorebiTheme {
|
||||
/// Border colour when the container is unfocused (default: Base01)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
unfocused_border: Option<komorebi_themes::Base16Value>,
|
||||
/// Border colour when the container is unfocused and locked (default: Base08)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
unfocused_locked_border: Option<komorebi_themes::Base16Value>,
|
||||
/// Stackbar focused tab text colour (default: Base0B)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
stackbar_focused_text: Option<komorebi_themes::Base16Value>,
|
||||
|
||||
@@ -76,6 +76,7 @@ pub fn handle_notifications() -> color_eyre::Result<()> {
|
||||
monocle_border,
|
||||
floating_border,
|
||||
unfocused_border,
|
||||
unfocused_locked_border,
|
||||
stackbar_focused_text,
|
||||
stackbar_unfocused_text,
|
||||
stackbar_background,
|
||||
@@ -87,6 +88,7 @@ pub fn handle_notifications() -> color_eyre::Result<()> {
|
||||
monocle_border,
|
||||
floating_border,
|
||||
unfocused_border,
|
||||
unfocused_locked_border,
|
||||
stackbar_focused_text,
|
||||
stackbar_unfocused_text,
|
||||
stackbar_background,
|
||||
@@ -112,6 +114,10 @@ pub fn handle_notifications() -> color_eyre::Result<()> {
|
||||
.unwrap_or(komorebi_themes::CatppuccinValue::Base)
|
||||
.color32(name.as_theme());
|
||||
|
||||
let unfocused_locked_border = unfocused_locked_border
|
||||
.unwrap_or(komorebi_themes::CatppuccinValue::Red)
|
||||
.color32(name.as_theme());
|
||||
|
||||
let stackbar_focused_text = stackbar_focused_text
|
||||
.unwrap_or(komorebi_themes::CatppuccinValue::Green)
|
||||
.color32(name.as_theme());
|
||||
@@ -130,6 +136,7 @@ pub fn handle_notifications() -> color_eyre::Result<()> {
|
||||
monocle_border,
|
||||
floating_border,
|
||||
unfocused_border,
|
||||
unfocused_locked_border,
|
||||
stackbar_focused_text,
|
||||
stackbar_unfocused_text,
|
||||
stackbar_background,
|
||||
@@ -142,6 +149,7 @@ pub fn handle_notifications() -> color_eyre::Result<()> {
|
||||
monocle_border,
|
||||
floating_border,
|
||||
unfocused_border,
|
||||
unfocused_locked_border,
|
||||
stackbar_focused_text,
|
||||
stackbar_unfocused_text,
|
||||
stackbar_background,
|
||||
@@ -163,6 +171,10 @@ pub fn handle_notifications() -> color_eyre::Result<()> {
|
||||
.unwrap_or(komorebi_themes::Base16Value::Base01)
|
||||
.color32(*name);
|
||||
|
||||
let unfocused_locked_border = unfocused_locked_border
|
||||
.unwrap_or(komorebi_themes::Base16Value::Base08)
|
||||
.color32(*name);
|
||||
|
||||
let floating_border = floating_border
|
||||
.unwrap_or(komorebi_themes::Base16Value::Base09)
|
||||
.color32(*name);
|
||||
@@ -185,6 +197,7 @@ pub fn handle_notifications() -> color_eyre::Result<()> {
|
||||
monocle_border,
|
||||
floating_border,
|
||||
unfocused_border,
|
||||
unfocused_locked_border,
|
||||
stackbar_focused_text,
|
||||
stackbar_unfocused_text,
|
||||
stackbar_background,
|
||||
@@ -198,6 +211,10 @@ pub fn handle_notifications() -> color_eyre::Result<()> {
|
||||
border_manager::FLOATING.store(u32::from(Colour::from(floating_border)), Ordering::SeqCst);
|
||||
border_manager::UNFOCUSED
|
||||
.store(u32::from(Colour::from(unfocused_border)), Ordering::SeqCst);
|
||||
border_manager::UNFOCUSED_LOCKED.store(
|
||||
u32::from(Colour::from(unfocused_locked_border)),
|
||||
Ordering::SeqCst,
|
||||
);
|
||||
|
||||
STACKBAR_TAB_BACKGROUND_COLOUR.store(
|
||||
u32::from(Colour::from(stackbar_background)),
|
||||
|
||||
@@ -342,6 +342,7 @@ impl From<&WindowManager> for State {
|
||||
float_override: workspace.float_override,
|
||||
layer: workspace.layer,
|
||||
globals: workspace.globals,
|
||||
locked_containers: workspace.locked_containers.clone(),
|
||||
workspace_config: None,
|
||||
})
|
||||
.collect::<VecDeque<_>>();
|
||||
@@ -2849,6 +2850,20 @@ impl WindowManager {
|
||||
self.update_focused_workspace(is_floating_window, true)
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub fn toggle_lock(&mut self) -> Result<()> {
|
||||
let workspace = self.focused_workspace_mut()?;
|
||||
let index = workspace.focused_container_idx();
|
||||
|
||||
if workspace.locked_containers().contains(&index) {
|
||||
workspace.locked_containers_mut().remove(&index);
|
||||
} else {
|
||||
workspace.locked_containers_mut().insert(index);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub fn float_window(&mut self) -> Result<()> {
|
||||
tracing::info!("floating window");
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::collections::BTreeSet;
|
||||
use std::collections::VecDeque;
|
||||
use std::fmt::Display;
|
||||
use std::fmt::Formatter;
|
||||
@@ -25,6 +26,7 @@ use crate::core::Rect;
|
||||
use crate::border_manager::BORDER_OFFSET;
|
||||
use crate::border_manager::BORDER_WIDTH;
|
||||
use crate::container::Container;
|
||||
use crate::locked_deque::LockedDeque;
|
||||
use crate::ring::Ring;
|
||||
use crate::should_act;
|
||||
use crate::stackbar_manager;
|
||||
@@ -90,6 +92,8 @@ pub struct Workspace {
|
||||
pub globals: WorkspaceGlobals,
|
||||
#[getset(get = "pub", get_mut = "pub", set = "pub")]
|
||||
pub layer: WorkspaceLayer,
|
||||
#[getset(get = "pub", get_mut = "pub", set = "pub")]
|
||||
pub locked_containers: BTreeSet<usize>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[getset(get = "pub", set = "pub")]
|
||||
pub workspace_config: Option<WorkspaceConfig>,
|
||||
@@ -139,6 +143,7 @@ impl Default for Workspace {
|
||||
layer: Default::default(),
|
||||
globals: Default::default(),
|
||||
workspace_config: None,
|
||||
locked_containers: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -806,9 +811,8 @@ impl Workspace {
|
||||
),
|
||||
};
|
||||
|
||||
self.containers_mut().insert(primary_idx, container);
|
||||
self.resize_dimensions_mut().insert(primary_idx, resize);
|
||||
|
||||
let insertion_idx = self.insert_container_at_idx(primary_idx, container);
|
||||
self.resize_dimensions_mut()[insertion_idx] = resize;
|
||||
self.focus_container(primary_idx);
|
||||
|
||||
Ok(())
|
||||
@@ -824,21 +828,38 @@ impl Workspace {
|
||||
self.focus_first_container();
|
||||
}
|
||||
|
||||
pub fn insert_container_at_idx(&mut self, idx: usize, container: Container) {
|
||||
self.containers_mut().insert(idx, container);
|
||||
self.focus_container(idx);
|
||||
// this fn respects locked container indexes - we should use it for pretty much everything
|
||||
// except monocle and maximize toggles
|
||||
pub fn insert_container_at_idx(&mut self, idx: usize, container: Container) -> usize {
|
||||
let mut locked_containers = self.locked_containers().clone();
|
||||
let mut ld = LockedDeque::new(self.containers_mut(), &mut locked_containers);
|
||||
let insertion_idx = ld.insert(idx, container);
|
||||
self.locked_containers = locked_containers;
|
||||
|
||||
if insertion_idx > self.resize_dimensions().len() {
|
||||
self.resize_dimensions_mut().push(None);
|
||||
} else {
|
||||
self.resize_dimensions_mut().insert(insertion_idx, None);
|
||||
}
|
||||
|
||||
self.focus_container(insertion_idx);
|
||||
|
||||
insertion_idx
|
||||
}
|
||||
|
||||
// this fn respects locked container indexes - we should use it for pretty much everything
|
||||
// except monocle and maximize toggles
|
||||
pub fn remove_container_by_idx(&mut self, idx: usize) -> Option<Container> {
|
||||
let mut locked_containers = self.locked_containers().clone();
|
||||
let mut ld = LockedDeque::new(self.containers_mut(), &mut locked_containers);
|
||||
let container = ld.remove(idx);
|
||||
self.locked_containers = locked_containers;
|
||||
|
||||
if idx < self.resize_dimensions().len() {
|
||||
self.resize_dimensions_mut().remove(idx);
|
||||
}
|
||||
|
||||
if idx < self.containers().len() {
|
||||
return self.containers_mut().remove(idx);
|
||||
}
|
||||
|
||||
None
|
||||
container
|
||||
}
|
||||
|
||||
fn container_idx_for_window(&self, hwnd: isize) -> Option<usize> {
|
||||
@@ -912,15 +933,7 @@ impl Workspace {
|
||||
.ok_or_else(|| anyhow!("there is no window"))?;
|
||||
|
||||
if container.windows().is_empty() {
|
||||
self.containers_mut()
|
||||
.remove(container_idx)
|
||||
.ok_or_else(|| anyhow!("there is no container"))?;
|
||||
|
||||
// Whenever a container is empty, we need to remove any resize dimensions for it too
|
||||
if self.resize_dimensions().get(container_idx).is_some() {
|
||||
self.resize_dimensions_mut().remove(container_idx);
|
||||
}
|
||||
|
||||
self.remove_container_by_idx(container_idx);
|
||||
self.focus_previous_container();
|
||||
} else {
|
||||
container.load_focused_window();
|
||||
@@ -957,6 +970,7 @@ impl Workspace {
|
||||
len,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_idx_for_cycle_direction(&self, direction: CycleDirection) -> Option<usize> {
|
||||
Option::from(direction.next_idx(
|
||||
self.focused_container_idx(),
|
||||
@@ -964,6 +978,7 @@ impl Workspace {
|
||||
))
|
||||
}
|
||||
|
||||
// this is what we use for stacking
|
||||
pub fn move_window_to_container(&mut self, target_container_idx: usize) -> Result<()> {
|
||||
let focused_idx = self.focused_container_idx();
|
||||
|
||||
@@ -977,8 +992,7 @@ impl Workspace {
|
||||
|
||||
// This is a little messy
|
||||
let adjusted_target_container_index = if container.windows().is_empty() {
|
||||
self.containers_mut().remove(focused_idx);
|
||||
self.resize_dimensions_mut().remove(focused_idx);
|
||||
self.remove_container_by_idx(focused_idx);
|
||||
|
||||
if focused_idx < target_container_idx {
|
||||
target_container_idx.saturating_sub(1)
|
||||
@@ -1017,8 +1031,7 @@ impl Workspace {
|
||||
.ok_or_else(|| anyhow!("there is no window"))?;
|
||||
|
||||
if container.windows().is_empty() {
|
||||
self.containers_mut().remove(focused_container_idx);
|
||||
self.resize_dimensions_mut().remove(focused_container_idx);
|
||||
self.remove_container_by_idx(focused_container_idx);
|
||||
} else {
|
||||
container.load_focused_window();
|
||||
}
|
||||
@@ -1038,8 +1051,8 @@ impl Workspace {
|
||||
|
||||
let mut container = Container::default();
|
||||
container.add_window(window);
|
||||
self.containers_mut().insert(focused_idx, container);
|
||||
self.resize_dimensions_mut().insert(focused_idx, None);
|
||||
|
||||
self.insert_container_at_idx(focused_idx, container);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1054,19 +1067,7 @@ impl Workspace {
|
||||
let mut container = Container::default();
|
||||
container.add_window(window);
|
||||
|
||||
if next_idx > self.containers().len() {
|
||||
self.containers_mut().push_back(container);
|
||||
} else {
|
||||
self.containers_mut().insert(next_idx, container);
|
||||
}
|
||||
|
||||
if next_idx > self.resize_dimensions().len() {
|
||||
self.resize_dimensions_mut().push(None);
|
||||
} else {
|
||||
self.resize_dimensions_mut().insert(next_idx, None);
|
||||
}
|
||||
|
||||
self.focus_container(next_idx);
|
||||
self.insert_container_at_idx(next_idx, container);
|
||||
}
|
||||
|
||||
pub fn new_floating_window(&mut self) -> Result<()> {
|
||||
@@ -1100,8 +1101,7 @@ impl Workspace {
|
||||
.ok_or_else(|| anyhow!("there is no window"))?;
|
||||
|
||||
if container.windows().is_empty() {
|
||||
self.containers_mut().remove(focused_idx);
|
||||
self.resize_dimensions_mut().remove(focused_idx);
|
||||
self.remove_container_by_idx(focused_idx);
|
||||
|
||||
if focused_idx == self.containers().len() {
|
||||
self.focus_container(focused_idx.saturating_sub(1));
|
||||
@@ -1373,6 +1373,10 @@ impl Workspace {
|
||||
|
||||
pub fn new_monocle_container(&mut self) -> Result<()> {
|
||||
let focused_idx = self.focused_container_idx();
|
||||
|
||||
// we shouldn't use remove_container_by_idx here because it doesn't make sense for
|
||||
// monocle and maximized toggles which take over the whole screen before being reinserted
|
||||
// at the same index to respect locked container indexes
|
||||
let container = self
|
||||
.containers_mut()
|
||||
.remove(focused_idx)
|
||||
@@ -1410,6 +1414,9 @@ impl Workspace {
|
||||
.resize(restore_idx, Container::default());
|
||||
}
|
||||
|
||||
// we shouldn't use insert_container_at_index here because it doesn't make sense for
|
||||
// monocle and maximized toggles which take over the whole screen before being reinserted
|
||||
// at the same index to respect locked container indexes
|
||||
self.containers_mut().insert(restore_idx, container);
|
||||
self.focus_container(restore_idx);
|
||||
self.focused_container_mut()
|
||||
@@ -1481,6 +1488,9 @@ impl Workspace {
|
||||
.ok_or_else(|| anyhow!("there is no window"))?;
|
||||
|
||||
if container.windows().is_empty() {
|
||||
// we shouldn't use remove_container_by_idx here because it doesn't make sense for
|
||||
// monocle and maximized toggles which take over the whole screen before being reinserted
|
||||
// at the same index to respect locked container indexes
|
||||
self.containers_mut().remove(focused_idx);
|
||||
if self.resize_dimensions().get(focused_idx).is_some() {
|
||||
self.resize_dimensions_mut().remove(focused_idx);
|
||||
@@ -1520,8 +1530,11 @@ impl Workspace {
|
||||
|
||||
let mut container = Container::default();
|
||||
container.windows_mut().push_back(window);
|
||||
self.containers_mut().insert(restore_idx, container);
|
||||
|
||||
// we shouldn't use insert_container_at_index here because it doesn't make sense for
|
||||
// monocle and maximized toggles which take over the whole screen before being reinserted
|
||||
// at the same index to respect locked container indexes
|
||||
self.containers_mut().insert(restore_idx, container);
|
||||
self.focus_container(restore_idx);
|
||||
|
||||
self.focused_container_mut()
|
||||
@@ -1640,6 +1653,170 @@ impl Workspace {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use crate::container::Container;
|
||||
use crate::Window;
|
||||
use std::collections::BTreeSet;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[test]
|
||||
fn test_locked_containers_with_new_window() {
|
||||
let mut ws = Workspace::default();
|
||||
|
||||
let mut state = HashMap::new();
|
||||
let mut locked = BTreeSet::new();
|
||||
|
||||
// add 3 containers
|
||||
for i in 0..4 {
|
||||
let container = Container::default();
|
||||
state.insert(i, container.id().to_string());
|
||||
ws.add_container_to_back(container);
|
||||
}
|
||||
assert_eq!(ws.containers().len(), 4);
|
||||
|
||||
// set index 3 locked
|
||||
locked.insert(3);
|
||||
ws.locked_containers = locked;
|
||||
|
||||
// focus container at index 2
|
||||
ws.focus_container(2);
|
||||
|
||||
// simulate a new window being launched on this workspace
|
||||
ws.new_container_for_window(Window::from(123));
|
||||
|
||||
// new length should be 5, with the focus on the new window at index 4
|
||||
assert_eq!(ws.containers().len(), 5);
|
||||
assert_eq!(ws.focused_container_idx(), 4);
|
||||
assert_eq!(
|
||||
ws.focused_container()
|
||||
.unwrap()
|
||||
.focused_window()
|
||||
.unwrap()
|
||||
.hwnd,
|
||||
123
|
||||
);
|
||||
|
||||
// when inserting a new container at index 0, index 3's container should not change
|
||||
ws.focus_container(0);
|
||||
ws.new_container_for_window(Window::from(234));
|
||||
assert_eq!(
|
||||
ws.containers()[3].id().to_string(),
|
||||
state.get(&3).unwrap().to_string()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_locked_containers_remove_window() {
|
||||
let mut ws = Workspace::default();
|
||||
|
||||
let mut locked = BTreeSet::new();
|
||||
|
||||
// add 4 containers
|
||||
for i in 0..4 {
|
||||
let mut container = Container::default();
|
||||
container.windows_mut().push_back(Window::from(i));
|
||||
ws.add_container_to_back(container);
|
||||
}
|
||||
assert_eq!(ws.containers().len(), 4);
|
||||
|
||||
// set index 1 locked
|
||||
locked.insert(1);
|
||||
ws.locked_containers = locked;
|
||||
|
||||
ws.remove_window(0).unwrap();
|
||||
assert_eq!(ws.containers()[0].focused_window().unwrap().hwnd, 2);
|
||||
// index 1 should still be the same
|
||||
assert_eq!(ws.containers()[1].focused_window().unwrap().hwnd, 1);
|
||||
assert_eq!(ws.containers()[2].focused_window().unwrap().hwnd, 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_locked_containers_toggle_float() {
|
||||
let mut ws = Workspace::default();
|
||||
|
||||
let mut locked = BTreeSet::new();
|
||||
|
||||
// add 4 containers
|
||||
for i in 0..4 {
|
||||
let mut container = Container::default();
|
||||
container.windows_mut().push_back(Window::from(i));
|
||||
ws.add_container_to_back(container);
|
||||
}
|
||||
assert_eq!(ws.containers().len(), 4);
|
||||
|
||||
// set index 1 locked
|
||||
locked.insert(1);
|
||||
ws.locked_containers = locked;
|
||||
|
||||
// set index 0 focused
|
||||
ws.focus_container(0);
|
||||
|
||||
// float index 0
|
||||
ws.new_floating_window().unwrap();
|
||||
|
||||
assert_eq!(ws.containers()[0].focused_window().unwrap().hwnd, 2);
|
||||
// index 1 should still be the same
|
||||
assert_eq!(ws.containers()[1].focused_window().unwrap().hwnd, 1);
|
||||
assert_eq!(ws.containers()[2].focused_window().unwrap().hwnd, 3);
|
||||
|
||||
// unfloat - have to do this semi-manually becuase of calls to WindowsApi in
|
||||
// new_container_for_floating_window which usually handles unfloating
|
||||
let window = ws.floating_windows_mut().pop().unwrap();
|
||||
let mut container = Container::default();
|
||||
container.add_window(window);
|
||||
ws.insert_container_at_idx(ws.focused_container_idx(), container);
|
||||
|
||||
// all indexes should be at their original position
|
||||
for i in 0..4 {
|
||||
assert_eq!(
|
||||
ws.containers()[i].focused_window().unwrap().hwnd,
|
||||
i as isize
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_locked_containers_stack() {
|
||||
let mut ws = Workspace::default();
|
||||
|
||||
let mut locked = BTreeSet::new();
|
||||
|
||||
// add 6 containers
|
||||
for i in 0..6 {
|
||||
let mut container = Container::default();
|
||||
container.windows_mut().push_back(Window::from(i));
|
||||
ws.add_container_to_back(container);
|
||||
}
|
||||
assert_eq!(ws.containers().len(), 6);
|
||||
|
||||
// set index 4 locked
|
||||
locked.insert(4);
|
||||
ws.locked_containers = locked;
|
||||
|
||||
// set index 3 focused
|
||||
ws.focus_container(3);
|
||||
|
||||
// stack index 3 on top of index 2
|
||||
ws.move_window_to_container(2).unwrap();
|
||||
|
||||
assert_eq!(ws.containers()[0].focused_window().unwrap().hwnd, 0);
|
||||
assert_eq!(ws.containers()[1].focused_window().unwrap().hwnd, 1);
|
||||
assert_eq!(ws.containers()[2].windows().len(), 2);
|
||||
assert_eq!(ws.containers()[3].focused_window().unwrap().hwnd, 5);
|
||||
// index 4 should still be the same
|
||||
assert_eq!(ws.containers()[4].focused_window().unwrap().hwnd, 4);
|
||||
|
||||
// unstack
|
||||
ws.new_container_for_focused_window().unwrap();
|
||||
|
||||
// all indexes should be at their original position
|
||||
for i in 0..6 {
|
||||
assert_eq!(
|
||||
ws.containers()[i].focused_window().unwrap().hwnd,
|
||||
i as isize
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_contains_window() {
|
||||
// Create default workspace
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "komorebic-no-console"
|
||||
version = "0.1.35"
|
||||
version = "0.1.36"
|
||||
description = "The command-line interface (without a console) for Komorebi, a tiling window manager for Windows"
|
||||
repository = "https://github.com/LGUG2Z/komorebi"
|
||||
edition = "2021"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "komorebic"
|
||||
version = "0.1.35"
|
||||
version = "0.1.36"
|
||||
description = "The command-line interface for Komorebi, a tiling window manager for Windows"
|
||||
repository = "https://github.com/LGUG2Z/komorebi"
|
||||
edition = "2021"
|
||||
|
||||
@@ -1283,6 +1283,8 @@ enum SubCommand {
|
||||
ToggleMonocle,
|
||||
/// Toggle native maximization for the focused window
|
||||
ToggleMaximize,
|
||||
/// Toggle a lock for the focused container, ensuring it will not be displaced by any new windows
|
||||
ToggleLock,
|
||||
/// Restore all hidden windows (debugging command)
|
||||
RestoreWindows,
|
||||
/// Force komorebi to manage the focused window
|
||||
@@ -1947,6 +1949,9 @@ fn main() -> Result<()> {
|
||||
SubCommand::ToggleMaximize => {
|
||||
send_message(&SocketMessage::ToggleMaximize)?;
|
||||
}
|
||||
SubCommand::ToggleLock => {
|
||||
send_message(&SocketMessage::ToggleLock)?;
|
||||
}
|
||||
SubCommand::WorkspaceLayout(arg) => {
|
||||
send_message(&SocketMessage::WorkspaceLayout(
|
||||
arg.monitor,
|
||||
|
||||
54
schema.json
54
schema.json
@@ -2211,6 +2211,38 @@
|
||||
"Mantle",
|
||||
"Crust"
|
||||
]
|
||||
},
|
||||
"unfocused_locked_border": {
|
||||
"description": "Border colour when the container is unfocused and locked (default: Red)",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Rosewater",
|
||||
"Flamingo",
|
||||
"Pink",
|
||||
"Mauve",
|
||||
"Red",
|
||||
"Maroon",
|
||||
"Peach",
|
||||
"Yellow",
|
||||
"Green",
|
||||
"Teal",
|
||||
"Sky",
|
||||
"Sapphire",
|
||||
"Blue",
|
||||
"Lavender",
|
||||
"Text",
|
||||
"Subtext1",
|
||||
"Subtext0",
|
||||
"Overlay2",
|
||||
"Overlay1",
|
||||
"Overlay0",
|
||||
"Surface2",
|
||||
"Surface1",
|
||||
"Surface0",
|
||||
"Base",
|
||||
"Mantle",
|
||||
"Crust"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2700,6 +2732,28 @@
|
||||
"Base0E",
|
||||
"Base0F"
|
||||
]
|
||||
},
|
||||
"unfocused_locked_border": {
|
||||
"description": "Border colour when the container is unfocused and locked (default: Base08)",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Base00",
|
||||
"Base01",
|
||||
"Base02",
|
||||
"Base03",
|
||||
"Base04",
|
||||
"Base05",
|
||||
"Base06",
|
||||
"Base07",
|
||||
"Base08",
|
||||
"Base09",
|
||||
"Base0A",
|
||||
"Base0B",
|
||||
"Base0C",
|
||||
"Base0D",
|
||||
"Base0E",
|
||||
"Base0F"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user