mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-04-11 18:21:28 +03:00
ui: scale wheel lines on Windows/Linux to Mac (#14395)
* input: accelerate wheel bursts on Windows->Mac - boost fast wheel bursts without affecting single-step scrolls\n- use dominant-axis smooth detection and velocity gate\n- reset wheel timestamp on enter/leave\n- enforce single-axis scrolling\n- extract/tune Sciter wheel accel thresholds Signed-off-by: Amirhossein Akhlaghpour <m9.akhlaghpoor@gmail.com> * input: clarify wheel burst tuning - add comments on acceleration rules and units\n- apply burst accel on Windows/Linux to macOS\n- reset wheel timing on enter/leave Signed-off-by: Amirhossein Akhlaghpour <m9.akhlaghpoor@gmail.com> * input: align wheel burst velocity thresholds - match Flutter velocity gate with Sciter Signed-off-by: Amirhossein Akhlaghpour <m9.akhlaghpoor@gmail.com> * input: restore flutter wheel velocity threshold - keep burst threshold at 0.002 delta/us Signed-off-by: Amirhossein Akhlaghpour <m9.akhlaghpoor@gmail.com> --------- Signed-off-by: Amirhossein Akhlaghpour <m9.akhlaghpoor@gmail.com>
This commit is contained in:
committed by
GitHub
parent
4abdb2e08b
commit
bb3501a4f9
@@ -365,6 +365,16 @@ class InputModel {
|
|||||||
final isPhysicalMouse = false.obs;
|
final isPhysicalMouse = false.obs;
|
||||||
int _lastButtons = 0;
|
int _lastButtons = 0;
|
||||||
Offset lastMousePos = Offset.zero;
|
Offset lastMousePos = Offset.zero;
|
||||||
|
int _lastWheelTsUs = 0;
|
||||||
|
|
||||||
|
// Wheel acceleration thresholds.
|
||||||
|
static const int _wheelAccelFastThresholdUs = 40000; // 40ms
|
||||||
|
static const int _wheelAccelMediumThresholdUs = 80000; // 80ms
|
||||||
|
static const double _wheelBurstVelocityThreshold =
|
||||||
|
0.002; // delta units per microsecond
|
||||||
|
// Wheel burst acceleration (empirical tuning).
|
||||||
|
// Applies only to fast, non-smooth bursts to preserve single-step scrolling.
|
||||||
|
// Flutter uses microseconds for dt, so velocity is in delta/us.
|
||||||
|
|
||||||
// Relative mouse mode (for games/3D apps).
|
// Relative mouse mode (for games/3D apps).
|
||||||
final relativeMouseMode = false.obs;
|
final relativeMouseMode = false.obs;
|
||||||
@@ -964,6 +974,7 @@ class InputModel {
|
|||||||
toReleaseRawKeys.release(handleRawKeyEvent);
|
toReleaseRawKeys.release(handleRawKeyEvent);
|
||||||
_pointerMovedAfterEnter = false;
|
_pointerMovedAfterEnter = false;
|
||||||
_pointerInsideImage = enter;
|
_pointerInsideImage = enter;
|
||||||
|
_lastWheelTsUs = 0;
|
||||||
|
|
||||||
// Fix status
|
// Fix status
|
||||||
if (!enter) {
|
if (!enter) {
|
||||||
@@ -1407,17 +1418,44 @@ class InputModel {
|
|||||||
if (isViewOnly) return;
|
if (isViewOnly) return;
|
||||||
if (isViewCamera) return;
|
if (isViewCamera) return;
|
||||||
if (e is PointerScrollEvent) {
|
if (e is PointerScrollEvent) {
|
||||||
var dx = e.scrollDelta.dx.toInt();
|
final rawDx = e.scrollDelta.dx;
|
||||||
var dy = e.scrollDelta.dy.toInt();
|
final rawDy = e.scrollDelta.dy;
|
||||||
|
final dominantDelta = rawDx.abs() > rawDy.abs() ? rawDx.abs() : rawDy.abs();
|
||||||
|
final isSmooth = dominantDelta < 1;
|
||||||
|
final nowUs = DateTime.now().microsecondsSinceEpoch;
|
||||||
|
final dtUs = _lastWheelTsUs == 0 ? 0 : nowUs - _lastWheelTsUs;
|
||||||
|
_lastWheelTsUs = nowUs;
|
||||||
|
int accel = 1;
|
||||||
|
if (!isSmooth &&
|
||||||
|
dtUs > 0 &&
|
||||||
|
dtUs <= _wheelAccelMediumThresholdUs &&
|
||||||
|
(isWindows || isLinux) &&
|
||||||
|
peerPlatform == kPeerPlatformMacOS) {
|
||||||
|
final velocity = dominantDelta / dtUs;
|
||||||
|
if (velocity >= _wheelBurstVelocityThreshold) {
|
||||||
|
if (dtUs < _wheelAccelFastThresholdUs) {
|
||||||
|
accel = 3;
|
||||||
|
} else {
|
||||||
|
accel = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var dx = rawDx.toInt();
|
||||||
|
var dy = rawDy.toInt();
|
||||||
|
if (rawDx.abs() > rawDy.abs()) {
|
||||||
|
dy = 0;
|
||||||
|
} else {
|
||||||
|
dx = 0;
|
||||||
|
}
|
||||||
if (dx > 0) {
|
if (dx > 0) {
|
||||||
dx = -1;
|
dx = -accel;
|
||||||
} else if (dx < 0) {
|
} else if (dx < 0) {
|
||||||
dx = 1;
|
dx = accel;
|
||||||
}
|
}
|
||||||
if (dy > 0) {
|
if (dy > 0) {
|
||||||
dy = -1;
|
dy = -accel;
|
||||||
} else if (dy < 0) {
|
} else if (dy < 0) {
|
||||||
dy = 1;
|
dy = accel;
|
||||||
}
|
}
|
||||||
bind.sessionSendMouse(
|
bind.sessionSendMouse(
|
||||||
sessionId: sessionId,
|
sessionId: sessionId,
|
||||||
|
|||||||
@@ -142,6 +142,14 @@ function resetWheel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var INERTIA_ACCELERATION = 30;
|
var INERTIA_ACCELERATION = 30;
|
||||||
|
var WHEEL_ACCEL_VELOCITY_THRESHOLD = 5000;
|
||||||
|
var WHEEL_ACCEL_DT_FAST = 0.04;
|
||||||
|
var WHEEL_ACCEL_DT_MEDIUM = 0.08;
|
||||||
|
var WHEEL_ACCEL_VALUE_FAST = 3;
|
||||||
|
var WHEEL_ACCEL_VALUE_MEDIUM = 2;
|
||||||
|
// Wheel burst acceleration (empirical tuning).
|
||||||
|
// Applies only on fast, non-smooth wheel bursts to keep single-step scroll unchanged.
|
||||||
|
// Sciter uses seconds for dt, so velocity is in delta/sec.
|
||||||
|
|
||||||
// not good, precision not enough to simulate acceleration effect,
|
// not good, precision not enough to simulate acceleration effect,
|
||||||
// seems have to use pixel based rather line based delta
|
// seems have to use pixel based rather line based delta
|
||||||
@@ -237,12 +245,28 @@ function handler.onMouse(evt)
|
|||||||
// mouseWheelDistance = 8 * [currentUserDefs floatForKey:@"com.apple.scrollwheel.scaling"];
|
// mouseWheelDistance = 8 * [currentUserDefs floatForKey:@"com.apple.scrollwheel.scaling"];
|
||||||
mask = 3;
|
mask = 3;
|
||||||
{
|
{
|
||||||
var (dx, dy) = evt.wheelDeltas;
|
var now = getTime();
|
||||||
if (dx > 0) dx = 1;
|
var dt = last_wheel_time > 0 ? (now - last_wheel_time) / 1000 : 0;
|
||||||
else if (dx < 0) dx = -1;
|
var (raw_dx, raw_dy) = evt.wheelDeltas;
|
||||||
if (dy > 0) dy = 1;
|
var dx = 0;
|
||||||
else if (dy < 0) dy = -1;
|
var dy = 0;
|
||||||
if (Math.abs(dx) > Math.abs(dy)) {
|
var abs_dx = Math.abs(raw_dx);
|
||||||
|
var abs_dy = Math.abs(raw_dy);
|
||||||
|
var dominant = abs_dx > abs_dy ? abs_dx : abs_dy;
|
||||||
|
var is_smooth = dominant < 1;
|
||||||
|
var accel = 1;
|
||||||
|
if (!is_smooth && dt > 0 && (is_win || is_linux) && get_peer_platform() == "Mac OS") {
|
||||||
|
var velocity = dominant / dt;
|
||||||
|
if (velocity >= WHEEL_ACCEL_VELOCITY_THRESHOLD) {
|
||||||
|
if (dt < WHEEL_ACCEL_DT_FAST) accel = WHEEL_ACCEL_VALUE_FAST;
|
||||||
|
else if (dt < WHEEL_ACCEL_DT_MEDIUM) accel = WHEEL_ACCEL_VALUE_MEDIUM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (raw_dx > 0) dx = accel;
|
||||||
|
else if (raw_dx < 0) dx = -accel;
|
||||||
|
if (raw_dy > 0) dy = accel;
|
||||||
|
else if (raw_dy < 0) dy = -accel;
|
||||||
|
if (abs_dx > abs_dy) {
|
||||||
dy = 0;
|
dy = 0;
|
||||||
} else {
|
} else {
|
||||||
dx = 0;
|
dx = 0;
|
||||||
@@ -253,8 +277,6 @@ function handler.onMouse(evt)
|
|||||||
wheel_delta_y = acc_wheel_delta_y.toInteger();
|
wheel_delta_y = acc_wheel_delta_y.toInteger();
|
||||||
acc_wheel_delta_x -= wheel_delta_x;
|
acc_wheel_delta_x -= wheel_delta_x;
|
||||||
acc_wheel_delta_y -= wheel_delta_y;
|
acc_wheel_delta_y -= wheel_delta_y;
|
||||||
var now = getTime();
|
|
||||||
var dt = last_wheel_time > 0 ? (now - last_wheel_time) / 1000 : 0;
|
|
||||||
if (dt > 0) {
|
if (dt > 0) {
|
||||||
var vx = dx / dt;
|
var vx = dx / dt;
|
||||||
var vy = dy / dt;
|
var vy = dy / dt;
|
||||||
@@ -297,11 +319,13 @@ function handler.onMouse(evt)
|
|||||||
entered = true;
|
entered = true;
|
||||||
stdout.println("enter");
|
stdout.println("enter");
|
||||||
handler.enter(handler.get_keyboard_mode());
|
handler.enter(handler.get_keyboard_mode());
|
||||||
|
last_wheel_time = 0;
|
||||||
return keyboard_enabled;
|
return keyboard_enabled;
|
||||||
case Event.MOUSE_LEAVE:
|
case Event.MOUSE_LEAVE:
|
||||||
entered = false;
|
entered = false;
|
||||||
stdout.println("leave");
|
stdout.println("leave");
|
||||||
handler.leave(handler.get_keyboard_mode());
|
handler.leave(handler.get_keyboard_mode());
|
||||||
|
last_wheel_time = 0;
|
||||||
if (is_left_down && get_peer_platform() == "Android") {
|
if (is_left_down && get_peer_platform() == "Android") {
|
||||||
is_left_down = false;
|
is_left_down = false;
|
||||||
handler.send_mouse((1 << 3) | 2, 0, 0, evt.altKey,
|
handler.send_mouse((1 << 3) | 2, 0, 0, evt.altKey,
|
||||||
|
|||||||
Reference in New Issue
Block a user