Skip to content

Commit c274237

Browse files
committed
fix: share title bar bounds between load and resize
The initial bounds in load() spanned the full content width with no inset, while _resizeViews() insets by 1px on non-macOS, so the title bar gapped by a pixel on the first paint until the first resize corrected it. Compute the bounds once in _titleBarBounds() and use it from both so the first paint matches every later resize. Note: AI-assisted (Claude Code). Manually verified: tsc and eslint clean, added a unit test for the macOS and non-macOS rects and confirmed it fails when the inset is removed.
1 parent 380eb7d commit c274237

2 files changed

Lines changed: 53 additions & 12 deletions

File tree

src/main/sessionwindow/sessionwindow.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -170,13 +170,7 @@ export class SessionWindow implements IDisposable {
170170
load() {
171171
const titleBarView = new TitleBarView({ isDarkTheme: this._isDarkTheme });
172172
this._window.contentView.addChildView(titleBarView.view);
173-
const { width: contentWidth } = this._window.getContentBounds();
174-
titleBarView.view.setBounds({
175-
x: 0,
176-
y: 0,
177-
width: contentWidth,
178-
height: titleBarHeight
179-
});
173+
titleBarView.view.setBounds(this._titleBarBounds());
180174

181175
this._window.on('focus', () => {
182176
titleBarView.activate();
@@ -1218,16 +1212,23 @@ export class SessionWindow implements IDisposable {
12181212
}, 300);
12191213
}
12201214

1221-
private _resizeViews() {
1222-
const { width, height } = this._window.getContentBounds();
1223-
// add padding to allow resizing around title bar
1215+
// Title bar bounds, shared by load() and _resizeViews() so the first paint
1216+
// matches every later resize. Non-macOS insets by 1px so the frame stays
1217+
// grabbable for resizing around the title bar.
1218+
private _titleBarBounds(): Electron.Rectangle {
1219+
const { width } = this._window.getContentBounds();
12241220
const padding = process.platform === 'darwin' ? 0 : 1;
1225-
this._titleBarView.view.setBounds({
1221+
return {
12261222
x: padding,
12271223
y: padding,
12281224
width: width - 2 * padding,
12291225
height: titleBarHeight - padding
1230-
});
1226+
};
1227+
}
1228+
1229+
private _resizeViews() {
1230+
const { width, height } = this._window.getContentBounds();
1231+
this._titleBarView.view.setBounds(this._titleBarBounds());
12311232
const contentRect: Electron.Rectangle = {
12321233
x: 0,
12331234
y: titleBarHeight,
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { afterEach, describe, expect, it } from 'vitest';
2+
import { SessionWindow } from '../../src/main/sessionwindow/sessionwindow';
3+
4+
// _titleBarBounds is the single source of truth shared by load() and
5+
// _resizeViews(); if the two ever diverge again the first paint gaps by a pixel
6+
// on non-macOS. Drive it directly without the heavy constructor.
7+
const realPlatform = process.platform;
8+
function setPlatform(p: string): void {
9+
Object.defineProperty(process, 'platform', { value: p, configurable: true });
10+
}
11+
12+
function windowWith(width: number): any {
13+
const win = Object.create(SessionWindow.prototype);
14+
win._window = { getContentBounds: () => ({ width, height: 600 }) };
15+
return win;
16+
}
17+
18+
describe('SessionWindow._titleBarBounds', () => {
19+
afterEach(() => setPlatform(realPlatform));
20+
21+
it('spans the full content width with no inset on macOS', () => {
22+
setPlatform('darwin');
23+
expect(windowWith(800)._titleBarBounds()).toEqual({
24+
x: 0,
25+
y: 0,
26+
width: 800,
27+
height: 29
28+
});
29+
});
30+
31+
it('insets by one pixel on non-macOS so the frame stays grabbable', () => {
32+
setPlatform('linux');
33+
expect(windowWith(800)._titleBarBounds()).toEqual({
34+
x: 1,
35+
y: 1,
36+
width: 798,
37+
height: 28
38+
});
39+
});
40+
});

0 commit comments

Comments
 (0)