Skip to main content

lingxia_platform/traits/
mouse.rs

1use crate::error::PlatformError;
2use async_trait::async_trait;
3use serde::{Deserialize, Serialize};
4
5/// Mouse button used by app-level devtool input.
6#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
7#[serde(rename_all = "snake_case")]
8pub enum AppMouseButton {
9    #[default]
10    Left,
11    Right,
12    Middle,
13}
14
15/// App-window mouse action.
16///
17/// Coordinates are logical points in the target window content area, with
18/// origin at the top-left corner of the same visual content captured by
19/// `AppScreenshot::take_app_screenshot`.
20#[derive(Debug, Clone, Serialize, Deserialize)]
21#[serde(tag = "kind", rename_all = "snake_case")]
22pub enum AppMouseAction {
23    Move {
24        x: f64,
25        y: f64,
26    },
27    Down {
28        x: f64,
29        y: f64,
30        #[serde(default)]
31        button: AppMouseButton,
32    },
33    Up {
34        x: f64,
35        y: f64,
36        #[serde(default)]
37        button: AppMouseButton,
38    },
39    Click {
40        x: f64,
41        y: f64,
42        #[serde(default)]
43        button: AppMouseButton,
44        #[serde(default = "default_click_count")]
45        click_count: u8,
46    },
47    Drag {
48        from_x: f64,
49        from_y: f64,
50        to_x: f64,
51        to_y: f64,
52        #[serde(default)]
53        button: AppMouseButton,
54    },
55    Scroll {
56        x: f64,
57        y: f64,
58        dx: f64,
59        dy: f64,
60    },
61}
62
63fn default_click_count() -> u8 {
64    1
65}
66
67impl AppMouseAction {
68    pub fn kind(&self) -> &'static str {
69        match self {
70            Self::Move { .. } => "move",
71            Self::Down { .. } => "down",
72            Self::Up { .. } => "up",
73            Self::Click { .. } => "click",
74            Self::Drag { .. } => "drag",
75            Self::Scroll { .. } => "scroll",
76        }
77    }
78}
79
80#[derive(Debug, Clone, Serialize, Deserialize)]
81pub struct AppMouseRequest {
82    #[serde(default, skip_serializing_if = "Option::is_none")]
83    pub window_id: Option<String>,
84    pub action: AppMouseAction,
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
88pub struct AppMouseResult {
89    pub window_id: String,
90    pub action: String,
91}
92
93/// Dispatch mouse input to the host app's top-level window.
94///
95/// This is intentionally app/window-level, not LxApp-level: it can target
96/// native chrome, overlays, WebViews, and future desktop shells consistently.
97#[async_trait]
98pub trait AppMouse: Send + Sync {
99    async fn perform_app_mouse(
100        &self,
101        request: AppMouseRequest,
102    ) -> Result<AppMouseResult, PlatformError> {
103        let _ = request;
104        Err(PlatformError::NotSupported(
105            "app mouse input is not implemented for this platform".to_string(),
106        ))
107    }
108}