omg big commit
This commit is contained in:
110
Cargo.lock
generated
110
Cargo.lock
generated
@@ -26,9 +26,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ahash"
|
name = "ahash"
|
||||||
version = "0.8.8"
|
version = "0.8.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42cd52102d3df161c77a887b608d7a4897d7cc112886a9537b738a887a03aaff"
|
checksum = "d713b3834d76b85304d4d525563c1276e2e30dc97cc67bfb4585a4a29fc2c89f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"getrandom",
|
"getrandom",
|
||||||
@@ -350,7 +350,7 @@ checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -385,7 +385,7 @@ checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -443,7 +443,7 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"shlex",
|
"shlex",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
"which",
|
"which",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -456,7 +456,7 @@ dependencies = [
|
|||||||
"autocxx-engine",
|
"autocxx-engine",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"indexmap 1.9.3",
|
"indexmap 1.9.3",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -483,7 +483,7 @@ dependencies = [
|
|||||||
"rustversion",
|
"rustversion",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"strum_macros 0.24.3",
|
"strum_macros 0.24.3",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"version_check",
|
"version_check",
|
||||||
@@ -499,7 +499,7 @@ dependencies = [
|
|||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -516,7 +516,7 @@ dependencies = [
|
|||||||
"quote",
|
"quote",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -537,7 +537,7 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"shlex",
|
"shlex",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -557,7 +557,7 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"shlex",
|
"shlex",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -645,7 +645,7 @@ checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1051,9 +1051,9 @@ checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx"
|
name = "cxx"
|
||||||
version = "1.0.116"
|
version = "1.0.117"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8aff472b83efd22bfc0176aa8ba34617dd5c17364670eb201a5f06d339b8abf7"
|
checksum = "0c15f3b597018782655a05d417f28bac009f6eb60f4b6703eb818998c1aaa16a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"cxxbridge-flags",
|
"cxxbridge-flags",
|
||||||
@@ -1063,31 +1063,31 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx-gen"
|
name = "cxx-gen"
|
||||||
version = "0.7.116"
|
version = "0.7.117"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a2a39f7064dacffa9bf2d33d8dcc7777b60c789a95e1cd62d5fbeb1161428f2"
|
checksum = "54b629c0d006c7e44c1444dd17d18a458c9390d32276b758ac7abd21a75c99b0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"codespan-reporting",
|
"codespan-reporting",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxxbridge-flags"
|
name = "cxxbridge-flags"
|
||||||
version = "1.0.116"
|
version = "1.0.117"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "589e83d02fc1d4fb78f5ad56ca08835341e23499d086d2821315869426d618dc"
|
checksum = "7a7eb4c4fd18505f5a935f9c2ee77780350dcdb56da7cd037634e806141c5c43"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxxbridge-macro"
|
name = "cxxbridge-macro"
|
||||||
version = "1.0.116"
|
version = "1.0.117"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2cb1fd8ffae4230c7cfbbaf3698dbeaf750fa8c5dadf7ed897df581b9b572a5"
|
checksum = "5d914fcc6452d133236ee067a9538be25ba6a644a450e1a6c617da84bf029854"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1110,7 +1110,7 @@ dependencies = [
|
|||||||
"ident_case",
|
"ident_case",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1121,7 +1121,7 @@ checksum = "c5a91391accf613803c2a9bf9abccdbaa07c54b4244a5b64883f9c3c137c86be"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"darling_core",
|
"darling_core",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1215,7 +1215,7 @@ checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1236,7 +1236,7 @@ dependencies = [
|
|||||||
"darling",
|
"darling",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1419,7 +1419,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1542,7 +1542,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2159,7 +2159,7 @@ checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2375,7 +2375,7 @@ dependencies = [
|
|||||||
"proc-macro-crate 2.0.2",
|
"proc-macro-crate 2.0.2",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2482,7 +2482,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ovr_overlay"
|
name = "ovr_overlay"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
source = "git+https://github.com/galister/ovr_overlay_oyasumi#e719339c017f36f090cb2ba87240580e9dff3b15"
|
source = "git+https://github.com/galister/ovr_overlay_oyasumi#c9794ab4439242fbaa908a2c625ed47fcf173508"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
@@ -2497,7 +2497,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ovr_overlay_sys"
|
name = "ovr_overlay_sys"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
source = "git+https://github.com/galister/ovr_overlay_oyasumi#e719339c017f36f090cb2ba87240580e9dff3b15"
|
source = "git+https://github.com/galister/ovr_overlay_oyasumi#c9794ab4439242fbaa908a2c625ed47fcf173508"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocxx",
|
"autocxx",
|
||||||
"autocxx-build",
|
"autocxx-build",
|
||||||
@@ -2715,7 +2715,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5"
|
checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3042,29 +3042,29 @@ checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.196"
|
version = "1.0.197"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
|
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.196"
|
version = "1.0.197"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
|
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.113"
|
version = "1.0.114"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79"
|
checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
@@ -3079,7 +3079,7 @@ checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3305,7 +3305,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3321,9 +3321,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.49"
|
version = "2.0.50"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "915aea9e586f80826ee59f8453c1101f9d1c4b3964cd2460185ee8e299ada496"
|
checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -3387,7 +3387,7 @@ checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3504,7 +3504,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3553,9 +3553,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-normalization"
|
name = "unicode-normalization"
|
||||||
version = "0.1.22"
|
version = "0.1.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
|
checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"tinyvec",
|
"tinyvec",
|
||||||
]
|
]
|
||||||
@@ -3654,7 +3654,7 @@ dependencies = [
|
|||||||
"proc-macro-crate 2.0.2",
|
"proc-macro-crate 2.0.2",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3667,7 +3667,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"shaderc",
|
"shaderc",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
"vulkano",
|
"vulkano",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -3714,7 +3714,7 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -3748,7 +3748,7 @@ checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
"wasm-bindgen-backend",
|
"wasm-bindgen-backend",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
@@ -4292,8 +4292,8 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wlx-capture"
|
name = "wlx-capture"
|
||||||
version = "0.1.1"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/galister/wlx-capture#06a6ff48464fdda0f563a3b5858fcb69ea0f5980"
|
source = "git+https://github.com/galister/wlx-capture#b715303245197ea3bb7b8b5e348f5c26299e3c8a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ashpd",
|
"ashpd",
|
||||||
"drm-fourcc",
|
"drm-fourcc",
|
||||||
@@ -4554,7 +4554,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.49",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ use crate::{
|
|||||||
state::AppState,
|
state::AppState,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::overlay::{OverlayData, OverlayState};
|
use super::overlay::{OverlayBackend, OverlayData, OverlayState};
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum BackendError {
|
pub enum BackendError {
|
||||||
@@ -91,6 +91,22 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn drop_by_selector(&mut self, selector: &OverlaySelector) {
|
||||||
|
match selector {
|
||||||
|
OverlaySelector::Id(id) => {
|
||||||
|
self.overlays.remove(id);
|
||||||
|
}
|
||||||
|
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<'a>(&'a mut self, id: usize) -> Option<&'a OverlayData<T>> {
|
pub fn get_by_id<'a>(&'a mut self, id: usize) -> Option<&'a OverlayData<T>> {
|
||||||
self.overlays.get(&id)
|
self.overlays.get(&id)
|
||||||
}
|
}
|
||||||
@@ -115,6 +131,10 @@ where
|
|||||||
self.overlays.values_mut()
|
self.overlays.values_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add(&mut self, overlay: OverlayData<T>) {
|
||||||
|
self.overlays.insert(overlay.state.id, overlay);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn show_hide(&mut self, app: &mut AppState) {
|
pub fn show_hide(&mut self, app: &mut AppState) {
|
||||||
let any_shown = self
|
let any_shown = self
|
||||||
.overlays
|
.overlays
|
||||||
@@ -170,6 +190,11 @@ pub enum TaskType {
|
|||||||
OverlaySelector,
|
OverlaySelector,
|
||||||
Box<dyn FnOnce(&mut AppState, &mut OverlayState) + Send>,
|
Box<dyn FnOnce(&mut AppState, &mut OverlayState) + Send>,
|
||||||
),
|
),
|
||||||
|
CreateOverlay(
|
||||||
|
OverlaySelector,
|
||||||
|
Box<dyn FnOnce(&mut AppState) -> Option<(OverlayState, Box<dyn OverlayBackend>)> + Send>,
|
||||||
|
),
|
||||||
|
DropOverlay(OverlaySelector),
|
||||||
Toast(Toast),
|
Toast(Toast),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ impl LinePool {
|
|||||||
state: OverlayState {
|
state: OverlayState {
|
||||||
name: Arc::from(format!("wlx-line{}", id)),
|
name: Arc::from(format!("wlx-line{}", id)),
|
||||||
show_hide: true,
|
show_hide: true,
|
||||||
size: (0, 0),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
backend: Box::new(SplitOverlayBackend {
|
backend: Box::new(SplitOverlayBackend {
|
||||||
@@ -181,7 +180,4 @@ impl OverlayRenderer for StaticRenderer {
|
|||||||
fn view(&mut self) -> Option<Arc<ImageView>> {
|
fn view(&mut self) -> Option<Arc<ImageView>> {
|
||||||
Some(self.view.clone())
|
Some(self.view.clone())
|
||||||
}
|
}
|
||||||
fn extent(&self) -> [u32; 3] {
|
|
||||||
self.view.image().extent().clone()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ use crate::{
|
|||||||
manifest::{install_manifest, uninstall_manifest},
|
manifest::{install_manifest, uninstall_manifest},
|
||||||
overlay::OpenVrOverlayData,
|
overlay::OpenVrOverlayData,
|
||||||
},
|
},
|
||||||
|
overlay::OverlayData,
|
||||||
},
|
},
|
||||||
graphics::WlxGraphics,
|
graphics::WlxGraphics,
|
||||||
overlays::watch::{watch_fade, WATCH_NAME},
|
overlays::watch::{watch_fade, WATCH_NAME},
|
||||||
@@ -157,6 +158,27 @@ pub fn openvr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
|||||||
f(&mut state, &mut o.state);
|
f(&mut state, &mut o.state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
TaskType::CreateOverlay(sel, f) => {
|
||||||
|
let None = overlays.mut_by_selector(&sel) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some((state, backend)) = f(&mut state) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
overlays.add(OverlayData {
|
||||||
|
state,
|
||||||
|
backend,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
TaskType::DropOverlay(sel) => {
|
||||||
|
if let Some(o) = overlays.mut_by_selector(&sel) {
|
||||||
|
o.destroy(&mut overlay_mngr);
|
||||||
|
overlays.drop_by_selector(&sel);
|
||||||
|
}
|
||||||
|
}
|
||||||
TaskType::Toast(t) => {
|
TaskType::Toast(t) => {
|
||||||
// TODO toasts
|
// TODO toasts
|
||||||
log::info!("Toast: {} {}", t.title, t.body);
|
log::info!("Toast: {} {}", t.title, t.body);
|
||||||
@@ -209,7 +231,7 @@ pub fn openvr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
|||||||
let _ = sender.send_params(&overlays);
|
let _ = sender.send_params(&overlays);
|
||||||
};
|
};
|
||||||
|
|
||||||
log::debug!("Rendering frame");
|
log::trace!("Rendering frame");
|
||||||
|
|
||||||
for o in overlays.iter_mut() {
|
for o in overlays.iter_mut() {
|
||||||
if o.state.want_visible {
|
if o.state.want_visible {
|
||||||
@@ -217,7 +239,7 @@ pub fn openvr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log::debug!("Rendering overlays");
|
log::trace!("Rendering overlays");
|
||||||
|
|
||||||
overlays
|
overlays
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
|
|||||||
@@ -254,4 +254,13 @@ impl OverlayData<OpenVrOverlayData> {
|
|||||||
log::error!("{}: Failed to set overlay texture: {}", self.state.name, e);
|
log::error!("{}: Failed to set overlay texture: {}", self.state.name, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn destroy(&mut self, overlay: &mut OverlayManager) {
|
||||||
|
if let Some(handle) = self.data.handle {
|
||||||
|
log::debug!("{}: destroy", self.state.name);
|
||||||
|
if let Err(e) = overlay.destroy_overlay(handle) {
|
||||||
|
log::error!("{}: Failed to destroy overlay: {}", self.state.name, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ use crate::{
|
|||||||
common::{OverlayContainer, TaskType},
|
common::{OverlayContainer, TaskType},
|
||||||
input::interact,
|
input::interact,
|
||||||
openxr::{input::DoubleClickCounter, lines::LinePool, overlay::OpenXrOverlayData},
|
openxr::{input::DoubleClickCounter, lines::LinePool, overlay::OpenXrOverlayData},
|
||||||
|
overlay::OverlayData,
|
||||||
},
|
},
|
||||||
graphics::WlxGraphics,
|
graphics::WlxGraphics,
|
||||||
overlays::watch::{watch_fade, WATCH_NAME},
|
overlays::watch::{watch_fade, WATCH_NAME},
|
||||||
@@ -187,6 +188,24 @@ pub fn openxr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
|||||||
f(&mut app_state, &mut o.state);
|
f(&mut app_state, &mut o.state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
TaskType::CreateOverlay(sel, f) => {
|
||||||
|
let None = overlays.mut_by_selector(&sel) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some((state, backend)) = f(&mut app_state) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
overlays.add(OverlayData {
|
||||||
|
state,
|
||||||
|
backend,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
TaskType::DropOverlay(sel) => {
|
||||||
|
overlays.drop_by_selector(&sel);
|
||||||
|
}
|
||||||
TaskType::Toast(t) => {
|
TaskType::Toast(t) => {
|
||||||
// TODO toasts
|
// TODO toasts
|
||||||
log::info!("Toast: {} {}", t.title, t.body);
|
log::info!("Toast: {} {}", t.title, t.body);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::Ok;
|
use anyhow::Ok;
|
||||||
use glam::{Affine2, Affine3A, Mat3A, Quat, Vec3, Vec3A};
|
use glam::{Affine2, Affine3A, Mat3A, Quat, Vec2, Vec3, Vec3A};
|
||||||
use vulkano::image::view::ImageView;
|
use vulkano::image::view::ImageView;
|
||||||
|
|
||||||
use crate::state::AppState;
|
use crate::state::AppState;
|
||||||
@@ -21,7 +21,6 @@ pub trait OverlayBackend: OverlayRenderer + InteractionHandler {}
|
|||||||
pub struct OverlayState {
|
pub struct OverlayState {
|
||||||
pub id: usize,
|
pub id: usize,
|
||||||
pub name: Arc<str>,
|
pub name: Arc<str>,
|
||||||
pub size: (i32, i32),
|
|
||||||
pub want_visible: bool,
|
pub want_visible: bool,
|
||||||
pub show_hide: bool,
|
pub show_hide: bool,
|
||||||
pub grabbable: bool,
|
pub grabbable: bool,
|
||||||
@@ -44,7 +43,6 @@ impl Default for OverlayState {
|
|||||||
OverlayState {
|
OverlayState {
|
||||||
id: AUTO_INCREMENT.fetch_add(1, Ordering::Relaxed),
|
id: AUTO_INCREMENT.fetch_add(1, Ordering::Relaxed),
|
||||||
name: Arc::from(""),
|
name: Arc::from(""),
|
||||||
size: (0, 0),
|
|
||||||
want_visible: false,
|
want_visible: false,
|
||||||
show_hide: false,
|
show_hide: false,
|
||||||
grabbable: false,
|
grabbable: false,
|
||||||
@@ -208,7 +206,6 @@ pub trait OverlayRenderer {
|
|||||||
fn resume(&mut self, app: &mut AppState) -> anyhow::Result<()>;
|
fn resume(&mut self, app: &mut AppState) -> anyhow::Result<()>;
|
||||||
fn render(&mut self, app: &mut AppState) -> anyhow::Result<()>;
|
fn render(&mut self, app: &mut AppState) -> anyhow::Result<()>;
|
||||||
fn view(&mut self) -> Option<Arc<ImageView>>;
|
fn view(&mut self) -> Option<Arc<ImageView>>;
|
||||||
fn extent(&self) -> [u32; 3];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FallbackRenderer;
|
pub struct FallbackRenderer;
|
||||||
@@ -229,9 +226,6 @@ impl OverlayRenderer for FallbackRenderer {
|
|||||||
fn view(&mut self) -> Option<Arc<ImageView>> {
|
fn view(&mut self) -> Option<Arc<ImageView>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
fn extent(&self) -> [u32; 3] {
|
|
||||||
[0, 0, 0]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Boilerplate and dummies
|
// Boilerplate and dummies
|
||||||
|
|
||||||
@@ -274,9 +268,6 @@ impl OverlayRenderer for SplitOverlayBackend {
|
|||||||
fn view(&mut self) -> Option<Arc<ImageView>> {
|
fn view(&mut self) -> Option<Arc<ImageView>> {
|
||||||
self.renderer.view()
|
self.renderer.view()
|
||||||
}
|
}
|
||||||
fn extent(&self) -> [u32; 3] {
|
|
||||||
self.renderer.extent()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
impl InteractionHandler for SplitOverlayBackend {
|
impl InteractionHandler for SplitOverlayBackend {
|
||||||
fn on_left(&mut self, app: &mut AppState, pointer: usize) {
|
fn on_left(&mut self, app: &mut AppState, pointer: usize) {
|
||||||
@@ -292,3 +283,20 @@ impl InteractionHandler for SplitOverlayBackend {
|
|||||||
self.interaction.on_pointer(app, hit, pressed);
|
self.interaction.on_pointer(app, hit, pressed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ui_transform(extent: &[u32; 2]) -> Affine2 {
|
||||||
|
let center = Vec2 { x: 0.5, y: 0.5 };
|
||||||
|
if extent[1] > extent[0] {
|
||||||
|
Affine2::from_cols(
|
||||||
|
Vec2::X * (extent[1] as f32 / extent[0] as f32),
|
||||||
|
Vec2::NEG_Y,
|
||||||
|
center,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Affine2::from_cols(
|
||||||
|
Vec2::X,
|
||||||
|
Vec2::NEG_Y * (extent[0] as f32 / extent[1] as f32),
|
||||||
|
center,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -506,10 +506,6 @@ impl<D, S> OverlayRenderer for Canvas<D, S> {
|
|||||||
fn view(&mut self) -> Option<Arc<ImageView>> {
|
fn view(&mut self) -> Option<Arc<ImageView>> {
|
||||||
Some(self.view_final.clone())
|
Some(self.view_final.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extent(&self) -> [u32; 3] {
|
|
||||||
self.view_final.image().extent().clone()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D, S> OverlayBackend for Canvas<D, S> {}
|
impl<D, S> OverlayBackend for Canvas<D, S> {}
|
||||||
|
|||||||
18
src/main.rs
18
src/main.rs
@@ -59,16 +59,26 @@ fn auto_run(running: Arc<AtomicBool>) {
|
|||||||
#[cfg(feature = "openxr")]
|
#[cfg(feature = "openxr")]
|
||||||
{
|
{
|
||||||
use crate::backend::openxr::openxr_run;
|
use crate::backend::openxr::openxr_run;
|
||||||
let Err(BackendError::NotSupported) = openxr_run(running.clone()) else {
|
match openxr_run(running.clone()) {
|
||||||
return;
|
Ok(()) => return,
|
||||||
|
Err(BackendError::NotSupported) => (),
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("{}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "openvr")]
|
#[cfg(feature = "openvr")]
|
||||||
{
|
{
|
||||||
use crate::backend::openvr::openvr_run;
|
use crate::backend::openvr::openvr_run;
|
||||||
let Err(BackendError::NotSupported) = openvr_run(running) else {
|
match openvr_run(running.clone()) {
|
||||||
return;
|
Ok(()) => return,
|
||||||
|
Err(BackendError::NotSupported) => (),
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("{}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -121,7 +121,6 @@ where
|
|||||||
Ok(OverlayData {
|
Ok(OverlayData {
|
||||||
state: OverlayState {
|
state: OverlayState {
|
||||||
name: KEYBOARD_NAME.into(),
|
name: KEYBOARD_NAME.into(),
|
||||||
size: (size.x as _, size.y as _),
|
|
||||||
grabbable: true,
|
grabbable: true,
|
||||||
recenter: true,
|
recenter: true,
|
||||||
interactable: true,
|
interactable: true,
|
||||||
|
|||||||
135
src/overlays/mirror.rs
Normal file
135
src/overlays/mirror.rs
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
use std::{sync::Arc, thread::JoinHandle};
|
||||||
|
|
||||||
|
use futures::executor;
|
||||||
|
use glam::vec3a;
|
||||||
|
use wlx_capture::pipewire::{pipewire_select_screen, PipewireCapture, PipewireSelectScreenResult};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
backend::{
|
||||||
|
common::{OverlaySelector, TaskType},
|
||||||
|
overlay::{
|
||||||
|
ui_transform, OverlayBackend, OverlayRenderer, OverlayState, SplitOverlayBackend,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
state::{AppSession, AppState},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::screen::ScreenRenderer;
|
||||||
|
|
||||||
|
pub struct MirrorRenderer {
|
||||||
|
name: Arc<str>,
|
||||||
|
renderer: Option<ScreenRenderer>,
|
||||||
|
selector: Option<JoinHandle<Option<PipewireSelectScreenResult>>>,
|
||||||
|
last_extent: [u32; 3],
|
||||||
|
}
|
||||||
|
impl MirrorRenderer {
|
||||||
|
pub fn new(name: Arc<str>) -> Self {
|
||||||
|
Self {
|
||||||
|
name,
|
||||||
|
renderer: None,
|
||||||
|
selector: Some(std::thread::spawn(|| {
|
||||||
|
executor::block_on(pipewire_select_screen(None, false, false, false)).ok()
|
||||||
|
})),
|
||||||
|
last_extent: [0; 3],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OverlayRenderer for MirrorRenderer {
|
||||||
|
fn init(&mut self, _app: &mut AppState) -> anyhow::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn render(&mut self, app: &mut AppState) -> anyhow::Result<()> {
|
||||||
|
if let Some(selector) = self.selector.take() {
|
||||||
|
if !selector.is_finished() {
|
||||||
|
self.selector = Some(selector);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// safe unwrap because we know it's finished
|
||||||
|
if let Some(pw_result) = selector.join().unwrap() {
|
||||||
|
log::info!(
|
||||||
|
"{}: PipeWire node selected: {}",
|
||||||
|
self.name.clone(),
|
||||||
|
pw_result.node_id
|
||||||
|
);
|
||||||
|
let capture = PipewireCapture::new(self.name.clone(), pw_result.node_id, 60);
|
||||||
|
self.renderer = Some(ScreenRenderer::new_raw(
|
||||||
|
self.name.clone(),
|
||||||
|
Box::new(capture),
|
||||||
|
));
|
||||||
|
app.tasks.enqueue(TaskType::Overlay(
|
||||||
|
OverlaySelector::Name(self.name.clone()),
|
||||||
|
Box::new(|app, o| {
|
||||||
|
o.grabbable = true;
|
||||||
|
o.interactable = true;
|
||||||
|
o.reset(app, false);
|
||||||
|
}),
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
log::warn!("Failed to create pipewire mirror");
|
||||||
|
self.renderer = None;
|
||||||
|
// drop self
|
||||||
|
app.tasks
|
||||||
|
.enqueue(TaskType::DropOverlay(OverlaySelector::Name(
|
||||||
|
self.name.clone(),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(renderer) = self.renderer.as_mut() {
|
||||||
|
renderer.render(app)?;
|
||||||
|
if let Some(view) = renderer.view() {
|
||||||
|
let extent = view.image().extent();
|
||||||
|
if self.last_extent != extent {
|
||||||
|
self.last_extent = extent.clone();
|
||||||
|
// resized
|
||||||
|
app.tasks.enqueue(TaskType::Overlay(
|
||||||
|
OverlaySelector::Name(self.name.clone()),
|
||||||
|
Box::new(move |_app, o| {
|
||||||
|
o.interaction_transform = ui_transform(&[extent[0], extent[1]]);
|
||||||
|
}),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn pause(&mut self, app: &mut AppState) -> anyhow::Result<()> {
|
||||||
|
if let Some(renderer) = self.renderer.as_mut() {
|
||||||
|
renderer.pause(app)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn resume(&mut self, app: &mut AppState) -> anyhow::Result<()> {
|
||||||
|
if let Some(renderer) = self.renderer.as_mut() {
|
||||||
|
renderer.resume(app)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn view(&mut self) -> Option<std::sync::Arc<vulkano::image::view::ImageView>> {
|
||||||
|
self.renderer.as_mut().and_then(|r| r.view())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_mirror(
|
||||||
|
name: Arc<str>,
|
||||||
|
show_hide: bool,
|
||||||
|
session: &AppSession,
|
||||||
|
) -> Option<(OverlayState, Box<dyn OverlayBackend>)> {
|
||||||
|
let state = OverlayState {
|
||||||
|
name: name.clone(),
|
||||||
|
show_hide,
|
||||||
|
want_visible: true,
|
||||||
|
spawn_scale: 0.5 * session.config.desktop_view_scale,
|
||||||
|
spawn_point: vec3a(0., 0.5, -0.5),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let backend = Box::new(SplitOverlayBackend {
|
||||||
|
renderer: Box::new(MirrorRenderer::new(name)),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
|
||||||
|
Some((state, backend))
|
||||||
|
}
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
pub mod keyboard;
|
pub mod keyboard;
|
||||||
|
#[cfg(feature = "wayland")]
|
||||||
|
pub mod mirror;
|
||||||
pub mod screen;
|
pub mod screen;
|
||||||
pub mod toast;
|
pub mod toast;
|
||||||
pub mod watch;
|
pub mod watch;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::{
|
use std::{
|
||||||
ops::Add,
|
ops::Add,
|
||||||
ptr,
|
ptr,
|
||||||
sync::{mpsc::Receiver, Arc},
|
sync::Arc,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
@@ -237,12 +237,22 @@ pub struct ScreenRenderer {
|
|||||||
name: Arc<str>,
|
name: Arc<str>,
|
||||||
capture: Box<dyn WlxCapture>,
|
capture: Box<dyn WlxCapture>,
|
||||||
pipeline: Option<ScreenPipeline>,
|
pipeline: Option<ScreenPipeline>,
|
||||||
receiver: Option<Receiver<WlxFrame>>,
|
|
||||||
last_view: Option<Arc<ImageView>>,
|
last_view: Option<Arc<ImageView>>,
|
||||||
extent: [u32; 3],
|
extent: [u32; 3],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScreenRenderer {
|
impl ScreenRenderer {
|
||||||
|
#[cfg(feature = "wayland")]
|
||||||
|
pub fn new_raw(name: Arc<str>, capture: Box<dyn WlxCapture>) -> ScreenRenderer {
|
||||||
|
ScreenRenderer {
|
||||||
|
name,
|
||||||
|
capture,
|
||||||
|
pipeline: None,
|
||||||
|
last_view: None,
|
||||||
|
extent: [0; 3],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "wayland")]
|
#[cfg(feature = "wayland")]
|
||||||
pub fn new_wlr(output: &WlxOutput) -> Option<ScreenRenderer> {
|
pub fn new_wlr(output: &WlxOutput) -> Option<ScreenRenderer> {
|
||||||
let client = WlxClient::new()?;
|
let client = WlxClient::new()?;
|
||||||
@@ -252,7 +262,6 @@ impl ScreenRenderer {
|
|||||||
name: output.name.clone(),
|
name: output.name.clone(),
|
||||||
capture: Box::new(capture),
|
capture: Box::new(capture),
|
||||||
pipeline: None,
|
pipeline: None,
|
||||||
receiver: None,
|
|
||||||
last_view: None,
|
last_view: None,
|
||||||
extent: extent_from_res(output.size),
|
extent: extent_from_res(output.size),
|
||||||
})
|
})
|
||||||
@@ -268,7 +277,7 @@ impl ScreenRenderer {
|
|||||||
)> {
|
)> {
|
||||||
let name = output.name.clone();
|
let name = output.name.clone();
|
||||||
let select_screen_result =
|
let select_screen_result =
|
||||||
futures::executor::block_on(pipewire_select_screen(token)).ok()?;
|
futures::executor::block_on(pipewire_select_screen(token, true, true, true)).ok()?;
|
||||||
|
|
||||||
let capture = PipewireCapture::new(name, select_screen_result.node_id, 60);
|
let capture = PipewireCapture::new(name, select_screen_result.node_id, 60);
|
||||||
|
|
||||||
@@ -277,7 +286,6 @@ impl ScreenRenderer {
|
|||||||
name: output.name.clone(),
|
name: output.name.clone(),
|
||||||
capture: Box::new(capture),
|
capture: Box::new(capture),
|
||||||
pipeline: None,
|
pipeline: None,
|
||||||
receiver: None,
|
|
||||||
last_view: None,
|
last_view: None,
|
||||||
extent: extent_from_res(output.size),
|
extent: extent_from_res(output.size),
|
||||||
},
|
},
|
||||||
@@ -293,7 +301,6 @@ impl ScreenRenderer {
|
|||||||
name: screen.name.clone(),
|
name: screen.name.clone(),
|
||||||
capture: Box::new(capture),
|
capture: Box::new(capture),
|
||||||
pipeline: None,
|
pipeline: None,
|
||||||
receiver: None,
|
|
||||||
last_view: None,
|
last_view: None,
|
||||||
extent: extent_from_res((screen.monitor.width(), screen.monitor.height())),
|
extent: extent_from_res((screen.monitor.width(), screen.monitor.height())),
|
||||||
}
|
}
|
||||||
@@ -305,7 +312,7 @@ impl OverlayRenderer for ScreenRenderer {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn render(&mut self, app: &mut AppState) -> anyhow::Result<()> {
|
fn render(&mut self, app: &mut AppState) -> anyhow::Result<()> {
|
||||||
let receiver = self.receiver.get_or_insert_with(|| {
|
if !self.capture.ready() {
|
||||||
let allow_dmabuf = &*app.session.config.capture_method != "pw_fallback";
|
let allow_dmabuf = &*app.session.config.capture_method != "pw_fallback";
|
||||||
|
|
||||||
let drm_formats = DRM_FORMATS.get_or_init({
|
let drm_formats = DRM_FORMATS.get_or_init({
|
||||||
@@ -349,14 +356,11 @@ impl OverlayRenderer for ScreenRenderer {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let rx = self.capture.init(&drm_formats);
|
self.capture.init(&drm_formats);
|
||||||
self.capture.request_new_frame();
|
self.capture.request_new_frame();
|
||||||
rx
|
};
|
||||||
});
|
|
||||||
|
|
||||||
let mut mouse = None;
|
for frame in self.capture.receive().into_iter() {
|
||||||
|
|
||||||
for frame in receiver.try_iter() {
|
|
||||||
match frame {
|
match frame {
|
||||||
WlxFrame::Dmabuf(frame) => {
|
WlxFrame::Dmabuf(frame) => {
|
||||||
if !frame.is_valid() {
|
if !frame.is_valid() {
|
||||||
@@ -425,29 +429,29 @@ impl OverlayRenderer for ScreenRenderer {
|
|||||||
upload.texture2d(frame.format.width, frame.format.height, format, &data)?;
|
upload.texture2d(frame.format.width, frame.format.height, format, &data)?;
|
||||||
|
|
||||||
let mut pipeline = None;
|
let mut pipeline = None;
|
||||||
if mouse.is_some() {
|
if frame.mouse.is_some() {
|
||||||
let new_pipeline = self.pipeline.get_or_insert_with(|| {
|
pipeline = Some(match self.pipeline {
|
||||||
let mut pipeline = ScreenPipeline::new(&self.extent, app).unwrap(); // TODO
|
Some(ref mut p) => p,
|
||||||
self.last_view = Some(pipeline.view.clone());
|
_ => {
|
||||||
pipeline.ensure_mouse_initialized(&mut upload).unwrap(); // TODO
|
let mut pipeline = ScreenPipeline::new(&self.extent, app)?;
|
||||||
pipeline
|
self.last_view = Some(pipeline.view.clone());
|
||||||
|
pipeline.ensure_mouse_initialized(&mut upload)?;
|
||||||
|
self.pipeline = Some(pipeline);
|
||||||
|
self.pipeline.as_mut().unwrap() // safe
|
||||||
|
}
|
||||||
});
|
});
|
||||||
pipeline = Some(new_pipeline);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
upload.build_and_execute_now()?;
|
upload.build_and_execute_now()?;
|
||||||
|
|
||||||
if let Some(pipeline) = pipeline {
|
if let Some(pipeline) = pipeline {
|
||||||
pipeline.render(image, mouse.as_ref(), app)?;
|
pipeline.render(image, frame.mouse.as_ref(), app)?;
|
||||||
} else {
|
} else {
|
||||||
let view = ImageView::new_default(image)?;
|
let view = ImageView::new_default(image)?;
|
||||||
self.last_view = Some(view);
|
self.last_view = Some(view);
|
||||||
}
|
}
|
||||||
self.capture.request_new_frame();
|
self.capture.request_new_frame();
|
||||||
}
|
}
|
||||||
WlxFrame::Mouse(m) => {
|
|
||||||
mouse = Some(m);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -463,9 +467,6 @@ impl OverlayRenderer for ScreenRenderer {
|
|||||||
fn view(&mut self) -> Option<Arc<ImageView>> {
|
fn view(&mut self) -> Option<Arc<ImageView>> {
|
||||||
self.last_view.clone()
|
self.last_view.clone()
|
||||||
}
|
}
|
||||||
fn extent(&self) -> [u32; 3] {
|
|
||||||
self.extent.clone()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "wayland")]
|
#[cfg(feature = "wayland")]
|
||||||
@@ -489,7 +490,6 @@ where
|
|||||||
output.logical_pos,
|
output.logical_pos,
|
||||||
);
|
);
|
||||||
|
|
||||||
let size = (output.size.0, output.size.1);
|
|
||||||
let mut capture: Option<ScreenRenderer> = None;
|
let mut capture: Option<ScreenRenderer> = None;
|
||||||
|
|
||||||
if &*session.config.capture_method == "auto" && wl.maybe_wlr_dmabuf_mgr.is_some() {
|
if &*session.config.capture_method == "auto" && wl.maybe_wlr_dmabuf_mgr.is_some() {
|
||||||
@@ -576,7 +576,6 @@ where
|
|||||||
Some(OverlayData {
|
Some(OverlayData {
|
||||||
state: OverlayState {
|
state: OverlayState {
|
||||||
name: output.name.clone(),
|
name: output.name.clone(),
|
||||||
size,
|
|
||||||
show_hide: session
|
show_hide: session
|
||||||
.config
|
.config
|
||||||
.show_screens
|
.show_screens
|
||||||
@@ -741,7 +740,6 @@ where
|
|||||||
OverlayData {
|
OverlayData {
|
||||||
state: OverlayState {
|
state: OverlayState {
|
||||||
name: s.name.clone(),
|
name: s.name.clone(),
|
||||||
size,
|
|
||||||
show_hide: session
|
show_hide: session
|
||||||
.config
|
.config
|
||||||
.show_screens
|
.show_screens
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ use std::{
|
|||||||
|
|
||||||
use chrono::Local;
|
use chrono::Local;
|
||||||
use chrono_tz::Tz;
|
use chrono_tz::Tz;
|
||||||
use glam::{vec2, Affine2, Quat, Vec3, Vec3A};
|
use glam::{Quat, Vec3, Vec3A};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::{
|
backend::{
|
||||||
common::{OverlaySelector, TaskType},
|
common::{OverlaySelector, TaskType},
|
||||||
input::PointerMode,
|
input::PointerMode,
|
||||||
overlay::{OverlayData, OverlayState, RelativeTo},
|
overlay::{ui_transform, OverlayData, OverlayState, RelativeTo},
|
||||||
},
|
},
|
||||||
config::load_watch,
|
config::load_watch,
|
||||||
gui::{color_parse, CanvasBuilder, Control},
|
gui::{color_parse, CanvasBuilder, Control},
|
||||||
@@ -270,24 +270,37 @@ where
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "wayland")]
|
||||||
|
WatchElement::MirrorButton {
|
||||||
|
rect: [x, y, w, h],
|
||||||
|
font_size,
|
||||||
|
bg_color,
|
||||||
|
fg_color,
|
||||||
|
text,
|
||||||
|
name,
|
||||||
|
show_hide,
|
||||||
|
} => {
|
||||||
|
canvas.bg_color = color_parse(&bg_color).unwrap_or(FALLBACK_COLOR);
|
||||||
|
canvas.fg_color = color_parse(&fg_color).unwrap_or(FALLBACK_COLOR);
|
||||||
|
canvas.font_size = font_size;
|
||||||
|
let button = canvas.button(x, y, w, h, text.clone());
|
||||||
|
button.state = Some(ElemState::Mirror { name, show_hide });
|
||||||
|
button.on_press = Some(btn_mirror_dn::<O>);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let interaction_transform =
|
|
||||||
Affine2::from_translation(vec2(0.5, 0.5)) * Affine2::from_scale(vec2(1., -2.0));
|
|
||||||
|
|
||||||
let relative_to = RelativeTo::Hand(state.session.watch_hand);
|
let relative_to = RelativeTo::Hand(state.session.watch_hand);
|
||||||
|
|
||||||
Ok(OverlayData {
|
Ok(OverlayData {
|
||||||
state: OverlayState {
|
state: OverlayState {
|
||||||
name: WATCH_NAME.into(),
|
name: WATCH_NAME.into(),
|
||||||
size: (400, 200),
|
|
||||||
want_visible: true,
|
want_visible: true,
|
||||||
interactable: true,
|
interactable: true,
|
||||||
spawn_scale: WATCH_SCALE * state.session.config.watch_scale,
|
spawn_scale: WATCH_SCALE * state.session.config.watch_scale,
|
||||||
spawn_point: state.session.watch_pos.into(),
|
spawn_point: state.session.watch_pos.into(),
|
||||||
spawn_rotation: state.session.watch_rot,
|
spawn_rotation: state.session.watch_rot,
|
||||||
interaction_transform,
|
interaction_transform: ui_transform(&config.watch_size),
|
||||||
relative_to,
|
relative_to,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -328,6 +341,60 @@ enum ElemState {
|
|||||||
func_right: Option<ButtonFunc>,
|
func_right: Option<ButtonFunc>,
|
||||||
func_middle: Option<ButtonFunc>,
|
func_middle: Option<ButtonFunc>,
|
||||||
},
|
},
|
||||||
|
#[cfg(feature = "wayland")]
|
||||||
|
Mirror { name: Arc<str>, show_hide: bool },
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "wayland")]
|
||||||
|
fn btn_mirror_dn<O>(
|
||||||
|
control: &mut Control<(), ElemState>,
|
||||||
|
_: &mut (),
|
||||||
|
app: &mut AppState,
|
||||||
|
mode: PointerMode,
|
||||||
|
) where
|
||||||
|
O: Default,
|
||||||
|
{
|
||||||
|
let ElemState::Mirror { name, show_hide } = control.state.as_ref().unwrap()
|
||||||
|
// want panic
|
||||||
|
else {
|
||||||
|
log::error!("Mirror state not found");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let selector = OverlaySelector::Name(name.clone());
|
||||||
|
|
||||||
|
match mode {
|
||||||
|
PointerMode::Left => {
|
||||||
|
app.tasks.enqueue(TaskType::Overlay(
|
||||||
|
selector.clone(),
|
||||||
|
Box::new(|_app, o| {
|
||||||
|
o.want_visible = !o.want_visible;
|
||||||
|
}),
|
||||||
|
));
|
||||||
|
|
||||||
|
app.tasks.enqueue(TaskType::CreateOverlay(
|
||||||
|
selector,
|
||||||
|
Box::new({
|
||||||
|
let name = name.clone();
|
||||||
|
let show_hide = *show_hide;
|
||||||
|
move |app| super::mirror::new_mirror(name.clone(), show_hide, &app.session)
|
||||||
|
}),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
PointerMode::Right => {
|
||||||
|
app.tasks.enqueue(TaskType::Overlay(
|
||||||
|
selector,
|
||||||
|
Box::new(|_app, o| {
|
||||||
|
o.grabbable = !o.grabbable;
|
||||||
|
o.interactable = o.grabbable;
|
||||||
|
}),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
PointerMode::Middle => {
|
||||||
|
app.tasks.enqueue(TaskType::DropOverlay(selector));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn btn_func_dn(
|
fn btn_func_dn(
|
||||||
@@ -773,6 +840,16 @@ enum WatchElement {
|
|||||||
func_middle: Option<ButtonFunc>,
|
func_middle: Option<ButtonFunc>,
|
||||||
text: Arc<str>,
|
text: Arc<str>,
|
||||||
},
|
},
|
||||||
|
#[cfg(feature = "wayland")]
|
||||||
|
MirrorButton {
|
||||||
|
rect: [f32; 4],
|
||||||
|
font_size: isize,
|
||||||
|
bg_color: Arc<str>,
|
||||||
|
fg_color: Arc<str>,
|
||||||
|
name: Arc<str>,
|
||||||
|
text: Arc<str>,
|
||||||
|
show_hide: bool,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
|||||||
@@ -132,14 +132,36 @@ watch_elements:
|
|||||||
# exec: ["echo", "customize me! see watch.yaml"]
|
# exec: ["echo", "customize me! see watch.yaml"]
|
||||||
# interval: 0 # seconds
|
# interval: 0 # seconds
|
||||||
|
|
||||||
# volume buttons
|
### MirrorButton
|
||||||
- type: ExecButton
|
# Bring an additional PipeWire screen, window, region or virtual screen share into VR.
|
||||||
|
# These are view-only, and will not respond to pointers by moving your mouse.
|
||||||
|
# You may have as many as you like, but the `name` must be unique for each.
|
||||||
|
# Controls:
|
||||||
|
# - Blue Click: Show/hide. Shows pipewire prompt on first show.
|
||||||
|
# - Orange Click: Toggle lock in place
|
||||||
|
# - Purple Click: Stop capture. After doing this, you may Blue-click again to select a different source.
|
||||||
|
# Warning:
|
||||||
|
# - Window shares may stop updating if the window goes off-screen or is on an inactive workspace
|
||||||
|
# - Resizing, minimizing, maximizing windows may break stuff. Complain to your xdg-desktop-portal implementation.
|
||||||
|
# - Selections are not saved across sessions
|
||||||
|
|
||||||
|
- type: MirrorButton
|
||||||
rect: [327, 52, 46, 32]
|
rect: [327, 52, 46, 32]
|
||||||
font_size: 14
|
font_size: 14
|
||||||
fg_color: "#FFFFFF"
|
fg_color: "#FFFFFF"
|
||||||
bg_color: "#505050"
|
bg_color: "#B05050"
|
||||||
text: "+"
|
name: "M1"
|
||||||
exec: [ "pactl", "set-sink-volume", "@DEFAULT_SINK@", "+5%" ]
|
text: "M"
|
||||||
|
show_hide: false # should it respond to show/hide binding?
|
||||||
|
|
||||||
|
# volume buttons
|
||||||
|
# - type: ExecButton
|
||||||
|
#rect: [327, 52, 46, 32]
|
||||||
|
#font_size: 14
|
||||||
|
#fg_color: "#FFFFFF"
|
||||||
|
#bg_color: "#505050"
|
||||||
|
# text: "+"
|
||||||
|
# exec: [ "pactl", "set-sink-volume", "@DEFAULT_SINK@", "+5%" ]
|
||||||
- type: ExecButton
|
- type: ExecButton
|
||||||
rect: [327, 116, 46, 32]
|
rect: [327, 116, 46, 32]
|
||||||
font_size: 14
|
font_size: 14
|
||||||
|
|||||||
Reference in New Issue
Block a user