diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index 1bc09f137..3bc450345 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -310,7 +310,7 @@ class _RemotePageState extends State } void leaveView(PointerExitEvent evt) { - if (_ffi.ffiModel.keyboard()) { + if (_ffi.ffiModel.keyboard) { _ffi.inputModel.tryMoveEdgeOnExit(evt.position); } diff --git a/flutter/lib/desktop/widgets/remote_toolbar.dart b/flutter/lib/desktop/widgets/remote_toolbar.dart index 45a1a55bc..0ef8674ef 100644 --- a/flutter/lib/desktop/widgets/remote_toolbar.dart +++ b/flutter/lib/desktop/widgets/remote_toolbar.dart @@ -317,6 +317,9 @@ class _RemoteMenubarState extends State { RxBool get show => widget.state.show; bool get pin => widget.state.pin; + PeerInfo get pi => widget.ffi.ffiModel.pi; + FfiModel get ffiModel => widget.ffi.ffiModel; + @override initState() { super.initState(); @@ -393,8 +396,7 @@ class _RemoteMenubarState extends State { toolbarItems.add(_MobileActionMenu(ffi: widget.ffi)); } - if (PrivacyModeState.find(widget.id).isFalse && - widget.ffi.ffiModel.pi.displays.length > 1) { + if (PrivacyModeState.find(widget.id).isFalse && pi.displays.length > 1) { toolbarItems.add( bind.mainGetUserDefaultOption(key: 'show_monitors_toolbar') == 'Y' ? _MultiMonitorMenu(id: widget.id, ffi: widget.ffi) @@ -819,11 +821,10 @@ class _ControlMenu extends StatelessWidget { } ctrlAltDel() { - final perms = ffi.ffiModel.permissions; final viewOnly = ffi.ffiModel.viewOnly; final pi = ffi.ffiModel.pi; final visible = !viewOnly && - perms['keyboard'] != false && + ffi.ffiModel.keyboard && (pi.platform == kPeerPlatformLinux || pi.sasEnabled); if (!visible) return Offstage(); return _MenuItemButton( @@ -847,9 +848,8 @@ class _ControlMenu extends StatelessWidget { } insertLock() { - final perms = ffi.ffiModel.permissions; final viewOnly = ffi.ffiModel.viewOnly; - final visible = !viewOnly && perms['keyboard'] != false; + final visible = !viewOnly && ffi.ffiModel.keyboard; if (!visible) return Offstage(); return _MenuItemButton( child: Text(translate('Insert Lock')), @@ -858,10 +858,9 @@ class _ControlMenu extends StatelessWidget { } blockUserInput() { - final perms = ffi.ffiModel.permissions; final pi = ffi.ffiModel.pi; final visible = - perms['keyboard'] != false && pi.platform == kPeerPlatformWindows; + ffi.ffiModel.keyboard && pi.platform == kPeerPlatformWindows; if (!visible) return Offstage(); return _MenuItemButton( child: Obx(() => Text(translate( @@ -876,9 +875,8 @@ class _ControlMenu extends StatelessWidget { } switchSides() { - final perms = ffi.ffiModel.permissions; final pi = ffi.ffiModel.pi; - final visible = perms['keyboard'] != false && + final visible = ffi.ffiModel.keyboard && pi.platform != kPeerPlatformAndroid && pi.platform != kPeerPlatformMacOS && version_cmp(pi.version, '1.2.0') >= 0; @@ -948,6 +946,7 @@ class _DisplayMenuState extends State<_DisplayMenu> { Map get perms => widget.ffi.ffiModel.permissions; PeerInfo get pi => widget.ffi.ffiModel.pi; + FfiModel get ffiModel => widget.ffi.ffiModel; @override Widget build(BuildContext context) { @@ -1419,11 +1418,10 @@ class _DisplayMenuState extends State<_DisplayMenu> { } resolutions() { - final resolutions = widget.ffi.ffiModel.pi.resolutions; - final visible = widget.ffi.ffiModel.permissions["keyboard"] != false && - resolutions.length > 1; + final resolutions = pi.resolutions; + final visible = ffiModel.keyboard && resolutions.length > 1; if (!visible) return Offstage(); - final display = widget.ffi.ffiModel.display; + final display = ffiModel.display; final groupValue = "${display.width}x${display.height}"; onChanged(String? value) async { if (value == null) return; @@ -1435,7 +1433,7 @@ class _DisplayMenuState extends State<_DisplayMenu> { await bind.sessionChangeResolution( id: widget.id, width: w, height: h); Future.delayed(Duration(seconds: 3), () async { - final display = widget.ffi.ffiModel.display; + final display = ffiModel.display; if (w == display.width && h == display.height) { if (_isWindowCanBeAdjusted()) { _doAdjustWindow(); @@ -1460,10 +1458,9 @@ class _DisplayMenuState extends State<_DisplayMenu> { } showRemoteCursor() { - if (widget.ffi.ffiModel.pi.platform == kPeerPlatformAndroid) { + if (pi.platform == kPeerPlatformAndroid) { return Offstage(); } - final ffiModel = widget.ffi.ffiModel; final visible = !widget.ffi.canvasModel.cursorEmbedded && !ffiModel.pi.is_wayland; if (!visible) return Offstage(); @@ -1485,7 +1482,7 @@ class _DisplayMenuState extends State<_DisplayMenu> { } zoomCursor() { - if (widget.ffi.ffiModel.pi.platform == kPeerPlatformAndroid) { + if (pi.platform == kPeerPlatformAndroid) { return Offstage(); } final visible = widget.state.viewStyle.value != kRemoteViewStyleOriginal; @@ -1551,8 +1548,7 @@ class _DisplayMenuState extends State<_DisplayMenu> { } disableClipboard() { - final ffiModel = widget.ffi.ffiModel; - final visible = perms['keyboard'] != false && perms['clipboard'] != false; + final visible = ffiModel.keyboard && perms['clipboard'] != false; if (!visible) return Offstage(); final enabled = !ffiModel.viewOnly; final option = 'disable-clipboard'; @@ -1571,8 +1567,7 @@ class _DisplayMenuState extends State<_DisplayMenu> { } lockAfterSessionEnd() { - final visible = perms['keyboard'] != false; - if (!visible) return Offstage(); + if (!ffiModel.keyboard) return Offstage(); final option = 'lock-after-session-end'; final value = bind.sessionGetToggleOptionSync(id: widget.id, arg: option); return _CheckboxMenuButton( @@ -1586,7 +1581,7 @@ class _DisplayMenuState extends State<_DisplayMenu> { } privacyMode() { - bool visible = perms['keyboard'] != false && pi.features.privacyMode; + bool visible = ffiModel.keyboard && pi.features.privacyMode; if (!visible) return Offstage(); final option = 'privacy-mode'; final rxValue = PrivacyModeState.find(widget.id); @@ -1594,7 +1589,7 @@ class _DisplayMenuState extends State<_DisplayMenu> { value: rxValue.value, onChanged: (value) { if (value == null) return; - if (widget.ffi.ffiModel.pi.currentDisplay != 0) { + if (ffiModel.pi.currentDisplay != 0) { msgBox( widget.id, 'custom-nook-nocancel-hasclose', @@ -1611,7 +1606,7 @@ class _DisplayMenuState extends State<_DisplayMenu> { } swapKey() { - final visible = perms['keyboard'] != false && + final visible = ffiModel.keyboard && ((Platform.isMacOS && pi.platform != kPeerPlatformMacOS) || (!Platform.isMacOS && pi.platform == kPeerPlatformMacOS)); if (!visible) return Offstage(); @@ -1642,15 +1637,17 @@ class _KeyboardMenu extends StatelessWidget { @override Widget build(BuildContext context) { var ffiModel = Provider.of(context); - if (ffiModel.permissions['keyboard'] == false) return Offstage(); + if (!ffiModel.keyboard) return Offstage(); + String? modeOnly; if (stateGlobal.grabKeyboard) { if (bind.sessionIsKeyboardModeSupported(id: id, mode: _kKeyMapMode)) { bind.sessionSetKeyboardMode(id: id, value: _kKeyMapMode); + modeOnly = _kKeyMapMode; } else if (bind.sessionIsKeyboardModeSupported( id: id, mode: _kKeyLegacyMode)) { bind.sessionSetKeyboardMode(id: id, value: _kKeyLegacyMode); + modeOnly = _kKeyLegacyMode; } - return Offstage(); } return _IconSubmenuButton( tooltip: 'Keyboard Settings', @@ -1659,14 +1656,14 @@ class _KeyboardMenu extends StatelessWidget { color: _MenubarTheme.blueColor, hoverColor: _MenubarTheme.hoverBlueColor, menuChildren: [ - mode(), + mode(modeOnly), localKeyboardType(), Divider(), view_mode(), ]); } - mode() { + mode(String? modeOnly) { return futureBuilder(future: () async { return await bind.sessionGetKeyboardMode(id: id) ?? _kKeyLegacyMode; }(), hasData: (data) { @@ -1684,22 +1681,28 @@ class _KeyboardMenu extends StatelessWidget { } for (KeyboardModeMenu mode in modes) { - if (bind.sessionIsKeyboardModeSupported(id: id, mode: mode.key)) { - if (pi.is_wayland && mode.key != _kKeyMapMode) { - continue; - } - var text = translate(mode.menu); - if (mode.key == _kKeyTranslateMode) { - text = '$text beta'; - } - list.add(_RadioMenuButton( - child: Text(text), - value: mode.key, - groupValue: groupValue, - onChanged: enabled ? onChanged : null, - ffi: ffi, - )); + if (modeOnly != null && mode.key != modeOnly) { + continue; + } else if (!bind.sessionIsKeyboardModeSupported( + id: id, mode: mode.key)) { + continue; } + + if (pi.is_wayland && mode.key != _kKeyMapMode) { + continue; + } + + var text = translate(mode.menu); + if (mode.key == _kKeyTranslateMode) { + text = '$text beta'; + } + list.add(_RadioMenuButton( + child: Text(text), + value: mode.key, + groupValue: groupValue, + onChanged: enabled ? onChanged : null, + ffi: ffi, + )); } return Column(children: list); }); @@ -1728,8 +1731,7 @@ class _KeyboardMenu extends StatelessWidget { view_mode() { final ffiModel = ffi.ffiModel; - final enabled = version_cmp(pi.version, '1.2.0') >= 0 && - ffiModel.permissions["keyboard"] != false; + final enabled = version_cmp(pi.version, '1.2.0') >= 0 && ffiModel.keyboard; return _CheckboxMenuButton( value: ffiModel.viewOnly, onChanged: enabled diff --git a/flutter/lib/models/input_model.dart b/flutter/lib/models/input_model.dart index 310a3cadb..95f0f2634 100644 --- a/flutter/lib/models/input_model.dart +++ b/flutter/lib/models/input_model.dart @@ -59,6 +59,8 @@ class InputModel { get id => parent.target?.id ?? ""; + bool get keyboardPerm => parent.target!.ffiModel.keyboard; + InputModel(this.parent); KeyEventResult handleRawKeyEvent(FocusNode data, RawKeyEvent e) { @@ -203,7 +205,7 @@ class InputModel { /// [down] indicates the key's state(down or up). /// [press] indicates a click event(down and up). void inputKey(String name, {bool? down, bool? press}) { - if (!parent.target!.ffiModel.keyboard()) return; + if (!keyboardPerm) return; bind.sessionInputKey( id: id, name: name, @@ -286,7 +288,7 @@ class InputModel { /// Send mouse press event. void sendMouse(String type, MouseButtons button) { - if (!parent.target!.ffiModel.keyboard()) return; + if (!keyboardPerm) return; bind.sessionSendMouse( id: id, 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]. void moveMouse(double x, double y) { - if (!parent.target!.ffiModel.keyboard()) return; + if (!keyboardPerm) return; var x2 = x.toInt(); var y2 = y.toInt(); bind.sessionSendMouse( @@ -379,7 +381,7 @@ class InputModel { } void _scheduleFling2(double x, double y, int delay) { - if ((x ==0 && y == 0) || _stopFling) { + if ((x == 0 && y == 0) || _stopFling) { return; } @@ -394,7 +396,7 @@ class InputModel { final dx0 = x * _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 dy = dy0.toInt(); var delay = _flingBaseDelay; @@ -432,7 +434,8 @@ class InputModel { void onPointerPanZoomEnd(PointerPanZoomEndEvent e) { _stopFling = false; _trackpadScrollUnsent = Offset.zero; - _scheduleFling2(_trackpadLastDelta.dx, _trackpadLastDelta.dy, _flingBaseDelay); + _scheduleFling2( + _trackpadLastDelta.dx, _trackpadLastDelta.dy, _flingBaseDelay); _trackpadLastDelta = Offset.zero; } diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 95813097d..06bfeec45 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -93,7 +93,7 @@ class FfiModel with ChangeNotifier { notifyListeners(); } - bool keyboard() => _permissions['keyboard'] != false; + bool get keyboard => _permissions['keyboard'] != false; clear() { _pi = PeerInfo(); @@ -906,7 +906,7 @@ class CanvasModel with ChangeNotifier { } // 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. if (!isDesktop) { parent.target!.cursorModel.moveLocal(x, y); diff --git a/libs/scrap/src/common/hwcodec.rs b/libs/scrap/src/common/hwcodec.rs index 42bf76cb5..e5ede45b1 100644 --- a/libs/scrap/src/common/hwcodec.rs +++ b/libs/scrap/src/common/hwcodec.rs @@ -7,7 +7,7 @@ use hbb_common::{ anyhow::{anyhow, Context}, bytes::Bytes, config::HwCodecConfig, - get_time, lazy_static, log, + lazy_static, log, message_proto::{EncodedVideoFrame, EncodedVideoFrames, Message, VideoFrame}, ResultType, };