Skip to content

Commit

Permalink
Implement mouse drag for Mac OS
Browse files Browse the repository at this point in the history
  • Loading branch information
nightscape committed Nov 1, 2024
1 parent 96384c5 commit a1177dd
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 14 deletions.
35 changes: 27 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ kanata-tcp-protocol = { path = "tcp_protocol" }

[target.'cfg(target_os = "macos")'.dependencies]
karabiner-driverkit = "0.1.3"
core-graphics = "0.23.2"
objc = "0.2.7"
core-graphics = "0.24.0"
open = { version = "5", optional = true }

[target.'cfg(target_os = "linux")'.dependencies]
Expand Down
33 changes: 28 additions & 5 deletions src/oskbd/macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use core_graphics::event_source::{CGEventSource, CGEventSourceStateID};
use kanata_parser::custom_action::*;
use kanata_parser::keys::*;
use karabiner_driverkit::*;
use objc::runtime::Class;
use objc::{msg_send, sel, sel_impl};
use std::convert::TryFrom;
use std::fmt;
use std::io;
Expand Down Expand Up @@ -235,7 +237,6 @@ impl KbdOut {
event.post(CGEventTapLocation::AnnotatedSession);
Ok(())
}

pub fn scroll(&mut self, _direction: MWheelDirection, _distance: u16) -> Result<(), io::Error> {
let event = Self::make_event()?;
event.set_type(CGEventType::ScrollWheel);
Expand Down Expand Up @@ -319,16 +320,38 @@ impl KbdOut {
}

pub fn move_mouse(&mut self, _mv: CalculatedMouseMove) -> Result<(), io::Error> {
let pressed = Self::pressed_buttons();

let event_type = if pressed & 1 > 0 {
CGEventType::LeftMouseDragged
} else if pressed & 2 > 0 {
CGEventType::RightMouseDragged
} else {
CGEventType::MouseMoved
};

let event = Self::make_event()?;
let mut mouse_position = event.location();
let display = CGDisplay::main();
Self::apply_calculated_move(&_mv, &mut mouse_position);
display
.move_cursor_to_point(mouse_position)
.map_err(|_| io::Error::new(ErrorKind::Other, "failed to move mouse"))?;
if let Ok(event) = CGEvent::new_mouse_event(
Self::make_event_source()?,
event_type,
mouse_position,
CGMouseButton::Left,
) {
event.post(CGEventTapLocation::HID);
}
Ok(())
}

fn pressed_buttons() -> usize {
if let Some(ns_event) = Class::get("NSEvent") {
unsafe { msg_send![ns_event, pressedMouseButtons] }
} else {
0
}
}

pub fn move_mouse_many(&mut self, _moves: &[CalculatedMouseMove]) -> Result<(), io::Error> {
let event = Self::make_event()?;
let mut mouse_position = event.location();
Expand Down

0 comments on commit a1177dd

Please sign in to comment.