From f3a47490532627e0cee329e211f22c380787c499 Mon Sep 17 00:00:00 2001 From: sladro Date: Fri, 10 Apr 2026 20:04:35 +0800 Subject: [PATCH] Freeze backend terminal resize while editing --- .../lib/features/terminal/terminal_page.dart | 1 + .../terminal_session_coordinator.dart | 21 ++++++++- .../terminal_session_coordinator_test.dart | 43 +++++++++++++++++++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/apps/mobile_app/lib/features/terminal/terminal_page.dart b/apps/mobile_app/lib/features/terminal/terminal_page.dart index 38c7e7d..0e1cfc3 100644 --- a/apps/mobile_app/lib/features/terminal/terminal_page.dart +++ b/apps/mobile_app/lib/features/terminal/terminal_page.dart @@ -330,6 +330,7 @@ class _TerminalPageState extends ConsumerState } void _applyInputMode() { + _coordinator.setBackendResizeEnabled(_inputMode != _TerminalInputMode.edit); _terminalFocusNode.canRequestFocus = _inputMode == _TerminalInputMode.edit; if (_inputMode == _TerminalInputMode.edit) { _terminalFocusNode.requestFocus(); diff --git a/apps/mobile_app/lib/features/terminal/terminal_session_coordinator.dart b/apps/mobile_app/lib/features/terminal/terminal_session_coordinator.dart index 99dd211..2a5760e 100644 --- a/apps/mobile_app/lib/features/terminal/terminal_session_coordinator.dart +++ b/apps/mobile_app/lib/features/terminal/terminal_session_coordinator.dart @@ -87,11 +87,23 @@ class TerminalSessionCoordinator extends ChangeNotifier { int? _lastSentColumns; int? _lastSentRows; int? _lastReceivedSequence; + bool _isBackendResizeEnabled = true; bool get isLoadingOlderHistory => _isLoadingOlderHistory; String get connectionStatus => _connectionStatus; + void setBackendResizeEnabled(bool enabled) { + if (_isBackendResizeEnabled == enabled) { + return; + } + + _isBackendResizeEnabled = enabled; + if (enabled) { + _flushPendingResize(); + } + } + Future start({bool isReconnect = false}) async { _cancelPendingReconnect(); _cancelPendingResize(); @@ -521,13 +533,18 @@ class TerminalSessionCoordinator extends ChangeNotifier { final socketSession = _socketSession; final columns = _pendingResizeColumns; final rows = _pendingResizeRows; - _pendingResizeColumns = null; - _pendingResizeRows = null; if (socketSession == null || columns == null || rows == null) { return; } + if (!_isBackendResizeEnabled) { + return; + } + + _pendingResizeColumns = null; + _pendingResizeRows = null; + if (_lastSentColumns == columns && _lastSentRows == rows) { return; } diff --git a/apps/mobile_app/test/features/terminal/terminal_session_coordinator_test.dart b/apps/mobile_app/test/features/terminal/terminal_session_coordinator_test.dart index 58e510a..2bbc051 100644 --- a/apps/mobile_app/test/features/terminal/terminal_session_coordinator_test.dart +++ b/apps/mobile_app/test/features/terminal/terminal_session_coordinator_test.dart @@ -500,6 +500,49 @@ void main() { }, ); + test( + 'edit mode freezes backend resize until read mode resumes', + () async { + final controller = TerminalInteractionController(); + final apiClient = _FakeAgentApiClient(); + final sessionFactory = _FakeTerminalSessionFactory(); + final resizeScheduler = _FakeResizeScheduler(); + final session = Session( + sessionId: 'abc', + name: 'codex-main', + status: 'idle', + ); + final coordinator = TerminalSessionCoordinator( + controller: controller, + apiClient: apiClient, + session: session, + sessionFactory: sessionFactory.create, + onFrame: (_) {}, + onRestore: (_) {}, + viewportProvider: () => const TerminalViewport(columns: 80, rows: 24), + resizeScheduler: resizeScheduler.schedule, + ); + + await coordinator.start(); + final socketSession = sessionFactory.createdSessions.single; + + coordinator.setBackendResizeEnabled(false); + coordinator.handleTerminalResize(98, 26); + resizeScheduler.runPending(); + + expect(socketSession.resizeCalls, const [ + [80, 24], + ]); + + coordinator.setBackendResizeEnabled(true); + + expect(socketSession.resizeCalls, const [ + [80, 24], + [98, 26], + ]); + }, + ); + test( 'frames from a replaced socket session are ignored after reconnect starts', () async {