From 02c1bc6080fd5e8de83f6a74c9d4a76d6aff5281 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 24 Nov 2022 11:19:16 +0800 Subject: [PATCH] hide zoom-cursor if view-style is original Signed-off-by: fufesou --- flutter/lib/consts.dart | 24 ++++++ .../lib/desktop/pages/remote_tab_page.dart | 7 +- .../lib/desktop/widgets/remote_menubar.dart | 81 +++++++++++-------- flutter/lib/mobile/pages/remote_page.dart | 25 +++--- flutter/lib/models/model.dart | 2 +- libs/hbb_common/src/config.rs | 5 +- 6 files changed, 92 insertions(+), 52 deletions(-) diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart index acba32780..4d3cd8cd9 100644 --- a/flutter/lib/consts.dart +++ b/flutter/lib/consts.dart @@ -70,6 +70,30 @@ const kMouseControlDistance = 12; /// [kMouseControlTimeoutMSec] indicates the timeout (in milliseconds) that self-side can get control of mouse. const kMouseControlTimeoutMSec = 1000; +/// [kRemoteViewStyleOriginal] Show remote image without scaling. +const kRemoteViewStyleOriginal = 'original'; + +/// [kRemoteViewStyleAdaptive] Show remote image scaling by ratio factor. +const kRemoteViewStyleAdaptive = 'adaptive'; + +/// [kRemoteScrollStyleAuto] Scroll image auto by position. +const kRemoteScrollStyleAuto = 'scrollauto'; + +/// [kRemoteScrollStyleBar] Scroll image with scroll bar. +const kRemoteScrollStyleBar = 'scrollbar'; + +/// [kRemoteImageQualityBest] Best image quality. +const kRemoteImageQualityBest = 'best'; + +/// [kRemoteImageQualityBalanced] Balanced image quality, mid performance. +const kRemoteImageQualityBalanced = 'balanced'; + +/// [kRemoteImageQualityLow] Low image quality, better performance. +const kRemoteImageQualityLow = 'low'; + +/// [kRemoteImageQualityCustom] Custom image quality. +const kRemoteImageQualityCustom = 'custom'; + /// flutter/packages/flutter/lib/src/services/keyboard_key.dart -> _keyLabels /// see [LogicalKeyboardKey.keyLabel] const Map logicalKeyMap = { diff --git a/flutter/lib/desktop/pages/remote_tab_page.dart b/flutter/lib/desktop/pages/remote_tab_page.dart index 1e942272c..85df25477 100644 --- a/flutter/lib/desktop/pages/remote_tab_page.dart +++ b/flutter/lib/desktop/pages/remote_tab_page.dart @@ -236,12 +236,12 @@ class _ConnectionTabPageState extends State { optionsGetter: () => [ MenuEntryRadioOption( text: translate('Scale original'), - value: 'original', + value: kRemoteViewStyleOriginal, dismissOnClicked: true, ), MenuEntryRadioOption( text: translate('Scale adaptive'), - value: 'adaptive', + value: kRemoteViewStyleAdaptive, dismissOnClicked: true, ), ], @@ -249,8 +249,7 @@ class _ConnectionTabPageState extends State { // null means peer id is not found, which there's no need to care about await bind.sessionGetViewStyle(id: key) ?? '', optionSetter: (String oldValue, String newValue) async { - await bind.sessionSetViewStyle( - id: key, value: newValue); + await bind.sessionSetViewStyle(id: key, value: newValue); ffi.canvasModel.updateViewStyle(); cancelFunc(); }, diff --git a/flutter/lib/desktop/widgets/remote_menubar.dart b/flutter/lib/desktop/widgets/remote_menubar.dart index ed69f3e65..656dc8546 100644 --- a/flutter/lib/desktop/widgets/remote_menubar.dart +++ b/flutter/lib/desktop/widgets/remote_menubar.dart @@ -7,6 +7,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hbb/models/chat_model.dart'; import 'package:flutter_hbb/models/state_model.dart'; +import 'package:flutter_hbb/consts.dart'; import 'package:get/get.dart'; import 'package:provider/provider.dart'; import 'package:rxdart/rxdart.dart' as rxdart; @@ -25,6 +26,7 @@ class MenubarState { final kStoreKey = 'remoteMenubarState'; late RxBool show; late RxBool _pin; + RxString viewStyle = RxString(kRemoteViewStyleOriginal); MenubarState() { final s = bind.getLocalFlutterConfig(k: kStoreKey); @@ -67,21 +69,25 @@ class MenubarState { switchPin() async { _pin.value = !_pin.value; // Save everytime changed, as this func will not be called frequently - await save(); + await _savePin(); } setPin(bool v) async { if (_pin.value != v) { _pin.value = v; // Save everytime changed, as this func will not be called frequently - await save(); + await _savePin(); } } - save() async { + _savePin() async { bind.setLocalFlutterConfig( k: kStoreKey, v: jsonEncode({'pin': _pin.value})); } + + save() async { + await _savePin(); + } } class _MenubarTheme { @@ -404,6 +410,8 @@ class _RemoteMenubarState extends State { Widget _buildDisplay(BuildContext context) { return FutureBuilder(future: () async { + widget.state.viewStyle.value = + await bind.sessionGetViewStyle(id: widget.id) ?? ''; final supportedHwcodec = await bind.sessionSupportedHwcodec(id: widget.id); return {'supportedHwcodec': supportedHwcodec}; @@ -719,20 +727,24 @@ class _RemoteMenubarState extends State { optionsGetter: () => [ MenuEntryRadioOption( text: translate('Scale original'), - value: 'original', + value: kRemoteViewStyleOriginal, dismissOnClicked: true, ), MenuEntryRadioOption( text: translate('Scale adaptive'), - value: 'adaptive', + value: kRemoteViewStyleAdaptive, dismissOnClicked: true, ), ], - curOptionGetter: () async => - // null means peer id is not found, which there's no need to care about - await bind.sessionGetViewStyle(id: widget.id) ?? '', + curOptionGetter: () async { + // null means peer id is not found, which there's no need to care about + final viewStyle = await bind.sessionGetViewStyle(id: widget.id) ?? ''; + widget.state.viewStyle.value = viewStyle; + return viewStyle; + }, optionSetter: (String oldValue, String newValue) async { await bind.sessionSetViewStyle(id: widget.id, value: newValue); + widget.state.viewStyle.value = newValue; widget.ffi.canvasModel.updateViewStyle(); }, padding: padding, @@ -744,12 +756,12 @@ class _RemoteMenubarState extends State { optionsGetter: () => [ MenuEntryRadioOption( text: translate('ScrollAuto'), - value: 'scrollauto', + value: kRemoteScrollStyleAuto, dismissOnClicked: true, ), MenuEntryRadioOption( text: translate('Scrollbar'), - value: 'scrollbar', + value: kRemoteScrollStyleBar, dismissOnClicked: true, ), ], @@ -769,22 +781,22 @@ class _RemoteMenubarState extends State { optionsGetter: () => [ MenuEntryRadioOption( text: translate('Good image quality'), - value: 'best', + value: kRemoteImageQualityBest, dismissOnClicked: true, ), MenuEntryRadioOption( text: translate('Balanced'), - value: 'balanced', + value: kRemoteImageQualityBalanced, dismissOnClicked: true, ), MenuEntryRadioOption( text: translate('Optimize reaction time'), - value: 'low', + value: kRemoteImageQualityLow, dismissOnClicked: true, ), MenuEntryRadioOption( text: translate('Custom'), - value: 'custom', + value: kRemoteImageQualityCustom, dismissOnClicked: true), ], curOptionGetter: () async => @@ -821,7 +833,7 @@ class _RemoteMenubarState extends State { } } - if (newValue == 'custom') { + if (newValue == kRemoteImageQualityCustom) { final btnClose = msgBoxButton(translate('Close'), () async { await setCustomValues(); widget.ffi.dialogManager.dismissAll(); @@ -1089,24 +1101,26 @@ class _RemoteMenubarState extends State { ); }()); - /// Show remote cursor - displayMenu.add(() { - final opt = 'zoom-cursor'; - final state = PeerBoolOption.find(widget.id, opt); - return MenuEntrySwitch2( - switchType: SwitchType.scheckbox, - text: translate('Zoom cursor'), - getter: () { - return state; - }, - setter: (bool v) async { - state.value = v; - await bind.sessionToggleOption(id: widget.id, value: opt); - }, - padding: padding, - dismissOnClicked: true, - ); - }()); + /// Show remote cursor scaling with image + if (widget.state.viewStyle.value != kRemoteViewStyleOriginal) { + displayMenu.add(() { + final opt = 'zoom-cursor'; + final state = PeerBoolOption.find(widget.id, opt); + return MenuEntrySwitch2( + switchType: SwitchType.scheckbox, + text: translate('Zoom cursor'), + getter: () { + return state; + }, + setter: (bool v) async { + state.value = v; + await bind.sessionToggleOption(id: widget.id, value: opt); + }, + padding: padding, + dismissOnClicked: true, + ); + }()); + } /// Show quality monitor displayMenu.add(MenuEntrySwitch( @@ -1179,7 +1193,6 @@ class _RemoteMenubarState extends State { optionSetter: (String oldValue, String newValue) async { await bind.sessionSetKeyboardMode( id: widget.id, keyboardMode: newValue); - widget.ffi.canvasModel.updateViewStyle(); }, ) ]; diff --git a/flutter/lib/mobile/pages/remote_page.dart b/flutter/lib/mobile/pages/remote_page.dart index b17f0ef54..e6ebfcb73 100644 --- a/flutter/lib/mobile/pages/remote_page.dart +++ b/flutter/lib/mobile/pages/remote_page.dart @@ -4,6 +4,7 @@ import 'dart:ui' as ui; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_hbb/consts.dart'; import 'package:flutter_hbb/mobile/widgets/gesture_help.dart'; import 'package:flutter_hbb/models/chat_model.dart'; import 'package:get/get_state_manager/src/rx_flutter/rx_obx_widget.dart'; @@ -642,7 +643,7 @@ class _RemotePageState extends State { // FIXME: // null means no session of id // empty string means no password - var password = await bind.sessionGetOption(id: id, arg: "os-password"); + var password = await bind.sessionGetOption(id: id, arg: 'os-password'); if (password != null) { bind.sessionInputOsPassword(id: widget.id, value: password); } else { @@ -908,13 +909,13 @@ class ImagePainter extends CustomPainter { void showOptions( BuildContext context, String id, OverlayDialogManager dialogManager) async { - String quality = await bind.sessionGetImageQuality(id: id) ?? 'balanced'; - if (quality == '') quality = 'balanced'; + String quality = + await bind.sessionGetImageQuality(id: id) ?? kRemoteImageQualityBalanced; + if (quality == '') quality = kRemoteImageQualityBalanced; String codec = await bind.sessionGetOption(id: id, arg: 'codec-preference') ?? 'auto'; if (codec == '') codec = 'auto'; - String viewStyle = - await bind.sessionGetOption(id: id, arg: 'view-style') ?? ''; + String viewStyle = await bind.sessionGetViewStyle(id: id) ?? ''; var displays = []; final pi = gFFI.ffiModel.pi; @@ -1017,12 +1018,16 @@ void showOptions( } final radios = [ - getRadio('Scale original', 'original', viewStyle, setViewStyle), - getRadio('Scale adaptive', 'adaptive', viewStyle, setViewStyle), + getRadio( + 'Scale original', kRemoteViewStyleOriginal, viewStyle, setViewStyle), + getRadio( + 'Scale adaptive', kRemoteViewStyleAdaptive, viewStyle, setViewStyle), const Divider(color: MyTheme.border), - getRadio('Good image quality', 'best', quality, setQuality), - getRadio('Balanced', 'balanced', quality, setQuality), - getRadio('Optimize reaction time', 'low', quality, setQuality), + getRadio( + 'Good image quality', kRemoteImageQualityBest, quality, setQuality), + getRadio('Balanced', kRemoteImageQualityBalanced, quality, setQuality), + getRadio('Optimize reaction time', kRemoteImageQualityLow, quality, + setQuality), const Divider(color: MyTheme.border) ]; diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index b7d72f878..a7a51b9a0 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -565,7 +565,7 @@ class CanvasModel with ChangeNotifier { updateScrollStyle() async { final style = await bind.sessionGetScrollStyle(id: id); - if (style == 'scrollbar') { + if (style == kRemoteScrollStyleBar) { _scrollStyle = ScrollStyle.scrollbar; _scrollX = 0.0; _scrollY = 0.0; diff --git a/libs/hbb_common/src/config.rs b/libs/hbb_common/src/config.rs index 40ae61f90..f476816ef 100644 --- a/libs/hbb_common/src/config.rs +++ b/libs/hbb_common/src/config.rs @@ -1,6 +1,5 @@ use std::{ collections::HashMap, - ffi::{OsStr, OsString}, fs, net::{IpAddr, Ipv4Addr, SocketAddr}, path::{Path, PathBuf}, @@ -896,13 +895,13 @@ impl PeerConfig { } fn path(id: &str) -> PathBuf { - let mut id_encoded: String; + let id_encoded: String; //If the id contains invalid chars, encode it let forbidden_paths = Regex::new(r".*[<>:/\\|\?\*].*").unwrap(); if forbidden_paths.is_match(id) { id_encoded = - ("base64_".to_string() + base64::encode(id, base64::Variant::Original).as_str()) + "base64_".to_string() + base64::encode(id, base64::Variant::Original).as_str(); } else { id_encoded = id.to_string(); }