Skip to content

Commit 72f73f0

Browse files
committed
fix: reposition window on resize so setSize doesn't clip under taskbar
Extracts the position calculation out of `showWindow` into a focused, synchronous `positionWindow` arrow field, and hooks it to the browser window's `resize` event. After `mb.window.setSize(...)` the window re-anchors to the tray, fixing the upstream issue where part of the window ended up clipped by the taskbar. `showWindow` now caches the latest tray bounds before calling `positionWindow`, keeping the cache as the single source of truth that the resize handler reads from. Closes the gap from upstream max-mapper#350 by @binvb / max-mapper#349.
1 parent f4a9811 commit 72f73f0

1 file changed

Lines changed: 37 additions & 21 deletions

File tree

src/Menubar.ts

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -176,32 +176,47 @@ export class Menubar extends EventEmitter {
176176
throw new Error('Window has been initialized just above. qed.');
177177
}
178178

179-
// 'Windows' taskbar: sync windows position each time before showing
180-
// https://github.com/maxogden/menubar/issues/232
181-
if (['win32', 'linux'].includes(process.platform)) {
182-
// Fill in this._options.windowPosition when taskbar position is available
183-
this._options.windowPosition = getWindowPosition(this.tray);
184-
}
185-
186179
this.emit('show');
187180

181+
// Cache fresh tray bounds (or fall back to existing cache / tray bounds)
182+
// so `positionWindow` can reposition without an event payload — for
183+
// example when the window resizes via `setSize`.
188184
if (trayPos && trayPos.x !== 0) {
189-
// Cache the bounds
190185
this._cachedBounds = trayPos;
191-
} else if (this._cachedBounds) {
192-
// Cached value will be used if showWindow is called without bounds data
193-
trayPos = this._cachedBounds;
194-
} else if (this.tray.getBounds) {
195-
// Get the current tray bounds
196-
trayPos = this.tray.getBounds();
186+
} else if (!this._cachedBounds && this.tray.getBounds) {
187+
this._cachedBounds = this.tray.getBounds();
188+
}
189+
190+
this.positionWindow();
191+
this._browserWindow.show();
192+
this._isVisible = true;
193+
this.emit('after-show');
194+
}
195+
196+
/**
197+
* Compute and apply the tray-anchored position of the browser window. Safe
198+
* to call any time after `createWindow` has run — invoked from
199+
* {@link showWindow} on every show, and from the window's `resize` event so
200+
* `setSize` calls reposition the window correctly.
201+
*/
202+
private positionWindow = (): void => {
203+
if (!this._browserWindow || !this._tray) {
204+
return;
197205
}
198206

207+
// 'Windows' taskbar: sync window position each time before positioning.
208+
// https://github.com/maxogden/menubar/issues/232
209+
if (['win32', 'linux'].includes(process.platform)) {
210+
this._options.windowPosition = getWindowPosition(this._tray);
211+
}
212+
213+
const trayPos = this._cachedBounds ?? this._tray.getBounds?.();
214+
199215
// Default the window to the right if `trayPos` bounds are undefined or null.
200216
let noBoundsPosition: Options['windowPosition'];
201217
if (
202218
(trayPos === undefined || trayPos.x === 0) &&
203-
this._options.windowPosition &&
204-
this._options.windowPosition.startsWith('tray')
219+
this._options.windowPosition?.startsWith('tray')
205220
) {
206221
noBoundsPosition =
207222
process.platform === 'win32' ? 'bottomRight' : 'topRight';
@@ -225,11 +240,7 @@ export class Menubar extends EventEmitter {
225240
// `.setPosition` crashed on non-integers
226241
// https://github.com/maxogden/menubar/issues/233
227242
this._browserWindow.setPosition(Math.round(x), Math.round(y));
228-
this._browserWindow.show();
229-
this._isVisible = true;
230-
this.emit('after-show');
231-
return;
232-
}
243+
};
233244

234245
private async appReady(): Promise<void> {
235246
if (this.app.dock && !this._options.showDockIcon) {
@@ -356,6 +367,11 @@ export class Menubar extends EventEmitter {
356367

357368
this._browserWindow.on('close', this.windowClear.bind(this));
358369

370+
// Re-anchor the window to the tray when its size changes (e.g. via
371+
// `mb.window.setSize(...)`), so the window doesn't end up clipped under
372+
// the taskbar. https://github.com/maxogden/menubar/issues/349
373+
this._browserWindow.on('resize', this.positionWindow);
374+
359375
this.emit('before-load');
360376

361377
// If the user explicity set options.index to false, we don't loadURL

0 commit comments

Comments
 (0)