mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-05-07 22:58:10 +03:00
Add an opt-in keyboard-shortcut system that triggers session
actions (Send Ctrl+Alt+Del, Toggle Fullscreen, Switch Display,
Screenshot, Switch Tab, etc.) via three-modifier combinations
during a remote session.
Architecture
- Native: src/keyboard/shortcuts.rs intercepts at the encoder
layer (process_event and process_event_with_session), so the
feature is input-source-independent. Bindings persist as a
single JSON blob in LocalConfig.
- Web: matching + keydown intercept live in the separate hand-
written TS client at flutter/web/js/ (gitignored, not in this
repo). flutter/lib/web/bridge.dart::mainInit registers
window.onShortcutTriggered so the JS matcher can dispatch
back into the active session's ShortcutModel; the bridge's
mainReloadKeyboardShortcuts forwards to a JS reloadShortcuts
on settings writes.
- Three-modifier prefix (Ctrl+Alt+Shift; Cmd+Option+Shift on
macOS/iOS) sidesteps the need for a pass-through toggle.
- Flutter native path threads the explicit per-call SessionID
for tab-precise routing; rdev path uses globally-current
session.
UI
- Settings -> General -> Keyboard Shortcuts opens a dedicated
configuration page; desktop and mobile share a body widget.
- Recording dialog with live capture, prefix validation, and a
conflict-replace flow.
- Toolbar menu items display the bound shortcut inline.
- Default bindings (adapted from AnyDesk):
+Del Send Ctrl+Alt+Del
+Enter Toggle Fullscreen
+Left/Right Switch Display Prev/Next
+P Screenshot
+1..9 Switch Session Tab
Other
- AGENTS.md: documented (a) flutter_rust_bridge_codegen needs
a pinned version + Dart bridge wrappers should be hand-
written, and (b) the Web-target split where flutter/web/js/
is the runtime owner on Web rather than wasm-compiled Rust.
- 38 new i18n strings in src/lang/en.rs with Chinese
translations in src/lang/cn.rs.
Refs discussion #1933.
59 lines
2.0 KiB
Dart
59 lines
2.0 KiB
Dart
// flutter/lib/desktop/pages/desktop_keyboard_shortcuts_page.dart
|
|
//
|
|
// Desktop shell for the Keyboard Shortcuts configuration page. Users land
|
|
// here from the General settings tab. The page exposes:
|
|
// * A top-level enable/disable toggle (mirrors the General-tab toggle —
|
|
// same JSON key, same semantics).
|
|
// * A grouped, scrollable list of actions, each with a current binding and
|
|
// edit / clear icons.
|
|
// * An AppBar "Reset to defaults" action with a confirmation dialog.
|
|
//
|
|
// All edits write back to LocalConfig under [kShortcutLocalConfigKey] in the
|
|
// canonical {enabled, bindings:[{action,mods,key}]} shape that the Rust and
|
|
// Web matchers consume.
|
|
//
|
|
// The body — group definitions, JSON I/O, conflict-replace flow,
|
|
// recording-dialog round-trip — lives in
|
|
// `common/widgets/keyboard_shortcuts/page_body.dart` and is shared with the
|
|
// mobile shell at `mobile/pages/mobile_keyboard_shortcuts_page.dart`.
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
|
|
import '../../common.dart';
|
|
import '../../common/widgets/keyboard_shortcuts/page_body.dart';
|
|
|
|
class DesktopKeyboardShortcutsPage extends StatefulWidget {
|
|
const DesktopKeyboardShortcutsPage({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
State<DesktopKeyboardShortcutsPage> createState() =>
|
|
_DesktopKeyboardShortcutsPageState();
|
|
}
|
|
|
|
class _DesktopKeyboardShortcutsPageState
|
|
extends State<DesktopKeyboardShortcutsPage> {
|
|
final GlobalKey<KeyboardShortcutsPageBodyState> _bodyKey = GlobalKey();
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: Text(translate('Keyboard Shortcuts')),
|
|
actions: [
|
|
TextButton.icon(
|
|
onPressed: () =>
|
|
_bodyKey.currentState?.resetToDefaultsWithConfirm(),
|
|
icon: const Icon(Icons.restore),
|
|
label: Text(translate('Reset to defaults')),
|
|
).marginOnly(right: 12),
|
|
],
|
|
),
|
|
body: KeyboardShortcutsPageBody(
|
|
key: _bodyKey,
|
|
compact: true,
|
|
),
|
|
);
|
|
}
|
|
}
|