From ca7b4872d9f1a59369fd0529b4c52e1ed0556377 Mon Sep 17 00:00:00 2001 From: fufesou <13586388+fufesou@users.noreply.github.com> Date: Fri, 9 May 2025 15:36:45 +0800 Subject: [PATCH] feat, trackpad speed (#11680) * feat, trackpad speed Signed-off-by: fufesou * comments Signed-off-by: fufesou * Trackpad speed, user default value Signed-off-by: fufesou --------- Signed-off-by: fufesou --- flutter/lib/common/widgets/dialog.dart | 22 +++++ .../lib/common/widgets/setting_widgets.dart | 90 +++++++++++++++++++ flutter/lib/consts.dart | 6 ++ .../desktop/pages/desktop_setting_page.dart | 25 +++++- .../lib/desktop/widgets/remote_toolbar.dart | 19 ++++ flutter/lib/models/input_model.dart | 46 ++++++++-- flutter/lib/models/model.dart | 4 + libs/hbb_common | 2 +- src/client.rs | 6 ++ src/flutter_ffi.rs | 14 +++ src/lang/ar.rs | 2 + src/lang/be.rs | 2 + src/lang/bg.rs | 2 + src/lang/ca.rs | 2 + src/lang/cn.rs | 2 + src/lang/cs.rs | 2 + src/lang/da.rs | 2 + src/lang/de.rs | 2 + src/lang/el.rs | 2 + src/lang/eo.rs | 2 + src/lang/es.rs | 2 + src/lang/et.rs | 2 + src/lang/eu.rs | 2 + src/lang/fa.rs | 2 + src/lang/fr.rs | 2 + src/lang/ge.rs | 2 + src/lang/he.rs | 2 + src/lang/hr.rs | 2 + src/lang/hu.rs | 2 + src/lang/id.rs | 2 + src/lang/it.rs | 2 + src/lang/ja.rs | 2 + src/lang/ko.rs | 2 + src/lang/kz.rs | 2 + src/lang/lt.rs | 2 + src/lang/lv.rs | 2 + src/lang/nb.rs | 2 + src/lang/nl.rs | 2 + src/lang/pl.rs | 2 + src/lang/pt_PT.rs | 2 + src/lang/ptbr.rs | 2 + src/lang/ro.rs | 2 + src/lang/ru.rs | 2 + src/lang/sc.rs | 2 + src/lang/sk.rs | 2 + src/lang/sl.rs | 2 + src/lang/sq.rs | 2 + src/lang/sr.rs | 2 + src/lang/sv.rs | 2 + src/lang/ta.rs | 2 + src/lang/template.rs | 2 + src/lang/th.rs | 2 + src/lang/tr.rs | 2 + src/lang/tw.rs | 2 + src/lang/uk.rs | 2 + src/lang/vn.rs | 2 + src/ui_session_interface.rs | 8 ++ 57 files changed, 325 insertions(+), 9 deletions(-) diff --git a/flutter/lib/common/widgets/dialog.dart b/flutter/lib/common/widgets/dialog.dart index 302b6b440..7c75f96f7 100644 --- a/flutter/lib/common/widgets/dialog.dart +++ b/flutter/lib/common/widgets/dialog.dart @@ -1623,6 +1623,28 @@ customImageQualityDialog(SessionID sessionId, String id, FFI ffi) async { msgBoxCommon(ffi.dialogManager, 'Custom Image Quality', content, [btnClose]); } +trackpadSpeedDialog(SessionID sessionId, FFI ffi) async { + int initSpeed = ffi.inputModel.trackpadSpeed; + final curSpeed = SimpleWrapper(initSpeed); + final btnClose = dialogButton('Close', onPressed: () async { + if (curSpeed.value <= kMaxTrackpadSpeed && + curSpeed.value >= kMinTrackpadSpeed && + curSpeed.value != initSpeed) { + await bind.sessionSetTrackpadSpeed( + sessionId: sessionId, value: curSpeed.value); + await ffi.inputModel.updateTrackpadSpeed(); + } + ffi.dialogManager.dismissAll(); + }); + msgBoxCommon( + ffi.dialogManager, + 'Trackpad speed', + TrackpadSpeedWidget( + value: curSpeed, + ), + [btnClose]); +} + void deleteConfirmDialog(Function onSubmit, String title) async { gFFI.dialogManager.show( (setState, close, context) { diff --git a/flutter/lib/common/widgets/setting_widgets.dart b/flutter/lib/common/widgets/setting_widgets.dart index 5bcb73a4c..cf8e89737 100644 --- a/flutter/lib/common/widgets/setting_widgets.dart +++ b/flutter/lib/common/widgets/setting_widgets.dart @@ -248,3 +248,93 @@ List<(String, String)> otherDefaultSettings() { return v; } + +class TrackpadSpeedWidget extends StatefulWidget { + final SimpleWrapper value; + // If null, no debouncer will be applied. + final Function(int)? onDebouncer; + + TrackpadSpeedWidget({Key? key, required this.value, this.onDebouncer}); + + @override + TrackpadSpeedWidgetState createState() => TrackpadSpeedWidgetState(); +} + +class TrackpadSpeedWidgetState extends State { + final TextEditingController _controller = TextEditingController(); + late final Debouncer debouncerSpeed; + + set value(int v) => widget.value.value = v; + int get value => widget.value.value; + + void updateValue(int newValue) { + setState(() { + value = newValue.clamp(kMinTrackpadSpeed, kMaxTrackpadSpeed); + // Scale the trackpad speed value to a percentage for display purposes. + _controller.text = value.toString(); + if (widget.onDebouncer != null) { + debouncerSpeed.setValue(value); + } + }); + } + + @override + void initState() { + super.initState(); + debouncerSpeed = Debouncer( + Duration(milliseconds: 1000), + onChanged: widget.onDebouncer, + initialValue: widget.value.value, + ); + } + + @override + Widget build(BuildContext context) { + if (_controller.text.isEmpty) { + _controller.text = value.toString(); + } + return Row( + children: [ + Expanded( + flex: 3, + child: Slider( + value: value.toDouble(), + min: kMinTrackpadSpeed.toDouble(), + max: kMaxTrackpadSpeed.toDouble(), + divisions: ((kMaxTrackpadSpeed - kMinTrackpadSpeed) / 10).round(), + onChanged: (double v) => updateValue(v.round()), + ), + ), + Expanded( + flex: 1, + child: Row( + children: [ + SizedBox( + width: 56, + child: TextField( + controller: _controller, + keyboardType: TextInputType.number, + textAlign: TextAlign.center, + onSubmitted: (text) { + int? v = int.tryParse(text); + if (v != null) { + updateValue(v); + } + }, + style: const TextStyle(fontSize: 13), + decoration: InputDecoration( + contentPadding: + EdgeInsets.symmetric(vertical: 8.0, horizontal: 12.0), + ), + ), + ).marginOnly(right: 8.0), + Text( + '%', + style: const TextStyle(fontSize: 15), + ) + ], + )), + ], + ); + } +} diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart index c2382bf20..aa5256a13 100644 --- a/flutter/lib/consts.dart +++ b/flutter/lib/consts.dart @@ -226,6 +226,12 @@ const double kDefaultQuality = 50; const double kMaxQuality = 100; const double kMaxMoreQuality = 2000; +// trackpad speed +const String kKeyTrackpadSpeed = 'trackpad-speed'; +const int kMinTrackpadSpeed = 10; +const int kDefaultTrackpadSpeed = 100; +const int kMaxTrackpadSpeed = 1000; + // incomming (should be incoming) is kept, because change it will break the previous setting. const String kKeyPrinterIncomingJobAction = 'printer-incomming-job-action'; const String kValuePrinterIncomingJobDismiss = 'dismiss'; diff --git a/flutter/lib/desktop/pages/desktop_setting_page.dart b/flutter/lib/desktop/pages/desktop_setting_page.dart index 351606d57..e683cce56 100644 --- a/flutter/lib/desktop/pages/desktop_setting_page.dart +++ b/flutter/lib/desktop/pages/desktop_setting_page.dart @@ -76,7 +76,9 @@ class DesktopSettingPage extends StatefulWidget { if (!isWeb && !bind.isIncomingOnly() && bind.pluginFeatureIsEnabled()) SettingsTabKey.plugin, if (!bind.isDisableAccount()) SettingsTabKey.account, - if (isWindows && bind.mainGetBuildinOption(key: kOptionHideRemotePrinterSetting) != 'Y') SettingsTabKey.printer, + if (isWindows && + bind.mainGetBuildinOption(key: kOptionHideRemotePrinterSetting) != 'Y') + SettingsTabKey.printer, SettingsTabKey.about, ]; @@ -1602,6 +1604,7 @@ class _DisplayState extends State<_Display> { scrollStyle(context), imageQuality(context), codec(context), + if (isDesktop) trackpadSpeed(context), if (!isWeb) privacyModeImpl(context), other(context), ]).marginOnly(bottom: _kListViewBottomMargin); @@ -1689,6 +1692,26 @@ class _DisplayState extends State<_Display> { ]); } + Widget trackpadSpeed(BuildContext context) { + final initSpeed = (int.tryParse( + bind.mainGetUserDefaultOption(key: kKeyTrackpadSpeed)) ?? + kDefaultTrackpadSpeed); + final curSpeed = SimpleWrapper(initSpeed); + void onDebouncer(int v) { + bind.mainSetUserDefaultOption( + key: kKeyTrackpadSpeed, value: v.toString()); + // It's better to notify all sessions that the default speed is changed. + // But it may also be ok to take effect in the next connection. + } + + return _Card(title: 'Default trackpad speed', children: [ + TrackpadSpeedWidget( + value: curSpeed, + onDebouncer: onDebouncer, + ), + ]); + } + Widget codec(BuildContext context) { onChanged(String value) async { await bind.mainSetUserDefaultOption( diff --git a/flutter/lib/desktop/widgets/remote_toolbar.dart b/flutter/lib/desktop/widgets/remote_toolbar.dart index 31b8b2263..f29908d51 100644 --- a/flutter/lib/desktop/widgets/remote_toolbar.dart +++ b/flutter/lib/desktop/widgets/remote_toolbar.dart @@ -4,6 +4,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hbb/common/widgets/audio_input.dart'; +import 'package:flutter_hbb/common/widgets/dialog.dart'; import 'package:flutter_hbb/common/widgets/toolbar.dart'; import 'package:flutter_hbb/models/chat_model.dart'; import 'package:flutter_hbb/models/state_model.dart'; @@ -1594,10 +1595,28 @@ class _KeyboardMenu extends StatelessWidget { viewMode(), Divider(), ...toolbarToggles(), + ...mouseSpeed(), ...mobileActions(), ]); } + mouseSpeed() { + final speedWidgets = []; + final sessionId = ffi.sessionId; + if (isDesktop) { + if (ffi.ffiModel.keyboard) { + final enabled = !ffi.ffiModel.viewOnly; + final trackpad = MenuButton( + child: Text(translate('Trackpad speed')).paddingOnly(left: 26.0), + onPressed: enabled ? () => trackpadSpeedDialog(sessionId, ffi) : null, + ffi: ffi, + ); + speedWidgets.add(trackpad); + } + } + return speedWidgets; + } + keyboardMode() { return futureBuilder(future: () async { return await bind.sessionGetKeyboardMode(sessionId: ffi.sessionId) ?? diff --git a/flutter/lib/models/input_model.dart b/flutter/lib/models/input_model.dart index 463d5a32b..dcccf8f7c 100644 --- a/flutter/lib/models/input_model.dart +++ b/flutter/lib/models/input_model.dart @@ -345,8 +345,11 @@ class InputModel { var _fling = false; Timer? _flingTimer; final _flingBaseDelay = 30; - // trackpad, peer linux - final _trackpadSpeed = 0.06; + final _trackpadAdjustPeerLinux = 0.06; + // This is an experience value. + final _trackpadAdjustMacToWin = 2.50; + int _trackpadSpeed = kDefaultTrackpadSpeed; + double _trackpadSpeedInner = kDefaultTrackpadSpeed / 100.0; var _trackpadScrollUnsent = Offset.zero; var _lastScale = 1.0; @@ -370,6 +373,7 @@ class InputModel { bool get isViewOnly => parent.target!.ffiModel.viewOnly; double get devicePixelRatio => parent.target!.canvasModel.devicePixelRatio; bool get isViewCamera => parent.target!.connType == ConnType.viewCamera; + int get trackpadSpeed => _trackpadSpeed; InputModel(this.parent) { sessionId = parent.target!.sessionId; @@ -385,6 +389,28 @@ class InputModel { } } + /// Updates the trackpad speed based on the session value. + /// + /// The expected format of the retrieved value is a string that can be parsed into a double. + /// If parsing fails or the value is out of bounds (less than `kMinTrackpadSpeed` or greater + /// than `kMaxTrackpadSpeed`), the trackpad speed is reset to the default + /// value (`kDefaultTrackpadSpeed`). + /// + /// Bounds: + /// - Minimum: `kMinTrackpadSpeed` + /// - Maximum: `kMaxTrackpadSpeed` + /// - Default: `kDefaultTrackpadSpeed` + Future updateTrackpadSpeed() async { + _trackpadSpeed = + (await bind.sessionGetTrackpadSpeed(sessionId: sessionId) ?? + kDefaultTrackpadSpeed); + if (_trackpadSpeed < kMinTrackpadSpeed || + _trackpadSpeed > kMaxTrackpadSpeed) { + _trackpadSpeed = kDefaultTrackpadSpeed; + } + _trackpadSpeedInner = _trackpadSpeed / 100.0; + } + void handleKeyDownEventModifiers(KeyEvent e) { KeyUpEvent upEvent(e) => KeyUpEvent( physicalKey: e.physicalKey, @@ -888,13 +914,16 @@ class InputModel { } } - final delta = e.panDelta; + var delta = e.panDelta * _trackpadSpeedInner; + if (isMacOS && peerPlatform == kPeerPlatformWindows) { + delta *= _trackpadAdjustMacToWin; + } _trackpadLastDelta = delta; var x = delta.dx.toInt(); var y = delta.dy.toInt(); if (peerPlatform == kPeerPlatformLinux) { - _trackpadScrollUnsent += (delta * _trackpadSpeed); + _trackpadScrollUnsent += (delta * _trackpadAdjustPeerLinux); x = _trackpadScrollUnsent.dx.truncate(); y = _trackpadScrollUnsent.dy.truncate(); _trackpadScrollUnsent -= Offset(x.toDouble(), y.toDouble()); @@ -942,8 +971,8 @@ class InputModel { var dx = x.toInt(); var dy = y.toInt(); if (parent.target?.ffiModel.pi.platform == kPeerPlatformLinux) { - dx = (x * _trackpadSpeed).toInt(); - dy = (y * _trackpadSpeed).toInt(); + dx = (x * _trackpadAdjustPeerLinux).toInt(); + dy = (y * _trackpadAdjustPeerLinux).toInt(); } var delay = _flingBaseDelay; @@ -989,7 +1018,10 @@ class InputModel { _stopFling = false; // 2.0 is an experience value - double minFlingValue = 2.0; + double minFlingValue = 2.0 * _trackpadSpeedInner; + if (isMacOS && peerPlatform == kPeerPlatformWindows) { + minFlingValue *= _trackpadAdjustMacToWin; + } if (_trackpadLastDelta.dx.abs() > minFlingValue || _trackpadLastDelta.dy.abs() > minFlingValue) { _fling = true; diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 52782fc95..cc56249d1 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -2991,6 +2991,10 @@ class FFI { textureModel.updateCurrentDisplay(display ?? 0); } + if (isDesktop) { + inputModel.updateTrackpadSpeed(); + } + // CAUTION: `sessionStart()` and `sessionStartWithDisplays()` are an async functions. // Though the stream is returned immediately, the stream may not be ready. // Any operations that depend on the stream should be carefully handled. diff --git a/libs/hbb_common b/libs/hbb_common index 7839dcf4e..6e556f7e1 160000 --- a/libs/hbb_common +++ b/libs/hbb_common @@ -1 +1 @@ -Subproject commit 7839dcf4e4ddc3feab9b52b0ae1903d443bc084d +Subproject commit 6e556f7e1751a3a709cd5cca0df7268ba3cb1c48 diff --git a/src/client.rs b/src/client.rs index 1372f93eb..0445a4e48 100644 --- a/src/client.rs +++ b/src/client.rs @@ -2105,6 +2105,12 @@ impl LoginConfigHandler { res } + pub fn save_trackpad_speed(&mut self, speed: i32) { + let mut config = self.load_config(); + config.trackpad_speed = speed; + self.save_config(config); + } + /// Create a [`Message`] for saving custom fps. /// /// # Arguments diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index 254a119d5..827faf74e 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -492,6 +492,20 @@ pub fn session_set_custom_fps(session_id: SessionID, fps: i32) { } } +pub fn session_get_trackpad_speed(session_id: SessionID) -> Option { + if let Some(session) = sessions::get_session_by_session_id(&session_id) { + Some(session.get_trackpad_speed()) + } else { + None + } +} + +pub fn session_set_trackpad_speed(session_id: SessionID, value: i32) { + if let Some(session) = sessions::get_session_by_session_id(&session_id) { + session.save_trackpad_speed(value); + } +} + pub fn session_lock_screen(session_id: SessionID) { if let Some(session) = sessions::get_session_by_session_id(&session_id) { session.lock_screen(); diff --git a/src/lang/ar.rs b/src/lang/ar.rs index b1a3193e6..3a92ef559 100644 --- a/src/lang/ar.rs +++ b/src/lang/ar.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/be.rs b/src/lang/be.rs index dbf4f2422..7a2daf5a1 100644 --- a/src/lang/be.rs +++ b/src/lang/be.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/bg.rs b/src/lang/bg.rs index 8f6b4536b..c4a30e9a4 100644 --- a/src/lang/bg.rs +++ b/src/lang/bg.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ca.rs b/src/lang/ca.rs index 8609332a2..125e0dce7 100644 --- a/src/lang/ca.rs +++ b/src/lang/ca.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/cn.rs b/src/lang/cn.rs index 8842d2b9b..f676060c0 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", "安装方式检测失败。请点击\"下载\"按钮,从发布网址下载,并手动升级。"), ("websocket_tip", "使用 WebSocket 时,仅支持中继连接。"), ("Use WebSocket", "使用 WebSocket"), + ("Trackpad speed", "触控板速度"), + ("Default trackpad speed", "默认触控板速度"), ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index 3354ba0c7..99bd13acb 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index d5f8abc1e..e0a29ff31 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index 46bd4c1be..d9e37e09b 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", "Prüfung der Installationsmethode fehlgeschlagen. Bitte klicken Sie auf die Schaltfläche \"Herunterladen\", um von der Versionsseite herunterzuladen und manuell zu aktualisieren."), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/el.rs b/src/lang/el.rs index 01043a7ef..1b2cc5f7f 100644 --- a/src/lang/el.rs +++ b/src/lang/el.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index e6e151e5e..acaca7105 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index 27c4847f3..01eea2ec9 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/et.rs b/src/lang/et.rs index 28987fbe3..cd8664e84 100644 --- a/src/lang/et.rs +++ b/src/lang/et.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/eu.rs b/src/lang/eu.rs index 01e1068da..a08aa969e 100644 --- a/src/lang/eu.rs +++ b/src/lang/eu.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fa.rs b/src/lang/fa.rs index bb43dad54..d407da616 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 21668b7fb..5fd4265a4 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ge.rs b/src/lang/ge.rs index 0d9f68539..d323f48c6 100644 --- a/src/lang/ge.rs +++ b/src/lang/ge.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/he.rs b/src/lang/he.rs index 37280449c..c8fd3460f 100644 --- a/src/lang/he.rs +++ b/src/lang/he.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/hr.rs b/src/lang/hr.rs index 8b782873c..5568509b5 100644 --- a/src/lang/hr.rs +++ b/src/lang/hr.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/hu.rs b/src/lang/hu.rs index ee8f53734..ec1821af2 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index ee796e42b..ce6e1dd86 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index 0a10f658a..39b3ab046 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", "Controllo metodo installazione non riuscito.\nSeleziona 'Download' per scaricare il programma e aggiornarlo manualmente."), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ja.rs b/src/lang/ja.rs index 42eda1c68..9790124e5 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ko.rs b/src/lang/ko.rs index 0dded1ff2..5e443bdc4 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", "업데이트에 실패했습니다. .msi 설치 파일을 확인하세요."), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/kz.rs b/src/lang/kz.rs index a68f19c63..a510709e5 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/lt.rs b/src/lang/lt.rs index 7fbf6eea4..2a09109c3 100644 --- a/src/lang/lt.rs +++ b/src/lang/lt.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/lv.rs b/src/lang/lv.rs index 8057ac862..d00f8052e 100644 --- a/src/lang/lv.rs +++ b/src/lang/lv.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/nb.rs b/src/lang/nb.rs index 07ed5a45b..c9aab2e51 100644 --- a/src/lang/nb.rs +++ b/src/lang/nb.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/nl.rs b/src/lang/nl.rs index 608fabbde..ae1e6d108 100644 --- a/src/lang/nl.rs +++ b/src/lang/nl.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", "Kan de installatiemethode niet bepalen. Klik op “Downloaden” om de applicatie van de officiële website te downloaden en handmatig bij te werken."), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pl.rs b/src/lang/pl.rs index 6ca59e54b..204c79de8 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", "Sprawdzenie metody instalacji nie powiodło się. Kliknij przycisk \"Pobierz\", aby pobrać ze strony wydania i uaktualnić ręcznie."), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index 9f8fae3b8..2562f03a4 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index e6d94db56..048f6c1ee 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ro.rs b/src/lang/ro.rs index a0cc49c66..4b4602358 100644 --- a/src/lang/ro.rs +++ b/src/lang/ro.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index 35e387d98..dbc3d3a71 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", "Невозможно определить метод установки. Нажмите кнопку \"Скачать\", чтобы скачать приложение с официального сайта и обновить его вручную."), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sc.rs b/src/lang/sc.rs index 10ea9c52b..37451a98a 100644 --- a/src/lang/sc.rs +++ b/src/lang/sc.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index 97b21eeec..b0a0ade03 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sl.rs b/src/lang/sl.rs index 206fec074..72c3ea1d8 100755 --- a/src/lang/sl.rs +++ b/src/lang/sl.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sq.rs b/src/lang/sq.rs index 834098067..1fccfcc09 100644 --- a/src/lang/sq.rs +++ b/src/lang/sq.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sr.rs b/src/lang/sr.rs index 79f0f46bc..47149a30d 100644 --- a/src/lang/sr.rs +++ b/src/lang/sr.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sv.rs b/src/lang/sv.rs index a06dacc39..65ab9a691 100644 --- a/src/lang/sv.rs +++ b/src/lang/sv.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ta.rs b/src/lang/ta.rs index 37303d2df..c245c3d50 100644 --- a/src/lang/ta.rs +++ b/src/lang/ta.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index e956f8ab5..4ba44d83a 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/th.rs b/src/lang/th.rs index e8185a0c1..9c51b5944 100644 --- a/src/lang/th.rs +++ b/src/lang/th.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tr.rs b/src/lang/tr.rs index 0eabb55a8..b9e00638a 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index c10c132ee..15ba201e1 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/uk.rs b/src/lang/uk.rs index 34b77415e..d5ae7677d 100644 --- a/src/lang/uk.rs +++ b/src/lang/uk.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/lang/vn.rs b/src/lang/vn.rs index 0e9834416..69c15ae2f 100644 --- a/src/lang/vn.rs +++ b/src/lang/vn.rs @@ -696,5 +696,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("update-failed-check-msi-tip", ""), ("websocket_tip", ""), ("Use WebSocket", ""), + ("Trackpad speed", ""), + ("Default trackpad speed", ""), ].iter().cloned().collect(); } diff --git a/src/ui_session_interface.rs b/src/ui_session_interface.rs index dbadd0747..2328a0570 100644 --- a/src/ui_session_interface.rs +++ b/src/ui_session_interface.rs @@ -230,6 +230,10 @@ impl Session { self.lc.read().unwrap().version.clone() } + pub fn get_trackpad_speed(&self) -> i32 { + self.lc.read().unwrap().trackpad_speed + } + pub fn fallback_keyboard_mode(&self) -> String { let peer_version = self.get_peer_version(); let platform = self.peer_platform(); @@ -448,6 +452,10 @@ impl Session { } } + pub fn save_trackpad_speed(&self, trackpad_speed: i32) { + self.lc.write().unwrap().save_trackpad_speed(trackpad_speed); + } + pub fn set_custom_fps(&self, custom_fps: i32) { let msg = self.lc.write().unwrap().set_custom_fps(custom_fps, true); self.send(Data::Message(msg));