diff --git a/src/ETTerms/App/AboutView.cs b/src/ETTerms/App/AboutView.cs
index e1fd0a7..4a2ade1 100644
--- a/src/ETTerms/App/AboutView.cs
+++ b/src/ETTerms/App/AboutView.cs
@@ -177,6 +177,11 @@ public sealed class AboutView : UserControl
private static readonly ChangelogEntry[] Changelog =
[
+ new("0.2.2", new DateOnly(2026, 6, 5), "Bugfix — terminal stability",
+ [
+ "Fixed: the terminal no longer freezes after minimizing or switching tabs (notably in PowerShell / Kiro).",
+ "Added: Shift+Enter inserts a newline in the shell, so you can type multi-line commands.",
+ ]),
new("0.2.1", new DateOnly(2026, 6, 4), "AI MCP one-click setup",
[
"New Settings → AI MCP tab: register the Serial MCP server into Claude Code or Kiro with one click.",
diff --git a/src/ETTerms/ETTerms.csproj b/src/ETTerms/ETTerms.csproj
index ed4c1c7..a776bd3 100644
--- a/src/ETTerms/ETTerms.csproj
+++ b/src/ETTerms/ETTerms.csproj
@@ -10,7 +10,7 @@
ETTerms
- 0.2.1
+ 0.2.2
ETTerms
ETTerms Project
diff --git a/src/ETTerms/Terminal/ScreenBuffer.cs b/src/ETTerms/Terminal/ScreenBuffer.cs
index ad1b4ba..5550564 100644
--- a/src/ETTerms/Terminal/ScreenBuffer.cs
+++ b/src/ETTerms/Terminal/ScreenBuffer.cs
@@ -270,20 +270,29 @@ public sealed class ScreenBuffer
{
cols = Math.Max(1, cols); rows = Math.Max(1, rows);
if (cols == Cols && rows == Rows) return;
- var ng = new Cell[rows][];
- for (int r = 0; r < rows; r++)
- {
- ng[r] = new Cell[cols];
- for (int c = 0; c < cols; c++)
- ng[r][c] = (r < Rows && c < Cols) ? _screen[r][c] : BlankDefault();
- }
- _screen = ng;
+ _screen = Reflow(_screen, rows, cols);
+ // alt screen 啟用中也要一併 reflow 保存的主畫面,否則 resize 後 ExitAlt 會還原失敗、
+ // 畫面殘留 TUI 內容。不可把 _mainScreen 丟掉。
+ if (_mainScreen != null) _mainScreen = Reflow(_mainScreen, rows, cols);
Rows = rows; Cols = cols;
_top = 0; _bottom = Rows - 1;
CursorRow = Math.Clamp(CursorRow, 0, Rows - 1);
CursorCol = Math.Clamp(CursorCol, 0, Cols - 1);
_wrapPending = false;
- _mainScreen = null;
- if (AltActive) { /* alt 下 resize:重建 alt 畫面 */ }
+ }
+
+ /// 把字格陣列重排到新尺寸,保留左上重疊區,其餘填預設空白。
+ private Cell[][] Reflow(Cell[][] src, int rows, int cols)
+ {
+ int oldRows = src.Length;
+ var ng = new Cell[rows][];
+ for (int r = 0; r < rows; r++)
+ {
+ ng[r] = new Cell[cols];
+ int oldCols = r < oldRows ? src[r].Length : 0;
+ for (int c = 0; c < cols; c++)
+ ng[r][c] = (c < oldCols) ? src[r][c] : BlankDefault();
+ }
+ return ng;
}
}
diff --git a/src/ETTerms/Terminal/TerminalInput.cs b/src/ETTerms/Terminal/TerminalInput.cs
index 081eeaf..038f21c 100644
--- a/src/ETTerms/Terminal/TerminalInput.cs
+++ b/src/ETTerms/Terminal/TerminalInput.cs
@@ -9,6 +9,11 @@ public static class TerminalInput
{
public static byte[]? Map(KeyEventArgs e, bool appCursor)
{
+ // Enter:一般送 CR(\r) 視為「送出」;Shift+Enter 送 LF(\n),讓 PSReadLine / Kiro 等
+ // 視為「插入換行」以便輸入多行指令,而不是直接送出。
+ if (e.KeyCode == Keys.Enter)
+ return new[] { (byte)(e.Shift ? '\n' : '\r') };
+
string? seq = e.KeyCode switch
{
Keys.Up => appCursor ? "\x1bOA" : "\x1b[A",
@@ -21,7 +26,6 @@ public static class TerminalInput
Keys.Delete => "\x1b[3~",
Keys.PageUp => "\x1b[5~",
Keys.PageDown => "\x1b[6~",
- Keys.Enter => "\r",
Keys.Tab => "\t",
Keys.Escape => "\x1b",
Keys.Back => "\x7f",
diff --git a/src/ETTerms/Terminal/TerminalView.cs b/src/ETTerms/Terminal/TerminalView.cs
index 87c7b64..4ff3759 100644
--- a/src/ETTerms/Terminal/TerminalView.cs
+++ b/src/ETTerms/Terminal/TerminalView.cs
@@ -59,6 +59,13 @@ public sealed class TerminalView : UserControl
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
+
+ // 視窗最小化、或分頁/分割切換的瞬間,ClientSize 會變成 0/極小。此時若把退化尺寸
+ // (會被算成 1×1)送給 PTY,ConPTY 下的全螢幕 TUI(如 Kiro CLI)會誤以為終端機只剩
+ // 1×1 而停止重繪、輸入也像「卡住」。直接忽略這種尺寸,還原後再以正常尺寸重繪即可。
+ if (ClientSize.Width < _cellW || ClientSize.Height < _cellH) return;
+ if (FindForm() is { WindowState: FormWindowState.Minimized }) return;
+
int cols = VisibleCols, rows = VisibleRows;
if (cols == _lastCols && rows == _lastRows) return;
_lastCols = cols; _lastRows = rows;