diff --git a/lib/pages/flow_editor.dart b/lib/pages/flow_editor.dart index 5f92c12..ca45628 100644 --- a/lib/pages/flow_editor.dart +++ b/lib/pages/flow_editor.dart @@ -253,6 +253,43 @@ outputs: final l = AppLocalizations.of(context)!; final theme = Theme.of(context); + // Cmd+S / Ctrl+S → save, Cmd+Enter / Ctrl+Enter → run. + // We layer the Shortcuts widget at the page root so the + // bindings work whether the editor area has focus or not. + final shortcuts = { + LogicalKeySet(LogicalKeyboardKey.meta, LogicalKeyboardKey.keyS): + const _SaveIntent(), + LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyS): + const _SaveIntent(), + LogicalKeySet(LogicalKeyboardKey.meta, LogicalKeyboardKey.enter): + const _RunIntent(), + LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.enter): + const _RunIntent(), + }; + + return Shortcuts( + shortcuts: shortcuts, + child: Actions( + actions: >{ + _SaveIntent: CallbackAction<_SaveIntent>( + onInvoke: (_) { + if (_activeName != null && !_saving) _save(); + return null; + }, + ), + _RunIntent: CallbackAction<_RunIntent>( + onInvoke: (_) { + if (_activeName != null && !_running) _run(); + return null; + }, + ), + }, + child: Focus(autofocus: true, child: _buildScaffold(l, theme)), + ), + ); + } + + Widget _buildScaffold(AppLocalizations l, ThemeData theme) { return Scaffold( body: Column( crossAxisAlignment: CrossAxisAlignment.stretch, @@ -303,6 +340,14 @@ outputs: } } +class _SaveIntent extends Intent { + const _SaveIntent(); +} + +class _RunIntent extends Intent { + const _RunIntent(); +} + class _FlowFile { final String name; final String path;