commit
e17717b9c5
@ -1318,6 +1318,7 @@ class _DisplayState extends State<_Display> {
|
|||||||
|
|
||||||
Widget other(BuildContext context) {
|
Widget other(BuildContext context) {
|
||||||
return _Card(title: 'Other Default Options', children: [
|
return _Card(title: 'Other Default Options', children: [
|
||||||
|
otherRow('View Mode', 'view-only'),
|
||||||
otherRow('show_monitors_tip', 'show_monitors_toolbar'),
|
otherRow('show_monitors_tip', 'show_monitors_toolbar'),
|
||||||
otherRow('Show remote cursor', 'show_remote_cursor'),
|
otherRow('Show remote cursor', 'show_remote_cursor'),
|
||||||
otherRow('Zoom cursor', 'zoom-cursor'),
|
otherRow('Zoom cursor', 'zoom-cursor'),
|
||||||
|
@ -139,8 +139,9 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
_ffi.ffiModel.updateEventListener(widget.id);
|
_ffi.ffiModel.updateEventListener(widget.id);
|
||||||
_ffi.qualityMonitorModel.checkShowQualityMonitor(widget.id);
|
_ffi.qualityMonitorModel.checkShowQualityMonitor(widget.id);
|
||||||
// Session option should be set after models.dart/FFI.start
|
// Session option should be set after models.dart/FFI.start
|
||||||
_showRemoteCursor.value = bind.sessionGetToggleOptionSync(
|
// _showRemoteCursor has been set by setViewOnly
|
||||||
id: widget.id, arg: 'show-remote-cursor');
|
_ffi.ffiModel.setViewOnly(widget.id,
|
||||||
|
bind.sessionGetToggleOptionSync(id: widget.id, arg: 'view-only'));
|
||||||
_zoomCursor.value =
|
_zoomCursor.value =
|
||||||
bind.sessionGetToggleOptionSync(id: widget.id, arg: 'zoom-cursor');
|
bind.sessionGetToggleOptionSync(id: widget.id, arg: 'zoom-cursor');
|
||||||
DesktopMultiWindow.addListener(this);
|
DesktopMultiWindow.addListener(this);
|
||||||
|
@ -385,6 +385,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildToolbar(BuildContext context) {
|
Widget _buildToolbar(BuildContext context) {
|
||||||
|
final ffiModel = Provider.of<FfiModel>(context);
|
||||||
final List<Widget> toolbarItems = [];
|
final List<Widget> toolbarItems = [];
|
||||||
if (!isWebDesktop) {
|
if (!isWebDesktop) {
|
||||||
toolbarItems.add(_PinMenu(state: widget.state));
|
toolbarItems.add(_PinMenu(state: widget.state));
|
||||||
@ -410,7 +411,9 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
|||||||
state: widget.state,
|
state: widget.state,
|
||||||
setFullscreen: _setFullscreen,
|
setFullscreen: _setFullscreen,
|
||||||
));
|
));
|
||||||
toolbarItems.add(_KeyboardMenu(id: widget.id, ffi: widget.ffi));
|
if (!ffiModel.viewOnly) {
|
||||||
|
toolbarItems.add(_KeyboardMenu(id: widget.id, ffi: widget.ffi));
|
||||||
|
}
|
||||||
if (!isWeb) {
|
if (!isWeb) {
|
||||||
toolbarItems.add(_ChatMenu(id: widget.id, ffi: widget.ffi));
|
toolbarItems.add(_ChatMenu(id: widget.id, ffi: widget.ffi));
|
||||||
toolbarItems.add(_VoiceCallMenu(id: widget.id, ffi: widget.ffi));
|
toolbarItems.add(_VoiceCallMenu(id: widget.id, ffi: widget.ffi));
|
||||||
@ -820,8 +823,10 @@ class _ControlMenu extends StatelessWidget {
|
|||||||
|
|
||||||
ctrlAltDel() {
|
ctrlAltDel() {
|
||||||
final perms = ffi.ffiModel.permissions;
|
final perms = ffi.ffiModel.permissions;
|
||||||
|
final viewOnly = ffi.ffiModel.viewOnly;
|
||||||
final pi = ffi.ffiModel.pi;
|
final pi = ffi.ffiModel.pi;
|
||||||
final visible = perms['keyboard'] != false &&
|
final visible = !viewOnly &&
|
||||||
|
perms['keyboard'] != false &&
|
||||||
(pi.platform == kPeerPlatformLinux || pi.sasEnabled);
|
(pi.platform == kPeerPlatformLinux || pi.sasEnabled);
|
||||||
if (!visible) return Offstage();
|
if (!visible) return Offstage();
|
||||||
return _MenuItemButton(
|
return _MenuItemButton(
|
||||||
@ -846,7 +851,8 @@ class _ControlMenu extends StatelessWidget {
|
|||||||
|
|
||||||
insertLock() {
|
insertLock() {
|
||||||
final perms = ffi.ffiModel.permissions;
|
final perms = ffi.ffiModel.permissions;
|
||||||
final visible = perms['keyboard'] != false;
|
final viewOnly = ffi.ffiModel.viewOnly;
|
||||||
|
final visible = !viewOnly && perms['keyboard'] != false;
|
||||||
if (!visible) return Offstage();
|
if (!visible) return Offstage();
|
||||||
return _MenuItemButton(
|
return _MenuItemButton(
|
||||||
child: Text(translate('Insert Lock')),
|
child: Text(translate('Insert Lock')),
|
||||||
@ -963,6 +969,7 @@ class _DisplayMenuState extends State<_DisplayMenu> {
|
|||||||
codec(),
|
codec(),
|
||||||
resolutions(),
|
resolutions(),
|
||||||
Divider(),
|
Divider(),
|
||||||
|
view_only(),
|
||||||
showRemoteCursor(),
|
showRemoteCursor(),
|
||||||
zoomCursor(),
|
zoomCursor(),
|
||||||
showQualityMonitor(),
|
showQualityMonitor(),
|
||||||
@ -1456,11 +1463,28 @@ class _DisplayMenuState extends State<_DisplayMenu> {
|
|||||||
child: Text(translate("Resolution")));
|
child: Text(translate("Resolution")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
view_only() {
|
||||||
|
final visible = version_cmp(pi.version, '1.2.0') >= 0;
|
||||||
|
if (!visible) return Offstage();
|
||||||
|
final ffiModel = widget.ffi.ffiModel;
|
||||||
|
return _CheckboxMenuButton(
|
||||||
|
value: ffiModel.viewOnly,
|
||||||
|
onChanged: (value) async {
|
||||||
|
if (value == null) return;
|
||||||
|
bind.sessionSetViewOnly(id: widget.id, viewOnly: value);
|
||||||
|
ffiModel.setViewOnly(widget.id, value);
|
||||||
|
},
|
||||||
|
ffi: widget.ffi,
|
||||||
|
child: Text(translate('View Mode')));
|
||||||
|
}
|
||||||
|
|
||||||
showRemoteCursor() {
|
showRemoteCursor() {
|
||||||
if (widget.ffi.ffiModel.pi.platform == kPeerPlatformAndroid) {
|
if (widget.ffi.ffiModel.pi.platform == kPeerPlatformAndroid) {
|
||||||
return Offstage();
|
return Offstage();
|
||||||
}
|
}
|
||||||
final visible = !widget.ffi.canvasModel.cursorEmbedded;
|
final ffiModel = widget.ffi.ffiModel;
|
||||||
|
final visible =
|
||||||
|
!ffiModel.viewOnly && !widget.ffi.canvasModel.cursorEmbedded;
|
||||||
if (!visible) return Offstage();
|
if (!visible) return Offstage();
|
||||||
final state = ShowRemoteCursorState.find(widget.id);
|
final state = ShowRemoteCursorState.find(widget.id);
|
||||||
final option = 'show-remote-cursor';
|
final option = 'show-remote-cursor';
|
||||||
@ -1543,7 +1567,10 @@ class _DisplayMenuState extends State<_DisplayMenu> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
disableClipboard() {
|
disableClipboard() {
|
||||||
final visible = perms['keyboard'] != false && perms['clipboard'] != false;
|
final ffiModel = widget.ffi.ffiModel;
|
||||||
|
final visible = perms['keyboard'] != false &&
|
||||||
|
perms['clipboard'] != false &&
|
||||||
|
!ffiModel.viewOnly;
|
||||||
if (!visible) return Offstage();
|
if (!visible) return Offstage();
|
||||||
final option = 'disable-clipboard';
|
final option = 'disable-clipboard';
|
||||||
final value = bind.sessionGetToggleOptionSync(id: widget.id, arg: option);
|
final value = bind.sessionGetToggleOptionSync(id: widget.id, arg: option);
|
||||||
|
@ -47,6 +47,7 @@ class FfiModel with ChangeNotifier {
|
|||||||
bool _touchMode = false;
|
bool _touchMode = false;
|
||||||
Timer? _timer;
|
Timer? _timer;
|
||||||
var _reconnects = 1;
|
var _reconnects = 1;
|
||||||
|
bool _viewOnly = false;
|
||||||
WeakReference<FFI> parent;
|
WeakReference<FFI> parent;
|
||||||
|
|
||||||
Map<String, bool> get permissions => _permissions;
|
Map<String, bool> get permissions => _permissions;
|
||||||
@ -65,6 +66,8 @@ class FfiModel with ChangeNotifier {
|
|||||||
|
|
||||||
bool get isPeerAndroid => _pi.platform == kPeerPlatformAndroid;
|
bool get isPeerAndroid => _pi.platform == kPeerPlatformAndroid;
|
||||||
|
|
||||||
|
bool get viewOnly => _viewOnly;
|
||||||
|
|
||||||
set inputBlocked(v) {
|
set inputBlocked(v) {
|
||||||
_inputBlocked = v;
|
_inputBlocked = v;
|
||||||
}
|
}
|
||||||
@ -373,7 +376,8 @@ class FfiModel with ChangeNotifier {
|
|||||||
_updateSessionWidthHeight(String id) {
|
_updateSessionWidthHeight(String id) {
|
||||||
parent.target?.canvasModel.updateViewStyle();
|
parent.target?.canvasModel.updateViewStyle();
|
||||||
if (display.width <= 0 || display.height <= 0) {
|
if (display.width <= 0 || display.height <= 0) {
|
||||||
debugPrintStack(label: 'invalid display size (${display.width},${display.height})');
|
debugPrintStack(
|
||||||
|
label: 'invalid display size (${display.width},${display.height})');
|
||||||
} else {
|
} else {
|
||||||
bind.sessionSetSize(id: id, width: display.width, height: display.height);
|
bind.sessionSetSize(id: id, width: display.width, height: display.height);
|
||||||
}
|
}
|
||||||
@ -516,6 +520,19 @@ class FfiModel with ChangeNotifier {
|
|||||||
//
|
//
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setViewOnly(String id, bool value) {
|
||||||
|
if (value) {
|
||||||
|
ShowRemoteCursorState.find(id).value = value;
|
||||||
|
} else {
|
||||||
|
ShowRemoteCursorState.find(id).value =
|
||||||
|
bind.sessionGetToggleOptionSync(id: id, arg: 'show-remote-cursor');
|
||||||
|
}
|
||||||
|
if (_viewOnly != value) {
|
||||||
|
_viewOnly = value;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ImageModel with ChangeNotifier {
|
class ImageModel with ChangeNotifier {
|
||||||
|
@ -487,6 +487,7 @@ message OptionMessage {
|
|||||||
BoolOption enable_file_transfer = 9;
|
BoolOption enable_file_transfer = 9;
|
||||||
VideoCodecState video_codec_state = 10;
|
VideoCodecState video_codec_state = 10;
|
||||||
int32 custom_fps = 11;
|
int32 custom_fps = 11;
|
||||||
|
BoolOption disable_keyboard = 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
message TestDelay {
|
message TestDelay {
|
||||||
|
@ -1061,6 +1061,10 @@ impl PeerConfig {
|
|||||||
if !mp.contains_key(key) {
|
if !mp.contains_key(key) {
|
||||||
mp.insert(key.to_owned(), UserDefaultConfig::read().get(key));
|
mp.insert(key.to_owned(), UserDefaultConfig::read().get(key));
|
||||||
}
|
}
|
||||||
|
key = "view-only";
|
||||||
|
if !mp.contains_key(key) {
|
||||||
|
mp.insert(key.to_owned(), UserDefaultConfig::read().get(key));
|
||||||
|
}
|
||||||
Ok(mp)
|
Ok(mp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1296,7 +1296,12 @@ impl LoginConfigHandler {
|
|||||||
if let Some(custom_fps) = self.options.get("custom-fps") {
|
if let Some(custom_fps) = self.options.get("custom-fps") {
|
||||||
msg.custom_fps = custom_fps.parse().unwrap_or(30);
|
msg.custom_fps = custom_fps.parse().unwrap_or(30);
|
||||||
}
|
}
|
||||||
if self.get_toggle_option("show-remote-cursor") {
|
let view_only = self.get_toggle_option("view-only");
|
||||||
|
if view_only {
|
||||||
|
msg.disable_keyboard = BoolOption::Yes.into();
|
||||||
|
n += 1;
|
||||||
|
}
|
||||||
|
if view_only || self.get_toggle_option("show-remote-cursor") {
|
||||||
msg.show_remote_cursor = BoolOption::Yes.into();
|
msg.show_remote_cursor = BoolOption::Yes.into();
|
||||||
n += 1;
|
n += 1;
|
||||||
}
|
}
|
||||||
@ -1312,7 +1317,7 @@ impl LoginConfigHandler {
|
|||||||
msg.enable_file_transfer = BoolOption::Yes.into();
|
msg.enable_file_transfer = BoolOption::Yes.into();
|
||||||
n += 1;
|
n += 1;
|
||||||
}
|
}
|
||||||
if self.get_toggle_option("disable-clipboard") {
|
if view_only || self.get_toggle_option("disable-clipboard") {
|
||||||
msg.disable_clipboard = BoolOption::Yes.into();
|
msg.disable_clipboard = BoolOption::Yes.into();
|
||||||
n += 1;
|
n += 1;
|
||||||
}
|
}
|
||||||
|
@ -543,6 +543,12 @@ pub fn session_set_size(_id: String, _width: i32, _height: i32) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn session_set_view_only(id: String, view_only: bool) {
|
||||||
|
if let Some(session) = SESSIONS.read().unwrap().get(&id) {
|
||||||
|
session.set_view_only(view_only);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn main_get_sound_inputs() -> Vec<String> {
|
pub fn main_get_sound_inputs() -> Vec<String> {
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
return get_sound_inputs();
|
return get_sound_inputs();
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", "此文件与对方的一致"),
|
("identical_file_tip", "此文件与对方的一致"),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", "浏览模式"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", "Mig"),
|
("Me", "Mig"),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", "Ich"),
|
("Me", "Ich"),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", "Yo"),
|
("Me", "Yo"),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", "من"),
|
("Me", "من"),
|
||||||
("identical_file_tip", "این فایل با فایل همتا یکسان است."),
|
("identical_file_tip", "این فایل با فایل همتا یکسان است."),
|
||||||
("show_monitors_tip", "نمایش مانیتورها در نوار ابزار"),
|
("show_monitors_tip", "نمایش مانیتورها در نوار ابزار"),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", "Io"),
|
("Me", "Io"),
|
||||||
("identical_file_tip", "Questo file è identico a quello del peer."),
|
("identical_file_tip", "Questo file è identico a quello del peer."),
|
||||||
("show_monitors_tip", "Mostra schermi nella barra degli strumenti"),
|
("show_monitors_tip", "Mostra schermi nella barra degli strumenti"),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", "瀏覽模式"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -479,5 +479,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Me", ""),
|
("Me", ""),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", ""),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", ""),
|
||||||
|
("View Mode", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -103,6 +103,9 @@ pub struct Connection {
|
|||||||
show_remote_cursor: bool,
|
show_remote_cursor: bool,
|
||||||
// by peer
|
// by peer
|
||||||
ip: String,
|
ip: String,
|
||||||
|
// by peer
|
||||||
|
disable_keyboard: bool,
|
||||||
|
// by peer
|
||||||
disable_clipboard: bool,
|
disable_clipboard: bool,
|
||||||
// by peer
|
// by peer
|
||||||
disable_audio: bool,
|
disable_audio: bool,
|
||||||
@ -219,6 +222,7 @@ impl Connection {
|
|||||||
disable_audio: false,
|
disable_audio: false,
|
||||||
enable_file_transfer: false,
|
enable_file_transfer: false,
|
||||||
disable_clipboard: false,
|
disable_clipboard: false,
|
||||||
|
disable_keyboard: false,
|
||||||
tx_input,
|
tx_input,
|
||||||
video_ack_required: false,
|
video_ack_required: false,
|
||||||
peer_info: Default::default(),
|
peer_info: Default::default(),
|
||||||
@ -327,7 +331,7 @@ impl Connection {
|
|||||||
if let Some(s) = conn.server.upgrade() {
|
if let Some(s) = conn.server.upgrade() {
|
||||||
s.write().unwrap().subscribe(
|
s.write().unwrap().subscribe(
|
||||||
super::clipboard_service::NAME,
|
super::clipboard_service::NAME,
|
||||||
conn.inner.clone(), conn.clipboard_enabled() && conn.keyboard);
|
conn.inner.clone(), conn.clipboard_enabled() && conn.peer_keyboard_enabled());
|
||||||
}
|
}
|
||||||
} else if &name == "audio" {
|
} else if &name == "audio" {
|
||||||
conn.audio = enabled;
|
conn.audio = enabled;
|
||||||
@ -939,13 +943,13 @@ impl Connection {
|
|||||||
} else if sub_service {
|
} else if sub_service {
|
||||||
if let Some(s) = self.server.upgrade() {
|
if let Some(s) = self.server.upgrade() {
|
||||||
let mut noperms = Vec::new();
|
let mut noperms = Vec::new();
|
||||||
if !self.keyboard && !self.show_remote_cursor {
|
if !self.peer_keyboard_enabled() && !self.show_remote_cursor {
|
||||||
noperms.push(NAME_CURSOR);
|
noperms.push(NAME_CURSOR);
|
||||||
}
|
}
|
||||||
if !self.show_remote_cursor {
|
if !self.show_remote_cursor {
|
||||||
noperms.push(NAME_POS);
|
noperms.push(NAME_POS);
|
||||||
}
|
}
|
||||||
if !self.clipboard_enabled() || !self.keyboard {
|
if !self.clipboard_enabled() || !self.peer_keyboard_enabled() {
|
||||||
noperms.push(super::clipboard_service::NAME);
|
noperms.push(super::clipboard_service::NAME);
|
||||||
}
|
}
|
||||||
if !self.audio_enabled() {
|
if !self.audio_enabled() {
|
||||||
@ -959,6 +963,10 @@ impl Connection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn peer_keyboard_enabled(&self) -> bool {
|
||||||
|
self.keyboard && !self.disable_keyboard
|
||||||
|
}
|
||||||
|
|
||||||
fn clipboard_enabled(&self) -> bool {
|
fn clipboard_enabled(&self) -> bool {
|
||||||
self.clipboard && !self.disable_clipboard
|
self.clipboard && !self.disable_clipboard
|
||||||
}
|
}
|
||||||
@ -1312,7 +1320,7 @@ impl Connection {
|
|||||||
log::debug!("call_main_service_mouse_input fail:{}", e);
|
log::debug!("call_main_service_mouse_input fail:{}", e);
|
||||||
}
|
}
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
if self.keyboard {
|
if self.peer_keyboard_enabled() {
|
||||||
if is_left_up(&me) {
|
if is_left_up(&me) {
|
||||||
CLICK_TIME.store(get_time(), Ordering::SeqCst);
|
CLICK_TIME.store(get_time(), Ordering::SeqCst);
|
||||||
} else {
|
} else {
|
||||||
@ -1323,7 +1331,7 @@ impl Connection {
|
|||||||
}
|
}
|
||||||
Some(message::Union::KeyEvent(me)) => {
|
Some(message::Union::KeyEvent(me)) => {
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
if self.keyboard {
|
if self.peer_keyboard_enabled() {
|
||||||
if is_enter(&me) {
|
if is_enter(&me) {
|
||||||
CLICK_TIME.store(get_time(), Ordering::SeqCst);
|
CLICK_TIME.store(get_time(), Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
@ -1750,7 +1758,7 @@ impl Connection {
|
|||||||
s.write().unwrap().subscribe(
|
s.write().unwrap().subscribe(
|
||||||
NAME_CURSOR,
|
NAME_CURSOR,
|
||||||
self.inner.clone(),
|
self.inner.clone(),
|
||||||
self.keyboard || self.show_remote_cursor,
|
self.peer_keyboard_enabled() || self.show_remote_cursor,
|
||||||
);
|
);
|
||||||
s.write().unwrap().subscribe(
|
s.write().unwrap().subscribe(
|
||||||
NAME_POS,
|
NAME_POS,
|
||||||
@ -1788,7 +1796,24 @@ impl Connection {
|
|||||||
s.write().unwrap().subscribe(
|
s.write().unwrap().subscribe(
|
||||||
super::clipboard_service::NAME,
|
super::clipboard_service::NAME,
|
||||||
self.inner.clone(),
|
self.inner.clone(),
|
||||||
self.clipboard_enabled() && self.keyboard,
|
self.clipboard_enabled() && self.peer_keyboard_enabled(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Ok(q) = o.disable_keyboard.enum_value() {
|
||||||
|
if q != BoolOption::NotSet {
|
||||||
|
self.disable_keyboard = q == BoolOption::Yes;
|
||||||
|
if let Some(s) = self.server.upgrade() {
|
||||||
|
s.write().unwrap().subscribe(
|
||||||
|
super::clipboard_service::NAME,
|
||||||
|
self.inner.clone(),
|
||||||
|
self.clipboard_enabled() && self.peer_keyboard_enabled(),
|
||||||
|
);
|
||||||
|
s.write().unwrap().subscribe(
|
||||||
|
NAME_CURSOR,
|
||||||
|
self.inner.clone(),
|
||||||
|
self.peer_keyboard_enabled() || self.show_remote_cursor,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ use std::time::{Duration, SystemTime};
|
|||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
use hbb_common::message_proto::option_message::BoolOption;
|
||||||
use rdev::{Event, EventType::*};
|
use rdev::{Event, EventType::*};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
@ -374,7 +375,6 @@ impl<T: InvokeUiSession> Session<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn swab_modifier_key(&self, msg: &mut KeyEvent) {
|
pub fn swab_modifier_key(&self, msg: &mut KeyEvent) {
|
||||||
|
|
||||||
let allow_swap_key = self.get_toggle_option("allow_swap_key".to_string());
|
let allow_swap_key = self.get_toggle_option("allow_swap_key".to_string());
|
||||||
if allow_swap_key {
|
if allow_swap_key {
|
||||||
if let Some(key_event::Union::ControlKey(ck)) = msg.union {
|
if let Some(key_event::Union::ControlKey(ck)) = msg.union {
|
||||||
@ -388,19 +388,22 @@ impl<T: InvokeUiSession> Session<T> {
|
|||||||
};
|
};
|
||||||
msg.set_control_key(ck);
|
msg.set_control_key(ck);
|
||||||
}
|
}
|
||||||
msg.modifiers = msg.modifiers.iter().map(|ck| {
|
msg.modifiers = msg
|
||||||
let ck = ck.enum_value_or_default();
|
.modifiers
|
||||||
let ck = match ck {
|
.iter()
|
||||||
ControlKey::Control => ControlKey::Meta,
|
.map(|ck| {
|
||||||
ControlKey::Meta => ControlKey::Control,
|
let ck = ck.enum_value_or_default();
|
||||||
ControlKey::RControl => ControlKey::Meta,
|
let ck = match ck {
|
||||||
ControlKey::RWin => ControlKey::Control,
|
ControlKey::Control => ControlKey::Meta,
|
||||||
_ => ck,
|
ControlKey::Meta => ControlKey::Control,
|
||||||
};
|
ControlKey::RControl => ControlKey::Meta,
|
||||||
hbb_common::protobuf::EnumOrUnknown::new(ck)
|
ControlKey::RWin => ControlKey::Control,
|
||||||
}).collect();
|
_ => ck,
|
||||||
|
};
|
||||||
|
hbb_common::protobuf::EnumOrUnknown::new(ck)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
let code = msg.chr();
|
let code = msg.chr();
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
let mut peer = self.peer_platform().to_lowercase();
|
let mut peer = self.peer_platform().to_lowercase();
|
||||||
@ -444,7 +447,6 @@ impl<T: InvokeUiSession> Session<T> {
|
|||||||
msg.set_chr(key);
|
msg.set_chr(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_key_event(&self, evt: &KeyEvent) {
|
pub fn send_key_event(&self, evt: &KeyEvent) {
|
||||||
@ -841,6 +843,37 @@ impl<T: InvokeUiSession> Session<T> {
|
|||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_view_only(&self, view_only: bool) {
|
||||||
|
let mut option = OptionMessage::default();
|
||||||
|
let f = |b: bool| {
|
||||||
|
if b {
|
||||||
|
BoolOption::Yes.into()
|
||||||
|
} else {
|
||||||
|
BoolOption::No.into()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if view_only {
|
||||||
|
option.disable_keyboard = f(true);
|
||||||
|
option.disable_clipboard = f(true);
|
||||||
|
option.show_remote_cursor = f(true);
|
||||||
|
} else {
|
||||||
|
option.disable_keyboard = f(false);
|
||||||
|
option.disable_clipboard = f(self.get_toggle_option("disable-clipboard".to_string()));
|
||||||
|
option.show_remote_cursor = f(self.get_toggle_option("show-remote-cursor".to_string()));
|
||||||
|
}
|
||||||
|
let mut misc = Misc::new();
|
||||||
|
misc.set_option(option);
|
||||||
|
let mut msg = Message::new();
|
||||||
|
msg.set_misc(misc);
|
||||||
|
self.send(Data::Message(msg));
|
||||||
|
if self.get_toggle_option("view-only".to_string()) != view_only {
|
||||||
|
self.lc
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.toggle_option("view-only".to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {
|
pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {
|
||||||
@ -1011,21 +1044,25 @@ impl<T: InvokeUiSession> Interface for Session<T> {
|
|||||||
handle_test_delay(t, peer).await;
|
handle_test_delay(t, peer).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn swap_modifier_mouse(&self, msg : &mut hbb_common::protos::message::MouseEvent) {
|
fn swap_modifier_mouse(&self, msg: &mut hbb_common::protos::message::MouseEvent) {
|
||||||
let allow_swap_key = self.get_toggle_option("allow_swap_key".to_string());
|
let allow_swap_key = self.get_toggle_option("allow_swap_key".to_string());
|
||||||
if allow_swap_key {
|
if allow_swap_key {
|
||||||
msg.modifiers = msg.modifiers.iter().map(|ck| {
|
msg.modifiers = msg
|
||||||
let ck = ck.enum_value_or_default();
|
.modifiers
|
||||||
let ck = match ck {
|
.iter()
|
||||||
ControlKey::Control => ControlKey::Meta,
|
.map(|ck| {
|
||||||
ControlKey::Meta => ControlKey::Control,
|
let ck = ck.enum_value_or_default();
|
||||||
ControlKey::RControl => ControlKey::Meta,
|
let ck = match ck {
|
||||||
ControlKey::RWin => ControlKey::Control,
|
ControlKey::Control => ControlKey::Meta,
|
||||||
_ => ck,
|
ControlKey::Meta => ControlKey::Control,
|
||||||
};
|
ControlKey::RControl => ControlKey::Meta,
|
||||||
hbb_common::protobuf::EnumOrUnknown::new(ck)
|
ControlKey::RWin => ControlKey::Control,
|
||||||
}).collect();
|
_ => ck,
|
||||||
|
};
|
||||||
|
hbb_common::protobuf::EnumOrUnknown::new(ck)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user