-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Overview
Implement VTE-based terminal panes that attach to tmux sessions, matching the macOS app's TerminalPane.swift + ScrollableTerminalView.swift.
Terminal Attachment Flow
Exactly mirrors macOS — VTE spawns a shell that creates a grouped tmux session:
let cmd = format!(
"if [ -x /usr/libexec/path_helper ]; then eval $(/usr/libexec/path_helper -s); fi; \
[ -f ~/.zprofile ] && source ~/.zprofile; \
[ -f ~/.zshrc ] && source ~/.zshrc; \
tmux set-option -t '{}' status off 2>/dev/null; \
exec tmux new-session -t '{}' -s '{}' \
\; set-option destroy-unattached on \
\; set-option status off \
\; set-option mouse on \
\; select-window -t ':{}'",
tmux_target, session_name, view_session_name, window_index
);
terminal.spawn_async(
vte::PtyFlags::DEFAULT,
Some(&working_dir),
&["/bin/zsh", "-c", &cmd],
&[], SpawnFlags::DEFAULT, -1,
None::<&gio::Cancellable>,
|_| {}
);The -t <session> flag creates a "grouped" session that shares windows with the original ppg session but has independent window selection — this is critical so each terminal view can show a different agent without affecting others.
The view session name format: <session>-view-<agentId>-<4random> with destroy-unattached so it auto-cleans when the terminal closes.
VTE Configuration
- Font: from AppSettings (default "Monospace 13")
- Colors: match theme (dark/light adaptive)
- Background: #1a1b26 (dark), #f8f8f2 (light)
- Foreground: #c0caf5 (dark), #383a42 (light)
- 16-color ANSI palette matching macOS app's
Theme.terminalColors
- Mouse: enabled for tmux interaction
- Scrollback: from AppSettings
history_limit - Allow bold, cursor blink
Scroll Handling
VTE handles mouse scroll natively when tmux's alternate screen is active (for vim/less/etc.), unlike macOS SwiftTerm which needed manual mouse button 4/5 escape sequence forwarding. VTE's built-in scroll should work correctly.
Drag and Drop
Accept file URL drops → shell-escape the path → terminal.feed_child() to send the text.
Lazy Creation
Only create the VTE terminal when the pane is actually visible (similar to macOS viewDidMoveToWindow pattern). Use gtk::Widget::connect_map signal.
Teardown
On pane close: the view session auto-destroys (via destroy-unattached). Call terminal.reset() and drop the widget.
References
- macOS:
PPG CLI/PPG CLI/TerminalPane.swift(tmux attachment) - macOS:
PPG CLI/PPG CLI/ScrollableTerminalView.swift(VT100 rendering, scroll, theme)
Acceptance Criteria
- VTE terminal spawns and attaches to tmux session
- Shows live agent output with correct ANSI colors
- Keyboard input works (types into tmux)
- Mouse scroll works in both normal mode and alternate screen (vim/less)
- Font and colors update from settings
- Terminal tears down cleanly when pane closes
- View session auto-destroys via
destroy-unattached