enable rust default option

Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
fufesou 2022-11-17 18:52:27 +08:00
parent 7bb39f5607
commit 75d8168070
9 changed files with 162 additions and 82 deletions

View File

@ -246,13 +246,12 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
dismissOnClicked: true, dismissOnClicked: true,
), ),
], ],
curOptionGetter: () async { curOptionGetter: () async =>
return await bind.sessionGetOption(id: key, arg: 'view-style') ?? // null means peer id is not found, which there's no need to care about
'adaptive'; await bind.sessionGetViewStyle(id: key) ?? '',
},
optionSetter: (String oldValue, String newValue) async { optionSetter: (String oldValue, String newValue) async {
await bind.sessionPeerOption( await bind.sessionSetViewStyle(
id: key, name: "view-style", value: newValue); id: key, value: newValue);
ffi.canvasModel.updateViewStyle(); ffi.canvasModel.updateViewStyle();
cancelFunc(); cancelFunc();
}, },

View File

@ -22,7 +22,7 @@ import './popup_menu.dart';
import './material_mod_popup_menu.dart' as mod_menu; import './material_mod_popup_menu.dart' as mod_menu;
class MenubarState { class MenubarState {
final kStoreKey = "remoteMenubarState"; final kStoreKey = 'remoteMenubarState';
late RxBool show; late RxBool show;
late RxBool _pin; late RxBool _pin;
@ -195,7 +195,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
} }
_updateScreen() async { _updateScreen() async {
final v = await DesktopMultiWindow.invokeMethod(0, "get_window_info", ""); final v = await DesktopMultiWindow.invokeMethod(0, 'get_window_info', '');
final String valueStr = v; final String valueStr = v;
if (valueStr.isEmpty) { if (valueStr.isEmpty) {
_screen = null; _screen = null;
@ -322,7 +322,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
child: Obx(() { child: Obx(() {
RxInt display = CurrentDisplayState.find(widget.id); RxInt display = CurrentDisplayState.find(widget.id);
return Text( return Text(
"${display.value + 1}/${pi.displays.length}", '${display.value + 1}/${pi.displays.length}',
style: const TextStyle( style: const TextStyle(
color: _MenubarTheme.commonColor, fontSize: 8), color: _MenubarTheme.commonColor, fontSize: 8),
); );
@ -595,10 +595,10 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
)); ));
} }
} }
if (perms["restart"] != false && if (perms['restart'] != false &&
(pi.platform == "Linux" || (pi.platform == 'Linux' ||
pi.platform == "Windows" || pi.platform == 'Windows' ||
pi.platform == "Mac OS")) { pi.platform == 'Mac OS')) {
displayMenu.add(MenuEntryButton<String>( displayMenu.add(MenuEntryButton<String>(
childBuilder: (TextStyle? style) => Text( childBuilder: (TextStyle? style) => Text(
translate('Restart Remote Device'), translate('Restart Remote Device'),
@ -629,14 +629,14 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
displayMenu.add(MenuEntryButton<String>( displayMenu.add(MenuEntryButton<String>(
childBuilder: (TextStyle? style) => Obx(() => Text( childBuilder: (TextStyle? style) => Obx(() => Text(
translate( translate(
'${BlockInputState.find(widget.id).value ? "Unb" : "B"}lock user input'), '${BlockInputState.find(widget.id).value ? 'Unb' : 'B'}lock user input'),
style: style, style: style,
)), )),
proc: () { proc: () {
RxBool blockInput = BlockInputState.find(widget.id); RxBool blockInput = BlockInputState.find(widget.id);
bind.sessionToggleOption( bind.sessionToggleOption(
id: widget.id, id: widget.id,
value: '${blockInput.value ? "un" : ""}block-input'); value: '${blockInput.value ? 'un' : ''}block-input');
blockInput.value = !blockInput.value; blockInput.value = !blockInput.value;
}, },
padding: padding, padding: padding,
@ -671,7 +671,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
// ClipboardData? data = // ClipboardData? data =
// await Clipboard.getData(Clipboard.kTextPlain); // await Clipboard.getData(Clipboard.kTextPlain);
// if (data != null && data.text != null) { // if (data != null && data.text != null) {
// bind.sessionInputString(id: widget.id, value: data.text ?? ""); // bind.sessionInputString(id: widget.id, value: data.text ?? '');
// } // }
// }(); // }();
// }, // },
@ -679,18 +679,6 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
// dismissOnClicked: true, // dismissOnClicked: true,
// )); // ));
// } // }
displayMenu.add(MenuEntryButton<String>(
childBuilder: (TextStyle? style) => Text(
translate('Reset canvas'),
style: style,
),
proc: () {
widget.ffi.cursorModel.reset();
},
padding: padding,
dismissOnClicked: true,
));
} }
return displayMenu; return displayMenu;
@ -740,14 +728,11 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
dismissOnClicked: true, dismissOnClicked: true,
), ),
], ],
curOptionGetter: () async { curOptionGetter: () async =>
return await bind.sessionGetOption( // null means peer id is not found, which there's no need to care about
id: widget.id, arg: 'view-style') ?? await bind.sessionGetViewStyle(id: widget.id) ?? '',
'adaptive';
},
optionSetter: (String oldValue, String newValue) async { optionSetter: (String oldValue, String newValue) async {
await bind.sessionPeerOption( await bind.sessionSetViewStyle(id: widget.id, value: newValue);
id: widget.id, name: "view-style", value: newValue);
widget.ffi.canvasModel.updateViewStyle(); widget.ffi.canvasModel.updateViewStyle();
}, },
padding: padding, padding: padding,
@ -768,14 +753,11 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
dismissOnClicked: true, dismissOnClicked: true,
), ),
], ],
curOptionGetter: () async { curOptionGetter: () async =>
return await bind.sessionGetOption( // null means peer id is not found, which there's no need to care about
id: widget.id, arg: 'scroll-style') ?? await bind.sessionGetScrollStyle(id: widget.id) ?? '',
'';
},
optionSetter: (String oldValue, String newValue) async { optionSetter: (String oldValue, String newValue) async {
await bind.sessionPeerOption( await bind.sessionSetScrollStyle(id: widget.id, value: newValue);
id: widget.id, name: "scroll-style", value: newValue);
widget.ffi.canvasModel.updateScrollStyle(); widget.ffi.canvasModel.updateScrollStyle();
}, },
padding: padding, padding: padding,
@ -805,12 +787,9 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
value: 'custom', value: 'custom',
dismissOnClicked: true), dismissOnClicked: true),
], ],
curOptionGetter: () async { curOptionGetter: () async =>
String quality = // null means peer id is not found, which there's no need to care about
await bind.sessionGetImageQuality(id: widget.id) ?? 'balanced'; await bind.sessionGetImageQuality(id: widget.id) ?? '',
if (quality == '') quality = 'balanced';
return quality;
},
optionSetter: (String oldValue, String newValue) async { optionSetter: (String oldValue, String newValue) async {
if (oldValue != newValue) { if (oldValue != newValue) {
await bind.sessionSetImageQuality(id: widget.id, value: newValue); await bind.sessionSetImageQuality(id: widget.id, value: newValue);
@ -1075,14 +1054,14 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
} }
return list; return list;
}, },
curOptionGetter: () async { curOptionGetter: () async =>
return await bind.sessionGetOption( // null means peer id is not found, which there's no need to care about
id: widget.id, arg: 'codec-preference') ?? await bind.sessionGetOption(
'auto'; id: widget.id, arg: 'codec-preference') ??
}, '',
optionSetter: (String oldValue, String newValue) async { optionSetter: (String oldValue, String newValue) async {
await bind.sessionPeerOption( await bind.sessionPeerOption(
id: widget.id, name: "codec-preference", value: newValue); id: widget.id, name: 'codec-preference', value: newValue);
bind.sessionChangePreferCodec(id: widget.id); bind.sessionChangePreferCodec(id: widget.id);
}, },
padding: padding, padding: padding,
@ -1195,9 +1174,8 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
MenuEntryRadioOption(text: translate('Legacy mode'), value: 'legacy'), MenuEntryRadioOption(text: translate('Legacy mode'), value: 'legacy'),
MenuEntryRadioOption(text: translate('Map mode'), value: 'map'), MenuEntryRadioOption(text: translate('Map mode'), value: 'map'),
], ],
curOptionGetter: () async { curOptionGetter: () async =>
return await bind.sessionGetKeyboardName(id: widget.id); await bind.sessionGetKeyboardName(id: widget.id),
},
optionSetter: (String oldValue, String newValue) async { optionSetter: (String oldValue, String newValue) async {
await bind.sessionSetKeyboardMode( await bind.sessionSetKeyboardMode(
id: widget.id, keyboardMode: newValue); id: widget.id, keyboardMode: newValue);
@ -1229,16 +1207,16 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
void showSetOSPassword( void showSetOSPassword(
String id, bool login, OverlayDialogManager dialogManager) async { String id, bool login, OverlayDialogManager dialogManager) async {
final controller = TextEditingController(); final controller = TextEditingController();
var password = await bind.sessionGetOption(id: id, arg: "os-password") ?? ""; var password = await bind.sessionGetOption(id: id, arg: 'os-password') ?? '';
var autoLogin = await bind.sessionGetOption(id: id, arg: "auto-login") != ""; var autoLogin = await bind.sessionGetOption(id: id, arg: 'auto-login') != '';
controller.text = password; controller.text = password;
dialogManager.show((setState, close) { dialogManager.show((setState, close) {
submit() { submit() {
var text = controller.text.trim(); var text = controller.text.trim();
bind.sessionPeerOption(id: id, name: "os-password", value: text); bind.sessionPeerOption(id: id, name: 'os-password', value: text);
bind.sessionPeerOption( bind.sessionPeerOption(
id: id, name: "auto-login", value: autoLogin ? 'Y' : ''); id: id, name: 'auto-login', value: autoLogin ? 'Y' : '');
if (text != "" && login) { if (text != '' && login) {
bind.sessionInputOsPassword(id: id, value: text); bind.sessionInputOsPassword(id: id, value: text);
} }
close(); close();
@ -1285,7 +1263,7 @@ void showAuditDialog(String id, dialogManager) async {
dialogManager.show((setState, close) { dialogManager.show((setState, close) {
submit() { submit() {
var text = controller.text.trim(); var text = controller.text.trim();
if (text != "") { if (text != '') {
bind.sessionSendNote(id: id, note: text); bind.sessionSendNote(id: id, note: text);
} }
close(); close();
@ -1324,11 +1302,11 @@ void showAuditDialog(String id, dialogManager) async {
keyboardType: TextInputType.multiline, keyboardType: TextInputType.multiline,
textInputAction: TextInputAction.newline, textInputAction: TextInputAction.newline,
decoration: const InputDecoration.collapsed( decoration: const InputDecoration.collapsed(
hintText: "input note here", hintText: 'input note here',
), ),
// inputFormatters: [ // inputFormatters: [
// LengthLimitingTextInputFormatter(16), // LengthLimitingTextInputFormatter(16),
// // FilteringTextInputFormatter(RegExp(r"[a-zA-z][a-zA-z0-9\_]*"), allow: true) // // FilteringTextInputFormatter(RegExp(r'[a-zA-z][a-zA-z0-9\_]*'), allow: true)
// ], // ],
maxLines: null, maxLines: null,
maxLength: 256, maxLength: 256,

View File

@ -474,7 +474,7 @@ class _RemotePageState extends State<RemotePage> {
}, },
onTwoFingerScaleEnd: (d) { onTwoFingerScaleEnd: (d) {
_scale = 1; _scale = 1;
bind.sessionPeerOption(id: widget.id, name: "view-style", value: ""); bind.sessionSetViewStyle(id: widget.id, value: "");
}, },
onThreeFingerVerticalDragUpdate: gFFI.ffiModel.isPeerAndroid onThreeFingerVerticalDragUpdate: gFFI.ffiModel.isPeerAndroid
? null ? null
@ -1001,7 +1001,7 @@ void showOptions(
setState(() { setState(() {
viewStyle = value; viewStyle = value;
bind bind
.sessionPeerOption(id: id, name: "view-style", value: value) .sessionSetViewStyle(id: id, value: value)
.then((_) => gFFI.canvasModel.updateViewStyle()); .then((_) => gFFI.canvasModel.updateViewStyle());
}); });
} }

View File

@ -413,7 +413,7 @@ class ImageModel with ChangeNotifier {
await initializeCursorAndCanvas(parent.target!); await initializeCursorAndCanvas(parent.target!);
} }
if (parent.target?.ffiModel.isPeerAndroid ?? false) { if (parent.target?.ffiModel.isPeerAndroid ?? false) {
bind.sessionPeerOption(id: id, name: 'view-style', value: 'adaptive'); bind.sessionSetViewStyle(id: id, value: 'adaptive');
parent.target?.canvasModel.updateViewStyle(); parent.target?.canvasModel.updateViewStyle();
} }
} }
@ -535,7 +535,7 @@ class CanvasModel with ChangeNotifier {
double get scrollY => _scrollY; double get scrollY => _scrollY;
updateViewStyle() async { updateViewStyle() async {
final style = await bind.sessionGetOption(id: id, arg: 'view-style'); final style = await bind.sessionGetViewStyle(id: id);
if (style == null) { if (style == null) {
return; return;
} }
@ -561,7 +561,7 @@ class CanvasModel with ChangeNotifier {
} }
updateScrollStyle() async { updateScrollStyle() async {
final style = await bind.sessionGetOption(id: id, arg: 'scroll-style'); final style = await bind.sessionGetScrollStyle(id: id);
if (style == 'scrollbar') { if (style == 'scrollbar') {
_scrollStyle = ScrollStyle.scrollbar; _scrollStyle = ScrollStyle.scrollbar;
_scrollX = 0.0; _scrollX = 0.0;

View File

@ -9,6 +9,7 @@ use std::{
use anyhow::Result; use anyhow::Result;
use rand::Rng; use rand::Rng;
use serde as de;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use sodiumoxide::crypto::sign; use sodiumoxide::crypto::sign;
@ -79,6 +80,26 @@ pub const RS_PUB_KEY: &'static str = "OeVuKk5nlHiXp+APNn0Y3pC1Iwpwn44JGqrQCsWqmB
pub const RENDEZVOUS_PORT: i32 = 21116; pub const RENDEZVOUS_PORT: i32 = 21116;
pub const RELAY_PORT: i32 = 21117; pub const RELAY_PORT: i32 = 21117;
macro_rules! serde_field_string {
($default_func:ident, $de_func:ident, $default_expr:expr) => {
fn $default_func() -> String {
$default_expr
}
fn $de_func<'de, D>(deserializer: D) -> Result<String, D::Error>
where
D: de::Deserializer<'de>,
{
let s: &str = de::Deserialize::deserialize(deserializer)?;
Ok(if s.is_empty() {
Self::$default_func()
} else {
s.to_owned()
})
}
};
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)] #[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum NetworkType { pub enum NetworkType {
Direct, Direct,
@ -141,9 +162,20 @@ pub struct PeerConfig {
pub size_ft: Size, pub size_ft: Size,
#[serde(default)] #[serde(default)]
pub size_pf: Size, pub size_pf: Size,
#[serde(default)] #[serde(
pub view_style: String, // original (default), scale default = "PeerConfig::default_view_style",
#[serde(default)] deserialize_with = "PeerConfig::deserialize_view_style"
)]
pub view_style: String,
#[serde(
default = "PeerConfig::default_scroll_style",
deserialize_with = "PeerConfig::deserialize_scroll_style"
)]
pub scroll_style: String,
#[serde(
default = "PeerConfig::default_image_quality",
deserialize_with = "PeerConfig::deserialize_image_quality"
)]
pub image_quality: String, pub image_quality: String,
#[serde(default)] #[serde(default)]
pub custom_image_quality: Vec<i32>, pub custom_image_quality: Vec<i32>,
@ -167,7 +199,10 @@ pub struct PeerConfig {
pub show_quality_monitor: bool, pub show_quality_monitor: bool,
// The other scalar value must before this // The other scalar value must before this
#[serde(default)] #[serde(
default,
deserialize_with = "PeerConfig::deserialize_options"
)]
pub options: HashMap<String, String>, pub options: HashMap<String, String>,
// Various data for flutter ui // Various data for flutter ui
#[serde(default)] #[serde(default)]
@ -400,7 +435,9 @@ impl Config {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
let org = ORG.read().unwrap().clone(); let org = ORG.read().unwrap().clone();
// /var/root for root // /var/root for root
if let Some(project) = directories_next::ProjectDirs::from("", &org, &*APP_NAME.read().unwrap()) { if let Some(project) =
directories_next::ProjectDirs::from("", &org, &*APP_NAME.read().unwrap())
{
let mut path = patch(project.config_dir().to_path_buf()); let mut path = patch(project.config_dir().to_path_buf());
path.push(p); path.push(p);
return path; return path;
@ -896,6 +933,21 @@ impl PeerConfig {
} }
Default::default() Default::default()
} }
serde_field_string!(default_view_style, deserialize_view_style, "original".to_owned());
serde_field_string!(default_scroll_style, deserialize_scroll_style, "scrollauto".to_owned());
serde_field_string!(default_image_quality, deserialize_image_quality, "balanced".to_owned());
fn deserialize_options<'de, D>(deserializer: D) -> Result<HashMap<String, String>, D::Error>
where
D: de::Deserializer<'de>,
{
let mut mp: HashMap<String, String> = de::Deserialize::deserialize(deserializer)?;
if !mp.contains_key("codec-preference") {
mp.insert("codec-preference".to_owned(), "auto".to_owned());
}
Ok(mp)
}
} }
#[derive(Debug, Default, Serialize, Deserialize, Clone)] #[derive(Debug, Default, Serialize, Deserialize, Clone)]

View File

@ -974,6 +974,8 @@ impl LoginConfigHandler {
self.save_config(config); self.save_config(config);
} }
//to-do: too many dup code below.
/// Save view style to the current config. /// Save view style to the current config.
/// ///
/// # Arguments /// # Arguments
@ -985,13 +987,24 @@ impl LoginConfigHandler {
self.save_config(config); self.save_config(config);
} }
/// Save scroll style to the current config.
///
/// # Arguments
///
/// * `value` - The view style to be saved.
pub fn save_scroll_style(&mut self, value: String) {
let mut config = self.load_config();
config.scroll_style = value;
self.save_config(config);
}
/// Set a ui config of flutter for handler's [`PeerConfig`]. /// Set a ui config of flutter for handler's [`PeerConfig`].
/// ///
/// # Arguments /// # Arguments
/// ///
/// * `k` - key of option /// * `k` - key of option
/// * `v` - value of option /// * `v` - value of option
pub fn set_ui_flutter(&mut self, k: String, v: String) { pub fn save_ui_flutter(&mut self, k: String, v: String) {
let mut config = self.load_config(); let mut config = self.load_config();
config.ui_flutter.insert(k, v); config.ui_flutter.insert(k, v);
self.save_config(config); self.save_config(config);

View File

@ -170,7 +170,7 @@ pub fn session_get_flutter_config(id: String, k: String) -> Option<String> {
pub fn session_set_flutter_config(id: String, k: String, v: String) { pub fn session_set_flutter_config(id: String, k: String, v: String) {
if let Some(session) = SESSIONS.write().unwrap().get_mut(&id) { if let Some(session) = SESSIONS.write().unwrap().get_mut(&id) {
session.set_flutter_config(k, v); session.save_flutter_config(k, v);
} }
} }
@ -182,6 +182,34 @@ pub fn set_local_flutter_config(k: String, v: String) {
ui_interface::set_local_flutter_config(k, v); ui_interface::set_local_flutter_config(k, v);
} }
pub fn session_get_view_style(id: String) -> Option<String> {
if let Some(session) = SESSIONS.read().unwrap().get(&id) {
Some(session.get_view_style())
} else {
None
}
}
pub fn session_set_view_style(id: String, value: String) {
if let Some(session) = SESSIONS.write().unwrap().get_mut(&id) {
session.save_view_style(value);
}
}
pub fn session_get_scroll_style(id: String) -> Option<String> {
if let Some(session) = SESSIONS.read().unwrap().get(&id) {
Some(session.get_scroll_style())
} else {
None
}
}
pub fn session_set_scroll_style(id: String, value: String) {
if let Some(session) = SESSIONS.write().unwrap().get_mut(&id) {
session.save_scroll_style(value);
}
}
pub fn session_get_image_quality(id: String) -> Option<String> { pub fn session_get_image_quality(id: String) -> Option<String> {
if let Some(session) = SESSIONS.read().unwrap().get(&id) { if let Some(session) = SESSIONS.read().unwrap().get(&id) {
Some(session.get_image_quality()) Some(session.get_image_quality())

View File

@ -25,12 +25,16 @@ use hbb_common::tokio::sync::{
mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender}, mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
Mutex as TokioMutex, Mutex as TokioMutex,
}; };
#[cfg(not(windows))]
use scrap::Capturer;
use scrap::{ use scrap::{
codec::{Encoder, EncoderCfg, HwEncoderConfig}, codec::{Encoder, EncoderCfg, HwEncoderConfig},
record::{Recorder, RecorderContext}, record::{Recorder, RecorderContext},
vpxcodec::{VpxEncoderConfig, VpxVideoCodecId}, vpxcodec::{VpxEncoderConfig, VpxVideoCodecId},
Capturer, Display, TraitCapturer, Display, TraitCapturer,
}; };
#[cfg(windows)]
use std::sync::Once;
use std::{ use std::{
collections::HashSet, collections::HashSet,
io::ErrorKind::WouldBlock, io::ErrorKind::WouldBlock,
@ -38,8 +42,6 @@ use std::{
time::{self, Duration, Instant}, time::{self, Duration, Instant},
}; };
#[cfg(windows)] #[cfg(windows)]
use std::sync::Once;
#[cfg(windows)]
use virtual_display; use virtual_display;
pub const SCRAP_UBUNTU_HIGHER_REQUIRED: &str = "Wayland requires Ubuntu 21.04 or higher version."; pub const SCRAP_UBUNTU_HIGHER_REQUIRED: &str = "Wayland requires Ubuntu 21.04 or higher version.";

View File

@ -79,6 +79,10 @@ impl<T: InvokeUiSession> Session<T> {
self.lc.read().unwrap().view_style.clone() self.lc.read().unwrap().view_style.clone()
} }
pub fn get_scroll_style(&self) -> String {
self.lc.read().unwrap().scroll_style.clone()
}
pub fn get_image_quality(&self) -> String { pub fn get_image_quality(&self) -> String {
self.lc.read().unwrap().image_quality.clone() self.lc.read().unwrap().image_quality.clone()
} }
@ -99,8 +103,12 @@ impl<T: InvokeUiSession> Session<T> {
self.lc.write().unwrap().save_view_style(value); self.lc.write().unwrap().save_view_style(value);
} }
pub fn set_flutter_config(&mut self, k: String, v: String) { pub fn save_scroll_style(&mut self, value: String) {
self.lc.write().unwrap().set_ui_flutter(k, v); self.lc.write().unwrap().save_scroll_style(value);
}
pub fn save_flutter_config(&mut self, k: String, v: String) {
self.lc.write().unwrap().save_ui_flutter(k, v);
} }
pub fn get_flutter_config(&self, k: String) -> String { pub fn get_flutter_config(&self, k: String) -> String {