commit
e02dd2940c
@ -51,6 +51,9 @@ class RawPointerMouseRegion extends StatelessWidget {
|
|||||||
onPointerUp: inputModel.onPointUpImage,
|
onPointerUp: inputModel.onPointUpImage,
|
||||||
onPointerMove: inputModel.onPointMoveImage,
|
onPointerMove: inputModel.onPointMoveImage,
|
||||||
onPointerSignal: inputModel.onPointerSignalImage,
|
onPointerSignal: inputModel.onPointerSignalImage,
|
||||||
|
onPointerPanZoomStart: inputModel.onPointerPanZoomStart,
|
||||||
|
onPointerPanZoomUpdate: inputModel.onPointerPanZoomUpdate,
|
||||||
|
onPointerPanZoomEnd: inputModel.onPointerPanZoomEnd,
|
||||||
child: MouseRegion(
|
child: MouseRegion(
|
||||||
cursor: cursor ?? MouseCursor.defer,
|
cursor: cursor ?? MouseCursor.defer,
|
||||||
onEnter: onEnter,
|
onEnter: onEnter,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'dart:ui' as ui;
|
import 'dart:ui' as ui;
|
||||||
@ -39,6 +40,10 @@ class InputModel {
|
|||||||
var alt = false;
|
var alt = false;
|
||||||
var command = false;
|
var command = false;
|
||||||
|
|
||||||
|
// trackpad
|
||||||
|
var trackpadScrollDistance = Offset.zero;
|
||||||
|
Timer? _flingTimer;
|
||||||
|
|
||||||
// mouse
|
// mouse
|
||||||
final isPhysicalMouse = false.obs;
|
final isPhysicalMouse = false.obs;
|
||||||
int _lastMouseDownButtons = 0;
|
int _lastMouseDownButtons = 0;
|
||||||
@ -236,6 +241,7 @@ class InputModel {
|
|||||||
if (!enter) {
|
if (!enter) {
|
||||||
resetModifiers();
|
resetModifiers();
|
||||||
}
|
}
|
||||||
|
_flingTimer?.cancel();
|
||||||
bind.sessionEnterOrLeave(id: id, enter: enter);
|
bind.sessionEnterOrLeave(id: id, enter: enter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,6 +264,57 @@ class InputModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _signOrZero(num x) {
|
||||||
|
if (x == 0) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return x > 0 ? 1 : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onPointerPanZoomStart(PointerPanZoomStartEvent e) {}
|
||||||
|
|
||||||
|
// https://docs.flutter.dev/release/breaking-changes/trackpad-gestures
|
||||||
|
// TODO(support zoom in/out)
|
||||||
|
void onPointerPanZoomUpdate(PointerPanZoomUpdateEvent e) {
|
||||||
|
var delta = e.panDelta;
|
||||||
|
trackpadScrollDistance += delta;
|
||||||
|
bind.sessionSendMouse(
|
||||||
|
id: id,
|
||||||
|
msg:
|
||||||
|
'{"type": "trackpad", "x": "${delta.dx.toInt()}", "y": "${delta.dy.toInt()}"}');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simple simulation for fling.
|
||||||
|
void _scheduleFling(var x, y, dx, dy) {
|
||||||
|
if (dx <= 0 && dy <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_flingTimer = Timer(Duration(milliseconds: 10), () {
|
||||||
|
bind.sessionSendMouse(
|
||||||
|
id: id, msg: '{"type": "trackpad", "x": "$x", "y": "$y"}');
|
||||||
|
dx--;
|
||||||
|
dy--;
|
||||||
|
if (dx == 0) {
|
||||||
|
x = 0;
|
||||||
|
}
|
||||||
|
if (dy == 0) {
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
_scheduleFling(x, y, dx, dy);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void onPointerPanZoomEnd(PointerPanZoomEndEvent e) {
|
||||||
|
var x = _signOrZero(trackpadScrollDistance.dx);
|
||||||
|
var y = _signOrZero(trackpadScrollDistance.dy);
|
||||||
|
var dx = trackpadScrollDistance.dx.abs() ~/ 40;
|
||||||
|
var dy = trackpadScrollDistance.dy.abs() ~/ 40;
|
||||||
|
_scheduleFling(x, y, dx, dy);
|
||||||
|
|
||||||
|
trackpadScrollDistance = Offset.zero;
|
||||||
|
}
|
||||||
|
|
||||||
void onPointDownImage(PointerDownEvent e) {
|
void onPointDownImage(PointerDownEvent e) {
|
||||||
debugPrint("onPointDownImage");
|
debugPrint("onPointDownImage");
|
||||||
if (e.kind != ui.PointerDeviceKind.mouse) {
|
if (e.kind != ui.PointerDeviceKind.mouse) {
|
||||||
|
@ -580,6 +580,63 @@ impl Enigo {
|
|||||||
_ => u16::MAX,
|
_ => u16::MAX,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mouse_scroll_impl(&mut self, length: i32, is_track_pad: bool, is_horizontal: bool) {
|
||||||
|
let mut scroll_direction = -1; // 1 left -1 right;
|
||||||
|
let mut length = length;
|
||||||
|
|
||||||
|
if length < 0 {
|
||||||
|
length *= -1;
|
||||||
|
scroll_direction *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fix scroll distance for track pad
|
||||||
|
if is_track_pad {
|
||||||
|
length *= 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(src) = self.event_source.as_ref() {
|
||||||
|
for _ in 0..length {
|
||||||
|
unsafe {
|
||||||
|
let units = if is_track_pad {
|
||||||
|
ScrollUnit::Pixel
|
||||||
|
} else {
|
||||||
|
ScrollUnit::Line
|
||||||
|
};
|
||||||
|
let mouse_ev = if is_horizontal {
|
||||||
|
CGEventCreateScrollWheelEvent(
|
||||||
|
&src,
|
||||||
|
units,
|
||||||
|
2, // CGWheelCount 1 = y 2 = xy 3 = xyz
|
||||||
|
0,
|
||||||
|
scroll_direction,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
CGEventCreateScrollWheelEvent(
|
||||||
|
&src,
|
||||||
|
units,
|
||||||
|
1, // CGWheelCount 1 = y 2 = xy 3 = xyz
|
||||||
|
scroll_direction,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
CGEventPost(CGEventTapLocation::HID, mouse_ev);
|
||||||
|
CFRelease(mouse_ev as *const std::ffi::c_void);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// handle scroll vertically
|
||||||
|
pub fn mouse_scroll_y(&mut self, length: i32, is_track_pad: bool) {
|
||||||
|
self.mouse_scroll_impl(length, is_track_pad, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// handle scroll horizontally
|
||||||
|
pub fn mouse_scroll_x(&mut self, length: i32, is_track_pad: bool) {
|
||||||
|
self.mouse_scroll_impl(length, is_track_pad, true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1572,13 +1572,37 @@ pub async fn handle_test_delay(t: TestDelay, peer: &mut Stream) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether is track pad scrolling.
|
||||||
|
#[inline]
|
||||||
|
#[cfg(all(target_os = "macos"))]
|
||||||
|
fn check_scroll_on_mac(mask: i32, x: i32, y: i32) -> bool {
|
||||||
|
// flutter version we set mask type bit to 4 when track pad scrolling.
|
||||||
|
if mask & 7 == 4 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if mask & 3 != 3 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let btn = mask >> 3;
|
||||||
|
if y == -1 {
|
||||||
|
btn != 0xff88 && btn != -0x780000
|
||||||
|
} else if y == 1 {
|
||||||
|
btn != 0x78 && btn != 0x780000
|
||||||
|
} else if x != 0 {
|
||||||
|
// No mouse support horizontal scrolling.
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Send mouse data.
|
/// Send mouse data.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `mask` - Mouse event.
|
/// * `mask` - Mouse event.
|
||||||
/// * mask = buttons << 3 | type
|
/// * mask = buttons << 3 | type
|
||||||
/// * type, 1: down, 2: up, 3: wheel
|
/// * type, 1: down, 2: up, 3: wheel, 4: trackpad
|
||||||
/// * buttons, 1: left, 2: right, 4: middle
|
/// * buttons, 1: left, 2: right, 4: middle
|
||||||
/// * `x` - X coordinate.
|
/// * `x` - X coordinate.
|
||||||
/// * `y` - Y coordinate.
|
/// * `y` - Y coordinate.
|
||||||
@ -1617,6 +1641,10 @@ pub fn send_mouse(
|
|||||||
if command {
|
if command {
|
||||||
mouse_event.modifiers.push(ControlKey::Meta.into());
|
mouse_event.modifiers.push(ControlKey::Meta.into());
|
||||||
}
|
}
|
||||||
|
#[cfg(all(target_os = "macos"))]
|
||||||
|
if check_scroll_on_mac(mask, x, y) {
|
||||||
|
mouse_event.modifiers.push(ControlKey::Scroll.into());
|
||||||
|
}
|
||||||
msg_out.set_mouse_event(mouse_event);
|
msg_out.set_mouse_event(mouse_event);
|
||||||
interface.send(Data::Message(msg_out));
|
interface.send(Data::Message(msg_out));
|
||||||
}
|
}
|
||||||
|
@ -156,6 +156,7 @@ pub fn session_reconnect(id: String) {
|
|||||||
|
|
||||||
pub fn session_toggle_option(id: String, value: String) {
|
pub fn session_toggle_option(id: String, value: String) {
|
||||||
if let Some(session) = SESSIONS.write().unwrap().get_mut(&id) {
|
if let Some(session) = SESSIONS.write().unwrap().get_mut(&id) {
|
||||||
|
log::warn!("toggle option {}", value);
|
||||||
session.toggle_option(value);
|
session.toggle_option(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -907,6 +908,7 @@ pub fn session_send_mouse(id: String, msg: String) {
|
|||||||
"down" => 1,
|
"down" => 1,
|
||||||
"up" => 2,
|
"up" => 2,
|
||||||
"wheel" => 3,
|
"wheel" => 3,
|
||||||
|
"trackpad" => 4,
|
||||||
_ => 0,
|
_ => 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -513,7 +513,7 @@ pub fn handle_mouse_(evt: &MouseEvent) {
|
|||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
3 => {
|
3 | 4 => {
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
let mut x = evt.x;
|
let mut x = evt.x;
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -523,21 +523,39 @@ pub fn handle_mouse_(evt: &MouseEvent) {
|
|||||||
x = -x;
|
x = -x;
|
||||||
y = -y;
|
y = -y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fix shift + scroll(down/up)
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
if evt
|
|
||||||
.modifiers
|
|
||||||
.contains(&EnumOrUnknown::new(ControlKey::Shift))
|
|
||||||
{
|
{
|
||||||
x = y;
|
// TODO: support track pad on win.
|
||||||
y = 0;
|
let is_track_pad = evt
|
||||||
|
.modifiers
|
||||||
|
.contains(&EnumOrUnknown::new(ControlKey::Scroll));
|
||||||
|
|
||||||
|
// fix shift + scroll(down/up)
|
||||||
|
if !is_track_pad
|
||||||
|
&& evt
|
||||||
|
.modifiers
|
||||||
|
.contains(&EnumOrUnknown::new(ControlKey::Shift))
|
||||||
|
{
|
||||||
|
x = y;
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if x != 0 {
|
||||||
|
en.mouse_scroll_x(x, is_track_pad);
|
||||||
|
}
|
||||||
|
if y != 0 {
|
||||||
|
en.mouse_scroll_y(y, is_track_pad);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if x != 0 {
|
|
||||||
en.mouse_scroll_x(x);
|
#[cfg(not(target_os = "macos"))]
|
||||||
}
|
{
|
||||||
if y != 0 {
|
if x != 0 {
|
||||||
en.mouse_scroll_y(y);
|
en.mouse_scroll_x(x);
|
||||||
|
}
|
||||||
|
if y != 0 {
|
||||||
|
en.mouse_scroll_y(y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user