├── .gitignore ├── .rustfmt.toml ├── Cargo.lock ├── Cargo.toml ├── Justfile ├── LICENSE.md ├── data ├── cosmic-mimeapps.list ├── cosmic-session.target ├── cosmic.desktop ├── dconf │ └── profile │ │ └── cosmic └── start-cosmic ├── debian ├── changelog ├── control ├── copyright ├── cosmic-session.gsettings-override ├── rules └── source │ └── format ├── flake.lock ├── flake.nix └── src ├── a11y.rs ├── comp.rs ├── main.rs ├── notifications.rs ├── process.rs ├── service.rs └── systemd.rs /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | # These are backup files generated by rustfmt 6 | **/*.rs.bk 7 | 8 | # Added by cargo 9 | /target 10 | 11 | # Added by Nix 12 | /result 13 | 14 | # Debian packaging stuff 15 | .cargo 16 | vendor/ 17 | vendor.tar 18 | *.xz 19 | *.deb 20 | *.ddeb 21 | *.dsc 22 | *.changes 23 | *.deb.tar.* 24 | *.buildinfo 25 | *.build 26 | debian/* 27 | !debian/*install 28 | !debian/*postinst 29 | !debian/*gsettings-override 30 | !debian/changelog 31 | !debian/control 32 | !debian/links 33 | !debian/rules 34 | !debian/source 35 | -------------------------------------------------------------------------------- /.rustfmt.toml: -------------------------------------------------------------------------------- 1 | edition = "2021" 2 | hard_tabs = true 3 | merge_derives = true 4 | newline_style = "Unix" 5 | remove_nested_parens = true 6 | reorder_imports = true 7 | reorder_modules = true 8 | use_field_init_shorthand = true 9 | # Unstable formatting options below; remove if you REALLY don't wanna use `cargo +nightly fmt` 10 | unstable_features = true 11 | format_code_in_doc_comments = true 12 | format_macro_bodies = true 13 | format_strings = true 14 | imports_indent = "Block" 15 | imports_granularity = "Crate" 16 | normalize_comments = true 17 | overflow_delimited_expr = true 18 | reorder_impl_items = true 19 | wrap_comments = true 20 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 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 = "ahash" 22 | version = "0.8.11" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" 25 | dependencies = [ 26 | "cfg-if", 27 | "once_cell", 28 | "version_check", 29 | "zerocopy", 30 | ] 31 | 32 | [[package]] 33 | name = "aho-corasick" 34 | version = "1.1.3" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 37 | dependencies = [ 38 | "memchr", 39 | ] 40 | 41 | [[package]] 42 | name = "allocator-api2" 43 | version = "0.2.21" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" 46 | 47 | [[package]] 48 | name = "async-broadcast" 49 | version = "0.7.1" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e" 52 | dependencies = [ 53 | "event-listener", 54 | "event-listener-strategy", 55 | "futures-core", 56 | "pin-project-lite", 57 | ] 58 | 59 | [[package]] 60 | name = "async-channel" 61 | version = "2.3.1" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" 64 | dependencies = [ 65 | "concurrent-queue", 66 | "event-listener-strategy", 67 | "futures-core", 68 | "pin-project-lite", 69 | ] 70 | 71 | [[package]] 72 | name = "async-executor" 73 | version = "1.13.1" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" 76 | dependencies = [ 77 | "async-task", 78 | "concurrent-queue", 79 | "fastrand", 80 | "futures-lite", 81 | "slab", 82 | ] 83 | 84 | [[package]] 85 | name = "async-fs" 86 | version = "2.1.2" 87 | source = "registry+https://github.com/rust-lang/crates.io-index" 88 | checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" 89 | dependencies = [ 90 | "async-lock", 91 | "blocking", 92 | "futures-lite", 93 | ] 94 | 95 | [[package]] 96 | name = "async-io" 97 | version = "2.4.0" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" 100 | dependencies = [ 101 | "async-lock", 102 | "cfg-if", 103 | "concurrent-queue", 104 | "futures-io", 105 | "futures-lite", 106 | "parking", 107 | "polling", 108 | "rustix", 109 | "slab", 110 | "tracing", 111 | "windows-sys 0.59.0", 112 | ] 113 | 114 | [[package]] 115 | name = "async-lock" 116 | version = "3.4.0" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" 119 | dependencies = [ 120 | "event-listener", 121 | "event-listener-strategy", 122 | "pin-project-lite", 123 | ] 124 | 125 | [[package]] 126 | name = "async-process" 127 | version = "2.3.0" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" 130 | dependencies = [ 131 | "async-channel", 132 | "async-io", 133 | "async-lock", 134 | "async-signal", 135 | "async-task", 136 | "blocking", 137 | "cfg-if", 138 | "event-listener", 139 | "futures-lite", 140 | "rustix", 141 | "tracing", 142 | ] 143 | 144 | [[package]] 145 | name = "async-recursion" 146 | version = "1.1.1" 147 | source = "registry+https://github.com/rust-lang/crates.io-index" 148 | checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" 149 | dependencies = [ 150 | "proc-macro2", 151 | "quote", 152 | "syn", 153 | ] 154 | 155 | [[package]] 156 | name = "async-signal" 157 | version = "0.2.10" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" 160 | dependencies = [ 161 | "async-io", 162 | "async-lock", 163 | "atomic-waker", 164 | "cfg-if", 165 | "futures-core", 166 | "futures-io", 167 | "rustix", 168 | "signal-hook-registry", 169 | "slab", 170 | "windows-sys 0.59.0", 171 | ] 172 | 173 | [[package]] 174 | name = "async-signals" 175 | version = "0.5.0" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "6510007266ba49eb87a49dd78b1319959a88be851442c94f3d838f6a25d0c038" 178 | dependencies = [ 179 | "crossbeam-queue", 180 | "crossbeam-skiplist", 181 | "futures-util", 182 | "nix 0.29.0", 183 | "once_cell", 184 | ] 185 | 186 | [[package]] 187 | name = "async-task" 188 | version = "4.7.1" 189 | source = "registry+https://github.com/rust-lang/crates.io-index" 190 | checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" 191 | 192 | [[package]] 193 | name = "async-trait" 194 | version = "0.1.83" 195 | source = "registry+https://github.com/rust-lang/crates.io-index" 196 | checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" 197 | dependencies = [ 198 | "proc-macro2", 199 | "quote", 200 | "syn", 201 | ] 202 | 203 | [[package]] 204 | name = "atomic-waker" 205 | version = "1.1.2" 206 | source = "registry+https://github.com/rust-lang/crates.io-index" 207 | checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 208 | 209 | [[package]] 210 | name = "autocfg" 211 | version = "1.4.0" 212 | source = "registry+https://github.com/rust-lang/crates.io-index" 213 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 214 | 215 | [[package]] 216 | name = "backtrace" 217 | version = "0.3.71" 218 | source = "registry+https://github.com/rust-lang/crates.io-index" 219 | checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" 220 | dependencies = [ 221 | "addr2line", 222 | "cc", 223 | "cfg-if", 224 | "libc", 225 | "miniz_oxide", 226 | "object", 227 | "rustc-demangle", 228 | ] 229 | 230 | [[package]] 231 | name = "bitflags" 232 | version = "1.3.2" 233 | source = "registry+https://github.com/rust-lang/crates.io-index" 234 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 235 | 236 | [[package]] 237 | name = "bitflags" 238 | version = "2.6.0" 239 | source = "registry+https://github.com/rust-lang/crates.io-index" 240 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 241 | 242 | [[package]] 243 | name = "block" 244 | version = "0.1.6" 245 | source = "registry+https://github.com/rust-lang/crates.io-index" 246 | checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" 247 | 248 | [[package]] 249 | name = "block-buffer" 250 | version = "0.10.4" 251 | source = "registry+https://github.com/rust-lang/crates.io-index" 252 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 253 | dependencies = [ 254 | "generic-array", 255 | ] 256 | 257 | [[package]] 258 | name = "blocking" 259 | version = "1.6.1" 260 | source = "registry+https://github.com/rust-lang/crates.io-index" 261 | checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" 262 | dependencies = [ 263 | "async-channel", 264 | "async-task", 265 | "futures-io", 266 | "futures-lite", 267 | "piper", 268 | ] 269 | 270 | [[package]] 271 | name = "bumpalo" 272 | version = "3.17.0" 273 | source = "registry+https://github.com/rust-lang/crates.io-index" 274 | checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" 275 | 276 | [[package]] 277 | name = "bytemuck" 278 | version = "1.20.0" 279 | source = "registry+https://github.com/rust-lang/crates.io-index" 280 | checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" 281 | 282 | [[package]] 283 | name = "byteorder" 284 | version = "1.5.0" 285 | source = "registry+https://github.com/rust-lang/crates.io-index" 286 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 287 | 288 | [[package]] 289 | name = "bytes" 290 | version = "1.8.0" 291 | source = "registry+https://github.com/rust-lang/crates.io-index" 292 | checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" 293 | 294 | [[package]] 295 | name = "cached" 296 | version = "0.54.0" 297 | source = "registry+https://github.com/rust-lang/crates.io-index" 298 | checksum = "9718806c4a2fe9e8a56fd736f97b340dd10ed1be8ed733ed50449f351dc33cae" 299 | dependencies = [ 300 | "ahash", 301 | "cached_proc_macro", 302 | "cached_proc_macro_types", 303 | "hashbrown 0.14.5", 304 | "once_cell", 305 | "thiserror 1.0.69", 306 | "web-time", 307 | ] 308 | 309 | [[package]] 310 | name = "cached_proc_macro" 311 | version = "0.23.0" 312 | source = "registry+https://github.com/rust-lang/crates.io-index" 313 | checksum = "2f42a145ed2d10dce2191e1dcf30cfccfea9026660e143662ba5eec4017d5daa" 314 | dependencies = [ 315 | "darling", 316 | "proc-macro2", 317 | "quote", 318 | "syn", 319 | ] 320 | 321 | [[package]] 322 | name = "cached_proc_macro_types" 323 | version = "0.1.1" 324 | source = "registry+https://github.com/rust-lang/crates.io-index" 325 | checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0" 326 | 327 | [[package]] 328 | name = "cc" 329 | version = "1.2.1" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" 332 | dependencies = [ 333 | "shlex", 334 | ] 335 | 336 | [[package]] 337 | name = "cfg-if" 338 | version = "1.0.0" 339 | source = "registry+https://github.com/rust-lang/crates.io-index" 340 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 341 | 342 | [[package]] 343 | name = "cfg_aliases" 344 | version = "0.2.1" 345 | source = "registry+https://github.com/rust-lang/crates.io-index" 346 | checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" 347 | 348 | [[package]] 349 | name = "color-eyre" 350 | version = "0.6.3" 351 | source = "registry+https://github.com/rust-lang/crates.io-index" 352 | checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5" 353 | dependencies = [ 354 | "backtrace", 355 | "color-spantrace", 356 | "eyre", 357 | "indenter", 358 | "once_cell", 359 | "owo-colors", 360 | "tracing-error", 361 | ] 362 | 363 | [[package]] 364 | name = "color-spantrace" 365 | version = "0.2.1" 366 | source = "registry+https://github.com/rust-lang/crates.io-index" 367 | checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" 368 | dependencies = [ 369 | "once_cell", 370 | "owo-colors", 371 | "tracing-core", 372 | "tracing-error", 373 | ] 374 | 375 | [[package]] 376 | name = "concurrent-queue" 377 | version = "2.5.0" 378 | source = "registry+https://github.com/rust-lang/crates.io-index" 379 | checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" 380 | dependencies = [ 381 | "crossbeam-utils", 382 | ] 383 | 384 | [[package]] 385 | name = "cosmic-dbus-a11y" 386 | version = "0.1.0" 387 | source = "git+https://github.com/pop-os/dbus-settings-bindings#62100129240d164e39fff16bda34faad520936de" 388 | dependencies = [ 389 | "zbus", 390 | ] 391 | 392 | [[package]] 393 | name = "cosmic-notifications-util" 394 | version = "0.1.0" 395 | source = "git+https://github.com/pop-os/cosmic-notifications#980b9621332502af4754c837f54e514282581c2f" 396 | dependencies = [ 397 | "bytemuck", 398 | "fast_image_resize", 399 | "serde", 400 | "tracing", 401 | "url", 402 | "zbus", 403 | ] 404 | 405 | [[package]] 406 | name = "cosmic-session" 407 | version = "0.1.0" 408 | dependencies = [ 409 | "async-signals", 410 | "color-eyre", 411 | "cosmic-dbus-a11y", 412 | "cosmic-notifications-util", 413 | "dirs 6.0.0", 414 | "freedesktop-desktop-entry", 415 | "futures-util", 416 | "itertools", 417 | "launch-pad", 418 | "libc", 419 | "log-panics", 420 | "rustix", 421 | "scopeguard", 422 | "sendfd", 423 | "serde", 424 | "serde_json", 425 | "shell-words", 426 | "tokio", 427 | "tokio-util", 428 | "tracing", 429 | "tracing-journald", 430 | "tracing-subscriber", 431 | "zbus", 432 | "zbus_systemd", 433 | ] 434 | 435 | [[package]] 436 | name = "cpufeatures" 437 | version = "0.2.16" 438 | source = "registry+https://github.com/rust-lang/crates.io-index" 439 | checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" 440 | dependencies = [ 441 | "libc", 442 | ] 443 | 444 | [[package]] 445 | name = "crossbeam-epoch" 446 | version = "0.9.18" 447 | source = "registry+https://github.com/rust-lang/crates.io-index" 448 | checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" 449 | dependencies = [ 450 | "crossbeam-utils", 451 | ] 452 | 453 | [[package]] 454 | name = "crossbeam-queue" 455 | version = "0.3.12" 456 | source = "registry+https://github.com/rust-lang/crates.io-index" 457 | checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" 458 | dependencies = [ 459 | "crossbeam-utils", 460 | ] 461 | 462 | [[package]] 463 | name = "crossbeam-skiplist" 464 | version = "0.1.3" 465 | source = "registry+https://github.com/rust-lang/crates.io-index" 466 | checksum = "df29de440c58ca2cc6e587ec3d22347551a32435fbde9d2bff64e78a9ffa151b" 467 | dependencies = [ 468 | "crossbeam-epoch", 469 | "crossbeam-utils", 470 | ] 471 | 472 | [[package]] 473 | name = "crossbeam-utils" 474 | version = "0.8.20" 475 | source = "registry+https://github.com/rust-lang/crates.io-index" 476 | checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" 477 | 478 | [[package]] 479 | name = "crypto-common" 480 | version = "0.1.6" 481 | source = "registry+https://github.com/rust-lang/crates.io-index" 482 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 483 | dependencies = [ 484 | "generic-array", 485 | "typenum", 486 | ] 487 | 488 | [[package]] 489 | name = "darling" 490 | version = "0.20.10" 491 | source = "registry+https://github.com/rust-lang/crates.io-index" 492 | checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" 493 | dependencies = [ 494 | "darling_core", 495 | "darling_macro", 496 | ] 497 | 498 | [[package]] 499 | name = "darling_core" 500 | version = "0.20.10" 501 | source = "registry+https://github.com/rust-lang/crates.io-index" 502 | checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" 503 | dependencies = [ 504 | "fnv", 505 | "ident_case", 506 | "proc-macro2", 507 | "quote", 508 | "strsim", 509 | "syn", 510 | ] 511 | 512 | [[package]] 513 | name = "darling_macro" 514 | version = "0.20.10" 515 | source = "registry+https://github.com/rust-lang/crates.io-index" 516 | checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" 517 | dependencies = [ 518 | "darling_core", 519 | "quote", 520 | "syn", 521 | ] 522 | 523 | [[package]] 524 | name = "digest" 525 | version = "0.10.7" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 528 | dependencies = [ 529 | "block-buffer", 530 | "crypto-common", 531 | ] 532 | 533 | [[package]] 534 | name = "dirs" 535 | version = "5.0.1" 536 | source = "registry+https://github.com/rust-lang/crates.io-index" 537 | checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" 538 | dependencies = [ 539 | "dirs-sys 0.4.1", 540 | ] 541 | 542 | [[package]] 543 | name = "dirs" 544 | version = "6.0.0" 545 | source = "registry+https://github.com/rust-lang/crates.io-index" 546 | checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" 547 | dependencies = [ 548 | "dirs-sys 0.5.0", 549 | ] 550 | 551 | [[package]] 552 | name = "dirs-sys" 553 | version = "0.4.1" 554 | source = "registry+https://github.com/rust-lang/crates.io-index" 555 | checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" 556 | dependencies = [ 557 | "libc", 558 | "option-ext", 559 | "redox_users 0.4.6", 560 | "windows-sys 0.48.0", 561 | ] 562 | 563 | [[package]] 564 | name = "dirs-sys" 565 | version = "0.5.0" 566 | source = "registry+https://github.com/rust-lang/crates.io-index" 567 | checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" 568 | dependencies = [ 569 | "libc", 570 | "option-ext", 571 | "redox_users 0.5.0", 572 | "windows-sys 0.59.0", 573 | ] 574 | 575 | [[package]] 576 | name = "displaydoc" 577 | version = "0.2.5" 578 | source = "registry+https://github.com/rust-lang/crates.io-index" 579 | checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" 580 | dependencies = [ 581 | "proc-macro2", 582 | "quote", 583 | "syn", 584 | ] 585 | 586 | [[package]] 587 | name = "either" 588 | version = "1.13.0" 589 | source = "registry+https://github.com/rust-lang/crates.io-index" 590 | checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" 591 | 592 | [[package]] 593 | name = "endi" 594 | version = "1.1.0" 595 | source = "registry+https://github.com/rust-lang/crates.io-index" 596 | checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" 597 | 598 | [[package]] 599 | name = "enumflags2" 600 | version = "0.7.10" 601 | source = "registry+https://github.com/rust-lang/crates.io-index" 602 | checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" 603 | dependencies = [ 604 | "enumflags2_derive", 605 | "serde", 606 | ] 607 | 608 | [[package]] 609 | name = "enumflags2_derive" 610 | version = "0.7.10" 611 | source = "registry+https://github.com/rust-lang/crates.io-index" 612 | checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" 613 | dependencies = [ 614 | "proc-macro2", 615 | "quote", 616 | "syn", 617 | ] 618 | 619 | [[package]] 620 | name = "equivalent" 621 | version = "1.0.1" 622 | source = "registry+https://github.com/rust-lang/crates.io-index" 623 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 624 | 625 | [[package]] 626 | name = "errno" 627 | version = "0.3.9" 628 | source = "registry+https://github.com/rust-lang/crates.io-index" 629 | checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" 630 | dependencies = [ 631 | "libc", 632 | "windows-sys 0.52.0", 633 | ] 634 | 635 | [[package]] 636 | name = "event-listener" 637 | version = "5.3.1" 638 | source = "registry+https://github.com/rust-lang/crates.io-index" 639 | checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" 640 | dependencies = [ 641 | "concurrent-queue", 642 | "parking", 643 | "pin-project-lite", 644 | ] 645 | 646 | [[package]] 647 | name = "event-listener-strategy" 648 | version = "0.5.2" 649 | source = "registry+https://github.com/rust-lang/crates.io-index" 650 | checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" 651 | dependencies = [ 652 | "event-listener", 653 | "pin-project-lite", 654 | ] 655 | 656 | [[package]] 657 | name = "eyre" 658 | version = "0.6.12" 659 | source = "registry+https://github.com/rust-lang/crates.io-index" 660 | checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" 661 | dependencies = [ 662 | "indenter", 663 | "once_cell", 664 | ] 665 | 666 | [[package]] 667 | name = "fast_image_resize" 668 | version = "2.7.3" 669 | source = "registry+https://github.com/rust-lang/crates.io-index" 670 | checksum = "cc789a40040e11bbe4ba31ca319406805a12fe3f8d71314bbc4bd076602ad55a" 671 | dependencies = [ 672 | "num-traits", 673 | "thiserror 1.0.69", 674 | ] 675 | 676 | [[package]] 677 | name = "fastrand" 678 | version = "2.2.0" 679 | source = "registry+https://github.com/rust-lang/crates.io-index" 680 | checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" 681 | 682 | [[package]] 683 | name = "fnv" 684 | version = "1.0.7" 685 | source = "registry+https://github.com/rust-lang/crates.io-index" 686 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 687 | 688 | [[package]] 689 | name = "form_urlencoded" 690 | version = "1.2.1" 691 | source = "registry+https://github.com/rust-lang/crates.io-index" 692 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 693 | dependencies = [ 694 | "percent-encoding", 695 | ] 696 | 697 | [[package]] 698 | name = "freedesktop-desktop-entry" 699 | version = "0.7.7" 700 | source = "registry+https://github.com/rust-lang/crates.io-index" 701 | checksum = "016f6ee9509f11c985aa402451f4ee900d1fafeb501a4c3d734ebecfc1130e05" 702 | dependencies = [ 703 | "cached", 704 | "dirs 5.0.1", 705 | "gettext-rs", 706 | "log", 707 | "memchr", 708 | "strsim", 709 | "textdistance", 710 | "thiserror 2.0.11", 711 | "xdg", 712 | ] 713 | 714 | [[package]] 715 | name = "futures" 716 | version = "0.3.31" 717 | source = "registry+https://github.com/rust-lang/crates.io-index" 718 | checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" 719 | dependencies = [ 720 | "futures-channel", 721 | "futures-core", 722 | "futures-executor", 723 | "futures-io", 724 | "futures-sink", 725 | "futures-task", 726 | "futures-util", 727 | ] 728 | 729 | [[package]] 730 | name = "futures-channel" 731 | version = "0.3.31" 732 | source = "registry+https://github.com/rust-lang/crates.io-index" 733 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 734 | dependencies = [ 735 | "futures-core", 736 | "futures-sink", 737 | ] 738 | 739 | [[package]] 740 | name = "futures-core" 741 | version = "0.3.31" 742 | source = "registry+https://github.com/rust-lang/crates.io-index" 743 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 744 | 745 | [[package]] 746 | name = "futures-executor" 747 | version = "0.3.31" 748 | source = "registry+https://github.com/rust-lang/crates.io-index" 749 | checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" 750 | dependencies = [ 751 | "futures-core", 752 | "futures-task", 753 | "futures-util", 754 | ] 755 | 756 | [[package]] 757 | name = "futures-io" 758 | version = "0.3.31" 759 | source = "registry+https://github.com/rust-lang/crates.io-index" 760 | checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 761 | 762 | [[package]] 763 | name = "futures-lite" 764 | version = "2.5.0" 765 | source = "registry+https://github.com/rust-lang/crates.io-index" 766 | checksum = "cef40d21ae2c515b51041df9ed313ed21e572df340ea58a922a0aefe7e8891a1" 767 | dependencies = [ 768 | "fastrand", 769 | "futures-core", 770 | "futures-io", 771 | "parking", 772 | "pin-project-lite", 773 | ] 774 | 775 | [[package]] 776 | name = "futures-macro" 777 | version = "0.3.31" 778 | source = "registry+https://github.com/rust-lang/crates.io-index" 779 | checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" 780 | dependencies = [ 781 | "proc-macro2", 782 | "quote", 783 | "syn", 784 | ] 785 | 786 | [[package]] 787 | name = "futures-sink" 788 | version = "0.3.31" 789 | source = "registry+https://github.com/rust-lang/crates.io-index" 790 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 791 | 792 | [[package]] 793 | name = "futures-task" 794 | version = "0.3.31" 795 | source = "registry+https://github.com/rust-lang/crates.io-index" 796 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 797 | 798 | [[package]] 799 | name = "futures-util" 800 | version = "0.3.31" 801 | source = "registry+https://github.com/rust-lang/crates.io-index" 802 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 803 | dependencies = [ 804 | "futures-channel", 805 | "futures-core", 806 | "futures-io", 807 | "futures-macro", 808 | "futures-sink", 809 | "futures-task", 810 | "memchr", 811 | "pin-project-lite", 812 | "pin-utils", 813 | "slab", 814 | ] 815 | 816 | [[package]] 817 | name = "generic-array" 818 | version = "0.14.7" 819 | source = "registry+https://github.com/rust-lang/crates.io-index" 820 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 821 | dependencies = [ 822 | "typenum", 823 | "version_check", 824 | ] 825 | 826 | [[package]] 827 | name = "getrandom" 828 | version = "0.2.15" 829 | source = "registry+https://github.com/rust-lang/crates.io-index" 830 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 831 | dependencies = [ 832 | "cfg-if", 833 | "libc", 834 | "wasi", 835 | ] 836 | 837 | [[package]] 838 | name = "gettext-rs" 839 | version = "0.7.2" 840 | source = "registry+https://github.com/rust-lang/crates.io-index" 841 | checksum = "a44e92f7dc08430aca7ed55de161253a22276dfd69c5526e5c5e95d1f7cf338a" 842 | dependencies = [ 843 | "gettext-sys", 844 | "locale_config", 845 | ] 846 | 847 | [[package]] 848 | name = "gettext-sys" 849 | version = "0.22.5" 850 | source = "registry+https://github.com/rust-lang/crates.io-index" 851 | checksum = "bb45773f5b8945f12aecd04558f545964f943dacda1b1155b3d738f5469ef661" 852 | dependencies = [ 853 | "cc", 854 | "temp-dir", 855 | ] 856 | 857 | [[package]] 858 | name = "gimli" 859 | version = "0.28.1" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" 862 | 863 | [[package]] 864 | name = "hashbrown" 865 | version = "0.14.5" 866 | source = "registry+https://github.com/rust-lang/crates.io-index" 867 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 868 | dependencies = [ 869 | "ahash", 870 | "allocator-api2", 871 | ] 872 | 873 | [[package]] 874 | name = "hashbrown" 875 | version = "0.15.1" 876 | source = "registry+https://github.com/rust-lang/crates.io-index" 877 | checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" 878 | 879 | [[package]] 880 | name = "hermit-abi" 881 | version = "0.3.9" 882 | source = "registry+https://github.com/rust-lang/crates.io-index" 883 | checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" 884 | 885 | [[package]] 886 | name = "hermit-abi" 887 | version = "0.4.0" 888 | source = "registry+https://github.com/rust-lang/crates.io-index" 889 | checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" 890 | 891 | [[package]] 892 | name = "hex" 893 | version = "0.4.3" 894 | source = "registry+https://github.com/rust-lang/crates.io-index" 895 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 896 | 897 | [[package]] 898 | name = "icu_collections" 899 | version = "1.5.0" 900 | source = "registry+https://github.com/rust-lang/crates.io-index" 901 | checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" 902 | dependencies = [ 903 | "displaydoc", 904 | "yoke", 905 | "zerofrom", 906 | "zerovec", 907 | ] 908 | 909 | [[package]] 910 | name = "icu_locid" 911 | version = "1.5.0" 912 | source = "registry+https://github.com/rust-lang/crates.io-index" 913 | checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" 914 | dependencies = [ 915 | "displaydoc", 916 | "litemap", 917 | "tinystr", 918 | "writeable", 919 | "zerovec", 920 | ] 921 | 922 | [[package]] 923 | name = "icu_locid_transform" 924 | version = "1.5.0" 925 | source = "registry+https://github.com/rust-lang/crates.io-index" 926 | checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" 927 | dependencies = [ 928 | "displaydoc", 929 | "icu_locid", 930 | "icu_locid_transform_data", 931 | "icu_provider", 932 | "tinystr", 933 | "zerovec", 934 | ] 935 | 936 | [[package]] 937 | name = "icu_locid_transform_data" 938 | version = "1.5.0" 939 | source = "registry+https://github.com/rust-lang/crates.io-index" 940 | checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" 941 | 942 | [[package]] 943 | name = "icu_normalizer" 944 | version = "1.5.0" 945 | source = "registry+https://github.com/rust-lang/crates.io-index" 946 | checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" 947 | dependencies = [ 948 | "displaydoc", 949 | "icu_collections", 950 | "icu_normalizer_data", 951 | "icu_properties", 952 | "icu_provider", 953 | "smallvec", 954 | "utf16_iter", 955 | "utf8_iter", 956 | "write16", 957 | "zerovec", 958 | ] 959 | 960 | [[package]] 961 | name = "icu_normalizer_data" 962 | version = "1.5.0" 963 | source = "registry+https://github.com/rust-lang/crates.io-index" 964 | checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" 965 | 966 | [[package]] 967 | name = "icu_properties" 968 | version = "1.5.1" 969 | source = "registry+https://github.com/rust-lang/crates.io-index" 970 | checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" 971 | dependencies = [ 972 | "displaydoc", 973 | "icu_collections", 974 | "icu_locid_transform", 975 | "icu_properties_data", 976 | "icu_provider", 977 | "tinystr", 978 | "zerovec", 979 | ] 980 | 981 | [[package]] 982 | name = "icu_properties_data" 983 | version = "1.5.0" 984 | source = "registry+https://github.com/rust-lang/crates.io-index" 985 | checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" 986 | 987 | [[package]] 988 | name = "icu_provider" 989 | version = "1.5.0" 990 | source = "registry+https://github.com/rust-lang/crates.io-index" 991 | checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" 992 | dependencies = [ 993 | "displaydoc", 994 | "icu_locid", 995 | "icu_provider_macros", 996 | "stable_deref_trait", 997 | "tinystr", 998 | "writeable", 999 | "yoke", 1000 | "zerofrom", 1001 | "zerovec", 1002 | ] 1003 | 1004 | [[package]] 1005 | name = "icu_provider_macros" 1006 | version = "1.5.0" 1007 | source = "registry+https://github.com/rust-lang/crates.io-index" 1008 | checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" 1009 | dependencies = [ 1010 | "proc-macro2", 1011 | "quote", 1012 | "syn", 1013 | ] 1014 | 1015 | [[package]] 1016 | name = "ident_case" 1017 | version = "1.0.1" 1018 | source = "registry+https://github.com/rust-lang/crates.io-index" 1019 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 1020 | 1021 | [[package]] 1022 | name = "idna" 1023 | version = "1.0.3" 1024 | source = "registry+https://github.com/rust-lang/crates.io-index" 1025 | checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" 1026 | dependencies = [ 1027 | "idna_adapter", 1028 | "smallvec", 1029 | "utf8_iter", 1030 | ] 1031 | 1032 | [[package]] 1033 | name = "idna_adapter" 1034 | version = "1.2.0" 1035 | source = "registry+https://github.com/rust-lang/crates.io-index" 1036 | checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" 1037 | dependencies = [ 1038 | "icu_normalizer", 1039 | "icu_properties", 1040 | ] 1041 | 1042 | [[package]] 1043 | name = "indenter" 1044 | version = "0.3.3" 1045 | source = "registry+https://github.com/rust-lang/crates.io-index" 1046 | checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" 1047 | 1048 | [[package]] 1049 | name = "indexmap" 1050 | version = "2.6.0" 1051 | source = "registry+https://github.com/rust-lang/crates.io-index" 1052 | checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" 1053 | dependencies = [ 1054 | "equivalent", 1055 | "hashbrown 0.15.1", 1056 | ] 1057 | 1058 | [[package]] 1059 | name = "itertools" 1060 | version = "0.12.1" 1061 | source = "registry+https://github.com/rust-lang/crates.io-index" 1062 | checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" 1063 | dependencies = [ 1064 | "either", 1065 | ] 1066 | 1067 | [[package]] 1068 | name = "itoa" 1069 | version = "1.0.13" 1070 | source = "registry+https://github.com/rust-lang/crates.io-index" 1071 | checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2" 1072 | 1073 | [[package]] 1074 | name = "js-sys" 1075 | version = "0.3.77" 1076 | source = "registry+https://github.com/rust-lang/crates.io-index" 1077 | checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" 1078 | dependencies = [ 1079 | "once_cell", 1080 | "wasm-bindgen", 1081 | ] 1082 | 1083 | [[package]] 1084 | name = "launch-pad" 1085 | version = "0.1.0" 1086 | source = "git+https://github.com/pop-os/launch-pad#adf371cc4bd8705f77df6a0d2879678bf0ef27b4" 1087 | dependencies = [ 1088 | "log", 1089 | "nix 0.26.4", 1090 | "rand", 1091 | "slotmap", 1092 | "sync_wrapper", 1093 | "thiserror 1.0.69", 1094 | "tokio", 1095 | "tokio-util", 1096 | ] 1097 | 1098 | [[package]] 1099 | name = "lazy_static" 1100 | version = "1.5.0" 1101 | source = "registry+https://github.com/rust-lang/crates.io-index" 1102 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 1103 | 1104 | [[package]] 1105 | name = "libc" 1106 | version = "0.2.164" 1107 | source = "registry+https://github.com/rust-lang/crates.io-index" 1108 | checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" 1109 | 1110 | [[package]] 1111 | name = "libredox" 1112 | version = "0.1.3" 1113 | source = "registry+https://github.com/rust-lang/crates.io-index" 1114 | checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" 1115 | dependencies = [ 1116 | "bitflags 2.6.0", 1117 | "libc", 1118 | ] 1119 | 1120 | [[package]] 1121 | name = "linux-raw-sys" 1122 | version = "0.4.14" 1123 | source = "registry+https://github.com/rust-lang/crates.io-index" 1124 | checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" 1125 | 1126 | [[package]] 1127 | name = "litemap" 1128 | version = "0.7.3" 1129 | source = "registry+https://github.com/rust-lang/crates.io-index" 1130 | checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" 1131 | 1132 | [[package]] 1133 | name = "locale_config" 1134 | version = "0.3.0" 1135 | source = "registry+https://github.com/rust-lang/crates.io-index" 1136 | checksum = "08d2c35b16f4483f6c26f0e4e9550717a2f6575bcd6f12a53ff0c490a94a6934" 1137 | dependencies = [ 1138 | "lazy_static", 1139 | "objc", 1140 | "objc-foundation", 1141 | "regex", 1142 | "winapi", 1143 | ] 1144 | 1145 | [[package]] 1146 | name = "lock_api" 1147 | version = "0.4.12" 1148 | source = "registry+https://github.com/rust-lang/crates.io-index" 1149 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 1150 | dependencies = [ 1151 | "autocfg", 1152 | "scopeguard", 1153 | ] 1154 | 1155 | [[package]] 1156 | name = "log" 1157 | version = "0.4.22" 1158 | source = "registry+https://github.com/rust-lang/crates.io-index" 1159 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 1160 | 1161 | [[package]] 1162 | name = "log-panics" 1163 | version = "2.1.0" 1164 | source = "registry+https://github.com/rust-lang/crates.io-index" 1165 | checksum = "68f9dd8546191c1850ecf67d22f5ff00a935b890d0e84713159a55495cc2ac5f" 1166 | dependencies = [ 1167 | "backtrace", 1168 | "log", 1169 | ] 1170 | 1171 | [[package]] 1172 | name = "malloc_buf" 1173 | version = "0.0.6" 1174 | source = "registry+https://github.com/rust-lang/crates.io-index" 1175 | checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" 1176 | dependencies = [ 1177 | "libc", 1178 | ] 1179 | 1180 | [[package]] 1181 | name = "matchers" 1182 | version = "0.1.0" 1183 | source = "registry+https://github.com/rust-lang/crates.io-index" 1184 | checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" 1185 | dependencies = [ 1186 | "regex-automata 0.1.10", 1187 | ] 1188 | 1189 | [[package]] 1190 | name = "memchr" 1191 | version = "2.7.4" 1192 | source = "registry+https://github.com/rust-lang/crates.io-index" 1193 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 1194 | 1195 | [[package]] 1196 | name = "memoffset" 1197 | version = "0.7.1" 1198 | source = "registry+https://github.com/rust-lang/crates.io-index" 1199 | checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" 1200 | dependencies = [ 1201 | "autocfg", 1202 | ] 1203 | 1204 | [[package]] 1205 | name = "memoffset" 1206 | version = "0.9.1" 1207 | source = "registry+https://github.com/rust-lang/crates.io-index" 1208 | checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" 1209 | dependencies = [ 1210 | "autocfg", 1211 | ] 1212 | 1213 | [[package]] 1214 | name = "miniz_oxide" 1215 | version = "0.7.4" 1216 | source = "registry+https://github.com/rust-lang/crates.io-index" 1217 | checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" 1218 | dependencies = [ 1219 | "adler", 1220 | ] 1221 | 1222 | [[package]] 1223 | name = "mio" 1224 | version = "1.0.2" 1225 | source = "registry+https://github.com/rust-lang/crates.io-index" 1226 | checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" 1227 | dependencies = [ 1228 | "hermit-abi 0.3.9", 1229 | "libc", 1230 | "wasi", 1231 | "windows-sys 0.52.0", 1232 | ] 1233 | 1234 | [[package]] 1235 | name = "nix" 1236 | version = "0.26.4" 1237 | source = "registry+https://github.com/rust-lang/crates.io-index" 1238 | checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" 1239 | dependencies = [ 1240 | "bitflags 1.3.2", 1241 | "cfg-if", 1242 | "libc", 1243 | "memoffset 0.7.1", 1244 | "pin-utils", 1245 | ] 1246 | 1247 | [[package]] 1248 | name = "nix" 1249 | version = "0.29.0" 1250 | source = "registry+https://github.com/rust-lang/crates.io-index" 1251 | checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" 1252 | dependencies = [ 1253 | "bitflags 2.6.0", 1254 | "cfg-if", 1255 | "cfg_aliases", 1256 | "libc", 1257 | "memoffset 0.9.1", 1258 | ] 1259 | 1260 | [[package]] 1261 | name = "nu-ansi-term" 1262 | version = "0.46.0" 1263 | source = "registry+https://github.com/rust-lang/crates.io-index" 1264 | checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" 1265 | dependencies = [ 1266 | "overload", 1267 | "winapi", 1268 | ] 1269 | 1270 | [[package]] 1271 | name = "num-traits" 1272 | version = "0.2.19" 1273 | source = "registry+https://github.com/rust-lang/crates.io-index" 1274 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 1275 | dependencies = [ 1276 | "autocfg", 1277 | ] 1278 | 1279 | [[package]] 1280 | name = "objc" 1281 | version = "0.2.7" 1282 | source = "registry+https://github.com/rust-lang/crates.io-index" 1283 | checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" 1284 | dependencies = [ 1285 | "malloc_buf", 1286 | ] 1287 | 1288 | [[package]] 1289 | name = "objc-foundation" 1290 | version = "0.1.1" 1291 | source = "registry+https://github.com/rust-lang/crates.io-index" 1292 | checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" 1293 | dependencies = [ 1294 | "block", 1295 | "objc", 1296 | "objc_id", 1297 | ] 1298 | 1299 | [[package]] 1300 | name = "objc_id" 1301 | version = "0.1.1" 1302 | source = "registry+https://github.com/rust-lang/crates.io-index" 1303 | checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" 1304 | dependencies = [ 1305 | "objc", 1306 | ] 1307 | 1308 | [[package]] 1309 | name = "object" 1310 | version = "0.32.2" 1311 | source = "registry+https://github.com/rust-lang/crates.io-index" 1312 | checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" 1313 | dependencies = [ 1314 | "memchr", 1315 | ] 1316 | 1317 | [[package]] 1318 | name = "once_cell" 1319 | version = "1.20.2" 1320 | source = "registry+https://github.com/rust-lang/crates.io-index" 1321 | checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" 1322 | 1323 | [[package]] 1324 | name = "option-ext" 1325 | version = "0.2.0" 1326 | source = "registry+https://github.com/rust-lang/crates.io-index" 1327 | checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" 1328 | 1329 | [[package]] 1330 | name = "ordered-stream" 1331 | version = "0.2.0" 1332 | source = "registry+https://github.com/rust-lang/crates.io-index" 1333 | checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" 1334 | dependencies = [ 1335 | "futures-core", 1336 | "pin-project-lite", 1337 | ] 1338 | 1339 | [[package]] 1340 | name = "overload" 1341 | version = "0.1.1" 1342 | source = "registry+https://github.com/rust-lang/crates.io-index" 1343 | checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" 1344 | 1345 | [[package]] 1346 | name = "owo-colors" 1347 | version = "3.5.0" 1348 | source = "registry+https://github.com/rust-lang/crates.io-index" 1349 | checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" 1350 | 1351 | [[package]] 1352 | name = "parking" 1353 | version = "2.2.1" 1354 | source = "registry+https://github.com/rust-lang/crates.io-index" 1355 | checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" 1356 | 1357 | [[package]] 1358 | name = "parking_lot" 1359 | version = "0.12.3" 1360 | source = "registry+https://github.com/rust-lang/crates.io-index" 1361 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 1362 | dependencies = [ 1363 | "lock_api", 1364 | "parking_lot_core", 1365 | ] 1366 | 1367 | [[package]] 1368 | name = "parking_lot_core" 1369 | version = "0.9.10" 1370 | source = "registry+https://github.com/rust-lang/crates.io-index" 1371 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 1372 | dependencies = [ 1373 | "cfg-if", 1374 | "libc", 1375 | "redox_syscall", 1376 | "smallvec", 1377 | "windows-targets 0.52.6", 1378 | ] 1379 | 1380 | [[package]] 1381 | name = "percent-encoding" 1382 | version = "2.3.1" 1383 | source = "registry+https://github.com/rust-lang/crates.io-index" 1384 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1385 | 1386 | [[package]] 1387 | name = "pin-project-lite" 1388 | version = "0.2.15" 1389 | source = "registry+https://github.com/rust-lang/crates.io-index" 1390 | checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" 1391 | 1392 | [[package]] 1393 | name = "pin-utils" 1394 | version = "0.1.0" 1395 | source = "registry+https://github.com/rust-lang/crates.io-index" 1396 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1397 | 1398 | [[package]] 1399 | name = "piper" 1400 | version = "0.2.4" 1401 | source = "registry+https://github.com/rust-lang/crates.io-index" 1402 | checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" 1403 | dependencies = [ 1404 | "atomic-waker", 1405 | "fastrand", 1406 | "futures-io", 1407 | ] 1408 | 1409 | [[package]] 1410 | name = "polling" 1411 | version = "3.7.4" 1412 | source = "registry+https://github.com/rust-lang/crates.io-index" 1413 | checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" 1414 | dependencies = [ 1415 | "cfg-if", 1416 | "concurrent-queue", 1417 | "hermit-abi 0.4.0", 1418 | "pin-project-lite", 1419 | "rustix", 1420 | "tracing", 1421 | "windows-sys 0.59.0", 1422 | ] 1423 | 1424 | [[package]] 1425 | name = "ppv-lite86" 1426 | version = "0.2.20" 1427 | source = "registry+https://github.com/rust-lang/crates.io-index" 1428 | checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" 1429 | dependencies = [ 1430 | "zerocopy", 1431 | ] 1432 | 1433 | [[package]] 1434 | name = "proc-macro-crate" 1435 | version = "3.2.0" 1436 | source = "registry+https://github.com/rust-lang/crates.io-index" 1437 | checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" 1438 | dependencies = [ 1439 | "toml_edit", 1440 | ] 1441 | 1442 | [[package]] 1443 | name = "proc-macro2" 1444 | version = "1.0.92" 1445 | source = "registry+https://github.com/rust-lang/crates.io-index" 1446 | checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" 1447 | dependencies = [ 1448 | "unicode-ident", 1449 | ] 1450 | 1451 | [[package]] 1452 | name = "quote" 1453 | version = "1.0.37" 1454 | source = "registry+https://github.com/rust-lang/crates.io-index" 1455 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" 1456 | dependencies = [ 1457 | "proc-macro2", 1458 | ] 1459 | 1460 | [[package]] 1461 | name = "rand" 1462 | version = "0.8.5" 1463 | source = "registry+https://github.com/rust-lang/crates.io-index" 1464 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1465 | dependencies = [ 1466 | "libc", 1467 | "rand_chacha", 1468 | "rand_core", 1469 | ] 1470 | 1471 | [[package]] 1472 | name = "rand_chacha" 1473 | version = "0.3.1" 1474 | source = "registry+https://github.com/rust-lang/crates.io-index" 1475 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1476 | dependencies = [ 1477 | "ppv-lite86", 1478 | "rand_core", 1479 | ] 1480 | 1481 | [[package]] 1482 | name = "rand_core" 1483 | version = "0.6.4" 1484 | source = "registry+https://github.com/rust-lang/crates.io-index" 1485 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1486 | dependencies = [ 1487 | "getrandom", 1488 | ] 1489 | 1490 | [[package]] 1491 | name = "redox_syscall" 1492 | version = "0.5.7" 1493 | source = "registry+https://github.com/rust-lang/crates.io-index" 1494 | checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" 1495 | dependencies = [ 1496 | "bitflags 2.6.0", 1497 | ] 1498 | 1499 | [[package]] 1500 | name = "redox_users" 1501 | version = "0.4.6" 1502 | source = "registry+https://github.com/rust-lang/crates.io-index" 1503 | checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" 1504 | dependencies = [ 1505 | "getrandom", 1506 | "libredox", 1507 | "thiserror 1.0.69", 1508 | ] 1509 | 1510 | [[package]] 1511 | name = "redox_users" 1512 | version = "0.5.0" 1513 | source = "registry+https://github.com/rust-lang/crates.io-index" 1514 | checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" 1515 | dependencies = [ 1516 | "getrandom", 1517 | "libredox", 1518 | "thiserror 2.0.11", 1519 | ] 1520 | 1521 | [[package]] 1522 | name = "regex" 1523 | version = "1.11.1" 1524 | source = "registry+https://github.com/rust-lang/crates.io-index" 1525 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 1526 | dependencies = [ 1527 | "aho-corasick", 1528 | "memchr", 1529 | "regex-automata 0.4.9", 1530 | "regex-syntax 0.8.5", 1531 | ] 1532 | 1533 | [[package]] 1534 | name = "regex-automata" 1535 | version = "0.1.10" 1536 | source = "registry+https://github.com/rust-lang/crates.io-index" 1537 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 1538 | dependencies = [ 1539 | "regex-syntax 0.6.29", 1540 | ] 1541 | 1542 | [[package]] 1543 | name = "regex-automata" 1544 | version = "0.4.9" 1545 | source = "registry+https://github.com/rust-lang/crates.io-index" 1546 | checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 1547 | dependencies = [ 1548 | "aho-corasick", 1549 | "memchr", 1550 | "regex-syntax 0.8.5", 1551 | ] 1552 | 1553 | [[package]] 1554 | name = "regex-syntax" 1555 | version = "0.6.29" 1556 | source = "registry+https://github.com/rust-lang/crates.io-index" 1557 | checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" 1558 | 1559 | [[package]] 1560 | name = "regex-syntax" 1561 | version = "0.8.5" 1562 | source = "registry+https://github.com/rust-lang/crates.io-index" 1563 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 1564 | 1565 | [[package]] 1566 | name = "rustc-demangle" 1567 | version = "0.1.24" 1568 | source = "registry+https://github.com/rust-lang/crates.io-index" 1569 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 1570 | 1571 | [[package]] 1572 | name = "rustix" 1573 | version = "0.38.41" 1574 | source = "registry+https://github.com/rust-lang/crates.io-index" 1575 | checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" 1576 | dependencies = [ 1577 | "bitflags 2.6.0", 1578 | "errno", 1579 | "libc", 1580 | "linux-raw-sys", 1581 | "windows-sys 0.52.0", 1582 | ] 1583 | 1584 | [[package]] 1585 | name = "ryu" 1586 | version = "1.0.18" 1587 | source = "registry+https://github.com/rust-lang/crates.io-index" 1588 | checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" 1589 | 1590 | [[package]] 1591 | name = "scopeguard" 1592 | version = "1.2.0" 1593 | source = "registry+https://github.com/rust-lang/crates.io-index" 1594 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1595 | 1596 | [[package]] 1597 | name = "sendfd" 1598 | version = "0.4.3" 1599 | source = "registry+https://github.com/rust-lang/crates.io-index" 1600 | checksum = "604b71b8fc267e13bb3023a2c901126c8f349393666a6d98ac1ae5729b701798" 1601 | dependencies = [ 1602 | "libc", 1603 | "tokio", 1604 | ] 1605 | 1606 | [[package]] 1607 | name = "serde" 1608 | version = "1.0.215" 1609 | source = "registry+https://github.com/rust-lang/crates.io-index" 1610 | checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" 1611 | dependencies = [ 1612 | "serde_derive", 1613 | ] 1614 | 1615 | [[package]] 1616 | name = "serde_derive" 1617 | version = "1.0.215" 1618 | source = "registry+https://github.com/rust-lang/crates.io-index" 1619 | checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" 1620 | dependencies = [ 1621 | "proc-macro2", 1622 | "quote", 1623 | "syn", 1624 | ] 1625 | 1626 | [[package]] 1627 | name = "serde_json" 1628 | version = "1.0.133" 1629 | source = "registry+https://github.com/rust-lang/crates.io-index" 1630 | checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" 1631 | dependencies = [ 1632 | "itoa", 1633 | "memchr", 1634 | "ryu", 1635 | "serde", 1636 | ] 1637 | 1638 | [[package]] 1639 | name = "serde_repr" 1640 | version = "0.1.19" 1641 | source = "registry+https://github.com/rust-lang/crates.io-index" 1642 | checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" 1643 | dependencies = [ 1644 | "proc-macro2", 1645 | "quote", 1646 | "syn", 1647 | ] 1648 | 1649 | [[package]] 1650 | name = "sha1" 1651 | version = "0.10.6" 1652 | source = "registry+https://github.com/rust-lang/crates.io-index" 1653 | checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" 1654 | dependencies = [ 1655 | "cfg-if", 1656 | "cpufeatures", 1657 | "digest", 1658 | ] 1659 | 1660 | [[package]] 1661 | name = "sharded-slab" 1662 | version = "0.1.7" 1663 | source = "registry+https://github.com/rust-lang/crates.io-index" 1664 | checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" 1665 | dependencies = [ 1666 | "lazy_static", 1667 | ] 1668 | 1669 | [[package]] 1670 | name = "shell-words" 1671 | version = "1.1.0" 1672 | source = "registry+https://github.com/rust-lang/crates.io-index" 1673 | checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" 1674 | 1675 | [[package]] 1676 | name = "shlex" 1677 | version = "1.3.0" 1678 | source = "registry+https://github.com/rust-lang/crates.io-index" 1679 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1680 | 1681 | [[package]] 1682 | name = "signal-hook-registry" 1683 | version = "1.4.2" 1684 | source = "registry+https://github.com/rust-lang/crates.io-index" 1685 | checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" 1686 | dependencies = [ 1687 | "libc", 1688 | ] 1689 | 1690 | [[package]] 1691 | name = "slab" 1692 | version = "0.4.9" 1693 | source = "registry+https://github.com/rust-lang/crates.io-index" 1694 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1695 | dependencies = [ 1696 | "autocfg", 1697 | ] 1698 | 1699 | [[package]] 1700 | name = "slotmap" 1701 | version = "1.0.7" 1702 | source = "registry+https://github.com/rust-lang/crates.io-index" 1703 | checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" 1704 | dependencies = [ 1705 | "version_check", 1706 | ] 1707 | 1708 | [[package]] 1709 | name = "smallvec" 1710 | version = "1.13.2" 1711 | source = "registry+https://github.com/rust-lang/crates.io-index" 1712 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 1713 | 1714 | [[package]] 1715 | name = "socket2" 1716 | version = "0.5.7" 1717 | source = "registry+https://github.com/rust-lang/crates.io-index" 1718 | checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" 1719 | dependencies = [ 1720 | "libc", 1721 | "windows-sys 0.52.0", 1722 | ] 1723 | 1724 | [[package]] 1725 | name = "stable_deref_trait" 1726 | version = "1.2.0" 1727 | source = "registry+https://github.com/rust-lang/crates.io-index" 1728 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 1729 | 1730 | [[package]] 1731 | name = "static_assertions" 1732 | version = "1.1.0" 1733 | source = "registry+https://github.com/rust-lang/crates.io-index" 1734 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 1735 | 1736 | [[package]] 1737 | name = "strsim" 1738 | version = "0.11.1" 1739 | source = "registry+https://github.com/rust-lang/crates.io-index" 1740 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1741 | 1742 | [[package]] 1743 | name = "syn" 1744 | version = "2.0.89" 1745 | source = "registry+https://github.com/rust-lang/crates.io-index" 1746 | checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" 1747 | dependencies = [ 1748 | "proc-macro2", 1749 | "quote", 1750 | "unicode-ident", 1751 | ] 1752 | 1753 | [[package]] 1754 | name = "sync_wrapper" 1755 | version = "1.0.2" 1756 | source = "registry+https://github.com/rust-lang/crates.io-index" 1757 | checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" 1758 | 1759 | [[package]] 1760 | name = "synstructure" 1761 | version = "0.13.1" 1762 | source = "registry+https://github.com/rust-lang/crates.io-index" 1763 | checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" 1764 | dependencies = [ 1765 | "proc-macro2", 1766 | "quote", 1767 | "syn", 1768 | ] 1769 | 1770 | [[package]] 1771 | name = "temp-dir" 1772 | version = "0.1.14" 1773 | source = "registry+https://github.com/rust-lang/crates.io-index" 1774 | checksum = "bc1ee6eef34f12f765cb94725905c6312b6610ab2b0940889cfe58dae7bc3c72" 1775 | 1776 | [[package]] 1777 | name = "tempfile" 1778 | version = "3.14.0" 1779 | source = "registry+https://github.com/rust-lang/crates.io-index" 1780 | checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" 1781 | dependencies = [ 1782 | "cfg-if", 1783 | "fastrand", 1784 | "once_cell", 1785 | "rustix", 1786 | "windows-sys 0.59.0", 1787 | ] 1788 | 1789 | [[package]] 1790 | name = "textdistance" 1791 | version = "1.1.1" 1792 | source = "registry+https://github.com/rust-lang/crates.io-index" 1793 | checksum = "aa672c55ab69f787dbc9126cc387dbe57fdd595f585e4524cf89018fa44ab819" 1794 | 1795 | [[package]] 1796 | name = "thiserror" 1797 | version = "1.0.69" 1798 | source = "registry+https://github.com/rust-lang/crates.io-index" 1799 | checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" 1800 | dependencies = [ 1801 | "thiserror-impl 1.0.69", 1802 | ] 1803 | 1804 | [[package]] 1805 | name = "thiserror" 1806 | version = "2.0.11" 1807 | source = "registry+https://github.com/rust-lang/crates.io-index" 1808 | checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" 1809 | dependencies = [ 1810 | "thiserror-impl 2.0.11", 1811 | ] 1812 | 1813 | [[package]] 1814 | name = "thiserror-impl" 1815 | version = "1.0.69" 1816 | source = "registry+https://github.com/rust-lang/crates.io-index" 1817 | checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" 1818 | dependencies = [ 1819 | "proc-macro2", 1820 | "quote", 1821 | "syn", 1822 | ] 1823 | 1824 | [[package]] 1825 | name = "thiserror-impl" 1826 | version = "2.0.11" 1827 | source = "registry+https://github.com/rust-lang/crates.io-index" 1828 | checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" 1829 | dependencies = [ 1830 | "proc-macro2", 1831 | "quote", 1832 | "syn", 1833 | ] 1834 | 1835 | [[package]] 1836 | name = "thread_local" 1837 | version = "1.1.8" 1838 | source = "registry+https://github.com/rust-lang/crates.io-index" 1839 | checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" 1840 | dependencies = [ 1841 | "cfg-if", 1842 | "once_cell", 1843 | ] 1844 | 1845 | [[package]] 1846 | name = "tinystr" 1847 | version = "0.7.6" 1848 | source = "registry+https://github.com/rust-lang/crates.io-index" 1849 | checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" 1850 | dependencies = [ 1851 | "displaydoc", 1852 | "zerovec", 1853 | ] 1854 | 1855 | [[package]] 1856 | name = "tokio" 1857 | version = "1.41.1" 1858 | source = "registry+https://github.com/rust-lang/crates.io-index" 1859 | checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" 1860 | dependencies = [ 1861 | "backtrace", 1862 | "bytes", 1863 | "libc", 1864 | "mio", 1865 | "parking_lot", 1866 | "pin-project-lite", 1867 | "signal-hook-registry", 1868 | "socket2", 1869 | "tokio-macros", 1870 | "tracing", 1871 | "windows-sys 0.52.0", 1872 | ] 1873 | 1874 | [[package]] 1875 | name = "tokio-macros" 1876 | version = "2.4.0" 1877 | source = "registry+https://github.com/rust-lang/crates.io-index" 1878 | checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" 1879 | dependencies = [ 1880 | "proc-macro2", 1881 | "quote", 1882 | "syn", 1883 | ] 1884 | 1885 | [[package]] 1886 | name = "tokio-util" 1887 | version = "0.7.12" 1888 | source = "registry+https://github.com/rust-lang/crates.io-index" 1889 | checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" 1890 | dependencies = [ 1891 | "bytes", 1892 | "futures-core", 1893 | "futures-sink", 1894 | "pin-project-lite", 1895 | "tokio", 1896 | ] 1897 | 1898 | [[package]] 1899 | name = "toml_datetime" 1900 | version = "0.6.8" 1901 | source = "registry+https://github.com/rust-lang/crates.io-index" 1902 | checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" 1903 | 1904 | [[package]] 1905 | name = "toml_edit" 1906 | version = "0.22.22" 1907 | source = "registry+https://github.com/rust-lang/crates.io-index" 1908 | checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" 1909 | dependencies = [ 1910 | "indexmap", 1911 | "toml_datetime", 1912 | "winnow", 1913 | ] 1914 | 1915 | [[package]] 1916 | name = "tracing" 1917 | version = "0.1.40" 1918 | source = "registry+https://github.com/rust-lang/crates.io-index" 1919 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" 1920 | dependencies = [ 1921 | "pin-project-lite", 1922 | "tracing-attributes", 1923 | "tracing-core", 1924 | ] 1925 | 1926 | [[package]] 1927 | name = "tracing-attributes" 1928 | version = "0.1.27" 1929 | source = "registry+https://github.com/rust-lang/crates.io-index" 1930 | checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" 1931 | dependencies = [ 1932 | "proc-macro2", 1933 | "quote", 1934 | "syn", 1935 | ] 1936 | 1937 | [[package]] 1938 | name = "tracing-core" 1939 | version = "0.1.32" 1940 | source = "registry+https://github.com/rust-lang/crates.io-index" 1941 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" 1942 | dependencies = [ 1943 | "once_cell", 1944 | "valuable", 1945 | ] 1946 | 1947 | [[package]] 1948 | name = "tracing-error" 1949 | version = "0.2.0" 1950 | source = "registry+https://github.com/rust-lang/crates.io-index" 1951 | checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" 1952 | dependencies = [ 1953 | "tracing", 1954 | "tracing-subscriber", 1955 | ] 1956 | 1957 | [[package]] 1958 | name = "tracing-journald" 1959 | version = "0.3.0" 1960 | source = "registry+https://github.com/rust-lang/crates.io-index" 1961 | checksum = "ba316a74e8fc3c3896a850dba2375928a9fa171b085ecddfc7c054d39970f3fd" 1962 | dependencies = [ 1963 | "libc", 1964 | "tracing-core", 1965 | "tracing-subscriber", 1966 | ] 1967 | 1968 | [[package]] 1969 | name = "tracing-log" 1970 | version = "0.2.0" 1971 | source = "registry+https://github.com/rust-lang/crates.io-index" 1972 | checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" 1973 | dependencies = [ 1974 | "log", 1975 | "once_cell", 1976 | "tracing-core", 1977 | ] 1978 | 1979 | [[package]] 1980 | name = "tracing-subscriber" 1981 | version = "0.3.18" 1982 | source = "registry+https://github.com/rust-lang/crates.io-index" 1983 | checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" 1984 | dependencies = [ 1985 | "matchers", 1986 | "nu-ansi-term", 1987 | "once_cell", 1988 | "regex", 1989 | "sharded-slab", 1990 | "smallvec", 1991 | "thread_local", 1992 | "tracing", 1993 | "tracing-core", 1994 | "tracing-log", 1995 | ] 1996 | 1997 | [[package]] 1998 | name = "typenum" 1999 | version = "1.17.0" 2000 | source = "registry+https://github.com/rust-lang/crates.io-index" 2001 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 2002 | 2003 | [[package]] 2004 | name = "uds_windows" 2005 | version = "1.1.0" 2006 | source = "registry+https://github.com/rust-lang/crates.io-index" 2007 | checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" 2008 | dependencies = [ 2009 | "memoffset 0.9.1", 2010 | "tempfile", 2011 | "winapi", 2012 | ] 2013 | 2014 | [[package]] 2015 | name = "unicode-ident" 2016 | version = "1.0.14" 2017 | source = "registry+https://github.com/rust-lang/crates.io-index" 2018 | checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" 2019 | 2020 | [[package]] 2021 | name = "url" 2022 | version = "2.5.3" 2023 | source = "registry+https://github.com/rust-lang/crates.io-index" 2024 | checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" 2025 | dependencies = [ 2026 | "form_urlencoded", 2027 | "idna", 2028 | "percent-encoding", 2029 | ] 2030 | 2031 | [[package]] 2032 | name = "utf16_iter" 2033 | version = "1.0.5" 2034 | source = "registry+https://github.com/rust-lang/crates.io-index" 2035 | checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" 2036 | 2037 | [[package]] 2038 | name = "utf8_iter" 2039 | version = "1.0.4" 2040 | source = "registry+https://github.com/rust-lang/crates.io-index" 2041 | checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" 2042 | 2043 | [[package]] 2044 | name = "valuable" 2045 | version = "0.1.0" 2046 | source = "registry+https://github.com/rust-lang/crates.io-index" 2047 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 2048 | 2049 | [[package]] 2050 | name = "version_check" 2051 | version = "0.9.5" 2052 | source = "registry+https://github.com/rust-lang/crates.io-index" 2053 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 2054 | 2055 | [[package]] 2056 | name = "wasi" 2057 | version = "0.11.0+wasi-snapshot-preview1" 2058 | source = "registry+https://github.com/rust-lang/crates.io-index" 2059 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 2060 | 2061 | [[package]] 2062 | name = "wasm-bindgen" 2063 | version = "0.2.100" 2064 | source = "registry+https://github.com/rust-lang/crates.io-index" 2065 | checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" 2066 | dependencies = [ 2067 | "cfg-if", 2068 | "once_cell", 2069 | "wasm-bindgen-macro", 2070 | ] 2071 | 2072 | [[package]] 2073 | name = "wasm-bindgen-backend" 2074 | version = "0.2.100" 2075 | source = "registry+https://github.com/rust-lang/crates.io-index" 2076 | checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" 2077 | dependencies = [ 2078 | "bumpalo", 2079 | "log", 2080 | "proc-macro2", 2081 | "quote", 2082 | "syn", 2083 | "wasm-bindgen-shared", 2084 | ] 2085 | 2086 | [[package]] 2087 | name = "wasm-bindgen-macro" 2088 | version = "0.2.100" 2089 | source = "registry+https://github.com/rust-lang/crates.io-index" 2090 | checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" 2091 | dependencies = [ 2092 | "quote", 2093 | "wasm-bindgen-macro-support", 2094 | ] 2095 | 2096 | [[package]] 2097 | name = "wasm-bindgen-macro-support" 2098 | version = "0.2.100" 2099 | source = "registry+https://github.com/rust-lang/crates.io-index" 2100 | checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" 2101 | dependencies = [ 2102 | "proc-macro2", 2103 | "quote", 2104 | "syn", 2105 | "wasm-bindgen-backend", 2106 | "wasm-bindgen-shared", 2107 | ] 2108 | 2109 | [[package]] 2110 | name = "wasm-bindgen-shared" 2111 | version = "0.2.100" 2112 | source = "registry+https://github.com/rust-lang/crates.io-index" 2113 | checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" 2114 | dependencies = [ 2115 | "unicode-ident", 2116 | ] 2117 | 2118 | [[package]] 2119 | name = "web-time" 2120 | version = "1.1.0" 2121 | source = "registry+https://github.com/rust-lang/crates.io-index" 2122 | checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" 2123 | dependencies = [ 2124 | "js-sys", 2125 | "wasm-bindgen", 2126 | ] 2127 | 2128 | [[package]] 2129 | name = "winapi" 2130 | version = "0.3.9" 2131 | source = "registry+https://github.com/rust-lang/crates.io-index" 2132 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 2133 | dependencies = [ 2134 | "winapi-i686-pc-windows-gnu", 2135 | "winapi-x86_64-pc-windows-gnu", 2136 | ] 2137 | 2138 | [[package]] 2139 | name = "winapi-i686-pc-windows-gnu" 2140 | version = "0.4.0" 2141 | source = "registry+https://github.com/rust-lang/crates.io-index" 2142 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2143 | 2144 | [[package]] 2145 | name = "winapi-x86_64-pc-windows-gnu" 2146 | version = "0.4.0" 2147 | source = "registry+https://github.com/rust-lang/crates.io-index" 2148 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2149 | 2150 | [[package]] 2151 | name = "windows-sys" 2152 | version = "0.48.0" 2153 | source = "registry+https://github.com/rust-lang/crates.io-index" 2154 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 2155 | dependencies = [ 2156 | "windows-targets 0.48.5", 2157 | ] 2158 | 2159 | [[package]] 2160 | name = "windows-sys" 2161 | version = "0.52.0" 2162 | source = "registry+https://github.com/rust-lang/crates.io-index" 2163 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 2164 | dependencies = [ 2165 | "windows-targets 0.52.6", 2166 | ] 2167 | 2168 | [[package]] 2169 | name = "windows-sys" 2170 | version = "0.59.0" 2171 | source = "registry+https://github.com/rust-lang/crates.io-index" 2172 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 2173 | dependencies = [ 2174 | "windows-targets 0.52.6", 2175 | ] 2176 | 2177 | [[package]] 2178 | name = "windows-targets" 2179 | version = "0.48.5" 2180 | source = "registry+https://github.com/rust-lang/crates.io-index" 2181 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 2182 | dependencies = [ 2183 | "windows_aarch64_gnullvm 0.48.5", 2184 | "windows_aarch64_msvc 0.48.5", 2185 | "windows_i686_gnu 0.48.5", 2186 | "windows_i686_msvc 0.48.5", 2187 | "windows_x86_64_gnu 0.48.5", 2188 | "windows_x86_64_gnullvm 0.48.5", 2189 | "windows_x86_64_msvc 0.48.5", 2190 | ] 2191 | 2192 | [[package]] 2193 | name = "windows-targets" 2194 | version = "0.52.6" 2195 | source = "registry+https://github.com/rust-lang/crates.io-index" 2196 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 2197 | dependencies = [ 2198 | "windows_aarch64_gnullvm 0.52.6", 2199 | "windows_aarch64_msvc 0.52.6", 2200 | "windows_i686_gnu 0.52.6", 2201 | "windows_i686_gnullvm", 2202 | "windows_i686_msvc 0.52.6", 2203 | "windows_x86_64_gnu 0.52.6", 2204 | "windows_x86_64_gnullvm 0.52.6", 2205 | "windows_x86_64_msvc 0.52.6", 2206 | ] 2207 | 2208 | [[package]] 2209 | name = "windows_aarch64_gnullvm" 2210 | version = "0.48.5" 2211 | source = "registry+https://github.com/rust-lang/crates.io-index" 2212 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 2213 | 2214 | [[package]] 2215 | name = "windows_aarch64_gnullvm" 2216 | version = "0.52.6" 2217 | source = "registry+https://github.com/rust-lang/crates.io-index" 2218 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 2219 | 2220 | [[package]] 2221 | name = "windows_aarch64_msvc" 2222 | version = "0.48.5" 2223 | source = "registry+https://github.com/rust-lang/crates.io-index" 2224 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 2225 | 2226 | [[package]] 2227 | name = "windows_aarch64_msvc" 2228 | version = "0.52.6" 2229 | source = "registry+https://github.com/rust-lang/crates.io-index" 2230 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 2231 | 2232 | [[package]] 2233 | name = "windows_i686_gnu" 2234 | version = "0.48.5" 2235 | source = "registry+https://github.com/rust-lang/crates.io-index" 2236 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 2237 | 2238 | [[package]] 2239 | name = "windows_i686_gnu" 2240 | version = "0.52.6" 2241 | source = "registry+https://github.com/rust-lang/crates.io-index" 2242 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 2243 | 2244 | [[package]] 2245 | name = "windows_i686_gnullvm" 2246 | version = "0.52.6" 2247 | source = "registry+https://github.com/rust-lang/crates.io-index" 2248 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 2249 | 2250 | [[package]] 2251 | name = "windows_i686_msvc" 2252 | version = "0.48.5" 2253 | source = "registry+https://github.com/rust-lang/crates.io-index" 2254 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 2255 | 2256 | [[package]] 2257 | name = "windows_i686_msvc" 2258 | version = "0.52.6" 2259 | source = "registry+https://github.com/rust-lang/crates.io-index" 2260 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 2261 | 2262 | [[package]] 2263 | name = "windows_x86_64_gnu" 2264 | version = "0.48.5" 2265 | source = "registry+https://github.com/rust-lang/crates.io-index" 2266 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 2267 | 2268 | [[package]] 2269 | name = "windows_x86_64_gnu" 2270 | version = "0.52.6" 2271 | source = "registry+https://github.com/rust-lang/crates.io-index" 2272 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 2273 | 2274 | [[package]] 2275 | name = "windows_x86_64_gnullvm" 2276 | version = "0.48.5" 2277 | source = "registry+https://github.com/rust-lang/crates.io-index" 2278 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 2279 | 2280 | [[package]] 2281 | name = "windows_x86_64_gnullvm" 2282 | version = "0.52.6" 2283 | source = "registry+https://github.com/rust-lang/crates.io-index" 2284 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 2285 | 2286 | [[package]] 2287 | name = "windows_x86_64_msvc" 2288 | version = "0.48.5" 2289 | source = "registry+https://github.com/rust-lang/crates.io-index" 2290 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 2291 | 2292 | [[package]] 2293 | name = "windows_x86_64_msvc" 2294 | version = "0.52.6" 2295 | source = "registry+https://github.com/rust-lang/crates.io-index" 2296 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 2297 | 2298 | [[package]] 2299 | name = "winnow" 2300 | version = "0.6.20" 2301 | source = "registry+https://github.com/rust-lang/crates.io-index" 2302 | checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" 2303 | dependencies = [ 2304 | "memchr", 2305 | ] 2306 | 2307 | [[package]] 2308 | name = "write16" 2309 | version = "1.0.0" 2310 | source = "registry+https://github.com/rust-lang/crates.io-index" 2311 | checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" 2312 | 2313 | [[package]] 2314 | name = "writeable" 2315 | version = "0.5.5" 2316 | source = "registry+https://github.com/rust-lang/crates.io-index" 2317 | checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" 2318 | 2319 | [[package]] 2320 | name = "xdg" 2321 | version = "2.5.2" 2322 | source = "registry+https://github.com/rust-lang/crates.io-index" 2323 | checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" 2324 | 2325 | [[package]] 2326 | name = "xdg-home" 2327 | version = "1.3.0" 2328 | source = "registry+https://github.com/rust-lang/crates.io-index" 2329 | checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" 2330 | dependencies = [ 2331 | "libc", 2332 | "windows-sys 0.59.0", 2333 | ] 2334 | 2335 | [[package]] 2336 | name = "yoke" 2337 | version = "0.7.4" 2338 | source = "registry+https://github.com/rust-lang/crates.io-index" 2339 | checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" 2340 | dependencies = [ 2341 | "serde", 2342 | "stable_deref_trait", 2343 | "yoke-derive", 2344 | "zerofrom", 2345 | ] 2346 | 2347 | [[package]] 2348 | name = "yoke-derive" 2349 | version = "0.7.4" 2350 | source = "registry+https://github.com/rust-lang/crates.io-index" 2351 | checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" 2352 | dependencies = [ 2353 | "proc-macro2", 2354 | "quote", 2355 | "syn", 2356 | "synstructure", 2357 | ] 2358 | 2359 | [[package]] 2360 | name = "zbus" 2361 | version = "4.4.0" 2362 | source = "registry+https://github.com/rust-lang/crates.io-index" 2363 | checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725" 2364 | dependencies = [ 2365 | "async-broadcast", 2366 | "async-executor", 2367 | "async-fs", 2368 | "async-io", 2369 | "async-lock", 2370 | "async-process", 2371 | "async-recursion", 2372 | "async-task", 2373 | "async-trait", 2374 | "blocking", 2375 | "enumflags2", 2376 | "event-listener", 2377 | "futures-core", 2378 | "futures-sink", 2379 | "futures-util", 2380 | "hex", 2381 | "nix 0.29.0", 2382 | "ordered-stream", 2383 | "rand", 2384 | "serde", 2385 | "serde_repr", 2386 | "sha1", 2387 | "static_assertions", 2388 | "tokio", 2389 | "tracing", 2390 | "uds_windows", 2391 | "windows-sys 0.52.0", 2392 | "xdg-home", 2393 | "zbus_macros", 2394 | "zbus_names", 2395 | "zvariant", 2396 | ] 2397 | 2398 | [[package]] 2399 | name = "zbus_macros" 2400 | version = "4.4.0" 2401 | source = "registry+https://github.com/rust-lang/crates.io-index" 2402 | checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e" 2403 | dependencies = [ 2404 | "proc-macro-crate", 2405 | "proc-macro2", 2406 | "quote", 2407 | "syn", 2408 | "zvariant_utils", 2409 | ] 2410 | 2411 | [[package]] 2412 | name = "zbus_names" 2413 | version = "3.0.0" 2414 | source = "registry+https://github.com/rust-lang/crates.io-index" 2415 | checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c" 2416 | dependencies = [ 2417 | "serde", 2418 | "static_assertions", 2419 | "zvariant", 2420 | ] 2421 | 2422 | [[package]] 2423 | name = "zbus_systemd" 2424 | version = "0.25600.0" 2425 | source = "registry+https://github.com/rust-lang/crates.io-index" 2426 | checksum = "14a94191447de6983b8c81f6d57d759501e03e59be7970ab0dc069ac9e36f786" 2427 | dependencies = [ 2428 | "futures", 2429 | "serde", 2430 | "zbus", 2431 | ] 2432 | 2433 | [[package]] 2434 | name = "zerocopy" 2435 | version = "0.7.35" 2436 | source = "registry+https://github.com/rust-lang/crates.io-index" 2437 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" 2438 | dependencies = [ 2439 | "byteorder", 2440 | "zerocopy-derive", 2441 | ] 2442 | 2443 | [[package]] 2444 | name = "zerocopy-derive" 2445 | version = "0.7.35" 2446 | source = "registry+https://github.com/rust-lang/crates.io-index" 2447 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" 2448 | dependencies = [ 2449 | "proc-macro2", 2450 | "quote", 2451 | "syn", 2452 | ] 2453 | 2454 | [[package]] 2455 | name = "zerofrom" 2456 | version = "0.1.4" 2457 | source = "registry+https://github.com/rust-lang/crates.io-index" 2458 | checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" 2459 | dependencies = [ 2460 | "zerofrom-derive", 2461 | ] 2462 | 2463 | [[package]] 2464 | name = "zerofrom-derive" 2465 | version = "0.1.4" 2466 | source = "registry+https://github.com/rust-lang/crates.io-index" 2467 | checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" 2468 | dependencies = [ 2469 | "proc-macro2", 2470 | "quote", 2471 | "syn", 2472 | "synstructure", 2473 | ] 2474 | 2475 | [[package]] 2476 | name = "zerovec" 2477 | version = "0.10.4" 2478 | source = "registry+https://github.com/rust-lang/crates.io-index" 2479 | checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" 2480 | dependencies = [ 2481 | "yoke", 2482 | "zerofrom", 2483 | "zerovec-derive", 2484 | ] 2485 | 2486 | [[package]] 2487 | name = "zerovec-derive" 2488 | version = "0.10.3" 2489 | source = "registry+https://github.com/rust-lang/crates.io-index" 2490 | checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" 2491 | dependencies = [ 2492 | "proc-macro2", 2493 | "quote", 2494 | "syn", 2495 | ] 2496 | 2497 | [[package]] 2498 | name = "zvariant" 2499 | version = "4.2.0" 2500 | source = "registry+https://github.com/rust-lang/crates.io-index" 2501 | checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe" 2502 | dependencies = [ 2503 | "endi", 2504 | "enumflags2", 2505 | "serde", 2506 | "static_assertions", 2507 | "zvariant_derive", 2508 | ] 2509 | 2510 | [[package]] 2511 | name = "zvariant_derive" 2512 | version = "4.2.0" 2513 | source = "registry+https://github.com/rust-lang/crates.io-index" 2514 | checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449" 2515 | dependencies = [ 2516 | "proc-macro-crate", 2517 | "proc-macro2", 2518 | "quote", 2519 | "syn", 2520 | "zvariant_utils", 2521 | ] 2522 | 2523 | [[package]] 2524 | name = "zvariant_utils" 2525 | version = "2.1.0" 2526 | source = "registry+https://github.com/rust-lang/crates.io-index" 2527 | checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" 2528 | dependencies = [ 2529 | "proc-macro2", 2530 | "quote", 2531 | "syn", 2532 | ] 2533 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cosmic-session" 3 | description = "The session manager for the COSMIC desktop environment" 4 | version = "0.1.0" 5 | license = "GPL-3.0-only" 6 | edition = "2021" 7 | authors = ["Lucy "] 8 | publish = false 9 | 10 | [dependencies] 11 | async-signals = "0.5" 12 | color-eyre = "0.6" 13 | futures-util = "0.3" 14 | cosmic-dbus-a11y = { git = "https://github.com/pop-os/dbus-settings-bindings" } 15 | freedesktop-desktop-entry = { version = "0.7.7", optional = true } 16 | shell-words = { version = "1.1.0", optional = true } 17 | dirs = { version = "6.0.0", optional = true } 18 | itertools = "0.12" 19 | launch-pad = { git = "https://github.com/pop-os/launch-pad" } 20 | libc = "0.2" 21 | log-panics = { version = "2", features = ["with-backtrace"] } 22 | rustix = "0.38" 23 | scopeguard = "1" 24 | sendfd = { version = "0.4", features = ["tokio"] } 25 | serde = { version = "1", features = ["derive"] } 26 | serde_json = "1" 27 | tokio = { version = "1", features = [ 28 | "fs", 29 | "io-util", 30 | "io-std", 31 | "macros", 32 | "net", 33 | "parking_lot", 34 | "process", 35 | "rt", 36 | "signal", 37 | "sync", 38 | "time", 39 | ] } 40 | zbus_systemd = { version = "0.25600.0", optional = true, features = [ 41 | "systemd1", 42 | ] } 43 | tokio-util = "0.7" 44 | tracing = "0.1" 45 | tracing-journald = { version = "0.3", optional = true } 46 | tracing-subscriber = { version = "0.3", features = ["env-filter"] } 47 | zbus = { version = "4.3.0", default-features = false, features = ["tokio"] } 48 | cosmic-notifications-util = { git = "https://github.com/pop-os/cosmic-notifications" } 49 | 50 | [features] 51 | systemd = ["dep:zbus_systemd", "dep:tracing-journald"] 52 | default = ["systemd"] 53 | autostart = ["dep:shell-words", "dep:dirs", "dep:freedesktop-desktop-entry"] 54 | -------------------------------------------------------------------------------- /Justfile: -------------------------------------------------------------------------------- 1 | rootdir := '' 2 | etcdir := '/etc' 3 | prefix := '/usr' 4 | clean := '0' 5 | debug := '0' 6 | vendor := '0' 7 | cargo-target-dir := env('CARGO_TARGET_DIR', 'target') 8 | target := if debug == '1' { 'debug' } else { 'release' } 9 | vendor_args := if vendor == '1' { '--frozen --offline' } else { '' } 10 | debug_args := if debug == '1' { '' } else { '--release' } 11 | cargo_args := vendor_args + ' ' + debug_args 12 | xdp_cosmic := '/usr/libexec/xdg-desktop-portal-cosmic' 13 | orca := '/usr/bin/orca' 14 | cosmic_dconf_profile := prefix + '/share/dconf/profile/cosmic' 15 | 16 | bindir := rootdir / prefix + '/bin' 17 | systemddir := rootdir / prefix + '/lib/systemd/user' 18 | sessiondir := rootdir / prefix + '/share/wayland-sessions' 19 | applicationdir := rootdir / prefix + '/share/applications' 20 | 21 | all: _extract_vendor build 22 | 23 | build: 24 | XDP_COSMIC={{xdp_cosmic}} ORCA={{orca}} cargo build {{cargo_args}} 25 | 26 | # Installs files into the system 27 | install: 28 | echo {{cosmic_dconf_profile}} 29 | # main binary 30 | install -Dm0755 {{cargo-target-dir}}/release/cosmic-session {{bindir}}/cosmic-session 31 | 32 | # session start script 33 | install -Dm0755 data/start-cosmic {{bindir}}/start-cosmic 34 | sed -i "s|DCONF_PROFILE=cosmic|DCONF_PROFILE={{cosmic_dconf_profile}}|" {{bindir}}/start-cosmic 35 | 36 | # systemd target 37 | install -Dm0644 data/cosmic-session.target {{systemddir}}/cosmic-session.target 38 | 39 | # session 40 | install -Dm0644 data/cosmic.desktop {{sessiondir}}/cosmic.desktop 41 | 42 | # mimeapps 43 | install -Dm0644 data/cosmic-mimeapps.list {{applicationdir}}/cosmic-mimeapps.list 44 | 45 | # dconf profile 46 | install -Dm644 data/dconf/profile/cosmic {{rootdir}}/{{cosmic_dconf_profile}} 47 | 48 | clean_vendor: 49 | rm -rf vendor vendor.tar .cargo/config 50 | 51 | clean: clean_vendor 52 | cargo clean 53 | 54 | # Extracts vendored dependencies if vendor=1 55 | _extract_vendor: 56 | #!/usr/bin/env sh 57 | if test {{vendor}} = 1; then 58 | rm -rf vendor; tar pxf vendor.tar 59 | fi 60 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | GNU General Public License 2 | ========================== 3 | 4 | _Version 3, 29 June 2007_ 5 | _Copyright © 2007 Free Software Foundation, Inc. <>_ 6 | 7 | Everyone is permitted to copy and distribute verbatim copies of this license 8 | document, but changing it is not allowed. 9 | 10 | ## Preamble 11 | 12 | The GNU General Public License is a free, copyleft license for software and other 13 | kinds of works. 14 | 15 | The licenses for most software and other practical works are designed to take away 16 | your freedom to share and change the works. By contrast, the GNU General Public 17 | License is intended to guarantee your freedom to share and change all versions of a 18 | program--to make sure it remains free software for all its users. We, the Free 19 | Software Foundation, use the GNU General Public License for most of our software; it 20 | applies also to any other work released this way by its authors. You can apply it to 21 | your programs, too. 22 | 23 | When we speak of free software, we are referring to freedom, not price. Our General 24 | Public Licenses are designed to make sure that you have the freedom to distribute 25 | copies of free software (and charge for them if you wish), that you receive source 26 | code or can get it if you want it, that you can change the software or use pieces of 27 | it in new free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you these rights or 30 | asking you to surrender the rights. Therefore, you have certain responsibilities if 31 | you distribute copies of the software, or if you modify it: responsibilities to 32 | respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether gratis or for a fee, 35 | you must pass on to the recipients the same freedoms that you received. You must make 36 | sure that they, too, receive or can get the source code. And you must show them these 37 | terms so they know their rights. 38 | 39 | Developers that use the GNU GPL protect your rights with two steps: **(1)** assert 40 | copyright on the software, and **(2)** offer you this License giving you legal permission 41 | to copy, distribute and/or modify it. 42 | 43 | For the developers' and authors' protection, the GPL clearly explains that there is 44 | no warranty for this free software. For both users' and authors' sake, the GPL 45 | requires that modified versions be marked as changed, so that their problems will not 46 | be attributed erroneously to authors of previous versions. 47 | 48 | Some devices are designed to deny users access to install or run modified versions of 49 | the software inside them, although the manufacturer can do so. This is fundamentally 50 | incompatible with the aim of protecting users' freedom to change the software. The 51 | systematic pattern of such abuse occurs in the area of products for individuals to 52 | use, which is precisely where it is most unacceptable. Therefore, we have designed 53 | this version of the GPL to prohibit the practice for those products. If such problems 54 | arise substantially in other domains, we stand ready to extend this provision to 55 | those domains in future versions of the GPL, as needed to protect the freedom of 56 | users. 57 | 58 | Finally, every program is threatened constantly by software patents. States should 59 | not allow patents to restrict development and use of software on general-purpose 60 | computers, but in those that do, we wish to avoid the special danger that patents 61 | applied to a free program could make it effectively proprietary. To prevent this, the 62 | GPL assures that patents cannot be used to render the program non-free. 63 | 64 | The precise terms and conditions for copying, distribution and modification follow. 65 | 66 | ## TERMS AND CONDITIONS 67 | 68 | ### 0. Definitions 69 | 70 | “This License” refers to version 3 of the GNU General Public License. 71 | 72 | “Copyright” also means copyright-like laws that apply to other kinds of 73 | works, such as semiconductor masks. 74 | 75 | “The Program” refers to any copyrightable work licensed under this 76 | License. Each licensee is addressed as “you”. “Licensees” and 77 | “recipients” may be individuals or organizations. 78 | 79 | To “modify” a work means to copy from or adapt all or part of the work in 80 | a fashion requiring copyright permission, other than the making of an exact copy. The 81 | resulting work is called a “modified version” of the earlier work or a 82 | work “based on” the earlier work. 83 | 84 | A “covered work” means either the unmodified Program or a work based on 85 | the Program. 86 | 87 | To “propagate” a work means to do anything with it that, without 88 | permission, would make you directly or secondarily liable for infringement under 89 | applicable copyright law, except executing it on a computer or modifying a private 90 | copy. Propagation includes copying, distribution (with or without modification), 91 | making available to the public, and in some countries other activities as well. 92 | 93 | To “convey” a work means any kind of propagation that enables other 94 | parties to make or receive copies. Mere interaction with a user through a computer 95 | network, with no transfer of a copy, is not conveying. 96 | 97 | An interactive user interface displays “Appropriate Legal Notices” to the 98 | extent that it includes a convenient and prominently visible feature that **(1)** 99 | displays an appropriate copyright notice, and **(2)** tells the user that there is no 100 | warranty for the work (except to the extent that warranties are provided), that 101 | licensees may convey the work under this License, and how to view a copy of this 102 | License. If the interface presents a list of user commands or options, such as a 103 | menu, a prominent item in the list meets this criterion. 104 | 105 | ### 1. Source Code 106 | 107 | The “source code” for a work means the preferred form of the work for 108 | making modifications to it. “Object code” means any non-source form of a 109 | work. 110 | 111 | A “Standard Interface” means an interface that either is an official 112 | standard defined by a recognized standards body, or, in the case of interfaces 113 | specified for a particular programming language, one that is widely used among 114 | developers working in that language. 115 | 116 | The “System Libraries” of an executable work include anything, other than 117 | the work as a whole, that **(a)** is included in the normal form of packaging a Major 118 | Component, but which is not part of that Major Component, and **(b)** serves only to 119 | enable use of the work with that Major Component, or to implement a Standard 120 | Interface for which an implementation is available to the public in source code form. 121 | A “Major Component”, in this context, means a major essential component 122 | (kernel, window system, and so on) of the specific operating system (if any) on which 123 | the executable work runs, or a compiler used to produce the work, or an object code 124 | interpreter used to run it. 125 | 126 | The “Corresponding Source” for a work in object code form means all the 127 | source code needed to generate, install, and (for an executable work) run the object 128 | code and to modify the work, including scripts to control those activities. However, 129 | it does not include the work's System Libraries, or general-purpose tools or 130 | generally available free programs which are used unmodified in performing those 131 | activities but which are not part of the work. For example, Corresponding Source 132 | includes interface definition files associated with source files for the work, and 133 | the source code for shared libraries and dynamically linked subprograms that the work 134 | is specifically designed to require, such as by intimate data communication or 135 | control flow between those subprograms and other parts of the work. 136 | 137 | The Corresponding Source need not include anything that users can regenerate 138 | automatically from other parts of the Corresponding Source. 139 | 140 | The Corresponding Source for a work in source code form is that same work. 141 | 142 | ### 2. Basic Permissions 143 | 144 | All rights granted under this License are granted for the term of copyright on the 145 | Program, and are irrevocable provided the stated conditions are met. This License 146 | explicitly affirms your unlimited permission to run the unmodified Program. The 147 | output from running a covered work is covered by this License only if the output, 148 | given its content, constitutes a covered work. This License acknowledges your rights 149 | of fair use or other equivalent, as provided by copyright law. 150 | 151 | You may make, run and propagate covered works that you do not convey, without 152 | conditions so long as your license otherwise remains in force. You may convey covered 153 | works to others for the sole purpose of having them make modifications exclusively 154 | for you, or provide you with facilities for running those works, provided that you 155 | comply with the terms of this License in conveying all material for which you do not 156 | control copyright. Those thus making or running the covered works for you must do so 157 | exclusively on your behalf, under your direction and control, on terms that prohibit 158 | them from making any copies of your copyrighted material outside their relationship 159 | with you. 160 | 161 | Conveying under any other circumstances is permitted solely under the conditions 162 | stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 163 | 164 | ### 3. Protecting Users' Legal Rights From Anti-Circumvention Law 165 | 166 | No covered work shall be deemed part of an effective technological measure under any 167 | applicable law fulfilling obligations under article 11 of the WIPO copyright treaty 168 | adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention 169 | of such measures. 170 | 171 | When you convey a covered work, you waive any legal power to forbid circumvention of 172 | technological measures to the extent such circumvention is effected by exercising 173 | rights under this License with respect to the covered work, and you disclaim any 174 | intention to limit operation or modification of the work as a means of enforcing, 175 | against the work's users, your or third parties' legal rights to forbid circumvention 176 | of technological measures. 177 | 178 | ### 4. Conveying Verbatim Copies 179 | 180 | You may convey verbatim copies of the Program's source code as you receive it, in any 181 | medium, provided that you conspicuously and appropriately publish on each copy an 182 | appropriate copyright notice; keep intact all notices stating that this License and 183 | any non-permissive terms added in accord with section 7 apply to the code; keep 184 | intact all notices of the absence of any warranty; and give all recipients a copy of 185 | this License along with the Program. 186 | 187 | You may charge any price or no price for each copy that you convey, and you may offer 188 | support or warranty protection for a fee. 189 | 190 | ### 5. Conveying Modified Source Versions 191 | 192 | You may convey a work based on the Program, or the modifications to produce it from 193 | the Program, in the form of source code under the terms of section 4, provided that 194 | you also meet all of these conditions: 195 | 196 | * **a)** The work must carry prominent notices stating that you modified it, and giving a 197 | relevant date. 198 | * **b)** The work must carry prominent notices stating that it is released under this 199 | License and any conditions added under section 7. This requirement modifies the 200 | requirement in section 4 to “keep intact all notices”. 201 | * **c)** You must license the entire work, as a whole, under this License to anyone who 202 | comes into possession of a copy. This License will therefore apply, along with any 203 | applicable section 7 additional terms, to the whole of the work, and all its parts, 204 | regardless of how they are packaged. This License gives no permission to license the 205 | work in any other way, but it does not invalidate such permission if you have 206 | separately received it. 207 | * **d)** If the work has interactive user interfaces, each must display Appropriate Legal 208 | Notices; however, if the Program has interactive interfaces that do not display 209 | Appropriate Legal Notices, your work need not make them do so. 210 | 211 | A compilation of a covered work with other separate and independent works, which are 212 | not by their nature extensions of the covered work, and which are not combined with 213 | it such as to form a larger program, in or on a volume of a storage or distribution 214 | medium, is called an “aggregate” if the compilation and its resulting 215 | copyright are not used to limit the access or legal rights of the compilation's users 216 | beyond what the individual works permit. Inclusion of a covered work in an aggregate 217 | does not cause this License to apply to the other parts of the aggregate. 218 | 219 | ### 6. Conveying Non-Source Forms 220 | 221 | You may convey a covered work in object code form under the terms of sections 4 and 222 | 5, provided that you also convey the machine-readable Corresponding Source under the 223 | terms of this License, in one of these ways: 224 | 225 | * **a)** Convey the object code in, or embodied in, a physical product (including a 226 | physical distribution medium), accompanied by the Corresponding Source fixed on a 227 | durable physical medium customarily used for software interchange. 228 | * **b)** Convey the object code in, or embodied in, a physical product (including a 229 | physical distribution medium), accompanied by a written offer, valid for at least 230 | three years and valid for as long as you offer spare parts or customer support for 231 | that product model, to give anyone who possesses the object code either **(1)** a copy of 232 | the Corresponding Source for all the software in the product that is covered by this 233 | License, on a durable physical medium customarily used for software interchange, for 234 | a price no more than your reasonable cost of physically performing this conveying of 235 | source, or **(2)** access to copy the Corresponding Source from a network server at no 236 | charge. 237 | * **c)** Convey individual copies of the object code with a copy of the written offer to 238 | provide the Corresponding Source. This alternative is allowed only occasionally and 239 | noncommercially, and only if you received the object code with such an offer, in 240 | accord with subsection 6b. 241 | * **d)** Convey the object code by offering access from a designated place (gratis or for 242 | a charge), and offer equivalent access to the Corresponding Source in the same way 243 | through the same place at no further charge. You need not require recipients to copy 244 | the Corresponding Source along with the object code. If the place to copy the object 245 | code is a network server, the Corresponding Source may be on a different server 246 | (operated by you or a third party) that supports equivalent copying facilities, 247 | provided you maintain clear directions next to the object code saying where to find 248 | the Corresponding Source. Regardless of what server hosts the Corresponding Source, 249 | you remain obligated to ensure that it is available for as long as needed to satisfy 250 | these requirements. 251 | * **e)** Convey the object code using peer-to-peer transmission, provided you inform 252 | other peers where the object code and Corresponding Source of the work are being 253 | offered to the general public at no charge under subsection 6d. 254 | 255 | A separable portion of the object code, whose source code is excluded from the 256 | Corresponding Source as a System Library, need not be included in conveying the 257 | object code work. 258 | 259 | A “User Product” is either **(1)** a “consumer product”, which 260 | means any tangible personal property which is normally used for personal, family, or 261 | household purposes, or **(2)** anything designed or sold for incorporation into a 262 | dwelling. In determining whether a product is a consumer product, doubtful cases 263 | shall be resolved in favor of coverage. For a particular product received by a 264 | particular user, “normally used” refers to a typical or common use of 265 | that class of product, regardless of the status of the particular user or of the way 266 | in which the particular user actually uses, or expects or is expected to use, the 267 | product. A product is a consumer product regardless of whether the product has 268 | substantial commercial, industrial or non-consumer uses, unless such uses represent 269 | the only significant mode of use of the product. 270 | 271 | “Installation Information” for a User Product means any methods, 272 | procedures, authorization keys, or other information required to install and execute 273 | modified versions of a covered work in that User Product from a modified version of 274 | its Corresponding Source. The information must suffice to ensure that the continued 275 | functioning of the modified object code is in no case prevented or interfered with 276 | solely because modification has been made. 277 | 278 | If you convey an object code work under this section in, or with, or specifically for 279 | use in, a User Product, and the conveying occurs as part of a transaction in which 280 | the right of possession and use of the User Product is transferred to the recipient 281 | in perpetuity or for a fixed term (regardless of how the transaction is 282 | characterized), the Corresponding Source conveyed under this section must be 283 | accompanied by the Installation Information. But this requirement does not apply if 284 | neither you nor any third party retains the ability to install modified object code 285 | on the User Product (for example, the work has been installed in ROM). 286 | 287 | The requirement to provide Installation Information does not include a requirement to 288 | continue to provide support service, warranty, or updates for a work that has been 289 | modified or installed by the recipient, or for the User Product in which it has been 290 | modified or installed. Access to a network may be denied when the modification itself 291 | materially and adversely affects the operation of the network or violates the rules 292 | and protocols for communication across the network. 293 | 294 | Corresponding Source conveyed, and Installation Information provided, in accord with 295 | this section must be in a format that is publicly documented (and with an 296 | implementation available to the public in source code form), and must require no 297 | special password or key for unpacking, reading or copying. 298 | 299 | ### 7. Additional Terms 300 | 301 | “Additional permissions” are terms that supplement the terms of this 302 | License by making exceptions from one or more of its conditions. Additional 303 | permissions that are applicable to the entire Program shall be treated as though they 304 | were included in this License, to the extent that they are valid under applicable 305 | law. If additional permissions apply only to part of the Program, that part may be 306 | used separately under those permissions, but the entire Program remains governed by 307 | this License without regard to the additional permissions. 308 | 309 | When you convey a copy of a covered work, you may at your option remove any 310 | additional permissions from that copy, or from any part of it. (Additional 311 | permissions may be written to require their own removal in certain cases when you 312 | modify the work.) You may place additional permissions on material, added by you to a 313 | covered work, for which you have or can give appropriate copyright permission. 314 | 315 | Notwithstanding any other provision of this License, for material you add to a 316 | covered work, you may (if authorized by the copyright holders of that material) 317 | supplement the terms of this License with terms: 318 | 319 | * **a)** Disclaiming warranty or limiting liability differently from the terms of 320 | sections 15 and 16 of this License; or 321 | * **b)** Requiring preservation of specified reasonable legal notices or author 322 | attributions in that material or in the Appropriate Legal Notices displayed by works 323 | containing it; or 324 | * **c)** Prohibiting misrepresentation of the origin of that material, or requiring that 325 | modified versions of such material be marked in reasonable ways as different from the 326 | original version; or 327 | * **d)** Limiting the use for publicity purposes of names of licensors or authors of the 328 | material; or 329 | * **e)** Declining to grant rights under trademark law for use of some trade names, 330 | trademarks, or service marks; or 331 | * **f)** Requiring indemnification of licensors and authors of that material by anyone 332 | who conveys the material (or modified versions of it) with contractual assumptions of 333 | liability to the recipient, for any liability that these contractual assumptions 334 | directly impose on those licensors and authors. 335 | 336 | All other non-permissive additional terms are considered “further 337 | restrictions” within the meaning of section 10. If the Program as you received 338 | it, or any part of it, contains a notice stating that it is governed by this License 339 | along with a term that is a further restriction, you may remove that term. If a 340 | license document contains a further restriction but permits relicensing or conveying 341 | under this License, you may add to a covered work material governed by the terms of 342 | that license document, provided that the further restriction does not survive such 343 | relicensing or conveying. 344 | 345 | If you add terms to a covered work in accord with this section, you must place, in 346 | the relevant source files, a statement of the additional terms that apply to those 347 | files, or a notice indicating where to find the applicable terms. 348 | 349 | Additional terms, permissive or non-permissive, may be stated in the form of a 350 | separately written license, or stated as exceptions; the above requirements apply 351 | either way. 352 | 353 | ### 8. Termination 354 | 355 | You may not propagate or modify a covered work except as expressly provided under 356 | this License. Any attempt otherwise to propagate or modify it is void, and will 357 | automatically terminate your rights under this License (including any patent licenses 358 | granted under the third paragraph of section 11). 359 | 360 | However, if you cease all violation of this License, then your license from a 361 | particular copyright holder is reinstated **(a)** provisionally, unless and until the 362 | copyright holder explicitly and finally terminates your license, and **(b)** permanently, 363 | if the copyright holder fails to notify you of the violation by some reasonable means 364 | prior to 60 days after the cessation. 365 | 366 | Moreover, your license from a particular copyright holder is reinstated permanently 367 | if the copyright holder notifies you of the violation by some reasonable means, this 368 | is the first time you have received notice of violation of this License (for any 369 | work) from that copyright holder, and you cure the violation prior to 30 days after 370 | your receipt of the notice. 371 | 372 | Termination of your rights under this section does not terminate the licenses of 373 | parties who have received copies or rights from you under this License. If your 374 | rights have been terminated and not permanently reinstated, you do not qualify to 375 | receive new licenses for the same material under section 10. 376 | 377 | ### 9. Acceptance Not Required for Having Copies 378 | 379 | You are not required to accept this License in order to receive or run a copy of the 380 | Program. Ancillary propagation of a covered work occurring solely as a consequence of 381 | using peer-to-peer transmission to receive a copy likewise does not require 382 | acceptance. However, nothing other than this License grants you permission to 383 | propagate or modify any covered work. These actions infringe copyright if you do not 384 | accept this License. Therefore, by modifying or propagating a covered work, you 385 | indicate your acceptance of this License to do so. 386 | 387 | ### 10. Automatic Licensing of Downstream Recipients 388 | 389 | Each time you convey a covered work, the recipient automatically receives a license 390 | from the original licensors, to run, modify and propagate that work, subject to this 391 | License. You are not responsible for enforcing compliance by third parties with this 392 | License. 393 | 394 | An “entity transaction” is a transaction transferring control of an 395 | organization, or substantially all assets of one, or subdividing an organization, or 396 | merging organizations. If propagation of a covered work results from an entity 397 | transaction, each party to that transaction who receives a copy of the work also 398 | receives whatever licenses to the work the party's predecessor in interest had or 399 | could give under the previous paragraph, plus a right to possession of the 400 | Corresponding Source of the work from the predecessor in interest, if the predecessor 401 | has it or can get it with reasonable efforts. 402 | 403 | You may not impose any further restrictions on the exercise of the rights granted or 404 | affirmed under this License. For example, you may not impose a license fee, royalty, 405 | or other charge for exercise of rights granted under this License, and you may not 406 | initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging 407 | that any patent claim is infringed by making, using, selling, offering for sale, or 408 | importing the Program or any portion of it. 409 | 410 | ### 11. Patents 411 | 412 | A “contributor” is a copyright holder who authorizes use under this 413 | License of the Program or a work on which the Program is based. The work thus 414 | licensed is called the contributor's “contributor version”. 415 | 416 | A contributor's “essential patent claims” are all patent claims owned or 417 | controlled by the contributor, whether already acquired or hereafter acquired, that 418 | would be infringed by some manner, permitted by this License, of making, using, or 419 | selling its contributor version, but do not include claims that would be infringed 420 | only as a consequence of further modification of the contributor version. For 421 | purposes of this definition, “control” includes the right to grant patent 422 | sublicenses in a manner consistent with the requirements of this License. 423 | 424 | Each contributor grants you a non-exclusive, worldwide, royalty-free patent license 425 | under the contributor's essential patent claims, to make, use, sell, offer for sale, 426 | import and otherwise run, modify and propagate the contents of its contributor 427 | version. 428 | 429 | In the following three paragraphs, a “patent license” is any express 430 | agreement or commitment, however denominated, not to enforce a patent (such as an 431 | express permission to practice a patent or covenant not to sue for patent 432 | infringement). To “grant” such a patent license to a party means to make 433 | such an agreement or commitment not to enforce a patent against the party. 434 | 435 | If you convey a covered work, knowingly relying on a patent license, and the 436 | Corresponding Source of the work is not available for anyone to copy, free of charge 437 | and under the terms of this License, through a publicly available network server or 438 | other readily accessible means, then you must either **(1)** cause the Corresponding 439 | Source to be so available, or **(2)** arrange to deprive yourself of the benefit of the 440 | patent license for this particular work, or **(3)** arrange, in a manner consistent with 441 | the requirements of this License, to extend the patent license to downstream 442 | recipients. “Knowingly relying” means you have actual knowledge that, but 443 | for the patent license, your conveying the covered work in a country, or your 444 | recipient's use of the covered work in a country, would infringe one or more 445 | identifiable patents in that country that you have reason to believe are valid. 446 | 447 | If, pursuant to or in connection with a single transaction or arrangement, you 448 | convey, or propagate by procuring conveyance of, a covered work, and grant a patent 449 | license to some of the parties receiving the covered work authorizing them to use, 450 | propagate, modify or convey a specific copy of the covered work, then the patent 451 | license you grant is automatically extended to all recipients of the covered work and 452 | works based on it. 453 | 454 | A patent license is “discriminatory” if it does not include within the 455 | scope of its coverage, prohibits the exercise of, or is conditioned on the 456 | non-exercise of one or more of the rights that are specifically granted under this 457 | License. You may not convey a covered work if you are a party to an arrangement with 458 | a third party that is in the business of distributing software, under which you make 459 | payment to the third party based on the extent of your activity of conveying the 460 | work, and under which the third party grants, to any of the parties who would receive 461 | the covered work from you, a discriminatory patent license **(a)** in connection with 462 | copies of the covered work conveyed by you (or copies made from those copies), or **(b)** 463 | primarily for and in connection with specific products or compilations that contain 464 | the covered work, unless you entered into that arrangement, or that patent license 465 | was granted, prior to 28 March 2007. 466 | 467 | Nothing in this License shall be construed as excluding or limiting any implied 468 | license or other defenses to infringement that may otherwise be available to you 469 | under applicable patent law. 470 | 471 | ### 12. No Surrender of Others' Freedom 472 | 473 | If conditions are imposed on you (whether by court order, agreement or otherwise) 474 | that contradict the conditions of this License, they do not excuse you from the 475 | conditions of this License. If you cannot convey a covered work so as to satisfy 476 | simultaneously your obligations under this License and any other pertinent 477 | obligations, then as a consequence you may not convey it at all. For example, if you 478 | agree to terms that obligate you to collect a royalty for further conveying from 479 | those to whom you convey the Program, the only way you could satisfy both those terms 480 | and this License would be to refrain entirely from conveying the Program. 481 | 482 | ### 13. Use with the GNU Affero General Public License 483 | 484 | Notwithstanding any other provision of this License, you have permission to link or 485 | combine any covered work with a work licensed under version 3 of the GNU Affero 486 | General Public License into a single combined work, and to convey the resulting work. 487 | The terms of this License will continue to apply to the part which is the covered 488 | work, but the special requirements of the GNU Affero General Public License, section 489 | 13, concerning interaction through a network will apply to the combination as such. 490 | 491 | ### 14. Revised Versions of this License 492 | 493 | The Free Software Foundation may publish revised and/or new versions of the GNU 494 | General Public License from time to time. Such new versions will be similar in spirit 495 | to the present version, but may differ in detail to address new problems or concerns. 496 | 497 | Each version is given a distinguishing version number. If the Program specifies that 498 | a certain numbered version of the GNU General Public License “or any later 499 | version” applies to it, you have the option of following the terms and 500 | conditions either of that numbered version or of any later version published by the 501 | Free Software Foundation. If the Program does not specify a version number of the GNU 502 | General Public License, you may choose any version ever published by the Free 503 | Software Foundation. 504 | 505 | If the Program specifies that a proxy can decide which future versions of the GNU 506 | General Public License can be used, that proxy's public statement of acceptance of a 507 | version permanently authorizes you to choose that version for the Program. 508 | 509 | Later license versions may give you additional or different permissions. However, no 510 | additional obligations are imposed on any author or copyright holder as a result of 511 | your choosing to follow a later version. 512 | 513 | ### 15. Disclaimer of Warranty 514 | 515 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 516 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 517 | PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER 518 | EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 519 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE 520 | QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE 521 | DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 522 | 523 | ### 16. Limitation of Liability 524 | 525 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY 526 | COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS 527 | PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, 528 | INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 529 | PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE 530 | OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE 531 | WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 532 | POSSIBILITY OF SUCH DAMAGES. 533 | 534 | ### 17. Interpretation of Sections 15 and 16 535 | 536 | If the disclaimer of warranty and limitation of liability provided above cannot be 537 | given local legal effect according to their terms, reviewing courts shall apply local 538 | law that most closely approximates an absolute waiver of all civil liability in 539 | connection with the Program, unless a warranty or assumption of liability accompanies 540 | a copy of the Program in return for a fee. 541 | 542 | _END OF TERMS AND CONDITIONS_ 543 | 544 | ## How to Apply These Terms to Your New Programs 545 | 546 | If you develop a new program, and you want it to be of the greatest possible use to 547 | the public, the best way to achieve this is to make it free software which everyone 548 | can redistribute and change under these terms. 549 | 550 | To do so, attach the following notices to the program. It is safest to attach them 551 | to the start of each source file to most effectively state the exclusion of warranty; 552 | and each file should have at least the “copyright” line and a pointer to 553 | where the full notice is found. 554 | 555 | 556 | Copyright (C) 557 | 558 | This program is free software: you can redistribute it and/or modify 559 | it under the terms of the GNU General Public License as published by 560 | the Free Software Foundation, either version 3 of the License, or 561 | (at your option) any later version. 562 | 563 | This program is distributed in the hope that it will be useful, 564 | but WITHOUT ANY WARRANTY; without even the implied warranty of 565 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 566 | GNU General Public License for more details. 567 | 568 | You should have received a copy of the GNU General Public License 569 | along with this program. If not, see . 570 | 571 | Also add information on how to contact you by electronic and paper mail. 572 | 573 | If the program does terminal interaction, make it output a short notice like this 574 | when it starts in an interactive mode: 575 | 576 | Copyright (C) 577 | This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'. 578 | This is free software, and you are welcome to redistribute it 579 | under certain conditions; type 'show c' for details. 580 | 581 | The hypothetical commands `show w` and `show c` should show the appropriate parts of 582 | the General Public License. Of course, your program's commands might be different; 583 | for a GUI interface, you would use an “about box”. 584 | 585 | You should also get your employer (if you work as a programmer) or school, if any, to 586 | sign a “copyright disclaimer” for the program, if necessary. For more 587 | information on this, and how to apply and follow the GNU GPL, see 588 | <>. 589 | 590 | The GNU General Public License does not permit incorporating your program into 591 | proprietary programs. If your program is a subroutine library, you may consider it 592 | more useful to permit linking proprietary applications with the library. If this is 593 | what you want to do, use the GNU Lesser General Public License instead of this 594 | License. But first, please read 595 | <>. 596 | -------------------------------------------------------------------------------- /data/cosmic-mimeapps.list: -------------------------------------------------------------------------------- 1 | [Default Applications] 2 | text/plain=com.system76.CosmicEdit.desktop 3 | text/css=com.system76.CosmicEdit.desktop 4 | text/javascript=com.system76.CosmicEdit.desktop 5 | text/markdown=com.system76.CosmicEdit.desktop 6 | text/mathml=com.system76.CosmicEdit.desktop 7 | text/rust=com.system76.CosmicEdit.desktop 8 | text/x-c++hdr=com.system76.CosmicEdit.desktop 9 | text/x-c++src=com.system76.CosmicEdit.desktop 10 | text/x-csrc=com.system76.CosmicEdit.desktop 11 | text/x-chdr=com.system76.CosmicEdit.desktop 12 | text/x-dtd=com.system76.CosmicEdit.desktop 13 | text/x-java=com.system76.CosmicEdit.desktop 14 | text/x-javascript=com.system76.CosmicEdit.desktop 15 | text/x-makefile=com.system76.CosmicEdit.desktop 16 | text/x-moc=com.system76.CosmicEdit.desktop 17 | text/x-pascal=com.system76.CosmicEdit.desktop 18 | text/x-patch=com.system76.CosmicEdit.desktop 19 | text/x-perl=com.system76.CosmicEdit.desktop 20 | text/x-php=com.system76.CosmicEdit.desktop 21 | text/x-python=com.system76.CosmicEdit.desktop 22 | text/x-sql=com.system76.CosmicEdit.desktop 23 | text/x-tcl=com.system76.CosmicEdit.desktop 24 | text/x-tex=com.system76.CosmicEdit.desktop 25 | text/xml=com.system76.CosmicEdit.desktop 26 | application/javascript=com.system76.CosmicEdit.desktop 27 | application/x-cgi=com.system76.CosmicEdit.desktop 28 | application/x-javascript=com.system76.CosmicEdit.desktop 29 | application/x-perl=com.system76.CosmicEdit.desktop 30 | application/x-php=com.system76.CosmicEdit.desktop 31 | application/x-python=com.system76.CosmicEdit.desktop 32 | application/x-shellscript=com.system76.CosmicEdit.desktop 33 | application/xml=com.system76.CosmicEdit.desktop 34 | application/xml-dtd=com.system76.CosmicEdit.desktop 35 | inode/directory=com.system76.CosmicFiles.desktop 36 | inode/mount-point=com.system76.CosmicFiles.desktop 37 | application/mxf=com.system76.CosmicPlayer.desktop 38 | application/ogg=com.system76.CosmicPlayer.desktop 39 | application/ram=com.system76.CosmicPlayer.desktop 40 | application/sdp=com.system76.CosmicPlayer.desktop 41 | application/smil=com.system76.CosmicPlayer.desktop 42 | application/smil+xml=com.system76.CosmicPlayer.desktop 43 | application/vnd.ms-wpl=com.system76.CosmicPlayer.desktop 44 | application/vnd.rn-realmedia=com.system76.CosmicPlayer.desktop 45 | application/x-extension-m4a=com.system76.CosmicPlayer.desktop 46 | application/x-extension-mp4=com.system76.CosmicPlayer.desktop 47 | application/x-flac=com.system76.CosmicPlayer.desktop 48 | application/x-flash-video=com.system76.CosmicPlayer.desktop 49 | application/x-matroska=com.system76.CosmicPlayer.desktop 50 | application/x-netshow-channel=com.system76.CosmicPlayer.desktop 51 | application/x-ogg=com.system76.CosmicPlayer.desktop 52 | application/x-quicktime-media-link=com.system76.CosmicPlayer.desktop 53 | application/x-quicktimeplayer=com.system76.CosmicPlayer.desktop 54 | application/x-shorten=com.system76.CosmicPlayer.desktop 55 | application/x-smil=com.system76.CosmicPlayer.desktop 56 | application/xspf+xml=com.system76.CosmicPlayer.desktop 57 | audio/3gpp=com.system76.CosmicPlayer.desktop 58 | audio/ac3=com.system76.CosmicPlayer.desktop 59 | audio/AMR=com.system76.CosmicPlayer.desktop 60 | audio/AMR-WB=com.system76.CosmicPlayer.desktop 61 | audio/basic=com.system76.CosmicPlayer.desktop 62 | audio/flac=com.system76.CosmicPlayer.desktop 63 | audio/midi=com.system76.CosmicPlayer.desktop 64 | audio/mp4=com.system76.CosmicPlayer.desktop 65 | audio/mpeg=com.system76.CosmicPlayer.desktop 66 | audio/mpegurl=com.system76.CosmicPlayer.desktop 67 | audio/ogg=com.system76.CosmicPlayer.desktop 68 | audio/prs.sid=com.system76.CosmicPlayer.desktop 69 | audio/vnd.rn-realaudio=com.system76.CosmicPlayer.desktop 70 | audio/x-ape=com.system76.CosmicPlayer.desktop 71 | audio/x-flac=com.system76.CosmicPlayer.desktop 72 | audio/x-gsm=com.system76.CosmicPlayer.desktop 73 | audio/x-it=com.system76.CosmicPlayer.desktop 74 | audio/x-m4a=com.system76.CosmicPlayer.desktop 75 | audio/x-matroska=com.system76.CosmicPlayer.desktop 76 | audio/x-mod=com.system76.CosmicPlayer.desktop 77 | audio/x-mp3=com.system76.CosmicPlayer.desktop 78 | audio/x-mpeg=com.system76.CosmicPlayer.desktop 79 | audio/x-mpegurl=com.system76.CosmicPlayer.desktop 80 | audio/x-ms-asf=com.system76.CosmicPlayer.desktop 81 | audio/x-ms-asx=com.system76.CosmicPlayer.desktop 82 | audio/x-ms-wax=com.system76.CosmicPlayer.desktop 83 | audio/x-ms-wma=com.system76.CosmicPlayer.desktop 84 | audio/x-musepack=com.system76.CosmicPlayer.desktop 85 | audio/x-pn-aiff=com.system76.CosmicPlayer.desktop 86 | audio/x-pn-au=com.system76.CosmicPlayer.desktop 87 | audio/x-pn-realaudio=com.system76.CosmicPlayer.desktop 88 | audio/x-pn-realaudio-plugin=com.system76.CosmicPlayer.desktop 89 | audio/x-pn-wav=com.system76.CosmicPlayer.desktop 90 | audio/x-pn-windows-acm=com.system76.CosmicPlayer.desktop 91 | audio/x-realaudio=com.system76.CosmicPlayer.desktop 92 | audio/x-real-audio=com.system76.CosmicPlayer.desktop 93 | audio/x-sbc=com.system76.CosmicPlayer.desktop 94 | audio/x-scpls=com.system76.CosmicPlayer.desktop 95 | audio/x-speex=com.system76.CosmicPlayer.desktop 96 | audio/x-tta=com.system76.CosmicPlayer.desktop 97 | audio/x-vorbis=com.system76.CosmicPlayer.desktop 98 | audio/x-vorbis+ogg=com.system76.CosmicPlayer.desktop 99 | audio/x-wav=com.system76.CosmicPlayer.desktop 100 | audio/x-wavpack=com.system76.CosmicPlayer.desktop 101 | audio/x-xm=com.system76.CosmicPlayer.desktop 102 | image/vnd.rn-realpix=com.system76.CosmicPlayer.desktop 103 | image/x-pict=com.system76.CosmicPlayer.desktop 104 | misc/ultravox=com.system76.CosmicPlayer.desktop 105 | text/google-video-pointer=com.system76.CosmicPlayer.desktop 106 | text/x-google-video-pointer=com.system76.CosmicPlayer.desktop 107 | video/3gpp=com.system76.CosmicPlayer.desktop 108 | video/dv=com.system76.CosmicPlayer.desktop 109 | video/fli=com.system76.CosmicPlayer.desktop 110 | video/flv=com.system76.CosmicPlayer.desktop 111 | video/mp2t=com.system76.CosmicPlayer.desktop 112 | video/mp4=com.system76.CosmicPlayer.desktop 113 | video/mp4v-es=com.system76.CosmicPlayer.desktop 114 | video/mpeg=com.system76.CosmicPlayer.desktop 115 | video/msvideo=com.system76.CosmicPlayer.desktop 116 | video/ogg=com.system76.CosmicPlayer.desktop 117 | video/quicktime=com.system76.CosmicPlayer.desktop 118 | video/vivo=com.system76.CosmicPlayer.desktop 119 | video/vnd.divx=com.system76.CosmicPlayer.desktop 120 | video/vnd.rn-realvideo=com.system76.CosmicPlayer.desktop 121 | video/vnd.vivo=com.system76.CosmicPlayer.desktop 122 | video/webm=com.system76.CosmicPlayer.desktop 123 | video/x-anim=com.system76.CosmicPlayer.desktop 124 | video/x-avi=com.system76.CosmicPlayer.desktop 125 | video/x-flc=com.system76.CosmicPlayer.desktop 126 | video/x-fli=com.system76.CosmicPlayer.desktop 127 | video/x-flic=com.system76.CosmicPlayer.desktop 128 | video/x-flv=com.system76.CosmicPlayer.desktop 129 | video/x-m4v=com.system76.CosmicPlayer.desktop 130 | video/x-matroska=com.system76.CosmicPlayer.desktop 131 | video/x-mpeg=com.system76.CosmicPlayer.desktop 132 | video/x-ms-asf=com.system76.CosmicPlayer.desktop 133 | video/x-ms-asx=com.system76.CosmicPlayer.desktop 134 | video/x-msvideo=com.system76.CosmicPlayer.desktop 135 | video/x-ms-wm=com.system76.CosmicPlayer.desktop 136 | video/x-ms-wmv=com.system76.CosmicPlayer.desktop 137 | video/x-ms-wmx=com.system76.CosmicPlayer.desktop 138 | video/x-ms-wvx=com.system76.CosmicPlayer.desktop 139 | video/x-nsv=com.system76.CosmicPlayer.desktop 140 | video/x-ogm+ogg=com.system76.CosmicPlayer.desktop 141 | video/x-theora+ogg=com.system76.CosmicPlayer.desktop 142 | video/x-totem-stream=com.system76.CosmicPlayer.desktop 143 | x-content/video-dvd=com.system76.CosmicPlayer.desktop 144 | x-content/video-vcd=com.system76.CosmicPlayer.desktop 145 | x-content/video-svcd=com.system76.CosmicPlayer.desktop 146 | x-scheme-handler/pnm=com.system76.CosmicPlayer.desktop 147 | x-scheme-handler/mms=com.system76.CosmicPlayer.desktop 148 | x-scheme-handler/net=com.system76.CosmicPlayer.desktop 149 | x-scheme-handler/rtp=com.system76.CosmicPlayer.desktop 150 | x-scheme-handler/rtsp=com.system76.CosmicPlayer.desktop 151 | x-scheme-handler/mmsh=com.system76.CosmicPlayer.desktop 152 | x-scheme-handler/uvox=com.system76.CosmicPlayer.desktop 153 | x-scheme-handler/icy=com.system76.CosmicPlayer.desktop 154 | x-scheme-handler/icyx=com.system76.CosmicPlayer.desktop 155 | application/x-cd-image=com.system76.Popsicle.desktop 156 | application/x-raw-disk-image=com.system76.Popsicle.desktop 157 | application/x-raw-disk-image-xz-compressed=com.system76.Popsicle.desktop 158 | application/x-debian-package=com.system76.CosmicStore.desktop 159 | application/vnd.debian.binary-package=com.system76.CosmicStore.desktop 160 | application/vnd.flatpak.ref=com.system76.CosmicStore.desktop 161 | x-scheme-handler/appstream=com.system76.CosmicStore.desktop 162 | x-scheme-handler/mime=com.system76.CosmicStore.desktop 163 | image/bmp=org.gnome.eog.desktop 164 | image/gif=org.gnome.eog.desktop 165 | image/jpeg=org.gnome.eog.desktop 166 | image/jpg=org.gnome.eog.desktop 167 | image/pjpeg=org.gnome.eog.desktop 168 | image/png=org.gnome.eog.desktop 169 | image/svg+xml=org.gnome.eog.desktop 170 | image/svg+xml-compressed=org.gnome.eog.desktop 171 | image/x-bmp=org.gnome.eog.desktop 172 | image/x-gray=org.gnome.eog.desktop 173 | image/x-icb=org.gnome.eog.desktop 174 | image/x-ico=org.gnome.eog.desktop 175 | image/x-pcx=org.gnome.eog.desktop 176 | image/x-png=org.gnome.eog.desktop 177 | image/x-portable-anymap=org.gnome.eog.desktop 178 | image/x-portable-bitmap=org.gnome.eog.desktop 179 | image/x-portable-graymap=org.gnome.eog.desktop 180 | image/x-portable-pixmap=org.gnome.eog.desktop 181 | image/x-xbitmap=org.gnome.eog.desktop 182 | image/x-xpixmap=org.gnome.eog.desktop 183 | image/vnd.wap.wbmp=org.gnome.eog.desktop 184 | image/g3fax=gimp.desktop 185 | image/x-compressed-xcf=gimp.desktop 186 | image/x-fits=gimp.desktop 187 | image/x-icon=gimp.desktop 188 | image/x-psd=gimp.desktop 189 | image/x-sgi=gimp.desktop 190 | image/x-sun-raster=gimp.desktop 191 | image/x-tga=gimp.desktop 192 | image/x-xcf=gimp.desktop 193 | image/x-xwindowdump=gimp.desktop 194 | application/pdf=org.gnome.Evince.desktop 195 | application/x-bzpdf=org.gnome.Evince.desktop 196 | application/x-gzpdf=org.gnome.Evince.desktop 197 | application/postscript=org.gnome.Evince.desktop 198 | application/x-bzpostscript=org.gnome.Evince.desktop 199 | application/x-gzpostscript=org.gnome.Evince.desktop 200 | image/x-eps=org.gnome.Evince.desktop 201 | image/x-bzeps=org.gnome.Evince.desktop 202 | image/x-gzeps=org.gnome.Evince.desktop 203 | application/x-dvi=org.gnome.Evince.desktop 204 | application/x-bzdvi=org.gnome.Evince.desktop 205 | application/x-gzdvi=org.gnome.Evince.desktop 206 | image/vnd.djvu=org.gnome.Evince.desktop 207 | image/tiff=org.gnome.Evince.desktop 208 | application/x-cbr=org.gnome.Evince.desktop 209 | application/x-cbz=org.gnome.Evince.desktop 210 | application/x-cb7=org.gnome.Evince.desktop 211 | application/x-7z-compressed=org.gnome.FileRoller.desktop 212 | application/x-7z-compressed-tar=org.gnome.FileRoller.desktop 213 | application/x-ace=org.gnome.FileRoller.desktop 214 | application/x-alz=org.gnome.FileRoller.desktop 215 | application/x-ar=org.gnome.FileRoller.desktop 216 | application/x-arj=org.gnome.FileRoller.desktop 217 | application/x-bzip=org.gnome.FileRoller.desktop 218 | application/x-bzip-compressed-tar=org.gnome.FileRoller.desktop 219 | application/x-bzip1=org.gnome.FileRoller.desktop 220 | application/x-bzip1-compressed-tar=org.gnome.FileRoller.desktop 221 | application/x-cabinet=org.gnome.FileRoller.desktop 222 | application/x-compress=org.gnome.FileRoller.desktop 223 | application/x-compressed-tar=org.gnome.FileRoller.desktop 224 | application/x-cpio=org.gnome.FileRoller.desktop 225 | application/x-deb=org.gnome.FileRoller.desktop 226 | application/x-ear=org.gnome.FileRoller.desktop 227 | application/x-gtar=org.gnome.FileRoller.desktop 228 | application/x-gzip=org.gnome.FileRoller.desktop 229 | application/x-java-archive=org.gnome.FileRoller.desktop 230 | application/x-lha=org.gnome.FileRoller.desktop 231 | application/x-lhz=org.gnome.FileRoller.desktop 232 | application/x-lzip=org.gnome.FileRoller.desktop 233 | application/x-lzip-compressed-tar=org.gnome.FileRoller.desktop 234 | application/x-lzma=org.gnome.FileRoller.desktop 235 | application/x-lzma-compressed-tar=org.gnome.FileRoller.desktop 236 | application/x-lzop=org.gnome.FileRoller.desktop 237 | application/x-lzop-compressed-tar=org.gnome.FileRoller.desktop 238 | application/x-rar=org.gnome.FileRoller.desktop 239 | application/x-rar-compressed=org.gnome.FileRoller.desktop 240 | application/x-rpm=org.gnome.FileRoller.desktop 241 | application/x-rzip=org.gnome.FileRoller.desktop 242 | application/x-tar=org.gnome.FileRoller.desktop 243 | application/x-tarz=org.gnome.FileRoller.desktop 244 | application/x-stuffit=org.gnome.FileRoller.desktop 245 | application/x-war=org.gnome.FileRoller.desktop 246 | application/x-xz=org.gnome.FileRoller.desktop 247 | application/x-xz-compressed-tar=org.gnome.FileRoller.desktop 248 | application/x-zip=org.gnome.FileRoller.desktop 249 | application/x-zip-compressed=org.gnome.FileRoller.desktop 250 | application/x-zoo=org.gnome.FileRoller.desktop 251 | application/zip=org.gnome.FileRoller.desktop 252 | multipart/x-zip=org.gnome.FileRoller.desktop 253 | application/x-font-ttf=org.gnome.font-viewer.desktop 254 | application/x-font-pcf=org.gnome.font-viewer.desktop 255 | application/x-font-type1=org.gnome.font-viewer.desktop 256 | application/x-font-otf=org.gnome.font-viewer.desktop 257 | text/html=firefox-esr.desktop;firefox.desktop; 258 | application/xhtml+xml=firefox-esr.desktop;firefox.desktop; 259 | application/rss+xml=firefox-esr.desktop;firefox.desktop; 260 | application/rdf+xml=firefox-esr.desktop;firefox.desktop; 261 | x-scheme-handler/http=firefox-esr.desktop;firefox.desktop; 262 | x-scheme-handler/https=firefox-esr.desktop;firefox.desktop; 263 | application/vnd.oasis.opendocument.spreadsheet=libreoffice-calc.desktop 264 | application/vnd.oasis.opendocument.spreadsheet-flat-xml=libreoffice-calc.desktop 265 | application/vnd.oasis.opendocument.spreadsheet-template=libreoffice-calc.desktop 266 | application/vnd.sun.xml.calc=libreoffice-calc.desktop 267 | application/vnd.sun.xml.calc.template=libreoffice-calc.desktop 268 | application/msexcel=libreoffice-calc.desktop 269 | application/vnd.ms-excel=libreoffice-calc.desktop 270 | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet=libreoffice-calc.desktop 271 | application/vnd.ms-excel.sheet.macroenabled.12=libreoffice-calc.desktop 272 | application/vnd.openxmlformats-officedocument.spreadsheetml.template=libreoffice-calc.desktop 273 | application/vnd.ms-excel.template.macroenabled.12=libreoffice-calc.desktop 274 | application/vnd.ms-excel.sheet.binary.macroenabled.12=libreoffice-calc.desktop 275 | application/x-dbf=libreoffice-calc.desktop 276 | text/spreadsheet=libreoffice-calc.desktop 277 | application/vnd.oasis.opendocument.graphics=libreoffice-draw.desktop 278 | application/vnd.oasis.opendocument.graphics-flat-xml=libreoffice-draw.desktop 279 | application/vnd.oasis.opendocument.graphics-template=libreoffice-draw.desktop 280 | application/vnd.sun.xml.draw=libreoffice-draw.desktop 281 | application/vnd.sun.xml.draw.template=libreoffice-draw.desktop 282 | application/vnd.visio=libreoffice-draw.desktop 283 | application/vnd.oasis.opendocument.presentation=libreoffice-impress.desktop 284 | application/vnd.oasis.opendocument.presentation-flat-xml=libreoffice-impress.desktop 285 | application/vnd.oasis.opendocument.presentation-template=libreoffice-impress.desktop 286 | application/vnd.sun.xml.impress=libreoffice-impress.desktop 287 | application/vnd.sun.xml.impress.template=libreoffice-impress.desktop 288 | application/mspowerpoint=libreoffice-impress.desktop 289 | application/vnd.ms-powerpoint=libreoffice-impress.desktop 290 | application/vnd.openxmlformats-officedocument.presentationml.presentation=libreoffice-impress.desktop 291 | application/vnd.ms-powerpoint.presentation.macroenabled.12=libreoffice-impress.desktop 292 | application/vnd.openxmlformats-officedocument.presentationml.template=libreoffice-impress.desktop 293 | application/vnd.ms-powerpoint.template.macroenabled.12=libreoffice-impress.desktop 294 | application/vnd.openxmlformats-officedocument.presentationml.slide=libreoffice-impress.desktop 295 | application/vnd.openxmlformats-officedocument.presentationml.slideshow=libreoffice-impress.desktop 296 | application/vnd.oasis.opendocument.formula=libreoffice-math.desktop 297 | application/vnd.sun.xml.math=libreoffice-math.desktop 298 | application/vnd.oasis.opendocument.text=libreoffice-writer.desktop 299 | application/vnd.oasis.opendocument.text-flat-xml=libreoffice-writer.desktop 300 | application/vnd.oasis.opendocument.text-template=libreoffice-writer.desktop 301 | application/vnd.oasis.opendocument.text-web=libreoffice-writer.desktop 302 | application/vnd.oasis.opendocument.text-master=libreoffice-writer.desktop 303 | application/vnd.sun.xml.writer=libreoffice-writer.desktop 304 | application/vnd.sun.xml.writer.template=libreoffice-writer.desktop 305 | application/vnd.sun.xml.writer.global=libreoffice-writer.desktop 306 | eapplication/vnd.ms-word=libreoffice-writer.desktop 307 | application/x-doc=libreoffice-writer.desktop 308 | application/x-hwp=libreoffice-writer.desktop 309 | application/vnd.wordperfect=libreoffice-writer.desktop 310 | application/wordperfect=libreoffice-writer.desktop 311 | application/vnd.lotus-wordpro=libreoffice-writer.desktop 312 | application/vnd.openxmlformats-officedocument.wordprocessingml.document=libreoffice-writer.desktop 313 | application/vnd.ms-word.document.macroenabled.12=libreoffice-writer.desktop 314 | application/vnd.openxmlformats-officedocument.wordprocessingml.template=libreoffice-writer.desktop 315 | application/vnd.ms-word.template.macroenabled.12=libreoffice-writer.desktop 316 | -------------------------------------------------------------------------------- /data/cosmic-session.target: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Cosmic Session Target 3 | Documentation=man:systemd.special(7) 4 | 5 | BindsTo=graphical-session.target 6 | Before=graphical-session.target 7 | 8 | Wants=graphical-session-pre.target 9 | After=graphical-session-pre.target 10 | 11 | Wants=xdg-desktop-autostart.target 12 | Before=xdg-desktop-autostart.target 13 | -------------------------------------------------------------------------------- /data/cosmic.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=COSMIC 3 | Comment=This session logs you into the COSMIC desktop 4 | Exec=/usr/bin/start-cosmic 5 | Type=Application 6 | DesktopNames=COSMIC 7 | -------------------------------------------------------------------------------- /data/dconf/profile/cosmic: -------------------------------------------------------------------------------- 1 | user-db:cosmic 2 | user-db:user 3 | -------------------------------------------------------------------------------- /data/start-cosmic: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | # From: https://people.debian.org/~mpitt/systemd.conf-2016-graphical-session.pdf 6 | 7 | if command -v systemctl >/dev/null; then 8 | # robustness: if the previous graphical session left some failed units, 9 | # reset them so that they don't break this startup 10 | for unit in $(systemctl --user --no-legend --state=failed --plain list-units | cut -f1 -d' '); do 11 | partof="$(systemctl --user show -p PartOf --value "$unit")" 12 | for target in cosmic-session.target graphical-session.target; do 13 | if [ "$partof" = "$target" ]; then 14 | systemctl --user reset-failed "$unit" 15 | break 16 | fi 17 | done 18 | done 19 | fi 20 | 21 | # use the user's preferred shell to acquire environment variables 22 | # see: https://github.com/pop-os/cosmic-session/issues/23 23 | if [ -n "${SHELL}" ]; then 24 | # --in-login-shell: our flag to indicate that we don't need to recurse any further 25 | if [ "${1}" != "--in-login-shell" ]; then 26 | # `exec -l`: like `login`, prefixes $SHELL with a hyphen to start a login shell 27 | exec bash -c "exec -l '${SHELL}' -c '${0} --in-login-shell'" 28 | fi 29 | fi 30 | 31 | export XDG_CURRENT_DESKTOP="${XDG_CURRENT_DESKTOP:=COSMIC}" 32 | export XDG_SESSION_TYPE="${XDG_SESSION_TYPE:=wayland}" 33 | export _JAVA_AWT_WM_NONREPARENTING=1 34 | export GDK_BACKEND=wayland,x11 35 | export MOZ_ENABLE_WAYLAND=1 36 | export QT_QPA_PLATFORM="wayland;xcb" 37 | export QT_AUTO_SCREEN_SCALE_FACTOR=1 38 | export QT_ENABLE_HIGHDPI_SCALING=1 39 | export DCONF_PROFILE=cosmic 40 | 41 | if command -v dbus-update-activation-environment >/dev/null; then 42 | # set environment variables for new units started by user service manager 43 | dbus-update-activation-environment --systemd \ 44 | DCONF_PROFILE \ 45 | DISPLAY \ 46 | WAYLAND_DISPLAY \ 47 | XDG_CURRENT_DESKTOP \ 48 | XDG_SESSION_TYPE \ 49 | # EOF 50 | fi 51 | # Run cosmic-session 52 | if [[ -z "${DBUS_SESSION_BUS_ADDRESS}" ]]; then 53 | exec /usr/bin/dbus-run-session -- /usr/bin/cosmic-session 54 | else 55 | exec /usr/bin/cosmic-session 56 | fi 57 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | cosmic-session (0.1.0) UNRELEASED; urgency=medium 2 | 3 | * Initial release. 4 | 5 | -- Lucy Thu, 07 Jul 2022 14:42:01 -0400 6 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: cosmic-session 2 | Section: admin 3 | Priority: optional 4 | Maintainer: System76 5 | Build-Depends: 6 | debhelper (>= 11), 7 | debhelper-compat (= 11), 8 | cargo, 9 | just 10 | Standards-Version: 4.3.0 11 | Homepage: https://github.com/pop-os/cosmic-session 12 | 13 | Package: cosmic-session 14 | Architecture: amd64 arm64 15 | Depends: 16 | ${misc:Depends}, 17 | ${shlibs:Depends}, 18 | cosmic-app-library, 19 | cosmic-applets, 20 | cosmic-bg, 21 | cosmic-comp, 22 | cosmic-files, 23 | cosmic-greeter, 24 | cosmic-icons, 25 | cosmic-idle, 26 | cosmic-launcher, 27 | cosmic-notifications, 28 | cosmic-osd, 29 | cosmic-panel, 30 | cosmic-randr, 31 | cosmic-screenshot, 32 | cosmic-settings, 33 | cosmic-settings-daemon, 34 | cosmic-workspaces, 35 | fonts-open-sans, 36 | pop-fonts, 37 | switcheroo-control, 38 | xdg-desktop-portal-cosmic, 39 | xwayland, 40 | Recommends: 41 | cosmic-edit, 42 | cosmic-player, 43 | cosmic-store, 44 | cosmic-term, 45 | cosmic-wallpapers, 46 | system-config-printer, 47 | Description: The session for the COSMIC desktop 48 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: cosmic-session 3 | Source: https://github.com/pop-os/cosmic-session 4 | 5 | Files: * 6 | Copyright: Copyright 2022 System76 7 | License: GPL-3.0-only 8 | -------------------------------------------------------------------------------- /debian/cosmic-session.gsettings-override: -------------------------------------------------------------------------------- 1 | [org.gnome.desktop.interface:COSMIC] 2 | color-scheme = "prefer-dark" 3 | gtk-theme = "Pop-dark" 4 | icon-theme = "Pop" 5 | cursor-theme = "Pop" 6 | font-name = "Open Sans 11" 7 | document-font-name = "Open Sans 11" 8 | monospace-font-name = "Noto Sans Mono 11" 9 | titlebar-font='Open Sans Bold 11' 10 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | DESTDIR = debian/cosmic-session 4 | CLEAN ?= 1 5 | VENDOR ?= 1 6 | 7 | %: 8 | dh $@ 9 | 10 | override_dh_installgsettings: 11 | dh_installgsettings --priority=50 12 | 13 | override_dh_shlibdeps: 14 | dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info 15 | 16 | override_dh_auto_clean: 17 | if test "${CLEAN}" = "1"; then \ 18 | cargo clean; \ 19 | fi 20 | 21 | if ! ischroot && test "${VENDOR}" = "1"; then \ 22 | mkdir -p .cargo; \ 23 | cargo vendor --sync Cargo.toml | head -n -1 > .cargo/config.toml; \ 24 | echo 'directory = "vendor"' >> .cargo/config.toml; \ 25 | tar pcf vendor.tar vendor; \ 26 | rm -rf vendor; \ 27 | fi 28 | 29 | override_dh_auto_build: 30 | just rootdir=$(DESTDIR) debug=$(DEBUG) vendor=$(VENDOR) 31 | 32 | override_dh_auto_install: 33 | just rootdir=$(DESTDIR) install 34 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "crane": { 4 | "inputs": { 5 | "nixpkgs": [ 6 | "nixpkgs" 7 | ] 8 | }, 9 | "locked": { 10 | "lastModified": 1702141249, 11 | "narHash": "sha256-8wDpJKbDTDqFmyJfNEJOLrHYDoEzCjCbmz+lSRoU3CI=", 12 | "owner": "ipetkov", 13 | "repo": "crane", 14 | "rev": "62fc1a0cbe144c1014d956e603d56bf1ffe69c7d", 15 | "type": "github" 16 | }, 17 | "original": { 18 | "owner": "ipetkov", 19 | "repo": "crane", 20 | "type": "github" 21 | } 22 | }, 23 | "fenix": { 24 | "inputs": { 25 | "nixpkgs": [ 26 | "nixpkgs" 27 | ], 28 | "rust-analyzer-src": "rust-analyzer-src" 29 | }, 30 | "locked": { 31 | "lastModified": 1702189261, 32 | "narHash": "sha256-TN6gE1eZddDhAoRrScV6Wji1Nk3uqMIDjGwN5ZesAZk=", 33 | "owner": "nix-community", 34 | "repo": "fenix", 35 | "rev": "cae060dbaf53430bb2b549ced0affd54d40e6cee", 36 | "type": "github" 37 | }, 38 | "original": { 39 | "owner": "nix-community", 40 | "repo": "fenix", 41 | "type": "github" 42 | } 43 | }, 44 | "flake-utils": { 45 | "inputs": { 46 | "systems": "systems" 47 | }, 48 | "locked": { 49 | "lastModified": 1701680307, 50 | "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", 51 | "owner": "numtide", 52 | "repo": "flake-utils", 53 | "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", 54 | "type": "github" 55 | }, 56 | "original": { 57 | "owner": "numtide", 58 | "repo": "flake-utils", 59 | "type": "github" 60 | } 61 | }, 62 | "nix-filter": { 63 | "locked": { 64 | "lastModified": 1701697642, 65 | "narHash": "sha256-L217WytWZHSY8GW9Gx1A64OnNctbuDbfslaTEofXXRw=", 66 | "owner": "numtide", 67 | "repo": "nix-filter", 68 | "rev": "c843418ecfd0344ecb85844b082ff5675e02c443", 69 | "type": "github" 70 | }, 71 | "original": { 72 | "owner": "numtide", 73 | "repo": "nix-filter", 74 | "type": "github" 75 | } 76 | }, 77 | "nixpkgs": { 78 | "locked": { 79 | "lastModified": 1702206697, 80 | "narHash": "sha256-vE9oEx3Y8TO5MnWwFlmopjHd1JoEBno+EhsfUCq5iR8=", 81 | "owner": "NixOS", 82 | "repo": "nixpkgs", 83 | "rev": "29d6c96900b9b576c2fb89491452f283aa979819", 84 | "type": "github" 85 | }, 86 | "original": { 87 | "owner": "NixOS", 88 | "ref": "nixpkgs-unstable", 89 | "repo": "nixpkgs", 90 | "type": "github" 91 | } 92 | }, 93 | "root": { 94 | "inputs": { 95 | "crane": "crane", 96 | "fenix": "fenix", 97 | "flake-utils": "flake-utils", 98 | "nix-filter": "nix-filter", 99 | "nixpkgs": "nixpkgs" 100 | } 101 | }, 102 | "rust-analyzer-src": { 103 | "flake": false, 104 | "locked": { 105 | "lastModified": 1702153490, 106 | "narHash": "sha256-F98s0+mUHtqiUk9iCApPTy23YMLmcKqTfsShpIPB40Q=", 107 | "owner": "rust-lang", 108 | "repo": "rust-analyzer", 109 | "rev": "9d87a23cdef6087c1a0c97980949e2310271a941", 110 | "type": "github" 111 | }, 112 | "original": { 113 | "owner": "rust-lang", 114 | "ref": "nightly", 115 | "repo": "rust-analyzer", 116 | "type": "github" 117 | } 118 | }, 119 | "systems": { 120 | "locked": { 121 | "lastModified": 1681028828, 122 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 123 | "owner": "nix-systems", 124 | "repo": "default", 125 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 126 | "type": "github" 127 | }, 128 | "original": { 129 | "owner": "nix-systems", 130 | "repo": "default", 131 | "type": "github" 132 | } 133 | } 134 | }, 135 | "root": "root", 136 | "version": 7 137 | } 138 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "Session manager for the COSMIC desktop environment"; 3 | 4 | inputs = { 5 | nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 6 | flake-utils.url = "github:numtide/flake-utils"; 7 | nix-filter.url = "github:numtide/nix-filter"; 8 | crane = { 9 | url = "github:ipetkov/crane"; 10 | inputs.nixpkgs.follows = "nixpkgs"; 11 | }; 12 | fenix = { 13 | url = "github:nix-community/fenix"; 14 | inputs.nixpkgs.follows = "nixpkgs"; 15 | }; 16 | }; 17 | 18 | outputs = { self, nixpkgs, flake-utils, nix-filter, crane, fenix }: 19 | flake-utils.lib.eachSystem [ "x86_64-linux" "aarch64-linux" ] (system: 20 | let 21 | pkgs = nixpkgs.legacyPackages.${system}; 22 | craneLib = crane.lib.${system}.overrideToolchain fenix.packages.${system}.stable.toolchain; 23 | 24 | pkgDef = { 25 | nativeBuildInputs = with pkgs; [ just pkg-config autoPatchelfHook ]; 26 | buildInputs = with pkgs; [ 27 | stdenv.cc.cc.lib 28 | ]; 29 | src = nix-filter.lib.filter { 30 | root = ./.; 31 | include = [ 32 | ./src 33 | ./Cargo.toml 34 | ./Cargo.lock 35 | ./Justfile 36 | ./data 37 | ]; 38 | }; 39 | }; 40 | 41 | cargoArtifacts = craneLib.buildDepsOnly pkgDef; 42 | cosmic-session = craneLib.buildPackage (pkgDef // { 43 | inherit cargoArtifacts; 44 | }); 45 | in { 46 | checks = { 47 | inherit cosmic-session; 48 | }; 49 | 50 | packages.default = cosmic-session.overrideAttrs (oldAttrs: rec { 51 | buildPhase = '' 52 | just prefix=$out xdp_cosmic=/run/current-system/sw/bin/xdg-desktop-portal-cosmic build 53 | ''; 54 | installPhase = '' 55 | runHook preInstallPhase 56 | just prefix=$out install 57 | ''; 58 | preInstallPhase = '' 59 | substituteInPlace data/start-cosmic --replace '#!/bin/bash' "#!${pkgs.bash}/bin/bash" 60 | substituteInPlace data/start-cosmic --replace '/usr/bin/cosmic-session' "${placeholder "out"}/bin/cosmic-session" 61 | substituteInPlace data/start-cosmic --replace '/usr/bin/dbus-run-session' "${pkgs.dbus}/bin/dbus-run-session" 62 | substituteInPlace data/cosmic.desktop --replace '/usr/bin/start-cosmic' "${placeholder "out"}/bin/start-cosmic" 63 | ''; 64 | passthru.providedSessions = [ "cosmic" ]; 65 | }); 66 | 67 | apps.default = flake-utils.lib.mkApp { 68 | drv = cosmic-session; 69 | }; 70 | 71 | devShells.default = pkgs.mkShell { 72 | inputsFrom = builtins.attrValues self.checks.${system}; 73 | }; 74 | }); 75 | 76 | nixConfig = { 77 | # Cache for the Rust toolchain in fenix 78 | extra-substituters = [ "https://nix-community.cachix.org" ]; 79 | extra-trusted-public-keys = [ "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" ]; 80 | }; 81 | } 82 | -------------------------------------------------------------------------------- /src/a11y.rs: -------------------------------------------------------------------------------- 1 | use futures_util::StreamExt; 2 | use launch_pad::ProcessManager; 3 | use tokio::sync::mpsc; 4 | use tracing::Instrument; 5 | 6 | const ORCA: Option<&'static str> = option_env!("ORCA"); 7 | 8 | pub async fn start_a11y( 9 | env_vars: Vec<(String, String)>, 10 | pman: ProcessManager, 11 | ) -> color_eyre::Result<()> { 12 | let (tx, mut rx) = mpsc::unbounded_channel(); 13 | let mut process_key = None; 14 | let conn = zbus::Connection::session().await?; 15 | let proxy = cosmic_dbus_a11y::StatusProxy::new(&conn).await?; 16 | 17 | tokio::spawn(async move { 18 | let mut watch_changes = proxy.receive_screen_reader_enabled_changed().await; 19 | let mut enabled = false; 20 | if let Ok(status) = proxy.screen_reader_enabled().await { 21 | _ = tx.send(status); 22 | 23 | enabled = status; 24 | } 25 | while let Some(change) = watch_changes.next().await { 26 | let Ok(new_enabled) = change.get().await else { 27 | tokio::time::sleep(tokio::time::Duration::from_secs(10)).await; 28 | continue; 29 | }; 30 | if enabled != new_enabled { 31 | _ = tx.send(new_enabled); 32 | enabled = new_enabled; 33 | } 34 | } 35 | }); 36 | 37 | while let Some(enabled) = rx.recv().await { 38 | let stdout_span = info_span!(parent: None, "screen-reader"); 39 | let stderr_span = stdout_span.clone(); 40 | if enabled && process_key.is_none() { 41 | // spawn orca 42 | match pman 43 | .start( 44 | launch_pad::process::Process::new() 45 | .with_executable(ORCA.unwrap_or("/usr/bin/orca")) 46 | .with_env(env_vars.clone()) 47 | .with_on_stdout(move |_, _, line| { 48 | let stdout_span = stdout_span.clone(); 49 | async move { 50 | info!("{}", line); 51 | } 52 | .instrument(stdout_span) 53 | }) 54 | .with_on_stderr(move |_, _, line| { 55 | let stderr_span = stderr_span.clone(); 56 | async move { 57 | warn!("{}", line); 58 | } 59 | .instrument(stderr_span) 60 | }), 61 | ) 62 | .await 63 | { 64 | Ok(key) => { 65 | process_key = Some(key); 66 | } 67 | Err(err) => { 68 | tracing::error!("Failed to start screen reader {err:?}"); 69 | } 70 | } 71 | } else if !enabled && process_key.is_some() { 72 | // kill orca 73 | info!("Stopping screen reader"); 74 | if let Err(err) = pman.stop_process(process_key.take().unwrap()).await { 75 | tracing::error!("Failed to stop screen reader. {err:?}") 76 | } 77 | } 78 | } 79 | Ok(()) 80 | } 81 | -------------------------------------------------------------------------------- /src/comp.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-only 2 | use color_eyre::eyre::{Result, WrapErr}; 3 | use launch_pad::{process::Process, ProcessManager}; 4 | use sendfd::SendWithFd; 5 | use serde::{Deserialize, Serialize}; 6 | use std::{collections::HashMap, os::unix::prelude::*}; 7 | use tokio::{ 8 | io::{AsyncReadExt, AsyncWriteExt}, 9 | net::{ 10 | unix::{OwnedReadHalf, OwnedWriteHalf}, 11 | UnixStream, 12 | }, 13 | sync::{mpsc, oneshot}, 14 | task::JoinHandle, 15 | }; 16 | use tokio_util::sync::CancellationToken; 17 | 18 | use crate::{process::mark_as_not_cloexec, service::SessionRequest}; 19 | 20 | #[derive(Debug, Serialize, Deserialize)] 21 | #[serde(rename_all = "snake_case", tag = "message")] 22 | pub enum Message { 23 | SetEnv { variables: HashMap }, 24 | NewPrivilegedClient { count: usize }, 25 | } 26 | 27 | // Cancellation safe! 28 | #[derive(Default)] 29 | struct IpcState { 30 | env_tx: Option>>, 31 | length: Option, 32 | bytes_read: usize, 33 | buf: Vec, 34 | } 35 | 36 | fn parse_and_handle_ipc(state: &mut IpcState) { 37 | match serde_json::from_slice::(&state.buf) { 38 | Ok(Message::SetEnv { variables }) => { 39 | if let Some(env_tx) = state.env_tx.take() { 40 | env_tx.send(variables).unwrap(); 41 | } 42 | } 43 | Ok(Message::NewPrivilegedClient { .. }) => { 44 | unreachable!("NewPrivilegedClient should not be sent TO the session!"); 45 | } 46 | Err(_) => { 47 | warn!( 48 | "Unknown session socket message, are you using incompatible cosmic-session and \ 49 | cosmic-comp versions?" 50 | ) 51 | } 52 | } 53 | } 54 | 55 | async fn receive_ipc(state: &mut IpcState, rx: &mut OwnedReadHalf) -> Result<()> { 56 | // This is kind of a doozy, but this is kinda complex so it can be 57 | // cancellation-safe. 58 | match state.length { 59 | // We already got the length, and are currently reading the message body. 60 | Some(length) => { 61 | let index = state.bytes_read.saturating_sub(1); 62 | // Add the amount of bytes read to our state. 63 | // I don't think this is entirely cancellation safe, which worries me. 64 | state.bytes_read += rx 65 | .read_exact(&mut state.buf[index..]) 66 | .await 67 | .wrap_err("failed to read IPC length")?; 68 | // If we've read enough bytes, parse the message. 69 | if state.bytes_read >= length as usize { 70 | parse_and_handle_ipc(state); 71 | // Set the state back to the default "waiting for a length" mode. 72 | state.length = None; 73 | state.bytes_read = 0; 74 | state.buf.clear(); 75 | } 76 | Ok(()) 77 | } 78 | None => { 79 | // Resize the state buffer enough to fit a u16./ 80 | state.buf.resize(2, 0); 81 | let index = state.bytes_read.saturating_sub(1); 82 | // Read the remaining bytes of the length. 83 | state.bytes_read += rx 84 | .read_exact(&mut state.buf[index..]) 85 | .await 86 | .wrap_err("failed to read IPC length")?; 87 | // If we've read two bytes, then parse a native-endian u16 from them. 88 | if state.bytes_read >= 2 { 89 | let length = u16::from_ne_bytes( 90 | state.buf[..2] 91 | .try_into() 92 | .wrap_err("failed to convert IPC length to u16")?, 93 | ); 94 | // Set the state to "reading the message body" mode, as we now have the length. 95 | state.length = Some(length); 96 | state.bytes_read = 0; 97 | state.buf.resize(length as usize, 0); 98 | } 99 | Ok(()) 100 | } 101 | } 102 | } 103 | 104 | pub fn create_privileged_socket( 105 | sockets: &mut Vec, 106 | env_vars: &[(String, String)], 107 | ) -> Result<(Vec<(String, String)>, OwnedFd)> { 108 | // Create a new pair of unnamed Unix sockets 109 | let (comp_socket, client_socket) = 110 | UnixStream::pair().wrap_err("failed to create socket pair")?; 111 | // Push one socket to the list of sockets we were passed 112 | sockets.push(comp_socket); 113 | // Turn the other socket into a non-blocking fd, which we can pass to the child 114 | // process 115 | let client_fd = { 116 | let std_stream = client_socket 117 | .into_std() 118 | .wrap_err("failed to convert client socket to std socket")?; 119 | std_stream 120 | .set_nonblocking(true) 121 | .wrap_err("failed to mark client socket as non-blocking")?; 122 | OwnedFd::from(std_stream) 123 | }; 124 | let mut env_vars = env_vars.to_vec(); 125 | env_vars.push(("WAYLAND_SOCKET".into(), client_fd.as_raw_fd().to_string())); 126 | Ok((env_vars, client_fd)) 127 | } 128 | 129 | async fn send_fd(session_tx: &mut OwnedWriteHalf, stream: Vec) -> Result<()> { 130 | // Turn our list of Unix streams into non-blocking file descriptors. 131 | let fds = stream 132 | .into_iter() 133 | .map(|stream| { 134 | let std_stream = stream 135 | .into_std() 136 | .wrap_err("failed to convert stream to std stream")?; 137 | std_stream 138 | .set_nonblocking(false) 139 | .wrap_err("failed to set stream as blocking")?; 140 | Ok(OwnedFd::from(std_stream)) 141 | }) 142 | .collect::>>() 143 | .wrap_err("failed to convert streams to file descriptors")?; 144 | // Create a NewPrivilegedClient message, with a count of how many file 145 | // descriptors we are about to send. 146 | let json = serde_json::to_string(&Message::NewPrivilegedClient { count: fds.len() }) 147 | .wrap_err("failed to encode json")?; 148 | // Send the length of our NewPrivilegedClient message. 149 | session_tx 150 | .write_all(&(json.len() as u16).to_le_bytes()) 151 | .await 152 | .wrap_err("failed to write length")?; 153 | // Send our NewPrivilegedClient message, in JSON form. 154 | session_tx 155 | .write_all(json.as_bytes()) 156 | .await 157 | .wrap_err("failed to write json")?; 158 | // Wait 100 us for the session to acknowledge our message. 159 | tokio::time::sleep(std::time::Duration::from_micros(100)).await; 160 | // Send our file descriptors. 161 | let fd: &UnixStream = session_tx.as_ref(); 162 | info!("sending {} fds", fds.len()); 163 | 164 | fd.send_with_fd( 165 | &[0], 166 | &fds.into_iter() 167 | .map(|fd| fd.into_raw_fd()) 168 | .collect::>(), 169 | ) 170 | .wrap_err("failed to send fd")?; 171 | Ok(()) 172 | } 173 | 174 | pub fn run_compositor( 175 | process_manager: &ProcessManager, 176 | exec: String, 177 | args: Vec, 178 | _token: CancellationToken, 179 | mut socket_rx: mpsc::UnboundedReceiver>, 180 | env_tx: oneshot::Sender>, 181 | session_dbus_tx: mpsc::Sender, 182 | ) -> Result>> { 183 | let process_manager = process_manager.clone(); 184 | // Create a pair of unix sockets - one for us (session), 185 | // one for the compositor (comp) 186 | let (session, comp) = UnixStream::pair().wrap_err("failed to create pair of unix sockets")?; 187 | let (mut session_rx, mut session_tx) = session.into_split(); 188 | // Convert our compositor socket to a non-blocking file descriptor. 189 | let comp = { 190 | let std_stream = comp 191 | .into_std() 192 | .wrap_err("failed to convert compositor unix stream to a standard unix stream")?; 193 | std_stream 194 | .set_nonblocking(false) 195 | .wrap_err("failed to mark compositor unix stream as blocking")?; 196 | OwnedFd::from(std_stream) 197 | }; 198 | mark_as_not_cloexec(&comp).expect("Failed to mark fd as not cloexec"); 199 | Ok(tokio::spawn(async move { 200 | // Create a new process handler for cosmic-comp, with our compositor socket's 201 | // file descriptor as the `COSMIC_SESSION_SOCK` environment variable. 202 | process_manager 203 | .start_process( 204 | Process::new() 205 | .with_executable(exec) 206 | .with_args(args) 207 | .with_env([("COSMIC_SESSION_SOCK", comp.as_raw_fd().to_string())]) 208 | .with_on_exit(move |pman, _, err_code, _will_restart| { 209 | let session_dbus_tx = session_dbus_tx.clone(); 210 | async move { 211 | pman.stop(); 212 | if err_code == Some(0) { 213 | info!("cosmic-comp exited successfully"); 214 | session_dbus_tx.send(SessionRequest::Exit).await.unwrap(); 215 | } else if let Some(err_code) = err_code { 216 | error!("cosmic-comp exited with error code {}", err_code); 217 | session_dbus_tx.send(SessionRequest::Restart).await.unwrap(); 218 | } else { 219 | warn!("cosmic-comp exited by signal"); 220 | session_dbus_tx.send(SessionRequest::Restart).await.unwrap(); 221 | } 222 | } 223 | }), 224 | ) 225 | .await 226 | .expect("failed to launch compositor"); 227 | // Create a new state object for IPC purposes. 228 | let mut ipc_state = IpcState { 229 | env_tx: Some(env_tx), 230 | ..IpcState::default() 231 | }; 232 | loop { 233 | tokio::select! { 234 | /* 235 | exit = receive_event(&mut rx) => if exit.is_none() { 236 | break; 237 | }, 238 | */ 239 | // Receive IPC messages from the process, 240 | // exiting the loop if IPC errors. 241 | result = receive_ipc(&mut ipc_state, &mut session_rx) => if let Err(err) = result { 242 | error!("failed to receive IPC: {:?}", err); 243 | break; 244 | }, 245 | // Send any file descriptors we need to the compositor. 246 | Some(socket) = socket_rx.recv() => { 247 | send_fd(&mut session_tx, socket) 248 | .await 249 | .wrap_err("failed to send file descriptor to compositor")?; 250 | } 251 | } 252 | } 253 | Result::<()>::Ok(()) 254 | })) 255 | } 256 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-only 2 | #[macro_use] 3 | extern crate tracing; 4 | 5 | mod a11y; 6 | mod comp; 7 | mod notifications; 8 | mod process; 9 | mod service; 10 | mod systemd; 11 | 12 | use async_signals::Signals; 13 | use color_eyre::{eyre::WrapErr, Result}; 14 | use comp::create_privileged_socket; 15 | use cosmic_notifications_util::{DAEMON_NOTIFICATIONS_FD, PANEL_NOTIFICATIONS_FD}; 16 | use futures_util::StreamExt; 17 | #[cfg(feature = "autostart")] 18 | use itertools::Itertools; 19 | use launch_pad::{process::Process, ProcessManager}; 20 | use service::SessionRequest; 21 | #[cfg(feature = "autostart")] 22 | use std::collections::HashSet; 23 | #[cfg(feature = "autostart")] 24 | use std::path::PathBuf; 25 | #[cfg(feature = "autostart")] 26 | use std::process::{Command, Stdio}; 27 | use std::{ 28 | borrow::Cow, 29 | env, 30 | os::fd::{AsRawFd, OwnedFd}, 31 | sync::Arc, 32 | }; 33 | #[cfg(feature = "systemd")] 34 | use systemd::{get_systemd_env, is_systemd_used, spawn_scope}; 35 | use tokio::{ 36 | net::UnixStream, 37 | sync::{ 38 | mpsc::{self, Receiver, Sender}, 39 | oneshot, Mutex, 40 | }, 41 | time::Duration, 42 | }; 43 | use tokio_util::sync::CancellationToken; 44 | use tracing::{metadata::LevelFilter, Instrument}; 45 | use tracing_subscriber::{fmt, prelude::*, EnvFilter}; 46 | use zbus::ConnectionBuilder; 47 | 48 | use crate::notifications::notifications_process; 49 | const XDP_COSMIC: Option<&'static str> = option_env!("XDP_COSMIC"); 50 | #[cfg(feature = "autostart")] 51 | const AUTOSTART_DIR: &'static str = "autostart"; 52 | #[cfg(feature = "autostart")] 53 | const ENVIRONMENT_NAME: &'static str = "COSMIC"; 54 | 55 | #[tokio::main(flavor = "current_thread")] 56 | async fn main() -> Result<()> { 57 | color_eyre::install().wrap_err("failed to install color_eyre error handler")?; 58 | 59 | let trace = tracing_subscriber::registry(); 60 | let env_filter = EnvFilter::builder() 61 | .with_default_directive(LevelFilter::INFO.into()) 62 | .from_env_lossy(); 63 | 64 | #[cfg(feature = "systemd")] 65 | if let Ok(journald) = tracing_journald::layer() { 66 | trace 67 | .with(journald) 68 | .with(fmt::layer()) 69 | .with(env_filter) 70 | .try_init() 71 | .wrap_err("failed to initialize logger")?; 72 | } else { 73 | trace 74 | .with(fmt::layer()) 75 | .with(env_filter) 76 | .try_init() 77 | .wrap_err("failed to initialize logger")?; 78 | warn!("failed to connect to journald") 79 | } 80 | 81 | #[cfg(not(feature = "systemd"))] 82 | trace 83 | .with(fmt::layer()) 84 | .with(env_filter) 85 | .try_init() 86 | .wrap_err("failed to initialize logger")?; 87 | 88 | log_panics::init(); 89 | 90 | let (session_tx, mut session_rx) = tokio::sync::mpsc::channel(10); 91 | let session_tx_clone = session_tx.clone(); 92 | let _conn = ConnectionBuilder::session()? 93 | .name("com.system76.CosmicSession")? 94 | .serve_at( 95 | "/com/system76/CosmicSession", 96 | service::SessionService { session_tx }, 97 | )? 98 | .build() 99 | .await?; 100 | 101 | loop { 102 | match start(session_tx_clone.clone(), &mut session_rx).await { 103 | Ok(Status::Exited) => { 104 | info!("Exited cleanly"); 105 | break; 106 | } 107 | Ok(Status::Restarted) => { 108 | info!("Restarting"); 109 | } 110 | Err(error) => { 111 | error!("Restarting after error: {:?}", error); 112 | } 113 | }; 114 | // Drain the session channel. 115 | while session_rx.try_recv().is_ok() {} 116 | } 117 | Ok(()) 118 | } 119 | 120 | #[derive(Debug)] 121 | pub enum Status { 122 | Restarted, 123 | Exited, 124 | } 125 | 126 | async fn start( 127 | session_tx: Sender, 128 | session_rx: &mut Receiver, 129 | ) -> Result { 130 | info!("Starting cosmic-session"); 131 | 132 | let mut args = env::args().skip(1); 133 | let (executable, args) = ( 134 | args.next().unwrap_or_else(|| String::from("cosmic-comp")), 135 | args.collect::>(), 136 | ); 137 | 138 | let process_manager = ProcessManager::new().await; 139 | _ = process_manager.set_max_restarts(usize::MAX).await; 140 | _ = process_manager 141 | .set_restart_mode(launch_pad::RestartMode::ExponentialBackoff( 142 | Duration::from_millis(10), 143 | )) 144 | .await; 145 | let token = CancellationToken::new(); 146 | let (socket_tx, socket_rx) = mpsc::unbounded_channel(); 147 | let (env_tx, env_rx) = oneshot::channel(); 148 | let compositor_handle = comp::run_compositor( 149 | &process_manager, 150 | executable.clone(), 151 | args, 152 | token.child_token(), 153 | socket_rx, 154 | env_tx, 155 | session_tx, 156 | ) 157 | .wrap_err("failed to start compositor")?; 158 | 159 | let mut env_vars = env_rx 160 | .await 161 | .expect("failed to receive environmental variables") 162 | .into_iter() 163 | .collect::>(); 164 | info!( 165 | "got environmental variables from cosmic-comp: {:?}", 166 | env_vars 167 | ); 168 | 169 | // now that cosmic-comp is ready, set XDG_SESSION_TYPE=wayland for new processes 170 | std::env::set_var("XDG_SESSION_TYPE", "wayland"); 171 | env_vars.push(("XDG_SESSION_TYPE".to_string(), "wayland".to_string())); 172 | systemd::set_systemd_environment("XDG_SESSION_TYPE", "wayland").await; 173 | 174 | #[cfg(feature = "systemd")] 175 | if *is_systemd_used() { 176 | match get_systemd_env().await { 177 | Ok(env) => { 178 | for systemd_env in env { 179 | // Only update the envvar if unset 180 | if std::env::var_os(&systemd_env.key) == None { 181 | // Blacklist of envvars that we shouldn't touch (taken from KDE) 182 | if (!systemd_env.key.starts_with("XDG_") 183 | || systemd_env.key == "XDG_DATA_DIRS" 184 | || systemd_env.key == "XDG_CONFIG_DIRS") 185 | && systemd_env.key != "DISPLAY" 186 | && systemd_env.key != "XAUTHORITY" 187 | && systemd_env.key != "WAYLAND_DISPLAY" 188 | && systemd_env.key != "WAYLAND_SOCKET" 189 | && systemd_env.key != "_" 190 | && systemd_env.key != "SHELL" 191 | && systemd_env.key != "SHLVL" 192 | { 193 | std::env::set_var(systemd_env.key, systemd_env.value); 194 | } 195 | } 196 | } 197 | } 198 | Err(err) => { 199 | warn!("Failed to sync systemd environment {}.", err); 200 | } 201 | } 202 | } 203 | 204 | let stdout_span = info_span!(parent: None, "cosmic-settings-daemon"); 205 | let stderr_span = stdout_span.clone(); 206 | let (settings_exit_tx, settings_exit_rx) = oneshot::channel(); 207 | let settings_exit_tx = Arc::new(std::sync::Mutex::new(Some(settings_exit_tx))); 208 | let settings_daemon = process_manager 209 | .start( 210 | Process::new() 211 | .with_executable("cosmic-settings-daemon") 212 | .with_on_stdout(move |_, _, line| { 213 | let stdout_span = stdout_span.clone(); 214 | async move { 215 | info!("{}", line); 216 | } 217 | .instrument(stdout_span) 218 | }) 219 | .with_on_stderr(move |_, _, line| { 220 | let stderr_span = stderr_span.clone(); 221 | async move { 222 | warn!("{}", line); 223 | } 224 | .instrument(stderr_span) 225 | }) 226 | .with_on_exit(move |_, _, _, will_restart| { 227 | if !will_restart { 228 | if let Some(tx) = settings_exit_tx.lock().unwrap().take() { 229 | _ = tx.send(()); 230 | } 231 | } 232 | async {} 233 | }), 234 | ) 235 | .await 236 | .expect("failed to start settings daemon"); 237 | 238 | // notifying the user service manager that we've reached the 239 | // graphical-session.target, which should only happen after: 240 | // - cosmic-comp is ready 241 | // - we've set any related variables 242 | // - cosmic-settings-daemon is ready 243 | systemd::start_systemd_target().await; 244 | // Always stop the target when the process exits or panics. 245 | scopeguard::defer! { 246 | systemd::stop_systemd_target(); 247 | } 248 | 249 | // start a11y if configured 250 | tokio::spawn(a11y::start_a11y(env_vars.clone(), process_manager.clone())); 251 | 252 | let (panel_notifications_fd, daemon_notifications_fd) = 253 | notifications::create_socket().expect("Failed to create notification socket"); 254 | 255 | let mut daemon_env_vars = env_vars.clone(); 256 | daemon_env_vars.push(( 257 | DAEMON_NOTIFICATIONS_FD.to_string(), 258 | daemon_notifications_fd.as_raw_fd().to_string(), 259 | )); 260 | let mut panel_env_vars = env_vars.clone(); 261 | panel_env_vars.push(( 262 | PANEL_NOTIFICATIONS_FD.to_string(), 263 | panel_notifications_fd.as_raw_fd().to_string(), 264 | )); 265 | 266 | let panel_key = Arc::new(Mutex::new(None)); 267 | let notif_key = Arc::new(Mutex::new(None)); 268 | 269 | let notifications_span = info_span!(parent: None, "cosmic-notifications"); 270 | let panel_span = info_span!(parent: None, "cosmic-panel"); 271 | 272 | let mut guard = notif_key.lock().await; 273 | *guard = Some( 274 | process_manager 275 | .start(notifications_process( 276 | notifications_span.clone(), 277 | "cosmic-notifications", 278 | notif_key.clone(), 279 | daemon_env_vars.clone(), 280 | daemon_notifications_fd, 281 | panel_span.clone(), 282 | "cosmic-panel", 283 | panel_key.clone(), 284 | panel_env_vars.clone(), 285 | socket_tx.clone(), 286 | )) 287 | .await 288 | .expect("failed to start notifications daemon"), 289 | ); 290 | drop(guard); 291 | 292 | let mut guard = panel_key.lock().await; 293 | *guard = Some( 294 | process_manager 295 | .start(notifications_process( 296 | panel_span, 297 | "cosmic-panel", 298 | panel_key.clone(), 299 | panel_env_vars, 300 | panel_notifications_fd, 301 | notifications_span, 302 | "cosmic-notifications", 303 | notif_key, 304 | daemon_env_vars, 305 | socket_tx.clone(), 306 | )) 307 | .await 308 | .expect("failed to start panel"), 309 | ); 310 | drop(guard); 311 | 312 | let span = info_span!(parent: None, "cosmic-app-library"); 313 | start_component( 314 | "cosmic-app-library", 315 | span, 316 | &process_manager, 317 | &env_vars, 318 | &socket_tx, 319 | Vec::new(), 320 | ) 321 | .await; 322 | 323 | let span = info_span!(parent: None, "cosmic-launcher"); 324 | start_component( 325 | "cosmic-launcher", 326 | span, 327 | &process_manager, 328 | &env_vars, 329 | &socket_tx, 330 | Vec::new(), 331 | ) 332 | .await; 333 | 334 | let span = info_span!(parent: None, "cosmic-workspaces"); 335 | start_component( 336 | "cosmic-workspaces", 337 | span, 338 | &process_manager, 339 | &env_vars, 340 | &socket_tx, 341 | Vec::new(), 342 | ) 343 | .await; 344 | 345 | let span = info_span!(parent: None, "cosmic-osd"); 346 | start_component( 347 | "cosmic-osd", 348 | span, 349 | &process_manager, 350 | &env_vars, 351 | &socket_tx, 352 | Vec::new(), 353 | ) 354 | .await; 355 | 356 | let span = info_span!(parent: None, "cosmic-bg"); 357 | start_component( 358 | "cosmic-bg", 359 | span, 360 | &process_manager, 361 | &env_vars, 362 | &socket_tx, 363 | Vec::new(), 364 | ) 365 | .await; 366 | 367 | let span = info_span!(parent: None, "cosmic-greeter"); 368 | start_component( 369 | "cosmic-greeter", 370 | span, 371 | &process_manager, 372 | &env_vars, 373 | &socket_tx, 374 | Vec::new(), 375 | ) 376 | .await; 377 | 378 | let span = info_span!(parent: None, "cosmic-files-applet"); 379 | start_component( 380 | "cosmic-files-applet", 381 | span, 382 | &process_manager, 383 | &env_vars, 384 | &socket_tx, 385 | Vec::new(), 386 | ) 387 | .await; 388 | 389 | let span = info_span!(parent: None, "cosmic-idle"); 390 | start_component( 391 | "cosmic-idle", 392 | span, 393 | &process_manager, 394 | &env_vars, 395 | &socket_tx, 396 | Vec::new(), 397 | ) 398 | .await; 399 | 400 | if env::var("XDG_CURRENT_DESKTOP").as_deref() == Ok("COSMIC") { 401 | let span = info_span!(parent: None, "xdg-desktop-portal-cosmic"); 402 | let mut sockets = Vec::with_capacity(1); 403 | let extra_env = Vec::with_capacity(1); 404 | let portal_extras = 405 | if let Ok((mut env, fd)) = create_privileged_socket(&mut sockets, &extra_env) { 406 | let mut env = env.remove(0); 407 | env.0 = "PORTAL_WAYLAND_SOCKET".to_string(); 408 | vec![(fd, env, sockets.remove(0))] 409 | } else { 410 | Vec::new() 411 | }; 412 | start_component( 413 | XDP_COSMIC.unwrap_or("/usr/libexec/xdg-desktop-portal-cosmic"), 414 | span, 415 | &process_manager, 416 | &env_vars, 417 | &socket_tx, 418 | portal_extras, 419 | ) 420 | .await; 421 | } 422 | 423 | #[cfg(feature = "autostart")] 424 | if !*is_systemd_used() { 425 | info!("looking for autostart folders"); 426 | let mut directories_to_scan = Vec::new(); 427 | 428 | // we start by taking user specific directories, so that we can deduplicate and ensure 429 | // user overrides are respected 430 | 431 | // user specific directories 432 | if let Some(user_config_dir) = dirs::config_dir() { 433 | directories_to_scan.push(user_config_dir.join(AUTOSTART_DIR)); 434 | } 435 | 436 | // system-wide directories 437 | if let Some(xdg_config_dirs) = env::var_os("XDG_CONFIG_DIRS") { 438 | let xdg_config_dirs = xdg_config_dirs 439 | .into_string() 440 | .expect("Invalid XDG_CONFIG_DIRS"); 441 | let dir_list = xdg_config_dirs.split(":"); 442 | 443 | for dir in dir_list { 444 | directories_to_scan.push(PathBuf::from(dir).join(AUTOSTART_DIR)); 445 | } 446 | } else { 447 | directories_to_scan.push(PathBuf::from("/etc/xdg/").join(AUTOSTART_DIR)); 448 | } 449 | 450 | info!("found autostart folders: {:?}", directories_to_scan); 451 | 452 | let mut dedupe = HashSet::new(); 453 | 454 | let iter = freedesktop_desktop_entry::Iter::new(directories_to_scan.into_iter()); 455 | let autostart_env = env_vars.clone(); 456 | for entry in iter.entries::<&str>(None) { 457 | // we've already tried to execute this! 458 | if dedupe.contains(&entry.appid) { 459 | continue; 460 | } 461 | 462 | // skip if we have an OnlyShowIn entry that doesn't include COSMIC 463 | if let Some(only_show_in) = entry.only_show_in() { 464 | if !only_show_in.contains(&ENVIRONMENT_NAME) { 465 | continue; 466 | } 467 | } 468 | 469 | // ... OR we have a NotShowIn entry that includes COSMIC 470 | if let Some(not_show_in) = entry.not_show_in() { 471 | if not_show_in.contains(&ENVIRONMENT_NAME) { 472 | continue; 473 | } 474 | } 475 | 476 | info!( 477 | "trying to start appid {} ({})", 478 | entry.appid, 479 | entry.path.display() 480 | ); 481 | 482 | if let Some(exec_raw) = entry.exec() { 483 | let mut exec_words = exec_raw.split(" "); 484 | 485 | if let Some(program_name) = exec_words.next() { 486 | // filter out any placeholder args, since we might not be able to deal with them 487 | let filtered_args = exec_words.filter(|s| !s.starts_with("%")).collect_vec(); 488 | 489 | // escape them 490 | let escaped_args = shell_words::split(&*filtered_args.join(" ")); 491 | if let Ok(args) = escaped_args { 492 | info!("trying to start {} {}", program_name, args.join(" ")); 493 | 494 | let mut command = Command::new(program_name); 495 | command.args(args); 496 | 497 | // add relevant envs 498 | for (k, v) in &autostart_env { 499 | command.env(k, v); 500 | } 501 | 502 | // detach stdin/out/err (should we?) 503 | let child = command 504 | .stdin(Stdio::null()) 505 | .stdout(Stdio::null()) 506 | .stderr(Stdio::null()) 507 | .spawn(); 508 | 509 | if let Ok(child) = child { 510 | info!( 511 | "successfully started program {} {}", 512 | entry.appid, 513 | child.id() 514 | ); 515 | dedupe.insert(entry.appid); 516 | } else { 517 | info!("could not start program {}", entry.appid); 518 | } 519 | } else { 520 | let why = escaped_args.unwrap_err(); 521 | error!(?why, "could not parse arguments"); 522 | } 523 | } 524 | } 525 | } 526 | info!("started {} programs", dedupe.len()); 527 | } 528 | 529 | let mut signals = Signals::new(vec![libc::SIGTERM, libc::SIGINT]).unwrap(); 530 | let mut status = Status::Exited; 531 | let session_dbus_rx_next = session_rx.recv(); 532 | tokio::select! { 533 | res = session_dbus_rx_next => { 534 | match res { 535 | Some(service::SessionRequest::Exit) => { 536 | info!("EXITING: session exited by request"); 537 | } 538 | Some(service::SessionRequest::Restart) => { 539 | info!("RESTARTING: session restarted by request"); 540 | status = Status::Restarted; 541 | } 542 | None => { 543 | warn!("exit channel dropped session"); 544 | } 545 | } 546 | }, 547 | signal = signals.next() => match signal { 548 | Some(libc::SIGTERM | libc::SIGINT) => { 549 | info!("EXITING: received request to terminate"); 550 | } 551 | Some(signal) => unreachable!("EXITING: received unhandled signal {}", signal), 552 | None => {}, 553 | } 554 | } 555 | 556 | compositor_handle.abort(); 557 | token.cancel(); 558 | if let Err(err) = process_manager.stop_process(settings_daemon).await { 559 | tracing::error!(?err, "Failed to gracefully stop settings daemon."); 560 | } else { 561 | match tokio::time::timeout(Duration::from_secs(1), settings_exit_rx).await { 562 | Ok(Ok(_)) => {} 563 | _ => { 564 | tracing::error!("Settings daemon process did not respond to the request to stop."); 565 | } 566 | }; 567 | }; 568 | 569 | tokio::time::sleep(std::time::Duration::from_secs(2)).await; 570 | Ok(status) 571 | } 572 | 573 | async fn start_component( 574 | cmd: impl Into>, 575 | span: tracing::Span, 576 | process_manager: &ProcessManager, 577 | env_vars: &[(String, String)], 578 | socket_tx: &mpsc::UnboundedSender>, 579 | extra_fds: Vec<(OwnedFd, (String, String), UnixStream)>, 580 | ) { 581 | let mut sockets = Vec::with_capacity(2); 582 | let (mut env_vars, fd) = create_privileged_socket(&mut sockets, &env_vars).unwrap(); 583 | 584 | let socket_tx_clone = socket_tx.clone(); 585 | let stdout_span = span.clone(); 586 | let stderr_span = span.clone(); 587 | let stderr_span_clone = stderr_span.clone(); 588 | let cmd = cmd.into(); 589 | let cmd_clone = cmd.clone(); 590 | 591 | let (mut fds, extra_fd_env, mut streams): (Vec<_>, Vec<_>, Vec<_>) = 592 | itertools::multiunzip(extra_fds); 593 | for kv in &extra_fd_env { 594 | env_vars.push(kv.clone()); 595 | } 596 | 597 | sockets.append(&mut streams); 598 | if let Err(why) = socket_tx.send(sockets) { 599 | error!(?why, "Failed to send the privileged socket"); 600 | } 601 | let (extra_fd_env, _): (Vec<_>, Vec<_>) = extra_fd_env.into_iter().unzip(); 602 | fds.push(fd); 603 | if let Err(err) = process_manager 604 | .start( 605 | Process::new() 606 | .with_executable(cmd.clone()) 607 | .with_env(env_vars.iter().cloned()) 608 | .with_on_stdout(move |_, _, line| { 609 | let stdout_span = stdout_span.clone(); 610 | async move { 611 | info!("{}", line); 612 | } 613 | .instrument(stdout_span) 614 | }) 615 | .with_on_stderr(move |_, _, line| { 616 | let stderr_span = stderr_span.clone(); 617 | async move { 618 | warn!("{}", line); 619 | } 620 | .instrument(stderr_span) 621 | }) 622 | .with_on_start(move |pman, pkey, _will_restart| async move { 623 | #[cfg(feature = "systemd")] 624 | if *is_systemd_used() { 625 | if let Ok((innr_cmd, Some(pid))) = pman.get_exe_and_pid(pkey).await { 626 | if let Err(err) = spawn_scope(innr_cmd.clone(), vec![pid]).await { 627 | warn!( 628 | "Failed to spawn scope for {}. Creating transient unit failed \ 629 | with {}", 630 | innr_cmd, err 631 | ); 632 | }; 633 | } 634 | } 635 | }) 636 | .with_on_exit(move |mut pman, key, err_code, will_restart| { 637 | if let Some(err) = err_code { 638 | error!("{cmd_clone} exited with error {}", err.to_string()); 639 | } 640 | let extra_fd_env = extra_fd_env.clone(); 641 | let socket_tx_clone = socket_tx_clone.clone(); 642 | async move { 643 | if !will_restart { 644 | return; 645 | } 646 | 647 | let mut sockets = Vec::with_capacity(1 + extra_fd_env.len()); 648 | let mut fds = Vec::with_capacity(1 + extra_fd_env.len()); 649 | let (mut env_vars, fd) = 650 | create_privileged_socket(&mut sockets, &[]).unwrap(); 651 | fds.push(fd); 652 | for k in extra_fd_env { 653 | let (mut fd_env_vars, fd) = 654 | create_privileged_socket(&mut sockets, &[]).unwrap(); 655 | fd_env_vars.last_mut().unwrap().0 = k; 656 | env_vars.append(&mut fd_env_vars); 657 | fds.push(fd) 658 | } 659 | 660 | if let Err(why) = socket_tx_clone.send(sockets) { 661 | error!(?why, "Failed to send the privileged socket"); 662 | } 663 | if let Err(why) = pman.update_process_env(&key, env_vars).await { 664 | error!(?why, "Failed to update environment variables"); 665 | } 666 | if let Err(why) = pman.update_process_fds(&key, move || fds).await { 667 | error!(?why, "Failed to update fds"); 668 | } 669 | } 670 | }) 671 | .with_fds(move || fds), 672 | ) 673 | .await 674 | { 675 | let _enter = stderr_span_clone.enter(); 676 | error!("failed to start {}: {}", cmd, err); 677 | } 678 | } 679 | -------------------------------------------------------------------------------- /src/notifications.rs: -------------------------------------------------------------------------------- 1 | use color_eyre::{eyre::Context, Result}; 2 | use cosmic_notifications_util::{DAEMON_NOTIFICATIONS_FD, PANEL_NOTIFICATIONS_FD}; 3 | use launch_pad::{process::Process, ProcessKey}; 4 | use rustix::fd::AsRawFd; 5 | use std::{ 6 | os::{fd::OwnedFd, unix::net::UnixStream}, 7 | sync::Arc, 8 | }; 9 | use tokio::sync::{mpsc, Mutex}; 10 | use tracing::Instrument; 11 | 12 | use crate::comp::create_privileged_socket; 13 | 14 | pub fn create_socket() -> Result<(OwnedFd, OwnedFd)> { 15 | // Create a new pair of unnamed Unix sockets 16 | let (sock_1, sock_2) = UnixStream::pair().wrap_err("failed to create socket pair")?; 17 | 18 | // Turn the sockets into non-blocking fd, which we can pass to the child 19 | // process 20 | sock_1 21 | .set_nonblocking(true) 22 | .wrap_err("failed to mark client socket as non-blocking")?; 23 | 24 | sock_2 25 | .set_nonblocking(true) 26 | .wrap_err("failed to mark client socket as non-blocking")?; 27 | 28 | Ok((OwnedFd::from(sock_1), OwnedFd::from(sock_2))) 29 | } 30 | 31 | pub fn notifications_process( 32 | span: tracing::Span, 33 | cmd: &'static str, 34 | key: Arc>>, 35 | mut env_vars: Vec<(String, String)>, 36 | fd: OwnedFd, 37 | restart_span: tracing::Span, 38 | restart_cmd: &'static str, 39 | restart_key: Arc>>, 40 | restart_env_vars: Vec<(String, String)>, 41 | socket_tx: mpsc::UnboundedSender>, 42 | ) -> Process { 43 | env_vars.retain(|v| &v.0 != "WAYLAND_SOCKET"); 44 | 45 | let stdout_span = span.clone(); 46 | let stderr_span = span.clone(); 47 | let mut sockets = Vec::with_capacity(1); 48 | let (env_vars, privileged_fd) = create_privileged_socket(&mut sockets, &env_vars).unwrap(); 49 | _ = socket_tx.send(sockets); 50 | let env_clone = env_vars.clone(); 51 | let socket_tx_clone = socket_tx.clone(); 52 | Process::new() 53 | .with_executable(cmd) 54 | .with_fds(move || vec![privileged_fd, fd]) 55 | .with_on_stdout(move |_, _, line| { 56 | let stdout_span = stdout_span.clone(); 57 | async move { 58 | info!("{}", line); 59 | } 60 | .instrument(stdout_span) 61 | }) 62 | .with_on_stderr(move |_, _, line| { 63 | let stderr_span = stderr_span.clone(); 64 | async move { 65 | warn!("{}", line); 66 | } 67 | .instrument(stderr_span) 68 | }) 69 | .with_on_exit(move |pman, my_key, _, will_restart| { 70 | // force restart of notifications / panel when the other exits 71 | // also update the environment variables to use the new socket 72 | let (my_fd, their_fd) = create_socket().expect("Failed to create notification socket"); 73 | let mut my_env_vars = env_clone.clone(); 74 | if let Some((_k, v)) = my_env_vars 75 | .iter_mut() 76 | .find(|(k, _v)| k == PANEL_NOTIFICATIONS_FD || k == DAEMON_NOTIFICATIONS_FD) 77 | { 78 | *v = my_fd.as_raw_fd().to_string(); 79 | } 80 | 81 | let mut their_env_vars = restart_env_vars.clone(); 82 | if let Some((_k, v)) = their_env_vars 83 | .iter_mut() 84 | .find(|(k, _v)| k == PANEL_NOTIFICATIONS_FD || k == DAEMON_NOTIFICATIONS_FD) 85 | { 86 | *v = their_fd.as_raw_fd().to_string(); 87 | } 88 | 89 | let new_process = notifications_process( 90 | restart_span.clone(), 91 | restart_cmd, 92 | restart_key.clone(), 93 | their_env_vars.clone(), 94 | their_fd, 95 | span.clone(), 96 | cmd, 97 | key.clone(), 98 | my_env_vars.clone(), 99 | socket_tx_clone.clone(), 100 | ); 101 | let restart_key = restart_key.clone(); 102 | let socket_tx_clone = socket_tx_clone.clone(); 103 | 104 | let mut pman_clone = pman.clone(); 105 | async move { 106 | if will_restart { 107 | let mut sockets = Vec::with_capacity(1); 108 | let (env_vars, new_fd) = 109 | create_privileged_socket(&mut sockets, &my_env_vars).unwrap(); 110 | 111 | if let Err(why) = socket_tx_clone.send(sockets) { 112 | error!(?why, "Failed to send the privileged socket"); 113 | } 114 | if let Err(why) = pman_clone.update_process_env(&my_key, env_vars).await { 115 | error!(?why, "Failed to update environment variables"); 116 | } 117 | if let Err(why) = pman_clone 118 | .update_process_fds(&my_key, move || vec![new_fd, my_fd]) 119 | .await 120 | { 121 | error!(?why, "Failed to update fds"); 122 | } 123 | 124 | let Some(old) = *restart_key.lock().await else { 125 | error!("Couldn't stop previous invocation of {}", cmd); 126 | return; 127 | }; 128 | _ = pman.stop_process(old).await; 129 | 130 | if let Ok(new) = pman.start(new_process).await { 131 | let mut guard = restart_key.lock().await; 132 | *guard = Some(new); 133 | } 134 | } 135 | } 136 | }) 137 | .with_env(env_vars) 138 | } 139 | -------------------------------------------------------------------------------- /src/process.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-only 2 | use color_eyre::eyre::{Result, WrapErr}; 3 | use rustix::io::FdFlags; 4 | use std::os::unix::prelude::*; 5 | 6 | pub(crate) fn mark_as_not_cloexec(file: &impl AsFd) -> Result<()> { 7 | let flags = rustix::io::fcntl_getfd(file).wrap_err("failed to get GETFD value of stream")?; 8 | rustix::io::fcntl_setfd(file, flags.difference(FdFlags::CLOEXEC)) 9 | .wrap_err("failed to unset CLOEXEC on file") 10 | } 11 | -------------------------------------------------------------------------------- /src/service.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-only 2 | use tokio::sync::mpsc; 3 | use zbus::interface; 4 | 5 | pub enum SessionRequest { 6 | Exit, 7 | Restart, 8 | } 9 | 10 | pub struct SessionService { 11 | pub session_tx: mpsc::Sender, 12 | } 13 | 14 | #[interface(name = "com.system76.CosmicSession")] 15 | impl SessionService { 16 | async fn exit(&mut self) { 17 | warn!("exiting session"); 18 | _ = self.session_tx.send(SessionRequest::Exit).await; 19 | } 20 | 21 | async fn restart(&self) { 22 | warn!("restarting session"); 23 | _ = self.session_tx.send(SessionRequest::Restart).await; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/systemd.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-only 2 | 3 | use std::path::Path; 4 | use std::process::{Command, Stdio}; 5 | use std::sync::OnceLock; 6 | 7 | use zbus::zvariant::{Array, OwnedValue}; 8 | use zbus::Connection; 9 | 10 | #[derive(Debug)] 11 | pub struct EnvVar { 12 | pub key: String, 13 | pub value: String, 14 | } 15 | 16 | impl Into for (&str, &str) { 17 | fn into(self) -> EnvVar { 18 | EnvVar { 19 | key: self.0.to_owned(), 20 | value: self.1.to_owned(), 21 | } 22 | } 23 | } 24 | 25 | #[cfg(feature = "systemd")] 26 | use zbus_systemd::systemd1::ManagerProxy as SystemdManagerProxy; 27 | 28 | pub async fn set_systemd_environment(key: &str, value: &str) { 29 | run_optional_command( 30 | "systemctl", 31 | &["--user", "set-environment", &format!("{key}={value}")], 32 | ) 33 | } 34 | 35 | pub async fn start_systemd_target() { 36 | run_optional_command( 37 | "systemctl", 38 | &["--user", "start", "--no-block", "cosmic-session.target"], 39 | ) 40 | } 41 | 42 | pub fn stop_systemd_target() { 43 | run_optional_command( 44 | "systemctl", 45 | &["--user", "stop", "--no-block", "cosmic-session.target"], 46 | ) 47 | } 48 | 49 | ///Determine if systemd is used as the init system. This should work on all linux distributions. 50 | pub fn is_systemd_used() -> &'static bool { 51 | static IS_SYSTEMD_USED: OnceLock = OnceLock::new(); 52 | IS_SYSTEMD_USED.get_or_init(|| Path::new("/run/systemd/system").exists()) 53 | } 54 | 55 | #[cfg(feature = "systemd")] 56 | pub async fn get_systemd_env() -> Result, zbus::Error> { 57 | let connection = Connection::session().await?; 58 | let systemd_manager = SystemdManagerProxy::new(&connection).await?; 59 | let systemd_env = systemd_manager.environment().await?; 60 | 61 | let mut out: Vec = Vec::new(); 62 | for i in systemd_env { 63 | if let Some(b) = i.split_once("=") { 64 | out.push(b.into()); 65 | } 66 | } 67 | Ok(out) 68 | } 69 | 70 | #[cfg(feature = "systemd")] 71 | ///Spawn a systemd scope unit with the given name and PIDs. 72 | pub async fn spawn_scope(mut command: String, pids: Vec) -> Result<(), zbus::Error> { 73 | let connection = Connection::session().await?; 74 | let systemd_manager = SystemdManagerProxy::new(&connection).await?; 75 | let pids = OwnedValue::try_from(Array::from(pids)).unwrap(); 76 | let properties: Vec<(String, OwnedValue)> = vec![(String::from("PIDs"), pids)]; 77 | if command.starts_with('/') { 78 | // use the last component of the path as the unit name 79 | command = command.rsplit('/').next().unwrap().to_string(); 80 | } 81 | let scope_name = format!("{}.scope", command); 82 | systemd_manager 83 | .start_transient_unit( 84 | scope_name.to_string(), 85 | String::from("replace"), 86 | properties, 87 | Vec::new(), 88 | ) 89 | .await?; 90 | Ok(()) 91 | } 92 | 93 | /// run a command, but log errors instead of returning them or panicking 94 | fn run_optional_command(cmd: &str, args: &[&str]) { 95 | match Command::new(cmd).args(args).stdin(Stdio::null()).status() { 96 | Ok(status) => { 97 | if !status.success() { 98 | match status.code() { 99 | Some(code) => warn!("{} {}: exit code {}", cmd, args.join(" "), code), 100 | None => warn!("{} {}: terminated by signal", cmd, args.join(" ")), 101 | } 102 | } 103 | } 104 | Err(error) => { 105 | warn!("unable to start {} {}: {}", cmd, args.join(" "), error); 106 | } 107 | } 108 | } 109 | --------------------------------------------------------------------------------