os_monitor/
event.rs

1use serde::{Deserialize, Serialize};
2use std::sync::Mutex;
3
4#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
5pub enum Platform {
6    Mac,
7    Windows,
8    Linux,
9}
10
11#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
12pub enum MouseEventType {
13    Move,
14    LeftDown,
15    LeftUp,
16    RightDown,
17    RightUp,
18    MiddleDown,
19    MiddleUp,
20    Scroll,
21}
22
23impl TryFrom<i32> for MouseEventType {
24    type Error = &'static str;
25
26    fn try_from(value: i32) -> Result<Self, Self::Error> {
27        match value {
28            0 => Ok(MouseEventType::Move),
29            1 => Ok(MouseEventType::LeftDown),
30            2 => Ok(MouseEventType::LeftUp),
31            3 => Ok(MouseEventType::RightDown),
32            4 => Ok(MouseEventType::RightUp),
33            5 => Ok(MouseEventType::MiddleDown),
34            6 => Ok(MouseEventType::MiddleUp),
35            7 => Ok(MouseEventType::Scroll),
36            _ => Err("Invalid mouse event type"),
37        }
38    }
39}
40
41#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
42pub enum WindowEventType {
43    Focused,
44    TitleChanged,
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize)]
48pub struct MouseEvent {}
49
50#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct KeyboardEvent {}
52
53#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct WindowEvent {
55    pub app_name: String,
56    pub window_title: String,
57    pub bundle_id: Option<String>,
58    pub url: Option<String>,
59    pub platform: Platform,
60}
61
62#[derive(Debug, Clone, Serialize, Deserialize)]
63pub struct BlockedApp {
64    pub app_name: String,
65    pub app_external_id: String,
66    pub is_site: bool,
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct BlockedAppEvent {
71    pub blocked_apps: Vec<BlockedApp>,
72}
73
74pub trait EventCallback: Send + Sync {
75    fn on_mouse_events(&self, has_activity: bool);
76    fn on_keyboard_events(&self, has_activity: bool);
77    fn on_window_event(&self, event: WindowEvent);
78    fn on_app_blocked(&self, event: BlockedAppEvent);
79}
80
81pub struct Monitor {
82    mouse_callbacks: Mutex<Vec<Box<dyn Fn(bool) + Send + Sync>>>,
83    keyboard_callbacks: Mutex<Vec<Box<dyn Fn(bool) + Send + Sync>>>,
84    window_callbacks: Mutex<Vec<Box<dyn Fn(WindowEvent) + Send + Sync>>>,
85    app_blocked_callbacks: Mutex<Vec<Box<dyn Fn(BlockedAppEvent) + Send + Sync>>>,
86}
87
88impl Monitor {
89    pub fn new() -> Self {
90        Self {
91            mouse_callbacks: Mutex::new(Vec::new()),
92            keyboard_callbacks: Mutex::new(Vec::new()),
93            window_callbacks: Mutex::new(Vec::new()),
94            app_blocked_callbacks: Mutex::new(Vec::new()),
95        }
96    }
97
98    pub fn register_keyboard_callback(&self, callback: Box<dyn Fn(bool) + Send + Sync>) {
99        self.keyboard_callbacks.lock().unwrap().push(callback);
100    }
101
102    pub fn register_mouse_callback(&self, callback: Box<dyn Fn(bool) + Send + Sync>) {
103        self.mouse_callbacks.lock().unwrap().push(callback);
104    }
105
106    pub fn register_window_callback(&self, callback: Box<dyn Fn(WindowEvent) + Send + Sync>) {
107        self.window_callbacks.lock().unwrap().push(callback);
108    }
109
110    pub fn register_app_blocked_callback(
111        &self,
112        callback: Box<dyn Fn(BlockedAppEvent) + Send + Sync>,
113    ) {
114        self.app_blocked_callbacks.lock().unwrap().push(callback);
115    }
116}
117
118impl EventCallback for Monitor {
119    fn on_mouse_events(&self, has_activity: bool) {
120        let mut callbacks = self.mouse_callbacks.lock().unwrap();
121        for callback in callbacks.iter_mut() {
122            callback(has_activity);
123        }
124    }
125
126    fn on_keyboard_events(&self, has_activity: bool) {
127        let mut callbacks = self.keyboard_callbacks.lock().unwrap();
128        for callback in callbacks.iter_mut() {
129            callback(has_activity);
130        }
131    }
132
133    fn on_window_event(&self, event: WindowEvent) {
134        let mut callbacks = self.window_callbacks.lock().unwrap();
135        for callback in callbacks.iter_mut() {
136            callback(event.clone());
137        }
138    }
139
140    fn on_app_blocked(&self, event: BlockedAppEvent) {
141        let callbacks = self.app_blocked_callbacks.lock().unwrap();
142        for callback in callbacks.iter() {
143            callback(event.clone());
144        }
145    }
146}