very wonky but works pet menu dismiss flow
This commit is contained in:
133
src-tauri/Cargo.lock
generated
133
src-tauri/Cargo.lock
generated
@@ -602,6 +602,19 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-graphics"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "064badf302c3194842cf2c5d61f56cc88e54a759313879cdf03abdd27d0c3b97"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"core-foundation 0.10.1",
|
||||
"core-graphics-types",
|
||||
"foreign-types 0.5.0",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-graphics-types"
|
||||
version = "0.2.0"
|
||||
@@ -967,6 +980,31 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf"
|
||||
|
||||
[[package]]
|
||||
name = "enigo"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71c6c56e50f7acae2906a0dcbb34529ca647e40421119ad5d12e7f8ba6e50010"
|
||||
dependencies = [
|
||||
"core-foundation 0.10.1",
|
||||
"core-graphics 0.25.0",
|
||||
"foreign-types-shared 0.3.1",
|
||||
"libc",
|
||||
"log",
|
||||
"nom",
|
||||
"objc2 0.6.3",
|
||||
"objc2-app-kit",
|
||||
"objc2-foundation 0.3.2",
|
||||
"tempfile",
|
||||
"wayland-client",
|
||||
"wayland-protocols-misc",
|
||||
"wayland-protocols-wlr",
|
||||
"windows 0.61.3",
|
||||
"x11rb",
|
||||
"xkbcommon",
|
||||
"xkeysym",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enumflags2"
|
||||
version = "0.7.12"
|
||||
@@ -1141,6 +1179,7 @@ dependencies = [
|
||||
"base64 0.22.1",
|
||||
"device_query",
|
||||
"dotenvy",
|
||||
"enigo",
|
||||
"flate2",
|
||||
"gif",
|
||||
"image",
|
||||
@@ -2302,6 +2341,15 @@ version = "2.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
||||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
version = "0.9.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.9.1"
|
||||
@@ -2441,6 +2489,15 @@ version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "8.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.50.3"
|
||||
@@ -3066,7 +3123,7 @@ checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"indexmap 2.12.0",
|
||||
"quick-xml 0.38.4",
|
||||
"quick-xml",
|
||||
"serde",
|
||||
"time",
|
||||
]
|
||||
@@ -3204,15 +3261,6 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.37.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.38.4"
|
||||
@@ -4037,7 +4085,7 @@ checksum = "18051cdd562e792cad055119e0cdb2cfc137e44e3987532e0f9659a77931bb08"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"cfg_aliases",
|
||||
"core-graphics",
|
||||
"core-graphics 0.24.0",
|
||||
"foreign-types 0.5.0",
|
||||
"js-sys",
|
||||
"log",
|
||||
@@ -4222,7 +4270,7 @@ dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"block2 0.6.2",
|
||||
"core-foundation 0.10.1",
|
||||
"core-graphics",
|
||||
"core-graphics 0.24.0",
|
||||
"crossbeam-channel",
|
||||
"dispatch",
|
||||
"dlopen2",
|
||||
@@ -5385,9 +5433,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wayland-backend"
|
||||
version = "0.3.11"
|
||||
version = "0.3.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "673a33c33048a5ade91a6b139580fa174e19fb0d23f396dca9fa15f2e1e49b35"
|
||||
checksum = "fee64194ccd96bf648f42a65a7e589547096dfa702f7cadef84347b66ad164f9"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"downcast-rs",
|
||||
@@ -5399,9 +5447,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wayland-client"
|
||||
version = "0.31.11"
|
||||
version = "0.31.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d"
|
||||
checksum = "b8e6faa537fbb6c186cb9f1d41f2f811a4120d1b57ec61f50da451a0c5122bec"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"rustix",
|
||||
@@ -5411,9 +5459,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wayland-protocols"
|
||||
version = "0.32.9"
|
||||
version = "0.32.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901"
|
||||
checksum = "baeda9ffbcfc8cd6ddaade385eaf2393bd2115a69523c735f12242353c3df4f3"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"wayland-backend",
|
||||
@@ -5422,21 +5470,47 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-scanner"
|
||||
version = "0.31.7"
|
||||
name = "wayland-protocols-misc"
|
||||
version = "0.3.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54cb1e9dc49da91950bdfd8b848c49330536d9d1fb03d4bfec8cae50caa50ae3"
|
||||
checksum = "791c58fdeec5406aa37169dd815327d1e47f334219b523444bc26d70ceb4c34e"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
"wayland-protocols",
|
||||
"wayland-scanner",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-protocols-wlr"
|
||||
version = "0.3.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9597cdf02cf0c34cd5823786dce6b5ae8598f05c2daf5621b6e178d4f7345f3"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
"wayland-protocols",
|
||||
"wayland-scanner",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-scanner"
|
||||
version = "0.31.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5423e94b6a63e68e439803a3e153a9252d5ead12fd853334e2ad33997e3889e3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quick-xml 0.37.5",
|
||||
"quick-xml",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-sys"
|
||||
version = "0.31.7"
|
||||
version = "0.31.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34949b42822155826b41db8e5d0c1be3a2bd296c747577a43a3e6daefc296142"
|
||||
checksum = "1e6dbfc3ac5ef974c92a2235805cc0114033018ae1290a72e474aa8b28cbbdfd"
|
||||
dependencies = [
|
||||
"dlib",
|
||||
"log",
|
||||
@@ -6206,6 +6280,17 @@ version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd"
|
||||
|
||||
[[package]]
|
||||
name = "xkbcommon"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a974f48060a14e95705c01f24ad9c3345022f4d97441b8a36beb7ed5c4a02d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"memmap2",
|
||||
"xkeysym",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xkeysym"
|
||||
version = "0.2.1"
|
||||
|
||||
@@ -47,6 +47,7 @@ tauri-plugin-dialog = "2.4.2"
|
||||
image = {version = "0.25.9", default-features = false, features = ["gif"] }
|
||||
gif = "0.14.1"
|
||||
raw-window-handle = "0.6"
|
||||
enigo = { version = "0.6.1", features = ["wayland"] }
|
||||
|
||||
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
||||
tauri-plugin-global-shortcut = "2"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use device_query::{DeviceEvents, DeviceEventsHandler};
|
||||
use once_cell::sync::OnceCell;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
use tauri::Emitter;
|
||||
use tokio::sync::mpsc;
|
||||
@@ -26,6 +27,15 @@ pub struct CursorPositions {
|
||||
}
|
||||
|
||||
static CURSOR_TRACKER: OnceCell<()> = OnceCell::new();
|
||||
static LATEST_CURSOR_POSITION: OnceCell<Arc<Mutex<Option<CursorPosition>>>> = OnceCell::new();
|
||||
|
||||
/// Get the latest known cursor position (thread-safe)
|
||||
pub fn get_latest_cursor_position() -> Option<CursorPosition> {
|
||||
LATEST_CURSOR_POSITION
|
||||
.get()
|
||||
.and_then(|mutex| mutex.lock().ok())
|
||||
.and_then(|guard| guard.clone())
|
||||
}
|
||||
|
||||
/// Convert absolute screen coordinates to normalized coordinates (0.0 - 1.0)
|
||||
pub fn absolute_to_normalized(pos: &CursorPosition) -> CursorPosition {
|
||||
@@ -59,6 +69,9 @@ pub async fn start_cursor_tracking() -> Result<(), String> {
|
||||
|
||||
// Use OnceCell to ensure this only runs once, even if called from multiple windows
|
||||
CURSOR_TRACKER.get_or_init(|| {
|
||||
// Initialize the shared state
|
||||
LATEST_CURSOR_POSITION.get_or_init(|| Arc::new(Mutex::new(None)));
|
||||
|
||||
info!("First call to start_cursor_tracking - spawning cursor tracking task");
|
||||
tauri::async_runtime::spawn(async {
|
||||
if let Err(e) = init_cursor_tracking().await {
|
||||
@@ -134,6 +147,13 @@ async fn init_cursor_tracking() -> Result<(), String> {
|
||||
y: position.1 as f64,
|
||||
};
|
||||
|
||||
// Update global state
|
||||
if let Some(mutex) = LATEST_CURSOR_POSITION.get() {
|
||||
if let Ok(mut guard) = mutex.lock() {
|
||||
*guard = Some(raw.clone());
|
||||
}
|
||||
}
|
||||
|
||||
let mapped = absolute_to_normalized(&raw);
|
||||
|
||||
let positions = CursorPositions { raw, mapped };
|
||||
|
||||
@@ -32,7 +32,7 @@ fn scene_interactive_state() -> Arc<AtomicBool> {
|
||||
.clone()
|
||||
}
|
||||
|
||||
pub fn update_scene_interactive(interactive: bool) {
|
||||
pub fn update_scene_interactive(interactive: bool, should_click: bool) {
|
||||
let app_handle = get_app_handle();
|
||||
|
||||
// If we are forcing interactive to false (e.g. background click), clear any open menus
|
||||
@@ -48,6 +48,27 @@ pub fn update_scene_interactive(interactive: bool) {
|
||||
error!("Failed to toggle scene cursor events: {}", e);
|
||||
}
|
||||
|
||||
if should_click {
|
||||
// Get cursor position on screen and use Enigo to click
|
||||
if let Some(pos) = crate::services::cursor::get_latest_cursor_position() {
|
||||
use enigo::{Button, Direction, Enigo, Mouse, Settings};
|
||||
// Initialize Enigo with default settings, handling potential failure
|
||||
match Enigo::new(&Settings::default()) {
|
||||
Ok(mut enigo) => {
|
||||
// Perform a click (Press and Release)
|
||||
// We ignore the result of the click action itself for now as it usually succeeds if init did
|
||||
let _ = enigo.button(Button::Left, Direction::Click);
|
||||
info!("Simulated click at ({}, {})", pos.x, pos.y);
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to initialize Enigo for clicking: {}", e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warn!("Cannot click: No cursor position available yet");
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(e) = window.emit("scene-interactive", &interactive) {
|
||||
error!("Failed to emit scene interactive event: {}", e);
|
||||
}
|
||||
@@ -57,8 +78,8 @@ pub fn update_scene_interactive(interactive: bool) {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn set_scene_interactive(interactive: bool) {
|
||||
update_scene_interactive(interactive);
|
||||
pub fn set_scene_interactive(interactive: bool, should_click: bool) {
|
||||
update_scene_interactive(interactive, should_click);
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
@@ -68,6 +89,11 @@ pub fn set_pet_menu_state(id: String, open: bool) {
|
||||
if let Ok(mut menus) = menus_arc.lock() {
|
||||
if open {
|
||||
menus.insert(id);
|
||||
get_app_handle()
|
||||
.get_window(SCENE_WINDOW_LABEL)
|
||||
.expect("Scene window should be present")
|
||||
.set_focus()
|
||||
.expect("Scene window should be focused");
|
||||
} else {
|
||||
menus.remove(&id);
|
||||
}
|
||||
@@ -84,7 +110,7 @@ pub fn set_pet_menu_state(id: String, open: bool) {
|
||||
// For now, let the loop handle it to avoid race conditions with key states.
|
||||
// But if we just OPENED a menu, we definitely want to ensure interactive is TRUE.
|
||||
if should_update {
|
||||
update_scene_interactive(true);
|
||||
update_scene_interactive(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +123,7 @@ extern "C" {
|
||||
fn start_scene_modifier_listener() {
|
||||
MODIFIER_LISTENER_INIT.get_or_init(|| {
|
||||
let state = scene_interactive_state();
|
||||
update_scene_interactive(false);
|
||||
update_scene_interactive(false, false);
|
||||
|
||||
let app_handle = get_app_handle().clone();
|
||||
|
||||
@@ -159,7 +185,7 @@ fn start_scene_modifier_listener() {
|
||||
info!("Interactive state changed to: {}", interactive);
|
||||
let previous = state.swap(interactive, Ordering::SeqCst);
|
||||
if previous != interactive {
|
||||
update_scene_interactive(interactive);
|
||||
update_scene_interactive(interactive, false);
|
||||
}
|
||||
last_interactive = interactive;
|
||||
}
|
||||
|
||||
@@ -37,8 +37,11 @@
|
||||
<button
|
||||
class="absolute inset-0 z-10 size-full"
|
||||
aria-label="Deactive scene interactive"
|
||||
onclick={async () => {
|
||||
await invoke("set_scene_interactive", { interactive: false });
|
||||
onmousedown={async () => {
|
||||
await invoke("set_scene_interactive", {
|
||||
interactive: false,
|
||||
shouldClick: true,
|
||||
});
|
||||
}}> </button
|
||||
>
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user