diff --git a/.github/workflows/build-all-features.yml b/.github/workflows/build-all-features.yml index dc367a5..da46711 100644 --- a/.github/workflows/build-all-features.yml +++ b/.github/workflows/build-all-features.yml @@ -12,13 +12,16 @@ env: jobs: build: runs-on: ubuntu-22.04 + defaults: + run: + working-directory: ./wlx-overlay-s steps: - uses: actions/checkout@v4 - name: Setup sccache uses: mozilla-actions/sccache-action@v0.0.9 - name: Prepare Environment run: | - .github/workflows/scripts/appimage_prepare_env.sh + ../.github/workflows/scripts/appimage_prepare_env.sh - name: Build run: cargo build --verbose --all-features - name: Run tests diff --git a/.github/workflows/build-appimage.yml b/.github/workflows/build-appimage.yml index b567f98..49d0683 100644 --- a/.github/workflows/build-appimage.yml +++ b/.github/workflows/build-appimage.yml @@ -15,19 +15,22 @@ env: jobs: build_appimage: runs-on: ubuntu-22.04 + defaults: + run: + working-directory: ./wlx-overlay-s steps: - uses: actions/checkout@v3 - name: Setup sccache uses: mozilla-actions/sccache-action@v0.0.9 - name: Prepare Environment run: | - .github/workflows/scripts/appimage_prepare_env.sh + ../.github/workflows/scripts/appimage_prepare_env.sh - name: Cargo Build run: | - .github/workflows/scripts/appimage_build_wlx.sh + ../.github/workflows/scripts/appimage_build_wlx.sh - name: Package AppImage run: | - .github/workflows/scripts/appimage_package.sh + ../.github/workflows/scripts/appimage_package.sh - name: Upload AppImage uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/build-default.yml b/.github/workflows/build-default.yml index 614b066..85665da 100644 --- a/.github/workflows/build-default.yml +++ b/.github/workflows/build-default.yml @@ -12,13 +12,16 @@ env: jobs: build: runs-on: ubuntu-22.04 + defaults: + run: + working-directory: ./wlx-overlay-s steps: - uses: actions/checkout@v4 - name: Setup sccache uses: mozilla-actions/sccache-action@v0.0.9 - name: Prepare Environment run: | - .github/workflows/scripts/appimage_prepare_env.sh + ../.github/workflows/scripts/appimage_prepare_env.sh - name: Run cargo fmt run: cargo fmt --check - name: Build diff --git a/.github/workflows/build-full-appimage.yml b/.github/workflows/build-full-appimage.yml index ad9df73..d4df61c 100644 --- a/.github/workflows/build-full-appimage.yml +++ b/.github/workflows/build-full-appimage.yml @@ -15,22 +15,25 @@ env: jobs: build_appimage: runs-on: ubuntu-22.04 + defaults: + run: + working-directory: ./wlx-overlay-s steps: - uses: actions/checkout@v3 - name: Setup sccache uses: mozilla-actions/sccache-action@v0.0.9 - name: Prepare Environment run: | - .github/workflows/scripts/appimage_prepare_env.sh + ../.github/workflows/scripts/appimage_prepare_env.sh - name: Cargo Build run: | - .github/workflows/scripts/appimage_build_wlx.sh + ../.github/workflows/scripts/appimage_build_wlx.sh - name: Build WayVR Dashboard run: | - .github/workflows/scripts/appimage_build_wayvr_dashboard.sh + ../.github/workflows/scripts/appimage_build_wayvr_dashboard.sh - name: Package AppImage run: | - .github/workflows/scripts/appimage_package_full.sh + ../.github/workflows/scripts/appimage_package_full.sh - name: Upload AppImage uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/build-wayland-openvr.yml b/.github/workflows/build-wayland-openvr.yml index dce2e71..07289dc 100644 --- a/.github/workflows/build-wayland-openvr.yml +++ b/.github/workflows/build-wayland-openvr.yml @@ -12,13 +12,16 @@ env: jobs: build: runs-on: ubuntu-22.04 + defaults: + run: + working-directory: ./wlx-overlay-s steps: - uses: actions/checkout@v4 - name: Setup sccache uses: mozilla-actions/sccache-action@v0.0.9 - name: Prepare Environment run: | - .github/workflows/scripts/appimage_prepare_env.sh + ../.github/workflows/scripts/appimage_prepare_env.sh - name: Build run: cargo build --verbose --no-default-features --features=wayland,openvr - name: Run tests diff --git a/.github/workflows/build-wayland-openxr-openvr-wayvr.yml b/.github/workflows/build-wayland-openxr-openvr-wayvr.yml index 1bc3589..cd37e97 100644 --- a/.github/workflows/build-wayland-openxr-openvr-wayvr.yml +++ b/.github/workflows/build-wayland-openxr-openvr-wayvr.yml @@ -12,13 +12,16 @@ env: jobs: build: runs-on: ubuntu-22.04 + defaults: + run: + working-directory: ./wlx-overlay-s steps: - uses: actions/checkout@v4 - name: Setup sccache uses: mozilla-actions/sccache-action@v0.0.9 - name: Prepare Environment run: | - .github/workflows/scripts/appimage_prepare_env.sh + ../.github/workflows/scripts/appimage_prepare_env.sh - name: Build run: cargo build --verbose --no-default-features --features=wayland,openxr,openvr,wayvr - name: Run tests diff --git a/.github/workflows/build-wayland-openxr.yml b/.github/workflows/build-wayland-openxr.yml index 1e64b24..4b433f0 100644 --- a/.github/workflows/build-wayland-openxr.yml +++ b/.github/workflows/build-wayland-openxr.yml @@ -12,13 +12,16 @@ env: jobs: build: runs-on: ubuntu-22.04 + defaults: + run: + working-directory: ./wlx-overlay-s steps: - uses: actions/checkout@v4 - name: Setup sccache uses: mozilla-actions/sccache-action@v0.0.9 - name: Prepare Environment run: | - .github/workflows/scripts/appimage_prepare_env.sh + ../.github/workflows/scripts/appimage_prepare_env.sh - name: Build run: cargo build --verbose --no-default-features --features=wayland,openxr - name: Run tests diff --git a/.github/workflows/build-x11-openvr.yml b/.github/workflows/build-x11-openvr.yml index 86327a1..8b3ece3 100644 --- a/.github/workflows/build-x11-openvr.yml +++ b/.github/workflows/build-x11-openvr.yml @@ -12,13 +12,16 @@ env: jobs: build: runs-on: ubuntu-22.04 + defaults: + run: + working-directory: ./wlx-overlay-s steps: - uses: actions/checkout@v4 - name: Setup sccache uses: mozilla-actions/sccache-action@v0.0.9 - name: Prepare Environment run: | - .github/workflows/scripts/appimage_prepare_env.sh + ../.github/workflows/scripts/appimage_prepare_env.sh - name: Build run: cargo build --verbose --no-default-features --features=x11,openvr - name: Run tests diff --git a/.github/workflows/build-x11-openxr.yml b/.github/workflows/build-x11-openxr.yml index be7f3d6..30082ab 100644 --- a/.github/workflows/build-x11-openxr.yml +++ b/.github/workflows/build-x11-openxr.yml @@ -12,13 +12,16 @@ env: jobs: build: runs-on: ubuntu-22.04 + defaults: + run: + working-directory: ./wlx-overlay-s steps: - uses: actions/checkout@v4 - name: Setup sccache uses: mozilla-actions/sccache-action@v0.0.9 - name: Prepare Environment run: | - .github/workflows/scripts/appimage_prepare_env.sh + ../.github/workflows/scripts/appimage_prepare_env.sh - name: Build run: cargo build --verbose --no-default-features --features=x11,openxr - name: Run tests diff --git a/.github/workflows/make-release.yml b/.github/workflows/make-release.yml index b1e6b2e..793fa61 100644 --- a/.github/workflows/make-release.yml +++ b/.github/workflows/make-release.yml @@ -14,13 +14,16 @@ env: jobs: make_release: runs-on: ubuntu-22.04 + defaults: + run: + working-directory: ./wlx-overlay-s steps: - uses: actions/checkout@v3 - name: Setup sccache uses: mozilla-actions/sccache-action@v0.0.9 - name: Prepare Environment run: | - .github/workflows/scripts/appimage_prepare_env.sh + ../.github/workflows/scripts/appimage_prepare_env.sh - name: Cargo Build run: | cargo build --release diff --git a/.gitignore b/.gitignore index 265b7f5..5cd5747 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ /target .gdb_history +.vscode +.cargo +scripts/translator/node_modules \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index e73e544..9034d0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 4 [[package]] name = "ab_glyph" -version = "0.2.29" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3672c180e71eeaaac3a541fbbc5f5ad4def8b747c595ad30d674e43049f7b0" +checksum = "01c0457472c38ea5bd1c3b5ada5e368271cb550be7a4ca4a0b4634e9913f6cc2" dependencies = [ "ab_glyph_rasterizer", "owned_ttf_parser", @@ -14,47 +14,77 @@ dependencies = [ [[package]] name = "ab_glyph_rasterizer" -version = "0.1.8" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" +checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" [[package]] name = "addr2line" -version = "0.24.2" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" dependencies = [ "gimli", ] [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom 0.2.15", + "getrandom 0.3.4", "once_cell", "version_check", - "zerocopy 0.7.35", + "zerocopy", ] [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] +[[package]] +name = "aliasable" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" + +[[package]] +name = "aligned" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "377e4c0ba83e4431b10df45c1d4666f178ea9c552cac93e60c3a88bf32785923" +dependencies = [ + "as-slice", +] + +[[package]] +name = "aligned-vec" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc890384c8602f339876ded803c97ad529f3842aba97f6392b3dba0dd171769b" +dependencies = [ + "equator", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "alsa" version = "0.9.1" @@ -62,7 +92,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed7572b7ba83a31e20d1b48970ee402d2e3e0537dcfe0a3ff4d6eb7508617d43" dependencies = [ "alsa-sys", - "bitflags 2.9.0", + "bitflags 2.10.0", "cfg-if", "libc", ] @@ -84,16 +114,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" dependencies = [ "android-properties", - "bitflags 2.9.0", + "bitflags 2.10.0", "cc", "cesu8", "jni", "jni-sys", "libc", "log", - "ndk 0.9.0", + "ndk", "ndk-context", - "ndk-sys 0.6.0+11769913", + "ndk-sys", "num_enum", "thiserror 1.0.69", ] @@ -104,12 +134,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -131,9 +155,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.18" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", @@ -146,44 +170,44 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.7" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", - "once_cell", - "windows-sys 0.59.0", + "once_cell_polyfill", + "windows-sys 0.61.2", ] [[package]] name = "anyhow" -version = "1.0.97" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "appendlist" @@ -200,15 +224,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "approx" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" -dependencies = [ - "num-traits", -] - [[package]] name = "aquamarine" version = "0.1.12" @@ -222,6 +237,23 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" + +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + [[package]] name = "arraydeque" version = "0.5.1" @@ -246,6 +278,15 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" +[[package]] +name = "as-slice" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516" +dependencies = [ + "stable_deref_trait", +] + [[package]] name = "ash" version = "0.38.0+1.3.281" @@ -257,16 +298,16 @@ dependencies = [ [[package]] name = "ashpd" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cbdf310d77fd3aaee6ea2093db7011dc2d35d2eb3481e5607f1f8d942ed99df" +checksum = "da0986d5b4f0802160191ad75f8d33ada000558757db3defb70299ca95d9fcbd" dependencies = [ "async-fs", "async-net", "enumflags2", "futures-channel", "futures-util", - "rand 0.9.0", + "rand", "serde", "serde_repr", "url", @@ -287,9 +328,9 @@ dependencies = [ [[package]] name = "async-channel" -version = "2.3.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" dependencies = [ "concurrent-queue", "event-listener-strategy", @@ -299,22 +340,23 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.13.1" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" +checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" dependencies = [ "async-task", "concurrent-queue", "fastrand", "futures-lite", + "pin-project-lite", "slab", ] [[package]] name = "async-fs" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" +checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5" dependencies = [ "async-lock", "blocking", @@ -323,28 +365,27 @@ dependencies = [ [[package]] name = "async-io" -version = "2.4.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" +checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" dependencies = [ - "async-lock", + "autocfg", "cfg-if", "concurrent-queue", "futures-io", "futures-lite", "parking", "polling", - "rustix 0.38.44", + "rustix 1.1.2", "slab", - "tracing", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "async-lock" -version = "3.4.0" +version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" dependencies = [ "event-listener", "event-listener-strategy", @@ -364,9 +405,9 @@ dependencies = [ [[package]] name = "async-process" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" +checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" dependencies = [ "async-channel", "async-io", @@ -377,8 +418,7 @@ dependencies = [ "cfg-if", "event-listener", "futures-lite", - "rustix 0.38.44", - "tracing", + "rustix 1.1.2", ] [[package]] @@ -389,14 +429,14 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "async-signal" -version = "0.2.10" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" +checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" dependencies = [ "async-io", "async-lock", @@ -404,10 +444,10 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 0.38.44", + "rustix 1.1.2", "signal-hook-registry", "slab", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -418,13 +458,36 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.88" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", +] + +[[package]] +name = "atk" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241b621213072e993be4f6f3a9e4b45f65b7e6faad43001be957184b7bb1824b" +dependencies = [ + "atk-sys", + "glib 0.18.5", + "libc", +] + +[[package]] +name = "atk-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e48b684b0ca77d2bbadeef17424c2ea3c897d44d566a1617e7e8f30614d086" +dependencies = [ + "glib-sys 0.18.1", + "gobject-sys 0.18.0", + "libc", + "system-deps 6.2.2", ] [[package]] @@ -433,6 +496,12 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "atomic_float" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "628d228f918ac3b82fe590352cc719d30664a0c13ca3a60266fe02c7132d480a" + [[package]] name = "atty" version = "0.2.14" @@ -446,9 +515,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "autocxx" @@ -468,7 +537,7 @@ version = "0.71.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7d41cf081e31a74378456586b47a5bae2b75a98e5f7c248c9d9bf433e3637f4" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "cexpr", "clang-sys", "itertools 0.13.0", @@ -478,7 +547,7 @@ dependencies = [ "regex", "rustc-hash 2.1.1", "shlex", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -490,7 +559,7 @@ dependencies = [ "autocxx-engine", "env_logger", "indexmap 1.9.3", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -516,7 +585,7 @@ dependencies = [ "regex", "rustversion", "serde_json", - "syn 2.0.100", + "syn 2.0.111", "tempfile", "thiserror 1.0.69", "version_check", @@ -532,7 +601,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -549,15 +618,58 @@ dependencies = [ "quote", "serde", "serde_json", - "syn 2.0.100", + "syn 2.0.111", "thiserror 1.0.69", ] [[package]] -name = "backtrace" -version = "0.3.74" +name = "av-scenechange" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +checksum = "0f321d77c20e19b92c39e7471cf986812cbb46659d2af674adc4331ef3f18394" +dependencies = [ + "aligned", + "anyhow", + "arg_enum_proc_macro", + "arrayvec", + "log", + "num-rational", + "num-traits", + "pastey", + "rayon", + "thiserror 2.0.17", + "v_frame", + "y4m", +] + +[[package]] +name = "av1-grain" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cfddb07216410377231960af4fcab838eaa12e013417781b78bd95ee22077f8" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom 8.0.0", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47c8fbc0f831f4519fe8b810b6a7a91410ec83031b8233f730a0480029f6a23f" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "backtrace" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" dependencies = [ "addr2line", "cfg-if", @@ -565,14 +677,14 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets 0.52.6", + "windows-link 0.2.1", ] [[package]] name = "base64" -version = "0.21.7" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bcdec_rs" @@ -587,7 +699,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ "annotate-snippets", - "bitflags 2.9.0", + "bitflags 2.10.0", "cexpr", "clang-sys", "itertools 0.12.1", @@ -600,27 +712,15 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.100", + "syn 2.0.111", "which", ] [[package]] -name = "bindgen" -version = "0.70.1" +name = "bit_field" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" -dependencies = [ - "bitflags 2.9.0", - "cexpr", - "clang-sys", - "itertools 0.13.0", - "proc-macro2", - "quote", - "regex", - "rustc-hash 1.1.0", - "shlex", - "syn 2.0.100", -] +checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6" [[package]] name = "bitflags" @@ -630,11 +730,20 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" dependencies = [ - "serde", + "serde_core", +] + +[[package]] +name = "bitstream-io" +version = "4.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60d4bd9d1db2c6bdf285e223a7fa369d5ce98ec767dec949c6ca62863ce61757" +dependencies = [ + "core2", ] [[package]] @@ -656,10 +765,19 @@ dependencies = [ ] [[package]] -name = "blocking" -version = "1.6.1" +name = "block2" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2 0.6.3", +] + +[[package]] +name = "blocking" +version = "1.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" dependencies = [ "async-channel", "async-task", @@ -669,29 +787,35 @@ dependencies = [ ] [[package]] -name = "bumpalo" -version = "3.17.0" +name = "built" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +checksum = "f4ad8f11f288f48ca24471bbd51ac257aaeaaa07adae295591266b792902ae64" + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "bytemuck" -version = "1.22.0" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.9.3" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ecc273b49b3205b83d648f0690daa588925572cc5063745bfe547fe7ec8e1a1" +checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -701,10 +825,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] -name = "bytes" -version = "1.10.1" +name = "byteorder-lite" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + +[[package]] +name = "bytes" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" + +[[package]] +name = "cairo-rs" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" +dependencies = [ + "bitflags 2.10.0", + "cairo-sys-rs", + "glib 0.18.5", + "libc", + "once_cell", + "thiserror 1.0.69", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51" +dependencies = [ + "glib-sys 0.18.1", + "libc", + "system-deps 6.2.2", +] [[package]] name = "calloop" @@ -712,7 +867,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "log", "polling", "rustix 0.38.44", @@ -722,13 +877,13 @@ dependencies = [ [[package]] name = "calloop" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10929724661d1c43856fd87c7a127ae944ec55579134fb485e4136fb6a46fdcb" +checksum = "cb9f6e1368bd4621d2c86baa7e37de77a938adf5221e5dd3d6133340101b309e" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "polling", - "rustix 0.38.44", + "rustix 1.1.2", "slab", "tracing", ] @@ -746,11 +901,24 @@ dependencies = [ ] [[package]] -name = "cc" -version = "1.2.18" +name = "calloop-wayland-source" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525046617d8376e3db1deffb079e91cef90a89fc3ca5c185bbf8c9ecdd15cd5c" +checksum = "138efcf0940a02ebf0cc8d1eff41a1682a46b431630f4c52450d6265876021fa" dependencies = [ + "calloop 0.14.3", + "rustix 1.1.2", + "wayland-backend", + "wayland-client", +] + +[[package]] +name = "cc" +version = "1.2.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" +dependencies = [ + "find-msvc-tools", "jobserver", "libc", "shlex", @@ -768,7 +936,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" dependencies = [ - "nom", + "nom 7.1.3", ] [[package]] @@ -778,14 +946,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" dependencies = [ "smallvec", - "target-lexicon", + "target-lexicon 0.12.16", +] + +[[package]] +name = "cfg-expr" +version = "0.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9acd0bdbbf4b2612d09f52ba61da432140cb10930354079d0d53fafc12968726" +dependencies = [ + "smallvec", + "target-lexicon 0.13.3", ] [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" @@ -799,45 +977,33 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a98d30140e3296250832bbaaff83b27dcd6fa3cc70fb6f1f3e5c9c0023b5317" dependencies = [ - "approx 0.4.0", + "approx", "num-traits", ] [[package]] name = "chrono" -version = "0.4.40" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "wasm-bindgen", - "windows-link", + "windows-link 0.2.1", ] [[package]] name = "chrono-tz" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efdce149c370f133a071ca8ef6ea340b7b88748ab0810097a9e2976eaa34b4f3" +checksum = "a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3" dependencies = [ "chrono", - "chrono-tz-build", "phf", ] -[[package]] -name = "chrono-tz-build" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f10f8c9340e31fc120ff885fcdb54a0b48e474bbd77cab557f0c30a3e569402" -dependencies = [ - "parse-zoneinfo", - "phf_codegen", -] - [[package]] name = "clang-sys" version = "1.8.1" @@ -851,9 +1017,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.35" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" +checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" dependencies = [ "clap_builder", "clap_derive", @@ -861,9 +1027,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.35" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" +checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" dependencies = [ "anstream", "anstyle", @@ -873,21 +1039,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.32" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "clap_lex" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "cmake" @@ -900,20 +1066,26 @@ dependencies = [ [[package]] name = "codespan-reporting" -version = "0.12.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" +checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681" dependencies = [ "serde", "termcolor", - "unicode-width 0.2.0", + "unicode-width 0.2.2", ] [[package]] -name = "colorchoice" -version = "1.0.3" +name = "color_quant" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "combine" @@ -936,29 +1108,24 @@ dependencies = [ [[package]] name = "config" -version = "0.15.11" +version = "0.15.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "595aae20e65c3be792d05818e8c63025294ac3cb7e200f11459063a352a6ef80" +checksum = "b30fa8254caad766fc03cb0ccae691e14bf3bd72bfff27f72802ce729551b3d6" dependencies = [ "async-trait", "convert_case 0.6.0", - "json5", + "json5 0.4.1", "pathdiff", "ron", "rust-ini", - "serde", + "serde-untagged", + "serde_core", "serde_json", - "toml", - "winnow", + "toml 0.9.8", + "winnow 0.7.14", "yaml-rust2", ] -[[package]] -name = "const-cstr" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3d0b5ff30645a68f35ece8cea4556ca14ef8a1651455f789a099a0513532a6" - [[package]] name = "const-random" version = "0.1.18" @@ -974,7 +1141,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", "once_cell", "tiny-keccak", ] @@ -1044,42 +1211,81 @@ dependencies = [ ] [[package]] -name = "coreaudio-rs" -version = "0.11.3" +name = "core2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "321077172d79c662f64f5071a03120748d5bb652f5231570141be24cfcd2bace" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" dependencies = [ - "bitflags 1.3.2", - "core-foundation-sys", - "coreaudio-sys", + "memchr", ] [[package]] -name = "coreaudio-sys" -version = "0.2.16" +name = "core_maths" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ce857aa0b77d77287acc1ac3e37a05a8c95a2af3647d23b15f263bdaeb7562b" +checksum = "77745e017f5edba1a9c1d854f6f3a52dac8a12dd5af5d2f54aecf61e43d80d30" dependencies = [ - "bindgen 0.70.1", + "libm", +] + +[[package]] +name = "coreaudio-rs" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aae284fbaf7d27aa0e292f7677dfbe26503b0d555026f702940805a630eac17" +dependencies = [ + "bitflags 1.3.2", + "libc", + "objc2-audio-toolbox", + "objc2-core-audio", + "objc2-core-audio-types", + "objc2-core-foundation", +] + +[[package]] +name = "cosmic-text" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "173852283a9a57a3cbe365d86e74dc428a09c50421477d5ad6fe9d9509e37737" +dependencies = [ + "bitflags 2.10.0", + "fontdb", + "harfrust", + "linebender_resource_handle", + "log", + "rangemap", + "rustc-hash 1.1.0", + "self_cell", + "skrifa", + "smol_str", + "swash", + "sys-locale", + "unicode-bidi", + "unicode-linebreak", + "unicode-script", + "unicode-segmentation", ] [[package]] name = "cpal" -version = "0.15.3" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "873dab07c8f743075e57f524c583985fbaf745602acbe916a01539364369a779" +checksum = "cbd307f43cc2a697e2d1f8bc7a1d824b5269e052209e28883e5bc04d095aaa3f" dependencies = [ "alsa", - "core-foundation-sys", "coreaudio-rs", "dasp_sample", "jni", "js-sys", "libc", "mach2", - "ndk 0.8.0", + "ndk", "ndk-context", - "oboe", + "num-derive", + "num-traits", + "objc2-audio-toolbox", + "objc2-core-audio", + "objc2-core-audio-types", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -1095,6 +1301,34 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-queue" version = "0.3.12" @@ -1112,15 +1346,15 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", "typenum", @@ -1128,82 +1362,101 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.4.6" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697b5419f348fd5ae2478e8018cb016c00a5881c7f46c717de98ffd135a5651c" +checksum = "73736a89c4aff73035ba2ed2e565061954da00d4970fc9ac25dcc85a2a20d790" dependencies = [ - "nix 0.29.0", - "windows-sys 0.59.0", + "dispatch2", + "nix 0.30.1", + "windows-sys 0.61.2", ] [[package]] name = "cursor-icon" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" +checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" [[package]] name = "cxx" -version = "1.0.156" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa3a202fc4f3dd6d2ce5a2f87b04fb2becc00f5643ee9c4743ba10777efb314f" +checksum = "a7620f6cfc4dcca21f2b085b7a890e16c60fd66f560cd69ee60594908dc72ab1" dependencies = [ "cc", + "cxx-build", "cxxbridge-cmd", "cxxbridge-flags", "cxxbridge-macro", - "foldhash", + "foldhash 0.2.0", "link-cplusplus", ] [[package]] -name = "cxx-gen" -version = "0.7.156" +name = "cxx-build" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b9e50968a66aa69ce1ac23bb1b30e1b728adfe3217b0e9267b018a71297a0d" +checksum = "7a9bc1a22964ff6a355fbec24cf68266a0ed28f8b84c0864c386474ea3d0e479" dependencies = [ + "cc", "codespan-reporting", + "indexmap 2.12.1", "proc-macro2", "quote", - "syn 2.0.100", + "scratch", + "syn 2.0.111", +] + +[[package]] +name = "cxx-gen" +version = "0.7.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e660ae76bd5fcfe7baa8510b93bdb684be66a5f84b72fd91eb7f90ad24a7c3b" +dependencies = [ + "codespan-reporting", + "indexmap 2.12.1", + "proc-macro2", + "quote", + "syn 2.0.111", ] [[package]] name = "cxxbridge-cmd" -version = "1.0.156" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8cefbebcb74ed0b4a08b76139e6c29d8884a0bb94d02c6f35de821a14a6e39" +checksum = "b1f29a879d35f7906e3c9b77d7a1005a6a0787d330c09dfe4ffb5f617728cb44" dependencies = [ "clap", "codespan-reporting", + "indexmap 2.12.1", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "cxxbridge-flags" -version = "1.0.156" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604e3eff62e2f27289d618f621491a068330c3c9f8eb06555dabc292c123596e" +checksum = "d67109015f93f683e364085aa6489a5b2118b4a40058482101d699936a7836d6" [[package]] name = "cxxbridge-macro" -version = "1.0.156" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "130c3a05501d9c15dedbf08f2ff9af60f8e78422e3dffac1f43e2d83c5b489a1" +checksum = "d187e019e7b05a1f3e69a8396b70800ee867aa9fc2ab972761173ccee03742df" dependencies = [ + "indexmap 2.12.1", "proc-macro2", "quote", - "rustversion", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "darling" -version = "0.20.11" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" dependencies = [ "darling_core", "darling_macro", @@ -1211,26 +1464,43 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.11" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "darling_macro" -version = "0.20.11" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core", "quote", - "syn 2.0.100", + "syn 2.0.111", +] + +[[package]] +name = "dash-frontend" +version = "0.1.0" +dependencies = [ + "anyhow", + "chrono", + "gio 0.21.5", + "glam", + "gtk", + "log", + "rust-embed", + "serde", + "serde_json", + "wgui", + "wlx-common", ] [[package]] @@ -1240,14 +1510,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f" [[package]] -name = "dbus" -version = "0.9.7" +name = "data-url" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bb21987b9fb1613058ba3843121dd18b163b254d8a6e797e144cbac14d96d1b" +checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376" + +[[package]] +name = "dbus" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190b6255e8ab55a7b568df5a883e9497edc3e4821c06396612048b430e5ad1e9" dependencies = [ "libc", "libdbus-sys", - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -1256,7 +1532,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479dfe1e6737aa9e96c6ac7b69689dc4c32da8383f2c12744739d76afa8b66c4" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "byteorder", "enum-primitive-derive", "num-traits", @@ -1264,24 +1540,24 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.0" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" dependencies = [ "powerfmt", ] [[package]] name = "derive_more" -version = "0.99.19" +version = "0.99.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3da29a38df43d6f156149c9b43ded5e018ddff2a855cf2cfd62e8cd7d079c69f" +checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" dependencies = [ "convert_case 0.4.0", "proc-macro2", "quote", "rustc_version", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -1300,6 +1576,18 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +[[package]] +name = "dispatch2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +dependencies = [ + "bitflags 2.10.0", + "block2 0.6.2", + "libc", + "objc2 0.6.3", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -1308,7 +1596,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -1334,13 +1622,13 @@ dependencies = [ [[package]] name = "dlopen2_derive" -version = "0.4.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54" +checksum = "0fbbb781877580993a8707ec48672673ec7b81eeba04cfd2310bd28c08e47c8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -1366,9 +1654,9 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "dpi" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" +checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" [[package]] name = "drm" @@ -1376,7 +1664,7 @@ version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80bc8c5c6c2941f70a55c15f8d9f00f9710ebda3ffda98075f996a0e6c92756f" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "bytemuck", "drm-ffi", "drm-fourcc", @@ -1427,9 +1715,9 @@ dependencies = [ [[package]] name = "endi" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" +checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099" [[package]] name = "enum-primitive-derive" @@ -1444,9 +1732,9 @@ dependencies = [ [[package]] name = "enumflags2" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba2f4b465f5318854c6f8dd686ede6c0a9dc67d4b1ac241cf0eb51521a309147" +checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" dependencies = [ "enumflags2_derive", "serde", @@ -1454,34 +1742,34 @@ dependencies = [ [[package]] name = "enumflags2_derive" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4caf64a58d7a6d65ab00639b046ff54399a39f5f2554728895ace4b297cd79" +checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "enumset" -version = "1.1.5" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a4b049558765cef5f0c1a273c3fc57084d768b44d2f98127aef4cceb17293" +checksum = "25b07a8dfbbbfc0064c0a6bdf9edcf966de6b1c33ce344bdeca3b41615452634" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" -version = "0.10.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59c3b24c345d8c314966bdc1832f6c2635bfcce8e7cf363bd115987bba2ee242" +checksum = "f43e744e4ea338060faee68ed933e46e722fb7f3617e722a5772d7e856d8b3ce" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -1497,6 +1785,26 @@ dependencies = [ "termcolor", ] +[[package]] +name = "equator" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4711b213838dfee0117e3be6ac926007d7f433d7bbe33595975d4190cb07e6fc" +dependencies = [ + "equator-macro", +] + +[[package]] +name = "equator-macro" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -1504,20 +1812,50 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] -name = "errno" -version = "0.3.11" +name = "erased-serde" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" +checksum = "89e8918065695684b2b0702da20382d5ae6065cf3327bc2d6436bd49a71ce9f3" +dependencies = [ + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", +] + +[[package]] +name = "etagere" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc89bf99e5dc15954a60f707c1e09d7540e5cd9af85fa75caa0b510bc08c5342" +dependencies = [ + "euclid", + "svg_fmt", +] + +[[package]] +name = "euclid" +version = "0.22.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad9cdb4b747e485a12abb0e6566612956c7a1bafa3bdb8d682c5b6d403589e48" +dependencies = [ + "num-traits", ] [[package]] name = "event-listener" -version = "5.4.0" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" dependencies = [ "concurrent-queue", "parking", @@ -1534,6 +1872,27 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "exr" +version = "1.74.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4300e043a56aa2cb633c01af81ca8f699a321879a7854d3896a0ba89056363be" +dependencies = [ + "bit_field", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + +[[package]] +name = "extended" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af9673d8203fcb076b19dfd17e38b3d4ae9f44959416ea532ce72415a6020365" + [[package]] name = "fastrand" version = "2.3.0" @@ -1541,10 +1900,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] -name = "fixedbitset" -version = "0.4.2" +name = "fdeflate" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" + +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" [[package]] name = "flagset" @@ -1552,6 +1936,22 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7ac824320a75a52197e8f2d787f6a38b6718bb6897a35142d749af3c0e8f4fe" +[[package]] +name = "flate2" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" + [[package]] name = "fnv" version = "1.0.7" @@ -1565,15 +1965,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] -name = "fontconfig-rs" -version = "0.1.1" +name = "foldhash" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4baadad5111c6820e97fc8bde5077258e6f272b5b38538db4b42e1812f29f3" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "font-types" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39a654f404bbcbd48ea58c617c2993ee91d1cb63727a37bf2323a4edeed1b8c5" dependencies = [ - "const-cstr", - "once_cell", - "thiserror 1.0.69", - "yeslogic-fontconfig-sys", + "bytemuck", +] + +[[package]] +name = "fontconfig-parser" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbc773e24e02d4ddd8395fd30dc147524273a83e54e0f312d986ea30de5f5646" +dependencies = [ + "roxmltree 0.20.0", +] + +[[package]] +name = "fontdb" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "457e789b3d1202543297a350643cf459f836cade38934e7a4cf6a39e7cde2905" +dependencies = [ + "fontconfig-parser", + "log", + "memmap2", + "slotmap", + "tinyvec", + "ttf-parser", ] [[package]] @@ -1594,7 +2020,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -1605,35 +2031,13 @@ checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] -[[package]] -name = "freetype-rs" -version = "0.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5442dee36ca09604133580dc0553780e867936bb3cbef3275859e889026d2b17" -dependencies = [ - "bitflags 2.9.0", - "freetype-sys", - "libc", -] - -[[package]] -name = "freetype-sys" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7edc5b9669349acfda99533e9e0bcf26a51862ab43b08ee7745c55d28eb134" -dependencies = [ - "cc", - "libc", - "pkg-config", -] - [[package]] name = "futures" version = "0.3.31" @@ -1684,9 +2088,9 @@ checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-lite" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" dependencies = [ "fastrand", "futures-core", @@ -1703,7 +2107,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -1736,6 +2140,64 @@ dependencies = [ "slab", ] +[[package]] +name = "gdk" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9f245958c627ac99d8e529166f9823fb3b838d1d41fd2b297af3075093c2691" +dependencies = [ + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio 0.18.4", + "glib 0.18.5", + "libc", + "pango", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec" +dependencies = [ + "gdk-pixbuf-sys", + "gio 0.18.4", + "glib 0.18.5", + "libc", + "once_cell", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7" +dependencies = [ + "gio-sys 0.18.1", + "glib-sys 0.18.1", + "gobject-sys 0.18.0", + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "gdk-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c2d13f38594ac1e66619e188c6d5a1adb98d11b2fcf7894fc416ad76aa2f3f7" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys 0.18.1", + "glib-sys 0.18.1", + "gobject-sys 0.18.0", + "libc", + "pango-sys", + "pkg-config", + "system-deps 6.2.2", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -1748,42 +2210,114 @@ dependencies = [ [[package]] name = "gethostname" -version = "0.4.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" dependencies = [ - "libc", - "windows-targets 0.48.5", + "rustix 1.1.2", + "windows-link 0.2.1", ] [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", ] [[package]] name = "getrandom" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasip2", +] + +[[package]] +name = "gif" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5df2ba84018d80c213569363bdcd0c64e6933c67fe4c1d60ecf822971a3c35e" +dependencies = [ + "color_quant", + "weezl", ] [[package]] name = "gimli" -version = "0.31.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" + +[[package]] +name = "gio" +version = "0.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fc8f532f87b79cbc51a79748f16a6828fb784be93145a322fa14d06d354c73" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys 0.18.1", + "glib 0.18.5", + "libc", + "once_cell", + "pin-project-lite", + "smallvec", + "thiserror 1.0.69", +] + +[[package]] +name = "gio" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5ff48bf600c68b476e61dc6b7c762f2f4eb91deef66583ba8bb815c30b5811a" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys 0.21.5", + "glib 0.21.5", + "libc", + "pin-project-lite", + "smallvec", +] + +[[package]] +name = "gio-sys" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2" +dependencies = [ + "glib-sys 0.18.1", + "gobject-sys 0.18.0", + "libc", + "system-deps 6.2.2", + "winapi", +] + +[[package]] +name = "gio-sys" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0071fe88dba8e40086c8ff9bbb62622999f49628344b1d1bf490a48a29d80f22" +dependencies = [ + "glib-sys 0.21.5", + "gobject-sys 0.21.5", + "libc", + "system-deps 7.0.7", + "windows-sys 0.61.2", +] [[package]] name = "gl_generator" @@ -1798,30 +2332,214 @@ dependencies = [ [[package]] name = "glam" -version = "0.30.1" +version = "0.30.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf3aa70d918d2b234126ff4f850f628f172542bf0603ded26b8ee36e5e22d5f9" +checksum = "bd47b05dddf0005d850e5644cae7f2b14ac3df487979dbfff3b56f20b1a6ae46" dependencies = [ - "approx 0.5.1", "mint", - "serde", + "serde_core", +] + +[[package]] +name = "glib" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" +dependencies = [ + "bitflags 2.10.0", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys 0.18.1", + "glib-macros 0.18.5", + "glib-sys 0.18.1", + "gobject-sys 0.18.0", + "libc", + "memchr", + "once_cell", + "smallvec", + "thiserror 1.0.69", +] + +[[package]] +name = "glib" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16de123c2e6c90ce3b573b7330de19be649080ec612033d397d72da265f1bd8b" +dependencies = [ + "bitflags 2.10.0", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys 0.21.5", + "glib-macros 0.21.5", + "glib-sys 0.21.5", + "gobject-sys 0.21.5", + "libc", + "memchr", + "smallvec", +] + +[[package]] +name = "glib-macros" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc" +dependencies = [ + "heck 0.4.1", + "proc-macro-crate 2.0.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "glib-macros" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf59b675301228a696fe01c3073974643365080a76cc3ed5bc2cbc466ad87f17" +dependencies = [ + "heck 0.5.0", + "proc-macro-crate 3.4.0", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "glib-sys" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898" +dependencies = [ + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "glib-sys" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d95e1a3a19ae464a7286e14af9a90683c64d70c02532d88d87ce95056af3e6c" +dependencies = [ + "libc", + "system-deps 7.0.7", ] [[package]] name = "glob" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "gobject-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44" +dependencies = [ + "glib-sys 0.18.1", + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "gobject-sys" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dca35da0d19a18f4575f3cb99fe1c9e029a2941af5662f326f738a21edaf294" +dependencies = [ + "glib-sys 0.21.5", + "libc", + "system-deps 7.0.7", +] + +[[package]] +name = "grid" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9e2d4c0a8296178d8802098410ca05d86b17a10bb5ab559b3fb404c1f948220" + +[[package]] +name = "gtk" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd56fb197bfc42bd5d2751f4f017d44ff59fbb58140c6b49f9b3b2bdab08506a" +dependencies = [ + "atk", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk", + "gdk-pixbuf", + "gio 0.18.4", + "glib 0.18.5", + "gtk-sys", + "gtk3-macros", + "libc", + "pango", + "pkg-config", +] + +[[package]] +name = "gtk-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f29a1c21c59553eb7dd40e918be54dccd60c52b049b75119d5d96ce6b624414" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys 0.18.1", + "glib-sys 0.18.1", + "gobject-sys 0.18.0", + "libc", + "pango-sys", + "system-deps 6.2.2", +] + +[[package]] +name = "gtk3-macros" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ff3c5b21f14f0736fed6dcfc0bfb4225ebf5725f3c0209edeec181e4d73e9d" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.111", +] [[package]] name = "half" -version = "2.6.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ "bytemuck", "cfg-if", "crunchy", + "zerocopy", +] + +[[package]] +name = "harfrust" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92c020db12c71d8a12a3fe7607873cade3a01a6287e29d540c8723276221b9d8" +dependencies = [ + "bitflags 2.10.0", + "bytemuck", + "core_maths", + "read-fonts", + "smallvec", ] [[package]] @@ -1838,11 +2556,22 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "foldhash", + "foldhash 0.1.5", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", ] [[package]] @@ -1851,7 +2580,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ - "hashbrown 0.15.2", + "hashbrown 0.15.5", ] [[package]] @@ -1877,9 +2606,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.4.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "hex" @@ -1889,11 +2618,11 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "home" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1904,15 +2633,15 @@ checksum = "62adaabb884c94955b19907d60019f4e145d091c75345379e70d1ee696f7854f" [[package]] name = "humantime" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" +checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" [[package]] name = "iana-time-zone" -version = "0.1.63" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1920,7 +2649,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.61.0", + "windows-core 0.62.2", ] [[package]] @@ -1934,21 +2663,22 @@ dependencies = [ [[package]] name = "icu_collections" -version = "1.5.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ "displaydoc", + "potential_utf", "yoke", "zerofrom", "zerovec", ] [[package]] -name = "icu_locid" -version = "1.5.0" +name = "icu_locale_core" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" dependencies = [ "displaydoc", "litemap", @@ -1957,99 +2687,61 @@ dependencies = [ "zerovec", ] -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" - [[package]] name = "icu_normalizer" -version = "1.5.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" dependencies = [ - "displaydoc", "icu_collections", "icu_normalizer_data", "icu_properties", "icu_provider", "smallvec", - "utf16_iter", - "utf8_iter", - "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" -version = "1.5.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "1.5.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" dependencies = [ - "displaydoc", "icu_collections", - "icu_locid_transform", + "icu_locale_core", "icu_properties_data", "icu_provider", - "tinystr", + "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "1.5.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" +checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" [[package]] name = "icu_provider" -version = "1.5.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" dependencies = [ "displaydoc", - "icu_locid", - "icu_provider_macros", - "stable_deref_trait", - "tinystr", + "icu_locale_core", "writeable", "yoke", "zerofrom", + "zerotrie", "zerovec", ] -[[package]] -name = "icu_provider_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", -] - [[package]] name = "ident_case" version = "1.0.1" @@ -2058,9 +2750,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idmap" -version = "0.2.21" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dba885f996064df334b1639785897d1c58c0646750101b839b8359664cb26c0e" +checksum = "1f92530a7d4564864380ca6747ef14312d264a342d1e6ada9e754debb2c789d4" dependencies = [ "fixedbitset", "serde", @@ -2068,20 +2760,20 @@ dependencies = [ [[package]] name = "idmap-derive" -version = "0.1.2" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3f44aa1b60e7de7e2833ad2cc3bc79880171d1e1efdb44ca833a1acf8102870" +checksum = "ac03bebb34669b3ef9c04ab65926ddf3513f5b5b74b45c540bf250829a1e92eb" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.111", ] [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -2090,14 +2782,45 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", ] +[[package]] +name = "image" +version = "0.25.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6506c6c10786659413faa717ceebcb8f70731c0a60cbae39795fdf114519c1a" +dependencies = [ + "bytemuck", + "byteorder-lite", + "color_quant", + "exr", + "gif", + "image-webp", + "moxcms", + "num-traits", + "png 0.18.0", + "ravif", + "rayon", + "zune-core", + "zune-jpeg", +] + +[[package]] +name = "image-webp" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3" +dependencies = [ + "byteorder-lite", + "quick-error", +] + [[package]] name = "image_dds" version = "0.7.2" @@ -2111,6 +2834,18 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "imagesize" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edcd27d72f2f071c64249075f42e205ff93c9a4c5f6c6da53e79ed9f9832c285" + +[[package]] +name = "imgref" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c5cedc30da3a610cac6b4ba17597bdf7152cf974e8aab3afb3d54455e371c8" + [[package]] name = "indexmap" version = "1.9.3" @@ -2124,12 +2859,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.9.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", - "hashbrown 0.15.2", + "hashbrown 0.16.1", ] [[package]] @@ -2158,6 +2893,17 @@ dependencies = [ "nix 0.29.0", ] +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + [[package]] name = "interprocess" version = "2.2.3" @@ -2173,9 +2919,9 @@ dependencies = [ [[package]] name = "is_terminal_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itertools" @@ -2213,6 +2959,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.15" @@ -2243,19 +2998,19 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ - "getrandom 0.3.2", + "getrandom 0.3.4", "libc", ] [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" dependencies = [ "once_cell", "wasm-bindgen", @@ -2278,6 +3033,16 @@ dependencies = [ "serde", ] +[[package]] +name = "json5" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c86c72f9e1d3fe29baa32cab8896548eef9aae271fce4e796d16b583fdf6d5" +dependencies = [ + "serde", + "ucd-trie", +] + [[package]] name = "khronos-egl" version = "6.0.0" @@ -2294,6 +3059,17 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" +[[package]] +name = "kurbo" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62026ae44756f8a599ba21140f350303d4f08dcdcc71b5ad9c9bb8128c13c62" +dependencies = [ + "arrayvec", + "euclid", + "smallvec", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -2307,37 +3083,59 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] -name = "libc" -version = "0.2.171" +name = "lebe" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8" + +[[package]] +name = "libc" +version = "0.2.178" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" [[package]] name = "libdbus-sys" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06085512b750d640299b79be4bad3d2fa90a9c00b1fd9e1b46364f66f0485c72" +checksum = "5cbe856efeb50e4681f010e9aaa2bf0a644e10139e54cde10fc83a307c23bd9f" dependencies = [ "pkg-config", ] [[package]] -name = "libloading" -version = "0.8.6" +name = "libfuzzer-sys" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +checksum = "5037190e1f70cbeef565bd267599242926f724d3b8a9f510fd7e0b540cfa4404" +dependencies = [ + "arbitrary", + "cc", +] + +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-link 0.2.1", ] +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + [[package]] name = "libmonado" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f56d8582a273a05076c57d5478faa51c39958744760938f2da770e890b43c62d" dependencies = [ - "bindgen 0.69.5", + "bindgen", "cmake", "convert_case 0.6.0", "dlopen2", @@ -2347,18 +3145,18 @@ dependencies = [ "semver", "serde", "serde_json", - "xdg", + "xdg 2.5.2", ] [[package]] name = "libredox" -version = "0.1.3" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "libc", - "redox_syscall 0.5.11", + "redox_syscall 0.5.18", ] [[package]] @@ -2366,15 +3164,15 @@ name = "libspa" version = "0.8.0" source = "git+https://gitlab.freedesktop.org/galister/pipewire-rs.git#ba32202c3c391004c3bb533b58fa75a50e47ff57" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "cc", "convert_case 0.6.0", "cookie-factory", "libc", "libspa-sys", "nix 0.27.1", - "nom", - "system-deps", + "nom 7.1.3", + "system-deps 6.2.2", ] [[package]] @@ -2382,16 +3180,22 @@ name = "libspa-sys" version = "0.8.0" source = "git+https://gitlab.freedesktop.org/galister/pipewire-rs.git#ba32202c3c391004c3bb533b58fa75a50e47ff57" dependencies = [ - "bindgen 0.69.5", + "bindgen", "cc", - "system-deps", + "system-deps 6.2.2", ] [[package]] -name = "link-cplusplus" -version = "1.0.10" +name = "linebender_resource_handle" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a6f6da007f968f9def0d65a05b187e2960183de70c160204ecfccf0ee330212" +checksum = "d4a5ff6bcca6c4867b1c4fd4ef63e4db7436ef363e0ad7531d1558856bae64f4" + +[[package]] +name = "link-cplusplus" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f78c730aaa7d0b9336a299029ea49f9ee53b0ed06e9202e8cb7db9bae7b8c82" dependencies = [ "cc", ] @@ -2410,31 +3214,30 @@ checksum = "2a385b1be4e5c3e362ad2ffa73c392e53f031eaa5b7d648e64cd87f27f6063d7" [[package]] name = "linux-raw-sys" -version = "0.9.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" -version = "0.7.5" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.27" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "log-panics" @@ -2447,43 +3250,62 @@ dependencies = [ ] [[package]] -name = "mach2" -version = "0.4.2" +name = "loop9" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + +[[package]] +name = "lru" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96051b46fc183dc9cd4a223960ef37b9af631b55191852a8274bfef064cda20f" +dependencies = [ + "hashbrown 0.16.1", +] + +[[package]] +name = "mach2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" dependencies = [ "libc", ] [[package]] name = "matchers" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" dependencies = [ - "regex-automata 0.1.10", + "regex-automata", +] + +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", ] [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "memmap2" -version = "0.8.0" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a5a03cefb0d953ec0be133036f14e109412fa594edc2f77227249db66cc3ed" -dependencies = [ - "libc", -] - -[[package]] -name = "memmap2" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" +checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" dependencies = [ "libc", ] @@ -2517,7 +3339,7 @@ checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -2528,11 +3350,12 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", + "simd-adler32", ] [[package]] @@ -2551,17 +3374,13 @@ dependencies = [ ] [[package]] -name = "ndk" -version = "0.8.0" +name = "moxcms" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" +checksum = "80986bbbcf925ebd3be54c26613d861255284584501595cf418320c078945608" dependencies = [ - "bitflags 2.9.0", - "jni-sys", - "log", - "ndk-sys 0.5.0+25.2.9519653", - "num_enum", - "thiserror 1.0.69", + "num-traits", + "pxfm", ] [[package]] @@ -2570,10 +3389,10 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "jni-sys", "log", - "ndk-sys 0.6.0+11769913", + "ndk-sys", "num_enum", "raw-window-handle", "thiserror 1.0.69", @@ -2585,15 +3404,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" -[[package]] -name = "ndk-sys" -version = "0.5.0+25.2.9519653" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" -dependencies = [ - "jni-sys", -] - [[package]] name = "ndk-sys" version = "0.6.0+11769913" @@ -2603,13 +3413,19 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + [[package]] name = "nix" version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "cfg-if", "libc", ] @@ -2620,7 +3436,19 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", + "cfg-if", + "cfg_aliases", + "libc", +] + +[[package]] +name = "nix" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +dependencies = [ + "bitflags 2.10.0", "cfg-if", "cfg_aliases", "libc", @@ -2638,12 +3466,27 @@ dependencies = [ ] [[package]] -name = "normpath" -version = "1.3.0" +name = "nom" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8911957c4b1549ac0dc74e30db9c8b0e66ddcd6d7acc33098f4c63a64a6d7ed" +checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" dependencies = [ - "windows-sys 0.59.0", + "memchr", +] + +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + +[[package]] +name = "normpath" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf23ab2b905654b4cb177e30b629937b3868311d4e1cba859f899c041046e69b" +dependencies = [ + "windows-sys 0.61.2", ] [[package]] @@ -2657,12 +3500,21 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.46.0" +version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "overload", - "winapi", + "windows-sys 0.61.2", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", ] [[package]] @@ -2679,7 +3531,27 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", ] [[package]] @@ -2693,23 +3565,24 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.3" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" dependencies = [ "num_enum_derive", + "rustversion", ] [[package]] name = "num_enum_derive" -version = "0.7.3" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -2730,9 +3603,9 @@ dependencies = [ [[package]] name = "objc2" -version = "0.6.0" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3531f65190d9cff863b77a99857e74c314dd16bf56c538c4b57c7cbc3f3a6e59" +checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" dependencies = [ "objc2-encode", ] @@ -2743,8 +3616,8 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ - "bitflags 2.9.0", - "block2", + "bitflags 2.10.0", + "block2 0.5.1", "libc", "objc2 0.5.2", "objc2-core-data", @@ -2753,14 +3626,29 @@ dependencies = [ "objc2-quartz-core 0.2.2", ] +[[package]] +name = "objc2-audio-toolbox" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6948501a91121d6399b79abaa33a8aa4ea7857fe019f341b8c23ad6e81b79b08" +dependencies = [ + "bitflags 2.10.0", + "libc", + "objc2 0.6.3", + "objc2-core-audio", + "objc2-core-audio-types", + "objc2-core-foundation", + "objc2-foundation 0.3.2", +] + [[package]] name = "objc2-cloud-kit" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ - "bitflags 2.9.0", - "block2", + "bitflags 2.10.0", + "block2 0.5.1", "objc2 0.5.2", "objc2-core-location", "objc2-foundation 0.2.2", @@ -2772,31 +3660,54 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" dependencies = [ - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", ] +[[package]] +name = "objc2-core-audio" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1eebcea8b0dbff5f7c8504f3107c68fc061a3eb44932051c8cf8a68d969c3b2" +dependencies = [ + "dispatch2", + "objc2 0.6.3", + "objc2-core-audio-types", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-core-audio-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a89f2ec274a0cf4a32642b2991e8b351a404d290da87bb6a9a9d8632490bd1c" +dependencies = [ + "bitflags 2.10.0", + "objc2 0.6.3", +] + [[package]] name = "objc2-core-data" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "bitflags 2.9.0", - "block2", + "bitflags 2.10.0", + "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", ] [[package]] name = "objc2-core-foundation" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daeaf60f25471d26948a1c2f840e3f7d86f4109e3af4e8e4b5cd70c39690d925" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.9.0", - "objc2 0.6.0", + "bitflags 2.10.0", + "dispatch2", + "objc2 0.6.3", ] [[package]] @@ -2805,7 +3716,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" dependencies = [ - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", "objc2-metal 0.2.2", @@ -2817,7 +3728,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" dependencies = [ - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-contacts", "objc2-foundation 0.2.2", @@ -2835,8 +3746,8 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ - "bitflags 2.9.0", - "block2", + "bitflags 2.10.0", + "block2 0.5.1", "dispatch", "libc", "objc2 0.5.2", @@ -2844,12 +3755,22 @@ dependencies = [ [[package]] name = "objc2-foundation" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a21c6c9014b82c39515db5b396f91645182611c97d24637cf56ac01e5f8d998" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ - "bitflags 2.9.0", - "objc2 0.6.0", + "bitflags 2.10.0", + "objc2 0.6.3", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-io-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15" +dependencies = [ + "libc", "objc2-core-foundation", ] @@ -2859,7 +3780,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" dependencies = [ - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-app-kit", "objc2-foundation 0.2.2", @@ -2871,21 +3792,21 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ - "bitflags 2.9.0", - "block2", + "bitflags 2.10.0", + "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", ] [[package]] name = "objc2-metal" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c41bc8b0e50ea7a5304a56f25e0066f526e99641b46fd7b9ad4421dd35bff6" +checksum = "a0125f776a10d00af4152d74616409f0d4a2053a6f57fa5b7d6aa2854ac04794" dependencies = [ - "bitflags 2.9.0", - "objc2 0.6.0", - "objc2-foundation 0.3.0", + "bitflags 2.10.0", + "objc2 0.6.3", + "objc2-foundation 0.3.2", ] [[package]] @@ -2894,8 +3815,8 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ - "bitflags 2.9.0", - "block2", + "bitflags 2.10.0", + "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", "objc2-metal 0.2.2", @@ -2903,15 +3824,15 @@ dependencies = [ [[package]] name = "objc2-quartz-core" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb3794501bb1bee12f08dcad8c61f2a5875791ad1c6f47faa71a0f033f20071" +checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" dependencies = [ - "bitflags 2.9.0", - "objc2 0.6.0", + "bitflags 2.10.0", + "objc2 0.6.3", "objc2-core-foundation", - "objc2-foundation 0.3.0", - "objc2-metal 0.3.0", + "objc2-foundation 0.3.2", + "objc2-metal 0.3.2", ] [[package]] @@ -2930,8 +3851,8 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ - "bitflags 2.9.0", - "block2", + "bitflags 2.10.0", + "block2 0.5.1", "objc2 0.5.2", "objc2-cloud-kit", "objc2-core-data", @@ -2951,7 +3872,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" dependencies = [ - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", ] @@ -2962,8 +3883,8 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ - "bitflags 2.9.0", - "block2", + "bitflags 2.10.0", + "block2 0.5.1", "objc2 0.5.2", "objc2-core-location", "objc2-foundation 0.2.2", @@ -2971,42 +3892,25 @@ dependencies = [ [[package]] name = "object" -version = "0.36.7" +version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "memchr", ] -[[package]] -name = "oboe" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8b61bebd49e5d43f5f8cc7ee2891c16e0f41ec7954d36bcb6c14c5e0de867fb" -dependencies = [ - "jni", - "ndk 0.8.0", - "ndk-context", - "num-derive", - "num-traits", - "oboe-sys", -] - -[[package]] -name = "oboe-sys" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8bb09a4a2b1d668170cfe0a7d5bc103f8999fb316c98099b6a9939c9f2e79d" -dependencies = [ - "cc", -] - [[package]] name = "once_cell" version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + [[package]] name = "openxr" version = "0.19.0" @@ -3029,9 +3933,9 @@ dependencies = [ [[package]] name = "orbclient" -version = "0.3.48" +version = "0.3.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba0b26cec2e24f08ed8bb31519a9333140a6599b867dac464bb150bdb796fd43" +checksum = "247ad146e19b9437f8604c21f8652423595cf710ad108af40e77d3ae6e96b827" dependencies = [ "libredox", ] @@ -3057,10 +3961,28 @@ dependencies = [ ] [[package]] -name = "overload" -version = "0.1.1" +name = "ouroboros" +version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +checksum = "1e0f050db9c44b97a94723127e6be766ac5c340c48f2c4bb3ffa11713744be59" +dependencies = [ + "aliasable", + "ouroboros_macro", + "static_assertions", +] + +[[package]] +name = "ouroboros_macro" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c7028bdd3d43083f6d8d4d5187680d0d3560d54df4cc9d752005268b41e64d0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn 2.0.111", +] [[package]] name = "ovr_overlay" @@ -3091,13 +4013,38 @@ dependencies = [ [[package]] name = "owned_ttf_parser" -version = "0.25.0" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec719bbf3b2a81c109a4e20b1f129b5566b7dce654bc3872f6a05abf82b2c4" +checksum = "36820e9051aca1014ddc75770aab4d68bc1e9e632f0f5627c4086bc216fb583b" dependencies = [ "ttf-parser", ] +[[package]] +name = "pango" +version = "0.18.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4" +dependencies = [ + "gio 0.18.4", + "glib 0.18.5", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5" +dependencies = [ + "glib-sys 0.18.1", + "gobject-sys 0.18.0", + "libc", + "system-deps 6.2.2", +] + [[package]] name = "parking" version = "2.2.1" @@ -3106,9 +4053,9 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -3116,25 +4063,28 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.11", + "redox_syscall 0.5.18", "smallvec", - "windows-targets 0.52.6", + "windows-link 0.2.1", ] [[package]] -name = "parse-zoneinfo" -version = "0.3.1" +name = "paste" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24" -dependencies = [ - "regex", -] +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pastey" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec" [[package]] name = "pathdiff" @@ -3144,26 +4094,25 @@ checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.0" +version = "2.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "198db74531d58c70a361c42201efde7e2591e976d518caf7662a47dc5720e7b6" +checksum = "cbcfd20a6d4eeba40179f05735784ad32bdaef05ce8e8af05f180d45bb3e7e22" dependencies = [ "memchr", - "thiserror 2.0.12", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.8.0" +version = "2.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d725d9cfd79e87dccc9341a2ef39d1b6f6353d68c4b33c177febbe1a402c97c5" +checksum = "51f72981ade67b1ca6adc26ec221be9f463f2b5839c7508998daa17c23d94d7f" dependencies = [ "pest", "pest_generator", @@ -3171,66 +4120,51 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.0" +version = "2.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db7d01726be8ab66ab32f9df467ae8b1148906685bbe75c82d1e65d7f5b3f841" +checksum = "dee9efd8cdb50d719a80088b76f81aec7c41ed6d522ee750178f83883d271625" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "pest_meta" -version = "2.8.0" +version = "2.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9f832470494906d1fca5329f8ab5791cc60beb230c74815dff541cbd2b5ca0" +checksum = "bf1d70880e76bdc13ba52eafa6239ce793d85c8e43896507e43dd8984ff05b82" dependencies = [ - "once_cell", "pest", "sha2", ] [[package]] name = "phf" -version = "0.11.3" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7" dependencies = [ "phf_shared", ] -[[package]] -name = "phf_codegen" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" -dependencies = [ - "phf_generator", - "phf_shared", -] - -[[package]] -name = "phf_generator" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" -dependencies = [ - "phf_shared", - "rand 0.8.5", -] - [[package]] name = "phf_shared" -version = "0.11.3" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981" dependencies = [ "siphasher", ] +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + [[package]] name = "pin-project" version = "1.1.10" @@ -3248,7 +4182,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -3280,7 +4214,7 @@ version = "0.8.0" source = "git+https://gitlab.freedesktop.org/galister/pipewire-rs.git#ba32202c3c391004c3bb533b58fa75a50e47ff57" dependencies = [ "anyhow", - "bitflags 2.9.0", + "bitflags 2.10.0", "libc", "libspa", "libspa-sys", @@ -3295,9 +4229,9 @@ name = "pipewire-sys" version = "0.8.0" source = "git+https://gitlab.freedesktop.org/galister/pipewire-rs.git#ba32202c3c391004c3bb533b58fa75a50e47ff57" dependencies = [ - "bindgen 0.69.5", + "bindgen", "libspa-sys", - "system-deps", + "system-deps 6.2.2", ] [[package]] @@ -3307,18 +4241,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] -name = "polling" -version = "3.7.4" +name = "png" +version = "0.17.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "png" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0" +dependencies = [ + "bitflags 2.10.0", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "polling" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" dependencies = [ "cfg-if", "concurrent-queue", - "hermit-abi 0.4.0", + "hermit-abi 0.5.2", "pin-project-lite", - "rustix 0.38.44", - "tracing", - "windows-sys 0.59.0", + "rustix 1.1.2", + "windows-sys 0.61.2", +] + +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", ] [[package]] @@ -3333,26 +4301,45 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy 0.8.24", + "zerocopy", ] [[package]] name = "prettyplease" -version = "0.2.32" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "proc-macro-crate" -version = "3.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ - "toml_edit", + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +dependencies = [ + "toml_edit 0.20.7", +] + +[[package]] +name = "proc-macro-crate" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +dependencies = [ + "toml_edit 0.23.9", ] [[package]] @@ -3381,32 +4368,60 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] [[package]] -name = "profiling" -version = "1.0.16" +name = "proc-macro2-diagnostics" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", + "version_check", + "yansi", +] + +[[package]] +name = "profiling" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" dependencies = [ "profiling-procmacros", ] [[package]] name = "profiling-procmacros" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" +checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b" dependencies = [ "quote", - "syn 2.0.100", + "syn 2.0.111", ] +[[package]] +name = "pxfm" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7186d3822593aa4393561d186d1393b3923e9d6163d3fbfd6e825e3e6cf3e6a8" +dependencies = [ + "num-traits", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "quick-xml" version = "0.30.0" @@ -3418,58 +4433,36 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.37.4" +version = "0.37.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4ce8c88de324ff838700f36fb6ab86c96df0e3c4ab6ef3a9b2044465cce1369" +checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" dependencies = [ "memchr", ] [[package]] name = "quote" -version = "1.0.40" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] [[package]] name = "r-efi" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "rand" -version = "0.8.5" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" -dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.3", - "zerocopy 0.8.24", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", + "rand_chacha", + "rand_core", ] [[package]] @@ -3479,16 +4472,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.15", + "rand_core", ] [[package]] @@ -3497,7 +4481,63 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.2", + "getrandom 0.3.4", +] + +[[package]] +name = "rangemap" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbbbbea733ec66275512d0b9694f34102e7d5406fdbe2ad8d21b28dce92887c" + +[[package]] +name = "rav1e" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b6dd56e85d9483277cde964fd1bdb0428de4fec5ebba7540995639a21cb32b" +dependencies = [ + "aligned-vec", + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av-scenechange", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools 0.14.0", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive", + "num-traits", + "paste", + "profiling", + "rand", + "rand_chacha", + "simd_helpers", + "thiserror 2.0.17", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef69c1990ceef18a116855938e74793a5f7496ee907562bd0857b6ac734ab285" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rayon", + "rgb", ] [[package]] @@ -3512,10 +4552,41 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40d213455a5f1dc59214213c7330e074ddf8114c9a42411eb890c767357ce135" dependencies = [ - "objc2 0.6.0", + "objc2 0.6.3", "objc2-core-foundation", - "objc2-foundation 0.3.0", - "objc2-quartz-core 0.3.0", + "objc2-foundation 0.3.2", + "objc2-quartz-core 0.3.2", +] + +[[package]] +name = "rayon" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "read-fonts" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6717cf23b488adf64b9d711329542ba34de147df262370221940dfabc2c91358" +dependencies = [ + "bytemuck", + "core_maths", + "font-types", ] [[package]] @@ -3535,77 +4606,90 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.11" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", ] [[package]] name = "regex" -version = "1.11.1" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.9", - "regex-syntax 0.8.5", + "regex-automata", + "regex-syntax", ] [[package]] name = "regex-automata" -version = "0.1.10" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", -] - -[[package]] -name = "regex-automata" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.5", + "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.6.29" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] -name = "regex-syntax" -version = "0.8.5" +name = "resvg" +version = "0.45.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "a8928798c0a55e03c9ca6c4c6846f76377427d2c1e1f7e6de3c06ae57942df43" +dependencies = [ + "log", + "pico-args", + "rgb", + "svgtypes", + "tiny-skia", + "usvg", +] + +[[package]] +name = "rgb" +version = "0.8.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce" +dependencies = [ + "bytemuck", +] [[package]] name = "rodio" -version = "0.20.1" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ceb6607dd738c99bc8cb28eff249b7cd5c8ec88b9db96c0608c1480d140fb1" +checksum = "e40ecf59e742e03336be6a3d53755e789fd05a059fa22dfa0ed624722319e183" dependencies = [ "cpal", + "dasp_sample", "hound", + "num-rational", + "symphonia", ] [[package]] name = "ron" -version = "0.8.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" +checksum = "fd490c5b18261893f14449cbd28cb9c0b637aebf161cd77900bfdedaff21ec32" dependencies = [ - "base64", - "bitflags 2.9.0", + "bitflags 2.10.0", + "once_cell", "serde", "serde_derive", + "typeid", + "unicode-ident", ] [[package]] @@ -3615,7 +4699,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd37602e1513794e952274082d074e8d31aa7f64d047e3acb746c91db40600a5" dependencies = [ "byteorder", - "nom", + "nom 7.1.3", "time", ] @@ -3629,21 +4713,69 @@ dependencies = [ ] [[package]] -name = "rust-ini" +name = "roxmltree" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" + +[[package]] +name = "roxmltree" version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e310ef0e1b6eeb79169a1171daf9abcb87a2e17c03bee2c4bb100b55c75409f" +checksum = "f1964b10c76125c36f8afe190065a4bf9a87bf324842c05701330bba9f1cacbb" +dependencies = [ + "memchr", +] + +[[package]] +name = "rust-embed" +version = "8.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "947d7f3fad52b283d261c4c99a084937e2fe492248cb9a68a8435a861b8798ca" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "8.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fa2c8c9e8711e10f9c4fd2d64317ef13feaab820a4c51541f1a8c8e2e851ab2" +dependencies = [ + "proc-macro2", + "quote", + "rust-embed-utils", + "syn 2.0.111", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "8.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b161f275cb337fe0a44d924a5f4df0ed69c2c39519858f931ce61c779d3475" +dependencies = [ + "sha2", + "walkdir", +] + +[[package]] +name = "rust-ini" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "796e8d2b6696392a43bea58116b667fb4c29727dc5abd27d6acf338bb4f688c7" dependencies = [ "cfg-if", "ordered-multimap", - "trim-in-place", ] [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" [[package]] name = "rustc-hash" @@ -3672,7 +4804,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "errno", "libc", "linux-raw-sys 0.4.15", @@ -3681,22 +4813,22 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.5" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "errno", "libc", - "linux-raw-sys 0.9.4", - "windows-sys 0.59.0", + "linux-raw-sys 0.11.0", + "windows-sys 0.61.2", ] [[package]] name = "rustversion" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "rxscreen" @@ -3734,6 +4866,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "scratch" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d68f2ec51b097e4c1a75b681a8bec621909b5e91f15bb7b840c4f2f7b01148b2" + [[package]] name = "sctk-adwaita" version = "0.10.1" @@ -3742,47 +4880,76 @@ checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" dependencies = [ "ab_glyph", "log", - "memmap2 0.9.5", - "smithay-client-toolkit", + "memmap2", + "smithay-client-toolkit 0.19.2", "tiny-skia", ] [[package]] -name = "semver" -version = "1.0.26" +name = "self_cell" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +checksum = "16c2f82143577edb4921b71ede051dac62ca3c16084e918bf7b40c96ae10eb33" + +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde-untagged" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058" +dependencies = [ + "erased-serde", + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "serde_json" -version = "1.0.140" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "itoa", "memchr", "ryu", "serde", + "serde_core", ] [[package]] @@ -3804,25 +4971,34 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "serde_spanned" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392" +dependencies = [ + "serde_core", +] + [[package]] name = "serde_yaml" version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.9.0", + "indexmap 2.12.1", "itoa", "ryu", "serde", @@ -3831,9 +5007,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", @@ -3858,7 +5034,7 @@ checksum = "73120d240fe22196300f39ca8547ca2d014960f27b19b47b21288b396272f7f7" dependencies = [ "cmake", "libc", - "roxmltree", + "roxmltree 0.14.1", ] [[package]] @@ -3878,13 +5054,37 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.2" +version = "1.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" dependencies = [ "libc", ] +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + +[[package]] +name = "simplecss" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a9c6883ca9c3c7c90e888de77b7a5c849c779d25d74a1269b0218b14e8b136c" +dependencies = [ + "log", +] + [[package]] name = "siphasher" version = "1.0.1" @@ -3892,14 +5092,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] -name = "slab" -version = "0.4.9" +name = "skrifa" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +checksum = "8c31071dedf532758ecf3fed987cdb4bd9509f900e026ab684b4ecb81ea49841" dependencies = [ - "autocfg", + "bytemuck", + "read-fonts", ] +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + [[package]] name = "slabbin" version = "1.2.0" @@ -3913,20 +5120,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4f120bb98cb4cb0dab21c882968c3cbff79dd23b46f07b1cf5c25044945ce84" [[package]] -name = "smallvec" -version = "1.15.0" +name = "slotmap" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" +checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "smithay" -version = "0.5.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497aa82b881bf392470c286b213e01f7aa30b2fb08857831f81c87b251ba4d89" +checksum = "740cea6927892bc182d5bf70c8f79806c8bc9f68f2fb96e55a30be171b63af98" dependencies = [ "appendlist", - "bitflags 2.9.0", - "calloop 0.14.2", + "atomic_float", + "bitflags 2.10.0", + "calloop 0.14.3", "cgmath", "cursor-icon", "downcast-rs", @@ -3936,16 +5153,17 @@ dependencies = [ "encoding_rs", "errno", "gl_generator", - "indexmap 2.9.0", + "indexmap 2.12.1", "libc", "libloading", "profiling", - "rand 0.8.5", - "rustix 0.38.44", + "rand", + "rustix 1.1.2", "scopeguard", + "sha2", "smallvec", "tempfile", - "thiserror 1.0.69", + "thiserror 2.0.17", "tracing", "wayland-protocols", "wayland-protocols-misc", @@ -3961,15 +5179,13 @@ version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" dependencies = [ - "bitflags 2.9.0", - "bytemuck", + "bitflags 2.10.0", "calloop 0.13.0", - "calloop-wayland-source", + "calloop-wayland-source 0.3.0", "cursor-icon", "libc", "log", - "memmap2 0.9.5", - "pkg-config", + "memmap2", "rustix 0.38.44", "thiserror 1.0.69", "wayland-backend", @@ -3979,7 +5195,36 @@ dependencies = [ "wayland-protocols", "wayland-protocols-wlr", "wayland-scanner", - "xkbcommon 0.7.0", + "xkeysym", +] + +[[package]] +name = "smithay-client-toolkit" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0512da38f5e2b31201a93524adb8d3136276fa4fe4aafab4e1f727a82b534cc0" +dependencies = [ + "bitflags 2.10.0", + "bytemuck", + "calloop 0.14.3", + "calloop-wayland-source 0.4.1", + "cursor-icon", + "libc", + "log", + "memmap2", + "pkg-config", + "rustix 1.1.2", + "thiserror 2.0.17", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols", + "wayland-protocols-experimental", + "wayland-protocols-misc", + "wayland-protocols-wlr", + "wayland-scanner", + "xkbcommon 0.8.0", "xkeysym", ] @@ -3994,9 +5239,9 @@ dependencies = [ [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "static_assertions" @@ -4009,6 +5254,9 @@ name = "strict-num" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" +dependencies = [ + "float-cmp", +] [[package]] name = "strsim" @@ -4018,24 +5266,110 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" -version = "0.27.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" -version = "0.27.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "rustversion", - "syn 2.0.100", + "syn 2.0.111", +] + +[[package]] +name = "svg_fmt" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0193cc4331cfd2f3d2011ef287590868599a2f33c3e69bc22c1a3d3acf9e02fb" + +[[package]] +name = "svgtypes" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68c7541fff44b35860c1a7a47a7cadf3e4a304c457b58f9870d9706ece028afc" +dependencies = [ + "kurbo", + "siphasher", +] + +[[package]] +name = "swash" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47846491253e976bdd07d0f9cc24b7daf24720d11309302ccbbc6e6b6e53550a" +dependencies = [ + "skrifa", + "yazi", + "zeno", +] + +[[package]] +name = "symphonia" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5773a4c030a19d9bfaa090f49746ff35c75dfddfa700df7a5939d5e076a57039" +dependencies = [ + "lazy_static", + "symphonia-codec-pcm", + "symphonia-core", + "symphonia-format-riff", + "symphonia-metadata", +] + +[[package]] +name = "symphonia-codec-pcm" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e89d716c01541ad3ebe7c91ce4c8d38a7cf266a3f7b2f090b108fb0cb031d95" +dependencies = [ + "log", + "symphonia-core", +] + +[[package]] +name = "symphonia-core" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea00cc4f79b7f6bb7ff87eddc065a1066f3a43fe1875979056672c9ef948c2af" +dependencies = [ + "arrayvec", + "bitflags 1.3.2", + "bytemuck", + "lazy_static", + "log", +] + +[[package]] +name = "symphonia-format-riff" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2d7c3df0e7d94efb68401d81906eae73c02b40d5ec1a141962c592d0f11a96f" +dependencies = [ + "extended", + "log", + "symphonia-core", + "symphonia-metadata", +] + +[[package]] +name = "symphonia-metadata" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36306ff42b9ffe6e5afc99d49e121e0bd62fe79b9db7b9681d48e29fa19e6b16" +dependencies = [ + "encoding_rs", + "lazy_static", + "log", + "symphonia-core", ] [[package]] @@ -4051,9 +5385,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.100" +version = "2.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" dependencies = [ "proc-macro2", "quote", @@ -4062,26 +5396,36 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", +] + +[[package]] +name = "sys-locale" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4" +dependencies = [ + "libc", ] [[package]] name = "sysinfo" -version = "0.34.2" +version = "0.37.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b93974b3d3aeaa036504b8eefd4c039dced109171c1ae973f1dc63b2c7e4b2" +checksum = "16607d5caffd1c07ce073528f9ed972d88db15dd44023fa57142963be3feb11f" dependencies = [ "libc", "memchr", "ntapi", "objc2-core-foundation", - "windows 0.57.0", + "objc2-io-kit", + "windows 0.61.3", ] [[package]] @@ -4090,13 +5434,38 @@ version = "6.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" dependencies = [ - "cfg-expr", + "cfg-expr 0.15.8", "heck 0.5.0", "pkg-config", - "toml", + "toml 0.8.23", "version-compare", ] +[[package]] +name = "system-deps" +version = "7.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c8f33736f986f16d69b6cb8b03f55ddcad5c41acc4ccc39dd88e84aa805e7f" +dependencies = [ + "cfg-expr 0.20.4", + "heck 0.5.0", + "pkg-config", + "toml 0.9.8", + "version-compare", +] + +[[package]] +name = "taffy" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ba83ebaf2954d31d05d67340fd46cebe99da2b7133b0dd68d70c65473a437b" +dependencies = [ + "arrayvec", + "grid", + "serde", + "slotmap", +] + [[package]] name = "target-lexicon" version = "0.12.16" @@ -4104,16 +5473,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] -name = "tempfile" -version = "3.19.1" +name = "target-lexicon" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" +checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" + +[[package]] +name = "tempfile" +version = "3.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", - "getrandom 0.3.2", + "getrandom 0.3.4", "once_cell", - "rustix 1.0.5", - "windows-sys 0.59.0", + "rustix 1.1.2", + "windows-sys 0.61.2", ] [[package]] @@ -4136,11 +5511,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.12", + "thiserror-impl 2.0.17", ] [[package]] @@ -4151,35 +5526,34 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "thread_local" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ "cfg-if", - "once_cell", ] [[package]] name = "time" -version = "0.3.41" +version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" dependencies = [ "deranged", "itoa", @@ -4192,15 +5566,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" [[package]] name = "time-macros" -version = "0.2.22" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" dependencies = [ "num-conv", "time-core", @@ -4226,6 +5600,7 @@ dependencies = [ "bytemuck", "cfg-if", "log", + "png 0.17.16", "tiny-skia-path", ] @@ -4242,53 +5617,141 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.7.6" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ "displaydoc", "zerovec", ] [[package]] -name = "toml" -version = "0.8.20" +name = "tinyvec" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_edit 0.22.27", +] + +[[package]] +name = "toml" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" +dependencies = [ + "indexmap 2.12.1", + "serde_core", + "serde_spanned 1.0.3", + "toml_datetime 0.7.3", + "toml_parser", + "toml_writer", + "winnow 0.7.14", ] [[package]] name = "toml_datetime" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +dependencies = [ + "serde_core", +] + [[package]] name = "toml_edit" -version = "0.22.24" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.9.0", - "serde", - "serde_spanned", - "toml_datetime", - "winnow", + "indexmap 2.12.1", + "toml_datetime 0.6.11", + "winnow 0.5.40", ] [[package]] -name = "tracing" -version = "0.1.41" +name = "toml_edit" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +dependencies = [ + "indexmap 2.12.1", + "toml_datetime 0.6.11", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap 2.12.1", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "winnow 0.7.14", +] + +[[package]] +name = "toml_edit" +version = "0.23.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d7cbc3b4b49633d57a0509303158ca50de80ae32c265093b24c414705807832" +dependencies = [ + "indexmap 2.12.1", + "toml_datetime 0.7.3", + "toml_parser", + "winnow 0.7.14", +] + +[[package]] +name = "toml_parser" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +dependencies = [ + "winnow 0.7.14", +] + +[[package]] +name = "toml_writer" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2" + +[[package]] +name = "tracing" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" dependencies = [ "log", "pin-project-lite", @@ -4298,20 +5761,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.28" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "tracing-core" -version = "0.1.33" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" dependencies = [ "once_cell", "valuable", @@ -4330,14 +5793,14 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.19" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" dependencies = [ "matchers", "nu-ansi-term", "once_cell", - "regex", + "regex-automata", "sharded-slab", "smallvec", "thread_local", @@ -4346,23 +5809,26 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "trim-in-place" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "343e926fc669bc8cde4fa3129ab681c63671bae288b1f1081ceee6d9d37904fc" - [[package]] name = "ttf-parser" version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" +dependencies = [ + "core_maths", +] + +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "ucd-trie" @@ -4382,10 +5848,44 @@ dependencies = [ ] [[package]] -name = "unicode-ident" -version = "1.0.18" +name = "uidev" +version = "0.1.0" +dependencies = [ + "anyhow", + "dash-frontend", + "glam", + "log", + "rust-embed", + "tracing-subscriber", + "vulkano", + "vulkano-shaders", + "wgui", + "winit", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" + +[[package]] +name = "unicode-ident" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + +[[package]] +name = "unicode-script" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "383ad40bb927465ec0ce7720e033cb4ca06912855fc35db31b5755d0de75b1ee" [[package]] name = "unicode-segmentation" @@ -4401,9 +5901,9 @@ checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-width" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "unsafe-libyaml" @@ -4413,9 +5913,9 @@ checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] name = "url" -version = "2.5.4" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", @@ -4424,10 +5924,26 @@ dependencies = [ ] [[package]] -name = "utf16_iter" -version = "1.0.5" +name = "usvg" +version = "0.45.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" +checksum = "80be9b06fbae3b8b303400ab20778c80bbaf338f563afe567cf3c9eea17b47ef" +dependencies = [ + "base64", + "data-url", + "flate2", + "imagesize", + "kurbo", + "log", + "pico-args", + "roxmltree 0.20.0", + "simplecss", + "siphasher", + "strict-num", + "svgtypes", + "tiny-skia-path", + "xmlwriter", +] [[package]] name = "utf8_iter" @@ -4443,12 +5959,26 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.16.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" dependencies = [ - "getrandom 0.3.2", - "rand 0.9.0", + "getrandom 0.3.4", + "js-sys", + "rand", + "serde_core", + "wasm-bindgen", +] + +[[package]] +name = "v_frame" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "666b7727c8875d6ab5db9533418d7c764233ac9c0cff1d469aec8fa127597be2" +dependencies = [ + "aligned-vec", + "num-traits", + "wasm-bindgen", ] [[package]] @@ -4459,9 +5989,9 @@ checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "version-compare" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" +checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e" [[package]] name = "version_check" @@ -4480,19 +6010,19 @@ dependencies = [ [[package]] name = "vulkano" -version = "0.35.1" +version = "0.35.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08840c2b51759a6f88f26f5ea378bc8b5c199a5b4760ddda292304be087249c4" +checksum = "ee487adf7c13e5aa46d4d7fac6ffb8e172eb7e6472aaf815e9ade4992f8f2414" dependencies = [ "ash", "bytemuck", "crossbeam-queue", - "foldhash", + "foldhash 0.1.5", "half", "heck 0.4.1", - "indexmap 2.9.0", + "indexmap 2.12.1", "libloading", - "nom", + "nom 7.1.3", "once_cell", "parking_lot", "proc-macro2", @@ -4506,8 +6036,6 @@ dependencies = [ "thread_local", "vk-parse", "vulkano-macros", - "x11-dl", - "x11rb", ] [[package]] @@ -4516,10 +6044,10 @@ version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dc929c42c9336fd082079ac3ea30126e4a0dfe36fd2e2b3581303f7d140d20f" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -4528,12 +6056,12 @@ version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bf501461be7cef2893c0e62c50945add9763cc482051d29053f6157089d5ea9" dependencies = [ - "foldhash", + "foldhash 0.1.5", "heck 0.4.1", "proc-macro2", "quote", "shaderc", - "syn 2.0.100", + "syn 2.0.111", "vulkano", ] @@ -4549,50 +6077,37 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "wasi" -version = "0.14.2+wasi-0.2.4" +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn 2.0.100", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.50" +version = "0.4.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" dependencies = [ "cfg-if", "js-sys", @@ -4603,9 +6118,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4613,35 +6128,35 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" dependencies = [ + "bumpalo", "proc-macro2", "quote", - "syn 2.0.100", - "wasm-bindgen-backend", + "syn 2.0.111", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" dependencies = [ "unicode-ident", ] [[package]] name = "wayland-backend" -version = "0.3.8" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7208998eaa3870dad37ec8836979581506e0c5c64c20c9e79e9d2a10d6f47bf" +checksum = "673a33c33048a5ade91a6b139580fa174e19fb0d23f396dca9fa15f2e1e49b35" dependencies = [ "cc", "downcast-rs", - "rustix 0.38.44", + "rustix 1.1.2", "scoped-tls", "smallvec", "wayland-sys", @@ -4649,12 +6164,12 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.8" +version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2120de3d33638aaef5b9f4472bff75f07c56379cf76ea320bd3a3d65ecaf73f" +checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d" dependencies = [ - "bitflags 2.9.0", - "rustix 0.38.44", + "bitflags 2.10.0", + "rustix 1.1.2", "wayland-backend", "wayland-scanner", ] @@ -4665,27 +6180,27 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "cursor-icon", "wayland-backend", ] [[package]] name = "wayland-cursor" -version = "0.31.8" +version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a93029cbb6650748881a00e4922b076092a6a08c11e7fbdb923f064b23968c5d" +checksum = "447ccc440a881271b19e9989f75726d60faa09b95b0200a9b7eb5cc47c3eeb29" dependencies = [ - "rustix 0.38.44", + "rustix 1.1.2", "wayland-client", "xcursor", ] [[package]] name = "wayland-egl" -version = "0.32.5" +version = "0.32.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504838241a10e271f48ffd429ac4033e0ac468b399fe7c2e2840f5c3a82d9902" +checksum = "d36232ee23ba3ea34a6835d68ca1af91d3ca3d6eddcf9c7147c4e0e66901b9fd" dependencies = [ "wayland-backend", "wayland-sys", @@ -4693,11 +6208,11 @@ dependencies = [ [[package]] name = "wayland-protocols" -version = "0.32.6" +version = "0.32.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0781cf46869b37e36928f7b432273c0995aa8aed9552c556fb18754420541efc" +checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "wayland-backend", "wayland-client", "wayland-scanner", @@ -4705,13 +6220,27 @@ dependencies = [ ] [[package]] -name = "wayland-protocols-misc" -version = "0.3.6" +name = "wayland-protocols-experimental" +version = "20250721.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feb7ee1810026d1bb15d47086d03a7e5c68651c707e305ba1e8cc796fcbf5a54" +checksum = "40a1f863128dcaaec790d7b4b396cc9b9a7a079e878e18c47e6c2d2c5a8dcbb1" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-misc" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfe33d551eb8bffd03ff067a8b44bb963919157841a99957151299a6307d19c" +dependencies = [ + "bitflags 2.10.0", + "wayland-backend", + "wayland-client", "wayland-protocols", "wayland-scanner", "wayland-server", @@ -4719,11 +6248,11 @@ dependencies = [ [[package]] name = "wayland-protocols-plasma" -version = "0.3.6" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ccaacc76703fefd6763022ac565b590fcade92202492381c95b2edfdf7d46b3" +checksum = "a07a14257c077ab3279987c4f8bb987851bf57081b93710381daea94f2c2c032" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -4732,11 +6261,11 @@ dependencies = [ [[package]] name = "wayland-protocols-wlr" -version = "0.3.6" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248a02e6f595aad796561fa82d25601bd2c8c3b145b1c7453fc8f94c1a58f8b2" +checksum = "efd94963ed43cf9938a090ca4f7da58eb55325ec8200c3848963e98dc25b78ec" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -4746,33 +6275,33 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.31.6" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "896fdafd5d28145fce7958917d69f2fd44469b1d4e861cb5961bcbeebc6d1484" +checksum = "54cb1e9dc49da91950bdfd8b848c49330536d9d1fb03d4bfec8cae50caa50ae3" dependencies = [ "proc-macro2", - "quick-xml 0.37.4", + "quick-xml 0.37.5", "quote", ] [[package]] name = "wayland-server" -version = "0.31.7" +version = "0.31.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fabd7ed68cff8e7657b8a8a1fbe90cb4a3f0c30d90da4bf179a7a23008a4cb" +checksum = "fcbd4f3aba6c9fba70445ad2a484c0ef0356c1a9459b1e8e435bedc1971a6222" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "downcast-rs", - "rustix 0.38.44", + "rustix 1.1.2", "wayland-backend", "wayland-scanner", ] [[package]] name = "wayland-sys" -version = "0.31.6" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbcebb399c77d5aa9fa5db874806ee7b4eba4e73650948e8f93963f128896615" +checksum = "34949b42822155826b41db8e5d0c1be3a2bd296c747577a43a3e6daefc296142" dependencies = [ "dlib", "log", @@ -4795,9 +6324,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.77" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" dependencies = [ "js-sys", "wasm-bindgen", @@ -4813,6 +6342,39 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "weezl" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" + +[[package]] +name = "wgui" +version = "0.1.0" +dependencies = [ + "anyhow", + "cosmic-text", + "etagere", + "flate2", + "glam", + "image", + "log", + "lru", + "ouroboros", + "parking_lot", + "regex", + "resvg", + "roxmltree 0.21.1", + "rust-embed", + "rustc-hash 2.1.1", + "serde_json", + "slotmap", + "smallvec", + "taffy", + "vulkano", + "vulkano-shaders", +] + [[package]] name = "which" version = "4.4.2" @@ -4827,9 +6389,9 @@ dependencies = [ [[package]] name = "widestring" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" +checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" [[package]] name = "winapi" @@ -4849,11 +6411,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -4874,12 +6436,24 @@ dependencies = [ [[package]] name = "windows" -version = "0.57.0" +version = "0.61.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" +checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" dependencies = [ - "windows-core 0.57.0", - "windows-targets 0.52.6", + "windows-collections", + "windows-core 0.61.2", + "windows-future", + "windows-link 0.1.3", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +dependencies = [ + "windows-core 0.61.2", ] [[package]] @@ -4894,78 +6468,84 @@ dependencies = [ [[package]] name = "windows-core" -version = "0.57.0" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ - "windows-implement 0.57.0", - "windows-interface 0.57.0", - "windows-result 0.1.2", - "windows-targets 0.52.6", + "windows-implement", + "windows-interface", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", ] [[package]] name = "windows-core" -version = "0.61.0" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ - "windows-implement 0.60.0", - "windows-interface 0.59.1", - "windows-link", - "windows-result 0.3.2", - "windows-strings", + "windows-implement", + "windows-interface", + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + +[[package]] +name = "windows-future" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +dependencies = [ + "windows-core 0.61.2", + "windows-link 0.1.3", + "windows-threading", ] [[package]] name = "windows-implement" -version = "0.57.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", -] - -[[package]] -name = "windows-implement" -version = "0.60.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "windows-interface" -version = "0.57.0" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", -] - -[[package]] -name = "windows-interface" -version = "0.59.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "windows-link" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-numerics" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +dependencies = [ + "windows-core 0.61.2", + "windows-link 0.1.3", +] [[package]] name = "windows-result" @@ -4978,20 +6558,38 @@ dependencies = [ [[package]] name = "windows-result" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-link", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link 0.2.1", ] [[package]] name = "windows-strings" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-link", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link 0.2.1", ] [[package]] @@ -5021,6 +6619,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link 0.2.1", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -5036,21 +6643,6 @@ dependencies = [ "windows_x86_64_msvc 0.42.2", ] -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - [[package]] name = "windows-targets" version = "0.52.6" @@ -5067,18 +6659,21 @@ dependencies = [ "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link 0.1.3", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" @@ -5091,12 +6686,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" @@ -5109,12 +6698,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -5133,12 +6716,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" @@ -5151,12 +6728,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" @@ -5169,12 +6740,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" @@ -5187,12 +6752,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -5201,15 +6760,15 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winit" -version = "0.30.9" +version = "0.30.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a809eacf18c8eca8b6635091543f02a5a06ddf3dad846398795460e6e0ae3cc0" +checksum = "c66d4b9ed69c4009f6321f762d6e61ad8a2389cd431b97cb1e146812e9e6c732" dependencies = [ "ahash", "android-activity", "atomic-waker", - "bitflags 2.9.0", - "block2", + "bitflags 2.10.0", + "block2 0.5.1", "bytemuck", "calloop 0.13.0", "cfg_aliases", @@ -5220,8 +6779,8 @@ dependencies = [ "dpi", "js-sys", "libc", - "memmap2 0.9.5", - "ndk 0.9.0", + "memmap2", + "ndk", "objc2 0.5.2", "objc2-app-kit", "objc2-foundation 0.2.2", @@ -5233,7 +6792,7 @@ dependencies = [ "redox_syscall 0.4.1", "rustix 0.38.44", "sctk-adwaita", - "smithay-client-toolkit", + "smithay-client-toolkit 0.19.2", "smol_str", "tracing", "unicode-segmentation", @@ -5253,26 +6812,31 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.6" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "winnow" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" dependencies = [ - "bitflags 2.9.0", + "memchr", ] +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + [[package]] name = "wlx-capture" -version = "0.5.4" -source = "git+https://github.com/galister/wlx-capture?tag=v0.5.4#1aad584fafd529c63cce3355f0b2e2175ab69c70" +version = "0.5.3" dependencies = [ "ashpd", "drm-fourcc", @@ -5281,11 +6845,22 @@ dependencies = [ "log", "pipewire", "rxscreen", - "smithay-client-toolkit", + "smithay-client-toolkit 0.20.0", "wayland-client", "wayland-protocols", ] +[[package]] +name = "wlx-common" +version = "0.1.0" +dependencies = [ + "chrono", + "glam", + "idmap", + "idmap-derive", + "serde", +] + [[package]] name = "wlx-overlay-s" version = "25.4.2" @@ -5299,8 +6874,6 @@ dependencies = [ "config", "ctrlc", "dbus", - "fontconfig-rs", - "freetype-rs", "futures", "glam", "idmap", @@ -5309,7 +6882,7 @@ dependencies = [ "input-linux", "interprocess", "json", - "json5", + "json5 1.3.0", "khronos-egl", "libc", "libmonado", @@ -5321,15 +6894,17 @@ dependencies = [ "regex", "rodio", "rosc", + "rust-embed", "serde", "serde_json", "serde_json5", "serde_yaml", + "slotmap", "smallvec", "smithay", "strum", "sysinfo", - "thiserror 2.0.12", + "thiserror 2.0.17", "tracing", "tracing-subscriber", "uuid", @@ -5338,24 +6913,20 @@ dependencies = [ "wayland-client", "wayland-egl", "wayvr_ipc", + "wgui", "winit", "wlx-capture", + "wlx-common", "xcb", - "xdg", - "xkbcommon 0.8.0", + "xdg 3.0.0", + "xkbcommon 0.9.0", ] -[[package]] -name = "write16" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" - [[package]] name = "writeable" -version = "0.5.5" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "x11-dl" @@ -5370,30 +6941,30 @@ dependencies = [ [[package]] name = "x11rb" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" +checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414" dependencies = [ "as-raw-xcb-connection", "gethostname", "libc", "libloading", "once_cell", - "rustix 0.38.44", + "rustix 1.1.2", "x11rb-protocol", ] [[package]] name = "x11rb-protocol" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" +checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" [[package]] name = "xcb" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1e2f212bb1a92cd8caac8051b829a6582ede155ccb60b5d5908b81b100952be" +checksum = "f07c123b796139bfe0603e654eaf08e132e52387ba95b252c78bad3640ba37ea" dependencies = [ "as-raw-xcb-connection", "bitflags 1.3.2", @@ -5403,9 +6974,9 @@ dependencies = [ [[package]] name = "xcursor" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef33da6b1660b4ddbfb3aef0ade110c8b8a781a3b6382fa5f2b5b040fd55f61" +checksum = "bec9e4a500ca8864c5b47b8b482a73d62e4237670e5b5f1d6b9e3cae50f28f2b" [[package]] name = "xdg" @@ -5414,35 +6985,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" [[package]] -name = "xdg-home" -version = "1.3.0" +name = "xdg" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "xkbcommon" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13867d259930edc7091a6c41b4ce6eee464328c6ff9659b7e4c668ca20d4c91e" -dependencies = [ - "libc", - "memmap2 0.8.0", - "xkeysym", -] +checksum = "2fb433233f2df9344722454bc7e96465c9d03bff9d77c248f9e7523fe79585b5" [[package]] name = "xkbcommon" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d66ca9352cbd4eecbbc40871d8a11b4ac8107cfc528a6e14d7c19c69d0e1ac9" +dependencies = [ + "libc", + "memmap2", + "xkeysym", +] + +[[package]] +name = "xkbcommon" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a974f48060a14e95705c01f24ad9c3345022f4d97441b8a36beb7ed5c4a02d" dependencies = [ "as-raw-xcb-connection", "libc", - "memmap2 0.9.5", + "memmap2", "xkeysym", ] @@ -5452,7 +7019,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "dlib", "log", "once_cell", @@ -5470,9 +7037,9 @@ dependencies = [ [[package]] name = "xml-rs" -version = "0.8.26" +version = "0.8.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62ce76d9b56901b19a74f19431b0d8b3bc7ca4ad685a746dfd78ca8f4fc6bda" +checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f" [[package]] name = "xmlparser" @@ -5481,16 +7048,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" [[package]] -name = "yaml-rust2" -version = "0.10.1" +name = "xmlwriter" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "818913695e83ece1f8d2a1c52d54484b7b46d0f9c06beeb2649b9da50d9b512d" +checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" + +[[package]] +name = "y4m" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5a4b21e1a62b67a2970e6831bc091d7b87e119e7f9791aef9702e3bef04448" + +[[package]] +name = "yaml-rust2" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2462ea039c445496d8793d052e13787f2b90e750b833afee748e601c17621ed9" dependencies = [ "arraydeque", "encoding_rs", "hashlink", ] +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + [[package]] name = "yansi-term" version = "0.1.2" @@ -5501,24 +7086,17 @@ dependencies = [ ] [[package]] -name = "yeslogic-fontconfig-sys" -version = "3.2.0" +name = "yazi" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2bbd69036d397ebbff671b1b8e4d918610c181c5a16073b96f984a38d08c386" -dependencies = [ - "const-cstr", - "dlib", - "once_cell", - "pkg-config", -] +checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5" [[package]] name = "yoke" -version = "0.7.5" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" dependencies = [ - "serde", "stable_deref_trait", "yoke-derive", "zerofrom", @@ -5526,25 +7104,24 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.5" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", "synstructure", ] [[package]] name = "zbus" -version = "5.5.0" +version = "5.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59c333f648ea1b647bc95dc1d34807c8e25ed7a6feff3394034dc4776054b236" +checksum = "b622b18155f7a93d1cd2dc8c01d2d6a44e08fb9ebb7b3f9e6ed101488bad6c91" dependencies = [ "async-broadcast", "async-executor", - "async-fs", "async-io", "async-lock", "async-process", @@ -5557,16 +7134,15 @@ dependencies = [ "futures-core", "futures-lite", "hex", - "nix 0.29.0", + "nix 0.30.1", "ordered-stream", "serde", "serde_repr", - "static_assertions", "tracing", "uds_windows", - "windows-sys 0.59.0", - "winnow", - "xdg-home", + "uuid", + "windows-sys 0.61.2", + "winnow 0.7.14", "zbus_macros", "zbus_names", "zvariant", @@ -5574,14 +7150,14 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "5.5.0" +version = "5.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f325ad10eb0d0a3eb060203494c3b7ec3162a01a59db75d2deee100339709fc0" +checksum = "1cdb94821ca8a87ca9c298b5d1cbd80e2a8b67115d99f6e4551ac49e42b6a314" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", "zbus_names", "zvariant", "zvariant_utils", @@ -5595,48 +7171,34 @@ checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97" dependencies = [ "serde", "static_assertions", - "winnow", + "winnow 0.7.14", "zvariant", ] [[package]] -name = "zerocopy" -version = "0.7.35" +name = "zeno" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "zerocopy-derive 0.7.35", -] +checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" [[package]] name = "zerocopy" -version = "0.8.24" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" dependencies = [ - "zerocopy-derive 0.8.24", + "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -5656,15 +7218,26 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", "synstructure", ] [[package]] -name = "zerovec" -version = "0.10.4" +name = "zerotrie" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" dependencies = [ "yoke", "zerofrom", @@ -5673,54 +7246,76 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.10.3" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", +] + +[[package]] +name = "zune-core" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "111f7d9820f05fd715df3144e254d6fc02ee4088b0644c0ffd0efc9e6d9d2773" + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "zune-jpeg" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f520eebad972262a1dde0ec455bce4f8b298b1e5154513de58c114c4c54303e8" +dependencies = [ + "zune-core", ] [[package]] name = "zvariant" -version = "5.4.0" +version = "5.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2df9ee044893fcffbdc25de30546edef3e32341466811ca18421e3cd6c5a3ac" +checksum = "2be61892e4f2b1772727be11630a62664a1826b62efa43a6fe7449521cb8744c" dependencies = [ "endi", "enumflags2", "serde", - "static_assertions", "url", - "winnow", + "winnow 0.7.14", "zvariant_derive", "zvariant_utils", ] [[package]] name = "zvariant_derive" -version = "5.4.0" +version = "5.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74170caa85b8b84cc4935f2d56a57c7a15ea6185ccdd7eadb57e6edd90f94b2f" +checksum = "da58575a1b2b20766513b1ec59d8e2e68db2745379f961f86650655e862d2006" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", "zvariant_utils", ] [[package]] name = "zvariant_utils" -version = "3.2.0" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16edfee43e5d7b553b77872d99bc36afdda75c223ca7ad5e3fbecd82ca5fc34" +checksum = "c6949d142f89f6916deca2232cf26a8afacf2b9fdc35ce766105e104478be599" dependencies = [ "proc-macro2", "quote", "serde", - "static_assertions", - "syn 2.0.100", - "winnow", + "syn 2.0.111", + "winnow 0.7.14", ] diff --git a/Cargo.toml b/Cargo.toml index d3f5fb6..5c89cda 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,120 +1,36 @@ +[profile.dev] +opt-level = 1 +debug = true +strip = "none" +debug-assertions = true +incremental = true + [profile.release-with-debug] inherits = "release" debug = true -[package] -name = "wlx-overlay-s" -version = "25.4.2" -edition = "2021" -license = "GPL-3.0-only" -authors = ["galister"] -description = "Access your Wayland/X11 desktop from Monado/WiVRn/SteamVR. Now with Vulkan!" -repository = "https://github.com/galister/wlx-overlay-s" -keywords = ["linux", "openvr", "openxr", "x11", "wayland", "openvr-overlay", "openxr-overlay"] -categories = ["games"] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -anyhow = "1.0.89" -ash = "^0.38.0" # must match vulkano -chrono = "0.4.38" -chrono-tz = "0.10.0" -clap = { version = "4.5.6", features = ["derive"] } -config = "0.15.11" -ctrlc = { version = "3.4.4", features = ["termination"] } -dbus = { version = "0.9.7" } -fontconfig-rs = "0.1.1" -freetype-rs = "0.36.0" # latest version supported on ubuntu 22.04 -futures = "0.3.30" -glam = { version = "0.30.1", features = ["approx", "mint", "serde"] } -idmap = { version = "0.2.21", features = ["serde"] } -idmap-derive = "0.1.2" -input-linux = "0.7.0" -json = { version = "0.12.4", optional = true } -json5 = "0.4.1" -libc = "0.2.155" -log = "0.4.21" -openxr = { git = "https://github.com/Ralith/openxrs", rev = "d0afdd3365bc1e14de28f6a3a21f457e788a702e", features = [ - "linked", - "mint", -], optional = true } -ovr_overlay = { features = [ - "ovr_input", - "ovr_system", -], git = "https://github.com/galister/ovr_overlay_oyasumi", optional = true } -regex = "1.11.1" -rodio = { version = "0.20.1", default-features = false, features = [ - "wav", - "hound", -] } -rosc = { version = "0.11.4", optional = true } -serde = { version = "1.0.203", features = ["derive", "rc"] } -serde_json = "1.0.117" -serde_yaml = "0.9.34" -smallvec = "1.13.2" -strum = { version = "0.27.1", features = ["derive"] } -sysinfo = { version = "0.34.2" } -thiserror = "2.0.3" -vulkano = { version = "0.35.1" } -vulkano-shaders = { version = "0.35.0" } -wlx-capture = { git = "https://github.com/galister/wlx-capture", tag = "v0.5.4", default-features = false } -libmonado = { version = "1.3.2", optional = true } -winit = { version = "0.30.0", optional = true } -xdg = "2.5.2" -log-panics = { version = "2.1.0", features = ["with-backtrace"] } -serde_json5 = "0.2.1" -xkbcommon = { version = "0.8.0" } -xcb = { version = "1.4.0", optional = true, features = [ - "as-raw-xcb-connection", -] } -image_dds = { version = "0.7.2", default-features = false, features = [ - "ddsfile", -] } -mint = "0.5.9" -tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } -tracing = "0.1.41" - -################################ -#WayVR-only deps -################################ -khronos-egl = { version = "6.0.0", features = ["static"], optional = true } -smithay = { version = "0.5.1", default-features = false, features = [ - "renderer_gl", - "backend_egl", - "backend_drm", - "xwayland", - "wayland_frontend", -], optional = true } -uuid = { version = "1.10.0", features = ["v4", "fast-rng"], optional = true } -wayland-client = { version = "0.31.6", optional = true } -wayland-egl = { version = "0.32.4", optional = true } -interprocess = { version = "2.2.2", optional = true } -bytes = { version = "1.9.0", optional = true } -wayvr_ipc = { git = "https://github.com/olekolek1000/wayvr-ipc.git", rev = "a72587d23f3bb8624d9aeb1f13c0a21e65350f51", default-features = false, optional = true } -################################ - -[build-dependencies] -regex = { version = "1.11.1" } - -[features] -default = ["openvr", "openxr", "osc", "x11", "wayland", "wayvr"] -openvr = ["dep:ovr_overlay", "dep:json"] -openxr = ["dep:openxr", "dep:libmonado"] -osc = ["dep:rosc"] -x11 = ["dep:xcb", "wlx-capture/xshm", "xkbcommon/x11"] -wayland = ["pipewire", "wlx-capture/wlr", "xkbcommon/wayland"] -pipewire = ["wlx-capture/pipewire"] -uidev = ["dep:winit"] -xcb = ["dep:xcb"] -wayvr = [ - "dep:khronos-egl", - "dep:smithay", - "dep:uuid", - "dep:wayland-client", - "dep:wayland-egl", - "dep:interprocess", - "dep:bytes", - "dep:wayvr_ipc", +[workspace] +members = [ + "uidev", + "wgui", + "wlx-common", + "wlx-overlay-s", + "wlx-capture", + "dash-frontend", ] -as-raw-xcb-connection = [] +resolver = "3" + +[workspace.dependencies] +anyhow = "1.0.100" +glam = { version = "0.30.9", features = ["mint", "serde"] } +idmap = "0.2.2" +idmap-derive = "0.2.22" +log = "0.4.29" +regex = "1.12.2" +rust-embed = "8.9.0" +slotmap = "1.1.1" +vulkano = { version = "0.35.2", default-features = false, features = [ + "macros", +] } +vulkano-shaders = "0.35.0" +wayland-client = { version = "0.31.11" } diff --git a/README.md b/README.md index b68ea23..dd0bff2 100644 --- a/README.md +++ b/README.md @@ -19,10 +19,18 @@ Questions/issues specific to WlxOverlay-S will be handled in the `wlxoverlay` ch ## Setup +### Installation + +There are multiple ways to install WlxOverlay-S: +1. AppImage: Download from [Releases](https://github.com/galister/wlx-overlay-s/releases) +1. AUR package: [wlx-overlay-s-git](https://aur.archlinux.org/packages/wlx-overlay-s-git) +1. Homebrew: + 1. Add AtomicXR tap: `brew tap matrixfurry.com/atomicxr https://tangled.sh/@matrixfurry.com/homebrew-atomicxr` + 1. Install WlxOverlay-S: `brew install wlx-overlay-s` +1. [Building from source](https://github.com/galister/wlx-overlay-s/wiki/Building-from-Source). + ### General Setup -1. Grab the latest AppImage from [Releases](https://github.com/galister/wlx-overlay-s/releases). -1. `chmod +x WlxOverlay-S-*.AppImage` 1. Start Monado, WiVRn or SteamVR. 1. Run the overlay @@ -41,30 +49,25 @@ For users specifically running **SteamVR via Steam Flatpak**, follow these steps 1. Start SteamVR. 1. `flatpak run --command='/path/to/squashfs-root/AppRun' com.valvesoftware.Steam` -### Install via Homebrew - -1. Add AtomicXR tap `brew tap matrixfurry.com/atomicxr https://tangled.sh/@matrixfurry.com/homebrew-atomicxr` -2. Install WlxOverlay-S: `brew install wlx-overlay-s` - -AUR package is [wlx-overlay-s-git](https://aur.archlinux.org/packages/wlx-overlay-s-git). - -You may also want to [build from source](https://github.com/galister/wlx-overlay-s/wiki/Building-from-Source). ## First Start -**When the screen share pop-up appears, check the terminal and select the screens in the order it requests.** +**When the screen share pop-up appears, check your notifications or the terminal and select the screens in the order it requests.** In case screens were selected in the wrong order: - `rm ~/.config/wlxoverlay/conf.d/pw_tokens.yaml` then restart -**SteamVR users**: WlxOverlay-S will register itself for auto-start, so there is no need to start it every time. + +**WiVRn users**: Select WlxOverlay-S from the `Application` drop-down. If there's no such entry, select `Custom` and browse to your WlxOverlay-S executable or AppImage. **Envision users**: Go to the Plugins menu and select the WlxOverlay-S plugin. This will download and run the AppImage version of the overlay. -In order to run a standalone installation (for instance from the AUR), create a bash script containing `wlx-overlay-s --openxr --show` and then select this bash script as a custom Envision plugin. +In order to run a standalone installation (for instance from the AUR), create a bash script containing `wlx-overlay-s --openxr --show` and then set this bash script as a custom Envision plugin. This will show a home environment with headset passthrough by default or a [customizable background](https://github.com/galister/wlx-overlay-s/wiki/OpenXR-Skybox)! +**SteamVR users**: WlxOverlay-S will register itself for auto-start, so there is no need to start it every time. Disclaimer: SteamVR will sometimes disregard this and not start Wlx anyway. + **Please continue reading the guide below.** ## Getting Started @@ -76,10 +79,11 @@ The working set consists of all currently selected overlays; screens, mirrors, k The working set appears in front of the headset when shown, and can be re-centered by hiding and showing again. Show and hide the working set using: - - Non-vive controller: double-tap B or Y on the left controller. - Vive controller: double-tap the menu button on the left controller (for SteamVR, the `showhide` binding must be bound) +See the [bindings](#default-bindings) section on how to grab, move and resize overlay windows. + ### Pointer Modes AKA Laser Colors Much of the functionality in WlxOverlay-S depends on what color of laser is used to interact with a UI element. \ @@ -93,27 +97,33 @@ Please see the bindings section below on how to activate these modes. The guide here uses the colors for ease of getting started. -### The Watch +### The watch Check your left wrist for the watch. The watch is the primary tool for controlling the app. +The top of the watch shows device batteries, and the bottom shows your overlay controls. + +Enter edit mode (leftmost button on bottom) to edit your overlay sets. + +While in edit mode, the watch can also be grabbed, and passed between your hands. + +After grabbing, the watch will automatically attach to the hand that's opposite from the one that held it. + +In edit mode, try hovering other overlays to see their advanced options! +  -### The Screens +### The screens Hovering a pointer over a screen will move the mouse. If there are more than one pointers hovering a screen, the pointer that was last used to click will take precedence. -The click depends on the laser color: +The click type depends on the laser color: - Blue laser: Left click - Orange laser: Right click - Purple laser: Middle click - Stick up/down: Scroll wheel -To **curve a screen**, grab it with one hand. Then, using the other hand, hover the laser over the screen and use the scroll action. - -See the [bindings](#default-bindings) section on how to grab, move and resize screens. - ### The keyboard The keyboard is fully customizable via the [keyboard.yaml](https://raw.githubusercontent.com/galister/wlx-overlay-s/main/src/res/keyboard.yaml) file. \ @@ -123,7 +133,7 @@ Typing - Use the BLUE laser when typing regularly. - While using ORANGE laser, all keystrokes will have SHIFT applied. -- Purple laser has no effect as of now. +- Purple laser is customizable via the `keyboard.yaml`'s `alt_modifier` settings. **Modifier Keys** are sticky. They will remain pressed until a non-modifier key is pressed, the modifier gets toggled off, or the keyboard gets hidden. @@ -150,9 +160,10 @@ Check [here](https://github.com/galister/wlx-overlay-s/wiki/Troubleshooting) for ### Mouse is not where it should be -Niri users: use on Niri 0.1.7 or later. - -X11 users might be dealing with a [Phantom Monitor](https://wiki.archlinux.org/title/Xrandr#Disabling_phantom_monitor). +X11 users: +- Might be dealing with a [Phantom Monitor](https://wiki.archlinux.org/title/Xrandr#Disabling_phantom_monitor). +- DPI scaling is not supported and will mess with the mouse. +- Upright screens are not supported and will mess with the mouse. Other desktops: The screens may have been selected in the wrong order, see [First Start](#first-start). @@ -168,17 +179,13 @@ echo 'capture_method: pw_fallback' > ~/.config/wlxoverlay/conf.d/pw_fallback.yam Without DMA-buf capture, capturing screens takes CPU power, so let's try and not show too many screens at the same time. -### Space-drag crashes SteamVR +### Modifiers get stuck, mouse clicks stop working on KDE Plasma -This has been idenfitied as an issue with SteamVR versions 2.5.5 and above (latest tested 2.7.2). One way to avoid the crash is by switching to the `temp-v1.27.5` branch of SteamVR (via beta selection) and selecting [Steam-Play-None](https://github.com/Scrumplex/Steam-Play-None) under the compatibility tab. - -### Modifiers get stuck in weird ways - -This is a rare issue that can make KDE Plasma not react to click or keys due to what seems to be a race condition with modifiers. Restarting the overlay fixes this. +We are not sure what causes this, but it only happens on KDE Plasma. Restarting the overlay fixes this. ### X11 limitations -- X11 capture can generally seem slow. This is because zero-copy GPU capture is not supported on the general X11 desktop. Consider trying Wayland or Picom. +- X11 capture can generally seem slow. This is because zero-copy GPU capture is not supported on the general X11 desktop. Consider trying Wayland. - DPI scaling is not supported and may cause the mouse to not follow the laser properly. -- Upright screens are not supported and can cause the mouse to act weirdly. +- Upright screens are not supported and can cause the mouse to not follow the laser properly. - Screen changes (connecting / disconnecting a display, resolution changes, etc) are not handled at runtime. Restart the overlay for these to take effect. diff --git a/dash-frontend/.editorconfig b/dash-frontend/.editorconfig new file mode 100644 index 0000000..f5834b7 --- /dev/null +++ b/dash-frontend/.editorconfig @@ -0,0 +1,8 @@ +root = true + +[*.rs] +indent_style = tab +indent_size = 2 +charset = utf-8 +trim_trailing_whitespace = false +insert_final_newline = false \ No newline at end of file diff --git a/dash-frontend/Cargo.toml b/dash-frontend/Cargo.toml new file mode 100644 index 0000000..5bd23d7 --- /dev/null +++ b/dash-frontend/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "dash-frontend" +version = "0.1.0" +edition = "2024" + +[dependencies] +anyhow.workspace = true +wgui = { path = "../wgui/" } +glam = { workspace = true, features = ["mint", "serde"] } +log = { workspace = true } +rust-embed = { workspace = true } +chrono = "0.4.42" +gio = "0.21.5" +gtk = "0.18.2" +serde = { version = "1.0.228", features = ["derive"] } +serde_json = "1.0.145" +wlx-common = { path = "../wlx-common" } diff --git a/dash-frontend/assets/Quicksand-Bold.ttf.gz b/dash-frontend/assets/Quicksand-Bold.ttf.gz new file mode 100644 index 0000000..b0467a6 Binary files /dev/null and b/dash-frontend/assets/Quicksand-Bold.ttf.gz differ diff --git a/dash-frontend/assets/Quicksand-Light.ttf.gz b/dash-frontend/assets/Quicksand-Light.ttf.gz new file mode 100644 index 0000000..dbda8da Binary files /dev/null and b/dash-frontend/assets/Quicksand-Light.ttf.gz differ diff --git a/dash-frontend/assets/Quicksand-Regular.ttf.gz b/dash-frontend/assets/Quicksand-Regular.ttf.gz new file mode 100644 index 0000000..f31c5b6 Binary files /dev/null and b/dash-frontend/assets/Quicksand-Regular.ttf.gz differ diff --git a/dash-frontend/assets/dashboard/add.svg b/dash-frontend/assets/dashboard/add.svg new file mode 100644 index 0000000..1f80e29 --- /dev/null +++ b/dash-frontend/assets/dashboard/add.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/alphabetical.svg b/dash-frontend/assets/dashboard/alphabetical.svg new file mode 100644 index 0000000..0373dc5 --- /dev/null +++ b/dash-frontend/assets/dashboard/alphabetical.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/apps.svg b/dash-frontend/assets/dashboard/apps.svg new file mode 100644 index 0000000..0ac73db --- /dev/null +++ b/dash-frontend/assets/dashboard/apps.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/back.svg b/dash-frontend/assets/dashboard/back.svg new file mode 100644 index 0000000..544a693 --- /dev/null +++ b/dash-frontend/assets/dashboard/back.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/bat_10.svg b/dash-frontend/assets/dashboard/bat_10.svg new file mode 100644 index 0000000..e191e12 --- /dev/null +++ b/dash-frontend/assets/dashboard/bat_10.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/bat_100.svg b/dash-frontend/assets/dashboard/bat_100.svg new file mode 100644 index 0000000..13ee847 --- /dev/null +++ b/dash-frontend/assets/dashboard/bat_100.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/bat_20.svg b/dash-frontend/assets/dashboard/bat_20.svg new file mode 100644 index 0000000..d1f8897 --- /dev/null +++ b/dash-frontend/assets/dashboard/bat_20.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/bat_30.svg b/dash-frontend/assets/dashboard/bat_30.svg new file mode 100644 index 0000000..ab76fe1 --- /dev/null +++ b/dash-frontend/assets/dashboard/bat_30.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/bat_40.svg b/dash-frontend/assets/dashboard/bat_40.svg new file mode 100644 index 0000000..fa96a39 --- /dev/null +++ b/dash-frontend/assets/dashboard/bat_40.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/bat_50.svg b/dash-frontend/assets/dashboard/bat_50.svg new file mode 100644 index 0000000..920078d --- /dev/null +++ b/dash-frontend/assets/dashboard/bat_50.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/bat_60.svg b/dash-frontend/assets/dashboard/bat_60.svg new file mode 100644 index 0000000..9820cf8 --- /dev/null +++ b/dash-frontend/assets/dashboard/bat_60.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/bat_70.svg b/dash-frontend/assets/dashboard/bat_70.svg new file mode 100644 index 0000000..af3bc56 --- /dev/null +++ b/dash-frontend/assets/dashboard/bat_70.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/bat_80.svg b/dash-frontend/assets/dashboard/bat_80.svg new file mode 100644 index 0000000..71213ae --- /dev/null +++ b/dash-frontend/assets/dashboard/bat_80.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/bat_90.svg b/dash-frontend/assets/dashboard/bat_90.svg new file mode 100644 index 0000000..3fb8e30 --- /dev/null +++ b/dash-frontend/assets/dashboard/bat_90.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/bat_chr_10.svg b/dash-frontend/assets/dashboard/bat_chr_10.svg new file mode 100644 index 0000000..ec0600d --- /dev/null +++ b/dash-frontend/assets/dashboard/bat_chr_10.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/bat_chr_100.svg b/dash-frontend/assets/dashboard/bat_chr_100.svg new file mode 100644 index 0000000..38d7778 --- /dev/null +++ b/dash-frontend/assets/dashboard/bat_chr_100.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/bat_chr_20.svg b/dash-frontend/assets/dashboard/bat_chr_20.svg new file mode 100644 index 0000000..7454195 --- /dev/null +++ b/dash-frontend/assets/dashboard/bat_chr_20.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/bat_chr_30.svg b/dash-frontend/assets/dashboard/bat_chr_30.svg new file mode 100644 index 0000000..a5a1161 --- /dev/null +++ b/dash-frontend/assets/dashboard/bat_chr_30.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/bat_chr_40.svg b/dash-frontend/assets/dashboard/bat_chr_40.svg new file mode 100644 index 0000000..484d04c --- /dev/null +++ b/dash-frontend/assets/dashboard/bat_chr_40.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/bat_chr_50.svg b/dash-frontend/assets/dashboard/bat_chr_50.svg new file mode 100644 index 0000000..e30ac3b --- /dev/null +++ b/dash-frontend/assets/dashboard/bat_chr_50.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/bat_chr_60.svg b/dash-frontend/assets/dashboard/bat_chr_60.svg new file mode 100644 index 0000000..8d2c392 --- /dev/null +++ b/dash-frontend/assets/dashboard/bat_chr_60.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/bat_chr_70.svg b/dash-frontend/assets/dashboard/bat_chr_70.svg new file mode 100644 index 0000000..7ebd603 --- /dev/null +++ b/dash-frontend/assets/dashboard/bat_chr_70.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/bat_chr_80.svg b/dash-frontend/assets/dashboard/bat_chr_80.svg new file mode 100644 index 0000000..bb5f153 --- /dev/null +++ b/dash-frontend/assets/dashboard/bat_chr_80.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/bat_chr_90.svg b/dash-frontend/assets/dashboard/bat_chr_90.svg new file mode 100644 index 0000000..1dfceb7 --- /dev/null +++ b/dash-frontend/assets/dashboard/bat_chr_90.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/binary.svg b/dash-frontend/assets/dashboard/binary.svg new file mode 100644 index 0000000..c5e9511 --- /dev/null +++ b/dash-frontend/assets/dashboard/binary.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/burger.svg b/dash-frontend/assets/dashboard/burger.svg new file mode 100644 index 0000000..35787d3 --- /dev/null +++ b/dash-frontend/assets/dashboard/burger.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/category_search.svg b/dash-frontend/assets/dashboard/category_search.svg new file mode 100644 index 0000000..b6d707b --- /dev/null +++ b/dash-frontend/assets/dashboard/category_search.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/circle.svg b/dash-frontend/assets/dashboard/circle.svg new file mode 100644 index 0000000..e28c5e1 --- /dev/null +++ b/dash-frontend/assets/dashboard/circle.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/close.svg b/dash-frontend/assets/dashboard/close.svg new file mode 100644 index 0000000..0b749bb --- /dev/null +++ b/dash-frontend/assets/dashboard/close.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/cpu.svg b/dash-frontend/assets/dashboard/cpu.svg new file mode 100644 index 0000000..6af76cf --- /dev/null +++ b/dash-frontend/assets/dashboard/cpu.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/display.svg b/dash-frontend/assets/dashboard/display.svg new file mode 100644 index 0000000..f749bda --- /dev/null +++ b/dash-frontend/assets/dashboard/display.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/displayport.svg b/dash-frontend/assets/dashboard/displayport.svg new file mode 100644 index 0000000..6915266 --- /dev/null +++ b/dash-frontend/assets/dashboard/displayport.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/eye.svg b/dash-frontend/assets/dashboard/eye.svg new file mode 100644 index 0000000..6ad576c --- /dev/null +++ b/dash-frontend/assets/dashboard/eye.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/fix_floor.svg b/dash-frontend/assets/dashboard/fix_floor.svg new file mode 100644 index 0000000..28b18ee --- /dev/null +++ b/dash-frontend/assets/dashboard/fix_floor.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/games.svg b/dash-frontend/assets/dashboard/games.svg new file mode 100644 index 0000000..ef5b6d1 --- /dev/null +++ b/dash-frontend/assets/dashboard/games.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/github.svg b/dash-frontend/assets/dashboard/github.svg new file mode 100644 index 0000000..887b902 --- /dev/null +++ b/dash-frontend/assets/dashboard/github.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/globe.svg b/dash-frontend/assets/dashboard/globe.svg new file mode 100644 index 0000000..bf429ab --- /dev/null +++ b/dash-frontend/assets/dashboard/globe.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/home.svg b/dash-frontend/assets/dashboard/home.svg new file mode 100644 index 0000000..08163c0 --- /dev/null +++ b/dash-frontend/assets/dashboard/home.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/knife.svg b/dash-frontend/assets/dashboard/knife.svg new file mode 100644 index 0000000..5f8d620 --- /dev/null +++ b/dash-frontend/assets/dashboard/knife.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/magic_wand.svg b/dash-frontend/assets/dashboard/magic_wand.svg new file mode 100644 index 0000000..e3471a6 --- /dev/null +++ b/dash-frontend/assets/dashboard/magic_wand.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/microphone.svg b/dash-frontend/assets/dashboard/microphone.svg new file mode 100644 index 0000000..9f6afba --- /dev/null +++ b/dash-frontend/assets/dashboard/microphone.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/minijack.svg b/dash-frontend/assets/dashboard/minijack.svg new file mode 100644 index 0000000..eec823f --- /dev/null +++ b/dash-frontend/assets/dashboard/minijack.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/monado.svg b/dash-frontend/assets/dashboard/monado.svg new file mode 100644 index 0000000..a50427d --- /dev/null +++ b/dash-frontend/assets/dashboard/monado.svg @@ -0,0 +1,44 @@ + + + + + + + + diff --git a/dash-frontend/assets/dashboard/panorama.svg b/dash-frontend/assets/dashboard/panorama.svg new file mode 100644 index 0000000..d123ee2 --- /dev/null +++ b/dash-frontend/assets/dashboard/panorama.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/play.svg b/dash-frontend/assets/dashboard/play.svg new file mode 100644 index 0000000..a0f4ecb --- /dev/null +++ b/dash-frontend/assets/dashboard/play.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/power.svg b/dash-frontend/assets/dashboard/power.svg new file mode 100644 index 0000000..bbb5ef2 --- /dev/null +++ b/dash-frontend/assets/dashboard/power.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/recenter.svg b/dash-frontend/assets/dashboard/recenter.svg new file mode 100644 index 0000000..d5ee383 --- /dev/null +++ b/dash-frontend/assets/dashboard/recenter.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/refresh.svg b/dash-frontend/assets/dashboard/refresh.svg new file mode 100644 index 0000000..0e633b1 --- /dev/null +++ b/dash-frontend/assets/dashboard/refresh.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/remove_circle.svg b/dash-frontend/assets/dashboard/remove_circle.svg new file mode 100644 index 0000000..a0eb15a --- /dev/null +++ b/dash-frontend/assets/dashboard/remove_circle.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/search.svg b/dash-frontend/assets/dashboard/search.svg new file mode 100644 index 0000000..482b8ac --- /dev/null +++ b/dash-frontend/assets/dashboard/search.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/settings.svg b/dash-frontend/assets/dashboard/settings.svg new file mode 100644 index 0000000..8659ae9 --- /dev/null +++ b/dash-frontend/assets/dashboard/settings.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/sleep.svg b/dash-frontend/assets/dashboard/sleep.svg new file mode 100644 index 0000000..cae7266 --- /dev/null +++ b/dash-frontend/assets/dashboard/sleep.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/terminal.svg b/dash-frontend/assets/dashboard/terminal.svg new file mode 100644 index 0000000..935681c --- /dev/null +++ b/dash-frontend/assets/dashboard/terminal.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/usage.svg b/dash-frontend/assets/dashboard/usage.svg new file mode 100644 index 0000000..398b1ee --- /dev/null +++ b/dash-frontend/assets/dashboard/usage.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/volume.svg b/dash-frontend/assets/dashboard/volume.svg new file mode 100644 index 0000000..048d567 --- /dev/null +++ b/dash-frontend/assets/dashboard/volume.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/volume_off.svg b/dash-frontend/assets/dashboard/volume_off.svg new file mode 100644 index 0000000..f490fc5 --- /dev/null +++ b/dash-frontend/assets/dashboard/volume_off.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/vr.svg b/dash-frontend/assets/dashboard/vr.svg new file mode 100644 index 0000000..7e399d3 --- /dev/null +++ b/dash-frontend/assets/dashboard/vr.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dash-frontend/assets/dashboard/wayvr_dashboard.svg b/dash-frontend/assets/dashboard/wayvr_dashboard.svg new file mode 100644 index 0000000..06d51c6 --- /dev/null +++ b/dash-frontend/assets/dashboard/wayvr_dashboard.svg @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/dash-frontend/assets/dashboard/wayvr_dashboard_mono.svg b/dash-frontend/assets/dashboard/wayvr_dashboard_mono.svg new file mode 100644 index 0000000..e2e7ad2 --- /dev/null +++ b/dash-frontend/assets/dashboard/wayvr_dashboard_mono.svg @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + diff --git a/dash-frontend/assets/dashboard/window.svg b/dash-frontend/assets/dashboard/window.svg new file mode 100644 index 0000000..7de9ab7 --- /dev/null +++ b/dash-frontend/assets/dashboard/window.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/dash-frontend/assets/gui/dashboard.xml b/dash-frontend/assets/gui/dashboard.xml new file mode 100644 index 0000000..aaab8af --- /dev/null +++ b/dash-frontend/assets/gui/dashboard.xml @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dash-frontend/assets/gui/t_group_box.xml b/dash-frontend/assets/gui/t_group_box.xml new file mode 100644 index 0000000..d91b25e --- /dev/null +++ b/dash-frontend/assets/gui/t_group_box.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dash-frontend/assets/gui/t_menu_button.xml b/dash-frontend/assets/gui/t_menu_button.xml new file mode 100644 index 0000000..671189e --- /dev/null +++ b/dash-frontend/assets/gui/t_menu_button.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/dash-frontend/assets/gui/t_separator.xml b/dash-frontend/assets/gui/t_separator.xml new file mode 100644 index 0000000..92a8285 --- /dev/null +++ b/dash-frontend/assets/gui/t_separator.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/dash-frontend/assets/gui/tab/apps.xml b/dash-frontend/assets/gui/tab/apps.xml new file mode 100644 index 0000000..fd8bf48 --- /dev/null +++ b/dash-frontend/assets/gui/tab/apps.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dash-frontend/assets/gui/tab/games.xml b/dash-frontend/assets/gui/tab/games.xml new file mode 100644 index 0000000..4a1fde2 --- /dev/null +++ b/dash-frontend/assets/gui/tab/games.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/dash-frontend/assets/gui/tab/home.xml b/dash-frontend/assets/gui/tab/home.xml new file mode 100644 index 0000000..7a9d2ff --- /dev/null +++ b/dash-frontend/assets/gui/tab/home.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dash-frontend/assets/gui/tab/monado.xml b/dash-frontend/assets/gui/tab/monado.xml new file mode 100644 index 0000000..729f356 --- /dev/null +++ b/dash-frontend/assets/gui/tab/monado.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/dash-frontend/assets/gui/tab/processes.xml b/dash-frontend/assets/gui/tab/processes.xml new file mode 100644 index 0000000..0330d48 --- /dev/null +++ b/dash-frontend/assets/gui/tab/processes.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/dash-frontend/assets/gui/tab/settings.xml b/dash-frontend/assets/gui/tab/settings.xml new file mode 100644 index 0000000..592c2b0 --- /dev/null +++ b/dash-frontend/assets/gui/tab/settings.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dash-frontend/assets/gui/tab/t_tab_title.xml b/dash-frontend/assets/gui/tab/t_tab_title.xml new file mode 100644 index 0000000..fc7e2b0 --- /dev/null +++ b/dash-frontend/assets/gui/tab/t_tab_title.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/dash-frontend/assets/gui/theme.xml b/dash-frontend/assets/gui/theme.xml new file mode 100644 index 0000000..28f4e57 --- /dev/null +++ b/dash-frontend/assets/gui/theme.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/dash-frontend/assets/gui/view/app_launcher.xml b/dash-frontend/assets/gui/view/app_launcher.xml new file mode 100644 index 0000000..8b0b4bd --- /dev/null +++ b/dash-frontend/assets/gui/view/app_launcher.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dash-frontend/assets/gui/view/audio_settings.xml b/dash-frontend/assets/gui/view/audio_settings.xml new file mode 100644 index 0000000..c792333 --- /dev/null +++ b/dash-frontend/assets/gui/view/audio_settings.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dash-frontend/assets/gui/view/popup_window.xml b/dash-frontend/assets/gui/view/popup_window.xml new file mode 100644 index 0000000..8d2cf37 --- /dev/null +++ b/dash-frontend/assets/gui/view/popup_window.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dash-frontend/assets/lang/de.json b/dash-frontend/assets/lang/de.json new file mode 100644 index 0000000..ba4d28c --- /dev/null +++ b/dash-frontend/assets/lang/de.json @@ -0,0 +1,49 @@ +{ + "HOME_SCREEN": "Startbildschirm", + "MONADO_RUNTIME": "„Monado”-Laufzeitumgebung", + "APPLICATIONS": "Anwendungen", + "GAMES": "Spiele", + "SETTINGS": "Einstellungen", + "PROCESSES": "Prozesse", + "HELLO_USER": "Hallo, {USER}!", + "GENERAL_SETTINGS": "Allgemeine Einstellungen", + "APPLICATION_LAUNCHER": "Anwendung Launcher", + "APP_SETTINGS": { + "HIDE_USERNAME": "Benutzernamen ausblenden", + "OPAQUE_BACKGROUND": "Undurchsichtiger Hintergrund", + "RUN_IN_XWAYLAND_MODE_BY_DEFAULT": "Standardmäßig in XWayland-Modus ausführen", + "WLX_OVERLAY_S_SETTINGS": "WlxOverlay-S Einstellungen", + "HEADSET_SETTINGS": "Headset-Einstellungen", + "BRIGHTNESS": "Helligkeit", + "WLX": { + "NOTIFICATIONS_ENABLED": "Benachrichtigungen aktiviert", + "NOTIFICATIONS_SOUND_ENABLED": "Benachrichtigungssound aktiviert", + "KEYBOARD_SOUND_ENABLED": "Tastaturgeräusch aktiviert", + "BLOCK_GAME_INPUT": "Spielsteuerung blockieren", + "SPACE_DRAG_MULTIPLIER": "Raum-Drag-Multiplikator", + "SPACE_DRAG_ROTATION_ENABLED": "Rotation im Space-Drag aktivieren", + "SHOW_SKYBOX": "Skybox anzeigen", + "ENABLE_PASSTHROUGH": "Passthrough aktivieren" + }, + "RESTART_SOFTWARE": "Software neu starten" + }, + "HELLO": "Hallo!", + "AUDIO": { + "VOLUME": "Lautstärke", + "SETTINGS": "Audioeinstellungen", + "AUTO_SWITCH_TO_VR_AUDIO": "Automatisch auf VR-Audio umschalten", + "SPEAKERS": "Lautsprecher", + "MICROPHONES": "Mikrofone", + "CARDS": "Karten", + "SELECT_AUDIO_CARD_PROFILE": "Wählen Sie das Audio-Kartenprofil", + "NO_VR_SPEAKERS_FOUND_SWITCH_MANUALLY": "Keine VR-Lautsprecher gefunden. Schalten Sie diese manuell um.", + "NO_VR_MICROPHONE_SWITCH_MANUALLY": "Kein VR-Mikrofon gefunden. Schalten Sie es manuell um.", + "FAILED_TO_SWITCH_MICROPHONE": "Fehler beim Wechseln des Mikrofons", + "MICROPHONE_SET_SUCCESSFULLY": "Mikrofon erfolgreich eingestellt", + "SPEAKERS_SET_SUCCESSFULLY": "Lautsprecher erfolgreich eingestellt", + "DEVICE_FOUND_AND_INITIALIZED_BUT_NOT_SWITCHED": "Gerät gefunden und initialisiert, aber nicht umgeschaltet" + }, + "ACTIONS": { + "RECENTER_PLAYSPACE": "Playspace neu zentrieren" + } +} \ No newline at end of file diff --git a/dash-frontend/assets/lang/en.json b/dash-frontend/assets/lang/en.json new file mode 100644 index 0000000..b92964e --- /dev/null +++ b/dash-frontend/assets/lang/en.json @@ -0,0 +1,49 @@ +{ + "HOME_SCREEN": "Home", + "MONADO_RUNTIME": "„Monado” runtime", + "APPLICATIONS": "Applications", + "GAMES": "Games", + "SETTINGS": "Settings", + "PROCESSES": "Processes", + "HELLO_USER": "Hello, {USER}!", + "HELLO": "Hello!", + "GENERAL_SETTINGS": "General settings", + "APPLICATION_LAUNCHER": "Application launcher", + "APP_SETTINGS": { + "RESTART_SOFTWARE": "Restart software", + "HIDE_USERNAME": "Hide username", + "OPAQUE_BACKGROUND": "Opaque background", + "RUN_IN_XWAYLAND_MODE_BY_DEFAULT": "Run in XWayland mode by default", + "WLX_OVERLAY_S_SETTINGS": "WlxOverlay-S settings", + "HEADSET_SETTINGS": "Headset settings", + "BRIGHTNESS": "Brightness", + "WLX": { + "NOTIFICATIONS_ENABLED": "Notifications enabled", + "NOTIFICATIONS_SOUND_ENABLED": "Notifications sound enabled", + "KEYBOARD_SOUND_ENABLED": "Keyboard sound enabled", + "BLOCK_GAME_INPUT": "Block game input", + "SPACE_DRAG_MULTIPLIER": "Space-drag multiplier", + "SPACE_DRAG_ROTATION_ENABLED": "Enable rotation in space-drag", + "SHOW_SKYBOX": "Show skybox", + "ENABLE_PASSTHROUGH": "Enable passthrough" + } + }, + "AUDIO": { + "SELECT_AUDIO_CARD_PROFILE": "Select audio card profile", + "SETTINGS": "Audio settings", + "VOLUME": "Volume", + "AUTO_SWITCH_TO_VR_AUDIO": "Auto-switch to VR audio", + "SPEAKERS": "Speakers", + "MICROPHONES": "Microphones", + "CARDS": "Cards", + "NO_VR_SPEAKERS_FOUND_SWITCH_MANUALLY": "No VR speakers found. Switch them manually.", + "NO_VR_MICROPHONE_SWITCH_MANUALLY": "No VR microphone found. Switch it manually.", + "FAILED_TO_SWITCH_MICROPHONE": "Failed to switch microphone", + "MICROPHONE_SET_SUCCESSFULLY": "Microphone set successfully", + "SPEAKERS_SET_SUCCESSFULLY": "Speakers set successfully", + "DEVICE_FOUND_AND_INITIALIZED_BUT_NOT_SWITCHED": "Device found and initialized, but not switched" + }, + "ACTIONS": { + "RECENTER_PLAYSPACE": "Re-center playspace" + } +} diff --git a/dash-frontend/assets/lang/es.json b/dash-frontend/assets/lang/es.json new file mode 100644 index 0000000..cb7869d --- /dev/null +++ b/dash-frontend/assets/lang/es.json @@ -0,0 +1,49 @@ +{ + "HOME_SCREEN": "Inicio", + "MONADO_RUNTIME": "„Monado” tiempo de ejecución", + "APPLICATIONS": "Aplicaciones", + "GAMES": "Juegos", + "SETTINGS": "Ajustes", + "PROCESSES": "Procesos", + "HELLO_USER": "¡Hola, {USER}!", + "GENERAL_SETTINGS": "Ajustes generales", + "APPLICATION_LAUNCHER": "Lanzador de aplicaciones", + "APP_SETTINGS": { + "HIDE_USERNAME": "Ocultar nombre de usuario", + "OPAQUE_BACKGROUND": "Fondo opaco", + "RUN_IN_XWAYLAND_MODE_BY_DEFAULT": "Ejecutar en modo XWayland por defecto", + "WLX_OVERLAY_S_SETTINGS": "Configuración de WlxOverlay-S", + "HEADSET_SETTINGS": "Configuración del casco", + "BRIGHTNESS": "Brillo", + "WLX": { + "NOTIFICATIONS_ENABLED": "Notificaciones activadas", + "NOTIFICATIONS_SOUND_ENABLED": "Sonido de notificaciones activado", + "KEYBOARD_SOUND_ENABLED": "Sonido del teclado activado", + "BLOCK_GAME_INPUT": "Bloquear entrada del juego", + "SPACE_DRAG_MULTIPLIER": "Multiplicador de movimiento por arrastre", + "SPACE_DRAG_ROTATION_ENABLED": "Habilitar rotación en space-drag", + "SHOW_SKYBOX": "Mostrar cielo", + "ENABLE_PASSTHROUGH": "Habilitar Passthrough" + }, + "RESTART_SOFTWARE": "Reiniciar software" + }, + "HELLO": "¡Hola!", + "AUDIO": { + "VOLUME": "Volumen", + "SETTINGS": "Configuración de audio", + "AUTO_SWITCH_TO_VR_AUDIO": "Conmutar automáticamente al audio VR", + "SPEAKERS": "Altavoces", + "MICROPHONES": "Micrófonos", + "CARDS": "Tarjetas", + "SELECT_AUDIO_CARD_PROFILE": "Seleccionar perfil de tarjeta de audio", + "NO_VR_SPEAKERS_FOUND_SWITCH_MANUALLY": "No se encontraron altavoces VR. Actívelos manualmente.", + "NO_VR_MICROPHONE_SWITCH_MANUALLY": "No se encontró micrófono VR. Actívelo manualmente.", + "FAILED_TO_SWITCH_MICROPHONE": "No se pudo cambiar el micrófono", + "MICROPHONE_SET_SUCCESSFULLY": "Micrófono configurado correctamente", + "SPEAKERS_SET_SUCCESSFULLY": "Altavoces configurados correctamente", + "DEVICE_FOUND_AND_INITIALIZED_BUT_NOT_SWITCHED": "Dispositivo encontrado e inicializado, pero no cambiado" + }, + "ACTIONS": { + "RECENTER_PLAYSPACE": "Re-centrar espacio de juego" + } +} \ No newline at end of file diff --git a/dash-frontend/assets/lang/ja.json b/dash-frontend/assets/lang/ja.json new file mode 100644 index 0000000..e8c59fb --- /dev/null +++ b/dash-frontend/assets/lang/ja.json @@ -0,0 +1,49 @@ +{ + "HOME_SCREEN": "ホーム", + "MONADO_RUNTIME": "「Monado」ランタイム", + "APPLICATIONS": "アプリケーション", + "GAMES": "ゲーム", + "SETTINGS": "設定", + "PROCESSES": "プロセス", + "HELLO_USER": "こんにちは、{USER}!", + "GENERAL_SETTINGS": "全般設定", + "APPLICATION_LAUNCHER": "アプリケーションランチャー", + "APP_SETTINGS": { + "HIDE_USERNAME": "ユーザー名を表示しない", + "OPAQUE_BACKGROUND": "不透明な背景", + "RUN_IN_XWAYLAND_MODE_BY_DEFAULT": "XWaylandモードでデフォルトで実行する", + "WLX_OVERLAY_S_SETTINGS": "WlxOverlay-Sの設定", + "HEADSET_SETTINGS": "ヘッドセット設定", + "BRIGHTNESS": "明るさ", + "WLX": { + "NOTIFICATIONS_ENABLED": "通知が有効", + "NOTIFICATIONS_SOUND_ENABLED": "通知音を有効にする", + "KEYBOARD_SOUND_ENABLED": "キーボード音を有効にする", + "BLOCK_GAME_INPUT": "ゲーム入力をブロック", + "SPACE_DRAG_MULTIPLIER": "スペースドラッグ乗数", + "SPACE_DRAG_ROTATION_ENABLED": "スペースドラッグでの回転を有効にする", + "SHOW_SKYBOX": "スカイボックスを表示", + "ENABLE_PASSTHROUGH": "Passthroughを有効にする" + }, + "RESTART_SOFTWARE": "ソフトウェアを再起動" + }, + "HELLO": "こんにちは!", + "AUDIO": { + "VOLUME": "音量", + "SETTINGS": "オーディオ設定", + "AUTO_SWITCH_TO_VR_AUDIO": "VRオーディオに自動切り替え", + "SPEAKERS": "スピーカー", + "MICROPHONES": "マイク", + "CARDS": "カード", + "SELECT_AUDIO_CARD_PROFILE": "オーディオカードプロファイルを選択", + "NO_VR_SPEAKERS_FOUND_SWITCH_MANUALLY": "VRスピーカーが見つかりませんでした。手動で切り替えてください。", + "NO_VR_MICROPHONE_SWITCH_MANUALLY": "VRマイクが見つかりませんでした。手動で切り替えてください。", + "FAILED_TO_SWITCH_MICROPHONE": "マイクの切り替えに失敗しました", + "MICROPHONE_SET_SUCCESSFULLY": "マイクの設定が完了しました", + "SPEAKERS_SET_SUCCESSFULLY": "スピーカーを設定しました", + "DEVICE_FOUND_AND_INITIALIZED_BUT_NOT_SWITCHED": "デバイスが見つかり、初期化されましたが、切り替えられていません" + }, + "ACTIONS": { + "RECENTER_PLAYSPACE": "プレイスペースを再中央" + } +} \ No newline at end of file diff --git a/dash-frontend/assets/lang/pl.json b/dash-frontend/assets/lang/pl.json new file mode 100644 index 0000000..f2896e2 --- /dev/null +++ b/dash-frontend/assets/lang/pl.json @@ -0,0 +1,49 @@ +{ + "HOME_SCREEN": "Ekran główny", + "MONADO_RUNTIME": "„Monado” środowisko uruchomieniowe", + "APPLICATIONS": "Aplikacje", + "GAMES": "Gry", + "SETTINGS": "Ustawienia", + "PROCESSES": "Procesy", + "HELLO_USER": "Witaj, {USER}!", + "GENERAL_SETTINGS": "Ustawienia ogólne", + "APPLICATION_LAUNCHER": "Uruchamiacz aplikacji", + "APP_SETTINGS": { + "HIDE_USERNAME": "Ukryj nazwę użytkownika", + "OPAQUE_BACKGROUND": "Nieprzezroczyste tło", + "RUN_IN_XWAYLAND_MODE_BY_DEFAULT": "Uruchom domyślnie w trybie XWayland", + "WLX_OVERLAY_S_SETTINGS": "Ustawienia wlx-overlay-s", + "HEADSET_SETTINGS": "Ustawienia HMD", + "BRIGHTNESS": "Jasność", + "WLX": { + "NOTIFICATIONS_ENABLED": "Powiadomienia", + "NOTIFICATIONS_SOUND_ENABLED": "Dźwięk powiadomień", + "KEYBOARD_SOUND_ENABLED": "Dźwięki klawiatury", + "BLOCK_GAME_INPUT": "Zablokuj sterowanie grą podczas używania Wlx", + "SPACE_DRAG_MULTIPLIER": "Mnożnik space-drag", + "SPACE_DRAG_ROTATION_ENABLED": "Włącz rotację w space-drag", + "SHOW_SKYBOX": "Pokaż skybox", + "ENABLE_PASSTHROUGH": "Włącz passthrough" + }, + "RESTART_SOFTWARE": "Uruchom ponownie oprogramowanie" + }, + "HELLO": "Witaj!", + "AUDIO": { + "VOLUME": "Głośność", + "SETTINGS": "Ustawienia dźwięku", + "AUTO_SWITCH_TO_VR_AUDIO": "Automatyczne przełączanie na dźwięk VR", + "SPEAKERS": "Głośniki", + "MICROPHONES": "Mikrofony", + "CARDS": "Karty", + "SELECT_AUDIO_CARD_PROFILE": "Wybierz profil karty dźwiękowej", + "NO_VR_SPEAKERS_FOUND_SWITCH_MANUALLY": "Brak głośników VR. Włącz je ręcznie.", + "NO_VR_MICROPHONE_SWITCH_MANUALLY": "Brak mikrofonu VR. Włącz go ręcznie.", + "FAILED_TO_SWITCH_MICROPHONE": "Nie udało się przełączyć mikrofon", + "MICROPHONE_SET_SUCCESSFULLY": "Mikrofon ustawiono pomyślnie", + "SPEAKERS_SET_SUCCESSFULLY": "Głośniki ustawiono pomyślnie", + "DEVICE_FOUND_AND_INITIALIZED_BUT_NOT_SWITCHED": "Urządzenie znalezione i zainicjalizowane, ale nie przełączone" + }, + "ACTIONS": { + "RECENTER_PLAYSPACE": "Wycentruj przestrzeń" + } +} \ No newline at end of file diff --git a/dash-frontend/rustfmt.toml b/dash-frontend/rustfmt.toml new file mode 100644 index 0000000..bfdeee4 --- /dev/null +++ b/dash-frontend/rustfmt.toml @@ -0,0 +1,3 @@ +tab_spaces = 2 +hard_tabs = true +max_width = 120 diff --git a/dash-frontend/src/assets.rs b/dash-frontend/src/assets.rs new file mode 100644 index 0000000..cbc6b5e --- /dev/null +++ b/dash-frontend/src/assets.rs @@ -0,0 +1,12 @@ +#[derive(rust_embed::Embed)] +#[folder = "assets/"] +pub struct Asset; + +impl wgui::assets::AssetProvider for Asset { + fn load_from_path(&mut self, path: &str) -> anyhow::Result> { + match Asset::get(path) { + Some(data) => Ok(data.data.to_vec()), + None => anyhow::bail!("embedded file {} not found", path), + } + } +} diff --git a/dash-frontend/src/frontend.rs b/dash-frontend/src/frontend.rs new file mode 100644 index 0000000..f1397c7 --- /dev/null +++ b/dash-frontend/src/frontend.rs @@ -0,0 +1,434 @@ +use std::{cell::RefCell, path::PathBuf, rc::Rc}; + +use chrono::Timelike; +use glam::Vec2; +use wgui::{ + assets::{AssetPath, AssetProvider}, + components::button::ComponentButton, + font_config::WguiFontConfig, + globals::WguiGlobals, + i18n::Translation, + layout::{LayoutParams, RcLayout, WidgetID}, + parser::{Fetchable, ParseDocumentParams, ParserState}, + widget::{label::WidgetLabel, rectangle::WidgetRectangle}, + windowing::{WguiWindow, WguiWindowParams, WguiWindowParamsExtra, WguiWindowPlacement}, +}; +use wlx_common::timestep::Timestep; + +use crate::{ + assets, settings, + tab::{ + Tab, TabParams, TabType, apps::TabApps, games::TabGames, home::TabHome, monado::TabMonado, processes::TabProcesses, + settings::TabSettings, + }, + task::Tasks, + util::{ + popup_manager::{MountPopupParams, PopupManager, PopupManagerParams}, + toast_manager::ToastManager, + }, + views, +}; + +pub struct FrontendWidgets { + pub id_label_time: WidgetID, + pub id_rect_content: WidgetID, +} + +pub type FrontendTasks = Tasks; + +pub struct Frontend { + pub layout: RcLayout, + globals: WguiGlobals, + + pub settings: Box, + + #[allow(dead_code)] + state: ParserState, + + current_tab: Option>, + + pub tasks: FrontendTasks, + + ticks: u32, + + widgets: FrontendWidgets, + popup_manager: PopupManager, + toast_manager: ToastManager, + timestep: Timestep, + + window_audio_settings: WguiWindow, + view_audio_settings: Option, +} + +pub struct InitParams { + pub settings: Box, +} + +pub type RcFrontend = Rc>; + +#[derive(Clone)] +pub enum FrontendTask { + SetTab(TabType), + RefreshClock, + RefreshBackground, + MountPopup(MountPopupParams), + RefreshPopupManager, + ShowAudioSettings, + UpdateAudioSettingsView, + RecenterPlayspace, + PushToast(Translation), +} + +impl Frontend { + pub fn new(params: InitParams) -> anyhow::Result<(RcFrontend, RcLayout)> { + let mut assets = Box::new(assets::Asset {}); + + let font_binary_bold = assets.load_from_path_gzip("Quicksand-Bold.ttf.gz")?; + let font_binary_regular = assets.load_from_path_gzip("Quicksand-Regular.ttf.gz")?; + let font_binary_light = assets.load_from_path_gzip("Quicksand-Light.ttf.gz")?; + + let globals = WguiGlobals::new( + assets, + wgui::globals::Defaults::default(), + &WguiFontConfig { + binaries: vec![&font_binary_regular, &font_binary_bold, &font_binary_light], + family_name_sans_serif: "Quicksand", + family_name_serif: "Quicksand", + family_name_monospace: "", + }, + PathBuf::new(), //FIXME: pass from somewhere else + )?; + + let (layout, state) = wgui::parser::new_layout_from_assets( + &ParseDocumentParams { + globals: globals.clone(), + path: AssetPath::BuiltIn("gui/dashboard.xml"), + extra: Default::default(), + }, + &LayoutParams { resize_to_parent: true }, + )?; + + let id_popup_manager = state.get_widget_id("popup_manager")?; + let popup_manager = PopupManager::new(PopupManagerParams { + parent_id: id_popup_manager, + }); + + let toast_manager = ToastManager::new(); + + let rc_layout = layout.as_rc(); + + let tasks = FrontendTasks::new(); + tasks.push(FrontendTask::SetTab(TabType::Home)); + + let id_label_time = state.get_widget_id("label_time")?; + let id_rect_content = state.get_widget_id("rect_content")?; + + let mut timestep = Timestep::new(); + timestep.set_tps(30.0); // 30 ticks per second + + let frontend = Self { + layout: rc_layout.clone(), + state, + current_tab: None, + globals, + tasks, + ticks: 0, + widgets: FrontendWidgets { + id_label_time, + id_rect_content, + }, + timestep, + settings: params.settings, + popup_manager, + toast_manager, + window_audio_settings: WguiWindow::default(), + view_audio_settings: None, + }; + + // init some things first + frontend.update_background()?; + frontend.update_time()?; + + let res = Rc::new(RefCell::new(frontend)); + + Frontend::register_widgets(&res)?; + + Ok((res, rc_layout)) + } + + pub fn update(&mut self, rc_this: &RcFrontend, width: f32, height: f32, timestep_alpha: f32) -> anyhow::Result<()> { + let mut tasks = self.tasks.drain(); + + while let Some(task) = tasks.pop_front() { + self.process_task(rc_this, task)?; + } + + self.tick(width, height, timestep_alpha)?; + self.ticks += 1; + + Ok(()) + } + + fn tick(&mut self, width: f32, height: f32, timestep_alpha: f32) -> anyhow::Result<()> { + // fixme: timer events instead of this thing + if self.ticks.is_multiple_of(1000) { + self.update_time()?; + } + + { + let mut layout = self.layout.borrow_mut(); + + // always 30 times per second + while self.timestep.on_tick() { + self.toast_manager.tick(&self.globals, &mut layout)?; + } + + layout.update(Vec2::new(width, height), timestep_alpha)?; + } + + Ok(()) + } + + fn update_time(&self) -> anyhow::Result<()> { + let mut layout = self.layout.borrow_mut(); + let mut c = layout.start_common(); + let mut common = c.common(); + + { + let Some(mut label) = common.state.widgets.get_as::(self.widgets.id_label_time) else { + anyhow::bail!(""); + }; + + let now = chrono::Local::now(); + let hours = now.hour(); + let minutes = now.minute(); + + let text: String = if !self.settings.get().general.am_pm_clock { + format!("{hours:02}:{minutes:02}") + } else { + let hours_ampm = (hours + 11) % 12 + 1; + let suffix = if hours >= 12 { "PM" } else { "AM" }; + format!("{hours_ampm:02}:{minutes:02} {suffix}") + }; + + label.set_text(&mut common, Translation::from_raw_text(&text)); + } + + c.finish()?; + Ok(()) + } + + fn mount_popup(&mut self, params: MountPopupParams) -> anyhow::Result<()> { + let mut layout = self.layout.borrow_mut(); + self + .popup_manager + .mount_popup(self.globals.clone(), &mut layout, self.tasks.clone(), params)?; + Ok(()) + } + + fn refresh_popup_manager(&mut self) -> anyhow::Result<()> { + let mut layout = self.layout.borrow_mut(); + let mut c = layout.start_common(); + self.popup_manager.refresh(c.common().alterables); + c.finish()?; + Ok(()) + } + + fn update_background(&self) -> anyhow::Result<()> { + let layout = self.layout.borrow_mut(); + + let Some(mut rect) = layout + .state + .widgets + .get_as::(self.widgets.id_rect_content) + else { + anyhow::bail!(""); + }; + + let (alpha1, alpha2) = if !self.settings.get().general.opaque_background { + (0.8666, 0.9333) + } else { + (1.0, 1.0) + }; + + rect.params.color.a = alpha1; + rect.params.color2.a = alpha2; + + Ok(()) + } + + pub fn get_layout(&self) -> &RcLayout { + &self.layout + } + + fn process_task(&mut self, rc_this: &RcFrontend, task: FrontendTask) -> anyhow::Result<()> { + match task { + FrontendTask::SetTab(tab_type) => self.set_tab(tab_type, rc_this)?, + FrontendTask::RefreshClock => self.update_time()?, + FrontendTask::RefreshBackground => self.update_background()?, + FrontendTask::MountPopup(params) => self.mount_popup(params)?, + FrontendTask::RefreshPopupManager => self.refresh_popup_manager()?, + FrontendTask::ShowAudioSettings => self.action_show_audio_settings()?, + FrontendTask::UpdateAudioSettingsView => self.action_update_audio_settings()?, + FrontendTask::RecenterPlayspace => self.action_recenter_playspace()?, + FrontendTask::PushToast(content) => self.toast_manager.push(content), + }; + Ok(()) + } + + fn set_tab(&mut self, tab_type: TabType, rc_this: &RcFrontend) -> anyhow::Result<()> { + log::info!("Setting tab to {tab_type:?}"); + let mut layout = self.layout.borrow_mut(); + let widget_content = self.state.fetch_widget(&layout.state, "content")?; + layout.remove_children(widget_content.id); + + let tab_params = TabParams { + globals: &self.globals, + layout: &mut layout, + parent_id: widget_content.id, + frontend: rc_this, + //frontend_widgets: &self.widgets, + settings: self.settings.get_mut(), + }; + + let tab: Box = match tab_type { + TabType::Home => Box::new(TabHome::new(tab_params)?), + TabType::Apps => Box::new(TabApps::new(tab_params)?), + TabType::Games => Box::new(TabGames::new(tab_params)?), + TabType::Monado => Box::new(TabMonado::new(tab_params)?), + TabType::Processes => Box::new(TabProcesses::new(tab_params)?), + TabType::Settings => Box::new(TabSettings::new(tab_params)?), + }; + + self.current_tab = Some(tab); + + Ok(()) + } + + pub fn register_button_task(this_rc: RcFrontend, btn: &Rc, task: FrontendTask) { + btn.on_click({ + Box::new(move |_common, _evt| { + this_rc.borrow_mut().tasks.push(task.clone()); + Ok(()) + }) + }); + } + + fn register_widgets(rc_this: &RcFrontend) -> anyhow::Result<()> { + let this = rc_this.borrow_mut(); + + // ################################ + // SIDE BUTTONS + // ################################ + + // "Home" side button + Frontend::register_button_task( + rc_this.clone(), + &this.state.fetch_component_as::("btn_side_home")?, + FrontendTask::SetTab(TabType::Home), + ); + + // "Apps" side button + Frontend::register_button_task( + rc_this.clone(), + &this.state.fetch_component_as::("btn_side_apps")?, + FrontendTask::SetTab(TabType::Apps), + ); + + // "Games" side button + Frontend::register_button_task( + rc_this.clone(), + &this.state.fetch_component_as::("btn_side_games")?, + FrontendTask::SetTab(TabType::Games), + ); + + // "Monado side button" + Frontend::register_button_task( + rc_this.clone(), + &this.state.fetch_component_as::("btn_side_monado")?, + FrontendTask::SetTab(TabType::Monado), + ); + + // "Processes" side button + Frontend::register_button_task( + rc_this.clone(), + &this.state.fetch_component_as::("btn_side_processes")?, + FrontendTask::SetTab(TabType::Processes), + ); + + // "Settings" side button + Frontend::register_button_task( + rc_this.clone(), + &this.state.fetch_component_as::("btn_side_settings")?, + FrontendTask::SetTab(TabType::Settings), + ); + + // ################################ + // BOTTOM BAR BUTTONS + // ################################ + + // "Audio" bottom bar button + Frontend::register_button_task( + rc_this.clone(), + &this.state.fetch_component_as::("btn_audio")?, + FrontendTask::ShowAudioSettings, + ); + + // "Recenter playspace" bottom bar button + Frontend::register_button_task( + rc_this.clone(), + &this.state.fetch_component_as::("btn_recenter")?, + FrontendTask::RecenterPlayspace, + ); + + Ok(()) + } + + fn action_show_audio_settings(&mut self) -> anyhow::Result<()> { + let mut layout = self.layout.borrow_mut(); + + self.window_audio_settings.open(&mut WguiWindowParams { + globals: self.globals.clone(), + position: Vec2::new(64.0, 64.0), + layout: &mut layout, + title: Translation::from_translation_key("AUDIO.SETTINGS"), + extra: WguiWindowParamsExtra { + fixed_width: Some(400.0), + placement: WguiWindowPlacement::BottomLeft, + ..Default::default() + }, + })?; + + let content = self.window_audio_settings.get_content(); + + self.view_audio_settings = Some(views::audio_settings::View::new(views::audio_settings::Params { + globals: self.globals.clone(), + frontend_tasks: self.tasks.clone(), + layout: &mut layout, + parent_id: content.id, + on_update: { + let tasks = self.tasks.clone(); + Rc::new(move || { + tasks.push(FrontendTask::UpdateAudioSettingsView); + }) + }, + })?); + Ok(()) + } + + fn action_update_audio_settings(&mut self) -> anyhow::Result<()> { + let Some(view) = &mut self.view_audio_settings else { + return Ok(()); + }; + + let mut layout = self.layout.borrow_mut(); + view.update(&mut layout)?; + + Ok(()) + } + + fn action_recenter_playspace(&mut self) -> anyhow::Result<()> { + log::info!("todo"); + Ok(()) + } +} diff --git a/dash-frontend/src/lib.rs b/dash-frontend/src/lib.rs new file mode 100644 index 0000000..e930036 --- /dev/null +++ b/dash-frontend/src/lib.rs @@ -0,0 +1,8 @@ +mod assets; +pub mod frontend; +pub mod settings; +mod tab; +mod task; +mod util; +mod various; +mod views; diff --git a/dash-frontend/src/settings.rs b/dash-frontend/src/settings.rs new file mode 100644 index 0000000..d4e2402 --- /dev/null +++ b/dash-frontend/src/settings.rs @@ -0,0 +1,42 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Default, Serialize, Deserialize)] +pub struct HomeScreen { + pub hide_username: bool, +} + +#[derive(Default, Serialize, Deserialize)] +pub struct General { + pub am_pm_clock: bool, + pub opaque_background: bool, +} + +#[derive(Default, Serialize, Deserialize)] +pub struct Tweaks { + pub xwayland_by_default: bool, +} + +#[derive(Default, Serialize, Deserialize)] +pub struct Settings { + pub home_screen: HomeScreen, + pub general: General, + pub tweaks: Tweaks, +} + +impl Settings { + pub fn save(&self) -> String { + serde_json::to_string_pretty(&self).unwrap() /* want panic */ + } + + pub fn load(input: &str) -> anyhow::Result { + Ok(serde_json::from_str::(input)?) + } +} + +pub trait SettingsIO { + fn get_mut(&mut self) -> &mut Settings; + fn get(&self) -> &Settings; + fn save_to_disk(&mut self); + fn read_from_disk(&mut self); + fn mark_as_dirty(&mut self); +} diff --git a/dash-frontend/src/tab/apps.rs b/dash-frontend/src/tab/apps.rs new file mode 100644 index 0000000..ee9ecc3 --- /dev/null +++ b/dash-frontend/src/tab/apps.rs @@ -0,0 +1,181 @@ +use std::{cell::RefCell, collections::HashMap, rc::Rc}; + +use wgui::{ + assets::AssetPath, + components::button::{ButtonClickCallback, ComponentButton}, + globals::WguiGlobals, + i18n::Translation, + layout::WidgetPair, + parser::{Fetchable, ParseDocumentParams, ParserState}, +}; + +use crate::{ + frontend::{FrontendTask, RcFrontend}, + tab::{Tab, TabParams, TabType}, + util::{ + self, + desktop_finder::DesktopEntry, + popup_manager::{MountPopupParams, PopupHandle}, + }, + views::{self, app_launcher}, +}; + +struct State { + launcher: Option<(PopupHandle, views::app_launcher::View)>, +} + +pub struct TabApps { + #[allow(dead_code)] + pub parser_state: ParserState, + + #[allow(dead_code)] + state: Rc>, + + #[allow(dead_code)] + entries: Vec, + #[allow(dead_code)] + app_list: AppList, +} + +impl Tab for TabApps { + fn get_type(&self) -> TabType { + TabType::Apps + } +} + +#[derive(Default)] +struct AppList { + //data: Vec, +} + +// called after the user clicks any desktop entry +fn on_app_click( + frontend: RcFrontend, + globals: WguiGlobals, + entry: DesktopEntry, + state: Rc>, +) -> ButtonClickCallback { + Box::new(move |_common, _evt| { + frontend + .borrow_mut() + .tasks + .push(FrontendTask::MountPopup(MountPopupParams { + title: Translation::from_raw_text(&entry.app_name), + on_content: { + let state = state.clone(); + let entry = entry.clone(); + let globals = globals.clone(); + Rc::new(move |data| { + let view = app_launcher::View::new(app_launcher::Params { + entry: entry.clone(), + globals: globals.clone(), + layout: data.layout, + parent_id: data.id_content, + })?; + + state.borrow_mut().launcher = Some((data.handle, view)); + Ok(()) + }) + }, + })); + Ok(()) + }) +} + +impl TabApps { + pub fn new(mut tab_params: TabParams) -> anyhow::Result { + let doc_params = &ParseDocumentParams { + globals: tab_params.globals.clone(), + path: AssetPath::BuiltIn("gui/tab/apps.xml"), + extra: Default::default(), + }; + + gtk::init()?; + let entries = util::desktop_finder::find_entries()?; + + let frontend = tab_params.frontend.clone(); + let globals = tab_params.globals.clone(); + + let state = Rc::new(RefCell::new(State { launcher: None })); + + let mut parser_state = wgui::parser::parse_from_assets(doc_params, tab_params.layout, tab_params.parent_id)?; + let app_list_parent = parser_state.fetch_widget(&tab_params.layout.state, "app_list_parent")?; + let mut app_list = AppList::default(); + app_list.mount_entries( + &entries, + &mut parser_state, + doc_params, + &mut tab_params, + &app_list_parent, + |button, entry| { + // Set up the click handler for the app button + button.on_click(on_app_click( + frontend.clone(), + globals.clone(), + entry.clone(), + state.clone(), + )); + }, + )?; + + Ok(Self { + app_list, + parser_state, + entries, + state, + }) + } +} + +impl AppList { + fn mount_entry( + &mut self, + parser_state: &mut ParserState, + doc_params: &ParseDocumentParams, + params: &mut TabParams, + list_parent: &WidgetPair, + entry: &DesktopEntry, + ) -> anyhow::Result> { + let mut template_params = HashMap::new(); + + // entry icon + template_params.insert( + Rc::from("src_ext"), + entry + .icon_path + .as_ref() + .map_or_else(|| Rc::from(""), |icon_path| Rc::from(icon_path.as_str())), + ); + + // entry fallback (question mark) icon + template_params.insert( + Rc::from("src"), + if entry.icon_path.is_none() { + Rc::from("dashboard/terminal.svg") + } else { + Rc::from("") + }, + ); + + template_params.insert(Rc::from("name"), Rc::from(entry.app_name.as_str())); + + let data = parser_state.parse_template(doc_params, "AppEntry", params.layout, list_parent.id, template_params)?; + data.fetch_component_as::("button") + } + + fn mount_entries( + &mut self, + entries: &[DesktopEntry], + parser_state: &mut ParserState, + doc_params: &ParseDocumentParams, + params: &mut TabParams, + list_parent: &WidgetPair, + on_button: impl Fn(Rc, &DesktopEntry), + ) -> anyhow::Result<()> { + for entry in entries { + let button = self.mount_entry(parser_state, doc_params, params, list_parent, entry)?; + on_button(button, entry); + } + Ok(()) + } +} diff --git a/dash-frontend/src/tab/games.rs b/dash-frontend/src/tab/games.rs new file mode 100644 index 0000000..1a304c7 --- /dev/null +++ b/dash-frontend/src/tab/games.rs @@ -0,0 +1,33 @@ +use wgui::{ + assets::AssetPath, + parser::{ParseDocumentParams, ParserState}, +}; + +use crate::tab::{Tab, TabParams, TabType}; + +pub struct TabGames { + #[allow(dead_code)] + pub state: ParserState, +} + +impl Tab for TabGames { + fn get_type(&self) -> TabType { + TabType::Games + } +} + +impl TabGames { + pub fn new(params: TabParams) -> anyhow::Result { + let state = wgui::parser::parse_from_assets( + &ParseDocumentParams { + globals: params.globals.clone(), + path: AssetPath::BuiltIn("gui/tab/games.xml"), + extra: Default::default(), + }, + params.layout, + params.parent_id, + )?; + + Ok(Self { state }) + } +} diff --git a/dash-frontend/src/tab/home.rs b/dash-frontend/src/tab/home.rs new file mode 100644 index 0000000..ffb4084 --- /dev/null +++ b/dash-frontend/src/tab/home.rs @@ -0,0 +1,82 @@ +use wgui::{ + assets::AssetPath, + components::button::ComponentButton, + event::CallbackDataCommon, + i18n::Translation, + layout::Widget, + parser::{Fetchable, ParseDocumentParams, ParserState}, + widget::label::WidgetLabel, +}; + +use crate::{ + frontend::{Frontend, FrontendTask}, + settings, + tab::{Tab, TabParams, TabType}, + various, +}; + +pub struct TabHome { + #[allow(dead_code)] + pub state: ParserState, +} + +impl Tab for TabHome { + fn get_type(&self) -> TabType { + TabType::Home + } +} + +fn configure_label_hello(common: &mut CallbackDataCommon, label_hello: Widget, settings: &settings::Settings) { + let mut username = various::get_username(); + // first character as uppercase + if let Some(first) = username.chars().next() { + let first = first.to_uppercase().to_string(); + username.replace_range(0..1, &first); + } + + let translated = if !settings.home_screen.hide_username { + common.i18n().translate_and_replace("HELLO_USER", ("{USER}", &username)) + } else { + common.i18n().translate("HELLO").to_string() + }; + + let mut label_hello = label_hello.get_as_mut::().unwrap(); + label_hello.set_text(common, Translation::from_raw_text(&translated)); +} + +impl TabHome { + pub fn new(params: TabParams) -> anyhow::Result { + let state = wgui::parser::parse_from_assets( + &ParseDocumentParams { + globals: params.globals.clone(), + path: AssetPath::BuiltIn("gui/tab/home.xml"), + extra: Default::default(), + }, + params.layout, + params.parent_id, + )?; + + let mut c = params.layout.start_common(); + let widget_label = state.fetch_widget(&c.layout.state, "label_hello")?.widget; + configure_label_hello(&mut c.common(), widget_label, params.settings); + + let btn_apps = state.fetch_component_as::("btn_apps")?; + let btn_games = state.fetch_component_as::("btn_games")?; + let btn_monado = state.fetch_component_as::("btn_monado")?; + let btn_processes = state.fetch_component_as::("btn_processes")?; + let btn_settings = state.fetch_component_as::("btn_settings")?; + + let frontend = params.frontend; + Frontend::register_button_task(frontend.clone(), &btn_apps, FrontendTask::SetTab(TabType::Apps)); + Frontend::register_button_task(frontend.clone(), &btn_games, FrontendTask::SetTab(TabType::Games)); + Frontend::register_button_task(frontend.clone(), &btn_monado, FrontendTask::SetTab(TabType::Monado)); + Frontend::register_button_task( + frontend.clone(), + &btn_processes, + FrontendTask::SetTab(TabType::Processes), + ); + Frontend::register_button_task(frontend.clone(), &btn_settings, FrontendTask::SetTab(TabType::Settings)); + + Ok(Self { state }) + } +} diff --git a/dash-frontend/src/tab/mod.rs b/dash-frontend/src/tab/mod.rs new file mode 100644 index 0000000..15a2f75 --- /dev/null +++ b/dash-frontend/src/tab/mod.rs @@ -0,0 +1,36 @@ +use wgui::{ + globals::WguiGlobals, + layout::{Layout, WidgetID}, +}; + +use crate::frontend::RcFrontend; + +pub mod apps; +pub mod games; +pub mod home; +pub mod monado; +pub mod processes; +pub mod settings; + +#[derive(Clone, Copy, Debug)] +pub enum TabType { + Home, + Apps, + Games, + Monado, + Processes, + Settings, +} + +pub struct TabParams<'a> { + pub globals: &'a WguiGlobals, + pub layout: &'a mut Layout, + pub parent_id: WidgetID, + pub frontend: &'a RcFrontend, + pub settings: &'a mut crate::settings::Settings, +} + +pub trait Tab { + #[allow(dead_code)] + fn get_type(&self) -> TabType; +} diff --git a/dash-frontend/src/tab/monado.rs b/dash-frontend/src/tab/monado.rs new file mode 100644 index 0000000..4130ac7 --- /dev/null +++ b/dash-frontend/src/tab/monado.rs @@ -0,0 +1,33 @@ +use wgui::{ + assets::AssetPath, + parser::{ParseDocumentParams, ParserState}, +}; + +use crate::tab::{Tab, TabParams, TabType}; + +pub struct TabMonado { + #[allow(dead_code)] + pub state: ParserState, +} + +impl Tab for TabMonado { + fn get_type(&self) -> TabType { + TabType::Games + } +} + +impl TabMonado { + pub fn new(params: TabParams) -> anyhow::Result { + let state = wgui::parser::parse_from_assets( + &ParseDocumentParams { + globals: params.globals.clone(), + path: AssetPath::BuiltIn("gui/tab/monado.xml"), + extra: Default::default(), + }, + params.layout, + params.parent_id, + )?; + + Ok(Self { state }) + } +} diff --git a/dash-frontend/src/tab/processes.rs b/dash-frontend/src/tab/processes.rs new file mode 100644 index 0000000..a19bf28 --- /dev/null +++ b/dash-frontend/src/tab/processes.rs @@ -0,0 +1,33 @@ +use wgui::{ + assets::AssetPath, + parser::{ParseDocumentParams, ParserState}, +}; + +use crate::tab::{Tab, TabParams, TabType}; + +pub struct TabProcesses { + #[allow(dead_code)] + pub state: ParserState, +} + +impl Tab for TabProcesses { + fn get_type(&self) -> TabType { + TabType::Games + } +} + +impl TabProcesses { + pub fn new(params: TabParams) -> anyhow::Result { + let state = wgui::parser::parse_from_assets( + &ParseDocumentParams { + globals: params.globals.clone(), + path: AssetPath::BuiltIn("gui/tab/processes.xml"), + extra: Default::default(), + }, + params.layout, + params.parent_id, + )?; + + Ok(Self { state }) + } +} diff --git a/dash-frontend/src/tab/settings.rs b/dash-frontend/src/tab/settings.rs new file mode 100644 index 0000000..3189e24 --- /dev/null +++ b/dash-frontend/src/tab/settings.rs @@ -0,0 +1,103 @@ +use std::rc::Rc; + +use wgui::{ + assets::AssetPath, + components::checkbox::ComponentCheckbox, + parser::{Fetchable, ParseDocumentParams, ParserState}, +}; + +use crate::{ + frontend::{Frontend, FrontendTask}, + settings, + tab::{Tab, TabParams, TabType}, +}; + +pub struct TabSettings { + #[allow(dead_code)] + pub state: ParserState, +} + +impl Tab for TabSettings { + fn get_type(&self) -> TabType { + TabType::Settings + } +} + +fn init_setting_checkbox( + params: &mut TabParams, + checkbox: Rc, + fetch_callback: fn(&mut settings::Settings) -> &mut bool, + change_callback: Option, +) -> anyhow::Result<()> { + let mut c = params.layout.start_common(); + + checkbox.set_checked(&mut c.common(), *fetch_callback(params.settings)); + let rc_frontend = params.frontend.clone(); + checkbox.on_toggle(Box::new(move |_common, e| { + let mut frontend = rc_frontend.borrow_mut(); + *fetch_callback(frontend.settings.get_mut()) = e.checked; + + if let Some(change_callback) = &change_callback { + change_callback(&mut frontend, e.checked); + } + + frontend.settings.mark_as_dirty(); + + Ok(()) + })); + + c.finish()?; + Ok(()) +} + +impl TabSettings { + pub fn new(mut params: TabParams) -> anyhow::Result { + let state = wgui::parser::parse_from_assets( + &ParseDocumentParams { + globals: params.globals.clone(), + path: AssetPath::BuiltIn("gui/tab/settings.xml"), + extra: Default::default(), + }, + params.layout, + params.parent_id, + )?; + + init_setting_checkbox( + &mut params, + state.data.fetch_component_as::("cb_hide_username")?, + |settings| &mut settings.home_screen.hide_username, + None, + )?; + + init_setting_checkbox( + &mut params, + state.data.fetch_component_as::("cb_am_pm_clock")?, + |settings| &mut settings.general.am_pm_clock, + Some(|frontend, _| { + frontend.tasks.push(FrontendTask::RefreshClock); + }), + )?; + + init_setting_checkbox( + &mut params, + state + .data + .fetch_component_as::("cb_opaque_background")?, + |settings| &mut settings.general.opaque_background, + Some(|frontend, _| { + frontend.tasks.push(FrontendTask::RefreshBackground); + }), + )?; + + init_setting_checkbox( + &mut params, + state + .data + .fetch_component_as::("cb_xwayland_by_default")?, + |settings| &mut settings.tweaks.xwayland_by_default, + None, + )?; + + Ok(Self { state }) + } +} diff --git a/dash-frontend/src/task.rs b/dash-frontend/src/task.rs new file mode 100644 index 0000000..f6af456 --- /dev/null +++ b/dash-frontend/src/task.rs @@ -0,0 +1,27 @@ +use std::{cell::RefCell, collections::VecDeque, rc::Rc}; + +#[derive(Clone)] +pub struct Tasks(Rc>>) +where + TaskType: Clone; + +impl Tasks { + pub fn new() -> Self { + Self(Rc::new(RefCell::new(VecDeque::new()))) + } + + pub fn push(&self, task: TaskType) { + self.0.borrow_mut().push_back(task); + } + + pub fn drain(&mut self) -> VecDeque { + let mut tasks = self.0.borrow_mut(); + std::mem::take(&mut *tasks) + } +} + +impl Default for Tasks { + fn default() -> Self { + Self::new() + } +} diff --git a/dash-frontend/src/util/desktop_finder.rs b/dash-frontend/src/util/desktop_finder.rs new file mode 100644 index 0000000..8f0b6b5 --- /dev/null +++ b/dash-frontend/src/util/desktop_finder.rs @@ -0,0 +1,131 @@ +use gio::prelude::{AppInfoExt, IconExt}; +use gtk::traits::IconThemeExt; + +#[derive(Debug, Clone)] +#[allow(dead_code)] // TODO: remove this +pub struct DesktopEntry { + pub exec_path: String, + pub exec_args: Vec, + pub app_name: String, + pub icon_path: Option, + pub categories: Vec, +} + +#[allow(dead_code)] // TODO: remove this +pub struct EntrySearchCell { + pub exec_path: String, + pub exec_args: Vec, + pub app_name: String, + pub icon_name: Option, + pub categories: Vec, +} + +const CMD_BLACKLIST: [&str; 1] = [ + "lsp-plugins", // LSP Plugins collection. They clutter the application list a lot +]; + +const CATEGORY_TYPE_BLACKLIST: [&str; 5] = ["GTK", "Qt", "X-XFCE", "X-Bluetooth", "ConsoleOnly"]; + +pub fn find_entries() -> anyhow::Result> { + let Some(icon_theme) = gtk::IconTheme::default() else { + anyhow::bail!("Failed to get current icon theme information"); + }; + + let mut res = Vec::::new(); + + let info = gio::AppInfo::all(); + + log::debug!("app entry count {}", info.len()); + + 'outer: for app_entry in info { + let Some(app_entry_id) = app_entry.id() else { + log::warn!( + "failed to get desktop entry ID for application named \"{}\"", + app_entry.name() + ); + continue; + }; + + let Some(desktop_app) = gio::DesktopAppInfo::new(&app_entry_id) else { + log::warn!( + "failed to find desktop app file from application named \"{}\"", + app_entry.name() + ); + continue; + }; + + if desktop_app.is_nodisplay() || desktop_app.is_hidden() { + continue; + } + + let Some(cmd) = desktop_app.commandline() else { + continue; + }; + + let name = String::from(desktop_app.name()); + + let exec = String::from(cmd.to_string_lossy()); + + for blacklisted in CMD_BLACKLIST { + if exec.contains(blacklisted) { + continue 'outer; + } + } + + let (exec_path, exec_args) = match exec.split_once(" ") { + Some((left, right)) => ( + String::from(left), + right + .split(" ") + .filter(|arg| !arg.starts_with('%')) // exclude arguments like "%f" + .map(String::from) + .collect(), + ), + None => (exec, Vec::new()), + }; + + let icon_path = match desktop_app.icon() { + Some(icon) => { + if let Some(icon_str) = icon.to_string() { + if let Some(s_icon) = icon_theme.lookup_icon(&icon_str, 128, gtk::IconLookupFlags::GENERIC_FALLBACK) { + s_icon.filename().map(|p| String::from(p.to_string_lossy())) + } else { + None + } + } else { + None + } + } + None => None, + }; + + let categories: Vec = match desktop_app.categories() { + Some(categories) => categories + .split(";") + .filter(|s| !s.is_empty()) + .filter(|s| { + for b in CATEGORY_TYPE_BLACKLIST { + if *s == b { + return false; + } + } + true + }) + .map(String::from) + .collect(), + None => Vec::new(), + }; + + let entry = DesktopEntry { + app_name: name, + categories, + exec_path, + exec_args, + icon_path, + }; + + res.push(entry); + } + + Ok(res) +} diff --git a/dash-frontend/src/util/mod.rs b/dash-frontend/src/util/mod.rs new file mode 100644 index 0000000..1331ba1 --- /dev/null +++ b/dash-frontend/src/util/mod.rs @@ -0,0 +1,4 @@ +pub mod desktop_finder; +pub mod pactl_wrapper; +pub mod popup_manager; +pub mod toast_manager; diff --git a/dash-frontend/src/util/pactl_wrapper.rs b/dash-frontend/src/util/pactl_wrapper.rs new file mode 100644 index 0000000..6fe9f2c --- /dev/null +++ b/dash-frontend/src/util/pactl_wrapper.rs @@ -0,0 +1,312 @@ +use std::collections::{BTreeMap, HashMap}; + +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct VolumeChannel { + pub value: u32, // 48231 + pub value_percent: String, // "80%" + pub db: String, // "-5.81 dB" +} + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct Volume { + // WiVRn and other devices + pub aux0: Option, + pub aux1: Option, + + // Analog and HDMI devices + #[serde(rename = "front-left")] + pub front_left: Option, + + #[serde(rename = "front-right")] + pub front_right: Option, +} + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct Sink { + pub index: u32, // 123 + pub state: String, // "RUNNING" / "SUSPENDED" + pub name: String, // alsa_output.pci-0000_0c_00.4.analog-stereo + pub description: String, // Starship/Matisse HD Audio Controller Analog Stereo + pub mute: bool, // false + pub volume: Volume, + pub properties: HashMap, +} + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct SourceProperties { + #[serde(rename = "device.name")] + pub device_name: Option, // "alsa_card.pci-0000_0b_00.1" + #[serde(rename = "device.class")] + pub device_class: Option, // "monitor", "sound" + #[serde(rename = "alsa.card_name")] + pub card_name: Option, // "Valve VR Radio & HMD Mic" + #[serde(rename = "alsa.components")] + pub components: Option, // USB28de:2102 + #[serde(rename = "device.vendor_name")] + pub vendor_name: Option, // Valve Software +} + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct Source { + pub index: u32, // 123 + pub state: String, // "RUNNING" / "SUSPENDED" + pub name: String, // alsa_input.pci-0000_0c_00.4.analog-stereo + pub description: String, // Valve VR Radio & HMD Mic Mono + pub mute: bool, // false + pub volume: Volume, + pub properties: SourceProperties, +} + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct CardProperties { + #[serde(rename = "device.description")] + pub device_description: String, // Starship/Matisse HD Audio Controller + + #[serde(rename = "device.name")] + pub device_name: String, // alsa_card.pci-0000_0c_00.4 + + #[serde(rename = "device.nick")] + pub device_nick: String, // HD-Audio Generic +} + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct CardProfile { + pub description: String, // "Digital Stereo (HDMI 2) Output", "Analog Stereo Output", + pub sinks: u32, // 1 + pub sources: u32, // 0 + pub priority: u32, // 6500 + pub available: bool, // true +} + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct CardPort { + pub description: String, // "HDMI / DisplayPort 2" + pub r#type: String, // "HDMI" + pub profiles: Vec, // "output:hdmi-stereo-extra1", "output:hdmi-surround-extra1", "output:analog-stereo", "output:analog-stereo+input:analog-stereo" + + // example: + // "port.type": "hdmi" + // "device.product_name": "Index HMD" + pub properties: HashMap, +} + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct Card { + pub index: u32, // 57 + pub name: String, // alsa_card.pci-0000_0c_00.4 + pub active_profile: String, // output:analog-stereo + pub properties: CardProperties, + pub profiles: BTreeMap, // key: "output:analog-stereo" + pub ports: BTreeMap, // key: "analog-output-lineout" +} + +// ######################################## +// ~ sinks ~ +// ######################################## + +pub fn list_sinks() -> anyhow::Result> { + let output = std::process::Command::new("pactl") + .arg("--format=json") + .arg("list") + .arg("sinks") + .output()?; + + if !output.status.success() { + anyhow::bail!("pactl exit status {}", output.status); + } + + let json_str = std::str::from_utf8(&output.stdout)?; + let sinks: Vec = serde_json::from_str(json_str)?; + Ok(sinks) +} + +pub fn get_default_sink(sinks: &[Sink]) -> anyhow::Result> { + let output = std::process::Command::new("pactl").arg("get-default-sink").output()?; + + let utf8_name = std::str::from_utf8(&output.stdout)?.trim(); + + for sink in sinks { + if sink.name == utf8_name { + return Ok(Some(sink.clone())); + } + } + + Ok(None) +} + +pub fn set_default_sink(sink_index: u32) -> anyhow::Result<()> { + std::process::Command::new("pactl") + .arg("set-default-sink") + .arg(format!("{}", sink_index)) + .output()?; + + Ok(()) +} + +pub fn get_sink_volume(sink: &Sink) -> anyhow::Result { + let volume_channel = { + if let Some(front_left) = &sink.volume.front_left { + front_left + } else if let Some(aux0) = &sink.volume.aux0 { + aux0 + } else { + return Ok(0.0); // fail silently + } + }; + + let Some(pair) = volume_channel.value_percent.split_once("%") else { + anyhow::bail!("volume percentage invalid"); // shouldn't happen + }; + + let percent_num: f32 = pair.0.parse().unwrap_or(0.0); + Ok(percent_num / 100.0) +} + +pub fn set_sink_volume(sink_index: u32, volume: f32) -> anyhow::Result<()> { + let target_vol = (volume * 100.0).clamp(0.0, 150.0); // limit to 150% + + std::process::Command::new("pactl") + .arg("set-sink-volume") + .arg(format!("{}", sink_index)) + .arg(format!("{}%", target_vol)) + .output()?; + + Ok(()) +} + +pub fn set_sink_mute(sink_index: u32, mute: bool) -> anyhow::Result<()> { + std::process::Command::new("pactl") + .arg("set-sink-mute") + .arg(format!("{}", sink_index)) + .arg(format!("{}", mute as i32)) + .output()?; + + Ok(()) +} + +// ######################################## +// ~ sources ~ +// ######################################## + +pub fn list_sources() -> anyhow::Result> { + let output = std::process::Command::new("pactl") + .arg("--format=json") + .arg("list") + .arg("sources") + .output()?; + + if !output.status.success() { + anyhow::bail!("pactl exit status {}", output.status); + } + + let json_str = std::str::from_utf8(&output.stdout)?; + let mut sources: Vec = serde_json::from_str(json_str)?; + + // exclude all monitor sources + sources.retain(|source| match &source.properties.device_class { + Some(c) => c != "monitor", + None => false, + }); + + Ok(sources) +} + +pub fn get_default_source(sources: &[Source]) -> anyhow::Result> { + let output = std::process::Command::new("pactl").arg("get-default-source").output()?; + + let utf8_name = std::str::from_utf8(&output.stdout)?.trim(); + + for source in sources { + if source.name == utf8_name { + return Ok(Some(source.clone())); + } + } + + Ok(None) +} + +pub fn set_default_source(source_index: u32) -> anyhow::Result<()> { + std::process::Command::new("pactl") + .arg("set-default-source") + .arg(format!("{}", source_index)) + .output()?; + + Ok(()) +} + +pub fn get_source_volume(source: &Source) -> anyhow::Result { + let volume_channel = { + if let Some(front_left) = &source.volume.front_left { + front_left + } else if let Some(aux0) = &source.volume.aux0 { + aux0 + } else { + return Ok(0.0); // fail silently + } + }; + + let Some(pair) = volume_channel.value_percent.split_once("%") else { + anyhow::bail!("volume percentage invalid"); // shouldn't happen + }; + + let percent_num: f32 = pair.0.parse().unwrap_or(0.0); + Ok(percent_num / 100.0) +} + +pub fn set_source_volume(source_index: u32, volume: f32) -> anyhow::Result<()> { + let target_vol = (volume * 100.0).clamp(0.0, 150.0); // limit to 150% + + std::process::Command::new("pactl") + .arg("set-source-volume") + .arg(format!("{}", source_index)) + .arg(format!("{}%", target_vol)) + .output()?; + + Ok(()) +} + +pub fn set_source_mute(source_index: u32, mute: bool) -> anyhow::Result<()> { + std::process::Command::new("pactl") + .arg("set-source-mute") + .arg(format!("{}", source_index)) + .arg(format!("{}", mute as i32)) + .output()?; + + Ok(()) +} + +// ######################################## +// ~ cards ~ +// ######################################## + +pub fn list_cards() -> anyhow::Result> { + let output = std::process::Command::new("pactl") + .arg("--format=json") + .arg("list") + .arg("cards") + .output()?; + + if !output.status.success() { + anyhow::bail!("pactl exit status {}", output.status); + } + + let json_str = std::str::from_utf8(&output.stdout)?; + let mut cards: Vec = serde_json::from_str(json_str)?; + + // exclude card which has "Loopback" in name + cards.retain(|card| card.properties.device_nick != "Loopback"); + + Ok(cards) +} + +pub fn set_card_profile(card_index: u32, profile: &str) -> anyhow::Result<()> { + std::process::Command::new("pactl") + .arg("set-card-profile") + .arg(format!("{}", card_index)) + .arg(profile) + .output()?; + + Ok(()) +} diff --git a/dash-frontend/src/util/popup_manager.rs b/dash-frontend/src/util/popup_manager.rs new file mode 100644 index 0000000..5c4e665 --- /dev/null +++ b/dash-frontend/src/util/popup_manager.rs @@ -0,0 +1,182 @@ +use std::{ + cell::RefCell, + rc::{Rc, Weak}, +}; + +use wgui::{ + assets::AssetPath, + components::button::ComponentButton, + event::{EventAlterables, StyleSetRequest}, + globals::WguiGlobals, + i18n::Translation, + layout::{Layout, LayoutTask, LayoutTasks, WidgetID}, + parser::{Fetchable, ParseDocumentParams, ParserState}, + taffy::Display, + widget::label::WidgetLabel, +}; + +use crate::frontend::{FrontendTask, FrontendTasks}; + +pub struct PopupManagerParams { + pub parent_id: WidgetID, +} + +struct State { + popup_stack: Vec>>, +} + +pub struct MountedPopup { + #[allow(dead_code)] + state: ParserState, + id_root: WidgetID, // decorations of a popup + layout_tasks: LayoutTasks, + frontend_tasks: FrontendTasks, +} + +struct MountedPopupState { + mounted_popup: Option, +} + +#[derive(Clone)] +pub struct PopupHandle { + state: Rc>, +} + +impl PopupHandle { + pub fn close(&self) { + self.state.borrow_mut().mounted_popup = None; // Drop will be called + } +} + +pub struct PopupManager { + state: Rc>, + parent_id: WidgetID, +} + +pub struct PopupContentFuncData<'a> { + pub layout: &'a mut Layout, + pub handle: PopupHandle, + pub id_content: WidgetID, +} + +#[derive(Clone)] +pub struct MountPopupParams { + pub title: Translation, + pub on_content: Rc anyhow::Result<()>>, +} + +impl Drop for MountedPopup { + fn drop(&mut self) { + self.layout_tasks.push(LayoutTask::RemoveWidget(self.id_root)); + self.frontend_tasks.push(FrontendTask::RefreshPopupManager); + } +} + +impl State { + fn refresh_stack(&mut self, alterables: &mut EventAlterables) { + // show only the topmost popup + self.popup_stack.retain(|weak| { + let Some(popup) = weak.upgrade() else { + return false; + }; + popup.borrow_mut().mounted_popup.is_some() + }); + + for (idx, popup) in self.popup_stack.iter().enumerate() { + let popup = popup.upgrade().unwrap(); // safe + let popup = popup.borrow_mut(); + let mounted_popup = popup.mounted_popup.as_ref().unwrap(); // safe; + + alterables.set_style( + mounted_popup.id_root, + StyleSetRequest::Display(if idx == self.popup_stack.len() - 1 { + Display::Flex + } else { + Display::None + }), + ); + } + } +} + +impl PopupManager { + pub fn new(params: PopupManagerParams) -> Self { + Self { + parent_id: params.parent_id, + state: Rc::new(RefCell::new(State { + popup_stack: Vec::new(), + })), + } + } + + pub fn refresh(&self, alterables: &mut EventAlterables) { + let mut state = self.state.borrow_mut(); + state.refresh_stack(alterables); + } + + /// Mount a new popup on top of the existing popup stack. + /// Only the topmost popup is visible. + pub fn mount_popup( + &mut self, + globals: WguiGlobals, + layout: &mut Layout, + frontend_tasks: FrontendTasks, + params: MountPopupParams, + ) -> anyhow::Result<()> { + let doc_params = &ParseDocumentParams { + globals: globals.clone(), + path: AssetPath::BuiltIn("gui/view/popup_window.xml"), + extra: Default::default(), + }; + let state = wgui::parser::parse_from_assets(doc_params, layout, self.parent_id)?; + + let id_root = state.get_widget_id("root")?; + let id_content = state.get_widget_id("content")?; + + { + let mut label_title = state.fetch_widget_as::(&layout.state, "popup_title")?; + label_title.set_text_simple(&mut globals.get(), params.title); + } + + let but_back = state.fetch_component_as::("but_back")?; + + let mounted_popup = MountedPopup { + state, + id_root, + layout_tasks: layout.tasks.clone(), + frontend_tasks: frontend_tasks.clone(), + }; + + let mounted_popup_state = MountedPopupState { + mounted_popup: Some(mounted_popup), + }; + + let popup_handle = PopupHandle { + state: Rc::new(RefCell::new(mounted_popup_state)), + }; + + let mut state = self.state.borrow_mut(); + state.popup_stack.push(Rc::downgrade(&popup_handle.state)); + + but_back.on_click({ + let popup_handle = Rc::downgrade(&popup_handle.state); + Box::new(move |_common, _evt| { + if let Some(popup_handle) = popup_handle.upgrade() { + popup_handle.borrow_mut().mounted_popup = None; // will call Drop + } + Ok(()) + }) + }); + + frontend_tasks.push(FrontendTask::RefreshPopupManager); + + // mount user-set popup content + (*params.on_content)(PopupContentFuncData { + layout, + handle: popup_handle.clone(), + id_content, + })?; + + Ok(()) + } +} diff --git a/dash-frontend/src/util/toast_manager.rs b/dash-frontend/src/util/toast_manager.rs new file mode 100644 index 0000000..d6eb3bd --- /dev/null +++ b/dash-frontend/src/util/toast_manager.rs @@ -0,0 +1,190 @@ +use std::{cell::RefCell, collections::VecDeque, rc::Rc}; + +use glam::{Mat4, Vec3}; +use wgui::{ + animation::{Animation, AnimationEasing}, + components::tooltip::{TOOLTIP_BORDER_COLOR, TOOLTIP_COLOR}, + drawing::Color, + globals::WguiGlobals, + i18n::Translation, + layout::{Layout, LayoutTask, LayoutTasks, WidgetID}, + renderer_vk::{ + text::{FontWeight, TextStyle}, + util::centered_matrix, + }, + taffy::{ + self, + prelude::{length, percent}, + }, + widget::{ + div::WidgetDiv, + label::{WidgetLabel, WidgetLabelParams}, + rectangle::{WidgetRectangle, WidgetRectangleParams}, + util::WLength, + }, +}; + +struct MountedToast { + #[allow(dead_code)] + id_root: WidgetID, // decorations of a toast + layout_tasks: LayoutTasks, +} + +struct State { + toast: Option, + queue: VecDeque, + timeout: u32, // in ticks +} + +pub struct ToastManager { + state: Rc>, + needs_tick: bool, +} + +impl Drop for MountedToast { + fn drop(&mut self) { + self.layout_tasks.push(LayoutTask::RemoveWidget(self.id_root)); + } +} + +const TOAST_DURATION_TICKS: u32 = 90; + +impl ToastManager { + pub fn new() -> Self { + Self { + state: Rc::new(RefCell::new(State { + toast: None, + timeout: 0, + queue: VecDeque::new(), + })), + needs_tick: false, + } + } + + fn mount_toast( + &self, + globals: &WguiGlobals, + layout: &mut Layout, + state: &mut State, + content: Translation, + ) -> anyhow::Result<()> { + let mut globals = globals.get(); + + let (root, _) = layout.add_topmost_child( + WidgetDiv::create(), + taffy::Style { + position: taffy::Position::Absolute, + size: taffy::Size { + width: percent(1.0), + height: percent(0.8), + }, + align_items: Some(taffy::AlignItems::End), + justify_content: Some(taffy::JustifyContent::Center), + ..Default::default() + }, + )?; + + let (rect, _) = layout.add_child( + root.id, + WidgetRectangle::create(WidgetRectangleParams { + color: TOOLTIP_COLOR, + border_color: TOOLTIP_BORDER_COLOR, + border: 2.0, + round: WLength::Percent(1.0), + ..Default::default() + }), + taffy::Style { + position: taffy::Position::Relative, + gap: length(4.0), + padding: taffy::Rect { + left: length(16.0), + right: length(16.0), + top: length(8.0), + bottom: length(8.0), + }, + ..Default::default() + }, + )?; + + let (label, _) = layout.add_child( + rect.id, + WidgetLabel::create( + &mut globals, + WidgetLabelParams { + content, + style: TextStyle { + weight: Some(FontWeight::Bold), + ..Default::default() + }, + }, + ), + taffy::Style { ..Default::default() }, + )?; + + // show-up animation + layout.animations.add(Animation::new( + rect.id, + 160, + AnimationEasing::Linear, + Box::new(move |common, data| { + let pos_showup = AnimationEasing::OutQuint.interpolate((data.pos * 4.0).min(1.0)); + let opacity = 1.0 - AnimationEasing::OutQuint.interpolate(((data.pos - 0.75) * 4.0).clamp(0.0, 1.0)); + let scale = AnimationEasing::OutBack.interpolate((data.pos * 4.0).min(1.0)); + + { + let mtx = Mat4::from_translation(Vec3::new(0.0, (1.0 - pos_showup) * 100.0, 0.0)) + * Mat4::from_scale(Vec3::new(scale, scale, 1.0)); + data.data.transform = centered_matrix(data.widget_boundary.size, &mtx); + } + + let rect = data.obj.get_as_mut::().unwrap(); + rect.params.color.a = opacity; + rect.params.border_color.a = opacity; + + let mut label = common.state.widgets.get_as::(label.id).unwrap(); + label.set_color(common, Color::new(1.0, 1.0, 1.0, opacity), true); + common.alterables.mark_redraw(); + }), + )); + + state.toast = Some(MountedToast { + id_root: root.id, + layout_tasks: layout.tasks.clone(), + }); + + Ok(()) + } + + pub fn tick(&mut self, globals: &WguiGlobals, layout: &mut Layout) -> anyhow::Result<()> { + if !self.needs_tick { + return Ok(()); + } + + let mut state = self.state.borrow_mut(); + + if state.timeout > 0 { + state.timeout -= 1; + } + + if state.timeout == 0 { + state.toast = None; + state.timeout = TOAST_DURATION_TICKS; + // mount next + if let Some(content) = state.queue.pop_front() { + self.mount_toast(globals, layout, &mut state, content)?; + } + } + + if state.queue.is_empty() && state.toast.is_none() { + self.needs_tick = false; + } + + Ok(()) + } + + pub fn push(&mut self, content: Translation) { + let mut state = self.state.borrow_mut(); + state.queue.push_back(content); + self.needs_tick = true; + } +} diff --git a/dash-frontend/src/various.rs b/dash-frontend/src/various.rs new file mode 100644 index 0000000..7f48cee --- /dev/null +++ b/dash-frontend/src/various.rs @@ -0,0 +1,6 @@ +pub fn get_username() -> String { + match std::env::var("USER") { + Ok(user) => user, + Err(_) => String::from("anonymous"), + } +} diff --git a/dash-frontend/src/views/app_launcher.rs b/dash-frontend/src/views/app_launcher.rs new file mode 100644 index 0000000..f8a2ed9 --- /dev/null +++ b/dash-frontend/src/views/app_launcher.rs @@ -0,0 +1,63 @@ +use std::{collections::HashMap, rc::Rc}; + +use wgui::{ + assets::AssetPath, + globals::WguiGlobals, + i18n::Translation, + layout::{Layout, WidgetID}, + parser::{Fetchable, ParseDocumentParams, ParserState}, + widget::label::WidgetLabel, +}; + +use crate::util::desktop_finder::DesktopEntry; + +pub struct View { + #[allow(dead_code)] + pub state: ParserState, + //entry: DesktopEntry, +} + +pub struct Params<'a> { + pub globals: WguiGlobals, + pub entry: DesktopEntry, + pub layout: &'a mut Layout, + pub parent_id: WidgetID, +} + +impl View { + pub fn new(params: Params) -> anyhow::Result { + let doc_params = &ParseDocumentParams { + globals: params.globals.clone(), + path: AssetPath::BuiltIn("gui/view/app_launcher.xml"), + extra: Default::default(), + }; + + let mut state = wgui::parser::parse_from_assets(doc_params, params.layout, params.parent_id)?; + let id_icon_parent = state.get_widget_id("icon_parent")?; + + // app icon + if let Some(icon_path) = ¶ms.entry.icon_path { + let mut template_params: HashMap, Rc> = HashMap::new(); + template_params.insert("path".into(), icon_path.as_str().into()); + state.instantiate_template( + doc_params, + "ApplicationIcon", + params.layout, + id_icon_parent, + template_params, + )?; + } + + let mut label_title = state.fetch_widget_as::(¶ms.layout.state, "label_title")?; + + label_title.set_text_simple( + &mut params.globals.get(), + Translation::from_raw_text(¶ms.entry.app_name), + ); + + Ok(Self { + //entry: params.entry, + state, + }) + } +} diff --git a/dash-frontend/src/views/audio_settings.rs b/dash-frontend/src/views/audio_settings.rs new file mode 100644 index 0000000..b24b29b --- /dev/null +++ b/dash-frontend/src/views/audio_settings.rs @@ -0,0 +1,967 @@ +use std::{collections::HashMap, rc::Rc}; + +use wgui::{ + assets::AssetPath, + components::{ + self, + button::{ButtonClickCallback, ComponentButton}, + checkbox::ComponentCheckbox, + slider::ComponentSlider, + }, + globals::WguiGlobals, + i18n::Translation, + layout::{Layout, WidgetID}, + parser::{Fetchable, ParseDocumentParams, ParserState}, + widget::ConstructEssentials, +}; + +use crate::{ + frontend::{FrontendTask, FrontendTasks}, + task::Tasks, + util::pactl_wrapper, +}; + +#[derive(Clone)] +#[allow(clippy::large_enum_variant)] +enum CurrentMode { + Sinks, + Sources, + Cards, + CardProfileSelector(pactl_wrapper::Card), +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum SearchType { + Sink, + #[allow(dead_code)] + Source, // might be useful in the future +} + +#[derive(Clone)] +struct IndexAndVolume { + idx: u32, + volume: f32, +} + +#[derive(Clone)] +struct CardAndProfileName { + card: pactl_wrapper::Card, + profile_name: String, +} + +#[derive(Clone)] +#[allow(clippy::large_enum_variant)] +enum ViewTask { + Remount, + SetMode(CurrentMode), + AutoSwitch, + SetSinkVolume(IndexAndVolume), + SetSourceVolume(IndexAndVolume), + SetCardProfile(CardAndProfileName), +} + +type ViewTasks = Tasks; + +pub struct View { + tasks: ViewTasks, + frontend_tasks: FrontendTasks, // used only for toasts + on_update: Rc, + + globals: WguiGlobals, + + #[allow(dead_code)] + state: ParserState, + + //entry: DesktopEntry, + mode: CurrentMode, + + id_devices: WidgetID, + + btn_sinks: Rc, + btn_sources: Rc, + btn_cards: Rc, +} + +pub struct Params<'a> { + pub globals: WguiGlobals, + pub frontend_tasks: FrontendTasks, + pub layout: &'a mut Layout, + pub parent_id: WidgetID, + pub on_update: Rc, +} + +struct ProfileDisplayName { + name: String, + icon_path: &'static str, + is_vr: bool, +} + +struct SelectorCell { + key: String, + display_text: String, + icon_path: &'static str, +} + +struct MultiSelectorParams<'a> { + cells: &'a [SelectorCell], + def_cell: &'a str, + ess: &'a mut ConstructEssentials<'a>, + on_click: Rc, +} + +fn mount_multi_selector(params: MultiSelectorParams) -> anyhow::Result<()> { + let globals = params.ess.layout.state.globals.clone(); + let accent_color = globals.get().defaults.accent_color; + + for cell in params.cells { + let highlighted = cell.key == params.def_cell; + let color = if highlighted { Some(accent_color) } else { None }; + + // button + let (_, button) = components::button::construct( + params.ess, + components::button::Params { + text: Some(Translation::from_raw_text(&cell.display_text)), + sprite_src: Some(AssetPath::BuiltIn(cell.icon_path)), + color, + ..Default::default() + }, + )?; + + button.on_click({ + let on_click = params.on_click.clone(); + let key = cell.key.clone(); + Box::new(move |_, _| { + (*on_click)(key.as_str()); + Ok(()) + }) + }); + } + + Ok(()) +} + +fn get_card_from_sink<'a>( + sink: &pactl_wrapper::Sink, + cards: &'a [pactl_wrapper::Card], +) -> Option<&'a pactl_wrapper::Card> { + let Some(sink_dev_name) = &sink.properties.get("device.name") else { + return None; + }; + + cards.iter().find(|&card| **sink_dev_name == card.name).map(|v| v as _) +} + +fn get_card_from_source<'a>( + source: &pactl_wrapper::Source, + cards: &'a [pactl_wrapper::Card], +) -> Option<&'a pactl_wrapper::Card> { + let Some(source_dev_name) = &source.properties.device_name else { + return None; + }; + + cards + .iter() + .find(|&card| **source_dev_name == card.name) + .map(|v| v as _) +} + +fn does_string_mention_hmd_sink(input: &str) -> bool { + let lwr = input.to_lowercase(); + lwr.contains("hmd") || // generic hmd name detected + lwr.contains("index") || // Valve hardware + lwr.contains("oculus") || // Oculus + lwr.contains("rift") || // Also Oculus + lwr.contains("beyond") // Bigscreen Beyond +} + +fn does_string_mention_hmd_source(input: &str) -> bool { + let lwr = input.to_lowercase(); + lwr.contains("hmd") || // generic hmd name detected + lwr.contains("valve") || // Valve hardware + lwr.contains("oculus") || // Oculus + lwr.contains("beyond") // Bigscreen Beyond +} + +fn is_card_mentioning_hmd(card: &pactl_wrapper::Card) -> bool { + does_string_mention_hmd_sink(&card.properties.device_name) +} + +fn is_source_mentioning_hmd(source: &pactl_wrapper::Source) -> bool { + if let Some(source_card_name) = &source.properties.card_name + && does_string_mention_hmd_source(source_card_name) + { + return true; + } + + // WiVRn + if source.name == "wivrn.source" { + return true; + } + + false +} + +fn get_profile_display_name(profile_name: &str, card: &pactl_wrapper::Card) -> ProfileDisplayName { + let Some(profile) = card.profiles.get(profile_name) else { + // fallback + return ProfileDisplayName { + name: profile_name.into(), + icon_path: "dashboard/binary.svg", + is_vr: false, + }; + }; + + let mut out_icon_path: &'static str; + let mut is_vr = false; + + let prof = profile_name.to_lowercase(); + if prof.contains("analog") { + out_icon_path = "dashboard/minijack.svg"; + } else if prof.contains("iec" /* digital */) { + out_icon_path = "dashboard/binary.svg"; + } else if prof.contains("hdmi") { + out_icon_path = "dashboard/displayport.svg"; + } else if prof.contains("off") { + out_icon_path = "dashboard/sleep.svg"; + } else if prof.contains("input") { + out_icon_path = "dashboard/microphone.svg"; + } else { + out_icon_path = "dashboard/volume.svg"; // Default fallback + } + + // All ports are tied to this VR headset, assign all of them to the VR icon + if is_card_mentioning_hmd(card) { + if prof.contains("mic") { + // Probably microphone + out_icon_path = "dashboard/microphone.svg"; + } else { + out_icon_path = "dashboard/vr.svg"; + } + } + + let mut out_name: Option = None; + + for port in card.ports.values() { + // Find profile + for port_profile in &port.profiles { + if !port_profile.contains("stereo") { + continue; // we only want stereo, not surround or other types + } + + if port_profile != profile_name { + continue; + } + + // Exact match! Use its device name + let Some(product_name) = port.properties.get("device.product.name") else { + continue; + }; + + out_name = Some(product_name.clone()); + + if does_string_mention_hmd_sink(product_name) { + // VR icon + out_icon_path = "dashboard/vr.svg"; + is_vr = true; + } else { + // Monitor icon + out_icon_path = "dashboard/displayport.svg"; + } + + break; + } + } + + ProfileDisplayName { + name: if let Some(name) = out_name { + name + } else { + profile.description.clone() + }, + icon_path: out_icon_path, + is_vr, + } +} + +fn doc_params(globals: &WguiGlobals) -> ParseDocumentParams<'_> { + ParseDocumentParams { + globals: globals.clone(), + path: AssetPath::BuiltIn("gui/view/audio_settings.xml"), + extra: Default::default(), + } +} + +trait DeviceControl { + fn on_volume_request(&self) -> anyhow::Result; + fn on_check(&self) -> anyhow::Result<()>; + fn on_mute_toggle(&self) -> anyhow::Result<()>; + fn on_volume_change(&self, volume: f32) -> anyhow::Result<()>; +} + +struct ControlSink { + tasks: ViewTasks, + on_update: Rc, + sink: pactl_wrapper::Sink, +} + +impl ControlSink { + fn new(tasks: ViewTasks, on_update: Rc, sink: pactl_wrapper::Sink) -> Self { + Self { tasks, sink, on_update } + } +} + +impl DeviceControl for ControlSink { + fn on_volume_request(&self) -> anyhow::Result { + let volume = pactl_wrapper::get_sink_volume(&self.sink)?; + Ok(volume) + } + + fn on_check(&self) -> anyhow::Result<()> { + pactl_wrapper::set_default_sink(self.sink.index)?; + self.tasks.push(ViewTask::Remount); + (*self.on_update)(); + Ok(()) + } + + fn on_mute_toggle(&self) -> anyhow::Result<()> { + pactl_wrapper::set_sink_mute(self.sink.index, !self.sink.mute)?; + self.tasks.push(ViewTask::Remount); + (*self.on_update)(); + Ok(()) + } + + fn on_volume_change(&self, volume: f32) -> anyhow::Result<()> { + self.tasks.push(ViewTask::SetSinkVolume(IndexAndVolume { + idx: self.sink.index, + volume, + })); + (*self.on_update)(); + Ok(()) + } +} + +struct ControlSource { + tasks: ViewTasks, + on_update: Rc, + source: pactl_wrapper::Source, +} + +impl ControlSource { + fn new(tasks: ViewTasks, on_update: Rc, source: pactl_wrapper::Source) -> Self { + Self { + tasks, + source, + on_update, + } + } +} + +impl DeviceControl for ControlSource { + fn on_volume_request(&self) -> anyhow::Result { + let volume = pactl_wrapper::get_source_volume(&self.source)?; + Ok(volume) + } + + fn on_check(&self) -> anyhow::Result<()> { + pactl_wrapper::set_default_source(self.source.index)?; + self.tasks.push(ViewTask::Remount); + (*self.on_update)(); + Ok(()) + } + + fn on_mute_toggle(&self) -> anyhow::Result<()> { + pactl_wrapper::set_source_mute(self.source.index, !self.source.mute)?; + self.tasks.push(ViewTask::Remount); + (*self.on_update)(); + Ok(()) + } + + fn on_volume_change(&self, volume: f32) -> anyhow::Result<()> { + self.tasks.push(ViewTask::SetSourceVolume(IndexAndVolume { + idx: self.source.index, + volume, + })); + (*self.on_update)(); + Ok(()) + } +} + +struct MountCardParams<'a> { + layout: &'a mut Layout, + card: &'a pactl_wrapper::Card, +} + +struct MountDeviceSliderParams<'a> { + layout: &'a mut Layout, + control: Rc, + checked: bool, + muted: bool, + disp: Option, + alt_desc: String, +} + +fn switch_sink_card( + frontend_tasks: &FrontendTasks, + card: &pactl_wrapper::Card, + profile_name: &str, + name: &ProfileDisplayName, +) -> anyhow::Result<()> { + let card_index = card.index; + let profile = profile_name.to_string(); + pactl_wrapper::set_card_profile(card_index, &profile)?; + let sinks = pactl_wrapper::list_sinks()?; + + let mut sink_found = false; + for sink in &sinks { + if let Some(device_name) = sink.properties.get("device.name") + && device_name == &card.name + { + pactl_wrapper::set_default_sink(sink.index)?; + sink_found = true; + break; + } + } + + if sink_found { + frontend_tasks.push(FrontendTask::PushToast(Translation::from_translation_key( + format!("[AUDIO.SPEAKERS_SET_SUCCESSFULLY]: {}", name.name).as_str(), + ))); + } else { + frontend_tasks.push(FrontendTask::PushToast(Translation::from_translation_key( + format!("[AUDIO.DEVICE_FOUND_AND_INITIALIZED_BUT_NOT_SWITCHED]: {}", name.name).as_str(), + ))); + } + + Ok(()) +} + +fn switch_source(frontend_tasks: &FrontendTasks, source: &pactl_wrapper::Source) -> anyhow::Result<()> { + match pactl_wrapper::set_default_source(source.index) { + Ok(()) => { + frontend_tasks.push(FrontendTask::PushToast(Translation::from_translation_key( + format!( + "[AUDIO.MICROPHONE_SET_SUCCESSFULLY]: {}", + if let Some(card_name) = &source.properties.card_name { + card_name + } else { + &source.description + } + ) + .as_str(), + ))); + Ok(()) + } + Err(e) => { + Translation::from_translation_key(format!("[AUDIO.FAILED_TO_SWITCH_MICROPHONE]: {:?}", e).as_str()); + Err(e) + } + } +} + +fn switch_to_vr_microphone(frontend_tasks: &FrontendTasks) -> anyhow::Result<()> { + let sources = pactl_wrapper::list_sources()?; + let mut switched = false; + + for source in &sources { + if is_source_mentioning_hmd(source) { + switch_source(frontend_tasks, source)?; + switched = true; + break; + } + } + + if !switched { + frontend_tasks.push(FrontendTask::PushToast(Translation::from_translation_key( + "AUDIO.NO_VR_MICROPHONE_SWITCH_MANUALLY", + ))); + } + + Ok(()) +} + +#[derive(Debug, Clone)] +struct CardPriorityResult<'a> { + priority: u32, + name: String, + card: &'a pactl_wrapper::Card, +} + +fn get_card_best_profile<'a>(card: &'a pactl_wrapper::Card, search_type: SearchType) -> Option> { + let mut best_priority = 0; + let mut best_profile_name = ""; + let mut best_profile: Option<&'a pactl_wrapper::CardProfile> = None; + + for (profile_name, profile) in &card.profiles { + match search_type { + SearchType::Sink if profile.sinks == 0 => continue, + SearchType::Source if profile.sources == 0 => continue, + _ => {} + } + + if profile.priority > best_priority { + best_priority = profile.priority; + best_profile = Some(profile); + best_profile_name = profile_name; + } + } + + best_profile?; // do not proceed if no profile was found + + Some(CardPriorityResult { + priority: best_priority, + name: best_profile_name.to_string(), + card, + }) +} + +fn get_best_profile_from_array<'a>(arr: &[CardPriorityResult<'a>]) -> Option> { + let mut best_priority = 0; + let mut res: Option> = None; + + for cell in arr { + if cell.priority > best_priority { + best_priority = cell.priority; + res = Some(cell.clone()); + } + } + + res +} + +fn switch_to_vr_speakers(frontend_tasks: &FrontendTasks) -> anyhow::Result<()> { + let cards = pactl_wrapper::list_cards()?; + let mut best_profiles = Vec::new(); + + for card in &cards { + if !is_card_mentioning_hmd(card) { + continue; + } + if let Some(best_profile) = get_card_best_profile(card, SearchType::Sink) { + best_profiles.push(best_profile); + } + } + + if !best_profiles.is_empty() { + let best_profile = get_best_profile_from_array(&best_profiles).unwrap(); + let name = get_profile_display_name(&best_profile.name, best_profile.card); + switch_sink_card(frontend_tasks, best_profile.card, &best_profile.name, &name)?; + return Ok(()); + } + + // There aren't any cards which mention VR explicitly. Time for plan B. + for card in &cards { + for profile_name in card.profiles.keys() { + let name = get_profile_display_name(profile_name, card); + if !name.is_vr { + continue; + } + switch_sink_card(frontend_tasks, card, profile_name, &name)?; + return Ok(()); + } + } + + frontend_tasks.push(FrontendTask::PushToast(Translation::from_translation_key( + "AUDIO.NO_VR_SPEAKERS_FOUND_SWITCH_MANUALLY", + ))); + + Ok(()) +} + +const ONE_HUNDRED_PERCENT: f32 = 100.0; +const VOLUME_MULT: f32 = 1.0 / ONE_HUNDRED_PERCENT; + +impl View { + fn handle_func_button_click(&self, task: ViewTask) -> ButtonClickCallback { + let tasks = self.tasks.clone(); + let on_update = self.on_update.clone(); + Box::new(move |_common, _evt| { + tasks.push(task.clone()); + (*on_update)(); + Ok(()) + }) + } + + pub fn new(params: Params) -> anyhow::Result { + let tasks = ViewTasks::new(); + + let state = wgui::parser::parse_from_assets(&doc_params(¶ms.globals), params.layout, params.parent_id)?; + + let id_devices = state.get_widget_id("devices")?; + + let btn_sinks = state.fetch_component_as::("btn_sinks")?; + let btn_sources = state.fetch_component_as::("btn_sources")?; + let btn_cards = state.fetch_component_as::("btn_cards")?; + let btn_auto = state.fetch_component_as::("btn_auto")?; + + let mut res = Self { + globals: params.globals, + frontend_tasks: params.frontend_tasks, + state, + mode: CurrentMode::Sinks, + id_devices, + tasks, + on_update: params.on_update, + btn_sinks: btn_sinks.clone(), + btn_sources: btn_sources.clone(), + btn_cards: btn_cards.clone(), + }; + + btn_sinks.on_click(res.handle_func_button_click(ViewTask::SetMode(CurrentMode::Sinks))); + btn_sources.on_click(res.handle_func_button_click(ViewTask::SetMode(CurrentMode::Sources))); + btn_cards.on_click(res.handle_func_button_click(ViewTask::SetMode(CurrentMode::Cards))); + btn_auto.on_click(res.handle_func_button_click(ViewTask::AutoSwitch)); + + res.init_mode_sinks(params.layout)?; + res.update_button_highlights(params.layout)?; + + Ok(res) + } + + fn update_button_highlights(&self, layout: &mut Layout) -> anyhow::Result<()> { + let defaults = self.globals.defaults(); + + let mut c = layout.start_common(); + let mut common = c.common(); + + let num: u8 = match &self.mode { + CurrentMode::Sinks => 0, + CurrentMode::Sources => 1, + CurrentMode::Cards => 2, + CurrentMode::CardProfileSelector(_) => 255, + }; + + let mut perform = |btn_num: u8, btn: &Rc| { + btn.set_color( + &mut common, + if num == btn_num { + defaults.accent_color + } else { + defaults.button_color + }, + ); + }; + + perform(0, &self.btn_sinks); + perform(1, &self.btn_sources); + perform(2, &self.btn_cards); + + c.finish()?; + Ok(()) + } + + fn process_tasks(&mut self, layout: &mut Layout) -> anyhow::Result { + let tasks = self.tasks.drain(); + if tasks.is_empty() { + return Ok(false); + } + + let mut set_sink_volume: Option = None; + let mut set_source_volume: Option = None; + + for task in tasks { + match task { + ViewTask::Remount => { + self.update_button_highlights(layout)?; + match &self.mode { + CurrentMode::Sinks => self.init_mode_sinks(layout)?, + CurrentMode::Sources => self.init_mode_sources(layout)?, + CurrentMode::Cards => self.init_mode_cards(layout)?, + CurrentMode::CardProfileSelector(card) => self.init_mode_card_selector(layout, card.clone())?, + } + } + ViewTask::SetSinkVolume(s) => { + set_sink_volume = Some(s); + } + ViewTask::SetSourceVolume(s) => { + set_source_volume = Some(s); + } + ViewTask::SetMode(current_mode) => { + self.mode = current_mode; + self.tasks.push(ViewTask::Remount); + } + ViewTask::SetCardProfile(c) => { + pactl_wrapper::set_card_profile(c.card.index, &c.profile_name)?; + } + ViewTask::AutoSwitch => { + switch_to_vr_microphone(&self.frontend_tasks)?; + switch_to_vr_speakers(&self.frontend_tasks)?; + self.tasks.push(ViewTask::Remount); + } + } + } + + // set volume only to the latest event (prevent cpu time starvation + // due to excessive input motion events) + if let Some(s) = set_sink_volume { + pactl_wrapper::set_sink_volume(s.idx, s.volume)?; + } + + if let Some(s) = set_source_volume { + pactl_wrapper::set_source_volume(s.idx, s.volume)?; + } + + Ok(true) + } + + pub fn update(&mut self, layout: &mut Layout) -> anyhow::Result<()> { + while self.process_tasks(layout)? {} + + Ok(()) + } + + fn mount_card(&mut self, params: MountCardParams) -> anyhow::Result<()> { + let desc = ¶ms.card.properties.device_description; + let disp_name = get_profile_display_name(¶ms.card.active_profile, params.card); + + let mut par = HashMap::, Rc>::new(); + par.insert("card_name".into(), desc.as_str().into()); + par.insert("profile_name".into(), disp_name.name.as_str().into()); + + let data = self + .state + .parse_template(&doc_params(&self.globals), "Card", params.layout, self.id_devices, par)?; + + let btn_card = data.fetch_component_as::("btn_card")?; + btn_card.on_click({ + let tasks = self.tasks.clone(); + let card = params.card.clone(); + let on_update = self.on_update.clone(); + Box::new(move |_common, _evt| { + tasks.push(ViewTask::SetMode(CurrentMode::CardProfileSelector(card.clone()))); + (*on_update)(); + Ok(()) + }) + }); + + log::info!("mount card TODO: {}", params.card.name); + Ok(()) + } + + fn mount_device_slider(&mut self, params: MountDeviceSliderParams) -> anyhow::Result<()> { + let mut par = HashMap::, Rc>::new(); + + if let Some(disp) = ¶ms.disp { + par.insert("device_name".into(), disp.name.as_str().into()); + par.insert("device_icon".into(), disp.icon_path.into()); + } else { + par.insert("device_name".into(), params.alt_desc.into()); + par.insert("device_icon".into(), "dashboard/binary.svg".into()); + } + + par.insert( + "volume_icon".into(), + if params.muted { + "dashboard/volume_off.svg".into() + } else { + "dashboard/volume.svg".into() + }, + ); + + let data = self.state.parse_template( + &doc_params(&self.globals), + "DeviceSlider", + params.layout, + self.id_devices, + par, + )?; + + let mut c = params.layout.start_common(); + let mut common = c.common(); + + let checkbox = data.fetch_component_as::("checkbox")?; + let btn_mute = data.fetch_component_as::("btn_mute")?; + let slider = data.fetch_component_as::("slider")?; + + slider.set_value(&mut common, params.control.on_volume_request()? / VOLUME_MULT); + + checkbox.set_checked(&mut common, params.checked); + + checkbox.on_toggle({ + let control = params.control.clone(); + Box::new(move |_common, _event| { + control.on_check()?; + Ok(()) + }) + }); + + slider.on_value_changed({ + let control = params.control.clone(); + Box::new(move |_common, event| { + control.on_volume_change(event.value * VOLUME_MULT)?; + Ok(()) + }) + }); + + btn_mute.on_click({ + let control = params.control.clone(); + Box::new(move |_common, _event| { + control.on_mute_toggle()?; + Ok(()) + }) + }); + + c.finish()?; + + Ok(()) + } + + fn init_mode_sinks(&mut self, layout: &mut Layout) -> anyhow::Result<()> { + log::info!("refreshing sink list"); + + let sinks = pactl_wrapper::list_sinks()?; + let cards = pactl_wrapper::list_cards()?; + let default_sink = pactl_wrapper::get_default_sink(&sinks)?; + + layout.remove_children(self.id_devices); + + for sink in sinks { + let card = get_card_from_sink(&sink, &cards); + + let checked = if let Some(default_sink) = &default_sink { + sink.index == default_sink.index + } else { + false + }; + + let alt_desc = sink.description.clone(); + let muted = sink.mute; + + let control = Rc::new(ControlSink::new(self.tasks.clone(), self.on_update.clone(), sink)); + + let disp = card + .as_ref() + .map(|card| get_profile_display_name(&card.active_profile, card)); + + self.mount_device_slider(MountDeviceSliderParams { + checked, + disp, + alt_desc, + layout, + control, + muted, + })?; + } + + Ok(()) + } + + fn init_mode_sources(&mut self, layout: &mut Layout) -> anyhow::Result<()> { + log::info!("refreshing source list"); + + let sources = pactl_wrapper::list_sources()?; + let cards = pactl_wrapper::list_cards()?; + let default_source = pactl_wrapper::get_default_source(&sources)?; + + layout.remove_children(self.id_devices); + + for source in sources { + let card = get_card_from_source(&source, &cards); + + let checked = if let Some(default_source) = &default_source { + source.index == default_source.index + } else { + false + }; + + let alt_desc = source.description.clone(); + let muted = source.mute; + + let control = Rc::new(ControlSource::new(self.tasks.clone(), self.on_update.clone(), source)); + + let disp = card + .as_ref() + .map(|card| get_profile_display_name(&card.active_profile, card)); + + self.mount_device_slider(MountDeviceSliderParams { + checked, + disp, + alt_desc, + layout, + control, + muted, + })?; + } + + Ok(()) + } + + fn init_mode_cards(&mut self, layout: &mut Layout) -> anyhow::Result<()> { + log::info!("refreshing card list"); + + let cards = pactl_wrapper::list_cards()?; + layout.remove_children(self.id_devices); + + for card in cards { + self.mount_card(MountCardParams { layout, card: &card })?; + } + + Ok(()) + } + + fn init_mode_card_selector(&mut self, layout: &mut Layout, card: pactl_wrapper::Card) -> anyhow::Result<()> { + log::info!("showing card selector for {}", card.name); + + layout.remove_children(self.id_devices); + + { + let data = self.state.parse_template( + &doc_params(&self.globals), + "SelectAudioProfileText", + layout, + self.id_devices, + Default::default(), + )?; + let btn_back = data.fetch_component_as::("btn_back")?; + btn_back.on_click({ + let tasks = self.tasks.clone(); + let on_update = self.on_update.clone(); + Box::new(move |_, _| { + tasks.push(ViewTask::SetMode(CurrentMode::Cards)); + (*on_update)(); + Ok(()) + }) + }); + } + + let mut cells = Vec::::new(); + for profile_name in card.profiles.keys() { + if profile_name.contains("surround") { + continue; // we aren't interested in that + } + + let disp_name = get_profile_display_name(profile_name, &card); + cells.push(SelectorCell { + key: profile_name.clone(), + display_text: disp_name.name, + icon_path: disp_name.icon_path, + }); + } + + let mut ess = ConstructEssentials { + layout, + parent: self.id_devices, + }; + + mount_multi_selector(MultiSelectorParams { + cells: &cells, + def_cell: &card.active_profile, + ess: &mut ess, + on_click: { + let card = card.clone(); + let tasks = self.tasks.clone(); + let on_update = self.on_update.clone(); + Rc::new(move |profile_name| { + tasks.push(ViewTask::SetCardProfile(CardAndProfileName { + card: card.clone(), + profile_name: profile_name.to_string(), + })); + tasks.push(ViewTask::SetMode(CurrentMode::Cards)); + (*on_update)(); + }) + }, + })?; + + Ok(()) + } +} diff --git a/dash-frontend/src/views/mod.rs b/dash-frontend/src/views/mod.rs new file mode 100644 index 0000000..8fe26e0 --- /dev/null +++ b/dash-frontend/src/views/mod.rs @@ -0,0 +1,2 @@ +pub mod app_launcher; +pub mod audio_settings; diff --git a/scripts/translator/bun.lock b/scripts/translator/bun.lock new file mode 100644 index 0000000..8df74b6 --- /dev/null +++ b/scripts/translator/bun.lock @@ -0,0 +1,37 @@ +{ + "lockfileVersion": 1, + "workspaces": { + "": { + "name": "llm_translator", + "dependencies": { + "ollama": "^0.5.14", + }, + "devDependencies": { + "@types/bun": "latest", + "@types/node": "^22.13.13", + }, + "peerDependencies": { + "typescript": "^5", + }, + }, + }, + "packages": { + "@types/bun": ["@types/bun@1.2.19", "", { "dependencies": { "bun-types": "1.2.19" } }, "sha512-d9ZCmrH3CJ2uYKXQIUuZ/pUnTqIvLDS0SK7pFmbx8ma+ziH/FRMoAq5bYpRG7y+w1gl+HgyNZbtqgMq4W4e2Lg=="], + + "@types/node": ["@types/node@22.17.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-bbAKTCqX5aNVryi7qXVMi+OkB3w/OyblodicMbvE38blyAz7GxXf6XYhklokijuPwwVg9sDLKRxt0ZHXQwZVfQ=="], + + "@types/react": ["@types/react@19.1.9", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-WmdoynAX8Stew/36uTSVMcLJJ1KRh6L3IZRx1PZ7qJtBqT3dYTgyDTx8H1qoRghErydW7xw9mSJ3wS//tCRpFA=="], + + "bun-types": ["bun-types@1.2.19", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-uAOTaZSPuYsWIXRpj7o56Let0g/wjihKCkeRqUBhlLVM/Bt+Fj9xTo+LhC1OV1XDaGkz4hNC80et5xgy+9KTHQ=="], + + "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="], + + "ollama": ["ollama@0.5.16", "", { "dependencies": { "whatwg-fetch": "^3.6.20" } }, "sha512-OEbxxOIUZtdZgOaTPAULo051F5y+Z1vosxEYOoABPnQKeW7i4O8tJNlxCB+xioyoorVqgjkdj+TA1f1Hy2ug/w=="], + + "typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="], + + "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], + + "whatwg-fetch": ["whatwg-fetch@3.6.20", "", {}, "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg=="], + } +} diff --git a/scripts/translator/description.txt b/scripts/translator/description.txt new file mode 100644 index 0000000..1774ac5 --- /dev/null +++ b/scripts/translator/description.txt @@ -0,0 +1,16 @@ +You are a translator for the VR application which translates strings from English to {TARGET_LANG} language. +Info: This program is intended to be used as an utility to easily access your desktop display from within VR. + +Glossary: +- wlx-overlay-s: The name of this software (also called WlxOverlay-S) +- WayVR: A Wayland compositor intended to be used in VR +- WayVR Dashboard: An application (and game) launcher which is displayed in front of the user +- OpenVR: API made by Valve +- OpenXR: API made by Khronos +- OSC: OpenSoundControl +- Playspace: A designated real area where users can interact with the virtual environment +- Space-drag: A feature which allows the user to move their HMD origin position via a controller +- Passthrough: Some headsets have built-in cameras for displaying image on the HMD screen +End of glossary; + +You will be given the input in the code blocks which needs to be translated to {TARGET_LANG} language. Write only the result in codeblocks, do not explain. Keep any newlines and other important formatting-required identifiers as-is. diff --git a/scripts/translator/main.ts b/scripts/translator/main.ts new file mode 100644 index 0000000..134ef76 --- /dev/null +++ b/scripts/translator/main.ts @@ -0,0 +1,189 @@ +import { exit } from "process"; +import * as fsp from "fs/promises"; +import path from "path"; +import * as fs from "fs"; +import ollama from 'ollama' + +const model_name = process.env["MODEL"] as string; +const template_name = process.env["TEMPLATE"] as string; +let lang_path = process.env["LANG_PATH"] as string; + +if (model_name === undefined) { + console.log("MODEL not set"); + exit(-1); +} + +if (template_name === undefined) { + console.log("TEMPLATE not set"); + exit(-1); +} + +if (lang_path === undefined) { + console.log("LANG_PATH is not set. Try one of these:\n\nLANG_PATH=../../uidev/assets/lang/ ./run.sh\nLANG_PATH=../../dash-frontend/assets/lang/ ./run.sh\n"); + exit(-1); +} + +lang_path = path.resolve(__dirname + "/" + lang_path); +if (lang_path === undefined || !fs.existsSync(lang_path)) { + console.log("Invalid or non-existent LANG_PATH"); + exit(-1); +} + +const current_path = path.resolve(__dirname); +const templates_path = path.resolve(__dirname + "/templates"); + +async function loop_object(obj: any, initial_str: string, callback: (key: string, value: string) => Promise) { + for (var key in obj) { + let full_key = initial_str + key; + if (typeof obj[key] === "object" && obj[key] !== null) { + await loop_object(obj[key], full_key + ".", callback) + } else if (obj.hasOwnProperty(key)) { + await callback(full_key, obj[key]) + } + } +} + +function extract_backticks(str: string) { + const regex = /`([^`]+)`/g; + return str.match(regex)?.map(match => match.slice(1, -1).trim()); +} + +function set_i18n_key(obj: any, key: string, value: string | undefined) { + const parts = key.split('.'); + let cur_level = obj; + for (let i = 0; i < parts.length - 1; i++) { + const part = parts[i]!; + if (!cur_level[part]) { + cur_level[part] = {}; + } + cur_level = cur_level[part]; + } + cur_level[parts[parts.length - 1]!] = value; +} + +function key_exists(obj: any, key: string) { + const parts = key.split('.'); + let level = obj; + + for (let i = 0; i < parts.length; i++) { + const part = parts[i]!; + if (!level || !level[part]) { + return false; + } + level = level[part]; + } + + return true; +}; + +interface Example { + key: string; + en: string; + translated: string; +} + +interface Template { + full_name: string; // "Polish" + examples: Example[] +} + +function gen_prompt(description: string, template: Template, key: string, english_translation: string) { + let num = 1; + for (const example of template.examples) { + description += "\nExample " + num + ":\n\n"; + description += "Translate key `" + example.key + "` from English to " + template.full_name + ":\n\n"; + description += "```\n"; + description += example.en + "\n"; + description += "```\n\n"; + description += "Result:\n\n"; + description += "```\n"; + description += example.translated + "\n"; + description += "```\n"; + num += 1; + } + description += "\nEnd of examples.\n\n"; + description += "Translate key `" + key + "` from English to " + template.full_name + ":\n\n"; + description += "```\n"; + description += english_translation + "\n"; + description += "```\n"; + return description; +} + +async function run() { + const template = JSON.parse(await fsp.readFile(templates_path + "/" + template_name + ".json", "utf-8")) as Template; + + let description_txt = await fsp.readFile(current_path + "/description.txt", "utf-8"); + description_txt = description_txt.replaceAll("{TARGET_LANG}", template.full_name); + + const orig_english_json = JSON.parse(await fsp.readFile(lang_path + "/en.json") as any); + + let orig_translated_json = {}; + try { + orig_translated_json = JSON.parse((await fsp.readFile(lang_path + "/" + template_name + ".json")).toString()); + } + catch (_e) { } + + let llm_translated_json = {}; + const translated_json_path = lang_path + "/" + template_name + ".json"; + if (await fsp.exists(translated_json_path)) { + llm_translated_json = JSON.parse((await fsp.readFile(translated_json_path)).toString()); + } + + let human = 0; + let llm = 0; + + let total_count = 0; + await loop_object(orig_english_json, "", async () => { + total_count += 1; + }); + + await loop_object(llm_translated_json, "", async (key, _) => { + if (!key_exists(orig_english_json, key)) { + console.log("Removing key", key); + set_i18n_key(llm_translated_json, key, undefined); + fsp.writeFile(translated_json_path, JSON.stringify(llm_translated_json, undefined, 2)); + } + }); + + await loop_object(orig_english_json, "", async (key, english_translation) => { + if (key_exists(orig_translated_json, key)) { + human += 1; + return; + } + + if (key_exists(llm_translated_json, key)) { + llm += 1; + return; + } + + console.log("Translating", key, "..."); + llm++; + + const prompt = gen_prompt(description_txt, template, key, english_translation); + + const response = await ollama.chat({ + model: model_name, + messages: [{ role: "user", content: prompt }], + options: { + seed: 12345, + } + }) + + const msg = extract_backticks(response.message.content); + if (msg === undefined || msg[0] === undefined) { + throw new Error("backticks failed. Raw content: " + response.message.content); + } + + console.log(" >>>", msg); + + set_i18n_key(llm_translated_json, key, msg[0]); + fsp.writeFile(translated_json_path, JSON.stringify(llm_translated_json, undefined, 2)); + }); + + console.log("\"" + template_name + "\" translation finished,", human, "were already human translated,", llm, "llm-translated (" + Math.round((llm / total_count) * 100.0) + "% machine-translated)"); +} + +run().catch((e) => { + console.log("Fatal error:", e); + exit(-1); +}); \ No newline at end of file diff --git a/scripts/translator/package-lock.json b/scripts/translator/package-lock.json new file mode 100644 index 0000000..0834aac --- /dev/null +++ b/scripts/translator/package-lock.json @@ -0,0 +1,108 @@ +{ + "name": "llm_translator", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "llm_translator", + "dependencies": { + "ollama": "^0.5.14" + }, + "devDependencies": { + "@types/bun": "latest", + "@types/node": "^22.13.13" + }, + "peerDependencies": { + "typescript": "^5" + } + }, + "node_modules/@types/bun": { + "version": "1.2.19", + "resolved": "https://registry.npmjs.org/@types/bun/-/bun-1.2.19.tgz", + "integrity": "sha512-d9ZCmrH3CJ2uYKXQIUuZ/pUnTqIvLDS0SK7pFmbx8ma+ziH/FRMoAq5bYpRG7y+w1gl+HgyNZbtqgMq4W4e2Lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "bun-types": "1.2.19" + } + }, + "node_modules/@types/node": { + "version": "22.17.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.17.0.tgz", + "integrity": "sha512-bbAKTCqX5aNVryi7qXVMi+OkB3w/OyblodicMbvE38blyAz7GxXf6XYhklokijuPwwVg9sDLKRxt0ZHXQwZVfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/react": { + "version": "19.1.9", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.9.tgz", + "integrity": "sha512-WmdoynAX8Stew/36uTSVMcLJJ1KRh6L3IZRx1PZ7qJtBqT3dYTgyDTx8H1qoRghErydW7xw9mSJ3wS//tCRpFA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/bun-types": { + "version": "1.2.19", + "resolved": "https://registry.npmjs.org/bun-types/-/bun-types-1.2.19.tgz", + "integrity": "sha512-uAOTaZSPuYsWIXRpj7o56Let0g/wjihKCkeRqUBhlLVM/Bt+Fj9xTo+LhC1OV1XDaGkz4hNC80et5xgy+9KTHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + }, + "peerDependencies": { + "@types/react": "^19" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/ollama": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/ollama/-/ollama-0.5.16.tgz", + "integrity": "sha512-OEbxxOIUZtdZgOaTPAULo051F5y+Z1vosxEYOoABPnQKeW7i4O8tJNlxCB+xioyoorVqgjkdj+TA1f1Hy2ug/w==", + "license": "MIT", + "dependencies": { + "whatwg-fetch": "^3.6.20" + } + }, + "node_modules/typescript": { + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", + "license": "MIT" + } + } +} diff --git a/scripts/translator/package.json b/scripts/translator/package.json new file mode 100644 index 0000000..d01cf03 --- /dev/null +++ b/scripts/translator/package.json @@ -0,0 +1,16 @@ +{ + "devDependencies": { + "@types/bun": "latest", + "@types/node": "^22.13.13" + }, + "name": "llm_translator", + "module": "index.ts", + "type": "module", + "private": true, + "peerDependencies": { + "typescript": "^5" + }, + "dependencies": { + "ollama": "^0.5.14" + } +} diff --git a/scripts/translator/run.sh b/scripts/translator/run.sh new file mode 100755 index 0000000..93261e6 --- /dev/null +++ b/scripts/translator/run.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -e +cd "$(dirname "$0")" + +bun install + +export MODEL="gemma3:12b" + +TEMPLATE="pl" bun main.ts +TEMPLATE="de" bun main.ts +TEMPLATE="ja" bun main.ts +TEMPLATE="es" bun main.ts diff --git a/scripts/translator/templates/de.json b/scripts/translator/templates/de.json new file mode 100644 index 0000000..4f617fa --- /dev/null +++ b/scripts/translator/templates/de.json @@ -0,0 +1,20 @@ +{ + "full_name": "German", + "examples": [ + { + "key": "BAR.OPACITY", + "en": "Opacity", + "translated": "Undurchsichtigkeit" + }, + { + "key": "PANEL.CLOSE", + "en": "Close panel", + "translated": "Schließen Sie das Panel" + }, + { + "key": "SETTINGS.LEFT_HANDED_MODE", + "en": "Left-handed mode", + "translated": "Linkshändige Modus" + } + ] +} diff --git a/scripts/translator/templates/es.json b/scripts/translator/templates/es.json new file mode 100644 index 0000000..f2eb766 --- /dev/null +++ b/scripts/translator/templates/es.json @@ -0,0 +1,20 @@ +{ + "full_name": "Spanish", + "examples": [ + { + "key": "BAR.OPACITY", + "en": "Opacity", + "translated": "Opacidad" + }, + { + "key": "PANEL.CLOSE", + "en": "Close panel", + "translated": "Cerrar panel" + }, + { + "key": "SETTINGS.LEFT_HANDED_MODE", + "en": "Left-handed mode", + "translated": "Modo para zurdos" + } + ] +} diff --git a/scripts/translator/templates/ja.json b/scripts/translator/templates/ja.json new file mode 100644 index 0000000..c4e657c --- /dev/null +++ b/scripts/translator/templates/ja.json @@ -0,0 +1,20 @@ +{ + "full_name": "Japanese", + "examples": [ + { + "key": "BAR.OPACITY", + "en": "Opacity", + "translated": "不透明度" + }, + { + "key": "PANEL.CLOSE", + "en": "Close panel", + "translated": "パネルを閉じる" + }, + { + "key": "SETTINGS.LEFT_HANDED_MODE", + "en": "Left-handed mode", + "translated": "左利きモード" + } + ] +} diff --git a/scripts/translator/templates/pl.json b/scripts/translator/templates/pl.json new file mode 100644 index 0000000..6e7866f --- /dev/null +++ b/scripts/translator/templates/pl.json @@ -0,0 +1,20 @@ +{ + "full_name": "Polish", + "examples": [ + { + "key": "BAR.OPACITY", + "en": "Opacity", + "translated": "Przezroczystość" + }, + { + "key": "PANEL.CLOSE", + "en": "Close panel", + "translated": "Zamknij panel" + }, + { + "key": "SETTINGS.LEFT_HANDED_MODE", + "en": "Left-handed mode", + "translated": "Tryb leworęczny" + } + ] +} diff --git a/scripts/translator/tsconfig.json b/scripts/translator/tsconfig.json new file mode 100644 index 0000000..7b72024 --- /dev/null +++ b/scripts/translator/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "lib": ["esnext"], + "target": "ESNext", + "module": "ESNext", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": true, + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false + } +} diff --git a/src/backend/common.rs b/src/backend/common.rs deleted file mode 100644 index de399d2..0000000 --- a/src/backend/common.rs +++ /dev/null @@ -1,378 +0,0 @@ -use std::sync::{Arc, LazyLock}; - -#[cfg(feature = "openxr")] -use openxr as xr; - -use glam::{Affine3A, Vec3, Vec3A}; -use idmap::IdMap; -use serde::Deserialize; -use thiserror::Error; - -use crate::{ - config::AStrSetExt, - hid::{get_keymap_wl, get_keymap_x11}, - overlays::{ - anchor::create_anchor, - keyboard::{create_keyboard, KEYBOARD_NAME}, - screen::WlxClientAlias, - watch::{create_watch, WATCH_NAME}, - }, - state::AppState, -}; - -use super::overlay::{OverlayData, OverlayID}; - -#[derive(Error, Debug)] -pub enum BackendError { - #[error("backend not supported")] - NotSupported, - #[cfg(feature = "openxr")] - #[error("OpenXR Error: {0:?}")] - OpenXrError(#[from] xr::sys::Result), - #[error("Shutdown")] - Shutdown, - #[error("Restart")] - Restart, - #[error("Fatal: {0:?}")] - Fatal(#[from] anyhow::Error), -} - -#[cfg(feature = "wayland")] -fn create_wl_client() -> Option { - wlx_capture::wayland::WlxClient::new() -} - -#[cfg(not(feature = "wayland"))] -fn create_wl_client() -> Option { - None -} - -pub struct OverlayContainer -where - T: Default, -{ - overlays: IdMap>, - wl: Option, -} - -impl OverlayContainer -where - T: Default, -{ - pub fn new(app: &mut AppState, headless: bool) -> anyhow::Result { - let mut overlays = IdMap::new(); - let mut show_screens = app.session.config.show_screens.clone(); - let mut wl = None; - let mut keymap = None; - - app.screens.clear(); - - if headless { - log::info!("Running in headless mode; keyboard will be en-US"); - } else { - wl = create_wl_client(); - - let data = if let Some(wl) = wl.as_mut() { - log::info!("Wayland detected."); - keymap = get_keymap_wl() - .map_err(|f| log::warn!("Could not load keyboard layout: {f}")) - .ok(); - crate::overlays::screen::create_screens_wayland(wl, app) - } else { - log::info!("Wayland not detected, assuming X11."); - keymap = get_keymap_x11() - .map_err(|f| log::warn!("Could not load keyboard layout: {f}")) - .ok(); - match crate::overlays::screen::create_screens_x11pw(app) { - Ok(data) => data, - Err(e) => { - log::info!("Will not use X11 PipeWire capture: {e:?}"); - crate::overlays::screen::create_screens_xshm(app)? - } - } - }; - - if show_screens.is_empty() { - if let Some((_, s, _)) = data.screens.first() { - show_screens.arc_set(s.name.clone()); - } - } - - for (meta, mut state, backend) in data.screens { - if show_screens.arc_get(state.name.as_ref()) { - state.show_hide = true; - } - overlays.insert( - state.id.0, - OverlayData:: { - state, - backend, - ..Default::default() - }, - ); - app.screens.push(meta); - } - } - - let anchor = create_anchor(app)?; - overlays.insert(anchor.state.id.0, anchor); - - let mut watch = create_watch::(app)?; - watch.state.want_visible = true; - overlays.insert(watch.state.id.0, watch); - - let mut keyboard = create_keyboard(app, keymap)?; - keyboard.state.show_hide = show_screens.arc_get(KEYBOARD_NAME); - keyboard.state.want_visible = false; - overlays.insert(keyboard.state.id.0, keyboard); - - Ok(Self { overlays, wl }) - } - - #[cfg(not(feature = "wayland"))] - pub fn update(&mut self, _app: &mut AppState) -> anyhow::Result>> { - Ok(vec![]) - } - #[cfg(feature = "wayland")] - #[allow(clippy::too_many_lines, clippy::cognitive_complexity)] - #[allow(clippy::all, clippy::pedantic, clippy::nursery, clippy::cargo)] - pub fn update(&mut self, app: &mut AppState) -> anyhow::Result>> { - use crate::overlays::{ - screen::{create_screen_interaction, create_screen_renderer_wl, load_pw_token_config}, - watch::create_watch_canvas, - }; - use glam::vec2; - use wlx_capture::wayland::OutputChangeEvent; - - let mut removed_overlays = vec![]; - let Some(wl) = self.wl.as_mut() else { - return Ok(removed_overlays); - }; - - wl.dispatch_pending(); - - let mut create_ran = false; - let mut extent_dirty = false; - let mut watch_dirty = false; - - let mut maybe_token_store = None; - - for ev in wl.iter_events().collect::>() { - match ev { - OutputChangeEvent::Create(_) => { - if create_ran { - continue; - } - let data = crate::overlays::screen::create_screens_wayland(wl, app); - create_ran = true; - for (meta, state, backend) in data.screens { - self.overlays.insert( - state.id.0, - OverlayData:: { - state, - backend, - ..Default::default() - }, - ); - app.screens.push(meta); - watch_dirty = true; - } - } - OutputChangeEvent::Destroy(id) => { - let Some(idx) = app.screens.iter().position(|s| s.native_handle == id) else { - continue; - }; - - let meta = &app.screens[idx]; - let removed = self.overlays.remove(meta.id.0).unwrap(); - removed_overlays.push(removed); - log::info!("{}: Destroyed", meta.name); - app.screens.remove(idx); - watch_dirty = true; - extent_dirty = true; - } - OutputChangeEvent::Logical(id) => { - let Some(meta) = app.screens.iter().find(|s| s.native_handle == id) else { - continue; - }; - let output = wl.outputs.get(id).unwrap(); - let Some(overlay) = self.overlays.get_mut(meta.id.0) else { - continue; - }; - let logical_pos = - vec2(output.logical_pos.0 as f32, output.logical_pos.1 as f32); - let logical_size = - vec2(output.logical_size.0 as f32, output.logical_size.1 as f32); - let transform = output.transform.into(); - overlay - .backend - .set_interaction(Box::new(create_screen_interaction( - logical_pos, - logical_size, - transform, - ))); - extent_dirty = true; - } - OutputChangeEvent::Physical(id) => { - let Some(meta) = app.screens.iter().find(|s| s.native_handle == id) else { - continue; - }; - let output = wl.outputs.get(id).unwrap(); - let Some(overlay) = self.overlays.get_mut(meta.id.0) else { - continue; - }; - - let has_wlr_dmabuf = wl.maybe_wlr_dmabuf_mgr.is_some(); - let has_wlr_screencopy = wl.maybe_wlr_screencopy_mgr.is_some(); - - let pw_token_store = maybe_token_store.get_or_insert_with(|| { - load_pw_token_config().unwrap_or_else(|e| { - log::warn!("Failed to load PipeWire token config: {:?}", e); - Default::default() - }) - }); - - if let Some(renderer) = create_screen_renderer_wl( - output, - has_wlr_dmabuf, - has_wlr_screencopy, - pw_token_store, - &app, - ) { - overlay.backend.set_renderer(Box::new(renderer)); - } - extent_dirty = true; - } - } - } - - if extent_dirty && !create_ran { - let extent = wl.get_desktop_extent(); - let origin = wl.get_desktop_origin(); - app.hid_provider - .set_desktop_extent(vec2(extent.0 as f32, extent.1 as f32)); - app.hid_provider - .set_desktop_origin(vec2(origin.0 as f32, origin.1 as f32)); - } - - if watch_dirty { - let watch = self.mut_by_name(WATCH_NAME).unwrap(); // want panic - match create_watch_canvas(None, app) { - Ok(canvas) => { - watch.backend = Box::new(canvas); - } - Err(e) => { - log::error!("Failed to create watch canvas: {}", e); - } - } - } - - Ok(removed_overlays) - } - - pub fn mut_by_selector(&mut self, selector: &OverlaySelector) -> Option<&mut OverlayData> { - match selector { - OverlaySelector::Id(id) => self.mut_by_id(*id), - OverlaySelector::Name(name) => self.mut_by_name(name), - } - } - - pub fn remove_by_selector(&mut self, selector: &OverlaySelector) -> Option> { - match selector { - OverlaySelector::Id(id) => self.overlays.remove(id.0), - OverlaySelector::Name(name) => { - let id = self - .overlays - .iter() - .find(|(_, o)| *o.state.name == **name) - .map(|(id, _)| *id); - id.and_then(|id| self.overlays.remove(id)) - } - } - } - - pub fn get_by_id(&mut self, id: OverlayID) -> Option<&OverlayData> { - self.overlays.get(id.0) - } - - pub fn mut_by_id(&mut self, id: OverlayID) -> Option<&mut OverlayData> { - self.overlays.get_mut(id.0) - } - - pub fn get_by_name<'a>(&'a mut self, name: &str) -> Option<&'a OverlayData> { - self.overlays.values().find(|o| *o.state.name == *name) - } - - pub fn mut_by_name<'a>(&'a mut self, name: &str) -> Option<&'a mut OverlayData> { - self.overlays.values_mut().find(|o| *o.state.name == *name) - } - - pub fn iter(&self) -> impl Iterator> { - self.overlays.values() - } - - pub fn iter_mut(&mut self) -> impl Iterator> { - self.overlays.values_mut() - } - - pub fn add(&mut self, overlay: OverlayData) { - self.overlays.insert(overlay.state.id.0, overlay); - } - - pub fn show_hide(&mut self, app: &mut AppState) { - let any_shown = self - .overlays - .values() - .any(|o| o.state.show_hide && o.state.want_visible); - - if !any_shown { - static ANCHOR_LOCAL: LazyLock = - LazyLock::new(|| Affine3A::from_translation(Vec3::NEG_Z)); - let hmd = snap_upright(app.input_state.hmd, Vec3A::Y); - app.anchor = hmd * *ANCHOR_LOCAL; - } - - self.overlays.values_mut().for_each(|o| { - if o.state.show_hide { - o.state.want_visible = !any_shown; - if o.state.want_visible - && app.session.config.realign_on_showhide - && o.state.recenter - { - o.state.reset(app, false); - } - } - // toggle watch back on if it was hidden - if !any_shown && *o.state.name == *WATCH_NAME { - o.state.reset(app, true); - } - }); - } -} - -#[derive(Clone, Deserialize, Debug)] -#[serde(untagged)] -pub enum OverlaySelector { - Id(OverlayID), - Name(Arc), -} - -pub fn snap_upright(transform: Affine3A, up_dir: Vec3A) -> Affine3A { - if transform.x_axis.dot(up_dir).abs() < 0.2 { - let scale = transform.x_axis.length(); - let col_z = transform.z_axis.normalize(); - let col_y = up_dir; - let col_x = col_y.cross(col_z); - let col_y = col_z.cross(col_x).normalize(); - let col_x = col_x.normalize(); - - Affine3A::from_cols( - col_x * scale, - col_y * scale, - col_z * scale, - transform.translation, - ) - } else { - transform - } -} diff --git a/src/backend/input.rs b/src/backend/input.rs deleted file mode 100644 index 2838703..0000000 --- a/src/backend/input.rs +++ /dev/null @@ -1,744 +0,0 @@ -use std::f32::consts::PI; -use std::process::{Child, Command}; -use std::{collections::VecDeque, time::Instant}; - -use glam::{Affine3A, Vec2, Vec3, Vec3A, Vec3Swizzles}; - -use smallvec::{smallvec, SmallVec}; - -use crate::backend::common::OverlaySelector; -use crate::backend::overlay::Positioning; -use crate::config::AStrMapExt; -use crate::overlays::anchor::ANCHOR_NAME; -use crate::state::{AppSession, AppState, KeyboardFocus}; - -use super::overlay::{OverlayID, OverlayState}; -use super::task::{TaskContainer, TaskType}; -use super::{common::OverlayContainer, overlay::OverlayData}; - -pub struct TrackedDevice { - pub soc: Option, - pub charging: bool, - pub role: TrackedDeviceRole, -} - -#[repr(u8)] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum TrackedDeviceRole { - None, - Hmd, - LeftHand, - RightHand, - Tracker, -} - -pub struct InputState { - pub hmd: Affine3A, - pub ipd: f32, - pub pointers: [Pointer; 2], - pub devices: Vec, - processes: Vec, -} - -impl InputState { - pub fn new() -> Self { - Self { - hmd: Affine3A::IDENTITY, - ipd: 0.0, - pointers: [Pointer::new(0), Pointer::new(1)], - devices: Vec::new(), - processes: Vec::new(), - } - } - - pub const fn pre_update(&mut self) { - self.pointers[0].before = self.pointers[0].now; - self.pointers[1].before = self.pointers[1].now; - } - - pub fn post_update(&mut self, session: &AppSession) { - for hand in &mut self.pointers { - #[cfg(debug_assertions)] - debug_print_hand(hand); - - if hand.now.click { - hand.last_click = Instant::now(); - } - - if hand.now.click_modifier_right { - hand.interaction.mode = PointerMode::Right; - continue; - } - - if hand.now.click_modifier_middle { - hand.interaction.mode = PointerMode::Middle; - continue; - } - - let hmd_up = self.hmd.transform_vector3a(Vec3A::Y); - let dot = hmd_up.dot(hand.pose.transform_vector3a(Vec3A::X)) - * 2.0f32.mul_add(-(hand.idx as f32), 1.0); - - hand.interaction.mode = if dot < -0.85 { - PointerMode::Right - } else if dot > 0.7 { - PointerMode::Middle - } else { - PointerMode::Left - }; - - let middle_click_orientation = false; - let right_click_orientation = false; - match hand.interaction.mode { - PointerMode::Middle => { - if !middle_click_orientation { - hand.interaction.mode = PointerMode::Left; - } - } - PointerMode::Right => { - if !right_click_orientation { - hand.interaction.mode = PointerMode::Left; - } - } - _ => {} - } - - if hand.now.alt_click != hand.before.alt_click { - // Reap previous processes - self.processes - .retain_mut(|child| !matches!(child.try_wait(), Ok(Some(_)))); - - let mut args = if hand.now.alt_click { - session.config.alt_click_down.iter() - } else { - session.config.alt_click_up.iter() - }; - - if let Some(program) = args.next() { - if let Ok(child) = Command::new(program).args(args).spawn() { - self.processes.push(child); - } - } - } - } - } -} - -#[cfg(debug_assertions)] -fn debug_print_hand(hand: &Pointer) { - { - if hand.now.click != hand.before.click { - log::debug!("Hand {}: click {}", hand.idx, hand.now.click); - } - if hand.now.grab != hand.before.grab { - log::debug!("Hand {}: grab {}", hand.idx, hand.now.grab); - } - if hand.now.alt_click != hand.before.alt_click { - log::debug!("Hand {}: alt_click {}", hand.idx, hand.now.alt_click); - } - if hand.now.show_hide != hand.before.show_hide { - log::debug!("Hand {}: show_hide {}", hand.idx, hand.now.show_hide); - } - if hand.now.toggle_dashboard != hand.before.toggle_dashboard { - log::debug!( - "Hand {}: toggle_dashboard {}", - hand.idx, - hand.now.toggle_dashboard - ); - } - if hand.now.space_drag != hand.before.space_drag { - log::debug!("Hand {}: space_drag {}", hand.idx, hand.now.space_drag); - } - if hand.now.space_rotate != hand.before.space_rotate { - log::debug!("Hand {}: space_rotate {}", hand.idx, hand.now.space_rotate); - } - if hand.now.space_reset != hand.before.space_reset { - log::debug!("Hand {}: space_reset {}", hand.idx, hand.now.space_reset); - } - if hand.now.click_modifier_right != hand.before.click_modifier_right { - log::debug!( - "Hand {}: click_modifier_right {}", - hand.idx, - hand.now.click_modifier_right - ); - } - if hand.now.click_modifier_middle != hand.before.click_modifier_middle { - log::debug!( - "Hand {}: click_modifier_middle {}", - hand.idx, - hand.now.click_modifier_middle - ); - } - } -} - -pub struct InteractionState { - pub mode: PointerMode, - pub grabbed: Option, - pub clicked_id: Option, - pub hovered_id: Option, - pub release_actions: VecDeque>, - pub next_push: Instant, - pub haptics: Option, -} - -impl Default for InteractionState { - fn default() -> Self { - Self { - mode: PointerMode::Left, - grabbed: None, - clicked_id: None, - hovered_id: None, - release_actions: VecDeque::new(), - next_push: Instant::now(), - haptics: None, - } - } -} - -pub struct Pointer { - pub idx: usize, - pub pose: Affine3A, - pub raw_pose: Affine3A, - pub now: PointerState, - pub before: PointerState, - pub last_click: Instant, - pub(super) interaction: InteractionState, -} - -impl Pointer { - pub fn new(idx: usize) -> Self { - debug_assert!(idx == 0 || idx == 1); - Self { - idx, - pose: Affine3A::IDENTITY, - raw_pose: Affine3A::IDENTITY, - now: PointerState::default(), - before: PointerState::default(), - last_click: Instant::now(), - interaction: InteractionState::default(), - } - } -} - -#[derive(Clone, Copy, Default)] -pub struct PointerState { - pub scroll_x: f32, - pub scroll_y: f32, - pub click: bool, - pub grab: bool, - pub alt_click: bool, - pub show_hide: bool, - pub toggle_dashboard: bool, - pub space_drag: bool, - pub space_rotate: bool, - pub space_reset: bool, - pub click_modifier_right: bool, - pub click_modifier_middle: bool, - pub move_mouse: bool, -} - -#[derive(Debug, Clone, Copy, Default)] -pub struct PointerHit { - pub pointer: usize, - pub overlay: OverlayID, - pub mode: PointerMode, - pub primary: bool, - pub uv: Vec2, - pub dist: f32, -} - -#[derive(Clone)] -pub struct Haptics { - pub intensity: f32, - pub duration: f32, - pub frequency: f32, -} - -pub trait InteractionHandler { - fn on_hover(&mut self, app: &mut AppState, hit: &PointerHit) -> Option; - fn on_left(&mut self, app: &mut AppState, pointer: usize); - fn on_pointer(&mut self, app: &mut AppState, hit: &PointerHit, pressed: bool); - fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta_y: f32, delta_x: f32); -} - -pub struct DummyInteractionHandler; - -impl InteractionHandler for DummyInteractionHandler { - fn on_left(&mut self, _app: &mut AppState, _pointer: usize) {} - fn on_hover(&mut self, _app: &mut AppState, _hit: &PointerHit) -> Option { - None - } - fn on_pointer(&mut self, _app: &mut AppState, _hit: &PointerHit, _pressed: bool) {} - fn on_scroll(&mut self, _app: &mut AppState, _hit: &PointerHit, _delta_y: f32, _delta_x: f32) {} -} - -#[derive(Debug, Clone, Copy, Default)] -struct RayHit { - overlay: OverlayID, - global_pos: Vec3A, - local_pos: Vec2, - dist: f32, -} - -#[derive(Debug, Clone, Copy, Default)] -pub struct GrabData { - pub offset: Vec3A, - pub grabbed_id: OverlayID, - pub old_curvature: Option, - pub grab_all: bool, -} - -#[repr(u8)] -#[derive(Debug, Clone, Copy, Default)] -pub enum PointerMode { - #[default] - Left, - Right, - Middle, - Special, -} - -fn update_focus(focus: &mut KeyboardFocus, state: &OverlayState) { - if let Some(f) = &state.keyboard_focus { - if *focus != *f { - log::info!("Setting keyboard focus to {:?}", *f); - *focus = *f; - } - } -} - -pub fn interact( - overlays: &mut OverlayContainer, - app: &mut AppState, -) -> [(f32, Option); 2] -where - O: Default, -{ - if app.input_state.pointers[1].last_click > app.input_state.pointers[0].last_click { - let right = interact_hand(1, overlays, app); - let left = interact_hand(0, overlays, app); - [left, right] - } else { - let left = interact_hand(0, overlays, app); - let right = interact_hand(1, overlays, app); - [left, right] - } -} - -#[allow(clippy::too_many_lines, clippy::cognitive_complexity)] -fn interact_hand( - idx: usize, - overlays: &mut OverlayContainer, - app: &mut AppState, -) -> (f32, Option) -where - O: Default, -{ - let mut pointer = &mut app.input_state.pointers[idx]; - if let Some(grab_data) = pointer.interaction.grabbed { - if let Some(grabbed) = overlays.mut_by_id(grab_data.grabbed_id) { - Pointer::handle_grabbed(idx, grabbed, app); - } else { - log::warn!("Grabbed overlay {} does not exist", grab_data.grabbed_id.0); - pointer.interaction.grabbed = None; - } - return (0.1, None); - } - - let Some(mut hit) = pointer.get_nearest_hit(overlays) else { - if let Some(hovered_id) = pointer.interaction.hovered_id.take() { - if let Some(hovered) = overlays.mut_by_id(hovered_id) { - hovered.backend.on_left(app, idx); - } - pointer = &mut app.input_state.pointers[idx]; - pointer.interaction.hovered_id = None; - } - if !pointer.now.click && pointer.before.click { - if let Some(clicked_id) = pointer.interaction.clicked_id.take() { - if let Some(clicked) = overlays.mut_by_id(clicked_id) { - let hit = PointerHit { - pointer: pointer.idx, - overlay: clicked_id, - mode: pointer.interaction.mode, - ..Default::default() - }; - clicked.backend.on_pointer(app, &hit, false); - } - } - } - return (0.0, None); // no hit - }; - - if let Some(hovered_id) = pointer.interaction.hovered_id { - if hovered_id != hit.overlay { - if let Some(old_hovered) = overlays.mut_by_id(hovered_id) { - if Some(pointer.idx) == old_hovered.primary_pointer { - old_hovered.primary_pointer = None; - } - old_hovered.backend.on_left(app, idx); - pointer = &mut app.input_state.pointers[idx]; - } - } - } - let Some(hovered) = overlays.mut_by_id(hit.overlay) else { - log::warn!("Hit overlay {} does not exist", hit.overlay.0); - return (0.0, None); // no hit - }; - - pointer.interaction.hovered_id = Some(hit.overlay); - - if let Some(primary_pointer) = hovered.primary_pointer { - if hit.pointer <= primary_pointer { - hovered.primary_pointer = Some(hit.pointer); - hit.primary = true; - } - } else { - hovered.primary_pointer = Some(hit.pointer); - hit.primary = true; - } - - #[cfg(debug_assertions)] - log::trace!("Hit: {} {:?}", hovered.state.name, hit); - - if pointer.now.grab && !pointer.before.grab && hovered.state.grabbable { - update_focus(&mut app.keyboard_focus, &hovered.state); - pointer.start_grab(hovered, &mut app.tasks); - return ( - hit.dist, - Some(Haptics { - intensity: 0.25, - duration: 0.1, - frequency: 0.1, - }), - ); - } - - // Pass mouse motion events only if not scrolling - // (allows scrolling on all Chromium-based applications) - let haptics = hovered.backend.on_hover(app, &hit); - - pointer = &mut app.input_state.pointers[idx]; - - if pointer.now.scroll_x.abs() > 0.1 || pointer.now.scroll_y.abs() > 0.1 { - let scroll_x = pointer.now.scroll_x; - let scroll_y = pointer.now.scroll_y; - if app.input_state.pointers[1 - idx] - .interaction - .grabbed - .is_some_and(|x| x.grabbed_id == hit.overlay) - { - let can_curve = hovered - .frame_meta() - .is_some_and(|e| e.extent[0] >= e.extent[1]); - - if can_curve { - let cur = hovered.state.curvature.unwrap_or(0.0); - let new = scroll_y.mul_add(-0.01, cur).min(0.5); - if new <= f32::EPSILON { - hovered.state.curvature = None; - } else { - hovered.state.curvature = Some(new); - } - } else { - hovered.state.curvature = None; - } - } else { - hovered.backend.on_scroll(app, &hit, scroll_y, scroll_x); - } - pointer = &mut app.input_state.pointers[idx]; - } - - if pointer.now.click && !pointer.before.click { - pointer.interaction.clicked_id = Some(hit.overlay); - update_focus(&mut app.keyboard_focus, &hovered.state); - hovered.backend.on_pointer(app, &hit, true); - } else if !pointer.now.click && pointer.before.click { - if let Some(clicked_id) = pointer.interaction.clicked_id.take() { - if let Some(clicked) = overlays.mut_by_id(clicked_id) { - clicked.backend.on_pointer(app, &hit, false); - } - } else { - hovered.backend.on_pointer(app, &hit, false); - } - } - (hit.dist, haptics) -} - -impl Pointer { - fn get_nearest_hit(&mut self, overlays: &mut OverlayContainer) -> Option - where - O: Default, - { - let mut hits: SmallVec<[RayHit; 8]> = smallvec!(); - - for overlay in overlays.iter() { - if !overlay.state.want_visible || !overlay.state.interactable { - continue; - } - - if let Some(hit) = self.ray_test( - overlay.state.id, - &overlay.state.transform, - overlay.state.curvature.as_ref(), - ) { - if hit.dist.is_infinite() || hit.dist.is_nan() { - continue; - } - hits.push(hit); - } - } - - hits.sort_by(|a, b| a.dist.total_cmp(&b.dist)); - - for hit in &hits { - let overlay = overlays.get_by_id(hit.overlay).unwrap(); // safe because we just got the id from the overlay - - let uv = overlay - .state - .interaction_transform - .transform_point2(hit.local_pos); - - if uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0 { - continue; - } - - return Some(PointerHit { - pointer: self.idx, - overlay: hit.overlay, - mode: self.interaction.mode, - primary: false, - uv, - dist: hit.dist, - }); - } - - None - } - - fn start_grab(&mut self, overlay: &mut OverlayData, tasks: &mut TaskContainer) - where - O: Default, - { - let offset = self - .pose - .inverse() - .transform_point3a(overlay.state.transform.translation); - - self.interaction.grabbed = Some(GrabData { - offset, - grabbed_id: overlay.state.id, - old_curvature: overlay.state.curvature, - grab_all: matches!(self.interaction.mode, PointerMode::Right), - }); - overlay.state.positioning = match overlay.state.positioning { - Positioning::FollowHand { hand, lerp } => Positioning::FollowHandPaused { hand, lerp }, - Positioning::FollowHead { lerp } => Positioning::FollowHeadPaused { lerp }, - x => x, - }; - - // Show anchor - tasks.enqueue(TaskType::Overlay( - OverlaySelector::Name(ANCHOR_NAME.clone()), - Box::new(|app, o| { - o.transform = app.anchor - * Affine3A::from_scale_rotation_translation( - Vec3::ONE * o.spawn_scale, - o.spawn_rotation, - o.spawn_point.into(), - ); - o.dirty = true; - o.want_visible = true; - }), - )); - log::info!("Hand {}: grabbed {}", self.idx, overlay.state.name); - } - - fn handle_grabbed(idx: usize, overlay: &mut OverlayData, app: &mut AppState) - where - O: Default, - { - let mut pointer = &mut app.input_state.pointers[idx]; - if pointer.now.grab { - if let Some(grab_data) = pointer.interaction.grabbed.as_mut() { - if pointer.now.click { - pointer.interaction.mode = PointerMode::Special; - let cur_scale = overlay.state.transform.x_axis.length(); - if cur_scale < 0.1 && pointer.now.scroll_y > 0.0 { - return; - } - if cur_scale > 20. && pointer.now.scroll_y < 0.0 { - return; - } - - overlay.state.transform.matrix3 = overlay - .state - .transform - .matrix3 - .mul_scalar(0.025f32.mul_add(-pointer.now.scroll_y, 1.0)); - } else if app.session.config.allow_sliding && pointer.now.scroll_y.is_finite() { - grab_data.offset.z -= pointer.now.scroll_y * 0.05; - } - overlay.state.transform.translation = - pointer.pose.transform_point3a(grab_data.offset); - overlay.state.realign(&app.input_state.hmd); - overlay.state.dirty = true; - } else { - log::error!("Grabbed overlay {} does not exist", overlay.state.id.0); - pointer.interaction.grabbed = None; - } - } else { - overlay.state.positioning = match overlay.state.positioning { - Positioning::FollowHandPaused { hand, lerp } => { - Positioning::FollowHand { hand, lerp } - } - Positioning::FollowHeadPaused { lerp } => Positioning::FollowHead { lerp }, - x => x, - }; - - let save_success = overlay.state.save_transform(app); - - // re-borrow - pointer = &mut app.input_state.pointers[idx]; - - if save_success { - if let Some(grab_data) = pointer.interaction.grabbed.as_ref() { - if overlay.state.curvature != grab_data.old_curvature { - if let Some(val) = overlay.state.curvature { - app.session - .config - .curve_values - .arc_set(overlay.state.name.clone(), val); - } else { - let ref_name = overlay.state.name.as_ref(); - app.session.config.curve_values.arc_rm(ref_name); - } - } - } - app.session.config.transform_values.arc_set( - overlay.state.name.clone(), - overlay.state.saved_transform.unwrap(), // safe - ); - } - - pointer.interaction.grabbed = None; - - // Hide anchor - app.tasks.enqueue(TaskType::Overlay( - OverlaySelector::Name(ANCHOR_NAME.clone()), - Box::new(|_app, o| { - o.want_visible = false; - }), - )); - log::info!("Hand {}: dropped {}", idx, overlay.state.name); - } - } - - fn ray_test( - &self, - overlay: OverlayID, - transform: &Affine3A, - curvature: Option<&f32>, - ) -> Option { - let (dist, local_pos) = curvature.map_or_else( - || { - Some(raycast_plane( - &self.pose, - Vec3A::NEG_Z, - transform, - Vec3A::NEG_Z, - )) - }, - |curvature| raycast_cylinder(&self.pose, Vec3A::NEG_Z, transform, *curvature), - )?; - - if dist < 0.0 { - // hit is behind us - return None; - } - - Some(RayHit { - overlay, - global_pos: self.pose.transform_point3a(Vec3A::NEG_Z * dist), - local_pos, - dist, - }) - } -} - -fn raycast_plane( - source: &Affine3A, - source_fwd: Vec3A, - plane: &Affine3A, - plane_norm: Vec3A, -) -> (f32, Vec2) { - let plane_normal = plane.transform_vector3a(plane_norm); - let ray_dir = source.transform_vector3a(source_fwd); - - let d = plane.translation.dot(-plane_normal); - let dist = -(d + source.translation.dot(plane_normal)) / ray_dir.dot(plane_normal); - - let hit_local = plane - .inverse() - .transform_point3a(source.translation + ray_dir * dist) - .xy(); - - (dist, hit_local) -} - -fn raycast_cylinder( - source: &Affine3A, - source_fwd: Vec3A, - plane: &Affine3A, - curvature: f32, -) -> Option<(f32, Vec2)> { - // this is solved locally; (0,0) is the center of the cylinder, and the cylinder is aligned with the Y axis - let size = plane.x_axis.length(); - let to_local = Affine3A { - matrix3: plane.matrix3.mul_scalar(1.0 / size), - translation: plane.translation, - } - .inverse(); - - let radius = size / (2.0 * PI * curvature); - - let ray_dir = to_local.transform_vector3a(source.transform_vector3a(source_fwd)); - let ray_origin = to_local.transform_point3a(source.translation) + Vec3A::NEG_Z * radius; - - let v_dir = ray_dir.xz(); - let v_pos = ray_origin.xz(); - - let l_dir = v_dir.dot(v_dir); - let l_pos = v_dir.dot(v_pos); - let c = radius.mul_add(-radius, v_pos.dot(v_pos)); - - let d = l_pos.mul_add(l_pos, -(l_dir * c)); - if d < f32::EPSILON { - return None; - } - - let sqrt_d = d.sqrt(); - - let t1 = (-l_pos - sqrt_d) / l_dir; - let t2 = (-l_pos + sqrt_d) / l_dir; - - let t = t1.max(t2); - - if t < f32::EPSILON { - return None; - } - - let mut hit_local = ray_origin + ray_dir * t; - if hit_local.z > 0.0 { - // hitting the opposite half of the cylinder - return None; - } - - let max_angle = 2.0 * (size / (2.0 * radius)); - let x_angle = (hit_local.x / radius).asin(); - - hit_local.x = x_angle / max_angle; - hit_local.y /= size; - - Some((t, hit_local.xy())) -} diff --git a/src/backend/mod.rs b/src/backend/mod.rs deleted file mode 100644 index fa5397a..0000000 --- a/src/backend/mod.rs +++ /dev/null @@ -1,25 +0,0 @@ -pub mod common; -pub mod input; -pub mod notifications; - -#[allow(clippy::all)] -mod notifications_dbus; - -#[cfg(feature = "openvr")] -pub mod openvr; - -#[cfg(feature = "openxr")] -pub mod openxr; - -#[cfg(feature = "uidev")] -pub mod uidev; - -#[cfg(feature = "osc")] -pub mod osc; - -#[cfg(feature = "wayvr")] -pub mod wayvr; - -pub mod overlay; - -pub mod task; diff --git a/src/backend/openvr/lines.rs b/src/backend/openvr/lines.rs deleted file mode 100644 index 1c590e6..0000000 --- a/src/backend/openvr/lines.rs +++ /dev/null @@ -1,203 +0,0 @@ -use std::f32::consts::PI; -use std::sync::atomic::{AtomicUsize, Ordering}; -use std::sync::Arc; - -use glam::{Affine3A, Vec3, Vec3A, Vec4}; -use idmap::IdMap; -use ovr_overlay::overlay::OverlayManager; -use ovr_overlay::sys::ETrackingUniverseOrigin; -use vulkano::command_buffer::CommandBufferUsage; -use vulkano::format::Format; -use vulkano::image::view::ImageView; -use vulkano::image::ImageLayout; - -use crate::backend::overlay::{ - FrameMeta, OverlayData, OverlayRenderer, OverlayState, ShouldRender, SplitOverlayBackend, - Z_ORDER_LINES, -}; -use crate::graphics::{CommandBuffers, WlxGraphics}; -use crate::state::AppState; - -use super::overlay::OpenVrOverlayData; - -static LINE_AUTO_INCREMENT: AtomicUsize = AtomicUsize::new(1); - -pub(super) struct LinePool { - lines: IdMap>, - view: Arc, - colors: [Vec4; 5], -} - -impl LinePool { - pub fn new(graphics: Arc) -> anyhow::Result { - let mut command_buffer = graphics.create_uploads_command_buffer( - graphics.transfer_queue.clone(), - CommandBufferUsage::OneTimeSubmit, - )?; - - let buf = vec![255; 16]; - - let texture = command_buffer.texture2d_raw(2, 2, Format::R8G8B8A8_UNORM, &buf)?; - command_buffer.build_and_execute_now()?; - - graphics - .transition_layout( - texture.clone(), - ImageLayout::ShaderReadOnlyOptimal, - ImageLayout::TransferSrcOptimal, - )? - .wait(None)?; - - let view = ImageView::new_default(texture)?; - - Ok(Self { - lines: IdMap::new(), - view, - colors: [ - Vec4::new(1., 1., 1., 1.), - Vec4::new(0., 0.375, 0.5, 1.), - Vec4::new(0.69, 0.188, 0., 1.), - Vec4::new(0.375, 0., 0.5, 1.), - Vec4::new(1., 0., 0., 1.), - ], - }) - } - - pub fn allocate(&mut self) -> usize { - let id = LINE_AUTO_INCREMENT.fetch_add(1, Ordering::Relaxed); - - let mut data = OverlayData:: { - state: OverlayState { - name: Arc::from(format!("wlx-line{id}")), - show_hide: true, - ..Default::default() - }, - backend: Box::new(SplitOverlayBackend { - renderer: Box::new(StaticRenderer { - view: self.view.clone(), - }), - ..Default::default() - }), - data: OpenVrOverlayData { - width: 0.002, - override_width: true, - image_view: Some(self.view.clone()), - image_dirty: true, - ..Default::default() - }, - ..Default::default() - }; - data.state.z_order = Z_ORDER_LINES; - data.state.dirty = true; - - self.lines.insert(id, data); - id - } - - pub fn draw_from( - &mut self, - id: usize, - mut from: Affine3A, - len: f32, - color: usize, - hmd: &Affine3A, - ) { - let rotation = Affine3A::from_axis_angle(Vec3::X, -PI * 0.5); - - from.translation += from.transform_vector3a(Vec3A::NEG_Z) * (len * 0.5); - let mut transform = from * rotation * Affine3A::from_scale(Vec3::new(1., len / 0.002, 1.)); - - let to_hmd = hmd.translation - from.translation; - let sides = [Vec3A::Z, Vec3A::X, Vec3A::NEG_Z, Vec3A::NEG_X]; - let rotations = [ - Affine3A::IDENTITY, - Affine3A::from_axis_angle(Vec3::Y, PI * 0.5), - Affine3A::from_axis_angle(Vec3::Y, PI * 1.0), - Affine3A::from_axis_angle(Vec3::Y, PI * 1.5), - ]; - let mut closest = (0, 0.0); - for (i, &side) in sides.iter().enumerate() { - let dot = to_hmd.dot(transform.transform_vector3a(side)); - if i == 0 || dot > closest.1 { - closest = (i, dot); - } - } - - transform *= rotations[closest.0]; - - debug_assert!(color < self.colors.len()); - - self.draw_transform(id, transform, self.colors[color]); - } - - fn draw_transform(&mut self, id: usize, transform: Affine3A, color: Vec4) { - if let Some(data) = self.lines.get_mut(id) { - data.state.want_visible = true; - data.state.transform = transform; - data.data.color = color; - } else { - log::warn!("Line {id} does not exist"); - } - } - - pub fn update( - &mut self, - universe: ETrackingUniverseOrigin, - overlay: &mut OverlayManager, - app: &mut AppState, - ) -> anyhow::Result<()> { - for data in self.lines.values_mut() { - data.after_input(overlay, app)?; - if data.state.want_visible { - if data.state.dirty { - data.upload_texture(overlay, &app.graphics); - data.state.dirty = false; - } - - data.upload_transform(universe.clone(), overlay); - data.upload_color(overlay); - } - } - Ok(()) - } - - pub fn mark_dirty(&mut self) { - for data in self.lines.values_mut() { - data.state.dirty = true; - } - } -} - -struct StaticRenderer { - view: Arc, -} - -impl OverlayRenderer for StaticRenderer { - fn init(&mut self, _app: &mut AppState) -> anyhow::Result<()> { - Ok(()) - } - fn pause(&mut self, _app: &mut AppState) -> anyhow::Result<()> { - Ok(()) - } - fn resume(&mut self, _app: &mut AppState) -> anyhow::Result<()> { - Ok(()) - } - fn should_render(&mut self, _app: &mut AppState) -> anyhow::Result { - Ok(ShouldRender::Unable) - } - fn render( - &mut self, - _app: &mut AppState, - _tgt: Arc, - _buf: &mut CommandBuffers, - _alpha: f32, - ) -> anyhow::Result { - Ok(false) - } - fn frame_meta(&mut self) -> Option { - Some(FrameMeta { - extent: self.view.image().extent(), - ..Default::default() - }) - } -} diff --git a/src/backend/overlay.rs b/src/backend/overlay.rs deleted file mode 100644 index d96614e..0000000 --- a/src/backend/overlay.rs +++ /dev/null @@ -1,462 +0,0 @@ -use std::{ - f32::consts::PI, - sync::{ - atomic::{AtomicUsize, Ordering}, - Arc, - }, -}; - -use anyhow::Ok; -use glam::{Affine2, Affine3A, Mat3A, Quat, Vec2, Vec3, Vec3A}; -use serde::Deserialize; -use vulkano::{format::Format, image::view::ImageView}; - -use crate::{ - config::AStrMapExt, - graphics::CommandBuffers, - state::{AppState, KeyboardFocus}, -}; - -use super::{ - common::snap_upright, - input::{DummyInteractionHandler, Haptics, InteractionHandler, PointerHit}, -}; - -static OVERLAY_AUTO_INCREMENT: AtomicUsize = AtomicUsize::new(0); - -pub trait OverlayBackend: OverlayRenderer + InteractionHandler { - fn set_renderer(&mut self, renderer: Box); - fn set_interaction(&mut self, interaction: Box); -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Default)] -pub struct OverlayID(pub usize); - -pub const Z_ORDER_TOAST: u32 = 70; -pub const Z_ORDER_LINES: u32 = 69; -pub const Z_ORDER_WATCH: u32 = 68; -pub const Z_ORDER_ANCHOR: u32 = 67; -pub const Z_ORDER_DEFAULT: u32 = 0; -pub const Z_ORDER_DASHBOARD: u32 = Z_ORDER_DEFAULT; - -pub struct OverlayState { - pub id: OverlayID, - pub name: Arc, - pub want_visible: bool, - pub show_hide: bool, - pub grabbable: bool, - pub interactable: bool, - pub recenter: bool, - pub keyboard_focus: Option, - pub dirty: bool, - pub alpha: f32, - pub z_order: u32, - pub transform: Affine3A, - pub spawn_scale: f32, // aka width - pub spawn_point: Vec3A, - pub spawn_rotation: Quat, - pub saved_transform: Option, - pub positioning: Positioning, - pub curvature: Option, - pub interaction_transform: Affine2, - pub birthframe: usize, -} - -impl Default for OverlayState { - fn default() -> Self { - Self { - id: OverlayID(OVERLAY_AUTO_INCREMENT.fetch_add(1, Ordering::Relaxed)), - name: Arc::from(""), - want_visible: false, - show_hide: false, - grabbable: false, - recenter: false, - interactable: false, - keyboard_focus: None, - dirty: true, - alpha: 1.0, - z_order: Z_ORDER_DEFAULT, - positioning: Positioning::Floating, - curvature: None, - spawn_scale: 1.0, - spawn_point: Vec3A::NEG_Z, - spawn_rotation: Quat::IDENTITY, - saved_transform: None, - transform: Affine3A::IDENTITY, - interaction_transform: Affine2::IDENTITY, - birthframe: 0, - } - } -} - -pub struct OverlayData -where - T: Default, -{ - pub state: OverlayState, - pub backend: Box, - pub primary_pointer: Option, - pub data: T, -} - -impl Default for OverlayData -where - T: Default, -{ - fn default() -> Self { - Self { - state: OverlayState::default(), - backend: Box::::default(), - primary_pointer: None, - data: Default::default(), - } - } -} - -impl OverlayState { - fn get_transform(&self) -> Affine3A { - self.saved_transform.unwrap_or_else(|| { - Affine3A::from_scale_rotation_translation( - Vec3::ONE * self.spawn_scale, - self.spawn_rotation, - self.spawn_point.into(), - ) - }) - } - - pub fn auto_movement(&mut self, app: &mut AppState) { - let (target_transform, lerp) = match self.positioning { - Positioning::FollowHead { lerp } => (app.input_state.hmd * self.get_transform(), lerp), - Positioning::FollowHand { hand, lerp } => ( - app.input_state.pointers[hand].pose * self.get_transform(), - lerp, - ), - _ => return, - }; - - self.transform = match lerp { - 1.0 => target_transform, - lerp => { - let scale = target_transform.matrix3.x_axis.length(); - - let rot_from = Quat::from_mat3a(&self.transform.matrix3.div_scalar(scale)); - let rot_to = Quat::from_mat3a(&target_transform.matrix3.div_scalar(scale)); - - let rotation = rot_from.slerp(rot_to, lerp); - let translation = self - .transform - .translation - .slerp(target_transform.translation, lerp); - - Affine3A::from_scale_rotation_translation( - Vec3::ONE * scale, - rotation, - translation.into(), - ) - } - }; - - self.dirty = true; - } - - pub fn reset(&mut self, app: &mut AppState, hard_reset: bool) { - let parent_transform = match self.positioning { - Positioning::Floating - | Positioning::FollowHead { .. } - | Positioning::FollowHeadPaused { .. } => app.input_state.hmd, - Positioning::FollowHand { hand, .. } | Positioning::FollowHandPaused { hand, .. } => { - app.input_state.pointers[hand].pose - } - Positioning::Anchored => app.anchor, - Positioning::Static => return, - }; - - if hard_reset { - self.saved_transform = None; - } - - self.transform = parent_transform * self.get_transform(); - - if self.grabbable && hard_reset { - self.realign(&app.input_state.hmd); - } - self.dirty = true; - } - - pub fn save_transform(&mut self, app: &mut AppState) -> bool { - let parent_transform = match self.positioning { - Positioning::Floating => snap_upright(app.input_state.hmd, Vec3A::Y), - Positioning::FollowHead { .. } | Positioning::FollowHeadPaused { .. } => { - app.input_state.hmd - } - Positioning::FollowHand { hand, .. } | Positioning::FollowHandPaused { hand, .. } => { - app.input_state.pointers[hand].pose - } - Positioning::Anchored => snap_upright(app.anchor, Vec3A::Y), - Positioning::Static => return false, - }; - - self.saved_transform = Some(parent_transform.inverse() * self.transform); - - true - } - - pub fn realign(&mut self, hmd: &Affine3A) { - let to_hmd = hmd.translation - self.transform.translation; - let up_dir: Vec3A; - - if hmd.x_axis.dot(Vec3A::Y).abs() > 0.2 { - // Snap upright - up_dir = hmd.y_axis; - } else { - let dot = to_hmd.normalize().dot(hmd.z_axis); - let z_dist = to_hmd.length(); - let y_dist = (self.transform.translation.y - hmd.translation.y).abs(); - let x_angle = (y_dist / z_dist).asin(); - - if dot < -f32::EPSILON { - // facing down - let up_point = hmd.translation + z_dist / x_angle.cos() * Vec3A::Y; - up_dir = (up_point - self.transform.translation).normalize(); - } else if dot > f32::EPSILON { - // facing up - let dn_point = hmd.translation + z_dist / x_angle.cos() * Vec3A::NEG_Y; - up_dir = (self.transform.translation - dn_point).normalize(); - } else { - // perfectly upright - up_dir = Vec3A::Y; - } - } - - let scale = self.transform.x_axis.length(); - - let col_z = (self.transform.translation - hmd.translation).normalize(); - let col_y = up_dir; - let col_x = col_y.cross(col_z); - let col_y = col_z.cross(col_x).normalize(); - let col_x = col_x.normalize(); - - let rot = Mat3A::from_quat(self.spawn_rotation) - * Mat3A::from_quat(Quat::from_axis_angle(Vec3::Y, PI)); - self.transform.matrix3 = Mat3A::from_cols(col_x, col_y, col_z).mul_scalar(scale) * rot; - } -} - -impl OverlayData -where - T: Default, -{ - pub fn init(&mut self, app: &mut AppState) -> anyhow::Result<()> { - if self.state.curvature.is_none() { - self.state.curvature = app - .session - .config - .curve_values - .arc_get(self.state.name.as_ref()) - .copied(); - } - - if matches!( - self.state.positioning, - Positioning::Floating | Positioning::Anchored - ) { - let hard_reset; - if let Some(transform) = app - .session - .config - .transform_values - .arc_get(self.state.name.as_ref()) - { - self.state.saved_transform = Some(*transform); - hard_reset = false; - } else { - hard_reset = true; - } - self.state.reset(app, hard_reset); - } - self.backend.init(app) - } - pub fn should_render(&mut self, app: &mut AppState) -> anyhow::Result { - self.backend.should_render(app) - } - pub fn render( - &mut self, - app: &mut AppState, - tgt: Arc, - buf: &mut CommandBuffers, - alpha: f32, - ) -> anyhow::Result { - self.backend.render(app, tgt, buf, alpha) - } - pub fn frame_meta(&mut self) -> Option { - self.backend.frame_meta() - } -} - -#[derive(Default, Clone, Copy)] -pub struct FrameMeta { - pub extent: [u32; 3], - pub transform: Affine3A, - pub format: Format, -} - -pub enum ShouldRender { - Should, - Can, - Unable, -} - -pub trait OverlayRenderer { - /// Called once, before the first frame is rendered - fn init(&mut self, app: &mut AppState) -> anyhow::Result<()>; - fn pause(&mut self, app: &mut AppState) -> anyhow::Result<()>; - fn resume(&mut self, app: &mut AppState) -> anyhow::Result<()>; - - /// Called when the presentation layer is ready to present a new frame - fn should_render(&mut self, app: &mut AppState) -> anyhow::Result; - - /// Called when the contents need to be rendered to the swapchain - fn render( - &mut self, - app: &mut AppState, - tgt: Arc, - buf: &mut CommandBuffers, - alpha: f32, - ) -> anyhow::Result; - - /// Called to retrieve the effective extent of the image - /// Used for creating swapchains. - /// - /// Must be true if should_render was also true on the same frame. - fn frame_meta(&mut self) -> Option; -} - -pub struct FallbackRenderer; - -impl OverlayRenderer for FallbackRenderer { - fn init(&mut self, _app: &mut AppState) -> anyhow::Result<()> { - Ok(()) - } - fn pause(&mut self, _app: &mut AppState) -> anyhow::Result<()> { - Ok(()) - } - fn resume(&mut self, _app: &mut AppState) -> anyhow::Result<()> { - Ok(()) - } - fn should_render(&mut self, _app: &mut AppState) -> anyhow::Result { - Ok(ShouldRender::Unable) - } - fn render( - &mut self, - _app: &mut AppState, - _tgt: Arc, - _buf: &mut CommandBuffers, - _alpha: f32, - ) -> anyhow::Result { - Ok(false) - } - fn frame_meta(&mut self) -> Option { - None - } -} -// Boilerplate and dummies - -#[derive(Clone, Copy, Debug, Default)] -pub enum Positioning { - /// Stays in place unless recentered, recenters relative to HMD - #[default] - Floating, - /// Stays in place unless recentered, recenters relative to anchor - Anchored, - /// Following HMD - FollowHead { lerp: f32 }, - /// Normally follows HMD, but paused due to interaction - FollowHeadPaused { lerp: f32 }, - /// Following hand - FollowHand { hand: usize, lerp: f32 }, - /// Normally follows hand, but paused due to interaction - FollowHandPaused { hand: usize, lerp: f32 }, - /// Stays in place, no recentering - Static, -} - -pub struct SplitOverlayBackend { - pub renderer: Box, - pub interaction: Box, -} - -impl Default for SplitOverlayBackend { - fn default() -> Self { - Self { - renderer: Box::new(FallbackRenderer), - interaction: Box::new(DummyInteractionHandler), - } - } -} - -impl OverlayBackend for SplitOverlayBackend { - fn set_renderer(&mut self, renderer: Box) { - self.renderer = renderer; - } - fn set_interaction(&mut self, interaction: Box) { - self.interaction = interaction; - } -} -impl OverlayRenderer for SplitOverlayBackend { - fn init(&mut self, app: &mut AppState) -> anyhow::Result<()> { - self.renderer.init(app) - } - fn pause(&mut self, app: &mut AppState) -> anyhow::Result<()> { - self.renderer.pause(app) - } - fn resume(&mut self, app: &mut AppState) -> anyhow::Result<()> { - self.renderer.resume(app) - } - fn should_render(&mut self, app: &mut AppState) -> anyhow::Result { - self.renderer.should_render(app) - } - fn render( - &mut self, - app: &mut AppState, - tgt: Arc, - buf: &mut CommandBuffers, - alpha: f32, - ) -> anyhow::Result { - self.renderer.render(app, tgt, buf, alpha) - } - fn frame_meta(&mut self) -> Option { - self.renderer.frame_meta() - } -} - -impl InteractionHandler for SplitOverlayBackend { - fn on_left(&mut self, app: &mut AppState, pointer: usize) { - self.interaction.on_left(app, pointer); - } - fn on_hover(&mut self, app: &mut AppState, hit: &PointerHit) -> Option { - self.interaction.on_hover(app, hit) - } - fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta_y: f32, delta_x: f32) { - self.interaction.on_scroll(app, hit, delta_y, delta_x); - } - fn on_pointer(&mut self, app: &mut AppState, hit: &PointerHit, pressed: bool) { - self.interaction.on_pointer(app, hit, pressed); - } -} - -pub fn ui_transform(extent: [u32; 2]) -> Affine2 { - let aspect = extent[0] as f32 / extent[1] as f32; - let scale = if aspect < 1.0 { - Vec2 { - x: 1.0 / aspect, - y: -1.0, - } - } else { - Vec2 { - x: 1.0, - y: -1.0 * aspect, - } - }; - let center = Vec2 { x: 0.5, y: 0.5 }; - Affine2::from_scale_angle_translation(scale, 0.0, center) -} diff --git a/src/backend/uidev/mod.rs b/src/backend/uidev/mod.rs deleted file mode 100644 index 5b62804..0000000 --- a/src/backend/uidev/mod.rs +++ /dev/null @@ -1,289 +0,0 @@ -use std::sync::Arc; - -use vulkano::{ - image::{view::ImageView, ImageUsage}, - swapchain::{ - acquire_next_image, Surface, SurfaceInfo, Swapchain, SwapchainCreateInfo, - SwapchainPresentInfo, - }, - sync::GpuFuture, - Validated, VulkanError, -}; -use winit::{ - dpi::LogicalSize, - event::{Event, WindowEvent}, - event_loop::ControlFlow, - window::Window, -}; - -use crate::{ - config::load_custom_ui, - config_io, - graphics::{CommandBuffers, WlxGraphics}, - gui::{ - canvas::Canvas, - modular::{modular_canvas, ModularData}, - }, - hid::USE_UINPUT, - state::{AppState, ScreenMeta}, -}; - -use super::{ - input::{TrackedDevice, TrackedDeviceRole}, - overlay::{OverlayID, OverlayRenderer}, -}; - -static LAST_SIZE: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0); - -struct PreviewState { - canvas: Canvas<(), ModularData>, - swapchain: Arc, - images: Vec>, -} - -impl PreviewState { - fn new( - state: &mut AppState, - surface: Arc, - window: Arc, - panel_name: &str, - ) -> anyhow::Result { - let config = load_custom_ui(panel_name)?; - - let last_size = { - let size_u64 = LAST_SIZE.load(std::sync::atomic::Ordering::Relaxed); - [size_u64 as u32, (size_u64 >> 32) as u32] - }; - - if last_size != config.size { - let logical_size = LogicalSize::new(config.size[0], config.size[1]); - let _ = window.request_inner_size(logical_size); - window.set_min_inner_size(Some(logical_size)); - window.set_max_inner_size(Some(logical_size)); - LAST_SIZE.store( - ((config.size[1] as u64) << 32) | config.size[0] as u64, - std::sync::atomic::Ordering::Relaxed, - ); - } - - let inner_size = window.inner_size(); - let swapchain_size = [inner_size.width, inner_size.height]; - let (swapchain, images) = create_swapchain(&state.graphics, surface, swapchain_size)?; - - let mut canvas = modular_canvas(config.size, &config.elements, state)?; - canvas.init(state)?; - - Ok(Self { - canvas, - swapchain, - images, - }) - } -} - -#[allow(clippy::too_many_lines)] -pub fn uidev_run(panel_name: &str) -> anyhow::Result<()> { - let (graphics, event_loop, window, surface) = WlxGraphics::new_window()?; - window.set_resizable(false); - window.set_title("WlxOverlay UI Preview"); - - USE_UINPUT.store(false, std::sync::atomic::Ordering::Relaxed); - - let mut state = AppState::from_graphics(graphics.clone())?; - add_dummy_devices(&mut state); - add_dummy_screens(&mut state); - - let mut preview = Some(PreviewState::new( - &mut state, - surface.clone(), - window.clone(), - panel_name, - )?); - - let watch_path = config_io::get_config_root().join(format!("{panel_name}.yaml")); - let mut path_last_modified = watch_path.metadata()?.modified()?; - let mut recreate = false; - let mut last_draw = std::time::Instant::now(); - - #[allow(deprecated)] - event_loop.run(move |event, elwt| { - elwt.set_control_flow(ControlFlow::Poll); - - match event { - Event::WindowEvent { - event: WindowEvent::CloseRequested, - .. - } => { - elwt.exit(); - } - Event::WindowEvent { - event: WindowEvent::Resized(_), - .. - } => { - recreate = true; - } - Event::WindowEvent { - event: WindowEvent::RedrawRequested, - .. - } => { - let new_modified = watch_path.metadata().unwrap().modified().unwrap(); - if new_modified > path_last_modified { - recreate = true; - path_last_modified = new_modified; - } - - if recreate { - drop(preview.take()); - preview = Some( - PreviewState::new(&mut state, surface.clone(), window.clone(), panel_name) - .unwrap(), - ); - recreate = false; - window.request_redraw(); - } - - { - let preview = preview.as_mut().unwrap(); - let (image_index, _, acquire_future) = - match acquire_next_image(preview.swapchain.clone(), None) - .map_err(Validated::unwrap) - { - Ok(r) => r, - Err(VulkanError::OutOfDate) => { - recreate = true; - return; - } - Err(e) => panic!("failed to acquire next image: {e}"), - }; - - let mut canvas_cmd_buf = CommandBuffers::default(); - let tgt = preview.images[image_index as usize].clone(); - - if let Err(e) = preview - .canvas - .render(&mut state, tgt, &mut canvas_cmd_buf, 1.0) - { - log::error!("failed to render canvas: {e}"); - window.request_redraw(); - } - - last_draw = std::time::Instant::now(); - - canvas_cmd_buf - .execute_after( - state.graphics.graphics_queue.clone(), - Box::new(acquire_future), - ) - .unwrap() - .then_swapchain_present( - graphics.graphics_queue.clone(), - SwapchainPresentInfo::swapchain_image_index( - preview.swapchain.clone(), - image_index, - ), - ) - .then_signal_fence_and_flush() - .unwrap() - .wait(None) - .unwrap(); - } - } - Event::AboutToWait => { - if last_draw.elapsed().as_millis() > 100 { - window.request_redraw(); - } - } - _ => (), - } - })?; - - Ok(()) -} - -fn create_swapchain( - graphics: &WlxGraphics, - surface: Arc, - extent: [u32; 2], -) -> anyhow::Result<(Arc, Vec>)> { - let surface_capabilities = graphics - .device - .physical_device() - .surface_capabilities(&surface, SurfaceInfo::default()) - .unwrap(); // want panic - - let (swapchain, images) = Swapchain::new( - graphics.device.clone(), - surface, - SwapchainCreateInfo { - min_image_count: surface_capabilities.min_image_count.max(2), - image_format: graphics.native_format, - image_extent: extent, - image_usage: ImageUsage::COLOR_ATTACHMENT, - composite_alpha: surface_capabilities - .supported_composite_alpha - .into_iter() - .next() - .unwrap(), // want panic - ..Default::default() - }, - )?; - - let image_views = images - .into_iter() - // want panic - .map(|image| ImageView::new_default(image).unwrap()) - .collect::>(); - - Ok((swapchain, image_views)) -} - -fn add_dummy_devices(app: &mut AppState) { - app.input_state.devices.push(TrackedDevice { - role: TrackedDeviceRole::Hmd, - soc: Some(0.42), - charging: true, - }); - app.input_state.devices.push(TrackedDevice { - role: TrackedDeviceRole::LeftHand, - soc: Some(0.72), - charging: false, - }); - app.input_state.devices.push(TrackedDevice { - role: TrackedDeviceRole::RightHand, - soc: Some(0.73), - charging: false, - }); - app.input_state.devices.push(TrackedDevice { - role: TrackedDeviceRole::Tracker, - soc: Some(0.65), - charging: false, - }); - app.input_state.devices.push(TrackedDevice { - role: TrackedDeviceRole::Tracker, - soc: Some(0.67), - charging: false, - }); - app.input_state.devices.push(TrackedDevice { - role: TrackedDeviceRole::Tracker, - soc: Some(0.69), - charging: false, - }); -} - -fn add_dummy_screens(app: &mut AppState) { - app.screens.push(ScreenMeta { - name: "HDMI-A-1".into(), - id: OverlayID(0), - native_handle: 0, - }); - app.screens.push(ScreenMeta { - name: "DP-2".into(), - id: OverlayID(0), - native_handle: 0, - }); - app.screens.push(ScreenMeta { - name: "DP-3".into(), - id: OverlayID(0), - native_handle: 0, - }); -} diff --git a/src/config.rs b/src/config.rs deleted file mode 100644 index 8a94a2d..0000000 --- a/src/config.rs +++ /dev/null @@ -1,521 +0,0 @@ -use std::path::PathBuf; -use std::sync::Arc; - -use crate::config_io; -use crate::gui::modular::ModularUiConfig; -use crate::overlays::toast::DisplayMethod; -use crate::overlays::toast::ToastTopic; -use crate::state::LeftRight; -use anyhow::bail; -use chrono::Offset; -use config::Config; -use config::File; -use glam::vec3a; -use glam::Affine3A; -use glam::Quat; -use glam::Vec3A; -use idmap::IdMap; -use log::error; -use serde::Deserialize; -use serde::Serialize; - -pub type AStrMap = Vec<(Arc, V)>; - -pub trait AStrMapExt { - fn arc_set(&mut self, key: Arc, value: V) -> bool; - fn arc_get(&self, key: &str) -> Option<&V>; - fn arc_rm(&mut self, key: &str) -> Option; -} - -impl AStrMapExt for AStrMap { - fn arc_set(&mut self, key: Arc