@@ -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