From ebb42e0766aaecd2332e9e09b325c918d116de99 Mon Sep 17 00:00:00 2001 From: Haitao Pan Date: Thu, 4 Jun 2026 11:00:31 +0800 Subject: [PATCH] feat: improve webrtc keyboard mapping and add adaptive resolution default --- .../desktop/desktop_input_handler.dart | 30 +++++++++++++++++ lib/features/desktop/desktop_view.dart | 33 ++++++++++++++++--- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/lib/features/desktop/desktop_input_handler.dart b/lib/features/desktop/desktop_input_handler.dart index bf1bbacf..cce5536b 100644 --- a/lib/features/desktop/desktop_input_handler.dart +++ b/lib/features/desktop/desktop_input_handler.dart @@ -97,6 +97,16 @@ String? desktopKeyName(LogicalKeyboardKey key) { if (key == LogicalKeyboardKey.end) return 'End'; if (key == LogicalKeyboardKey.pageUp) return 'Page_Up'; if (key == LogicalKeyboardKey.pageDown) return 'Page_Down'; + + if (key == LogicalKeyboardKey.shiftLeft) return 'Shift_L'; + if (key == LogicalKeyboardKey.shiftRight) return 'Shift_R'; + if (key == LogicalKeyboardKey.controlLeft) return 'Control_L'; + if (key == LogicalKeyboardKey.controlRight) return 'Control_R'; + if (key == LogicalKeyboardKey.altLeft) return 'Alt_L'; + if (key == LogicalKeyboardKey.altRight) return 'Alt_R'; + if (key == LogicalKeyboardKey.metaLeft) return 'Super_L'; + if (key == LogicalKeyboardKey.metaRight) return 'Super_R'; + if (key == LogicalKeyboardKey.capsLock) return 'Caps_Lock'; final label = key.keyLabel; if (label.isEmpty) return null; @@ -123,6 +133,26 @@ const Map _xdotoolPunctuationNames = { '[': 'bracketleft', ']': 'bracketright', '\\': 'backslash', + '!': 'exclam', + '@': 'at', + '#': 'numbersign', + '\$': 'dollar', + '%': 'percent', + '^': 'asciicircum', + '&': 'ampersand', + '*': 'asterisk', + '(': 'parenleft', + ')': 'parenright', + '+': 'plus', + '{': 'braceleft', + '}': 'braceright', + '|': 'bar', + ':': 'colon', + '"': 'quotedbl', + '<': 'less', + '>': 'greater', + '?': 'question', + '~': 'asciitilde', }; Offset? desktopContentPosition( diff --git a/lib/features/desktop/desktop_view.dart b/lib/features/desktop/desktop_view.dart index 8151f21c..d43d8879 100644 --- a/lib/features/desktop/desktop_view.dart +++ b/lib/features/desktop/desktop_view.dart @@ -47,6 +47,7 @@ class _DesktopViewState extends State { ); bool _useGpu = false; + bool _adaptiveResolution = true; bool _showAdvancedOptions = false; bool _showControlPanel = true; String _connectionState = 'disconnected'; @@ -123,8 +124,19 @@ class _DesktopViewState extends State { await _client.disconnect(); } else { final display = _displayController.text.trim(); - final width = int.tryParse(_widthController.text) ?? 1280; - final height = int.tryParse(_heightController.text) ?? 720; + int width = int.tryParse(_widthController.text) ?? 1280; + int height = int.tryParse(_heightController.text) ?? 720; + + if (_adaptiveResolution) { + final viewportSize = _getViewportSize(); + if (viewportSize.width > 0 && viewportSize.height > 0) { + width = (viewportSize.width.toInt() ~/ 2) * 2; + height = (viewportSize.height.toInt() ~/ 2) * 2; + _widthController.text = width.toString(); + _heightController.text = height.toString(); + } + } + final fps = int.tryParse(_fpsController.text) ?? 30; final bitrate = int.tryParse(_bitrateController.text) ?? 2000; _remoteDesktopSize = Size(width.toDouble(), height.toDouble()); @@ -323,12 +335,25 @@ class _DesktopViewState extends State { ), ), ), + // Adaptive Resolution Toggle + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text(appText('自适应分辨率', 'Adaptive Resolution')), + Switch( + value: _adaptiveResolution, + onChanged: _connectionState == 'disconnected' + ? (val) => setState(() => _adaptiveResolution = val) + : null, + ), + ], + ), // Resolution settings SizedBox( width: 90, child: TextField( controller: _widthController, - enabled: _connectionState == 'disconnected', + enabled: _connectionState == 'disconnected' && !_adaptiveResolution, keyboardType: TextInputType.number, decoration: const InputDecoration(labelText: '宽度'), ), @@ -337,7 +362,7 @@ class _DesktopViewState extends State { width: 90, child: TextField( controller: _heightController, - enabled: _connectionState == 'disconnected', + enabled: _connectionState == 'disconnected' && !_adaptiveResolution, keyboardType: TextInputType.number, decoration: const InputDecoration(labelText: '高度'), ),