fix(agents): terminal fills the panel on maximize
- Mount xterm as an absolute inset-0 fill so it always has an explicit box and fit() measures the real size when the dock expands (was collapsing via the flex/percentage height chain). - Acquire the pty slave as the child's controlling terminal (setsid + TIOCSCTTY) so the kernel delivers SIGWINCH on a browser resize. Previously the initial size was read once but live resizes were dropped, so the pane stayed at its startup size — content never grew with the window.
This commit is contained in:
@@ -219,13 +219,18 @@ export function AgentTerminal({
|
|||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
{/* Sized region + an absolutely-filled xterm mount. The absolute inset-0
|
||||||
|
child always has an explicit box equal to its parent, so `fit()` never
|
||||||
|
measures a stale/percentage-collapsed height — the terminal tracks the
|
||||||
|
panel as it expands. */}
|
||||||
<div
|
<div
|
||||||
ref={containerRef}
|
className={cn("relative", maximized || fill ? "flex-1 min-h-0" : "h-[560px]")}
|
||||||
className={cn(
|
>
|
||||||
maximized || fill ? "flex-1 min-h-0 p-2" : "h-[560px] p-2",
|
<div
|
||||||
compact && "max-sm:p-0",
|
ref={containerRef}
|
||||||
)}
|
className={cn("absolute inset-0 p-2", compact && "max-sm:p-0")}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,20 @@ def _set_winsize(fd: int, rows: int, cols: int) -> None:
|
|||||||
fcntl.ioctl(fd, termios.TIOCSWINSZ, winsize)
|
fcntl.ioctl(fd, termios.TIOCSWINSZ, winsize)
|
||||||
|
|
||||||
|
|
||||||
|
def _acquire_controlling_tty() -> None:
|
||||||
|
"""Child-side setup (preexec), run after the pty slave is dup'd to fd 0/1/2.
|
||||||
|
|
||||||
|
``setsid()`` starts a new session (own process group, so cleanup can
|
||||||
|
``killpg`` the whole tree). ``TIOCSCTTY`` then makes the slave our
|
||||||
|
*controlling terminal* — without it the kernel has no foreground process
|
||||||
|
group to deliver ``SIGWINCH`` to, so a later winsize change (a browser resize)
|
||||||
|
is silently dropped and the app never reflows. This is what makes live resize
|
||||||
|
work, not just the initial size.
|
||||||
|
"""
|
||||||
|
os.setsid()
|
||||||
|
fcntl.ioctl(0, termios.TIOCSCTTY, 0)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class PtySession:
|
class PtySession:
|
||||||
"""A child process attached to a pty master.
|
"""A child process attached to a pty master.
|
||||||
@@ -77,7 +91,9 @@ class PtySession:
|
|||||||
stderr=slave_fd,
|
stderr=slave_fd,
|
||||||
cwd=str(cwd) if cwd else None,
|
cwd=str(cwd) if cwd else None,
|
||||||
env=proc_env,
|
env=proc_env,
|
||||||
start_new_session=True, # own session/group → controlling tty + killpg
|
# setsid + TIOCSCTTY in the child: own session/group (for killpg) AND
|
||||||
|
# the slave as controlling tty (for SIGWINCH resize delivery).
|
||||||
|
preexec_fn=_acquire_controlling_tty,
|
||||||
close_fds=True,
|
close_fds=True,
|
||||||
)
|
)
|
||||||
os.close(slave_fd) # parent keeps only the master
|
os.close(slave_fd) # parent keeps only the master
|
||||||
|
|||||||
Reference in New Issue
Block a user