mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-04-02 19:41:28 +03:00
Compare commits
4 Commits
emulate-do
...
macos-capt
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
138c43febd | ||
|
|
f91b6bd3c1 | ||
|
|
2d1a037eba | ||
|
|
057f6e2567 |
@@ -40,6 +40,7 @@ struct InputCaptureState {
|
|||||||
active_clients: Lazy<HashSet<Position>>,
|
active_clients: Lazy<HashSet<Position>>,
|
||||||
current_pos: Option<Position>,
|
current_pos: Option<Position>,
|
||||||
bounds: Bounds,
|
bounds: Bounds,
|
||||||
|
modifier_state: XMods,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -57,6 +58,7 @@ impl InputCaptureState {
|
|||||||
active_clients: Lazy::new(HashSet::new),
|
active_clients: Lazy::new(HashSet::new),
|
||||||
current_pos: None,
|
current_pos: None,
|
||||||
bounds: Bounds::default(),
|
bounds: Bounds::default(),
|
||||||
|
modifier_state: Default::default(),
|
||||||
};
|
};
|
||||||
res.update_bounds()?;
|
res.update_bounds()?;
|
||||||
Ok(res)
|
Ok(res)
|
||||||
@@ -180,6 +182,7 @@ fn get_events(
|
|||||||
ev_type: &CGEventType,
|
ev_type: &CGEventType,
|
||||||
ev: &CGEvent,
|
ev: &CGEvent,
|
||||||
result: &mut Vec<CaptureEvent>,
|
result: &mut Vec<CaptureEvent>,
|
||||||
|
modifier_state: &mut XMods,
|
||||||
) -> Result<(), CaptureError> {
|
) -> Result<(), CaptureError> {
|
||||||
fn map_pointer_event(ev: &CGEvent) -> PointerEvent {
|
fn map_pointer_event(ev: &CGEvent) -> PointerEvent {
|
||||||
PointerEvent::Motion {
|
PointerEvent::Motion {
|
||||||
@@ -215,29 +218,42 @@ fn get_events(
|
|||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
CGEventType::FlagsChanged => {
|
CGEventType::FlagsChanged => {
|
||||||
let mut mods = XMods::empty();
|
let mut depressed = XMods::empty();
|
||||||
let mut mods_locked = XMods::empty();
|
let mut mods_locked = XMods::empty();
|
||||||
let cg_flags = ev.get_flags();
|
let cg_flags = ev.get_flags();
|
||||||
|
|
||||||
if cg_flags.contains(CGEventFlags::CGEventFlagShift) {
|
if cg_flags.contains(CGEventFlags::CGEventFlagShift) {
|
||||||
mods |= XMods::ShiftMask;
|
depressed |= XMods::ShiftMask;
|
||||||
}
|
}
|
||||||
if cg_flags.contains(CGEventFlags::CGEventFlagControl) {
|
if cg_flags.contains(CGEventFlags::CGEventFlagControl) {
|
||||||
mods |= XMods::ControlMask;
|
depressed |= XMods::ControlMask;
|
||||||
}
|
}
|
||||||
if cg_flags.contains(CGEventFlags::CGEventFlagAlternate) {
|
if cg_flags.contains(CGEventFlags::CGEventFlagAlternate) {
|
||||||
mods |= XMods::Mod1Mask;
|
depressed |= XMods::Mod1Mask;
|
||||||
}
|
}
|
||||||
if cg_flags.contains(CGEventFlags::CGEventFlagCommand) {
|
if cg_flags.contains(CGEventFlags::CGEventFlagCommand) {
|
||||||
mods |= XMods::Mod4Mask;
|
depressed |= XMods::Mod4Mask;
|
||||||
}
|
}
|
||||||
if cg_flags.contains(CGEventFlags::CGEventFlagAlphaShift) {
|
if cg_flags.contains(CGEventFlags::CGEventFlagAlphaShift) {
|
||||||
mods |= XMods::LockMask;
|
depressed |= XMods::LockMask;
|
||||||
mods_locked |= XMods::LockMask;
|
mods_locked |= XMods::LockMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if pressed or released
|
||||||
|
let state = if depressed > *modifier_state { 1 } else { 0 };
|
||||||
|
*modifier_state = depressed;
|
||||||
|
|
||||||
|
if let Ok(key) = map_key(ev) {
|
||||||
|
let key_event = CaptureEvent::Input(Event::Keyboard(KeyboardEvent::Key {
|
||||||
|
time: 0,
|
||||||
|
key,
|
||||||
|
state,
|
||||||
|
}));
|
||||||
|
result.push(key_event);
|
||||||
|
}
|
||||||
|
|
||||||
let modifier_event = KeyboardEvent::Modifiers {
|
let modifier_event = KeyboardEvent::Modifiers {
|
||||||
depressed: mods.bits(),
|
depressed: depressed.bits(),
|
||||||
latched: 0,
|
latched: 0,
|
||||||
locked: mods_locked.bits(),
|
locked: mods_locked.bits(),
|
||||||
group: 0,
|
group: 0,
|
||||||
@@ -366,7 +382,13 @@ fn create_event_tap<'a>(
|
|||||||
// Are we in a client?
|
// Are we in a client?
|
||||||
if let Some(current_pos) = state.current_pos {
|
if let Some(current_pos) = state.current_pos {
|
||||||
pos = Some(current_pos);
|
pos = Some(current_pos);
|
||||||
get_events(&event_type, cg_ev, &mut res_events).unwrap_or_else(|e| {
|
get_events(
|
||||||
|
&event_type,
|
||||||
|
cg_ev,
|
||||||
|
&mut res_events,
|
||||||
|
&mut state.modifier_state,
|
||||||
|
)
|
||||||
|
.unwrap_or_else(|e| {
|
||||||
log::error!("Failed to get events: {e}");
|
log::error!("Failed to get events: {e}");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ impl MacOSEmulation {
|
|||||||
button_state,
|
button_state,
|
||||||
previous_button: None,
|
previous_button: None,
|
||||||
previous_button_click: None,
|
previous_button_click: None,
|
||||||
button_click_state: 1,
|
button_click_state: 0,
|
||||||
repeat_task: None,
|
repeat_task: None,
|
||||||
notify_repeat_task: Arc::new(Notify::new()),
|
notify_repeat_task: Arc::new(Notify::new()),
|
||||||
modifier_state: Rc::new(Cell::new(XMods::empty())),
|
modifier_state: Rc::new(Cell::new(XMods::empty())),
|
||||||
@@ -104,6 +104,9 @@ impl MacOSEmulation {
|
|||||||
// there can only be one repeating key and it's
|
// there can only be one repeating key and it's
|
||||||
// always the last to be pressed
|
// always the last to be pressed
|
||||||
self.cancel_repeat_task().await;
|
self.cancel_repeat_task().await;
|
||||||
|
// initial key event
|
||||||
|
key_event(self.event_source.clone(), key, 1, self.modifier_state.get());
|
||||||
|
// repeat task
|
||||||
let event_source = self.event_source.clone();
|
let event_source = self.event_source.clone();
|
||||||
let notify = self.notify_repeat_task.clone();
|
let notify = self.notify_repeat_task.clone();
|
||||||
let modifiers = self.modifier_state.clone();
|
let modifiers = self.modifier_state.clone();
|
||||||
@@ -239,8 +242,10 @@ impl Emulation for MacOSEmulation {
|
|||||||
event: Event,
|
event: Event,
|
||||||
_handle: EmulationHandle,
|
_handle: EmulationHandle,
|
||||||
) -> Result<(), EmulationError> {
|
) -> Result<(), EmulationError> {
|
||||||
|
log::trace!("{event:?}");
|
||||||
match event {
|
match event {
|
||||||
Event::Pointer(pointer_event) => match pointer_event {
|
Event::Pointer(pointer_event) => {
|
||||||
|
match pointer_event {
|
||||||
PointerEvent::Motion { time: _, dx, dy } => {
|
PointerEvent::Motion { time: _, dx, dy } => {
|
||||||
let mut mouse_location = match self.get_mouse_location() {
|
let mut mouse_location = match self.get_mouse_location() {
|
||||||
Some(l) => l,
|
Some(l) => l,
|
||||||
@@ -391,7 +396,13 @@ impl Emulation for MacOSEmulation {
|
|||||||
};
|
};
|
||||||
event.post(CGEventTapLocation::HID);
|
event.post(CGEventTapLocation::HID);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
|
// reset button click state in case it's not a button event
|
||||||
|
if !matches!(pointer_event, PointerEvent::Button { .. }) {
|
||||||
|
self.button_click_state = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
Event::Keyboard(keyboard_event) => match keyboard_event {
|
Event::Keyboard(keyboard_event) => match keyboard_event {
|
||||||
KeyboardEvent::Key {
|
KeyboardEvent::Key {
|
||||||
time: _,
|
time: _,
|
||||||
@@ -405,18 +416,12 @@ impl Emulation for MacOSEmulation {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
update_modifiers(&self.modifier_state, key, state);
|
||||||
match state {
|
match state {
|
||||||
// pressed
|
// pressed
|
||||||
1 => self.spawn_repeat_task(code).await,
|
1 => self.spawn_repeat_task(code).await,
|
||||||
_ => self.cancel_repeat_task().await,
|
_ => self.cancel_repeat_task().await,
|
||||||
}
|
}
|
||||||
update_modifiers(&self.modifier_state, key, state);
|
|
||||||
key_event(
|
|
||||||
self.event_source.clone(),
|
|
||||||
code,
|
|
||||||
state,
|
|
||||||
self.modifier_state.get(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
KeyboardEvent::Modifiers {
|
KeyboardEvent::Modifiers {
|
||||||
depressed,
|
depressed,
|
||||||
|
|||||||
Reference in New Issue
Block a user