diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart index 7fcc7b3a7..24a9b3fad 100644 --- a/flutter/lib/consts.dart +++ b/flutter/lib/consts.dart @@ -138,6 +138,11 @@ const kRemoteScrollStyleAuto = 'scrollauto'; /// [kRemoteScrollStyleBar] Scroll image with scroll bar. const kRemoteScrollStyleBar = 'scrollbar'; +/// [kScrollModeDefault] Mouse or touchpad, the default scroll mode. +const kScrollModeDefault = 'default'; +/// [kScrollModeReverse] Mouse or touchpad, the reverse scroll mode. +const kScrollModeReverse = 'reverse'; + /// [kRemoteImageQualityBest] Best image quality. const kRemoteImageQualityBest = 'best'; diff --git a/flutter/lib/desktop/pages/desktop_setting_page.dart b/flutter/lib/desktop/pages/desktop_setting_page.dart index 3a33c7e5b..468886cb8 100644 --- a/flutter/lib/desktop/pages/desktop_setting_page.dart +++ b/flutter/lib/desktop/pages/desktop_setting_page.dart @@ -1216,6 +1216,7 @@ class _DisplayState extends State<_Display> { otherRow('Disable clipboard', 'disable_clipboard'), otherRow('Lock after session end', 'lock_after_session_end'), otherRow('Privacy mode', 'privacy_mode'), + otherRow('Reverse mouse wheel', 'reverse_mouse_wheel'), ]); } } diff --git a/flutter/lib/desktop/widgets/remote_toolbar.dart b/flutter/lib/desktop/widgets/remote_toolbar.dart index b59ae3736..a03fc7047 100644 --- a/flutter/lib/desktop/widgets/remote_toolbar.dart +++ b/flutter/lib/desktop/widgets/remote_toolbar.dart @@ -101,7 +101,7 @@ class ToolbarState { class _ToolbarTheme { static const Color blueColor = MyTheme.button; static const Color hoverBlueColor = MyTheme.accent; - static Color inactiveColor = Colors.grey[800]!; + static Color inactiveColor = Colors.grey[800]!; static Color hoverInactiveColor = Colors.grey[850]!; static const Color redColor = Colors.redAccent; @@ -546,9 +546,11 @@ class _PinMenu extends StatelessWidget { assetName: state.pin ? "assets/pinned.svg" : "assets/unpinned.svg", tooltip: state.pin ? 'Unpin Toolbar' : 'Pin Toolbar', onPressed: state.switchPin, - color: state.pin ? _ToolbarTheme.blueColor : _ToolbarTheme.inactiveColor, - hoverColor: - state.pin ? _ToolbarTheme.hoverBlueColor : _ToolbarTheme.hoverInactiveColor, + color: + state.pin ? _ToolbarTheme.blueColor : _ToolbarTheme.inactiveColor, + hoverColor: state.pin + ? _ToolbarTheme.hoverBlueColor + : _ToolbarTheme.hoverInactiveColor, ), ); } @@ -561,15 +563,18 @@ class _MobileActionMenu extends StatelessWidget { @override Widget build(BuildContext context) { if (!ffi.ffiModel.isPeerAndroid) return Offstage(); - return Obx(()=>_IconMenuButton( - assetName: 'assets/actions_mobile.svg', - tooltip: 'Mobile Actions', - onPressed: () => ffi.dialogManager.toggleMobileActionsOverlay(ffi: ffi), - color: ffi.dialogManager.mobileActionsOverlayVisible.isTrue - ? _ToolbarTheme.blueColor : _ToolbarTheme.inactiveColor, - hoverColor: ffi.dialogManager.mobileActionsOverlayVisible.isTrue - ? _ToolbarTheme.hoverBlueColor : _ToolbarTheme.hoverInactiveColor, - )); + return Obx(() => _IconMenuButton( + assetName: 'assets/actions_mobile.svg', + tooltip: 'Mobile Actions', + onPressed: () => + ffi.dialogManager.toggleMobileActionsOverlay(ffi: ffi), + color: ffi.dialogManager.mobileActionsOverlayVisible.isTrue + ? _ToolbarTheme.blueColor + : _ToolbarTheme.inactiveColor, + hoverColor: ffi.dialogManager.mobileActionsOverlayVisible.isTrue + ? _ToolbarTheme.hoverBlueColor + : _ToolbarTheme.hoverInactiveColor, + )); } } @@ -1304,23 +1309,25 @@ class _KeyboardMenu extends StatelessWidget { color: _ToolbarTheme.blueColor, hoverColor: _ToolbarTheme.hoverBlueColor, menuChildren: [ - mode(modeOnly), + keyboardMode(modeOnly), localKeyboardType(), Divider(), - view_mode(), + viewMode(), + Divider(), + reverseMouseWheel(), ]); } - mode(String? modeOnly) { + keyboardMode(String? modeOnly) { return futureBuilder(future: () async { return await bind.sessionGetKeyboardMode(sessionId: ffi.sessionId) ?? _kKeyLegacyMode; }(), hasData: (data) { final groupValue = data as String; - List modes = [ - KeyboardModeMenu(key: _kKeyLegacyMode, menu: 'Legacy mode'), - KeyboardModeMenu(key: _kKeyMapMode, menu: 'Map mode'), - KeyboardModeMenu(key: _kKeyTranslateMode, menu: 'Translate mode'), + List modes = [ + InputModeMenu(key: _kKeyLegacyMode, menu: 'Legacy mode'), + InputModeMenu(key: _kKeyMapMode, menu: 'Map mode'), + InputModeMenu(key: _kKeyTranslateMode, menu: 'Translate mode'), ]; List list = []; final enabled = !ffi.ffiModel.viewOnly; @@ -1330,7 +1337,7 @@ class _KeyboardMenu extends StatelessWidget { sessionId: ffi.sessionId, value: value); } - for (KeyboardModeMenu mode in modes) { + for (InputModeMenu mode in modes) { if (modeOnly != null && mode.key != modeOnly) { continue; } else if (!bind.sessionIsKeyboardModeSupported( @@ -1379,7 +1386,7 @@ class _KeyboardMenu extends StatelessWidget { ); } - view_mode() { + viewMode() { final ffiModel = ffi.ffiModel; final enabled = version_cmp(pi.version, '1.2.0') >= 0 && ffiModel.keyboard; return CkbMenuButton( @@ -1395,6 +1402,32 @@ class _KeyboardMenu extends StatelessWidget { ffi: ffi, child: Text(translate('View Mode'))); } + + reverseMouseWheel() { + return futureBuilder(future: () async { + final v = + await bind.sessionGetReverseMouseWheel(sessionId: ffi.sessionId); + debugPrint('REMOVE ME ======================== $v'); + if (v != null && v != '') { + return v; + } + return bind.mainGetUserDefaultOption(key: 'reverse_mouse_wheel'); + }(), hasData: (data) { + debugPrint('REMOVE ME ======================== data $data'); + final enabled = !ffi.ffiModel.viewOnly; + onChanged(bool? value) async { + if (value == null) return; + await bind.sessionSetReverseMouseWheel( + sessionId: ffi.sessionId, value: value ? 'Y' : 'N'); + } + + return CkbMenuButton( + value: data == 'Y', + onChanged: enabled ? onChanged : null, + child: Text(translate('Reverse mouse wheel')), + ffi: ffi); + }); + } } class _ChatMenu extends StatefulWidget { @@ -1592,26 +1625,26 @@ class _IconMenuButtonState extends State<_IconMenuButton> { width: _ToolbarTheme.buttonSize, height: _ToolbarTheme.buttonSize, child: MenuItemButton( - style: ButtonStyle( - backgroundColor: MaterialStatePropertyAll(Colors.transparent), - padding: MaterialStatePropertyAll(EdgeInsets.zero), - overlayColor: MaterialStatePropertyAll(Colors.transparent)), - onHover: (value) => setState(() { - hover = value; - }), - onPressed: widget.onPressed, - child: Tooltip( - message: translate(widget.tooltip), - child: Material( - type: MaterialType.transparency, - child: Ink( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(_ToolbarTheme.iconRadius), - color: hover ? widget.hoverColor : widget.color, - ), - child: icon)), - ) - ), + style: ButtonStyle( + backgroundColor: MaterialStatePropertyAll(Colors.transparent), + padding: MaterialStatePropertyAll(EdgeInsets.zero), + overlayColor: MaterialStatePropertyAll(Colors.transparent)), + onHover: (value) => setState(() { + hover = value; + }), + onPressed: widget.onPressed, + child: Tooltip( + message: translate(widget.tooltip), + child: Material( + type: MaterialType.transparency, + child: Ink( + decoration: BoxDecoration( + borderRadius: + BorderRadius.circular(_ToolbarTheme.iconRadius), + color: hover ? widget.hoverColor : widget.color, + ), + child: icon)), + )), ).marginSymmetric( horizontal: widget.hMargin ?? _ToolbarTheme.buttonHMargin, vertical: widget.vMargin ?? _ToolbarTheme.buttonVMargin); @@ -1675,18 +1708,17 @@ class _IconSubmenuButtonState extends State<_IconSubmenuButton> { onHover: (value) => setState(() { hover = value; }), - child: Tooltip( - message: translate(widget.tooltip), - child: Material( + child: Tooltip( + message: translate(widget.tooltip), + child: Material( type: MaterialType.transparency, child: Ink( - decoration: BoxDecoration( - borderRadius: - BorderRadius.circular(_ToolbarTheme.iconRadius), + decoration: BoxDecoration( + borderRadius: + BorderRadius.circular(_ToolbarTheme.iconRadius), color: hover ? widget.hoverColor : widget.color, - ), - child: icon)) - ), + ), + child: icon))), menuChildren: widget.menuChildren .map((e) => _buildPointerTrackWidget(e, widget.ffi)) .toList())); @@ -1973,11 +2005,11 @@ class _DraggableShowHideState extends State<_DraggableShowHide> { } } -class KeyboardModeMenu { +class InputModeMenu { final String key; final String menu; - KeyboardModeMenu({required this.key, required this.menu}); + InputModeMenu({required this.key, required this.menu}); } _menuDismissCallback(FFI ffi) => ffi.inputModel.refreshMousePos(); diff --git a/libs/hbb_common/src/config.rs b/libs/hbb_common/src/config.rs index a48da5ff0..82174754c 100644 --- a/libs/hbb_common/src/config.rs +++ b/libs/hbb_common/src/config.rs @@ -230,6 +230,7 @@ pub struct PeerConfig { skip_serializing_if = "String::is_empty" )] pub view_style: String, + // Image scroll style, scrollbar or scroll auto #[serde( default = "PeerConfig::default_scroll_style", deserialize_with = "PeerConfig::deserialize_scroll_style", @@ -276,6 +277,13 @@ pub struct PeerConfig { pub keyboard_mode: String, #[serde(flatten)] pub view_only: ViewOnly, + // Mouse wheel or touchpad scroll mode + #[serde( + default = "PeerConfig::default_reverse_mouse_wheel", + deserialize_with = "PeerConfig::deserialize_reverse_mouse_wheel", + skip_serializing_if = "String::is_empty" + )] + pub reverse_mouse_wheel: String, #[serde( default, @@ -319,6 +327,7 @@ impl Default for PeerConfig { show_quality_monitor: Default::default(), keyboard_mode: Default::default(), view_only: Default::default(), + reverse_mouse_wheel: Self::default_reverse_mouse_wheel(), custom_resolutions: Default::default(), options: Self::default_options(), ui_flutter: Default::default(), @@ -1130,6 +1139,11 @@ impl PeerConfig { deserialize_image_quality, UserDefaultConfig::read().get("image_quality") ); + serde_field_string!( + default_reverse_mouse_wheel, + deserialize_reverse_mouse_wheel, + UserDefaultConfig::read().get("reverse_mouse_wheel") + ); fn default_custom_image_quality() -> Vec { let f: f64 = UserDefaultConfig::read() @@ -1483,7 +1497,11 @@ impl UserDefaultConfig { } pub fn set(&mut self, key: String, value: String) { - self.options.insert(key, value); + if value.is_empty() { + self.options.remove(&key); + } else { + self.options.insert(key, value); + } self.store(); } diff --git a/src/client.rs b/src/client.rs index 0bfcfb655..85b6fc0f4 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1195,6 +1195,17 @@ impl LoginConfigHandler { self.save_config(config); } + /// Save reverse mouse wheel ("", "Y") to the current config. + /// + /// # Arguments + /// + /// * `value` - The reverse mouse wheel ("", "Y"). + pub fn save_reverse_mouse_wheel(&mut self, value: String) { + let mut config = self.load_config(); + config.reverse_mouse_wheel = value; + self.save_config(config); + } + /// Save scroll style to the current config. /// /// # Arguments diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index eaf273d2e..69f6f507c 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -21,8 +21,6 @@ use hbb_common::{ }; use std::{ collections::HashMap, - ffi::{CStr, CString}, - os::raw::c_char, str::FromStr, sync::{ atomic::{AtomicI32, Ordering}, @@ -302,6 +300,20 @@ pub fn session_set_keyboard_mode(session_id: SessionID, value: String) { } } +pub fn session_get_reverse_mouse_wheel(session_id: SessionID) -> Option { + if let Some(session) = SESSIONS.read().unwrap().get(&session_id) { + Some(session.get_reverse_mouse_wheel()) + } else { + None + } +} + +pub fn session_set_reverse_mouse_wheel(session_id: SessionID, value: String) { + if let Some(session) = SESSIONS.write().unwrap().get_mut(&session_id) { + session.save_reverse_mouse_wheel(value); + } +} + pub fn session_get_custom_image_quality(session_id: SessionID) -> Option> { if let Some(session) = SESSIONS.read().unwrap().get(&session_id) { Some(session.get_custom_image_quality()) diff --git a/src/lang/ar.rs b/src/lang/ar.rs index 0d9bdacd3..4a1f8486c 100644 --- a/src/lang/ar.rs +++ b/src/lang/ar.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ca.rs b/src/lang/ca.rs index 1ec5d78f3..55e01fefa 100644 --- a/src/lang/ca.rs +++ b/src/lang/ca.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/cn.rs b/src/lang/cn.rs index 8e07a2965..5fdfa460e 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", "HSV 色"), ("Installation Successful!", "安装成功!"), ("Installation failed!", "安装失败!"), + ("Reverse mouse wheel", "鼠标滚轮反向"), ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index 5dd4dc9a3..37473e0b6 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index 999875df2..9a9ecdfe1 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index 8dcf672c5..cc0ae6af9 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", "HSV-Farbe"), ("Installation Successful!", "Installation erfolgreich!"), ("Installation failed!", "Installation fehlgeschlagen!"), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/el.rs b/src/lang/el.rs index 4e7a83017..d2ae3eb5c 100644 --- a/src/lang/el.rs +++ b/src/lang/el.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/en.rs b/src/lang/en.rs index c949575c2..dc17ac7eb 100644 --- a/src/lang/en.rs +++ b/src/lang/en.rs @@ -77,5 +77,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("pull_ab_failed_tip", "Failed to refresh address book"), ("push_ab_failed_tip", "Failed to sync address book to server"), ("synced_peer_readded_tip", "The devices that were present in the recent sessions will be synchronized back to the address book."), + ("View Mode", "View mode"), ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index 7cb5a1b2a..90144c694 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index b1fc57954..779135f00 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", "Color HSV"), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fa.rs b/src/lang/fa.rs index 1284ec985..ab1d7ab12 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index fea4f7ffa..3ce8bca02 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", "Couleur TSL"), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/hu.rs b/src/lang/hu.rs index a9089de35..50ca96792 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index 27676a420..5f802e44b 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", "Warna HSV"), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index 07234b3f4..493e62d18 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", "Colore HSV"), ("Installation Successful!", "Installazione completata"), ("Installation failed!", "Installazione fallita"), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ja.rs b/src/lang/ja.rs index e6ef75815..015ee7af3 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ko.rs b/src/lang/ko.rs index 6f26674c5..2897ed5f8 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/kz.rs b/src/lang/kz.rs index b68caad51..5a0c14871 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/lt.rs b/src/lang/lt.rs index 41caa606f..100e22955 100644 --- a/src/lang/lt.rs +++ b/src/lang/lt.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/nl.rs b/src/lang/nl.rs index 6010a4132..7503831bf 100644 --- a/src/lang/nl.rs +++ b/src/lang/nl.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", "HSV Kleur"), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pl.rs b/src/lang/pl.rs index fe0693595..d488f681d 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index d0ade1088..91a85a3b1 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index 6dfc8f2a2..7ca81495d 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ro.rs b/src/lang/ro.rs index 01e0402a9..bcc13a0df 100644 --- a/src/lang/ro.rs +++ b/src/lang/ro.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index 2f86351cb..ee5467af2 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", "Цвет HSV"), ("Installation Successful!", "Установка выполнена успешно!"), ("Installation failed!", "Установка не выполнена!"), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index 615dd08f4..003b2cabc 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sl.rs b/src/lang/sl.rs index a05b5f4c0..80b9aed1d 100755 --- a/src/lang/sl.rs +++ b/src/lang/sl.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sq.rs b/src/lang/sq.rs index cfc2fda74..fd2db0c83 100644 --- a/src/lang/sq.rs +++ b/src/lang/sq.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sr.rs b/src/lang/sr.rs index 85bb6f488..9092d453d 100644 --- a/src/lang/sr.rs +++ b/src/lang/sr.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sv.rs b/src/lang/sv.rs index 90f543617..ed8c3697a 100644 --- a/src/lang/sv.rs +++ b/src/lang/sv.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index 7f58b4452..6b4d176d2 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/th.rs b/src/lang/th.rs index 94251c5b2..a5e193a00 100644 --- a/src/lang/th.rs +++ b/src/lang/th.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tr.rs b/src/lang/tr.rs index 57a337b1a..0fe1369df 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", "HSV Rengi"), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index 49d1c08cf..5e533e9bc 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", "HSV 色"), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ua.rs b/src/lang/ua.rs index b398afab5..7cc885f56 100644 --- a/src/lang/ua.rs +++ b/src/lang/ua.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/lang/vn.rs b/src/lang/vn.rs index a6a4478e7..e65fab66b 100644 --- a/src/lang/vn.rs +++ b/src/lang/vn.rs @@ -543,5 +543,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("HSV Color", ""), ("Installation Successful!", ""), ("Installation failed!", ""), + ("Reverse mouse wheel", ""), ].iter().cloned().collect(); } diff --git a/src/ui_session_interface.rs b/src/ui_session_interface.rs index a8304b5d0..dae85fe5f 100644 --- a/src/ui_session_interface.rs +++ b/src/ui_session_interface.rs @@ -1,4 +1,4 @@ -use crate::input::{MOUSE_BUTTON_LEFT, MOUSE_TYPE_DOWN, MOUSE_TYPE_UP}; +use crate::input::{MOUSE_BUTTON_LEFT, MOUSE_TYPE_DOWN, MOUSE_TYPE_UP, MOUSE_TYPE_WHEEL}; #[cfg(not(any(target_os = "android", target_os = "ios")))] use std::{collections::HashMap, sync::atomic::AtomicBool}; use std::{ @@ -175,6 +175,14 @@ impl Session { self.lc.write().unwrap().save_keyboard_mode(value); } + pub fn get_reverse_mouse_wheel(&self) -> String { + self.lc.read().unwrap().reverse_mouse_wheel.clone() + } + + pub fn save_reverse_mouse_wheel(&mut self, value: String) { + self.lc.write().unwrap().save_reverse_mouse_wheel(value); + } + pub fn save_view_style(&mut self, value: String) { self.lc.write().unwrap().save_view_style(value); } @@ -730,6 +738,7 @@ impl Session { }); } "pan_update" => { + let (x, y) = self.get_scroll_xy((x, y)); touch_evt.set_pan_update(TouchPanUpdate { x, y, @@ -753,6 +762,21 @@ impl Session { send_pointer_device_event(evt, alt, ctrl, shift, command, self); } + #[inline] + #[cfg(not(any(target_os = "android", target_os = "ios")))] + fn is_scroll_reverse_mode(&self) -> bool { + self.lc.read().unwrap().reverse_mouse_wheel.eq("Y") + } + + #[inline] + fn get_scroll_xy(&self, xy: (i32, i32)) -> (i32, i32) { + #[cfg(not(any(target_os = "android", target_os = "ios")))] + if self.is_scroll_reverse_mode() { + return (-xy.0, -xy.1); + } + xy + } + pub fn send_mouse( &self, mask: i32, @@ -772,6 +796,12 @@ impl Session { } } + let (x, y) = if mask == MOUSE_TYPE_WHEEL { + self.get_scroll_xy((x, y)) + } else { + (x, y) + }; + // #[cfg(not(any(target_os = "android", target_os = "ios")))] let (alt, ctrl, shift, command) = keyboard::client::get_modifiers_state(alt, ctrl, shift, command);