mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-02-17 14:07:28 +08:00
Fix terminal clear command to remove residual output (#13531)
* Fix terminal clear command to remove residual output * Update flutter/lib/models/terminal_model.dart Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update flutter/lib/desktop/pages/terminal_page.dart Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Fix: Prevent "Build scheduled during frame" in terminal resize --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -41,6 +41,7 @@ class _TerminalPageState extends State<TerminalPage>
|
|||||||
with AutomaticKeepAliveClientMixin {
|
with AutomaticKeepAliveClientMixin {
|
||||||
late FFI _ffi;
|
late FFI _ffi;
|
||||||
late TerminalModel _terminalModel;
|
late TerminalModel _terminalModel;
|
||||||
|
double? _cellHeight;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -60,6 +61,17 @@ class _TerminalPageState extends State<TerminalPage>
|
|||||||
debugPrint(
|
debugPrint(
|
||||||
'[TerminalPage] Terminal model created for terminal ${widget.terminalId}');
|
'[TerminalPage] Terminal model created for terminal ${widget.terminalId}');
|
||||||
|
|
||||||
|
_terminalModel.onResizeExternal = (w, h, pw, ph) {
|
||||||
|
_cellHeight = ph * 1.0;
|
||||||
|
|
||||||
|
// Schedule the setState for the next frame
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Register this terminal model with FFI for event routing
|
// Register this terminal model with FFI for event routing
|
||||||
_ffi.registerTerminalModel(widget.terminalId, _terminalModel);
|
_ffi.registerTerminalModel(widget.terminalId, _terminalModel);
|
||||||
|
|
||||||
@@ -95,30 +107,48 @@ class _TerminalPageState extends State<TerminalPage>
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This method ensures that the number of visible rows is an integer by computing the
|
||||||
|
// extra space left after dividing the available height by the height of a single
|
||||||
|
// terminal row (`_cellHeight`) and distributing it evenly as top and bottom padding.
|
||||||
|
EdgeInsets _calculatePadding(double heightPx) {
|
||||||
|
if (_cellHeight == null) {
|
||||||
|
return const EdgeInsets.symmetric(horizontal: 5.0, vertical: 2.0);
|
||||||
|
}
|
||||||
|
final rows = (heightPx / _cellHeight!).floor();
|
||||||
|
final extraSpace = heightPx - rows * _cellHeight!;
|
||||||
|
final topBottom = extraSpace / 2.0;
|
||||||
|
return EdgeInsets.symmetric(horizontal: 5.0, vertical: topBottom);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
super.build(context);
|
super.build(context);
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||||
body: TerminalView(
|
body: LayoutBuilder(
|
||||||
_terminalModel.terminal,
|
builder: (context, constraints) {
|
||||||
controller: _terminalModel.terminalController,
|
final heightPx = constraints.maxHeight;
|
||||||
autofocus: true,
|
return TerminalView(
|
||||||
backgroundOpacity: 0.7,
|
_terminalModel.terminal,
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 5.0, vertical: 2.0),
|
controller: _terminalModel.terminalController,
|
||||||
onSecondaryTapDown: (details, offset) async {
|
autofocus: true,
|
||||||
final selection = _terminalModel.terminalController.selection;
|
backgroundOpacity: 0.7,
|
||||||
if (selection != null) {
|
padding: _calculatePadding(heightPx),
|
||||||
final text = _terminalModel.terminal.buffer.getText(selection);
|
onSecondaryTapDown: (details, offset) async {
|
||||||
_terminalModel.terminalController.clearSelection();
|
final selection = _terminalModel.terminalController.selection;
|
||||||
await Clipboard.setData(ClipboardData(text: text));
|
if (selection != null) {
|
||||||
} else {
|
final text = _terminalModel.terminal.buffer.getText(selection);
|
||||||
final data = await Clipboard.getData('text/plain');
|
_terminalModel.terminalController.clearSelection();
|
||||||
final text = data?.text;
|
await Clipboard.setData(ClipboardData(text: text));
|
||||||
if (text != null) {
|
} else {
|
||||||
_terminalModel.terminal.paste(text);
|
final data = await Clipboard.getData('text/plain');
|
||||||
}
|
final text = data?.text;
|
||||||
}
|
if (text != null) {
|
||||||
|
_terminalModel.terminal.paste(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ class TerminalModel with ChangeNotifier {
|
|||||||
|
|
||||||
bool get isPeerWindows => parent.ffiModel.pi.platform == kPeerPlatformWindows;
|
bool get isPeerWindows => parent.ffiModel.pi.platform == kPeerPlatformWindows;
|
||||||
|
|
||||||
|
void Function(int w, int h, int pw, int ph)? onResizeExternal;
|
||||||
|
|
||||||
Future<void> _handleInput(String data) async {
|
Future<void> _handleInput(String data) async {
|
||||||
// If we press the `Enter` button on Android,
|
// If we press the `Enter` button on Android,
|
||||||
// `data` can be '\r' or '\n' when using different keyboards.
|
// `data` can be '\r' or '\n' when using different keyboards.
|
||||||
@@ -68,6 +70,10 @@ class TerminalModel with ChangeNotifier {
|
|||||||
if (w > 0 && h > 0 && pw > 0 && ph > 0) {
|
if (w > 0 && h > 0 && pw > 0 && ph > 0) {
|
||||||
debugPrint(
|
debugPrint(
|
||||||
'[TerminalModel] Terminal resized to ${w}x$h (pixel: ${pw}x$ph)');
|
'[TerminalModel] Terminal resized to ${w}x$h (pixel: ${pw}x$ph)');
|
||||||
|
|
||||||
|
// This piece of code must be placed before the conditional check in order to initialize properly.
|
||||||
|
onResizeExternal?.call(w, h, pw, ph);
|
||||||
|
|
||||||
if (_terminalOpened) {
|
if (_terminalOpened) {
|
||||||
// Notify remote terminal of resize
|
// Notify remote terminal of resize
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user