* fix(terminal): ensure tab close is resilient to session cleanup failures
- Wrap _closeTerminalSessionIfNeeded in isolated try/catch so that
tabController.closeBy always executes even if FFI calls throw
- Add clarifying comment in handleWindowCloseButton for single-tab
audit dialog flow
* fix(terminal): fix session reconnect ID mismatch and tab close race condition
Remap surviving persistent sessions to client-requested terminal IDs on
reconnect, preventing new shell creation when IDs are non-contiguous.
Snapshot peerTabCount before async operations in _closeTab to avoid race
with concurrent _closeAllTabs clearing the tab controller.
Remove debug log statements.
Signed-off-by: fufesou <linlong1266@gmail.com>
---------
Signed-off-by: fufesou <linlong1266@gmail.com>
- Fix new tab not auto-focusing: add FocusNode to TerminalView and
request focus when tab is selected via tab state listener
- Fix NaN error when data arrives before terminal view layout: buffer
output data until terminal view has valid dimensions, flush on first
valid resize callback
Signed-off-by: fufesou <linlong1266@gmail.com>
Terminal tab keys use the format "peerId_terminalId". The previous code
used split('_')[0] or startsWith('$peerId_') to extract the peerId,
which breaks when the peerId itself contains underscores.
This can happen in two scenarios:
- Hostname-based ID: when OPTION_ALLOW_HOSTNAME_AS_ID is enabled, the
peerId is derived from the system hostname, which commonly contains
underscores (e.g. "my_dev_machine").
- Custom ID: the validation regex ^[a-zA-Z][\w-]{5,15}$ allows
underscores since \w matches [a-zA-Z0-9_], so IDs like "my_dev_01"
are valid.
Fix all three parsing sites in terminal_tab_page.dart to use
lastIndexOf('_'), which is safe because terminalId is always a plain
integer with no underscores.