This commit is contained in:
Yotam 2026-07-17 12:16:57 +09:00 committed by GitHub
commit 4e0a52fb40
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 90 additions and 2 deletions

View File

@ -39,8 +39,18 @@
ended: document.getElementById('terminal-ended'),
restart: document.getElementById('terminal-restart'),
restartNow: document.getElementById('terminal-restart-now'),
fontSize: document.getElementById('terminal-fontsize'),
};
// Sidebar text-size selector. sm = 13px is the shipped default (do not change it — it is
// what every existing session renders at); the others step around it. Persisted per user
// in chrome.storage.local and applied to the live xterm.
const FONT_SIZES = { xs: 11, sm: 13, md: 15, lg: 17, xl: 20 };
const FONT_SIZE_DEFAULT = 'sm';
const FONT_SIZE_KEY = 'terminalFontSize';
let fontSizeKey = FONT_SIZE_DEFAULT; // the chosen T-shirt size; px comes from FONT_SIZES
const fontPx = () => FONT_SIZES[fontSizeKey] || FONT_SIZES[FONT_SIZE_DEFAULT];
/** State machine. */
const STATE = {
IDLE: 'idle',
@ -392,7 +402,7 @@
if (term) return;
term = new Terminal({
fontFamily: '"JetBrains Mono", "SF Mono", Menlo, "Noto Sans Mono CJK KR", "Malgun Gothic", monospace',
fontSize: 13,
fontSize: fontPx(), // the persisted size (default 13 = sm); see FONT_SIZES
theme: { background: '#0a0a0a', foreground: '#e5e5e5' },
cursorBlink: true,
scrollback: 5000,
@ -931,6 +941,40 @@
els.restart?.addEventListener('click', forceRestart);
els.restartNow?.addEventListener('click', forceRestart);
// Re-measure the terminal and tell the PTY its new size. Same body the first-fit and the
// ResizeObserver use — a bare fitAddon.fit() is not enough: without the resize message
// claude keeps wrapping to the old cols/rows.
const refitTerminal = () => {
try {
fitAddon && fitAddon.fit();
if (term && ws && ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: 'resize', cols: term.cols, rows: term.rows }));
}
} catch {}
};
// Sidebar text-size selector: restore the saved size, then apply on change. Changing the
// font is asynchronous inside xterm — it re-measures the character cell on the next render
// frame, so fitting in the same tick reads the OLD cell and leaves the grid clipped (the
// bug that made a live change need a close/reopen). Two rAFs let the new metrics land
// before we fit + resize. If the terminal isn't up yet, ensureXterm reads fontPx() at
// creation, so no refit is needed then.
const applyFontSize = (key, persist) => {
fontSizeKey = FONT_SIZES[key] ? key : FONT_SIZE_DEFAULT;
if (els.fontSize) els.fontSize.value = fontSizeKey;
if (term) {
term.options.fontSize = fontPx();
requestAnimationFrame(() => requestAnimationFrame(refitTerminal));
}
if (persist) { try { chrome.storage.local.set({ [FONT_SIZE_KEY]: fontSizeKey }); } catch {} }
};
els.fontSize?.addEventListener('change', (e) => applyFontSize(e.target.value, true));
try {
chrome.storage.local.get([FONT_SIZE_KEY], (r) => applyFontSize(r?.[FONT_SIZE_KEY] || FONT_SIZE_DEFAULT, false));
} catch {
applyFontSize(FONT_SIZE_DEFAULT, false);
}
// Live browser-tab state. background.js → sidepanel.js → us. We
// forward over the live PTY WebSocket; terminal-agent.ts writes

View File

@ -719,6 +719,38 @@ body::after {
color: #f59e0b;
border-color: #f59e0b;
}
/* Right cluster: text-size selector + Restart, kept together on the toolbar's right end. */
.terminal-toolbar-right {
display: flex;
align-items: center;
gap: 6px;
flex-shrink: 0;
}
.terminal-fontsize {
display: flex;
align-items: center;
gap: 3px;
color: #a1a1aa;
}
/* The glyph is a size hint, not decoration — a small 'A' beside the picker. */
.terminal-fontsize-icon {
font-family: 'JetBrains Mono', monospace;
font-size: 13px;
line-height: 1;
}
.terminal-fontsize select {
background: #0a0a0a;
color: #a1a1aa;
border: 1px solid #27272a;
border-radius: 3px;
padding: 3px 4px;
font-size: 11px;
font-family: 'JetBrains Mono', monospace;
cursor: pointer;
color-scheme: dark; /* keep the native option list dark, not a white flash over the panel */
}
.terminal-fontsize select:hover { color: #f59e0b; border-color: #f59e0b; }
.terminal-fontsize select:focus-visible { outline: 2px solid #f59e0b; outline-offset: 1px; }
.terminal-bootstrap {
flex: 1;
display: flex;

View File

@ -40,7 +40,19 @@
<button id="chat-screenshot-btn" class="terminal-toolbar-btn" title="Take a screenshot">📸 Screenshot</button>
<button id="chat-cookies-btn" class="terminal-toolbar-btn" title="Import cookies from your browser">🍪 Cookies</button>
</div>
<button class="terminal-toolbar-btn" id="terminal-restart-now" title="Restart Claude Code session">↻ Restart</button>
<div class="terminal-toolbar-right">
<label class="terminal-fontsize" title="Sidebar text size">
<span class="terminal-fontsize-icon" aria-hidden="true">A</span>
<select id="terminal-fontsize" aria-label="Sidebar text size">
<option value="xs">XS</option>
<option value="sm">SM</option>
<option value="md">MD</option>
<option value="lg">LG</option>
<option value="xl">XL</option>
</select>
</label>
<button class="terminal-toolbar-btn" id="terminal-restart-now" title="Restart Claude Code session">↻ Restart</button>
</div>
</div>
<div class="terminal-bootstrap" id="terminal-bootstrap">
<div class="terminal-bootstrap-icon"></div>