├── .github └── workflows │ └── rust.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md ├── lua_configs └── idle_config.lua ├── rustfmt.toml └── src ├── color.rs ├── config.rs ├── dbus.rs ├── joystick_handler.rs ├── main.rs ├── sunset.rs ├── types.rs ├── udev_handler.rs ├── utils.rs └── wayland.rs /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - name: Install udev 19 | run: sudo apt-get install -y libudev-dev 20 | - uses: actions/checkout@v3 21 | - name: Build 22 | run: cargo build --verbose 23 | - name: Run tests 24 | run: cargo test --verbose 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | debug/ 4 | target/ 5 | tmp/ 6 | 7 | # These are backup files generated by rustfmt 8 | **/*.rs.bk 9 | 10 | # MSVC Windows builds of rustc generate these, which store debugging information 11 | *.pdb 12 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.21.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "aho-corasick" 22 | version = "1.1.1" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" 25 | dependencies = [ 26 | "memchr", 27 | ] 28 | 29 | [[package]] 30 | name = "android-tzdata" 31 | version = "0.1.1" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" 34 | 35 | [[package]] 36 | name = "android_system_properties" 37 | version = "0.1.5" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 40 | dependencies = [ 41 | "libc", 42 | ] 43 | 44 | [[package]] 45 | name = "anstream" 46 | version = "0.6.15" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" 49 | dependencies = [ 50 | "anstyle", 51 | "anstyle-parse", 52 | "anstyle-query", 53 | "anstyle-wincon", 54 | "colorchoice", 55 | "is_terminal_polyfill", 56 | "utf8parse", 57 | ] 58 | 59 | [[package]] 60 | name = "anstyle" 61 | version = "1.0.8" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" 64 | 65 | [[package]] 66 | name = "anstyle-parse" 67 | version = "0.2.2" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" 70 | dependencies = [ 71 | "utf8parse", 72 | ] 73 | 74 | [[package]] 75 | name = "anstyle-query" 76 | version = "1.0.0" 77 | source = "registry+https://github.com/rust-lang/crates.io-index" 78 | checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" 79 | dependencies = [ 80 | "windows-sys 0.48.0", 81 | ] 82 | 83 | [[package]] 84 | name = "anstyle-wincon" 85 | version = "3.0.1" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" 88 | dependencies = [ 89 | "anstyle", 90 | "windows-sys 0.48.0", 91 | ] 92 | 93 | [[package]] 94 | name = "anyhow" 95 | version = "1.0.91" 96 | source = "registry+https://github.com/rust-lang/crates.io-index" 97 | checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" 98 | 99 | [[package]] 100 | name = "async-broadcast" 101 | version = "0.5.1" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | checksum = "7c48ccdbf6ca6b121e0f586cbc0e73ae440e56c67c30fa0873b4e110d9c26d2b" 104 | dependencies = [ 105 | "event-listener 2.5.3", 106 | "futures-core", 107 | ] 108 | 109 | [[package]] 110 | name = "async-channel" 111 | version = "2.3.1" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" 114 | dependencies = [ 115 | "concurrent-queue", 116 | "event-listener-strategy", 117 | "futures-core", 118 | "pin-project-lite", 119 | ] 120 | 121 | [[package]] 122 | name = "async-executor" 123 | version = "1.13.1" 124 | source = "registry+https://github.com/rust-lang/crates.io-index" 125 | checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" 126 | dependencies = [ 127 | "async-task", 128 | "concurrent-queue", 129 | "fastrand 2.0.1", 130 | "futures-lite 2.3.0", 131 | "slab", 132 | ] 133 | 134 | [[package]] 135 | name = "async-fs" 136 | version = "1.6.0" 137 | source = "registry+https://github.com/rust-lang/crates.io-index" 138 | checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" 139 | dependencies = [ 140 | "async-lock 2.8.0", 141 | "autocfg", 142 | "blocking", 143 | "futures-lite 1.13.0", 144 | ] 145 | 146 | [[package]] 147 | name = "async-io" 148 | version = "1.13.0" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" 151 | dependencies = [ 152 | "async-lock 2.8.0", 153 | "autocfg", 154 | "cfg-if 1.0.0", 155 | "concurrent-queue", 156 | "futures-lite 1.13.0", 157 | "log", 158 | "parking", 159 | "polling 2.8.0", 160 | "rustix 0.37.27", 161 | "slab", 162 | "socket2 0.4.10", 163 | "waker-fn", 164 | ] 165 | 166 | [[package]] 167 | name = "async-io" 168 | version = "2.3.4" 169 | source = "registry+https://github.com/rust-lang/crates.io-index" 170 | checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" 171 | dependencies = [ 172 | "async-lock 3.4.0", 173 | "cfg-if 1.0.0", 174 | "concurrent-queue", 175 | "futures-io", 176 | "futures-lite 2.3.0", 177 | "parking", 178 | "polling 3.7.3", 179 | "rustix 0.38.37", 180 | "slab", 181 | "tracing", 182 | "windows-sys 0.59.0", 183 | ] 184 | 185 | [[package]] 186 | name = "async-lock" 187 | version = "2.8.0" 188 | source = "registry+https://github.com/rust-lang/crates.io-index" 189 | checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" 190 | dependencies = [ 191 | "event-listener 2.5.3", 192 | ] 193 | 194 | [[package]] 195 | name = "async-lock" 196 | version = "3.4.0" 197 | source = "registry+https://github.com/rust-lang/crates.io-index" 198 | checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" 199 | dependencies = [ 200 | "event-listener 5.3.1", 201 | "event-listener-strategy", 202 | "pin-project-lite", 203 | ] 204 | 205 | [[package]] 206 | name = "async-process" 207 | version = "1.8.1" 208 | source = "registry+https://github.com/rust-lang/crates.io-index" 209 | checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" 210 | dependencies = [ 211 | "async-io 1.13.0", 212 | "async-lock 2.8.0", 213 | "async-signal", 214 | "blocking", 215 | "cfg-if 1.0.0", 216 | "event-listener 3.1.0", 217 | "futures-lite 1.13.0", 218 | "rustix 0.38.37", 219 | "windows-sys 0.48.0", 220 | ] 221 | 222 | [[package]] 223 | name = "async-recursion" 224 | version = "1.1.1" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" 227 | dependencies = [ 228 | "proc-macro2", 229 | "quote", 230 | "syn 2.0.79", 231 | ] 232 | 233 | [[package]] 234 | name = "async-signal" 235 | version = "0.2.10" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" 238 | dependencies = [ 239 | "async-io 2.3.4", 240 | "async-lock 3.4.0", 241 | "atomic-waker", 242 | "cfg-if 1.0.0", 243 | "futures-core", 244 | "futures-io", 245 | "rustix 0.38.37", 246 | "signal-hook-registry", 247 | "slab", 248 | "windows-sys 0.59.0", 249 | ] 250 | 251 | [[package]] 252 | name = "async-task" 253 | version = "4.7.1" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" 256 | 257 | [[package]] 258 | name = "async-trait" 259 | version = "0.1.83" 260 | source = "registry+https://github.com/rust-lang/crates.io-index" 261 | checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" 262 | dependencies = [ 263 | "proc-macro2", 264 | "quote", 265 | "syn 2.0.79", 266 | ] 267 | 268 | [[package]] 269 | name = "atomic-waker" 270 | version = "1.1.2" 271 | source = "registry+https://github.com/rust-lang/crates.io-index" 272 | checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 273 | 274 | [[package]] 275 | name = "autocfg" 276 | version = "1.1.0" 277 | source = "registry+https://github.com/rust-lang/crates.io-index" 278 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 279 | 280 | [[package]] 281 | name = "backtrace" 282 | version = "0.3.69" 283 | source = "registry+https://github.com/rust-lang/crates.io-index" 284 | checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" 285 | dependencies = [ 286 | "addr2line", 287 | "cc", 288 | "cfg-if 1.0.0", 289 | "libc", 290 | "miniz_oxide", 291 | "object", 292 | "rustc-demangle", 293 | ] 294 | 295 | [[package]] 296 | name = "bitflags" 297 | version = "1.3.2" 298 | source = "registry+https://github.com/rust-lang/crates.io-index" 299 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 300 | 301 | [[package]] 302 | name = "bitflags" 303 | version = "2.6.0" 304 | source = "registry+https://github.com/rust-lang/crates.io-index" 305 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 306 | 307 | [[package]] 308 | name = "bitvec" 309 | version = "1.0.1" 310 | source = "registry+https://github.com/rust-lang/crates.io-index" 311 | checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" 312 | dependencies = [ 313 | "funty", 314 | "radium", 315 | "tap", 316 | "wyz", 317 | ] 318 | 319 | [[package]] 320 | name = "block-buffer" 321 | version = "0.10.4" 322 | source = "registry+https://github.com/rust-lang/crates.io-index" 323 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 324 | dependencies = [ 325 | "generic-array", 326 | ] 327 | 328 | [[package]] 329 | name = "blocking" 330 | version = "1.6.1" 331 | source = "registry+https://github.com/rust-lang/crates.io-index" 332 | checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" 333 | dependencies = [ 334 | "async-channel", 335 | "async-task", 336 | "futures-io", 337 | "futures-lite 2.3.0", 338 | "piper", 339 | ] 340 | 341 | [[package]] 342 | name = "bstr" 343 | version = "1.8.0" 344 | source = "registry+https://github.com/rust-lang/crates.io-index" 345 | checksum = "542f33a8835a0884b006a0c3df3dadd99c0c3f296ed26c2fdc8028e01ad6230c" 346 | dependencies = [ 347 | "memchr", 348 | "serde", 349 | ] 350 | 351 | [[package]] 352 | name = "bumpalo" 353 | version = "3.16.0" 354 | source = "registry+https://github.com/rust-lang/crates.io-index" 355 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 356 | 357 | [[package]] 358 | name = "bytemuck" 359 | version = "1.19.0" 360 | source = "registry+https://github.com/rust-lang/crates.io-index" 361 | checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" 362 | 363 | [[package]] 364 | name = "byteorder" 365 | version = "1.5.0" 366 | source = "registry+https://github.com/rust-lang/crates.io-index" 367 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 368 | 369 | [[package]] 370 | name = "bytes" 371 | version = "1.5.0" 372 | source = "registry+https://github.com/rust-lang/crates.io-index" 373 | checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" 374 | 375 | [[package]] 376 | name = "cc" 377 | version = "1.1.31" 378 | source = "registry+https://github.com/rust-lang/crates.io-index" 379 | checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" 380 | dependencies = [ 381 | "shlex", 382 | ] 383 | 384 | [[package]] 385 | name = "cfg-if" 386 | version = "0.1.10" 387 | source = "registry+https://github.com/rust-lang/crates.io-index" 388 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 389 | 390 | [[package]] 391 | name = "cfg-if" 392 | version = "1.0.0" 393 | source = "registry+https://github.com/rust-lang/crates.io-index" 394 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 395 | 396 | [[package]] 397 | name = "cfg_aliases" 398 | version = "0.2.1" 399 | source = "registry+https://github.com/rust-lang/crates.io-index" 400 | checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" 401 | 402 | [[package]] 403 | name = "chrono" 404 | version = "0.4.38" 405 | source = "registry+https://github.com/rust-lang/crates.io-index" 406 | checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" 407 | dependencies = [ 408 | "android-tzdata", 409 | "iana-time-zone", 410 | "js-sys", 411 | "num-traits", 412 | "wasm-bindgen", 413 | "windows-targets 0.52.6", 414 | ] 415 | 416 | [[package]] 417 | name = "clap" 418 | version = "4.5.20" 419 | source = "registry+https://github.com/rust-lang/crates.io-index" 420 | checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" 421 | dependencies = [ 422 | "clap_builder", 423 | "clap_derive", 424 | ] 425 | 426 | [[package]] 427 | name = "clap_builder" 428 | version = "4.5.20" 429 | source = "registry+https://github.com/rust-lang/crates.io-index" 430 | checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" 431 | dependencies = [ 432 | "anstream", 433 | "anstyle", 434 | "clap_lex", 435 | "strsim", 436 | ] 437 | 438 | [[package]] 439 | name = "clap_derive" 440 | version = "4.5.18" 441 | source = "registry+https://github.com/rust-lang/crates.io-index" 442 | checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" 443 | dependencies = [ 444 | "heck", 445 | "proc-macro2", 446 | "quote", 447 | "syn 2.0.79", 448 | ] 449 | 450 | [[package]] 451 | name = "clap_lex" 452 | version = "0.7.2" 453 | source = "registry+https://github.com/rust-lang/crates.io-index" 454 | checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" 455 | 456 | [[package]] 457 | name = "colorchoice" 458 | version = "1.0.0" 459 | source = "registry+https://github.com/rust-lang/crates.io-index" 460 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 461 | 462 | [[package]] 463 | name = "concurrent-queue" 464 | version = "2.5.0" 465 | source = "registry+https://github.com/rust-lang/crates.io-index" 466 | checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" 467 | dependencies = [ 468 | "crossbeam-utils 0.8.20", 469 | ] 470 | 471 | [[package]] 472 | name = "core-foundation-sys" 473 | version = "0.8.7" 474 | source = "registry+https://github.com/rust-lang/crates.io-index" 475 | checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 476 | 477 | [[package]] 478 | name = "cpufeatures" 479 | version = "0.2.14" 480 | source = "registry+https://github.com/rust-lang/crates.io-index" 481 | checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" 482 | dependencies = [ 483 | "libc", 484 | ] 485 | 486 | [[package]] 487 | name = "crossbeam-deque" 488 | version = "0.8.3" 489 | source = "registry+https://github.com/rust-lang/crates.io-index" 490 | checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" 491 | dependencies = [ 492 | "cfg-if 1.0.0", 493 | "crossbeam-epoch", 494 | "crossbeam-utils 0.8.20", 495 | ] 496 | 497 | [[package]] 498 | name = "crossbeam-epoch" 499 | version = "0.9.15" 500 | source = "registry+https://github.com/rust-lang/crates.io-index" 501 | checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" 502 | dependencies = [ 503 | "autocfg", 504 | "cfg-if 1.0.0", 505 | "crossbeam-utils 0.8.20", 506 | "memoffset 0.9.0", 507 | "scopeguard", 508 | ] 509 | 510 | [[package]] 511 | name = "crossbeam-utils" 512 | version = "0.7.2" 513 | source = "registry+https://github.com/rust-lang/crates.io-index" 514 | checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" 515 | dependencies = [ 516 | "autocfg", 517 | "cfg-if 0.1.10", 518 | "lazy_static", 519 | ] 520 | 521 | [[package]] 522 | name = "crossbeam-utils" 523 | version = "0.8.20" 524 | source = "registry+https://github.com/rust-lang/crates.io-index" 525 | checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" 526 | 527 | [[package]] 528 | name = "crypto-common" 529 | version = "0.1.6" 530 | source = "registry+https://github.com/rust-lang/crates.io-index" 531 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 532 | dependencies = [ 533 | "generic-array", 534 | "typenum", 535 | ] 536 | 537 | [[package]] 538 | name = "derivative" 539 | version = "2.2.0" 540 | source = "registry+https://github.com/rust-lang/crates.io-index" 541 | checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" 542 | dependencies = [ 543 | "proc-macro2", 544 | "quote", 545 | "syn 1.0.109", 546 | ] 547 | 548 | [[package]] 549 | name = "digest" 550 | version = "0.10.7" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 553 | dependencies = [ 554 | "block-buffer", 555 | "crypto-common", 556 | ] 557 | 558 | [[package]] 559 | name = "dlib" 560 | version = "0.5.2" 561 | source = "registry+https://github.com/rust-lang/crates.io-index" 562 | checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" 563 | dependencies = [ 564 | "libloading", 565 | ] 566 | 567 | [[package]] 568 | name = "downcast-rs" 569 | version = "1.2.0" 570 | source = "registry+https://github.com/rust-lang/crates.io-index" 571 | checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" 572 | 573 | [[package]] 574 | name = "either" 575 | version = "1.9.0" 576 | source = "registry+https://github.com/rust-lang/crates.io-index" 577 | checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" 578 | 579 | [[package]] 580 | name = "enumflags2" 581 | version = "0.7.10" 582 | source = "registry+https://github.com/rust-lang/crates.io-index" 583 | checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" 584 | dependencies = [ 585 | "enumflags2_derive", 586 | "serde", 587 | ] 588 | 589 | [[package]] 590 | name = "enumflags2_derive" 591 | version = "0.7.10" 592 | source = "registry+https://github.com/rust-lang/crates.io-index" 593 | checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" 594 | dependencies = [ 595 | "proc-macro2", 596 | "quote", 597 | "syn 2.0.79", 598 | ] 599 | 600 | [[package]] 601 | name = "env_logger" 602 | version = "0.10.2" 603 | source = "registry+https://github.com/rust-lang/crates.io-index" 604 | checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" 605 | dependencies = [ 606 | "humantime", 607 | "is-terminal", 608 | "log", 609 | "regex", 610 | "termcolor", 611 | ] 612 | 613 | [[package]] 614 | name = "equivalent" 615 | version = "1.0.1" 616 | source = "registry+https://github.com/rust-lang/crates.io-index" 617 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 618 | 619 | [[package]] 620 | name = "errno" 621 | version = "0.3.9" 622 | source = "registry+https://github.com/rust-lang/crates.io-index" 623 | checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" 624 | dependencies = [ 625 | "libc", 626 | "windows-sys 0.52.0", 627 | ] 628 | 629 | [[package]] 630 | name = "evdev" 631 | version = "0.12.2" 632 | source = "registry+https://github.com/rust-lang/crates.io-index" 633 | checksum = "ab6055a93a963297befb0f4f6e18f314aec9767a4bbe88b151126df2433610a7" 634 | dependencies = [ 635 | "bitvec", 636 | "cfg-if 1.0.0", 637 | "futures-core", 638 | "libc", 639 | "nix 0.23.2", 640 | "thiserror", 641 | "tokio", 642 | ] 643 | 644 | [[package]] 645 | name = "event-listener" 646 | version = "2.5.3" 647 | source = "registry+https://github.com/rust-lang/crates.io-index" 648 | checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" 649 | 650 | [[package]] 651 | name = "event-listener" 652 | version = "3.1.0" 653 | source = "registry+https://github.com/rust-lang/crates.io-index" 654 | checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" 655 | dependencies = [ 656 | "concurrent-queue", 657 | "parking", 658 | "pin-project-lite", 659 | ] 660 | 661 | [[package]] 662 | name = "event-listener" 663 | version = "5.3.1" 664 | source = "registry+https://github.com/rust-lang/crates.io-index" 665 | checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" 666 | dependencies = [ 667 | "concurrent-queue", 668 | "parking", 669 | "pin-project-lite", 670 | ] 671 | 672 | [[package]] 673 | name = "event-listener-strategy" 674 | version = "0.5.2" 675 | source = "registry+https://github.com/rust-lang/crates.io-index" 676 | checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" 677 | dependencies = [ 678 | "event-listener 5.3.1", 679 | "pin-project-lite", 680 | ] 681 | 682 | [[package]] 683 | name = "fastrand" 684 | version = "1.9.0" 685 | source = "registry+https://github.com/rust-lang/crates.io-index" 686 | checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" 687 | dependencies = [ 688 | "instant", 689 | ] 690 | 691 | [[package]] 692 | name = "fastrand" 693 | version = "2.0.1" 694 | source = "registry+https://github.com/rust-lang/crates.io-index" 695 | checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" 696 | 697 | [[package]] 698 | name = "funty" 699 | version = "2.0.0" 700 | source = "registry+https://github.com/rust-lang/crates.io-index" 701 | checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" 702 | 703 | [[package]] 704 | name = "futures" 705 | version = "0.1.31" 706 | source = "registry+https://github.com/rust-lang/crates.io-index" 707 | checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" 708 | 709 | [[package]] 710 | name = "futures" 711 | version = "0.3.31" 712 | source = "registry+https://github.com/rust-lang/crates.io-index" 713 | checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" 714 | dependencies = [ 715 | "futures-channel", 716 | "futures-core", 717 | "futures-executor", 718 | "futures-io", 719 | "futures-sink", 720 | "futures-task", 721 | "futures-util", 722 | ] 723 | 724 | [[package]] 725 | name = "futures-channel" 726 | version = "0.3.31" 727 | source = "registry+https://github.com/rust-lang/crates.io-index" 728 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 729 | dependencies = [ 730 | "futures-core", 731 | "futures-sink", 732 | ] 733 | 734 | [[package]] 735 | name = "futures-core" 736 | version = "0.3.31" 737 | source = "registry+https://github.com/rust-lang/crates.io-index" 738 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 739 | 740 | [[package]] 741 | name = "futures-executor" 742 | version = "0.3.31" 743 | source = "registry+https://github.com/rust-lang/crates.io-index" 744 | checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" 745 | dependencies = [ 746 | "futures-core", 747 | "futures-task", 748 | "futures-util", 749 | ] 750 | 751 | [[package]] 752 | name = "futures-io" 753 | version = "0.3.31" 754 | source = "registry+https://github.com/rust-lang/crates.io-index" 755 | checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 756 | 757 | [[package]] 758 | name = "futures-lite" 759 | version = "1.13.0" 760 | source = "registry+https://github.com/rust-lang/crates.io-index" 761 | checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" 762 | dependencies = [ 763 | "fastrand 1.9.0", 764 | "futures-core", 765 | "futures-io", 766 | "memchr", 767 | "parking", 768 | "pin-project-lite", 769 | "waker-fn", 770 | ] 771 | 772 | [[package]] 773 | name = "futures-lite" 774 | version = "2.3.0" 775 | source = "registry+https://github.com/rust-lang/crates.io-index" 776 | checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" 777 | dependencies = [ 778 | "fastrand 2.0.1", 779 | "futures-core", 780 | "futures-io", 781 | "parking", 782 | "pin-project-lite", 783 | ] 784 | 785 | [[package]] 786 | name = "futures-macro" 787 | version = "0.3.31" 788 | source = "registry+https://github.com/rust-lang/crates.io-index" 789 | checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" 790 | dependencies = [ 791 | "proc-macro2", 792 | "quote", 793 | "syn 2.0.79", 794 | ] 795 | 796 | [[package]] 797 | name = "futures-sink" 798 | version = "0.3.31" 799 | source = "registry+https://github.com/rust-lang/crates.io-index" 800 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 801 | 802 | [[package]] 803 | name = "futures-task" 804 | version = "0.3.31" 805 | source = "registry+https://github.com/rust-lang/crates.io-index" 806 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 807 | 808 | [[package]] 809 | name = "futures-util" 810 | version = "0.3.31" 811 | source = "registry+https://github.com/rust-lang/crates.io-index" 812 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 813 | dependencies = [ 814 | "futures 0.1.31", 815 | "futures-channel", 816 | "futures-core", 817 | "futures-io", 818 | "futures-macro", 819 | "futures-sink", 820 | "futures-task", 821 | "memchr", 822 | "pin-project-lite", 823 | "pin-utils", 824 | "slab", 825 | ] 826 | 827 | [[package]] 828 | name = "generic-array" 829 | version = "0.14.7" 830 | source = "registry+https://github.com/rust-lang/crates.io-index" 831 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 832 | dependencies = [ 833 | "typenum", 834 | "version_check", 835 | ] 836 | 837 | [[package]] 838 | name = "getrandom" 839 | version = "0.2.10" 840 | source = "registry+https://github.com/rust-lang/crates.io-index" 841 | checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" 842 | dependencies = [ 843 | "cfg-if 1.0.0", 844 | "libc", 845 | "wasi", 846 | ] 847 | 848 | [[package]] 849 | name = "gimli" 850 | version = "0.28.0" 851 | source = "registry+https://github.com/rust-lang/crates.io-index" 852 | checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" 853 | 854 | [[package]] 855 | name = "hashbrown" 856 | version = "0.14.1" 857 | source = "registry+https://github.com/rust-lang/crates.io-index" 858 | checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" 859 | 860 | [[package]] 861 | name = "heck" 862 | version = "0.5.0" 863 | source = "registry+https://github.com/rust-lang/crates.io-index" 864 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 865 | 866 | [[package]] 867 | name = "hermit-abi" 868 | version = "0.3.9" 869 | source = "registry+https://github.com/rust-lang/crates.io-index" 870 | checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" 871 | 872 | [[package]] 873 | name = "hermit-abi" 874 | version = "0.4.0" 875 | source = "registry+https://github.com/rust-lang/crates.io-index" 876 | checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" 877 | 878 | [[package]] 879 | name = "hex" 880 | version = "0.4.3" 881 | source = "registry+https://github.com/rust-lang/crates.io-index" 882 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 883 | 884 | [[package]] 885 | name = "humantime" 886 | version = "2.1.0" 887 | source = "registry+https://github.com/rust-lang/crates.io-index" 888 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 889 | 890 | [[package]] 891 | name = "iana-time-zone" 892 | version = "0.1.61" 893 | source = "registry+https://github.com/rust-lang/crates.io-index" 894 | checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" 895 | dependencies = [ 896 | "android_system_properties", 897 | "core-foundation-sys", 898 | "iana-time-zone-haiku", 899 | "js-sys", 900 | "wasm-bindgen", 901 | "windows-core", 902 | ] 903 | 904 | [[package]] 905 | name = "iana-time-zone-haiku" 906 | version = "0.1.2" 907 | source = "registry+https://github.com/rust-lang/crates.io-index" 908 | checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" 909 | dependencies = [ 910 | "cc", 911 | ] 912 | 913 | [[package]] 914 | name = "indexmap" 915 | version = "2.5.0" 916 | source = "registry+https://github.com/rust-lang/crates.io-index" 917 | checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" 918 | dependencies = [ 919 | "equivalent", 920 | "hashbrown", 921 | ] 922 | 923 | [[package]] 924 | name = "inotify" 925 | version = "0.10.2" 926 | source = "registry+https://github.com/rust-lang/crates.io-index" 927 | checksum = "fdd168d97690d0b8c412d6b6c10360277f4d7ee495c5d0d5d5fe0854923255cc" 928 | dependencies = [ 929 | "bitflags 1.3.2", 930 | "futures-core", 931 | "inotify-sys", 932 | "libc", 933 | "tokio", 934 | ] 935 | 936 | [[package]] 937 | name = "inotify-sys" 938 | version = "0.1.5" 939 | source = "registry+https://github.com/rust-lang/crates.io-index" 940 | checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" 941 | dependencies = [ 942 | "libc", 943 | ] 944 | 945 | [[package]] 946 | name = "instant" 947 | version = "0.1.13" 948 | source = "registry+https://github.com/rust-lang/crates.io-index" 949 | checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" 950 | dependencies = [ 951 | "cfg-if 1.0.0", 952 | ] 953 | 954 | [[package]] 955 | name = "io-lifetimes" 956 | version = "1.0.11" 957 | source = "registry+https://github.com/rust-lang/crates.io-index" 958 | checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" 959 | dependencies = [ 960 | "hermit-abi 0.3.9", 961 | "libc", 962 | "windows-sys 0.48.0", 963 | ] 964 | 965 | [[package]] 966 | name = "is-terminal" 967 | version = "0.4.13" 968 | source = "registry+https://github.com/rust-lang/crates.io-index" 969 | checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" 970 | dependencies = [ 971 | "hermit-abi 0.4.0", 972 | "libc", 973 | "windows-sys 0.52.0", 974 | ] 975 | 976 | [[package]] 977 | name = "is_terminal_polyfill" 978 | version = "1.70.1" 979 | source = "registry+https://github.com/rust-lang/crates.io-index" 980 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 981 | 982 | [[package]] 983 | name = "js-sys" 984 | version = "0.3.72" 985 | source = "registry+https://github.com/rust-lang/crates.io-index" 986 | checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" 987 | dependencies = [ 988 | "wasm-bindgen", 989 | ] 990 | 991 | [[package]] 992 | name = "lazy_static" 993 | version = "1.5.0" 994 | source = "registry+https://github.com/rust-lang/crates.io-index" 995 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 996 | 997 | [[package]] 998 | name = "libc" 999 | version = "0.2.161" 1000 | source = "registry+https://github.com/rust-lang/crates.io-index" 1001 | checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" 1002 | 1003 | [[package]] 1004 | name = "libloading" 1005 | version = "0.8.1" 1006 | source = "registry+https://github.com/rust-lang/crates.io-index" 1007 | checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" 1008 | dependencies = [ 1009 | "cfg-if 1.0.0", 1010 | "windows-sys 0.48.0", 1011 | ] 1012 | 1013 | [[package]] 1014 | name = "libudev-sys" 1015 | version = "0.1.4" 1016 | source = "registry+https://github.com/rust-lang/crates.io-index" 1017 | checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324" 1018 | dependencies = [ 1019 | "libc", 1020 | "pkg-config", 1021 | ] 1022 | 1023 | [[package]] 1024 | name = "linux-raw-sys" 1025 | version = "0.3.8" 1026 | source = "registry+https://github.com/rust-lang/crates.io-index" 1027 | checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" 1028 | 1029 | [[package]] 1030 | name = "linux-raw-sys" 1031 | version = "0.4.14" 1032 | source = "registry+https://github.com/rust-lang/crates.io-index" 1033 | checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" 1034 | 1035 | [[package]] 1036 | name = "lock_api" 1037 | version = "0.4.12" 1038 | source = "registry+https://github.com/rust-lang/crates.io-index" 1039 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 1040 | dependencies = [ 1041 | "autocfg", 1042 | "scopeguard", 1043 | ] 1044 | 1045 | [[package]] 1046 | name = "log" 1047 | version = "0.4.22" 1048 | source = "registry+https://github.com/rust-lang/crates.io-index" 1049 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 1050 | 1051 | [[package]] 1052 | name = "luau0-src" 1053 | version = "0.11.0+luau647" 1054 | source = "registry+https://github.com/rust-lang/crates.io-index" 1055 | checksum = "ca47356c40f9121e3b3d582bf7355e8b25751b2e8afdfda49cf05775dfbc6b0a" 1056 | dependencies = [ 1057 | "cc", 1058 | ] 1059 | 1060 | [[package]] 1061 | name = "memchr" 1062 | version = "2.6.3" 1063 | source = "registry+https://github.com/rust-lang/crates.io-index" 1064 | checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" 1065 | 1066 | [[package]] 1067 | name = "memoffset" 1068 | version = "0.6.5" 1069 | source = "registry+https://github.com/rust-lang/crates.io-index" 1070 | checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" 1071 | dependencies = [ 1072 | "autocfg", 1073 | ] 1074 | 1075 | [[package]] 1076 | name = "memoffset" 1077 | version = "0.7.1" 1078 | source = "registry+https://github.com/rust-lang/crates.io-index" 1079 | checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" 1080 | dependencies = [ 1081 | "autocfg", 1082 | ] 1083 | 1084 | [[package]] 1085 | name = "memoffset" 1086 | version = "0.9.0" 1087 | source = "registry+https://github.com/rust-lang/crates.io-index" 1088 | checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" 1089 | dependencies = [ 1090 | "autocfg", 1091 | ] 1092 | 1093 | [[package]] 1094 | name = "miniz_oxide" 1095 | version = "0.7.1" 1096 | source = "registry+https://github.com/rust-lang/crates.io-index" 1097 | checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" 1098 | dependencies = [ 1099 | "adler", 1100 | ] 1101 | 1102 | [[package]] 1103 | name = "mio" 1104 | version = "1.0.2" 1105 | source = "registry+https://github.com/rust-lang/crates.io-index" 1106 | checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" 1107 | dependencies = [ 1108 | "hermit-abi 0.3.9", 1109 | "libc", 1110 | "wasi", 1111 | "windows-sys 0.52.0", 1112 | ] 1113 | 1114 | [[package]] 1115 | name = "mlua" 1116 | version = "0.9.9" 1117 | source = "registry+https://github.com/rust-lang/crates.io-index" 1118 | checksum = "d111deb18a9c9bd33e1541309f4742523bfab01d276bfa9a27519f6de9c11dc7" 1119 | dependencies = [ 1120 | "bstr", 1121 | "futures-util", 1122 | "libloading", 1123 | "mlua-sys", 1124 | "num-traits", 1125 | "once_cell", 1126 | "rustc-hash", 1127 | ] 1128 | 1129 | [[package]] 1130 | name = "mlua-sys" 1131 | version = "0.6.4" 1132 | source = "registry+https://github.com/rust-lang/crates.io-index" 1133 | checksum = "e9eebac25c35a13285456c88ee2fde93d9aee8bcfdaf03f9d6d12be3391351ec" 1134 | dependencies = [ 1135 | "cc", 1136 | "cfg-if 1.0.0", 1137 | "luau0-src", 1138 | "pkg-config", 1139 | ] 1140 | 1141 | [[package]] 1142 | name = "nix" 1143 | version = "0.23.2" 1144 | source = "registry+https://github.com/rust-lang/crates.io-index" 1145 | checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c" 1146 | dependencies = [ 1147 | "bitflags 1.3.2", 1148 | "cc", 1149 | "cfg-if 1.0.0", 1150 | "libc", 1151 | "memoffset 0.6.5", 1152 | ] 1153 | 1154 | [[package]] 1155 | name = "nix" 1156 | version = "0.26.4" 1157 | source = "registry+https://github.com/rust-lang/crates.io-index" 1158 | checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" 1159 | dependencies = [ 1160 | "bitflags 1.3.2", 1161 | "cfg-if 1.0.0", 1162 | "libc", 1163 | "memoffset 0.7.1", 1164 | ] 1165 | 1166 | [[package]] 1167 | name = "nix" 1168 | version = "0.29.0" 1169 | source = "registry+https://github.com/rust-lang/crates.io-index" 1170 | checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" 1171 | dependencies = [ 1172 | "bitflags 2.6.0", 1173 | "cfg-if 1.0.0", 1174 | "cfg_aliases", 1175 | "libc", 1176 | ] 1177 | 1178 | [[package]] 1179 | name = "ntapi" 1180 | version = "0.4.1" 1181 | source = "registry+https://github.com/rust-lang/crates.io-index" 1182 | checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" 1183 | dependencies = [ 1184 | "winapi", 1185 | ] 1186 | 1187 | [[package]] 1188 | name = "num-traits" 1189 | version = "0.2.19" 1190 | source = "registry+https://github.com/rust-lang/crates.io-index" 1191 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 1192 | dependencies = [ 1193 | "autocfg", 1194 | ] 1195 | 1196 | [[package]] 1197 | name = "object" 1198 | version = "0.32.1" 1199 | source = "registry+https://github.com/rust-lang/crates.io-index" 1200 | checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" 1201 | dependencies = [ 1202 | "memchr", 1203 | ] 1204 | 1205 | [[package]] 1206 | name = "once_cell" 1207 | version = "1.20.2" 1208 | source = "registry+https://github.com/rust-lang/crates.io-index" 1209 | checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" 1210 | 1211 | [[package]] 1212 | name = "ordered-stream" 1213 | version = "0.2.0" 1214 | source = "registry+https://github.com/rust-lang/crates.io-index" 1215 | checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" 1216 | dependencies = [ 1217 | "futures-core", 1218 | "pin-project-lite", 1219 | ] 1220 | 1221 | [[package]] 1222 | name = "parking" 1223 | version = "2.2.1" 1224 | source = "registry+https://github.com/rust-lang/crates.io-index" 1225 | checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" 1226 | 1227 | [[package]] 1228 | name = "parking_lot" 1229 | version = "0.12.3" 1230 | source = "registry+https://github.com/rust-lang/crates.io-index" 1231 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 1232 | dependencies = [ 1233 | "lock_api", 1234 | "parking_lot_core", 1235 | ] 1236 | 1237 | [[package]] 1238 | name = "parking_lot_core" 1239 | version = "0.9.10" 1240 | source = "registry+https://github.com/rust-lang/crates.io-index" 1241 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 1242 | dependencies = [ 1243 | "cfg-if 1.0.0", 1244 | "libc", 1245 | "redox_syscall 0.5.7", 1246 | "smallvec", 1247 | "windows-targets 0.52.6", 1248 | ] 1249 | 1250 | [[package]] 1251 | name = "pin-project-lite" 1252 | version = "0.2.13" 1253 | source = "registry+https://github.com/rust-lang/crates.io-index" 1254 | checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" 1255 | 1256 | [[package]] 1257 | name = "pin-utils" 1258 | version = "0.1.0" 1259 | source = "registry+https://github.com/rust-lang/crates.io-index" 1260 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1261 | 1262 | [[package]] 1263 | name = "piper" 1264 | version = "0.2.1" 1265 | source = "registry+https://github.com/rust-lang/crates.io-index" 1266 | checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" 1267 | dependencies = [ 1268 | "atomic-waker", 1269 | "fastrand 2.0.1", 1270 | "futures-io", 1271 | ] 1272 | 1273 | [[package]] 1274 | name = "pkg-config" 1275 | version = "0.3.27" 1276 | source = "registry+https://github.com/rust-lang/crates.io-index" 1277 | checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" 1278 | 1279 | [[package]] 1280 | name = "polling" 1281 | version = "2.8.0" 1282 | source = "registry+https://github.com/rust-lang/crates.io-index" 1283 | checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" 1284 | dependencies = [ 1285 | "autocfg", 1286 | "bitflags 1.3.2", 1287 | "cfg-if 1.0.0", 1288 | "concurrent-queue", 1289 | "libc", 1290 | "log", 1291 | "pin-project-lite", 1292 | "windows-sys 0.48.0", 1293 | ] 1294 | 1295 | [[package]] 1296 | name = "polling" 1297 | version = "3.7.3" 1298 | source = "registry+https://github.com/rust-lang/crates.io-index" 1299 | checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" 1300 | dependencies = [ 1301 | "cfg-if 1.0.0", 1302 | "concurrent-queue", 1303 | "hermit-abi 0.4.0", 1304 | "pin-project-lite", 1305 | "rustix 0.38.37", 1306 | "tracing", 1307 | "windows-sys 0.59.0", 1308 | ] 1309 | 1310 | [[package]] 1311 | name = "ppv-lite86" 1312 | version = "0.2.17" 1313 | source = "registry+https://github.com/rust-lang/crates.io-index" 1314 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 1315 | 1316 | [[package]] 1317 | name = "proc-macro-crate" 1318 | version = "1.3.1" 1319 | source = "registry+https://github.com/rust-lang/crates.io-index" 1320 | checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" 1321 | dependencies = [ 1322 | "once_cell", 1323 | "toml_edit", 1324 | ] 1325 | 1326 | [[package]] 1327 | name = "proc-macro2" 1328 | version = "1.0.87" 1329 | source = "registry+https://github.com/rust-lang/crates.io-index" 1330 | checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" 1331 | dependencies = [ 1332 | "unicode-ident", 1333 | ] 1334 | 1335 | [[package]] 1336 | name = "quick-xml" 1337 | version = "0.36.2" 1338 | source = "registry+https://github.com/rust-lang/crates.io-index" 1339 | checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe" 1340 | dependencies = [ 1341 | "memchr", 1342 | ] 1343 | 1344 | [[package]] 1345 | name = "quote" 1346 | version = "1.0.37" 1347 | source = "registry+https://github.com/rust-lang/crates.io-index" 1348 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" 1349 | dependencies = [ 1350 | "proc-macro2", 1351 | ] 1352 | 1353 | [[package]] 1354 | name = "radium" 1355 | version = "0.7.0" 1356 | source = "registry+https://github.com/rust-lang/crates.io-index" 1357 | checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" 1358 | 1359 | [[package]] 1360 | name = "rand" 1361 | version = "0.8.5" 1362 | source = "registry+https://github.com/rust-lang/crates.io-index" 1363 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1364 | dependencies = [ 1365 | "libc", 1366 | "rand_chacha", 1367 | "rand_core", 1368 | ] 1369 | 1370 | [[package]] 1371 | name = "rand_chacha" 1372 | version = "0.3.1" 1373 | source = "registry+https://github.com/rust-lang/crates.io-index" 1374 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1375 | dependencies = [ 1376 | "ppv-lite86", 1377 | "rand_core", 1378 | ] 1379 | 1380 | [[package]] 1381 | name = "rand_core" 1382 | version = "0.6.4" 1383 | source = "registry+https://github.com/rust-lang/crates.io-index" 1384 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1385 | dependencies = [ 1386 | "getrandom", 1387 | ] 1388 | 1389 | [[package]] 1390 | name = "rayon" 1391 | version = "1.8.0" 1392 | source = "registry+https://github.com/rust-lang/crates.io-index" 1393 | checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" 1394 | dependencies = [ 1395 | "either", 1396 | "rayon-core", 1397 | ] 1398 | 1399 | [[package]] 1400 | name = "rayon-core" 1401 | version = "1.12.0" 1402 | source = "registry+https://github.com/rust-lang/crates.io-index" 1403 | checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" 1404 | dependencies = [ 1405 | "crossbeam-deque", 1406 | "crossbeam-utils 0.8.20", 1407 | ] 1408 | 1409 | [[package]] 1410 | name = "redox_syscall" 1411 | version = "0.3.5" 1412 | source = "registry+https://github.com/rust-lang/crates.io-index" 1413 | checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" 1414 | dependencies = [ 1415 | "bitflags 1.3.2", 1416 | ] 1417 | 1418 | [[package]] 1419 | name = "redox_syscall" 1420 | version = "0.5.7" 1421 | source = "registry+https://github.com/rust-lang/crates.io-index" 1422 | checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" 1423 | dependencies = [ 1424 | "bitflags 2.6.0", 1425 | ] 1426 | 1427 | [[package]] 1428 | name = "regex" 1429 | version = "1.9.6" 1430 | source = "registry+https://github.com/rust-lang/crates.io-index" 1431 | checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff" 1432 | dependencies = [ 1433 | "aho-corasick", 1434 | "memchr", 1435 | "regex-automata", 1436 | "regex-syntax", 1437 | ] 1438 | 1439 | [[package]] 1440 | name = "regex-automata" 1441 | version = "0.3.9" 1442 | source = "registry+https://github.com/rust-lang/crates.io-index" 1443 | checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" 1444 | dependencies = [ 1445 | "aho-corasick", 1446 | "memchr", 1447 | "regex-syntax", 1448 | ] 1449 | 1450 | [[package]] 1451 | name = "regex-syntax" 1452 | version = "0.7.5" 1453 | source = "registry+https://github.com/rust-lang/crates.io-index" 1454 | checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" 1455 | 1456 | [[package]] 1457 | name = "rustc-demangle" 1458 | version = "0.1.23" 1459 | source = "registry+https://github.com/rust-lang/crates.io-index" 1460 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 1461 | 1462 | [[package]] 1463 | name = "rustc-hash" 1464 | version = "2.0.0" 1465 | source = "registry+https://github.com/rust-lang/crates.io-index" 1466 | checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" 1467 | 1468 | [[package]] 1469 | name = "rustix" 1470 | version = "0.37.27" 1471 | source = "registry+https://github.com/rust-lang/crates.io-index" 1472 | checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" 1473 | dependencies = [ 1474 | "bitflags 1.3.2", 1475 | "errno", 1476 | "io-lifetimes", 1477 | "libc", 1478 | "linux-raw-sys 0.3.8", 1479 | "windows-sys 0.48.0", 1480 | ] 1481 | 1482 | [[package]] 1483 | name = "rustix" 1484 | version = "0.38.37" 1485 | source = "registry+https://github.com/rust-lang/crates.io-index" 1486 | checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" 1487 | dependencies = [ 1488 | "bitflags 2.6.0", 1489 | "errno", 1490 | "libc", 1491 | "linux-raw-sys 0.4.14", 1492 | "windows-sys 0.52.0", 1493 | ] 1494 | 1495 | [[package]] 1496 | name = "scoped-tls" 1497 | version = "1.0.1" 1498 | source = "registry+https://github.com/rust-lang/crates.io-index" 1499 | checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" 1500 | 1501 | [[package]] 1502 | name = "scopeguard" 1503 | version = "1.2.0" 1504 | source = "registry+https://github.com/rust-lang/crates.io-index" 1505 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1506 | 1507 | [[package]] 1508 | name = "serde" 1509 | version = "1.0.210" 1510 | source = "registry+https://github.com/rust-lang/crates.io-index" 1511 | checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" 1512 | dependencies = [ 1513 | "serde_derive", 1514 | ] 1515 | 1516 | [[package]] 1517 | name = "serde_derive" 1518 | version = "1.0.210" 1519 | source = "registry+https://github.com/rust-lang/crates.io-index" 1520 | checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" 1521 | dependencies = [ 1522 | "proc-macro2", 1523 | "quote", 1524 | "syn 2.0.79", 1525 | ] 1526 | 1527 | [[package]] 1528 | name = "serde_repr" 1529 | version = "0.1.19" 1530 | source = "registry+https://github.com/rust-lang/crates.io-index" 1531 | checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" 1532 | dependencies = [ 1533 | "proc-macro2", 1534 | "quote", 1535 | "syn 2.0.79", 1536 | ] 1537 | 1538 | [[package]] 1539 | name = "sha1" 1540 | version = "0.10.6" 1541 | source = "registry+https://github.com/rust-lang/crates.io-index" 1542 | checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" 1543 | dependencies = [ 1544 | "cfg-if 1.0.0", 1545 | "cpufeatures", 1546 | "digest", 1547 | ] 1548 | 1549 | [[package]] 1550 | name = "shlex" 1551 | version = "1.3.0" 1552 | source = "registry+https://github.com/rust-lang/crates.io-index" 1553 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1554 | 1555 | [[package]] 1556 | name = "shmemfdrs2" 1557 | version = "1.0.0" 1558 | source = "registry+https://github.com/rust-lang/crates.io-index" 1559 | checksum = "70a05cf957f811e44f99c629e6d34025429912ffb2333f2960372669e670f54c" 1560 | dependencies = [ 1561 | "libc", 1562 | ] 1563 | 1564 | [[package]] 1565 | name = "signal-hook-registry" 1566 | version = "1.4.1" 1567 | source = "registry+https://github.com/rust-lang/crates.io-index" 1568 | checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" 1569 | dependencies = [ 1570 | "libc", 1571 | ] 1572 | 1573 | [[package]] 1574 | name = "slab" 1575 | version = "0.4.9" 1576 | source = "registry+https://github.com/rust-lang/crates.io-index" 1577 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1578 | dependencies = [ 1579 | "autocfg", 1580 | ] 1581 | 1582 | [[package]] 1583 | name = "sleepwatcher-rs" 1584 | version = "0.1.0" 1585 | dependencies = [ 1586 | "anyhow", 1587 | "bytemuck", 1588 | "chrono", 1589 | "clap", 1590 | "env_logger", 1591 | "evdev", 1592 | "futures 0.3.31", 1593 | "inotify", 1594 | "lazy_static", 1595 | "log", 1596 | "mlua", 1597 | "nix 0.29.0", 1598 | "once_cell", 1599 | "parking_lot", 1600 | "shmemfdrs2", 1601 | "sysinfo", 1602 | "tokio", 1603 | "tokio-timer", 1604 | "tokio-udev", 1605 | "udev 0.9.1", 1606 | "uuid", 1607 | "wayland-client", 1608 | "wayland-protocols", 1609 | "wayland-protocols-wlr", 1610 | "xdg", 1611 | "zbus", 1612 | ] 1613 | 1614 | [[package]] 1615 | name = "smallvec" 1616 | version = "1.11.2" 1617 | source = "registry+https://github.com/rust-lang/crates.io-index" 1618 | checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" 1619 | 1620 | [[package]] 1621 | name = "socket2" 1622 | version = "0.4.10" 1623 | source = "registry+https://github.com/rust-lang/crates.io-index" 1624 | checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" 1625 | dependencies = [ 1626 | "libc", 1627 | "winapi", 1628 | ] 1629 | 1630 | [[package]] 1631 | name = "socket2" 1632 | version = "0.5.7" 1633 | source = "registry+https://github.com/rust-lang/crates.io-index" 1634 | checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" 1635 | dependencies = [ 1636 | "libc", 1637 | "windows-sys 0.52.0", 1638 | ] 1639 | 1640 | [[package]] 1641 | name = "static_assertions" 1642 | version = "1.1.0" 1643 | source = "registry+https://github.com/rust-lang/crates.io-index" 1644 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 1645 | 1646 | [[package]] 1647 | name = "strsim" 1648 | version = "0.11.1" 1649 | source = "registry+https://github.com/rust-lang/crates.io-index" 1650 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1651 | 1652 | [[package]] 1653 | name = "syn" 1654 | version = "1.0.109" 1655 | source = "registry+https://github.com/rust-lang/crates.io-index" 1656 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 1657 | dependencies = [ 1658 | "proc-macro2", 1659 | "quote", 1660 | "unicode-ident", 1661 | ] 1662 | 1663 | [[package]] 1664 | name = "syn" 1665 | version = "2.0.79" 1666 | source = "registry+https://github.com/rust-lang/crates.io-index" 1667 | checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" 1668 | dependencies = [ 1669 | "proc-macro2", 1670 | "quote", 1671 | "unicode-ident", 1672 | ] 1673 | 1674 | [[package]] 1675 | name = "sysinfo" 1676 | version = "0.29.11" 1677 | source = "registry+https://github.com/rust-lang/crates.io-index" 1678 | checksum = "cd727fc423c2060f6c92d9534cef765c65a6ed3f428a03d7def74a8c4348e666" 1679 | dependencies = [ 1680 | "cfg-if 1.0.0", 1681 | "core-foundation-sys", 1682 | "libc", 1683 | "ntapi", 1684 | "once_cell", 1685 | "rayon", 1686 | "winapi", 1687 | ] 1688 | 1689 | [[package]] 1690 | name = "tap" 1691 | version = "1.0.1" 1692 | source = "registry+https://github.com/rust-lang/crates.io-index" 1693 | checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" 1694 | 1695 | [[package]] 1696 | name = "tempfile" 1697 | version = "3.8.0" 1698 | source = "registry+https://github.com/rust-lang/crates.io-index" 1699 | checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" 1700 | dependencies = [ 1701 | "cfg-if 1.0.0", 1702 | "fastrand 2.0.1", 1703 | "redox_syscall 0.3.5", 1704 | "rustix 0.38.37", 1705 | "windows-sys 0.48.0", 1706 | ] 1707 | 1708 | [[package]] 1709 | name = "termcolor" 1710 | version = "1.4.1" 1711 | source = "registry+https://github.com/rust-lang/crates.io-index" 1712 | checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" 1713 | dependencies = [ 1714 | "winapi-util", 1715 | ] 1716 | 1717 | [[package]] 1718 | name = "thiserror" 1719 | version = "1.0.65" 1720 | source = "registry+https://github.com/rust-lang/crates.io-index" 1721 | checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" 1722 | dependencies = [ 1723 | "thiserror-impl", 1724 | ] 1725 | 1726 | [[package]] 1727 | name = "thiserror-impl" 1728 | version = "1.0.65" 1729 | source = "registry+https://github.com/rust-lang/crates.io-index" 1730 | checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" 1731 | dependencies = [ 1732 | "proc-macro2", 1733 | "quote", 1734 | "syn 2.0.79", 1735 | ] 1736 | 1737 | [[package]] 1738 | name = "tokio" 1739 | version = "1.41.0" 1740 | source = "registry+https://github.com/rust-lang/crates.io-index" 1741 | checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" 1742 | dependencies = [ 1743 | "backtrace", 1744 | "bytes", 1745 | "libc", 1746 | "mio", 1747 | "pin-project-lite", 1748 | "signal-hook-registry", 1749 | "socket2 0.5.7", 1750 | "tokio-macros", 1751 | "tracing", 1752 | "windows-sys 0.52.0", 1753 | ] 1754 | 1755 | [[package]] 1756 | name = "tokio-executor" 1757 | version = "0.1.10" 1758 | source = "registry+https://github.com/rust-lang/crates.io-index" 1759 | checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671" 1760 | dependencies = [ 1761 | "crossbeam-utils 0.7.2", 1762 | "futures 0.1.31", 1763 | ] 1764 | 1765 | [[package]] 1766 | name = "tokio-macros" 1767 | version = "2.4.0" 1768 | source = "registry+https://github.com/rust-lang/crates.io-index" 1769 | checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" 1770 | dependencies = [ 1771 | "proc-macro2", 1772 | "quote", 1773 | "syn 2.0.79", 1774 | ] 1775 | 1776 | [[package]] 1777 | name = "tokio-timer" 1778 | version = "0.2.13" 1779 | source = "registry+https://github.com/rust-lang/crates.io-index" 1780 | checksum = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296" 1781 | dependencies = [ 1782 | "crossbeam-utils 0.7.2", 1783 | "futures 0.1.31", 1784 | "slab", 1785 | "tokio-executor", 1786 | ] 1787 | 1788 | [[package]] 1789 | name = "tokio-udev" 1790 | version = "0.9.1" 1791 | source = "registry+https://github.com/rust-lang/crates.io-index" 1792 | checksum = "f25418da261774ef3dcae985951bc138cf5fd49b3f4bd7450124ca75af8ed142" 1793 | dependencies = [ 1794 | "futures-core", 1795 | "tokio", 1796 | "udev 0.7.0", 1797 | ] 1798 | 1799 | [[package]] 1800 | name = "toml_datetime" 1801 | version = "0.6.8" 1802 | source = "registry+https://github.com/rust-lang/crates.io-index" 1803 | checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" 1804 | 1805 | [[package]] 1806 | name = "toml_edit" 1807 | version = "0.19.15" 1808 | source = "registry+https://github.com/rust-lang/crates.io-index" 1809 | checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" 1810 | dependencies = [ 1811 | "indexmap", 1812 | "toml_datetime", 1813 | "winnow", 1814 | ] 1815 | 1816 | [[package]] 1817 | name = "tracing" 1818 | version = "0.1.40" 1819 | source = "registry+https://github.com/rust-lang/crates.io-index" 1820 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" 1821 | dependencies = [ 1822 | "pin-project-lite", 1823 | "tracing-attributes", 1824 | "tracing-core", 1825 | ] 1826 | 1827 | [[package]] 1828 | name = "tracing-attributes" 1829 | version = "0.1.27" 1830 | source = "registry+https://github.com/rust-lang/crates.io-index" 1831 | checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" 1832 | dependencies = [ 1833 | "proc-macro2", 1834 | "quote", 1835 | "syn 2.0.79", 1836 | ] 1837 | 1838 | [[package]] 1839 | name = "tracing-core" 1840 | version = "0.1.32" 1841 | source = "registry+https://github.com/rust-lang/crates.io-index" 1842 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" 1843 | dependencies = [ 1844 | "once_cell", 1845 | ] 1846 | 1847 | [[package]] 1848 | name = "typenum" 1849 | version = "1.17.0" 1850 | source = "registry+https://github.com/rust-lang/crates.io-index" 1851 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 1852 | 1853 | [[package]] 1854 | name = "udev" 1855 | version = "0.7.0" 1856 | source = "registry+https://github.com/rust-lang/crates.io-index" 1857 | checksum = "4ebdbbd670373442a12fe9ef7aeb53aec4147a5a27a00bbc3ab639f08f48191a" 1858 | dependencies = [ 1859 | "libc", 1860 | "libudev-sys", 1861 | "pkg-config", 1862 | ] 1863 | 1864 | [[package]] 1865 | name = "udev" 1866 | version = "0.9.1" 1867 | source = "registry+https://github.com/rust-lang/crates.io-index" 1868 | checksum = "e3d5c197b95f1769931c89f85c33c407801d1fb7a311113bc0b39ad036f1bd81" 1869 | dependencies = [ 1870 | "io-lifetimes", 1871 | "libc", 1872 | "libudev-sys", 1873 | "pkg-config", 1874 | ] 1875 | 1876 | [[package]] 1877 | name = "uds_windows" 1878 | version = "1.1.0" 1879 | source = "registry+https://github.com/rust-lang/crates.io-index" 1880 | checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" 1881 | dependencies = [ 1882 | "memoffset 0.9.0", 1883 | "tempfile", 1884 | "winapi", 1885 | ] 1886 | 1887 | [[package]] 1888 | name = "unicode-ident" 1889 | version = "1.0.12" 1890 | source = "registry+https://github.com/rust-lang/crates.io-index" 1891 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 1892 | 1893 | [[package]] 1894 | name = "utf8parse" 1895 | version = "0.2.1" 1896 | source = "registry+https://github.com/rust-lang/crates.io-index" 1897 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 1898 | 1899 | [[package]] 1900 | name = "uuid" 1901 | version = "1.11.0" 1902 | source = "registry+https://github.com/rust-lang/crates.io-index" 1903 | checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" 1904 | dependencies = [ 1905 | "getrandom", 1906 | "rand", 1907 | ] 1908 | 1909 | [[package]] 1910 | name = "version_check" 1911 | version = "0.9.5" 1912 | source = "registry+https://github.com/rust-lang/crates.io-index" 1913 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 1914 | 1915 | [[package]] 1916 | name = "waker-fn" 1917 | version = "1.2.0" 1918 | source = "registry+https://github.com/rust-lang/crates.io-index" 1919 | checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" 1920 | 1921 | [[package]] 1922 | name = "wasi" 1923 | version = "0.11.0+wasi-snapshot-preview1" 1924 | source = "registry+https://github.com/rust-lang/crates.io-index" 1925 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1926 | 1927 | [[package]] 1928 | name = "wasm-bindgen" 1929 | version = "0.2.95" 1930 | source = "registry+https://github.com/rust-lang/crates.io-index" 1931 | checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" 1932 | dependencies = [ 1933 | "cfg-if 1.0.0", 1934 | "once_cell", 1935 | "wasm-bindgen-macro", 1936 | ] 1937 | 1938 | [[package]] 1939 | name = "wasm-bindgen-backend" 1940 | version = "0.2.95" 1941 | source = "registry+https://github.com/rust-lang/crates.io-index" 1942 | checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" 1943 | dependencies = [ 1944 | "bumpalo", 1945 | "log", 1946 | "once_cell", 1947 | "proc-macro2", 1948 | "quote", 1949 | "syn 2.0.79", 1950 | "wasm-bindgen-shared", 1951 | ] 1952 | 1953 | [[package]] 1954 | name = "wasm-bindgen-macro" 1955 | version = "0.2.95" 1956 | source = "registry+https://github.com/rust-lang/crates.io-index" 1957 | checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" 1958 | dependencies = [ 1959 | "quote", 1960 | "wasm-bindgen-macro-support", 1961 | ] 1962 | 1963 | [[package]] 1964 | name = "wasm-bindgen-macro-support" 1965 | version = "0.2.95" 1966 | source = "registry+https://github.com/rust-lang/crates.io-index" 1967 | checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" 1968 | dependencies = [ 1969 | "proc-macro2", 1970 | "quote", 1971 | "syn 2.0.79", 1972 | "wasm-bindgen-backend", 1973 | "wasm-bindgen-shared", 1974 | ] 1975 | 1976 | [[package]] 1977 | name = "wasm-bindgen-shared" 1978 | version = "0.2.95" 1979 | source = "registry+https://github.com/rust-lang/crates.io-index" 1980 | checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" 1981 | 1982 | [[package]] 1983 | name = "wayland-backend" 1984 | version = "0.3.7" 1985 | source = "registry+https://github.com/rust-lang/crates.io-index" 1986 | checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6" 1987 | dependencies = [ 1988 | "cc", 1989 | "downcast-rs", 1990 | "rustix 0.38.37", 1991 | "scoped-tls", 1992 | "smallvec", 1993 | "wayland-sys", 1994 | ] 1995 | 1996 | [[package]] 1997 | name = "wayland-client" 1998 | version = "0.31.7" 1999 | source = "registry+https://github.com/rust-lang/crates.io-index" 2000 | checksum = "b66249d3fc69f76fd74c82cc319300faa554e9d865dab1f7cd66cc20db10b280" 2001 | dependencies = [ 2002 | "bitflags 2.6.0", 2003 | "log", 2004 | "rustix 0.38.37", 2005 | "wayland-backend", 2006 | "wayland-scanner", 2007 | ] 2008 | 2009 | [[package]] 2010 | name = "wayland-protocols" 2011 | version = "0.32.5" 2012 | source = "registry+https://github.com/rust-lang/crates.io-index" 2013 | checksum = "7cd0ade57c4e6e9a8952741325c30bf82f4246885dca8bf561898b86d0c1f58e" 2014 | dependencies = [ 2015 | "bitflags 2.6.0", 2016 | "wayland-backend", 2017 | "wayland-client", 2018 | "wayland-scanner", 2019 | ] 2020 | 2021 | [[package]] 2022 | name = "wayland-protocols-wlr" 2023 | version = "0.3.5" 2024 | source = "registry+https://github.com/rust-lang/crates.io-index" 2025 | checksum = "782e12f6cd923c3c316130d56205ebab53f55d6666b7faddfad36cecaeeb4022" 2026 | dependencies = [ 2027 | "bitflags 2.6.0", 2028 | "wayland-backend", 2029 | "wayland-client", 2030 | "wayland-protocols", 2031 | "wayland-scanner", 2032 | ] 2033 | 2034 | [[package]] 2035 | name = "wayland-scanner" 2036 | version = "0.31.5" 2037 | source = "registry+https://github.com/rust-lang/crates.io-index" 2038 | checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3" 2039 | dependencies = [ 2040 | "proc-macro2", 2041 | "quick-xml", 2042 | "quote", 2043 | ] 2044 | 2045 | [[package]] 2046 | name = "wayland-sys" 2047 | version = "0.31.5" 2048 | source = "registry+https://github.com/rust-lang/crates.io-index" 2049 | checksum = "efa8ac0d8e8ed3e3b5c9fc92c7881406a268e11555abe36493efabe649a29e09" 2050 | dependencies = [ 2051 | "dlib", 2052 | "log", 2053 | "pkg-config", 2054 | ] 2055 | 2056 | [[package]] 2057 | name = "winapi" 2058 | version = "0.3.9" 2059 | source = "registry+https://github.com/rust-lang/crates.io-index" 2060 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 2061 | dependencies = [ 2062 | "winapi-i686-pc-windows-gnu", 2063 | "winapi-x86_64-pc-windows-gnu", 2064 | ] 2065 | 2066 | [[package]] 2067 | name = "winapi-i686-pc-windows-gnu" 2068 | version = "0.4.0" 2069 | source = "registry+https://github.com/rust-lang/crates.io-index" 2070 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2071 | 2072 | [[package]] 2073 | name = "winapi-util" 2074 | version = "0.1.9" 2075 | source = "registry+https://github.com/rust-lang/crates.io-index" 2076 | checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" 2077 | dependencies = [ 2078 | "windows-sys 0.59.0", 2079 | ] 2080 | 2081 | [[package]] 2082 | name = "winapi-x86_64-pc-windows-gnu" 2083 | version = "0.4.0" 2084 | source = "registry+https://github.com/rust-lang/crates.io-index" 2085 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2086 | 2087 | [[package]] 2088 | name = "windows-core" 2089 | version = "0.52.0" 2090 | source = "registry+https://github.com/rust-lang/crates.io-index" 2091 | checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" 2092 | dependencies = [ 2093 | "windows-targets 0.52.6", 2094 | ] 2095 | 2096 | [[package]] 2097 | name = "windows-sys" 2098 | version = "0.48.0" 2099 | source = "registry+https://github.com/rust-lang/crates.io-index" 2100 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 2101 | dependencies = [ 2102 | "windows-targets 0.48.5", 2103 | ] 2104 | 2105 | [[package]] 2106 | name = "windows-sys" 2107 | version = "0.52.0" 2108 | source = "registry+https://github.com/rust-lang/crates.io-index" 2109 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 2110 | dependencies = [ 2111 | "windows-targets 0.52.6", 2112 | ] 2113 | 2114 | [[package]] 2115 | name = "windows-sys" 2116 | version = "0.59.0" 2117 | source = "registry+https://github.com/rust-lang/crates.io-index" 2118 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 2119 | dependencies = [ 2120 | "windows-targets 0.52.6", 2121 | ] 2122 | 2123 | [[package]] 2124 | name = "windows-targets" 2125 | version = "0.48.5" 2126 | source = "registry+https://github.com/rust-lang/crates.io-index" 2127 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 2128 | dependencies = [ 2129 | "windows_aarch64_gnullvm 0.48.5", 2130 | "windows_aarch64_msvc 0.48.5", 2131 | "windows_i686_gnu 0.48.5", 2132 | "windows_i686_msvc 0.48.5", 2133 | "windows_x86_64_gnu 0.48.5", 2134 | "windows_x86_64_gnullvm 0.48.5", 2135 | "windows_x86_64_msvc 0.48.5", 2136 | ] 2137 | 2138 | [[package]] 2139 | name = "windows-targets" 2140 | version = "0.52.6" 2141 | source = "registry+https://github.com/rust-lang/crates.io-index" 2142 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 2143 | dependencies = [ 2144 | "windows_aarch64_gnullvm 0.52.6", 2145 | "windows_aarch64_msvc 0.52.6", 2146 | "windows_i686_gnu 0.52.6", 2147 | "windows_i686_gnullvm", 2148 | "windows_i686_msvc 0.52.6", 2149 | "windows_x86_64_gnu 0.52.6", 2150 | "windows_x86_64_gnullvm 0.52.6", 2151 | "windows_x86_64_msvc 0.52.6", 2152 | ] 2153 | 2154 | [[package]] 2155 | name = "windows_aarch64_gnullvm" 2156 | version = "0.48.5" 2157 | source = "registry+https://github.com/rust-lang/crates.io-index" 2158 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 2159 | 2160 | [[package]] 2161 | name = "windows_aarch64_gnullvm" 2162 | version = "0.52.6" 2163 | source = "registry+https://github.com/rust-lang/crates.io-index" 2164 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 2165 | 2166 | [[package]] 2167 | name = "windows_aarch64_msvc" 2168 | version = "0.48.5" 2169 | source = "registry+https://github.com/rust-lang/crates.io-index" 2170 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 2171 | 2172 | [[package]] 2173 | name = "windows_aarch64_msvc" 2174 | version = "0.52.6" 2175 | source = "registry+https://github.com/rust-lang/crates.io-index" 2176 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 2177 | 2178 | [[package]] 2179 | name = "windows_i686_gnu" 2180 | version = "0.48.5" 2181 | source = "registry+https://github.com/rust-lang/crates.io-index" 2182 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 2183 | 2184 | [[package]] 2185 | name = "windows_i686_gnu" 2186 | version = "0.52.6" 2187 | source = "registry+https://github.com/rust-lang/crates.io-index" 2188 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 2189 | 2190 | [[package]] 2191 | name = "windows_i686_gnullvm" 2192 | version = "0.52.6" 2193 | source = "registry+https://github.com/rust-lang/crates.io-index" 2194 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 2195 | 2196 | [[package]] 2197 | name = "windows_i686_msvc" 2198 | version = "0.48.5" 2199 | source = "registry+https://github.com/rust-lang/crates.io-index" 2200 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 2201 | 2202 | [[package]] 2203 | name = "windows_i686_msvc" 2204 | version = "0.52.6" 2205 | source = "registry+https://github.com/rust-lang/crates.io-index" 2206 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 2207 | 2208 | [[package]] 2209 | name = "windows_x86_64_gnu" 2210 | version = "0.48.5" 2211 | source = "registry+https://github.com/rust-lang/crates.io-index" 2212 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 2213 | 2214 | [[package]] 2215 | name = "windows_x86_64_gnu" 2216 | version = "0.52.6" 2217 | source = "registry+https://github.com/rust-lang/crates.io-index" 2218 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 2219 | 2220 | [[package]] 2221 | name = "windows_x86_64_gnullvm" 2222 | version = "0.48.5" 2223 | source = "registry+https://github.com/rust-lang/crates.io-index" 2224 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 2225 | 2226 | [[package]] 2227 | name = "windows_x86_64_gnullvm" 2228 | version = "0.52.6" 2229 | source = "registry+https://github.com/rust-lang/crates.io-index" 2230 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 2231 | 2232 | [[package]] 2233 | name = "windows_x86_64_msvc" 2234 | version = "0.48.5" 2235 | source = "registry+https://github.com/rust-lang/crates.io-index" 2236 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 2237 | 2238 | [[package]] 2239 | name = "windows_x86_64_msvc" 2240 | version = "0.52.6" 2241 | source = "registry+https://github.com/rust-lang/crates.io-index" 2242 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 2243 | 2244 | [[package]] 2245 | name = "winnow" 2246 | version = "0.5.40" 2247 | source = "registry+https://github.com/rust-lang/crates.io-index" 2248 | checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" 2249 | dependencies = [ 2250 | "memchr", 2251 | ] 2252 | 2253 | [[package]] 2254 | name = "wyz" 2255 | version = "0.5.1" 2256 | source = "registry+https://github.com/rust-lang/crates.io-index" 2257 | checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" 2258 | dependencies = [ 2259 | "tap", 2260 | ] 2261 | 2262 | [[package]] 2263 | name = "xdg" 2264 | version = "2.5.2" 2265 | source = "registry+https://github.com/rust-lang/crates.io-index" 2266 | checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" 2267 | 2268 | [[package]] 2269 | name = "xdg-home" 2270 | version = "1.3.0" 2271 | source = "registry+https://github.com/rust-lang/crates.io-index" 2272 | checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" 2273 | dependencies = [ 2274 | "libc", 2275 | "windows-sys 0.59.0", 2276 | ] 2277 | 2278 | [[package]] 2279 | name = "zbus" 2280 | version = "3.15.2" 2281 | source = "registry+https://github.com/rust-lang/crates.io-index" 2282 | checksum = "675d170b632a6ad49804c8cf2105d7c31eddd3312555cffd4b740e08e97c25e6" 2283 | dependencies = [ 2284 | "async-broadcast", 2285 | "async-executor", 2286 | "async-fs", 2287 | "async-io 1.13.0", 2288 | "async-lock 2.8.0", 2289 | "async-process", 2290 | "async-recursion", 2291 | "async-task", 2292 | "async-trait", 2293 | "blocking", 2294 | "byteorder", 2295 | "derivative", 2296 | "enumflags2", 2297 | "event-listener 2.5.3", 2298 | "futures-core", 2299 | "futures-sink", 2300 | "futures-util", 2301 | "hex", 2302 | "nix 0.26.4", 2303 | "once_cell", 2304 | "ordered-stream", 2305 | "rand", 2306 | "serde", 2307 | "serde_repr", 2308 | "sha1", 2309 | "static_assertions", 2310 | "tokio", 2311 | "tracing", 2312 | "uds_windows", 2313 | "winapi", 2314 | "xdg-home", 2315 | "zbus_macros", 2316 | "zbus_names", 2317 | "zvariant", 2318 | ] 2319 | 2320 | [[package]] 2321 | name = "zbus_macros" 2322 | version = "3.15.2" 2323 | source = "registry+https://github.com/rust-lang/crates.io-index" 2324 | checksum = "7131497b0f887e8061b430c530240063d33bf9455fa34438f388a245da69e0a5" 2325 | dependencies = [ 2326 | "proc-macro-crate", 2327 | "proc-macro2", 2328 | "quote", 2329 | "regex", 2330 | "syn 1.0.109", 2331 | "zvariant_utils", 2332 | ] 2333 | 2334 | [[package]] 2335 | name = "zbus_names" 2336 | version = "2.6.1" 2337 | source = "registry+https://github.com/rust-lang/crates.io-index" 2338 | checksum = "437d738d3750bed6ca9b8d423ccc7a8eb284f6b1d6d4e225a0e4e6258d864c8d" 2339 | dependencies = [ 2340 | "serde", 2341 | "static_assertions", 2342 | "zvariant", 2343 | ] 2344 | 2345 | [[package]] 2346 | name = "zvariant" 2347 | version = "3.15.2" 2348 | source = "registry+https://github.com/rust-lang/crates.io-index" 2349 | checksum = "4eef2be88ba09b358d3b58aca6e41cd853631d44787f319a1383ca83424fb2db" 2350 | dependencies = [ 2351 | "byteorder", 2352 | "enumflags2", 2353 | "libc", 2354 | "serde", 2355 | "static_assertions", 2356 | "zvariant_derive", 2357 | ] 2358 | 2359 | [[package]] 2360 | name = "zvariant_derive" 2361 | version = "3.15.2" 2362 | source = "registry+https://github.com/rust-lang/crates.io-index" 2363 | checksum = "37c24dc0bed72f5f90d1f8bb5b07228cbf63b3c6e9f82d82559d4bae666e7ed9" 2364 | dependencies = [ 2365 | "proc-macro-crate", 2366 | "proc-macro2", 2367 | "quote", 2368 | "syn 1.0.109", 2369 | "zvariant_utils", 2370 | ] 2371 | 2372 | [[package]] 2373 | name = "zvariant_utils" 2374 | version = "1.0.1" 2375 | source = "registry+https://github.com/rust-lang/crates.io-index" 2376 | checksum = "7234f0d811589db492d16893e3f21e8e2fd282e6d01b0cddee310322062cc200" 2377 | dependencies = [ 2378 | "proc-macro2", 2379 | "quote", 2380 | "syn 1.0.109", 2381 | ] 2382 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sleepwatcher-rs" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | anyhow = "1.0.75" 10 | bytemuck = "1.18.0" 11 | clap = { version = "4.4.8", features = ["derive"] } 12 | env_logger = "0.10.1" 13 | evdev = { version = "0.12.2", features = ["tokio"] } 14 | futures = { version = "0.3.29", features = ["compat"] } 15 | inotify = "0.10.2" 16 | lazy_static = "1.5.0" 17 | log = "0.4.20" 18 | mlua = { version = "0.9.1", features = ["async", "luau", "send"] } 19 | nix = { version = "0.29.0", features = ["fs", "poll", "signal", "time"] } 20 | once_cell = "1.18.0" 21 | parking_lot = "0.12.1" 22 | shmemfdrs2 = "1.0.0" 23 | sysinfo = "0.29.10" 24 | tokio = { version = "1.32.0", features = ["rt", "macros", "process", "rt-multi-thread", "mio", "signal"] } 25 | tokio-timer = "0.2.13" 26 | tokio-udev = "0.9.1" 27 | udev = "0.9.0" 28 | uuid = { version = "1.5.0", features = ["fast-rng", "v4"] } 29 | wayland-client = { version = "0.31.6", features = ["log"] } 30 | wayland-protocols = { version = "0.32.4", features = ["client", "staging", "unstable"] } 31 | wayland-protocols-wlr = { version = "0.3.4", features = ["client"] } 32 | xdg = "2.5.2" 33 | zbus = { version = "3.14.1", features = ["tokio"] } 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wlsleephandler-rs - Wayland SleepHandler 2 | 3 | This is intended as a replacement of sway's idle management daemon. I use it as a tool to understand rust message passing and state management. It aims to have the following goals: 4 | 5 | - automatic setup of xdg config folder 6 | - lua scripting to define idle management with a lua config 7 | - automatic script reloading 8 | - handling of AC and battery based idle timeouts 9 | - screen locking with systemd locking 10 | 11 | I am now using it as a replacement for any ac and battery power daemon, since I can run tasks with it. 12 | 13 | ## Install 14 | 15 | Until packaging is added you can install sleepwatcher using cargo. 16 | 17 | `cargo install --git https://github.com/fishman/sleepwatcher-rs` 18 | 19 | ## Debug 20 | 21 | sleepwatcher-rs uses `env_logger`. You can enable logging by setting the `RUST_LOG` environment variable: 22 | 23 | `RUST_LOG=debug sleepwatcher-rs` 24 | 25 | ## Default config 26 | 27 | The default config is written to `~/.config/sleepwatcher-rs/idle_config.lua` on startup if the folder and file does not exist yet. 28 | 29 | ## Syntax 30 | 31 | Lua is configured to be sandboxed, so no library functions can be used and only functions exposed inside the Rust can be used. 32 | 33 | Important distinction between `Helpers:run` and `Helpers:run_once`. `run_once` will check if a process of that name is already running and won't spawn a new one in that case. This may be useful, when a screen locker can create race conditions if spawned twice. 34 | 35 | Originally I wanted to reload the config whenever the AC adaptor is plugged in and out, but due to the timeout issue described below, you can check for the `on_battery` state in functions. 36 | 37 | ``` lua 38 | Helpers:log("Loading idle_config.lua") 39 | 40 | function LockScreen() 41 | Helpers:log("Locking Screen") 42 | IdleNotifier:run_once("swaylock -f") 43 | end 44 | 45 | function ScreenLockBattery(event) 46 | if event == "idled" and Helpers:on_battery() then 47 | LockScreen() 48 | end 49 | end 50 | 51 | DbusHandler:PrepareSleep("LockScreen") 52 | DbusHandler:LockHandler("LockHandler") 53 | DbusHandler:UnlockHandler("UnlockHandler") 54 | IdleNotifier:get_notification(300, "ScreenLockBattery") 55 | ``` 56 | 57 | `get_notification` creates a Wayland idle timeout handler. It uses the `ext-idle-notify-v1` protocol. It is not (yet) possible to create callback functions, so the function calls are made by specifying the name of the function. 58 | 59 | `PrepareSleep`, `LockScreen`, `UnlockScreen`, are dbus signals from the `org.freedesktop.logind.manager` and `org.freedesktop.logind.session`. 60 | 61 | ## Known issues 62 | 63 | - sleepwatcher-rs should automatically reload the config when `~/.config/sleepwatcher-rs/idle_config.lua` is changed. However, due to an unknown reason the first trigger after reload still follows the old timeout and the next trigger is therefore equal to the rest of the previous timeout+the new timeout setting. 64 | 65 | ## TODOS 66 | 67 | - [ ] build CI 68 | - [ ] AUR package 69 | - [ ] use more idiomatic lua syntax 70 | - [ ] add tests 71 | - [ ] enable callbacks for lua code. it currently complains about lua functions not supporting Send. It's related to the way the user methods are implemented 72 | - [ ] duplicate state information 73 | - [ ] find a way to remove the std::thread::spawn that used within the lua thread to run_once 74 | - [ ] add idle hints 75 | - [ ] improve return and error handling 76 | - [ ] turn wayland_run spawn_blocking into async 77 | -------------------------------------------------------------------------------- /lua_configs/idle_config.lua: -------------------------------------------------------------------------------- 1 | Helpers:log("Loading idle_config.lua") 2 | 3 | function LockScreen() 4 | Helpers:log("Locking Screen") 5 | IdleNotifier:run_once("swaylock") 6 | end 7 | 8 | function LockHandler() 9 | IdleNotifier:run("playerctl -a pause") 10 | IdleNotifier:run("nmcli radio wwan off") 11 | LockScreen() 12 | end 13 | 14 | function UnlockHandler() 15 | DpmsOn() 16 | end 17 | 18 | function DpmsOn() 19 | Helpers:log("Turning screen on") 20 | IdleNotifier:run("swaymsg output '*' dpms on") 21 | -- IdleNotifier:run("hyprctl dispatch dpms on") 22 | end 23 | 24 | function DpmsOff() 25 | Helpers:log("Turning screen off") 26 | IdleNotifier:run("swaymsg output '*' dpms off") 27 | -- IdleNotifier:run("hyprctl dispatch dpms off") 28 | end 29 | 30 | function HybridSleep() 31 | IdleNotifier:run("systemctl suspend") 32 | end 33 | 34 | function ScreenLockBattery(event) 35 | if event == "idled" and Helpers:on_battery() then 36 | LockScreen() 37 | end 38 | end 39 | 40 | function SleepBattery(event) 41 | if event == "idled" and Helpers:on_battery() then 42 | HybridSleep() 43 | end 44 | end 45 | 46 | function SleepAC(event) 47 | if event == "idled" and Helpers:on_battery() then 48 | HybridSleep() 49 | end 50 | end 51 | 52 | function ScreenDpmsBattery(event) 53 | -- Resumed should always be executed 54 | if event == "resumed" then 55 | DpmsOn() 56 | elseif event == "idled" and Helpers:on_battery() then 57 | DpmsOff() 58 | end 59 | end 60 | 61 | function ScreenLockAC(event) 62 | if event == "idled" and not Helpers:on_battery() then 63 | LockScreen() 64 | end 65 | end 66 | 67 | function ScreenDpmsAC(event) 68 | if event == "resumed" then 69 | DpmsOn() 70 | elseif event == "idled" and not Helpers:on_battery() then 71 | DpmsOff() 72 | end 73 | end 74 | 75 | DbusHandler:PrepareSleep("LockHandler") 76 | DbusHandler:LockHandler("LockHandler") 77 | -- DbusHandler:UnlockHandler("UnlockHandler") 78 | IdleNotifier:get_notification(300, "ScreenLockBattery") 79 | IdleNotifier:get_notification(30, "ScreenDpmsBattery") 80 | IdleNotifier:get_notification(600, "SleepBattery") 81 | IdleNotifier:get_notification(600, "ScreenLockAC") 82 | IdleNotifier:get_notification(900, "ScreenDpmsAC") 83 | 84 | Helpers:log("Finished loading idle_config.lua") 85 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | edition = "2021" 2 | # imports_granularity = "Crate" 3 | # group_imports = "One" 4 | -------------------------------------------------------------------------------- /src/color.rs: -------------------------------------------------------------------------------- 1 | /* @piater, @MaxVerevkin 2 | * https://github.com/MaxVerevkin/wl-gammarelay-rs 3 | * Copyright © 2024 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | /// Color parameters 20 | #[derive(Debug, Clone, Copy, PartialEq)] 21 | pub struct Color { 22 | pub temp: u16, 23 | pub gamma: f64, 24 | pub brightness: f64, 25 | pub inverted: bool, 26 | } 27 | 28 | impl Default for Color { 29 | fn default() -> Self { 30 | Self { 31 | temp: 6500, 32 | gamma: 1.0, 33 | brightness: 1.0, 34 | inverted: false, 35 | } 36 | } 37 | } 38 | 39 | impl Color { 40 | /// Returns a color with update temperature, clamping it to [1K, 10K] range, or none if 41 | /// temperature could not be updated. 42 | pub fn with_updated_temp(self, delta: i16) -> Option { 43 | let new_temp = self.temp.saturating_add_signed(delta).clamp(1_000, 10_000); 44 | (new_temp != self.temp).then_some(Self { 45 | temp: new_temp, 46 | ..self 47 | }) 48 | } 49 | } 50 | 51 | fn map_intensity(v: f64, white: f64, color: Color, v_max_gamma: f64) -> u16 { 52 | // A gamma ramp is computed as f(x) = x^γ, for x ∈ [0,1]. 53 | // Multiple gamma adjustments can reasonably be combined as 54 | // f(x) = x^(γ₁γ₂) = (x^γ₁)^γ₂. 55 | // Here, x^γ₁ ≡ (v * white) is the color-temperature-adjusted intensity, 56 | // and γ₂ is the overall gamma correction. 57 | // The factor v_max_gamma adjusts for the fact that generally v ∉ [0,1]: 58 | // (v/v_max)^γ * v_max = v^γ * v_max^(1-γ) 59 | ((v * white).powf(color.gamma) * v_max_gamma) as u16 60 | } 61 | 62 | pub fn colorramp_fill(r: &mut [u16], g: &mut [u16], b: &mut [u16], ramp_size: usize, color: Color) { 63 | let color_i = ((color.temp as usize - 1000) / 100) * 3; 64 | let [white_r, white_g, white_b] = interpolate_color( 65 | (color.temp % 100) as f64 / 100.0, 66 | &BLACKBODY_COLOR[color_i..], 67 | &BLACKBODY_COLOR[(color_i + 3)..], 68 | ); 69 | 70 | let v_max = u16::MAX as f64 * color.brightness; 71 | let v_max_gamma = v_max.powf(1.0 - color.gamma); 72 | let step = v_max / (ramp_size - 1) as f64; 73 | for i in 0..ramp_size { 74 | let v = step * i as f64; 75 | let index = if color.inverted { ramp_size - 1 - i } else { i }; 76 | r[index] = map_intensity(v, white_r, color, v_max_gamma); 77 | g[index] = map_intensity(v, white_g, color, v_max_gamma); 78 | b[index] = map_intensity(v, white_b, color, v_max_gamma); 79 | } 80 | } 81 | 82 | fn interpolate_color(a: f64, c1: &[f64], c2: &[f64]) -> [f64; 3] { 83 | [ 84 | (1.0 - a) * c1[0] + a * c2[0], 85 | (1.0 - a) * c1[1] + a * c2[1], 86 | (1.0 - a) * c1[2] + a * c2[2], 87 | ] 88 | } 89 | 90 | /// [Black body radiation color](https://en.wikipedia.org/wiki/Black-body_radiation) mapped by 91 | /// temperature in the range [1_000,10_100]. 92 | /// 93 | /// Refer to for more info. 94 | const BLACKBODY_COLOR: &[f64] = &[ 95 | 1.00000000, 0.18172716, 0.00000000, 1.00000000, 0.25503671, 0.00000000, 1.00000000, 0.30942099, 96 | 0.00000000, 1.00000000, 0.35357379, 0.00000000, 1.00000000, 0.39091524, 0.00000000, 1.00000000, 97 | 0.42322816, 0.00000000, 1.00000000, 0.45159884, 0.00000000, 1.00000000, 0.47675916, 0.00000000, 98 | 1.00000000, 0.49923747, 0.00000000, 1.00000000, 0.51943421, 0.00000000, 1.00000000, 0.54360078, 99 | 0.08679949, 1.00000000, 0.56618736, 0.14065513, 1.00000000, 0.58734976, 0.18362641, 1.00000000, 100 | 0.60724493, 0.22137978, 1.00000000, 0.62600248, 0.25591950, 1.00000000, 0.64373109, 0.28819679, 101 | 1.00000000, 0.66052319, 0.31873863, 1.00000000, 0.67645822, 0.34786758, 1.00000000, 0.69160518, 102 | 0.37579588, 1.00000000, 0.70602449, 0.40267128, 1.00000000, 0.71976951, 0.42860152, 1.00000000, 103 | 0.73288760, 0.45366838, 1.00000000, 0.74542112, 0.47793608, 1.00000000, 0.75740814, 0.50145662, 104 | 1.00000000, 0.76888303, 0.52427322, 1.00000000, 0.77987699, 0.54642268, 1.00000000, 0.79041843, 105 | 0.56793692, 1.00000000, 0.80053332, 0.58884417, 1.00000000, 0.81024551, 0.60916971, 1.00000000, 106 | 0.81957693, 0.62893653, 1.00000000, 0.82854786, 0.64816570, 1.00000000, 0.83717703, 0.66687674, 107 | 1.00000000, 0.84548188, 0.68508786, 1.00000000, 0.85347859, 0.70281616, 1.00000000, 0.86118227, 108 | 0.72007777, 1.00000000, 0.86860704, 0.73688797, 1.00000000, 0.87576611, 0.75326132, 1.00000000, 109 | 0.88267187, 0.76921169, 1.00000000, 0.88933596, 0.78475236, 1.00000000, 0.89576933, 0.79989606, 110 | 1.00000000, 0.90198230, 0.81465502, 1.00000000, 0.90963069, 0.82838210, 1.00000000, 0.91710889, 111 | 0.84190889, 1.00000000, 0.92441842, 0.85523742, 1.00000000, 0.93156127, 0.86836903, 1.00000000, 112 | 0.93853986, 0.88130458, 1.00000000, 0.94535695, 0.89404470, 1.00000000, 0.95201559, 0.90658983, 113 | 1.00000000, 0.95851906, 0.91894041, 1.00000000, 0.96487079, 0.93109690, 1.00000000, 0.97107439, 114 | 0.94305985, 1.00000000, 0.97713351, 0.95482993, 1.00000000, 0.98305189, 0.96640795, 1.00000000, 115 | 0.98883326, 0.97779486, 1.00000000, 0.99448139, 0.98899179, 1.00000000, 1.00000000, 1.00000000, 116 | 0.98947904, 0.99348723, 1.00000000, 0.97940448, 0.98722715, 1.00000000, 0.96975025, 0.98120637, 117 | 1.00000000, 0.96049223, 0.97541240, 1.00000000, 0.95160805, 0.96983355, 1.00000000, 0.94303638, 118 | 0.96443333, 1.00000000, 0.93480451, 0.95923080, 1.00000000, 0.92689056, 0.95421394, 1.00000000, 119 | 0.91927697, 0.94937330, 1.00000000, 0.91194747, 0.94470005, 1.00000000, 0.90488690, 0.94018594, 120 | 1.00000000, 0.89808115, 0.93582323, 1.00000000, 0.89151710, 0.93160469, 1.00000000, 0.88518247, 121 | 0.92752354, 1.00000000, 0.87906581, 0.92357340, 1.00000000, 0.87315640, 0.91974827, 1.00000000, 122 | 0.86744421, 0.91604254, 1.00000000, 0.86191983, 0.91245088, 1.00000000, 0.85657444, 0.90896831, 123 | 1.00000000, 0.85139976, 0.90559011, 1.00000000, 0.84638799, 0.90231183, 1.00000000, 0.84153180, 124 | 0.89912926, 1.00000000, 0.83682430, 0.89603843, 1.00000000, 0.83225897, 0.89303558, 1.00000000, 125 | 0.82782969, 0.89011714, 1.00000000, 0.82353066, 0.88727974, 1.00000000, 0.81935641, 0.88452017, 126 | 1.00000000, 0.81530175, 0.88183541, 1.00000000, 0.81136180, 0.87922257, 1.00000000, 0.80753191, 127 | 0.87667891, 1.00000000, 0.80380769, 0.87420182, 1.00000000, 0.80018497, 0.87178882, 1.00000000, 128 | 0.79665980, 0.86943756, 1.00000000, 0.79322843, 0.86714579, 1.00000000, 0.78988728, 0.86491137, 129 | 1.00000000, 0.78663296, 0.86273225, 1.00000000, 130 | ]; 131 | -------------------------------------------------------------------------------- /src/config.rs: -------------------------------------------------------------------------------- 1 | pub const APP_NAME: &str = "sleepwatcher-rs"; 2 | pub const CONFIG_FILE_NAME: &str = "idle_config.lua"; 3 | pub const CONFIG_FILE: &str = include_str!("../lua_configs/idle_config.lua"); 4 | pub const TIMEOUT_SEC: u64 = 30; 5 | -------------------------------------------------------------------------------- /src/dbus.rs: -------------------------------------------------------------------------------- 1 | use super::types::Request; 2 | use futures::stream::StreamExt; 3 | use log::{debug, error}; 4 | use tokio::sync::mpsc; 5 | use zbus::dbus_proxy; 6 | 7 | pub async fn upower_watcher(tx: mpsc::Sender) -> anyhow::Result<()> { 8 | let conn = zbus::Connection::system().await?; 9 | let proxy = UPowerInterfaceProxy::new(&conn).await?; 10 | 11 | let state = proxy.on_battery().await?; 12 | let mut power_stream = proxy.receive_on_battery_changed().await; 13 | tx.send(Request::OnBattery(state)).await.unwrap(); 14 | 15 | tokio::spawn(async move { 16 | while let Some(on_battery_changed) = power_stream.next().await { 17 | match on_battery_changed.get().await { 18 | Ok(on_battery) => { 19 | tx.send(Request::OnBattery(on_battery)).await.unwrap(); 20 | } 21 | Err(e) => { 22 | error!("Error, getting on_battery property {}", e) 23 | } 24 | } 25 | } 26 | }); 27 | Ok(()) 28 | } 29 | 30 | #[dbus_proxy( 31 | interface = "org.freedesktop.UPower", 32 | default_service = "org.freedesktop.UPower", 33 | default_path = "/org/freedesktop/UPower" 34 | )] 35 | trait UPowerInterface { 36 | #[dbus_proxy(property)] 37 | fn on_battery(&self) -> zbus::Result; 38 | } 39 | 40 | #[dbus_proxy( 41 | interface = "org.freedesktop.login1.Manager", 42 | default_service = "org.freedesktop.login1", 43 | default_path = "/org/freedesktop/login1" 44 | )] 45 | trait LogindManagerInterface { 46 | #[dbus_proxy(signal)] 47 | fn prepare_for_sleep(&self, start: bool) -> fdo::Result<()>; 48 | } 49 | 50 | #[dbus_proxy( 51 | interface = "org.freedesktop.login1.Session", 52 | default_service = "org.freedesktop.login1", 53 | default_path = "/org/freedesktop/login1" 54 | )] 55 | trait LogindSessionInterface { 56 | #[dbus_proxy(signal)] 57 | fn lock(&self) -> fdo::Result<()>; 58 | #[dbus_proxy(signal)] 59 | fn unlock(&self) -> fdo::Result<()>; 60 | } 61 | 62 | pub async fn logind_watcher(tx: mpsc::Sender) -> anyhow::Result<()> { 63 | let conn = zbus::Connection::system().await?; 64 | let session_proxy = LogindSessionInterfaceProxy::new(&conn).await?; 65 | let manager_proxy = LogindManagerInterfaceProxy::new(&conn).await?; 66 | 67 | tokio::spawn(async move { 68 | let mut lock_stream = session_proxy.receive_lock().await.unwrap(); 69 | let mut unlock_stream = session_proxy.receive_unlock().await.unwrap(); 70 | let mut prepare_sleep_stream = manager_proxy.receive_prepare_for_sleep().await.unwrap(); 71 | 72 | loop { 73 | tokio::select! { 74 | Some(_) = lock_stream.next() => { 75 | debug!("Lock signal received"); 76 | let _ = tx.send(Request::LuaMethod("Lock".to_string())).await; 77 | }, 78 | Some(_) = unlock_stream.next() => { 79 | debug!("Unlock signal received"); 80 | let _ = tx.send(Request::LuaMethod("Unlock".to_string())).await; 81 | }, 82 | Some(signal) = prepare_sleep_stream.next() => { 83 | debug!("Prepare for Sleep signal received"); 84 | match signal.args() { 85 | Ok(args) => { 86 | if *args.start() { 87 | let _ = tx.send(Request::LuaMethod("PrepareSleep".to_string())).await; 88 | } else { 89 | let _ = tx.send(Request::LuaMethod("Wakeup".to_string())).await; 90 | } 91 | } 92 | Err(e) => { 93 | error!("Error getting prepare_for_sleep args: {}", e); 94 | } 95 | } 96 | }, 97 | } 98 | } 99 | }); 100 | Ok(()) 101 | } 102 | -------------------------------------------------------------------------------- /src/joystick_handler.rs: -------------------------------------------------------------------------------- 1 | use evdev::{Device, InputEventKind}; 2 | use log::{debug, info}; 3 | use std::path::Path; 4 | use tokio::sync::mpsc; 5 | 6 | use crate::types::Request; 7 | 8 | #[derive(Debug)] 9 | pub struct JoystickHandler { 10 | syspath: String, 11 | tx: mpsc::Sender, 12 | } 13 | 14 | impl JoystickHandler { 15 | pub fn new(syspath: String, tx: mpsc::Sender) -> Self { 16 | Self { syspath, tx } 17 | } 18 | 19 | pub async fn js_handler(&self) -> anyhow::Result<()> { 20 | let device_path = Path::new("/dev/input").join(&self.syspath); 21 | let device = Device::open(device_path)?; 22 | //let absinfo = device.get_abs_state(); 23 | let mut event_stream = device.into_event_stream()?; 24 | 25 | loop { 26 | tokio::select! { 27 | ev = event_stream.next_event() => { 28 | match ev { 29 | Ok(ev) => { 30 | match ev.kind() { 31 | InputEventKind::Key(_key) => { 32 | //debug!("Key event: {:?}, value: {}", key, ev.value()); 33 | self.tx.send(Request::Inhibit).await.unwrap(); 34 | } 35 | // Ignore axis and synchronization events for now. For Axis events 36 | // it's not currently clear how to get absinfo 37 | InputEventKind::AbsAxis(..) => { 38 | } 39 | InputEventKind::Synchronization(..) => {} 40 | _ => { 41 | debug!("Other event: {:?}", ev); 42 | } 43 | } 44 | } 45 | Err(e) => { 46 | info!("Error reading event: {:?}", e); 47 | break Ok(()); 48 | } 49 | } 50 | } 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | use env_logger::{Builder, Env}; 3 | use inotify::{EventMask, Inotify, WatchMask}; 4 | use log::{debug, error, info}; 5 | use mlua::{AnyUserDataExt, Function, Lua, UserData, UserDataMethods}; 6 | use std::{ 7 | collections::HashMap, 8 | env, 9 | fs::{self, File}, 10 | io::Write, 11 | path::Path, 12 | process::Stdio, 13 | sync::{ 14 | atomic::{AtomicBool, Ordering}, 15 | Arc, Mutex, 16 | }, 17 | time::Duration, 18 | }; 19 | use sysinfo::{ProcessExt, System, SystemExt}; 20 | use tokio::{process::Command, sync::mpsc, task::JoinHandle, time::sleep}; 21 | use uuid::Uuid; 22 | use wayland::NotificationContext; 23 | use wayland_client::{ 24 | backend::ReadEventsGuard, 25 | protocol::{wl_seat, wl_surface::WlSurface}, 26 | Connection, EventQueue, QueueHandle, 27 | }; 28 | use wayland_protocols::{ 29 | ext::idle_notify::v1::client::{ext_idle_notification_v1, ext_idle_notifier_v1}, 30 | wp::idle_inhibit::zv1::client::{ 31 | zwp_idle_inhibit_manager_v1, zwp_idle_inhibitor_v1::ZwpIdleInhibitorV1, 32 | }, 33 | }; 34 | 35 | use crate::types::CallbackListHandle; 36 | use crate::types::LuaHandle; 37 | use crate::types::NotificationListHandle; 38 | 39 | mod color; 40 | mod config; 41 | mod dbus; 42 | mod joystick_handler; 43 | mod sunset; 44 | mod types; 45 | mod udev_handler; 46 | mod utils; 47 | mod wayland; 48 | 49 | use types::{Request, State}; 50 | use udev_handler::UdevHandler; 51 | 52 | lazy_static::lazy_static! { 53 | pub static ref INHIBIT_MANAGER: std::sync::Mutex> = std::sync::Mutex::new(None); 54 | pub static ref SURFACE: std::sync::Mutex> = std::sync::Mutex::new(None); 55 | } 56 | static IS_INHIBITED: AtomicBool = AtomicBool::new(false); 57 | 58 | fn ensure_config_file_exists(filename: &str) -> std::io::Result<()> { 59 | let config_path = utils::xdg_config_path(Some(filename.to_string()))?; 60 | 61 | if !config_path.exists() { 62 | // Write the default settings to the file 63 | let mut file = File::create(&config_path)?; 64 | file.write_all(config::CONFIG_FILE.as_bytes())?; 65 | } 66 | 67 | Ok(()) 68 | } 69 | 70 | #[derive(Debug)] 71 | pub enum FileRequest { 72 | Write, 73 | } 74 | 75 | #[derive(Parser, Debug)] 76 | #[command(author, version, about, long_about = None)] 77 | struct Args { 78 | #[arg(short, long, default_value = config::CONFIG_FILE_NAME)] 79 | config: String, 80 | } 81 | 82 | struct MyLuaFunctions { 83 | wl_seat: Option, 84 | qh: QueueHandle, 85 | idle_notifier: Option, 86 | tx: mpsc::Sender, 87 | notification_list: NotificationListHandle, 88 | tasks: Mutex>>>, 89 | //gamma_control: Option, 90 | } 91 | 92 | #[derive(Clone, Debug)] 93 | struct LuaHelpers { 94 | on_battery: bool, 95 | } 96 | 97 | #[derive(Clone, Debug)] 98 | struct DbusHandler { 99 | handlers: CallbackListHandle, 100 | } 101 | 102 | impl UserData for DbusHandler { 103 | fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) { 104 | methods.add_method("PrepareSleep", |_lua, this, fn_name: String| { 105 | debug!("PrepareSleep callback"); 106 | let mut map = this.handlers.lock().unwrap(); 107 | map.insert("PrepareSleep".to_string(), fn_name); 108 | Ok(()) 109 | }); 110 | methods.add_method("LockHandler", |_lua, this, fn_name: String| { 111 | debug!("LcokHandler callback"); 112 | let mut map = this.handlers.lock().unwrap(); 113 | map.insert("LockHandler".to_string(), fn_name); 114 | Ok(()) 115 | }); 116 | methods.add_method("UnlockHandler", |_lua, this, fn_name: String| { 117 | debug!("UnlockHandler callback"); 118 | let mut map = this.handlers.lock().unwrap(); 119 | map.insert("UnlockHandler".to_string(), fn_name); 120 | Ok(()) 121 | }); 122 | } 123 | } 124 | 125 | impl UserData for LuaHelpers { 126 | // fn add_fields<'lua, F: UserDataFields<'lua, Self>>(fields: &mut F) { 127 | // fields.add_field_method_get("on_battery", |_, this| Ok(this.on_battery)); 128 | // } 129 | 130 | fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) { 131 | methods.add_method("on_battery", |_lua, this, (): ()| Ok(this.on_battery)); 132 | methods.add_method_mut("set_on_battery", |_lua, this, value: bool| { 133 | this.on_battery = value; 134 | Ok(()) 135 | }); 136 | methods.add_method("log", |_lua, _this, message: String| { 137 | info!("{}", message); 138 | Ok(()) 139 | }); 140 | } 141 | } 142 | 143 | impl UserData for MyLuaFunctions { 144 | fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) { 145 | methods.add_method( 146 | "get_notification", 147 | |_lua, this, (timeout, fn_name): (i32, String)| { 148 | let ctx = NotificationContext { 149 | uuid: generate_uuid(), 150 | }; 151 | 152 | debug!( 153 | "get_notification id: {} fn: {} timeout: {} seconds", 154 | ctx.uuid, fn_name, timeout 155 | ); 156 | let notification = this.idle_notifier.as_ref().unwrap().get_idle_notification( 157 | (timeout * 1000).try_into().unwrap(), 158 | this.wl_seat.as_ref().unwrap(), 159 | &this.qh, 160 | ctx.clone(), 161 | ); 162 | 163 | { 164 | let mut map = this.notification_list.lock().unwrap(); 165 | map.insert(ctx.uuid, (fn_name, notification)); 166 | } 167 | 168 | Ok(()) 169 | }, 170 | ); 171 | 172 | async fn run(cmd: String) -> JoinHandle> { 173 | let (cmd, args) = utils::get_args(cmd.clone()); 174 | 175 | tokio::spawn(async move { 176 | match Command::new(&cmd) 177 | .env( 178 | "WAYLAND_DISPLAY", 179 | env::var("WAYLAND_DISPLAY").unwrap_or_default(), 180 | ) 181 | .env( 182 | "DBUS_SESSION_BUS_ADDRESS", 183 | env::var("DBUS_SESSION_BUS_ADDRESS").unwrap_or_default(), 184 | ) 185 | .stdout(Stdio::inherit()) 186 | .stderr(Stdio::inherit()) 187 | .args(args) 188 | .spawn() 189 | { 190 | Ok(mut child) => match child.wait().await { 191 | Ok(status) => { 192 | debug!("Command {} completed with status: {:?}", cmd, status); 193 | Ok(()) 194 | } 195 | Err(e) => { 196 | error!("{} process failed to run: {}", cmd, e); 197 | Err(anyhow::Error::msg(format!("Failed to run command: {}", e))) 198 | } 199 | }, 200 | Err(e) => { 201 | error!("Failed to spawn {} process: {}", cmd, e); 202 | Err(anyhow::Error::msg(format!( 203 | "Failed to spawn process: {}", 204 | e 205 | ))) 206 | } 207 | } 208 | }) 209 | } 210 | 211 | methods.add_async_method("run", |_lua, _this, command: String| async move { 212 | debug!("run function called {}", command.clone()); 213 | let _handle = run(command).await; 214 | Ok(()) 215 | }); 216 | 217 | methods.add_async_method("run_once", |_lua, _this, command: String| async move { 218 | debug!("run_once function called {}", command.clone()); 219 | let s = System::new_all(); 220 | let (cmd_name, _) = utils::get_args(command.clone()); 221 | 222 | // Check if the process is already running 223 | let is_running = s 224 | .processes_by_exact_name(&cmd_name) 225 | .any(|p| p.name() == cmd_name); 226 | 227 | if !is_running { 228 | //let mut tasks = this.tasks.lock(); 229 | //if !tasks.contains_key(&cmd) { 230 | let _handle = run(command.clone()).await; 231 | //tasks.insert(cmd_name, handle); 232 | //} 233 | } 234 | Ok(()) 235 | }); 236 | } 237 | } 238 | 239 | fn generate_uuid() -> uuid::Uuid { 240 | Uuid::new_v4() 241 | } 242 | 243 | async fn _wait_for_wayland_event( 244 | read_guard: ReadEventsGuard, 245 | event_queue: &mut EventQueue, 246 | state: &mut State, 247 | ) { 248 | // to turn synchronous Wayland socket events into async events 249 | // If epoll notified readiness of the Wayland socket, you can now proceed to the read 250 | read_guard.read().unwrap(); 251 | // And now, you must invoke dispatch_pending() to actually process the events 252 | event_queue.dispatch_pending(state).unwrap(); 253 | } 254 | 255 | pub async fn filewatcher_run(config_path: &Path, tx: mpsc::Sender) -> anyhow::Result<()> { 256 | let mut inotify = Inotify::init().expect("Error while initializing inotify instance"); 257 | 258 | debug!("Watching {:?}", config_path); 259 | // Watch for modify and close events. 260 | inotify 261 | .watches() 262 | .add(config_path, WatchMask::MODIFY) 263 | .expect("Failed to add file watch"); 264 | 265 | let mut buffer = [0; 1024]; 266 | 267 | let _spawn_blocking = tokio::task::spawn_blocking(move || loop { 268 | let events = inotify 269 | .read_events_blocking(&mut buffer) 270 | .expect("Failed to read inotify events"); 271 | 272 | debug!("Received events"); 273 | for event in events { 274 | debug!("File modified: {:?}", event.name); 275 | if event.mask.contains(EventMask::MODIFY) && !event.mask.contains(EventMask::ISDIR) { 276 | debug!("File modified: {:?}", event.name); 277 | tx.blocking_send(Request::Reset).unwrap(); 278 | } 279 | } 280 | }); 281 | Ok(()) 282 | } 283 | 284 | fn lua_load_config(lua: &Lua) -> anyhow::Result> { 285 | let args = Args::parse(); 286 | 287 | let config_path = utils::xdg_config_path(Some(args.config))?; 288 | let config = fs::read_to_string(config_path)?; 289 | let result = lua.load(&config).exec(); 290 | match result { 291 | Ok(_) => {} 292 | Err(ref e) => { 293 | error!("Error loading config: {}", e); 294 | } 295 | } 296 | 297 | Ok(result) 298 | } 299 | 300 | pub fn lua_init(state: &mut State) -> anyhow::Result<()> { 301 | let lua = state.lua.lock().unwrap(); 302 | lua.sandbox(true)?; 303 | let my_lua_functions = MyLuaFunctions { 304 | wl_seat: state.wl_seat.clone(), 305 | idle_notifier: state.idle_notifier.clone(), 306 | qh: state.qh.clone(), 307 | notification_list: state.notification_list.clone(), 308 | tx: state.tx.clone(), 309 | tasks: Mutex::new(HashMap::new()), 310 | }; 311 | 312 | let globals = lua.globals(); 313 | globals.set("IdleNotifier", my_lua_functions)?; 314 | globals.set("Helpers", LuaHelpers { on_battery: true })?; 315 | let _ = globals.set( 316 | "DbusHandler", 317 | DbusHandler { 318 | handlers: state.dbus_handlers.clone(), 319 | }, 320 | ); 321 | let _ = lua_load_config(&lua)?; 322 | 323 | Ok(()) 324 | } 325 | 326 | #[derive(Clone)] 327 | pub struct WaylandRunner { 328 | connection: Connection, 329 | qhandle: QueueHandle, 330 | lua: LuaHandle, 331 | tx: mpsc::Sender, 332 | notification_list: NotificationListHandle, 333 | dbus_handlers: CallbackListHandle, 334 | } 335 | 336 | impl WaylandRunner { 337 | pub fn new( 338 | connection: Connection, 339 | qhandle: QueueHandle, 340 | lua: LuaHandle, 341 | tx: mpsc::Sender, 342 | ) -> Self { 343 | let map: HashMap = 344 | HashMap::new(); 345 | 346 | let notification_list = Arc::new(Mutex::new(map)); 347 | let dbus_handlers = Arc::new(Mutex::new(HashMap::new())); 348 | 349 | Self { 350 | connection, 351 | qhandle, 352 | lua, 353 | tx, 354 | notification_list, 355 | dbus_handlers, 356 | } 357 | } 358 | 359 | pub async fn wayland_run( 360 | &self, 361 | mut event_queue: EventQueue, 362 | ) -> anyhow::Result>> { 363 | let display = self.connection.display(); 364 | display.get_registry(&self.qhandle, ()); 365 | 366 | let mut state = State { 367 | wl_seat: None, 368 | idle_notifier: None, 369 | qh: self.qhandle.clone(), 370 | notification_list: self.notification_list.clone(), 371 | dbus_handlers: self.dbus_handlers.clone(), 372 | tx: self.tx.clone(), 373 | lua: self.lua.clone(), 374 | outputs: HashMap::new(), 375 | }; 376 | 377 | Ok(tokio::task::spawn_blocking(move || loop { 378 | event_queue.blocking_dispatch(&mut state)?; 379 | })) 380 | } 381 | 382 | pub async fn process_command(&self, rx: &mut mpsc::Receiver) -> anyhow::Result<()> { 383 | while let Some(event) = rx.recv().await { 384 | match event { 385 | Request::Reset => { 386 | debug!("Reloading config"); 387 | { 388 | let map = self.notification_list.lock().unwrap(); 389 | for (_, (_, notification)) in map.iter() { 390 | notification.destroy(); 391 | } 392 | let _ = self.connection.flush(); 393 | } 394 | self.tx.send(Request::LuaReload).await.unwrap(); 395 | } 396 | Request::LuaReload => { 397 | debug!("Reloading lua config"); 398 | let lua = self.lua.lock().unwrap(); 399 | let _ = lua_load_config(&lua).unwrap(); 400 | } 401 | Request::LuaMethod(method_name) => { 402 | let lua = self.lua.lock().unwrap(); 403 | let globals = lua.globals(); 404 | let map = self.dbus_handlers.lock().unwrap(); 405 | match map.get(&method_name) { 406 | Some(fn_name) => { 407 | let fn_name = fn_name.clone(); 408 | let result: Result = globals.get(fn_name.clone()); 409 | if let Ok(lua_func) = result { 410 | lua_func.call(())?; 411 | } else { 412 | debug!("Lua function not found: {}", fn_name); 413 | } 414 | } 415 | None => { 416 | debug!("No dbus handler found for {}", method_name); 417 | } 418 | } 419 | } 420 | Request::OnBattery(state) => { 421 | let lua = self.lua.lock().unwrap(); 422 | let globals = lua.globals(); 423 | let res: mlua::Result = globals.get("Helpers"); 424 | 425 | match res { 426 | Ok(helpers) => { 427 | let _ = helpers.call_method::<_, bool>("set_on_battery", state); 428 | } 429 | Err(_e) => {} 430 | } 431 | } 432 | Request::Inhibit => { 433 | let _ = self.inhibit_sleep(); 434 | } 435 | Request::Flush => { 436 | let _ = self.connection.flush(); 437 | } 438 | } 439 | } 440 | Ok(()) 441 | } 442 | 443 | fn inhibit_sleep(&self) -> anyhow::Result<()> { 444 | async fn run(connection: Connection, qhandle: QueueHandle) -> anyhow::Result<()> { 445 | // Return early if already inhibited 446 | if IS_INHIBITED.load(Ordering::SeqCst) { 447 | return Ok(()); 448 | } 449 | 450 | debug!("Inhibiting sleep"); 451 | IS_INHIBITED.store(true, Ordering::SeqCst); 452 | 453 | let mut inhibitor: Option = None; 454 | if let Some(manager) = INHIBIT_MANAGER.lock().unwrap().as_ref() { 455 | let surface = SURFACE.lock().unwrap(); 456 | if let Some(surface) = surface.as_ref() { 457 | inhibitor = Some(manager.create_inhibitor(surface, &qhandle.clone(), ())); 458 | let _ = connection.flush(); 459 | } 460 | } 461 | sleep(Duration::from_secs(config::TIMEOUT_SEC)).await; 462 | 463 | if let Some(inhibitor) = inhibitor { 464 | debug!("Destroying inhibitor"); 465 | inhibitor.destroy(); 466 | let _ = connection.flush(); 467 | } 468 | 469 | // Reset inhibited state 470 | IS_INHIBITED.store(false, Ordering::SeqCst); 471 | 472 | Ok(()) 473 | } 474 | let qh = self.qhandle.clone(); 475 | let connection = self.connection.clone(); 476 | tokio::spawn(async move { run(connection, qh).await }); 477 | Ok(()) 478 | } 479 | } 480 | #[tokio::main] 481 | async fn main() -> anyhow::Result<()> { 482 | Builder::from_env(Env::default().default_filter_or("info")).init(); 483 | let _ = ensure_config_file_exists(config::CONFIG_FILE_NAME); 484 | let (tx, mut rx) = mpsc::channel(32); 485 | 486 | let lua = Arc::new(Mutex::new(Lua::new())); 487 | 488 | let config_path = utils::xdg_config_path(None)?; 489 | filewatcher_run(&config_path, tx.clone()) 490 | .await 491 | .expect("Failed to spawn task"); 492 | 493 | let connection = Connection::connect_to_env().unwrap(); 494 | let event_queue: EventQueue = connection.new_event_queue(); 495 | let qhandle = event_queue.handle(); 496 | 497 | let wayland_runner = WaylandRunner::new(connection, qhandle.clone(), lua.clone(), tx.clone()); 498 | let udev_handler = UdevHandler::new(tx.clone()); 499 | 500 | let _ = wayland_runner.wayland_run(event_queue).await; 501 | 502 | tokio::try_join!( 503 | dbus::upower_watcher(tx.clone()), 504 | dbus::logind_watcher(tx.clone()), 505 | wayland_runner.process_command(&mut rx), 506 | udev_handler.monitor() 507 | )?; 508 | 509 | Ok(()) 510 | } 511 | -------------------------------------------------------------------------------- /src/sunset.rs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishman/wlsleephandler-rs/50b4075cada376b07d0d8254a9141cf1dd80d4ee/src/sunset.rs -------------------------------------------------------------------------------- /src/types.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | collections::HashMap, 3 | sync::{Arc, Mutex}, 4 | }; 5 | use tokio::sync::mpsc; 6 | 7 | use mlua::Lua; 8 | use uuid::Uuid; 9 | use wayland_client::{protocol::wl_seat, QueueHandle}; 10 | use wayland_protocols::ext::idle_notify::v1::client::{ 11 | ext_idle_notification_v1, ext_idle_notifier_v1, 12 | }; 13 | 14 | use crate::wayland::Output; 15 | 16 | #[derive(Debug)] 17 | pub enum Request { 18 | LuaReload, 19 | LuaMethod(String), 20 | Reset, 21 | OnBattery(bool), 22 | Flush, 23 | Inhibit, 24 | } 25 | 26 | pub type NotificationListHandle = 27 | Arc>>; 28 | 29 | pub type CallbackListHandle = Arc>>; 30 | pub type LuaHandle = Arc>; 31 | 32 | #[derive(Debug)] 33 | pub struct State { 34 | pub(crate) wl_seat: Option, 35 | pub(crate) qh: QueueHandle, 36 | pub(crate) idle_notifier: Option, 37 | pub(crate) notification_list: NotificationListHandle, 38 | pub(crate) dbus_handlers: CallbackListHandle, 39 | pub(crate) tx: mpsc::Sender, 40 | pub(crate) lua: LuaHandle, 41 | pub(crate) outputs: HashMap, 42 | } 43 | -------------------------------------------------------------------------------- /src/udev_handler.rs: -------------------------------------------------------------------------------- 1 | use log::debug; 2 | use std::collections::HashMap; 3 | use tokio::{ 4 | io::unix::AsyncFd, 5 | sync::{mpsc, Mutex}, 6 | task::JoinHandle, 7 | }; 8 | use udev::{EventType, MonitorBuilder}; 9 | 10 | use crate::joystick_handler::JoystickHandler; 11 | use crate::types::Request; 12 | 13 | pub struct UdevHandler { 14 | joysticks: Mutex>>>, 15 | tx: mpsc::Sender, 16 | } 17 | 18 | impl UdevHandler { 19 | pub fn new(tx: mpsc::Sender) -> Self { 20 | Self { 21 | joysticks: Mutex::new(HashMap::new()), 22 | tx, 23 | } 24 | } 25 | 26 | async fn joystick_add(&self, joystick: udev::Device) -> anyhow::Result<()> { 27 | if let Some(sysname) = self.get_joystick_sysname(joystick) { 28 | debug!("Added joystick {}", sysname.clone()); 29 | let joystick_handler = JoystickHandler::new(sysname.clone(), self.tx.clone()); 30 | let mut joysticks = self.joysticks.lock().await; 31 | joysticks.insert( 32 | sysname.clone(), 33 | tokio::spawn(async move { joystick_handler.js_handler().await }), 34 | ); 35 | } 36 | Ok(()) 37 | } 38 | 39 | async fn joystick_remove(&self, joystick: udev::Device) -> anyhow::Result<()> { 40 | if let Some(sysname) = self.get_joystick_sysname(joystick) { 41 | debug!("Removed joystick {}", sysname.clone()); 42 | let mut joysticks = self.joysticks.lock().await; 43 | let task = joysticks.get(&sysname).unwrap(); 44 | task.abort(); 45 | joysticks.remove(&sysname); 46 | } 47 | Ok(()) 48 | } 49 | 50 | fn _timer_event(&mut self) { 51 | // Handle timer event 52 | //if let Some(ref mut inhibitor) = self.idle_inhibitor { 53 | // inhibitor.destroy(); 54 | // self.idle_inhibitor = None; 55 | // self.wl_display.as_ref().unwrap().flush(); 56 | //} 57 | } 58 | 59 | fn _log_device(&self, event: udev::Device) { 60 | debug!( 61 | "{}: (subsystem={}, sysname={}, devtype={})", 62 | event.sysname().to_str().unwrap_or("---"), 63 | event 64 | .subsystem() 65 | .map_or("", |s| { s.to_str().unwrap_or("") }), 66 | event.sysname().to_str().unwrap_or(""), 67 | event.devtype().map_or("", |s| { s.to_str().unwrap_or("") }) 68 | ); 69 | } 70 | 71 | fn _log_event(&self, event: udev::Event) { 72 | debug!( 73 | "{}: {} {} (subsystem={}, sysname={}, devtype={})", 74 | event.sequence_number(), 75 | event.event_type(), 76 | event.sysname().to_str().unwrap_or("---"), 77 | event 78 | .subsystem() 79 | .map_or("", |s| { s.to_str().unwrap_or("") }), 80 | event.sysname().to_str().unwrap_or(""), 81 | event.devtype().map_or("", |s| { s.to_str().unwrap_or("") }) 82 | ); 83 | } 84 | 85 | fn get_joystick_sysname(&self, device: udev::Device) -> Option { 86 | if device.property_value("ID_INPUT_JOYSTICK").is_some() { 87 | if let Some(sysname) = device.sysname().to_str() { 88 | if sysname.starts_with("event") { 89 | return Some(sysname.to_string()); 90 | } 91 | } 92 | } 93 | None 94 | } 95 | 96 | async fn update_device(&self, event_type: EventType, device: udev::Device) { 97 | match event_type { 98 | EventType::Add => { 99 | let _ = self.joystick_add(device).await; 100 | } 101 | EventType::Remove => { 102 | let _ = self.joystick_remove(device).await; 103 | } 104 | _ => {} 105 | } 106 | } 107 | 108 | async fn iterate_joystick_devices(&self) -> anyhow::Result<()> { 109 | let mut enumerator = udev::Enumerator::new()?; 110 | let _ = enumerator.match_subsystem("input"); 111 | let _ = enumerator.match_property("ID_INPUT_JOYSTICK", "1"); 112 | let _ = enumerator.match_sysname("event*"); 113 | 114 | for device in enumerator.scan_devices()? { 115 | let _ = self.update_device(EventType::Add, device).await; 116 | } 117 | 118 | Ok(()) 119 | } 120 | 121 | pub async fn monitor(&self) -> anyhow::Result<()> { 122 | let socket = MonitorBuilder::new()?.match_subsystem("input")?.listen()?; 123 | 124 | let _ = self.iterate_joystick_devices().await; 125 | let async_socket = AsyncFd::new(socket)?; 126 | 127 | loop { 128 | tokio::select! { 129 | result = async_socket.readable() => { 130 | let mut guard = result?; 131 | 132 | while let Some(event) = async_socket.get_ref().iter().next() { 133 | if let Some(_sysname) = self.get_joystick_sysname(event.clone()) { 134 | self.update_device(event.event_type(), event.device()).await; 135 | } 136 | } 137 | 138 | guard.clear_ready(); 139 | } 140 | } 141 | } 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/utils.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | use xdg::BaseDirectories; 3 | 4 | use super::config; 5 | 6 | pub fn get_args(cmd: String) -> (String, Vec) { 7 | let mut args = cmd.split_whitespace(); 8 | let cmd = args.next().unwrap().to_string(); 9 | let args: Vec = args.map(|s| s.to_string()).collect(); 10 | (cmd, args) 11 | } 12 | 13 | pub fn xdg_config_path(filename: Option) -> std::io::Result { 14 | let xdg_dirs = BaseDirectories::with_prefix(config::APP_NAME)?; 15 | 16 | match filename { 17 | Some(filename) => { 18 | let config_path: PathBuf = xdg_dirs.place_config_file(filename)?; 19 | Ok(config_path) 20 | } 21 | None => Ok(xdg_dirs.get_config_home()), 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/wayland.rs: -------------------------------------------------------------------------------- 1 | use mlua::Function; 2 | 3 | use log::{debug, info}; 4 | use uuid::Uuid; 5 | use wayland_client::{ 6 | protocol::{ 7 | wl_compositor, wl_output, wl_registry, wl_seat, 8 | wl_surface::{self}, 9 | }, 10 | Connection, Dispatch, QueueHandle, 11 | }; 12 | use wayland_protocols::{ 13 | ext::idle_notify::v1::client::{ext_idle_notification_v1, ext_idle_notifier_v1}, 14 | wp::idle_inhibit::zv1::client::{ 15 | zwp_idle_inhibit_manager_v1, 16 | zwp_idle_inhibitor_v1::{self}, 17 | }, 18 | xdg::activation::v1::client::{xdg_activation_token_v1, xdg_activation_v1}, 19 | }; 20 | use wayland_protocols_wlr::gamma_control::v1::client::{ 21 | zwlr_gamma_control_manager_v1, zwlr_gamma_control_v1, 22 | }; 23 | 24 | use crate::{color::Color, lua_init, types::State, INHIBIT_MANAGER, SURFACE}; 25 | 26 | #[derive(Debug)] 27 | pub struct Output { 28 | reg_name: u32, 29 | wl_output: wl_output::WlOutput, 30 | name: Option, 31 | color: Color, 32 | ramp_size: usize, 33 | color_changed: bool, 34 | } 35 | 36 | #[derive(Clone, Debug)] 37 | pub struct NotificationContext { 38 | pub uuid: Uuid, 39 | } 40 | 41 | impl Dispatch for State { 42 | fn event( 43 | _state: &mut Self, 44 | _output: &wl_output::WlOutput, 45 | event: wl_output::Event, 46 | _: &(), 47 | _: &Connection, 48 | _qh: &QueueHandle, 49 | ) { 50 | if let wl_output::Event::Geometry { 51 | x, 52 | y, 53 | physical_width, 54 | physical_height, 55 | subpixel, 56 | make, 57 | model, 58 | transform, 59 | } = event 60 | { 61 | info!( 62 | "Output geometry: x: {}, y: {}, physical_width: {}, physical_height: {}, subpixel: {:?}, make: {}, model: {}, transform: {:?}", 63 | x, y, physical_width, physical_height, subpixel, make, model, transform 64 | ); 65 | } 66 | } 67 | } 68 | 69 | impl Dispatch for State { 70 | fn event( 71 | state: &mut Self, 72 | registry: &wl_registry::WlRegistry, 73 | event: wl_registry::Event, 74 | _: &(), 75 | _: &Connection, 76 | qh: &QueueHandle, 77 | ) { 78 | if let wl_registry::Event::Global { 79 | name, interface, .. 80 | } = event 81 | { 82 | match &interface[..] { 83 | "wl_seat" => { 84 | let wl_seat = registry.bind::(name, 1, qh, ()); 85 | state.wl_seat = Some(wl_seat.clone()); 86 | debug!("wl_seat: {:?}", name); 87 | if state.wl_seat.is_some() && state.idle_notifier.is_some() { 88 | let _ = lua_init(state); 89 | } 90 | } 91 | "ext_idle_notifier_v1" => { 92 | let idle_notifier = registry 93 | .bind::(name, 1, qh, ()); 94 | 95 | debug!("ext_idle_notifier_v1: {:?}", name); 96 | state.idle_notifier = Some(idle_notifier); 97 | if state.wl_seat.is_some() && state.idle_notifier.is_some() { 98 | let _ = lua_init(state); 99 | } 100 | } 101 | "xdg_activation_v1" => { 102 | let _activation = 103 | registry.bind::(name, 1, qh, ()); 104 | info!("xdg_activation_v1: {:?}", name); 105 | } 106 | "xdg_activation_token_v1" => { 107 | let _activation = registry 108 | .bind::( 109 | name, 110 | 1, 111 | qh, 112 | (), 113 | ); 114 | info!("xdg_activation_token_v1: {:?}", name); 115 | } 116 | // Idle inhibitor is used to handle sleep events for joystick input 117 | "zwp_idle_inhibitor_v1" => { 118 | let _inhibitor = registry 119 | .bind::(name, 1, qh, ()); 120 | info!("zwp_idle_inhibitor_v1: {:?}", name); 121 | } 122 | "zwp_idle_inhibit_manager_v1" => { 123 | let inhibit_manager = registry 124 | .bind::( 125 | name, 126 | 1, 127 | qh, 128 | (), 129 | ); 130 | 131 | *INHIBIT_MANAGER.lock().unwrap() = Some(inhibit_manager); 132 | 133 | info!("zwp_idle_inhibit_manager_v1: {:?}", name); 134 | } 135 | "zwlr_gamma_control_v1" => { 136 | let _gamma_control = registry 137 | .bind::(name, 1, qh, ()); 138 | info!("zwlr_gamma_control_v1: {:?}", name); 139 | //state.gamma_control = Some(_gamma_control); 140 | } 141 | "zwlr_gamma_control_manager_v1" => { 142 | let _gamma_control_manager = 143 | registry 144 | .bind::( 145 | name, 146 | 1, 147 | qh, 148 | (), 149 | ); 150 | info!("zwlr_gamma_control_manager_v1: {:?}", name); 151 | } 152 | "wl_compositor" => { 153 | let compositor = 154 | registry.bind::(name, 1, qh, ()); 155 | info!("wl_compositor: {:?}", name); 156 | 157 | let surface = compositor.create_surface(qh, ()); 158 | *SURFACE.lock().unwrap() = Some(surface); 159 | } 160 | "wl_output" => { 161 | let wl_output = registry.bind::(name, 1, qh, ()); 162 | let output = Output { 163 | reg_name: name, 164 | wl_output, 165 | name: None, 166 | color: Color::default(), 167 | ramp_size: 0, 168 | color_changed: false, 169 | }; 170 | state.outputs.insert(name, output); 171 | info!("wl_output: {:?}", name); 172 | } 173 | _ => {} 174 | } 175 | } 176 | } 177 | } 178 | 179 | impl Dispatch for State { 180 | fn event( 181 | _: &mut Self, 182 | _: &wl_seat::WlSeat, 183 | _: wl_seat::Event, 184 | _: &(), 185 | _: &Connection, 186 | _qh: &QueueHandle, 187 | ) { 188 | } 189 | } 190 | 191 | impl Dispatch for State { 192 | fn event( 193 | _: &mut Self, 194 | _: &zwp_idle_inhibitor_v1::ZwpIdleInhibitorV1, 195 | _event: zwp_idle_inhibitor_v1::Event, 196 | _: &(), 197 | _: &Connection, 198 | _qh: &QueueHandle, 199 | ) { 200 | info!("Idle inhibitor event: {:?}", _event) 201 | } 202 | } 203 | 204 | impl Dispatch for State { 205 | fn event( 206 | _: &mut Self, 207 | _: &zwp_idle_inhibit_manager_v1::ZwpIdleInhibitManagerV1, 208 | _event: zwp_idle_inhibit_manager_v1::Event, 209 | _: &(), 210 | _: &Connection, 211 | _qh: &QueueHandle, 212 | ) { 213 | info!("Idle Inhibit Manager event: {:?}", _event); 214 | } 215 | } 216 | 217 | impl Dispatch for State { 218 | fn event( 219 | _: &mut Self, 220 | _: &zwlr_gamma_control_v1::ZwlrGammaControlV1, 221 | _event: zwlr_gamma_control_v1::Event, 222 | _: &(), 223 | _: &Connection, 224 | _qh: &QueueHandle, 225 | ) { 226 | info!("Gamma Control: {:?}", _event); 227 | } 228 | } 229 | 230 | impl Dispatch for State { 231 | fn event( 232 | _: &mut Self, 233 | manager: &zwlr_gamma_control_manager_v1::ZwlrGammaControlManagerV1, 234 | _event: zwlr_gamma_control_manager_v1::Event, 235 | _: &(), 236 | _: &Connection, 237 | _qh: &QueueHandle, 238 | ) { 239 | info!("Gamma Control: {:?} {:?}", manager, _event); 240 | } 241 | } 242 | 243 | impl Dispatch for State { 244 | fn event( 245 | _: &mut Self, 246 | _: &xdg_activation_v1::XdgActivationV1, 247 | _: xdg_activation_v1::Event, 248 | _: &(), 249 | _: &Connection, 250 | _qh: &QueueHandle, 251 | ) { 252 | info!("XdgActivation event"); 253 | } 254 | } 255 | 256 | impl Dispatch for State { 257 | fn event( 258 | _: &mut Self, 259 | _: &xdg_activation_token_v1::XdgActivationTokenV1, 260 | _: xdg_activation_token_v1::Event, 261 | _: &(), 262 | _: &Connection, 263 | _qh: &QueueHandle, 264 | ) { 265 | info!("XdgActivation event"); 266 | } 267 | } 268 | impl Dispatch for State { 269 | fn event( 270 | _state: &mut Self, 271 | _idle_notifier: &ext_idle_notifier_v1::ExtIdleNotifierV1, 272 | _event: ext_idle_notifier_v1::Event, 273 | _: &(), 274 | _: &Connection, 275 | _qh: &QueueHandle, 276 | ) { 277 | } 278 | } 279 | 280 | impl Dispatch for State { 281 | fn event( 282 | state: &mut Self, 283 | _idle_notification: &ext_idle_notification_v1::ExtIdleNotificationV1, 284 | event: ext_idle_notification_v1::Event, 285 | ctx: &NotificationContext, 286 | _: &Connection, 287 | _qh: &QueueHandle, 288 | ) { 289 | debug!("Idle Notification: {:?} {:?}", event, ctx.uuid); 290 | let map = state.notification_list.lock().unwrap(); 291 | let binding = state.lua.lock().unwrap(); 292 | let globals = binding.globals(); 293 | let fn_name = map.get(&ctx.uuid).unwrap().0.clone(); 294 | let handler: Function = globals.get(fn_name).unwrap(); 295 | let _ = handler.call::<_, ()>(match event { 296 | ext_idle_notification_v1::Event::Idled => "idled", 297 | ext_idle_notification_v1::Event::Resumed => "resumed", 298 | _ => "unknown", 299 | }); 300 | } 301 | } 302 | 303 | impl Dispatch for State { 304 | fn event( 305 | _: &mut Self, 306 | _: &wl_compositor::WlCompositor, 307 | _: wl_compositor::Event, 308 | _: &(), 309 | _: &Connection, 310 | _qh: &QueueHandle, 311 | ) { 312 | info!("Compositor event"); 313 | } 314 | } 315 | 316 | impl Dispatch for State { 317 | fn event( 318 | _: &mut Self, 319 | _: &wl_surface::WlSurface, 320 | _: wl_surface::Event, 321 | _: &(), 322 | _: &Connection, 323 | _qh: &QueueHandle, 324 | ) { 325 | info!("Surface event"); 326 | } 327 | } 328 | --------------------------------------------------------------------------------