mirror of
https://github.com/moeru-ai/airi.git
synced 2026-07-10 00:08:33 +00:00
feat(stage-tamagotchi): allowing click through and fade away when hovering (currently macOS only) (#186)
Co-authored-by: Midori Kochiya <1381736+kmod-midori@users.noreply.github.com> Co-authored-by: LemonNeko <17664845+LemonNekoGH@users.noreply.github.com>
This commit is contained in:
parent
a99ba7f50a
commit
da4da0aeb6
6 changed files with 335 additions and 185 deletions
236
Cargo.lock
generated
236
Cargo.lock
generated
|
|
@ -95,12 +95,18 @@ name = "app"
|
|||
version = "0.4.27"
|
||||
dependencies = [
|
||||
"log",
|
||||
"objc2 0.6.1",
|
||||
"objc2-foundation 0.3.1",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"tauri-plugin-log",
|
||||
"tauri-plugin-mcp",
|
||||
"tauri-plugin-os",
|
||||
"tauri-plugin-prevent-default",
|
||||
"tokio",
|
||||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -487,9 +493,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.10.0"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63"
|
||||
checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
|
|
@ -735,9 +741,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "dlopen2_derive"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54"
|
||||
checksum = "788160fb30de9cdd857af31c6a2675904b16ece8fc2737b2c7127ba368c9d0f4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -788,9 +794,9 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
|||
|
||||
[[package]]
|
||||
name = "embed-resource"
|
||||
version = "3.0.2"
|
||||
version = "3.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fbc6e0d8e0c03a655b53ca813f0463d2c956bc4db8138dbc89f120b066551e3"
|
||||
checksum = "e8fe7d068ca6b3a5782ca5ec9afc244acd99dd441e4686a83b1c3973aba1d489"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"memchr",
|
||||
|
|
@ -1451,17 +1457,21 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "hyper-util"
|
||||
version = "0.1.12"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf9f1e950e0d9d1d3c47184416723cf29c0d1f93bd8cccf37e4beb6b44f31710"
|
||||
checksum = "b1c293b6b3d21eca78250dc7dbebd6b9210ec5530e038cbfe0661b5c47ab06e8"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"ipnet",
|
||||
"libc",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"tokio",
|
||||
|
|
@ -1665,6 +1675,16 @@ version = "2.11.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
|
||||
|
||||
[[package]]
|
||||
name = "iri-string"
|
||||
version = "0.7.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.14.0"
|
||||
|
|
@ -1857,9 +1877,9 @@ checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
|
|||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.12"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
||||
checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
|
|
@ -2323,9 +2343,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.3"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
|
||||
checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
|
|
@ -2333,9 +2353,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.10"
|
||||
version = "0.9.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
||||
checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
|
|
@ -2828,9 +2848,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.12.15"
|
||||
version = "0.12.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb"
|
||||
checksum = "e98ff6b0dbbe4d5a37318f433d4fc82babd21631f194d370409ceb2e40b2f0b5"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
|
|
@ -2855,13 +2875,13 @@ dependencies = [
|
|||
"tokio",
|
||||
"tokio-util",
|
||||
"tower",
|
||||
"tower-http",
|
||||
"tower-service",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"wasm-streams",
|
||||
"web-sys",
|
||||
"windows-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3273,9 +3293,9 @@ checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9"
|
|||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.5.9"
|
||||
version = "0.5.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef"
|
||||
checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
|
|
@ -4059,6 +4079,24 @@ dependencies = [
|
|||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-http"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fdb0c213ca27a9f57ab69ddb290fd80d970922355b83ae380b395d3986b8a2e"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http-body",
|
||||
"iri-string",
|
||||
"pin-project-lite",
|
||||
"tower",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-layer"
|
||||
version = "0.3.3"
|
||||
|
|
@ -4579,7 +4617,7 @@ dependencies = [
|
|||
"windows-interface",
|
||||
"windows-link",
|
||||
"windows-result",
|
||||
"windows-strings 0.4.2",
|
||||
"windows-strings",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -4631,17 +4669,6 @@ dependencies = [
|
|||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-registry"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3"
|
||||
dependencies = [
|
||||
"windows-result",
|
||||
"windows-strings 0.3.1",
|
||||
"windows-targets 0.53.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.3.4"
|
||||
|
|
@ -4651,15 +4678,6 @@ dependencies = [
|
|||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.4.2"
|
||||
|
|
@ -4678,15 +4696,6 @@ dependencies = [
|
|||
"windows-targets 0.42.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
|
|
@ -4720,21 +4729,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"
|
||||
|
|
@ -4744,29 +4738,13 @@ dependencies = [
|
|||
"windows_aarch64_gnullvm 0.52.6",
|
||||
"windows_aarch64_msvc 0.52.6",
|
||||
"windows_i686_gnu 0.52.6",
|
||||
"windows_i686_gnullvm 0.52.6",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc 0.52.6",
|
||||
"windows_x86_64_gnu 0.52.6",
|
||||
"windows_x86_64_gnullvm 0.52.6",
|
||||
"windows_x86_64_msvc 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.53.0",
|
||||
"windows_aarch64_msvc 0.53.0",
|
||||
"windows_i686_gnu 0.53.0",
|
||||
"windows_i686_gnullvm 0.53.0",
|
||||
"windows_i686_msvc 0.53.0",
|
||||
"windows_x86_64_gnu 0.53.0",
|
||||
"windows_x86_64_gnullvm 0.53.0",
|
||||
"windows_x86_64_msvc 0.53.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-threading"
|
||||
version = "0.1.0"
|
||||
|
|
@ -4791,180 +4769,90 @@ 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"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
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"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
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"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
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"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
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"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
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"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
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"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.40"
|
||||
|
|
@ -4985,12 +4873,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.52.0"
|
||||
version = "0.55.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
|
||||
checksum = "cb5a765337c50e9ec252c2069be9bf91c7df47afb103b642ba3a53bf8101be97"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@ tauri-plugin-log = "2.0.0-rc"
|
|||
tauri-plugin-os = "2"
|
||||
tauri-plugin-mcp = { workspace = true }
|
||||
tauri-plugin-prevent-default = "1.3"
|
||||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
serde_json = "1.0.140"
|
||||
tokio = "1.45.1"
|
||||
|
||||
[profile.dev]
|
||||
incremental = true
|
||||
|
|
@ -40,3 +43,10 @@ debug = true
|
|||
[profile.dev.package."*"]
|
||||
opt-level = 1
|
||||
debug = false
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
objc2 = "0.6.1"
|
||||
objc2-foundation = "0.3.1"
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
windows = { version = "0.61.1", features = ["Win32_UI_WindowsAndMessaging", "Win32_Foundation"] }
|
||||
|
|
|
|||
|
|
@ -3,14 +3,234 @@ use tauri::tray::TrayIconBuilder;
|
|||
use tauri::Emitter;
|
||||
use tauri::RunEvent;
|
||||
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tokio::time::sleep;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
use objc2::{class, msg_send};
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
use objc2_foundation::{NSPoint, NSRect};
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
use tauri::{ActivationPolicy, TitleBarStyle};
|
||||
use tauri::{Manager, WebviewUrl, WebviewWindowBuilder};
|
||||
use tauri_plugin_prevent_default::Flags;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
use windows::Win32::UI::WindowsAndMessaging::{
|
||||
GetWindowLongW, SetWindowLongW, GWL_EXSTYLE, WS_EX_TRANSPARENT,
|
||||
};
|
||||
|
||||
mod commands;
|
||||
mod windows;
|
||||
|
||||
#[derive(Default)]
|
||||
struct WindowClickThroughState {
|
||||
is_click_through_monitoring_enabled: Arc<AtomicBool>,
|
||||
is_click_through_enabled: Arc<AtomicBool>,
|
||||
is_click_through_cursor_inside: Arc<AtomicBool>,
|
||||
}
|
||||
|
||||
fn set_cursor_inside(window: &tauri::Window, is_inside: bool) -> Result<(), String> {
|
||||
let state = window.state::<WindowClickThroughState>();
|
||||
|
||||
state
|
||||
.is_click_through_cursor_inside
|
||||
.store(is_inside, Ordering::Relaxed);
|
||||
|
||||
window
|
||||
.set_ignore_cursor_events(is_inside)
|
||||
.map_err(|e| format!("Failed to set click-through state: {}", e))?;
|
||||
|
||||
let _ = window.emit("tauri-app:window-click-through:is-inside", is_inside);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_click_through_enabled(window: &tauri::Window, enabled: bool) -> Result<(), String> {
|
||||
let state = window.state::<WindowClickThroughState>();
|
||||
|
||||
state
|
||||
.is_click_through_enabled
|
||||
.store(enabled, Ordering::Relaxed);
|
||||
|
||||
window
|
||||
.set_ignore_cursor_events(enabled)
|
||||
.map_err(|e| format!("Failed to set click-through state: {}", e))?;
|
||||
|
||||
let _ = window.emit("tauri-app:window-click-through:enabled", enabled);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get cursor position relative to the window
|
||||
#[cfg(target_os = "macos")]
|
||||
async fn is_cursor_in_window(window: &tauri::Window) -> bool {
|
||||
unsafe {
|
||||
// Get cursor position in screen coordinates (macOS coordinates - origin at bottom left)
|
||||
let mouse_location: NSPoint = msg_send![class!(NSEvent), mouseLocation];
|
||||
|
||||
// Get all screens
|
||||
//
|
||||
// We need screens count because for multiple-display users,
|
||||
// in macOS, the Native API returns the mouse coordinates relative to the primary
|
||||
// display, for example, if we say the primary display is 1920x1080, another two lies
|
||||
// on both sides of the primary display with the size of 1920x1080 too, mouse coordinates
|
||||
// will be 0 at the left edge of p-display, and 1920 at the right edge of the p-display,
|
||||
// -1080 at the left edge of the left-side display, and 2160 at the right edge of the right-side
|
||||
// display.
|
||||
let screens: *const objc2::runtime::AnyObject = msg_send![class!(NSScreen), screens];
|
||||
let screens_count: usize = msg_send![screens, count];
|
||||
|
||||
// Get window position and size from Tauri
|
||||
// Get the NSWindow from Tauri window to access native properties
|
||||
//
|
||||
// While Tauri does provide us window.outer_position() and window.outer_size()
|
||||
// it's not enough to determine if the cursor is inside the window.
|
||||
// The value of those two functions returns the in-compatible coordinates (top-left origin)
|
||||
// with OBJ-C Native API values. This produces a lot of issues when calculating the collision
|
||||
// of the cursor relative to the window.
|
||||
//
|
||||
// We need to get the window's frame in macOS coordinates (bottom-left origin)
|
||||
// and check if the cursor is inside that frame.
|
||||
let ns_window: *mut objc2::runtime::AnyObject = window.ns_window().unwrap() as *mut _;
|
||||
let window_frame: NSRect = msg_send![ns_window, frame];
|
||||
|
||||
// Log all screens information
|
||||
for _ in 0..screens_count {
|
||||
// For debugging purpose, screen object, frame size of the screen, visible frame size of the screen,
|
||||
// and the scale factor of the screen can be obtained as follows:
|
||||
//
|
||||
// let screen: *const objc2::runtime::AnyObject = msg_send![screens, objectAtIndex: i];
|
||||
// let frame: NSRect = msg_send![screen, frame];
|
||||
// let visible_frame: NSRect = msg_send![screen, visibleFrame];
|
||||
// let scale_factor: f64 = msg_send![screen, backingScaleFactor];
|
||||
|
||||
// Check if mouse is inside our window's frame
|
||||
let is_inside = mouse_location.x >= window_frame.origin.x
|
||||
&& mouse_location.x <= (window_frame.origin.x + window_frame.size.width)
|
||||
&& mouse_location.y >= window_frame.origin.y
|
||||
&& mouse_location.y <= (window_frame.origin.y + window_frame.size.height);
|
||||
|
||||
if is_inside {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Check if modifier key is pressed (Option/Alt or Control)
|
||||
#[cfg(target_os = "macos")]
|
||||
fn is_modifier_pressed() -> bool {
|
||||
unsafe {
|
||||
let event_class: &'static objc2::runtime::AnyClass = class!(NSEvent);
|
||||
let flags: u64 = msg_send![event_class, modifierFlags];
|
||||
|
||||
// Check for Alt/Option (1 << 19) or Control (1 << 18)
|
||||
let alt_pressed = (flags & (1 << 19)) != 0;
|
||||
// let ctrl_pressed = (flags & (1 << 18)) != 0;
|
||||
|
||||
// alt_pressed || ctrl_pressed
|
||||
alt_pressed
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn start_monitor_for_clicking_through(window: tauri::Window) -> Result<(), String> {
|
||||
log::info!("Starting monitor for clicking through");
|
||||
|
||||
let window = window.clone();
|
||||
let state = window.state::<WindowClickThroughState>();
|
||||
let is_click_through_enabled = state.is_click_through_enabled.clone();
|
||||
let is_click_through_monitoring_enabled = state.is_click_through_monitoring_enabled.clone();
|
||||
|
||||
// Already monitoring?
|
||||
if is_click_through_monitoring_enabled.load(Ordering::Relaxed) {
|
||||
return Ok(());
|
||||
} else {
|
||||
// Set to true
|
||||
state
|
||||
.is_click_through_monitoring_enabled
|
||||
.store(true, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
// Then start interval timer for monitoring
|
||||
tauri::async_runtime::spawn(async move {
|
||||
loop {
|
||||
sleep(Duration::from_millis(32)).await; // ~30FPS check rate
|
||||
|
||||
// If monitoring is already stopped, break the loop
|
||||
if !is_click_through_monitoring_enabled.load(Ordering::Relaxed) {
|
||||
log::info!("Monitoring is stopped, breaking loop");
|
||||
break;
|
||||
}
|
||||
|
||||
// If is disabled already, skip until next check
|
||||
if !is_click_through_enabled.load(Ordering::Relaxed) {
|
||||
log::info!("Click-through is disabled, skipping check");
|
||||
continue;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
let cursor_inside = is_cursor_in_window(&window).await;
|
||||
let modifier_pressed = is_modifier_pressed();
|
||||
|
||||
log::info!(
|
||||
"Cursor inside: {}, Modifier pressed: {}",
|
||||
cursor_inside,
|
||||
modifier_pressed
|
||||
);
|
||||
|
||||
// Only allow disabling click-through when:
|
||||
// 1. Cursor is OUTSIDE the window AND
|
||||
// 2. Modifier key is pressed
|
||||
let should_be_click_through = cursor_inside && !modifier_pressed;
|
||||
|
||||
if should_be_click_through {
|
||||
let _ = set_cursor_inside(&window, true);
|
||||
} else {
|
||||
let _ = set_cursor_inside(&window, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn stop_monitor_for_clicking_through(window: tauri::Window) -> Result<(), String> {
|
||||
log::info!("Stopping monitor for clicking through");
|
||||
|
||||
let window = window.clone();
|
||||
let state = window.state::<WindowClickThroughState>();
|
||||
|
||||
// Set to false
|
||||
// Termination will be triggered in the next interval check (tick)
|
||||
state
|
||||
.is_click_through_monitoring_enabled
|
||||
.store(false, Ordering::Relaxed);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn start_click_through(window: tauri::Window) -> Result<(), String> {
|
||||
set_click_through_enabled(&window, true)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn stop_click_through(window: tauri::Window) -> Result<(), String> {
|
||||
set_click_through_enabled(&window, false)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
let prevent_default_plugin = tauri_plugin_prevent_default::Builder::new()
|
||||
|
|
@ -21,6 +241,7 @@ pub fn run() {
|
|||
.plugin(prevent_default_plugin)
|
||||
.plugin(tauri_plugin_mcp::Builder.build())
|
||||
.plugin(tauri_plugin_os::init())
|
||||
.manage(WindowClickThroughState::default())
|
||||
.setup(|app| {
|
||||
let mut builder = WebviewWindowBuilder::new(app, "main", WebviewUrl::default());
|
||||
|
||||
|
|
@ -98,6 +319,10 @@ pub fn run() {
|
|||
.invoke_handler(tauri::generate_handler![
|
||||
commands::open_settings_window,
|
||||
commands::open_chat_window,
|
||||
start_monitor_for_clicking_through,
|
||||
stop_monitor_for_clicking_through,
|
||||
start_click_through,
|
||||
stop_click_through,
|
||||
])
|
||||
.build(tauri::generate_context!())
|
||||
.expect("error while building tauri application")
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ import { WidgetStage } from '@proj-airi/stage-ui/components'
|
|||
import { useMcpStore } from '@proj-airi/stage-ui/stores'
|
||||
import { connectServer } from '@proj-airi/tauri-plugin-mcp'
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { computed, onMounted } from 'vue'
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
|
||||
import { useWindowShortcuts } from '../composables/window-shortcuts'
|
||||
import { useWindowControlStore } from '../stores/window-controls'
|
||||
|
|
@ -13,6 +14,7 @@ import { WindowControlMode } from '../types/window-controls'
|
|||
const windowStore = useWindowControlStore()
|
||||
useWindowShortcuts()
|
||||
|
||||
const viewRef = ref<HTMLDivElement>()
|
||||
const mcpStore = useMcpStore()
|
||||
const { connected, serverCmd, serverArgs } = storeToRefs(mcpStore)
|
||||
|
||||
|
|
@ -29,6 +31,18 @@ const modeIndicatorClass = computed(() => {
|
|||
}
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
await invoke('start_monitor_for_clicking_through')
|
||||
await invoke('start_click_through')
|
||||
})
|
||||
|
||||
onUnmounted(async () => {
|
||||
await invoke('stop_click_through')
|
||||
await invoke('stop_monitor_for_clicking_through')
|
||||
})
|
||||
|
||||
const unlisten: (() => void)[] = []
|
||||
|
||||
function openSettings() {
|
||||
invoke('open_settings_window')
|
||||
}
|
||||
|
|
@ -38,6 +52,19 @@ function openChat() {
|
|||
}
|
||||
|
||||
onMounted(async () => {
|
||||
// Listen for click-through state changes
|
||||
unlisten.push(await listen('tauri-app:window-click-through:is-inside', (event: { payload: boolean }) => {
|
||||
if (!viewRef.value)
|
||||
return
|
||||
|
||||
if (event.payload) {
|
||||
viewRef.value.style.opacity = '0'
|
||||
}
|
||||
else {
|
||||
viewRef.value.style.opacity = '1'
|
||||
}
|
||||
}))
|
||||
|
||||
if (connected.value)
|
||||
return
|
||||
if (!serverCmd.value || !serverArgs.value)
|
||||
|
|
@ -50,10 +77,15 @@ onMounted(async () => {
|
|||
console.error(error)
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
unlisten.forEach(fn => fn?.())
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
ref="viewRef"
|
||||
:class="[modeIndicatorClass]"
|
||||
relative
|
||||
max-h="[100vh]"
|
||||
|
|
@ -63,6 +95,7 @@ onMounted(async () => {
|
|||
z-2
|
||||
h-full
|
||||
overflow-hidden
|
||||
transition="opacity duration-500 ease-in-out"
|
||||
>
|
||||
<div relative h-full w-full items-end gap-2 class="view">
|
||||
<WidgetStage h-full w-full flex-1 mb="<md:18" />
|
||||
|
|
@ -91,7 +124,6 @@ onMounted(async () => {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Debug Mode UI -->
|
||||
<div v-if="windowStore.controlMode === WindowControlMode.DEBUG" class="debug-controls">
|
||||
<!-- Add debug controls here -->
|
||||
|
|
@ -138,12 +170,7 @@ onMounted(async () => {
|
|||
|
||||
<style scoped>
|
||||
.view {
|
||||
&:hover {
|
||||
.interaction-area {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
}
|
||||
transition: opacity 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
.drag-region {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { ref } from 'vue'
|
|||
import { WindowControlMode } from '../types/window-controls'
|
||||
|
||||
export const useWindowControlStore = defineStore('windowControl', () => {
|
||||
const controlMode = ref<WindowControlMode>(WindowControlMode.DEFAULT)
|
||||
const controlMode = ref<WindowControlMode>(WindowControlMode.NONE)
|
||||
const isControlActive = ref(false)
|
||||
const size = useLocalStorage('window/control/size', { width: 300 * 1.5, height: 400 * 1.5 })
|
||||
const position = useLocalStorage('window/control/position', { x: 0, y: 0 })
|
||||
|
|
@ -21,7 +21,7 @@ export const useWindowControlStore = defineStore('windowControl', () => {
|
|||
function toggleControl() {
|
||||
isControlActive.value = !isControlActive.value
|
||||
if (!isControlActive.value) {
|
||||
controlMode.value = WindowControlMode.DEFAULT
|
||||
controlMode.value = WindowControlMode.NONE
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
export enum WindowControlMode {
|
||||
DEFAULT = 'default',
|
||||
NONE = 'none',
|
||||
MOVE = 'move',
|
||||
RESIZE = 'resize',
|
||||
DEBUG = 'debug',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue