Merge pull request #3809 from fufesou/fix/toolbar_keyboard_button

Fix/toolbar keyboard button
This commit is contained in:
RustDesk 2023-03-28 13:31:34 +08:00 committed by GitHub
commit 81bc362b2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 61 additions and 56 deletions

View File

@ -310,7 +310,7 @@ class _RemotePageState extends State<RemotePage>
} }
void leaveView(PointerExitEvent evt) { void leaveView(PointerExitEvent evt) {
if (_ffi.ffiModel.keyboard()) { if (_ffi.ffiModel.keyboard) {
_ffi.inputModel.tryMoveEdgeOnExit(evt.position); _ffi.inputModel.tryMoveEdgeOnExit(evt.position);
} }

View File

@ -317,6 +317,9 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
RxBool get show => widget.state.show; RxBool get show => widget.state.show;
bool get pin => widget.state.pin; bool get pin => widget.state.pin;
PeerInfo get pi => widget.ffi.ffiModel.pi;
FfiModel get ffiModel => widget.ffi.ffiModel;
@override @override
initState() { initState() {
super.initState(); super.initState();
@ -393,8 +396,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
toolbarItems.add(_MobileActionMenu(ffi: widget.ffi)); toolbarItems.add(_MobileActionMenu(ffi: widget.ffi));
} }
if (PrivacyModeState.find(widget.id).isFalse && if (PrivacyModeState.find(widget.id).isFalse && pi.displays.length > 1) {
widget.ffi.ffiModel.pi.displays.length > 1) {
toolbarItems.add( toolbarItems.add(
bind.mainGetUserDefaultOption(key: 'show_monitors_toolbar') == 'Y' bind.mainGetUserDefaultOption(key: 'show_monitors_toolbar') == 'Y'
? _MultiMonitorMenu(id: widget.id, ffi: widget.ffi) ? _MultiMonitorMenu(id: widget.id, ffi: widget.ffi)
@ -819,11 +821,10 @@ class _ControlMenu extends StatelessWidget {
} }
ctrlAltDel() { ctrlAltDel() {
final perms = ffi.ffiModel.permissions;
final viewOnly = ffi.ffiModel.viewOnly; final viewOnly = ffi.ffiModel.viewOnly;
final pi = ffi.ffiModel.pi; final pi = ffi.ffiModel.pi;
final visible = !viewOnly && final visible = !viewOnly &&
perms['keyboard'] != false && ffi.ffiModel.keyboard &&
(pi.platform == kPeerPlatformLinux || pi.sasEnabled); (pi.platform == kPeerPlatformLinux || pi.sasEnabled);
if (!visible) return Offstage(); if (!visible) return Offstage();
return _MenuItemButton( return _MenuItemButton(
@ -847,9 +848,8 @@ class _ControlMenu extends StatelessWidget {
} }
insertLock() { insertLock() {
final perms = ffi.ffiModel.permissions;
final viewOnly = ffi.ffiModel.viewOnly; final viewOnly = ffi.ffiModel.viewOnly;
final visible = !viewOnly && perms['keyboard'] != false; final visible = !viewOnly && ffi.ffiModel.keyboard;
if (!visible) return Offstage(); if (!visible) return Offstage();
return _MenuItemButton( return _MenuItemButton(
child: Text(translate('Insert Lock')), child: Text(translate('Insert Lock')),
@ -858,10 +858,9 @@ class _ControlMenu extends StatelessWidget {
} }
blockUserInput() { blockUserInput() {
final perms = ffi.ffiModel.permissions;
final pi = ffi.ffiModel.pi; final pi = ffi.ffiModel.pi;
final visible = final visible =
perms['keyboard'] != false && pi.platform == kPeerPlatformWindows; ffi.ffiModel.keyboard && pi.platform == kPeerPlatformWindows;
if (!visible) return Offstage(); if (!visible) return Offstage();
return _MenuItemButton( return _MenuItemButton(
child: Obx(() => Text(translate( child: Obx(() => Text(translate(
@ -876,9 +875,8 @@ class _ControlMenu extends StatelessWidget {
} }
switchSides() { switchSides() {
final perms = ffi.ffiModel.permissions;
final pi = ffi.ffiModel.pi; final pi = ffi.ffiModel.pi;
final visible = perms['keyboard'] != false && final visible = ffi.ffiModel.keyboard &&
pi.platform != kPeerPlatformAndroid && pi.platform != kPeerPlatformAndroid &&
pi.platform != kPeerPlatformMacOS && pi.platform != kPeerPlatformMacOS &&
version_cmp(pi.version, '1.2.0') >= 0; version_cmp(pi.version, '1.2.0') >= 0;
@ -948,6 +946,7 @@ class _DisplayMenuState extends State<_DisplayMenu> {
Map<String, bool> get perms => widget.ffi.ffiModel.permissions; Map<String, bool> get perms => widget.ffi.ffiModel.permissions;
PeerInfo get pi => widget.ffi.ffiModel.pi; PeerInfo get pi => widget.ffi.ffiModel.pi;
FfiModel get ffiModel => widget.ffi.ffiModel;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -1419,11 +1418,10 @@ class _DisplayMenuState extends State<_DisplayMenu> {
} }
resolutions() { resolutions() {
final resolutions = widget.ffi.ffiModel.pi.resolutions; final resolutions = pi.resolutions;
final visible = widget.ffi.ffiModel.permissions["keyboard"] != false && final visible = ffiModel.keyboard && resolutions.length > 1;
resolutions.length > 1;
if (!visible) return Offstage(); if (!visible) return Offstage();
final display = widget.ffi.ffiModel.display; final display = ffiModel.display;
final groupValue = "${display.width}x${display.height}"; final groupValue = "${display.width}x${display.height}";
onChanged(String? value) async { onChanged(String? value) async {
if (value == null) return; if (value == null) return;
@ -1435,7 +1433,7 @@ class _DisplayMenuState extends State<_DisplayMenu> {
await bind.sessionChangeResolution( await bind.sessionChangeResolution(
id: widget.id, width: w, height: h); id: widget.id, width: w, height: h);
Future.delayed(Duration(seconds: 3), () async { Future.delayed(Duration(seconds: 3), () async {
final display = widget.ffi.ffiModel.display; final display = ffiModel.display;
if (w == display.width && h == display.height) { if (w == display.width && h == display.height) {
if (_isWindowCanBeAdjusted()) { if (_isWindowCanBeAdjusted()) {
_doAdjustWindow(); _doAdjustWindow();
@ -1460,10 +1458,9 @@ class _DisplayMenuState extends State<_DisplayMenu> {
} }
showRemoteCursor() { showRemoteCursor() {
if (widget.ffi.ffiModel.pi.platform == kPeerPlatformAndroid) { if (pi.platform == kPeerPlatformAndroid) {
return Offstage(); return Offstage();
} }
final ffiModel = widget.ffi.ffiModel;
final visible = final visible =
!widget.ffi.canvasModel.cursorEmbedded && !ffiModel.pi.is_wayland; !widget.ffi.canvasModel.cursorEmbedded && !ffiModel.pi.is_wayland;
if (!visible) return Offstage(); if (!visible) return Offstage();
@ -1485,7 +1482,7 @@ class _DisplayMenuState extends State<_DisplayMenu> {
} }
zoomCursor() { zoomCursor() {
if (widget.ffi.ffiModel.pi.platform == kPeerPlatformAndroid) { if (pi.platform == kPeerPlatformAndroid) {
return Offstage(); return Offstage();
} }
final visible = widget.state.viewStyle.value != kRemoteViewStyleOriginal; final visible = widget.state.viewStyle.value != kRemoteViewStyleOriginal;
@ -1551,8 +1548,7 @@ class _DisplayMenuState extends State<_DisplayMenu> {
} }
disableClipboard() { disableClipboard() {
final ffiModel = widget.ffi.ffiModel; final visible = ffiModel.keyboard && perms['clipboard'] != false;
final visible = perms['keyboard'] != false && perms['clipboard'] != false;
if (!visible) return Offstage(); if (!visible) return Offstage();
final enabled = !ffiModel.viewOnly; final enabled = !ffiModel.viewOnly;
final option = 'disable-clipboard'; final option = 'disable-clipboard';
@ -1571,8 +1567,7 @@ class _DisplayMenuState extends State<_DisplayMenu> {
} }
lockAfterSessionEnd() { lockAfterSessionEnd() {
final visible = perms['keyboard'] != false; if (!ffiModel.keyboard) return Offstage();
if (!visible) return Offstage();
final option = 'lock-after-session-end'; final option = 'lock-after-session-end';
final value = bind.sessionGetToggleOptionSync(id: widget.id, arg: option); final value = bind.sessionGetToggleOptionSync(id: widget.id, arg: option);
return _CheckboxMenuButton( return _CheckboxMenuButton(
@ -1586,7 +1581,7 @@ class _DisplayMenuState extends State<_DisplayMenu> {
} }
privacyMode() { privacyMode() {
bool visible = perms['keyboard'] != false && pi.features.privacyMode; bool visible = ffiModel.keyboard && pi.features.privacyMode;
if (!visible) return Offstage(); if (!visible) return Offstage();
final option = 'privacy-mode'; final option = 'privacy-mode';
final rxValue = PrivacyModeState.find(widget.id); final rxValue = PrivacyModeState.find(widget.id);
@ -1594,7 +1589,7 @@ class _DisplayMenuState extends State<_DisplayMenu> {
value: rxValue.value, value: rxValue.value,
onChanged: (value) { onChanged: (value) {
if (value == null) return; if (value == null) return;
if (widget.ffi.ffiModel.pi.currentDisplay != 0) { if (ffiModel.pi.currentDisplay != 0) {
msgBox( msgBox(
widget.id, widget.id,
'custom-nook-nocancel-hasclose', 'custom-nook-nocancel-hasclose',
@ -1611,7 +1606,7 @@ class _DisplayMenuState extends State<_DisplayMenu> {
} }
swapKey() { swapKey() {
final visible = perms['keyboard'] != false && final visible = ffiModel.keyboard &&
((Platform.isMacOS && pi.platform != kPeerPlatformMacOS) || ((Platform.isMacOS && pi.platform != kPeerPlatformMacOS) ||
(!Platform.isMacOS && pi.platform == kPeerPlatformMacOS)); (!Platform.isMacOS && pi.platform == kPeerPlatformMacOS));
if (!visible) return Offstage(); if (!visible) return Offstage();
@ -1642,15 +1637,17 @@ class _KeyboardMenu extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var ffiModel = Provider.of<FfiModel>(context); var ffiModel = Provider.of<FfiModel>(context);
if (ffiModel.permissions['keyboard'] == false) return Offstage(); if (!ffiModel.keyboard) return Offstage();
String? modeOnly;
if (stateGlobal.grabKeyboard) { if (stateGlobal.grabKeyboard) {
if (bind.sessionIsKeyboardModeSupported(id: id, mode: _kKeyMapMode)) { if (bind.sessionIsKeyboardModeSupported(id: id, mode: _kKeyMapMode)) {
bind.sessionSetKeyboardMode(id: id, value: _kKeyMapMode); bind.sessionSetKeyboardMode(id: id, value: _kKeyMapMode);
modeOnly = _kKeyMapMode;
} else if (bind.sessionIsKeyboardModeSupported( } else if (bind.sessionIsKeyboardModeSupported(
id: id, mode: _kKeyLegacyMode)) { id: id, mode: _kKeyLegacyMode)) {
bind.sessionSetKeyboardMode(id: id, value: _kKeyLegacyMode); bind.sessionSetKeyboardMode(id: id, value: _kKeyLegacyMode);
modeOnly = _kKeyLegacyMode;
} }
return Offstage();
} }
return _IconSubmenuButton( return _IconSubmenuButton(
tooltip: 'Keyboard Settings', tooltip: 'Keyboard Settings',
@ -1659,14 +1656,14 @@ class _KeyboardMenu extends StatelessWidget {
color: _MenubarTheme.blueColor, color: _MenubarTheme.blueColor,
hoverColor: _MenubarTheme.hoverBlueColor, hoverColor: _MenubarTheme.hoverBlueColor,
menuChildren: [ menuChildren: [
mode(), mode(modeOnly),
localKeyboardType(), localKeyboardType(),
Divider(), Divider(),
view_mode(), view_mode(),
]); ]);
} }
mode() { mode(String? modeOnly) {
return futureBuilder(future: () async { return futureBuilder(future: () async {
return await bind.sessionGetKeyboardMode(id: id) ?? _kKeyLegacyMode; return await bind.sessionGetKeyboardMode(id: id) ?? _kKeyLegacyMode;
}(), hasData: (data) { }(), hasData: (data) {
@ -1684,22 +1681,28 @@ class _KeyboardMenu extends StatelessWidget {
} }
for (KeyboardModeMenu mode in modes) { for (KeyboardModeMenu mode in modes) {
if (bind.sessionIsKeyboardModeSupported(id: id, mode: mode.key)) { if (modeOnly != null && mode.key != modeOnly) {
if (pi.is_wayland && mode.key != _kKeyMapMode) { continue;
continue; } else if (!bind.sessionIsKeyboardModeSupported(
} id: id, mode: mode.key)) {
var text = translate(mode.menu); continue;
if (mode.key == _kKeyTranslateMode) {
text = '$text beta';
}
list.add(_RadioMenuButton<String>(
child: Text(text),
value: mode.key,
groupValue: groupValue,
onChanged: enabled ? onChanged : null,
ffi: ffi,
));
} }
if (pi.is_wayland && mode.key != _kKeyMapMode) {
continue;
}
var text = translate(mode.menu);
if (mode.key == _kKeyTranslateMode) {
text = '$text beta';
}
list.add(_RadioMenuButton<String>(
child: Text(text),
value: mode.key,
groupValue: groupValue,
onChanged: enabled ? onChanged : null,
ffi: ffi,
));
} }
return Column(children: list); return Column(children: list);
}); });
@ -1728,8 +1731,7 @@ class _KeyboardMenu extends StatelessWidget {
view_mode() { view_mode() {
final ffiModel = ffi.ffiModel; final ffiModel = ffi.ffiModel;
final enabled = version_cmp(pi.version, '1.2.0') >= 0 && final enabled = version_cmp(pi.version, '1.2.0') >= 0 && ffiModel.keyboard;
ffiModel.permissions["keyboard"] != false;
return _CheckboxMenuButton( return _CheckboxMenuButton(
value: ffiModel.viewOnly, value: ffiModel.viewOnly,
onChanged: enabled onChanged: enabled

View File

@ -59,6 +59,8 @@ class InputModel {
get id => parent.target?.id ?? ""; get id => parent.target?.id ?? "";
bool get keyboardPerm => parent.target!.ffiModel.keyboard;
InputModel(this.parent); InputModel(this.parent);
KeyEventResult handleRawKeyEvent(FocusNode data, RawKeyEvent e) { KeyEventResult handleRawKeyEvent(FocusNode data, RawKeyEvent e) {
@ -203,7 +205,7 @@ class InputModel {
/// [down] indicates the key's state(down or up). /// [down] indicates the key's state(down or up).
/// [press] indicates a click event(down and up). /// [press] indicates a click event(down and up).
void inputKey(String name, {bool? down, bool? press}) { void inputKey(String name, {bool? down, bool? press}) {
if (!parent.target!.ffiModel.keyboard()) return; if (!keyboardPerm) return;
bind.sessionInputKey( bind.sessionInputKey(
id: id, id: id,
name: name, name: name,
@ -286,7 +288,7 @@ class InputModel {
/// Send mouse press event. /// Send mouse press event.
void sendMouse(String type, MouseButtons button) { void sendMouse(String type, MouseButtons button) {
if (!parent.target!.ffiModel.keyboard()) return; if (!keyboardPerm) return;
bind.sessionSendMouse( bind.sessionSendMouse(
id: id, id: id,
msg: json.encode(modify({'type': type, 'buttons': button.value}))); msg: json.encode(modify({'type': type, 'buttons': button.value})));
@ -303,7 +305,7 @@ class InputModel {
/// Send mouse movement event with distance in [x] and [y]. /// Send mouse movement event with distance in [x] and [y].
void moveMouse(double x, double y) { void moveMouse(double x, double y) {
if (!parent.target!.ffiModel.keyboard()) return; if (!keyboardPerm) return;
var x2 = x.toInt(); var x2 = x.toInt();
var y2 = y.toInt(); var y2 = y.toInt();
bind.sessionSendMouse( bind.sessionSendMouse(
@ -379,7 +381,7 @@ class InputModel {
} }
void _scheduleFling2(double x, double y, int delay) { void _scheduleFling2(double x, double y, int delay) {
if ((x ==0 && y == 0) || _stopFling) { if ((x == 0 && y == 0) || _stopFling) {
return; return;
} }
@ -394,7 +396,7 @@ class InputModel {
final dx0 = x * _trackpadSpeed * 2; final dx0 = x * _trackpadSpeed * 2;
final dy0 = y * _trackpadSpeed * 2; final dy0 = y * _trackpadSpeed * 2;
// Try set delta (x,y) and delay. // Try set delta (x,y) and delay.
var dx = dx0.toInt(); var dx = dx0.toInt();
var dy = dy0.toInt(); var dy = dy0.toInt();
var delay = _flingBaseDelay; var delay = _flingBaseDelay;
@ -432,7 +434,8 @@ class InputModel {
void onPointerPanZoomEnd(PointerPanZoomEndEvent e) { void onPointerPanZoomEnd(PointerPanZoomEndEvent e) {
_stopFling = false; _stopFling = false;
_trackpadScrollUnsent = Offset.zero; _trackpadScrollUnsent = Offset.zero;
_scheduleFling2(_trackpadLastDelta.dx, _trackpadLastDelta.dy, _flingBaseDelay); _scheduleFling2(
_trackpadLastDelta.dx, _trackpadLastDelta.dy, _flingBaseDelay);
_trackpadLastDelta = Offset.zero; _trackpadLastDelta = Offset.zero;
} }

View File

@ -93,7 +93,7 @@ class FfiModel with ChangeNotifier {
notifyListeners(); notifyListeners();
} }
bool keyboard() => _permissions['keyboard'] != false; bool get keyboard => _permissions['keyboard'] != false;
clear() { clear() {
_pi = PeerInfo(); _pi = PeerInfo();
@ -906,7 +906,7 @@ class CanvasModel with ChangeNotifier {
} }
// If keyboard is not permitted, do not move cursor when mouse is moving. // If keyboard is not permitted, do not move cursor when mouse is moving.
if (parent.target != null && parent.target!.ffiModel.keyboard()) { if (parent.target != null && parent.target!.ffiModel.keyboard) {
// Draw cursor if is not desktop. // Draw cursor if is not desktop.
if (!isDesktop) { if (!isDesktop) {
parent.target!.cursorModel.moveLocal(x, y); parent.target!.cursorModel.moveLocal(x, y);

View File

@ -7,7 +7,7 @@ use hbb_common::{
anyhow::{anyhow, Context}, anyhow::{anyhow, Context},
bytes::Bytes, bytes::Bytes,
config::HwCodecConfig, config::HwCodecConfig,
get_time, lazy_static, log, lazy_static, log,
message_proto::{EncodedVideoFrame, EncodedVideoFrames, Message, VideoFrame}, message_proto::{EncodedVideoFrame, EncodedVideoFrames, Message, VideoFrame},
ResultType, ResultType,
}; };