From 2f7435f271d1ee4dd34639617510a9a2ef916a2e Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Fri, 1 May 2026 11:40:12 +0200 Subject: [PATCH] debounce terminal resize, add SIGWINCH, remove padding Rapid resize during window drag sends many SIGWINCH signals causing the shell to redraw repeatedly, corrupting xterm's render. Debounce to 150ms so only the final size is sent. NativePty.resize now explicitly sends SIGWINCH (signal 28) after TIOCSWINSZ, matching the legacy Python implementation. Removed 8px padding from ClidePtyView to eliminate potential dimension mismatch between widget size and PTY cols/rows. Default window size increased to 1600x900. Co-Authored-By: Claude Opus 4.6 (1M context) --- .pql/pql-plan.json | 2 +- lib/builtin/claude/src/claude_pane.dart | 14 +++++++++++--- lib/src/pty/native_pty.dart | 4 ++++ lib/widgets/src/clide_pty_view.dart | 2 +- macos/Runner/Base.lproj/MainMenu.xib | 2 +- 5 files changed, 18 insertions(+), 6 deletions(-) diff --git a/.pql/pql-plan.json b/.pql/pql-plan.json index dfc998bc..14e70dd6 100644 --- a/.pql/pql-plan.json +++ b/.pql/pql-plan.json @@ -1,5 +1,5 @@ { - "exported_at": "2026-05-01T07:24:10Z", + "exported_at": "2026-05-01T09:40:12Z", "decisions": [ { "id": "D-1", diff --git a/lib/builtin/claude/src/claude_pane.dart b/lib/builtin/claude/src/claude_pane.dart index 3bf7d8ae..1112e9c4 100644 --- a/lib/builtin/claude/src/claude_pane.dart +++ b/lib/builtin/claude/src/claude_pane.dart @@ -65,6 +65,7 @@ class _ClaudePaneState extends State { @override void dispose() { + _resizeTimer?.cancel(); _eventSub?.cancel(); _eventSub = null; final id = _paneId; @@ -203,6 +204,8 @@ class _ClaudePaneState extends State { _ipc()?.request('pane.write', args: {'id': id, 'text': text}); } + Timer? _resizeTimer; + void _onResize(int cols, int rows, int _, int __) { if (!_spawned) { // First resize — TerminalView has real dimensions now. @@ -210,9 +213,14 @@ class _ClaudePaneState extends State { _spawnWhenReady(); return; } - final id = _paneId; - if (id == null) return; - _ipc()?.request('pane.resize', args: {'id': id, 'cols': cols, 'rows': rows}); + // Debounce resize — rapid SIGWINCH during window drag corrupts + // the terminal rendering. Wait for the resize to settle. + _resizeTimer?.cancel(); + _resizeTimer = Timer(const Duration(milliseconds: 150), () { + final id = _paneId; + if (id == null) return; + _ipc()?.request('pane.resize', args: {'id': id, 'cols': cols, 'rows': rows}); + }); } DaemonClient? _ipc() => _kernel()?.ipc; diff --git a/lib/src/pty/native_pty.dart b/lib/src/pty/native_pty.dart index e03153bb..3effac60 100644 --- a/lib/src/pty/native_pty.dart +++ b/lib/src/pty/native_pty.dart @@ -278,6 +278,10 @@ class NativePty { ..ref.wsCol = cols; _ioctl(_fd, _kTiocsWinsz, ws); calloc.free(ws); + // Explicitly signal the child to re-query its terminal size. + // macOS should auto-send SIGWINCH on TIOCSWINSZ, but the legacy + // Python implementation sent it explicitly for reliability. + _nativeKill(pid, 28); // SIGWINCH = 28 on macOS/Linux } /// Send a signal to the child. diff --git a/lib/widgets/src/clide_pty_view.dart b/lib/widgets/src/clide_pty_view.dart index 0fbc609f..8097bef1 100644 --- a/lib/widgets/src/clide_pty_view.dart +++ b/lib/widgets/src/clide_pty_view.dart @@ -54,7 +54,7 @@ class ClidePtyView extends StatelessWidget { fontFamily: clideMonoFamily, fontFamilyFallback: clideMonoFamilyFallback, ), - padding: const EdgeInsets.all(8), + padding: EdgeInsets.zero, backgroundOpacity: 1, cursorType: TerminalCursorType.block, ), diff --git a/macos/Runner/Base.lproj/MainMenu.xib b/macos/Runner/Base.lproj/MainMenu.xib index 06afcd8e..d8976328 100644 --- a/macos/Runner/Base.lproj/MainMenu.xib +++ b/macos/Runner/Base.lproj/MainMenu.xib @@ -332,7 +332,7 @@ - +