{"version":3,"file":"index.cjs","names":["screen","app","path","url","electronScreen","EventEmitter","globalShortcut","path","fs","Tray","BrowserWindow","app"],"sources":["../src/Positioner.ts","../src/util/cleanOptions.ts","../src/util/getWindowPosition.ts","../src/Menubar.ts","../src/index.ts"],"sourcesContent":["import { type BrowserWindow, type Rectangle, screen } from 'electron';\n\n/**\n * Named anchor points for placing the menubar window. The `tray*` values are\n * relative to the tray icon's bounds; the rest are relative to the work area\n * of the display containing the cursor (or the tray, when bounds are given).\n */\nexport type WindowPosition =\n  | 'trayLeft'\n  | 'trayBottomLeft'\n  | 'trayRight'\n  | 'trayBottomRight'\n  | 'trayCenter'\n  | 'trayBottomCenter'\n  | 'topLeft'\n  | 'topRight'\n  | 'bottomLeft'\n  | 'bottomRight'\n  | 'topCenter'\n  | 'bottomCenter'\n  | 'leftCenter'\n  | 'rightCenter'\n  | 'center';\n\n/**\n * Computes `{x, y}` coordinates for placing a {@link BrowserWindow} at a named\n * position, optionally relative to a tray icon's bounds. Ported from\n * `electron-positioner@4.1.0` to drop the unmaintained runtime dependency.\n */\nexport class Positioner {\n  private readonly browserWindow: BrowserWindow;\n\n  constructor(browserWindow: BrowserWindow) {\n    this.browserWindow = browserWindow;\n  }\n\n  calculate(\n    position?: WindowPosition,\n    trayBounds?: Rectangle,\n  ): { x: number; y: number } {\n    if (!position) {\n      throw new TypeError(\n        'Positioner.calculate: a `position` argument is required.',\n      );\n    }\n\n    const screenSize = trayBounds\n      ? screen.getDisplayMatching(trayBounds).workArea\n      : screen.getDisplayNearestPoint(screen.getCursorScreenPoint()).workArea;\n    const [windowWidth, windowHeight] = this.browserWindow.getSize();\n    const trayX = trayBounds?.x ?? Number.NaN;\n    const trayWidth = trayBounds?.width ?? Number.NaN;\n\n    const positions: Record<WindowPosition, { x: number; y: number }> = {\n      trayLeft: {\n        x: Math.floor(trayX),\n        y: screenSize.y,\n      },\n      trayBottomLeft: {\n        x: Math.floor(trayX),\n        y: Math.floor(screenSize.height - (windowHeight - screenSize.y)),\n      },\n      trayRight: {\n        x: Math.floor(trayX - windowWidth + trayWidth),\n        y: screenSize.y,\n      },\n      trayBottomRight: {\n        x: Math.floor(trayX - windowWidth + trayWidth),\n        y: Math.floor(screenSize.height - (windowHeight - screenSize.y)),\n      },\n      trayCenter: {\n        x: Math.floor(trayX - windowWidth / 2 + trayWidth / 2),\n        y: screenSize.y,\n      },\n      trayBottomCenter: {\n        x: Math.floor(trayX - windowWidth / 2 + trayWidth / 2),\n        y: Math.floor(screenSize.height - (windowHeight - screenSize.y)),\n      },\n      topLeft: {\n        x: screenSize.x,\n        y: screenSize.y,\n      },\n      topRight: {\n        x: Math.floor(screenSize.x + (screenSize.width - windowWidth)),\n        y: screenSize.y,\n      },\n      bottomLeft: {\n        x: screenSize.x,\n        y: Math.floor(screenSize.height - (windowHeight - screenSize.y)),\n      },\n      bottomRight: {\n        x: Math.floor(screenSize.x + (screenSize.width - windowWidth)),\n        y: Math.floor(screenSize.height - (windowHeight - screenSize.y)),\n      },\n      topCenter: {\n        x: Math.floor(screenSize.x + (screenSize.width / 2 - windowWidth / 2)),\n        y: screenSize.y,\n      },\n      bottomCenter: {\n        x: Math.floor(screenSize.x + (screenSize.width / 2 - windowWidth / 2)),\n        y: Math.floor(screenSize.height - (windowHeight - screenSize.y)),\n      },\n      leftCenter: {\n        x: screenSize.x,\n        y:\n          screenSize.y +\n          Math.floor(screenSize.height / 2) -\n          Math.floor(windowHeight / 2),\n      },\n      rightCenter: {\n        x: Math.floor(screenSize.x + (screenSize.width - windowWidth)),\n        y:\n          screenSize.y +\n          Math.floor(screenSize.height / 2) -\n          Math.floor(windowHeight / 2),\n      },\n      center: {\n        x: Math.floor(screenSize.x + (screenSize.width / 2 - windowWidth / 2)),\n        y: Math.floor(\n          (screenSize.height + screenSize.y) / 2 - windowHeight / 2,\n        ),\n      },\n    };\n\n    const coords = positions[position];\n\n    // On Windows, a tray-relative position can push the window past the right\n    // edge of the work area. Snap back to `topRight` x in that case so it stays\n    // visible. See https://github.com/jenslind/electron-positioner.\n    if (position.startsWith('tray')) {\n      if (coords.x + windowWidth > screenSize.width + screenSize.x) {\n        return { x: positions.topRight.x, y: coords.y };\n      }\n    }\n\n    return coords;\n  }\n}\n","/**\n * @ignore\n */\n\n/** */\n\nimport path from 'node:path';\nimport url from 'node:url';\n\nimport { app } from 'electron';\n\nimport type { Options } from '../types';\n\nconst DEFAULT_WINDOW_HEIGHT = 400;\nconst DEFAULT_WINDOW_WIDTH = 400;\n\n/**\n * Take as input some options, and return a sanitized version of it.\n *\n * @param opts - The options to clean.\n * @ignore\n */\nexport function cleanOptions(opts?: Partial<Options>): Options {\n  const options: Partial<Options> = { ...opts };\n\n  if (options.activateWithApp === undefined) {\n    options.activateWithApp = true;\n  }\n  if (options.ignoreDoubleClickEvents === undefined) {\n    options.ignoreDoubleClickEvents = true;\n  }\n  if (!options.dir) {\n    options.dir = app.getAppPath();\n  }\n  if (!path.isAbsolute(options.dir)) {\n    options.dir = path.resolve(options.dir);\n  }\n  // Note: options.index can be `false`\n  if (options.index === undefined) {\n    options.index = url.format({\n      pathname: path.join(options.dir, 'index.html'),\n      protocol: 'file:',\n      slashes: true,\n    });\n  }\n  options.loadUrlOptions = options.loadUrlOptions || {};\n\n  options.tooltip = options.tooltip || '';\n\n  // `icon`, `preloadWindow`, `showDockIcon`, `showOnAllWorkspaces`,\n  // `showOnRightClick` don't need any special treatment\n\n  // Now we take care of `browserWindow`\n  if (!options.browserWindow) {\n    options.browserWindow = {};\n  }\n\n  // Set width/height on options to be usable before the window is created\n  options.browserWindow.width =\n    // Note: not using `options.browserWindow.width || DEFAULT_WINDOW_WIDTH` so\n    // that users can put a 0 width\n    options.browserWindow.width !== undefined\n      ? options.browserWindow.width\n      : DEFAULT_WINDOW_WIDTH;\n  options.browserWindow.height =\n    options.browserWindow.height !== undefined\n      ? options.browserWindow.height\n      : DEFAULT_WINDOW_HEIGHT;\n\n  return options as Options;\n}\n","/**\n * Utilities to get taskbar position and consequently menubar's position\n */\n\n/** */\n\nimport { screen as electronScreen, type Rectangle, type Tray } from 'electron';\n\nconst isLinux = process.platform === 'linux';\n\nconst trayToScreenRects = (tray: Tray): [Rectangle, Rectangle] => {\n  // There may be more than one screen, so we need to figure out on which screen our tray icon lives.\n  const { workArea, bounds: screenBounds } = electronScreen.getDisplayMatching(\n    tray.getBounds(),\n  );\n\n  workArea.x -= screenBounds.x;\n  workArea.y -= screenBounds.y;\n\n  return [screenBounds, workArea];\n};\n\ntype TaskbarLocation = 'top' | 'bottom' | 'left' | 'right';\n\n/**\n * Determine taskbard location: \"top\", \"bottom\", \"left\" or \"right\".\n *\n * Only tested on Windows for now, and only used in Windows.\n *\n * @param tray - The Electron Tray instance.\n */\nexport function taskbarLocation(tray: Tray): TaskbarLocation {\n  const [screenBounds, workArea] = trayToScreenRects(tray);\n\n  // TASKBAR LEFT\n  if (workArea.x > 0) {\n    // Most likely Ubuntu hence assuming the window should be on top\n    if (isLinux && workArea.y > 0) return 'top';\n    // The workspace starts more on the right\n    return 'left';\n  }\n\n  // TASKBAR TOP\n  if (workArea.y > 0) {\n    return 'top';\n  }\n\n  // TASKBAR RIGHT\n  // Here both workArea.y and workArea.x are 0 so we can no longer leverage them.\n  // We can use the workarea and display width though.\n  // Determine taskbar location\n  if (workArea.width < screenBounds.width) {\n    // The taskbar is either on the left or right, but since the LEFT case was handled above,\n    // we can be sure we're dealing with a right taskbar\n    return 'right';\n  }\n\n  // TASKBAR BOTTOM\n  // Since all the other cases were handled, we can be sure we're dealing with a bottom taskbar\n  return 'bottom';\n}\n\ntype WindowPosition =\n  | 'trayCenter'\n  | 'topRight'\n  | 'trayBottomCenter'\n  | 'leftCenter'\n  | 'bottomRight';\n\n/**\n * Depending on where the taskbar is, determine where the window should be\n * positioned.\n *\n * @param tray - The Electron Tray instance.\n */\nexport function getWindowPosition(tray: Tray): WindowPosition {\n  switch (process.platform) {\n    // macOS\n    // Supports top taskbars\n    case 'darwin':\n      return 'trayCenter';\n    // Linux\n    // Windows\n    // Supports top/bottom/left/right taskbar\n    case 'linux':\n    case 'win32': {\n      const traySide = taskbarLocation(tray);\n\n      // Assign position for menubar\n      if (traySide === 'top') {\n        return isLinux ? 'topRight' : 'trayCenter';\n      }\n      if (traySide === 'bottom') {\n        return 'bottomRight';\n      }\n      if (traySide === 'left') {\n        // Vertically centered against the left edge of the work area.\n        // `bottomLeft` would put the window in the screen's bottom-left\n        // corner — visually disconnected from the tray icon, which sits\n        // somewhere on the left strip. Tray-anchored y isn't available\n        // through `Positioner` for side taskbars, so center is the best\n        // compromise that stays close to the tray.\n        return 'leftCenter';\n      }\n      if (traySide === 'right') {\n        return 'bottomRight';\n      }\n    }\n  }\n\n  // When we really don't know, we just show the menubar on the top-right\n  return 'topRight';\n}\n","import { EventEmitter } from 'node:events';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport {\n  autoUpdater,\n  BrowserWindow,\n  globalShortcut,\n  type Menu,\n  Tray,\n} from 'electron';\n\nimport { Positioner } from './Positioner';\nimport type { Options } from './types';\nimport { cleanOptions } from './util/cleanOptions';\nimport { getWindowPosition } from './util/getWindowPosition';\n\n/**\n * Grace period after `showWindow()` during which a `blur` on the popup is\n * treated as the spurious Windows post-show blur and ignored instead of\n * triggering the auto-hide. See the `blur` handler in {@link Menubar.createWindow}.\n */\nconst BLUR_HIDE_GRACE_MS = 400;\n\n/**\n * Delay before re-asserting the hidden dock after startup. macOS can silently\n * drop an `app.dock.hide()` that races the app's launch activation\n * transition, leaving the dock icon stuck for the whole session. See the\n * re-check in {@link Menubar.appReady}.\n */\nconst DOCK_REHIDE_DELAY_MS = 2_000;\n\n/**\n * The main Menubar class.\n */\nexport class Menubar extends EventEmitter {\n  private _app: Electron.App;\n  private _browserWindow?: BrowserWindow;\n  private _contextMenu?: Menu;\n  private _blurTimeout: NodeJS.Timeout | null = null; // track blur events with timeout\n  private _isDestroyed: boolean;\n  private _isQuitting: boolean; // set when the app is shutting down, used by hideOnClose\n  private _isVisible: boolean; // track visibility\n  private _cachedBounds?: Electron.Rectangle; // _cachedBounds are needed for double-clicked event\n  private _options: Options;\n  private _positioner: Positioner | undefined;\n  private _shortcut?: Electron.Accelerator;\n  private _rightClickContextMenuBound = false;\n  private _warnedNoPositioning = false; // guards the one-time Wayland warning\n  private _lastShowTime = 0; // timestamp of last show(), debounces the post-show blur on Windows\n  private _dockRehideTimeout?: NodeJS.Timeout; // pending post-startup dock re-hide check\n  private _repositioning = false; // guards against re-entrant positionWindow calls\n  private _tray?: Tray;\n\n  constructor(app: Electron.App, options?: Partial<Options>) {\n    super();\n    this._app = app;\n    this._options = cleanOptions(options);\n    this._isDestroyed = false;\n    this._isQuitting = false;\n    this._isVisible = false;\n\n    app.on('before-quit', this.onBeforeQuit);\n    autoUpdater.on('before-quit-for-update', this.onBeforeQuit);\n\n    if (app.isReady()) {\n      // See https://github.com/maxogden/menubar/pull/151\n      process.nextTick(this.onAppReady);\n    } else {\n      app.on('ready', this.onAppReady);\n    }\n  }\n\n  /**\n   * The Electron [App](https://electronjs.org/docs/api/app)\n   * instance.\n   */\n  get app(): Electron.App {\n    return this._app;\n  }\n\n  /**\n   * The {@link Positioner} instance used to compute where the menubar window\n   * should appear on screen. Available after the `after-create-window` event.\n   */\n  get positioner(): Positioner {\n    if (!this._positioner) {\n      throw new Error(\n        'Please access `this.positioner` after the `after-create-window` event has fired.',\n      );\n    }\n\n    return this._positioner;\n  }\n\n  /**\n   * The Electron [Tray](https://electronjs.org/docs/api/tray) instance.\n   */\n  get tray(): Tray {\n    if (!this._tray) {\n      throw new Error(\n        'Please access `this.tray` after the `ready` event has fired.',\n      );\n    }\n\n    return this._tray;\n  }\n\n  /**\n   * The Electron [BrowserWindow](https://electronjs.org/docs/api/browser-window)\n   * instance, if it's present.\n   */\n  get window(): BrowserWindow | undefined {\n    return this._browserWindow;\n  }\n\n  /**\n   * Tear down the menubar instance: destroy the window, remove the tray, and\n   * detach all listeners. Subsequent clicks on the tray will be no-ops until a\n   * new {@link Menubar} instance is created.\n   */\n  destroy(): void {\n    if (this.isDestroyed()) {\n      return;\n    }\n    // Set first so `hideOnClose` lets the close go through instead of\n    // intercepting it.\n    this._isDestroyed = true;\n\n    if (this._shortcut) {\n      globalShortcut.unregister(this._shortcut);\n      this._shortcut = undefined;\n    }\n\n    if (this._dockRehideTimeout) {\n      clearTimeout(this._dockRehideTimeout);\n      this._dockRehideTimeout = undefined;\n    }\n\n    if (this._browserWindow) {\n      this._browserWindow.destroy();\n      this._browserWindow = undefined;\n    }\n\n    if (this._tray) {\n      // Ensure all potential listeners are removed.\n      for (const event of ['click', 'right-click', 'double-click']) {\n        this._tray.removeListener(\n          event as Parameters<Tray['on']>[0],\n          this.clicked,\n        );\n      }\n      this._tray.setToolTip('');\n      this._tray = undefined;\n    }\n\n    this._app.removeListener('ready', this.onAppReady);\n    this._app.removeListener('activate', this.onAppActivate);\n    this._app.removeListener('before-quit', this.onBeforeQuit);\n    autoUpdater.removeListener('before-quit-for-update', this.onBeforeQuit);\n  }\n\n  /**\n   * Whether {@link destroy} has been called on this menubar instance.\n   */\n  isDestroyed(): boolean {\n    return this._isDestroyed;\n  }\n\n  /**\n   * Retrieve a menubar option.\n   *\n   * @param key - The option key to retrieve, see {@link Options}.\n   */\n  getOption<K extends keyof Options>(key: K): Options[K] {\n    return this._options[key];\n  }\n\n  /**\n   * Hide the menubar window.\n   */\n  hideWindow(): void {\n    if (!this._browserWindow || !this._isVisible) {\n      return;\n    }\n    this.emit('hide');\n    this._browserWindow.hide();\n    this.emit('after-hide');\n    this._isVisible = false;\n    if (this._blurTimeout) {\n      clearTimeout(this._blurTimeout);\n      this._blurTimeout = null;\n    }\n    this.refreshContextMenu();\n  }\n\n  /**\n   * Register a global keyboard accelerator that toggles the menubar window.\n   * Replaces any previously registered shortcut owned by this Menubar.\n   * Pass `undefined` to clear the current shortcut without registering a new\n   * one. Returns whether the registration succeeded.\n   *\n   * @param accelerator - An Electron\n   * [Accelerator](https://electronjs.org/docs/api/accelerator) string, or\n   * `undefined` to clear.\n   */\n  setGlobalShortcut(accelerator: Electron.Accelerator | undefined): boolean {\n    if (this._shortcut) {\n      globalShortcut.unregister(this._shortcut);\n      this._shortcut = undefined;\n    }\n    this._options.globalShortcut = accelerator;\n    if (!accelerator) {\n      return true;\n    }\n    const ok = globalShortcut.register(accelerator, () => this.toggleWindow());\n    if (ok) {\n      this._shortcut = accelerator;\n    }\n    return ok;\n  }\n\n  /**\n   * Toggle the menubar window: hide it if visible, show it otherwise.\n   * Resolves once the window finishes showing or hiding.\n   */\n  async toggleWindow(): Promise<void> {\n    if (this._browserWindow && this._isVisible) {\n      this.hideWindow();\n      return;\n    }\n    await this.showWindow();\n  }\n\n  /**\n   * Re-center the menubar window over the tray icon. Convenience wrapper for\n   * `positioner.move('trayCenter', tray.getBounds())` that's safe to call\n   * after the `after-create-window` event. No-op if the window doesn't\n   * exist yet.\n   */\n  recenterOnTray(): void {\n    if (!this._browserWindow || !this._tray) {\n      return;\n    }\n    const bounds = this._tray.getBounds();\n    const { x, y } = this.positioner.calculate('trayCenter', bounds);\n    this._browserWindow.setPosition(Math.round(x), Math.round(y));\n  }\n\n  /**\n   * Replace the tray context menu after construction. On Linux this also\n   * re-publishes the menu to the SNI host, which is required after mutating\n   * items in-place since libappindicator caches the previous serialization.\n   * On macOS/Windows the right-click popup handler reads the current menu\n   * reference, so swapping or clearing here takes effect immediately.\n   *\n   * @param menu - The new menu, or `null` to clear it.\n   */\n  setContextMenu(menu: Menu | null): void {\n    this._contextMenu = menu ?? undefined;\n    this._options.contextMenu = menu ?? undefined;\n    if (!this._tray) {\n      return;\n    }\n    if (process.platform === 'linux') {\n      // `setContextMenu(null)` clears the menu on Linux.\n      this._tray.setContextMenu(menu);\n      return;\n    }\n    // macOS / Windows: bind the right-click popup once on first non-empty\n    // assignment. The handler reads `this._contextMenu` at invoke time, so\n    // later swaps and clears take effect without rebinding (and never leak\n    // a stale closure reference).\n    if (menu && !this._rightClickContextMenuBound) {\n      this.bindRightClickContextMenu();\n    }\n  }\n\n  /**\n   * Re-publish the current context menu so in-place mutations of its items\n   * (`visible`, `enabled`, `checked`, `label`) become visible to the user.\n   *\n   * Only Linux needs this: libappindicator / StatusNotifierItem serializes the\n   * menu once and serves that copy until it is set again, so a mutated item\n   * would otherwise keep rendering its old state until the next show or hide.\n   * A no-op on macOS and Windows, where the menu is read at popup time — call\n   * it unconditionally after mutating items.\n   */\n  refreshContextMenu(): void {\n    if (\n      process.platform === 'linux' &&\n      this._contextMenu &&\n      this._tray &&\n      !this._tray.isDestroyed?.()\n    ) {\n      this._tray.setContextMenu(this._contextMenu);\n    }\n  }\n\n  /**\n   * Change an option after menubar is created.\n   *\n   * @param key - The option key to modify, see {@link Options}.\n   * @param value - The value to set.\n   */\n  setOption<K extends keyof Options>(key: K, value: Options[K]): void {\n    this._options[key] = value;\n  }\n\n  /**\n   * Show the menubar window.\n   *\n   * @param trayPos - The bounds to show the window in.\n   */\n  async showWindow(trayPos?: Electron.Rectangle): Promise<void> {\n    if (!this.tray) {\n      throw new Error('Tray should have been instantiated by now');\n    }\n\n    if (!this._browserWindow) {\n      await this.createWindow();\n    }\n\n    // Use guard for TypeScript, to avoid ! everywhere\n    if (!this._browserWindow) {\n      throw new Error('Window has been initialized just above. qed.');\n    }\n\n    this.emit('show');\n\n    // Cache fresh tray bounds (or fall back to existing cache / tray bounds)\n    // so `positionWindow` can reposition without an event payload — for\n    // example when the window resizes via `setSize`.\n    if (trayPos && trayPos.x !== 0) {\n      this._cachedBounds = trayPos;\n    } else if (!this._cachedBounds && this.tray.getBounds) {\n      this._cachedBounds = this.tray.getBounds();\n    }\n\n    this.positionWindow();\n    // Record the show time before `show()` so the blur handler can recognise\n    // and ignore the transient blur Windows fires right after (see below).\n    this._lastShowTime = Date.now();\n    this._browserWindow.show();\n    this._isVisible = true;\n    this.emit('after-show');\n    this.refreshContextMenu();\n  }\n\n  /**\n   * Compute and apply the tray-anchored position of the browser window. Safe\n   * to call any time after `createWindow` has run — invoked from\n   * {@link showWindow} on every show, and from the window's `resize` event so\n   * `setSize` calls reposition the window correctly.\n   */\n  private positionWindow = (): void => {\n    if (!this._browserWindow || !this._tray) {\n      return;\n    }\n\n    // `setPosition` below can make Windows emit `resize` synchronously, which\n    // re-enters this method through the window's `resize` listener. Each pass\n    // nudges the window again, so the recursion never unwinds: the main\n    // process wedges with the event loop blocked and the window grows past\n    // screen size (gitify-app/gitify#3064). Ignore re-entrant calls; the\n    // outermost one already applies the final position.\n    if (this._repositioning) {\n      return;\n    }\n    this._repositioning = true;\n    try {\n      this.applyWindowPosition();\n    } finally {\n      this._repositioning = false;\n    }\n  };\n\n  /**\n   * Compute and apply the tray-anchored position. Always call through\n   * {@link positionWindow}, which guards against re-entrancy.\n   */\n  private applyWindowPosition(): void {\n    if (!this._browserWindow || !this._tray) {\n      return;\n    }\n\n    // 'Windows' taskbar: sync window position each time before positioning.\n    // https://github.com/maxogden/menubar/issues/232\n    if (['win32', 'linux'].includes(process.platform)) {\n      this._options.windowPosition = getWindowPosition(this._tray);\n    }\n\n    const trayPos = this._cachedBounds ?? this._tray.getBounds?.();\n\n    // Default the window to the right if `trayPos` bounds are undefined or null.\n    let noBoundsPosition: Options['windowPosition'];\n    if (\n      (trayPos === undefined || trayPos.x === 0) &&\n      this._options.windowPosition?.startsWith('tray')\n    ) {\n      noBoundsPosition =\n        process.platform === 'win32' ? 'bottomRight' : 'topRight';\n    }\n\n    const position = this.positioner.calculate(\n      this._options.windowPosition || noBoundsPosition,\n      trayPos,\n    ) as { x: number; y: number };\n\n    // Not using `||` because x and y can be zero.\n    const x =\n      this._options.browserWindow.x !== undefined\n        ? this._options.browserWindow.x\n        : position.x;\n    const y =\n      this._options.browserWindow.y !== undefined\n        ? this._options.browserWindow.y\n        : position.y;\n\n    // `.setPosition` crashed on non-integers\n    // https://github.com/maxogden/menubar/issues/233\n    const targetX = Math.round(x);\n    const targetY = Math.round(y);\n    this._browserWindow.setPosition(targetX, targetY);\n\n    // Native Wayland gives an application no way to position its own window:\n    // `setPosition` is a no-op and `getPosition` reads back [0, 0]\n    // (https://github.com/electron/electron/issues/40886). The compositor\n    // decides where the window lands, usually centered, so the popover can't\n    // be anchored to the tray. Detect that the move didn't take and warn once,\n    // pointing at the X11 fallback. Gated on a Wayland session (`WAYLAND_DISPLAY`)\n    // so pure X11 never trips it; the tolerance absorbs the few-pixel offsets\n    // X11 window managers add for decorations, so XWayland (where positioning\n    // works) doesn't trip it either.\n    if (\n      process.platform === 'linux' &&\n      !!process.env.WAYLAND_DISPLAY &&\n      !this._warnedNoPositioning\n    ) {\n      const [actualX, actualY] = this._browserWindow.getPosition();\n      const ignored =\n        Math.abs(actualX - targetX) > 24 || Math.abs(actualY - targetY) > 24;\n      if (ignored) {\n        this._warnedNoPositioning = true;\n        console.warn(\n          '[menubar] The window could not be positioned programmatically, ' +\n            'which is expected on native Wayland where the compositor controls ' +\n            'placement. The popover will not be anchored to the tray icon. Run ' +\n            'with --ozone-platform=x11 to restore tray-relative positioning.',\n        );\n      }\n    }\n  }\n\n  private async appReady(): Promise<void> {\n    if (this.app.dock && !this._options.showDockIcon) {\n      this.app.dock.hide();\n\n      // The hide above can be silently dropped when it races the launch\n      // activation transition. Re-check once startup has settled; guarded on\n      // visibility because `dock.hide()` also deactivates the app, so it must\n      // not run when the dock is already hidden.\n      this._dockRehideTimeout = setTimeout(() => {\n        if (!this._isDestroyed && this.app.dock?.isVisible()) {\n          this.app.dock.hide();\n        }\n      }, DOCK_REHIDE_DELAY_MS);\n    }\n\n    if (this._options.activateWithApp) {\n      this.app.on('activate', this.onAppActivate);\n    }\n\n    let trayImage =\n      this._options.icon || path.join(this._options.dir, 'IconTemplate.png');\n    if (typeof trayImage === 'string' && !fs.existsSync(trayImage)) {\n      trayImage = path.join(__dirname, '..', 'assets', 'IconTemplate.png'); // Default cat icon\n    }\n\n    const trigger =\n      this._options.trigger ??\n      (this._options.showOnRightClick ? 'right-click' : 'click');\n\n    this._tray = this._options.tray || new Tray(trayImage);\n    // Type guards for TS not to complain\n    if (!this.tray) {\n      throw new Error('Tray has been initialized above');\n    }\n    if (trigger !== 'none') {\n      this.tray.on(trigger as Parameters<Tray['on']>[0], this.clicked);\n      this.tray.on('double-click', this.clicked);\n    }\n    // macOS-only: ignore double-click so an accidental second click doesn't\n    // race the blur handler and cause a tray-icon flicker.\n    if (\n      process.platform === 'darwin' &&\n      this._options.ignoreDoubleClickEvents\n    ) {\n      this.tray.setIgnoreDoubleClickEvents(true);\n    }\n    this.tray.setToolTip(this._options.tooltip);\n\n    if (this._options.contextMenu) {\n      this.bindContextMenu(this._options.contextMenu);\n    }\n\n    if (this._options.globalShortcut) {\n      this.setGlobalShortcut(this._options.globalShortcut);\n    }\n\n    if (!this._options.windowPosition) {\n      this._options.windowPosition = getWindowPosition(this.tray);\n    }\n\n    if (this._options.preloadWindow) {\n      await this.createWindow();\n    }\n\n    this.emit('ready');\n  }\n\n  /**\n   * Callback on tray icon click or double-click.\n   *\n   * @param e\n   * @param bounds\n   */\n  private clicked = async (\n    event?: Electron.KeyboardEvent,\n    bounds?: Electron.Rectangle,\n  ): Promise<void> => {\n    if (event && (event.shiftKey || event.ctrlKey || event.metaKey)) {\n      return this.hideWindow();\n    }\n\n    // if blur was invoked clear timeout\n    if (this._blurTimeout) {\n      clearInterval(this._blurTimeout);\n    }\n\n    if (this._browserWindow && this._isVisible) {\n      return this.hideWindow();\n    }\n\n    this._cachedBounds = bounds || this._cachedBounds;\n    await this.showWindow(this._cachedBounds);\n  };\n\n  private onAppActivate = (\n    _event: Electron.Event,\n    hasVisibleWindows: boolean,\n  ): void => {\n    if (!hasVisibleWindows) {\n      this.showWindow().catch(console.error);\n    }\n  };\n\n  /**\n   * Marks the app as shutting down so `hideOnClose` stops intercepting closes.\n   *\n   * Bound to both `app`'s `before-quit` and the auto updater's\n   * `before-quit-for-update`. Installing an update never emits `before-quit`:\n   * Electron closes every window first and only quits once the window list is\n   * empty, so a `hideOnClose` veto there would leave the window open and the\n   * install waiting forever.\n   */\n  private onBeforeQuit = (): void => {\n    this._isQuitting = true;\n  };\n\n  private bindContextMenu(menu: Menu): void {\n    this._contextMenu = menu;\n    if (process.platform === 'linux') {\n      // libappindicator / StatusNotifierItem requires the menu to live on the\n      // tray itself; right-click is handled by the desktop environment.\n      this.tray.setContextMenu(menu);\n      return;\n    }\n    this.bindRightClickContextMenu();\n  }\n\n  private bindRightClickContextMenu(): void {\n    // macOS / Windows: pop up the current menu on right-click so left-click\n    // stays bound to toggling the menubar window. Read `this._contextMenu`\n    // at invoke time so `setContextMenu()` swaps and clears take effect\n    // without rebinding (and without leaking a stale closure reference).\n    this.tray.on('right-click', (_event, bounds) => {\n      const current = this._contextMenu;\n      if (!current) {\n        return;\n      }\n      this.tray.popUpContextMenu(current, { x: bounds.x, y: bounds.y });\n    });\n    this._rightClickContextMenuBound = true;\n  }\n\n  private onAppReady = (): void => {\n    // Guard against `destroy()` being called between construction and the\n    // scheduled `process.nextTick`/`'ready'` firing.\n    if (this._isDestroyed) {\n      return;\n    }\n    this.appReady().catch((err) => console.error('menubar: ', err));\n  };\n\n  private async createWindow(): Promise<void> {\n    this.emit('create-window');\n\n    // We add some default behavior for menubar's browserWindow, to make it\n    // look like a menubar\n    const defaults = {\n      show: false, // Don't show it at first\n      frame: false, // Remove window frame\n    };\n\n    this._browserWindow = new BrowserWindow({\n      ...defaults,\n      ...this._options.browserWindow,\n    });\n\n    this._positioner = new Positioner(this._browserWindow);\n\n    this._browserWindow.on('blur', () => {\n      if (!this._browserWindow) {\n        return;\n      }\n\n      // The window was pinned (e.g. a host \"keep open on blur\" preference);\n      // don't auto-hide, just surface the event for the host app to react to.\n      if (this._browserWindow.isAlwaysOnTop()) {\n        this.emit('focus-lost');\n        return;\n      }\n\n      // Windows foreground-activation race: clicking the tray icon keeps the\n      // shell (explorer.exe) as the foreground process, so `show()` cannot pull\n      // focus to the popup and Windows immediately fires `blur`. Left unguarded,\n      // the hide timer below fires before the first paint and the window never\n      // visibly appears (gitify-app/gitify#3064). Ignore blur events that land\n      // within the grace window right after a show; a genuine click-away\n      // arrives well after it.\n      if (\n        process.platform === 'win32' &&\n        Date.now() - this._lastShowTime < BLUR_HIDE_GRACE_MS\n      ) {\n        return;\n      }\n\n      this._blurTimeout = setTimeout(() => {\n        this.hideWindow();\n      }, 100);\n    });\n\n    if (this._options.showOnAllWorkspaces !== false) {\n      // https://github.com/electron/electron/issues/37832#issuecomment-1497882944\n      this._browserWindow.setVisibleOnAllWorkspaces(true, {\n        // Maps to NSWindowCollectionBehaviorFullScreenAuxiliary, which\n        // Electron clears when the flag is omitted. Without it the popup\n        // cannot appear inside a fullscreen space, so macOS switches to\n        // another space to show it.\n        visibleOnFullScreen: true,\n        skipTransformProcessType: true, // Avoid damaging the original visible state of app.dock\n      });\n    }\n\n    if (this._options.hideOnClose) {\n      this._browserWindow.on('close', (event) => {\n        if (this._isDestroyed || this._isQuitting) {\n          return;\n        }\n        event.preventDefault();\n        // Defer the hide for Wayland: hiding synchronously from the `close`\n        // handler can leave frameless surfaces in a half-closed state.\n        setImmediate(() => this.hideWindow());\n      });\n    }\n\n    if (this._options.escapeToHide) {\n      this._browserWindow.webContents.on(\n        'before-input-event',\n        (_event, input) => {\n          if (input.type === 'keyDown' && input.key === 'Escape') {\n            this.hideWindow();\n          }\n        },\n      );\n    }\n\n    // Use `closed` (not `close`) so consumer `close` listeners can still read\n    // `mb.window` and call `event.preventDefault()` without racing our cleanup.\n    this._browserWindow.on('closed', this.windowClear.bind(this));\n\n    // Re-anchor the window to the tray when its size changes (e.g. via\n    // `mb.window.setSize(...)`), so the window doesn't end up clipped under\n    // the taskbar. https://github.com/maxogden/menubar/issues/349\n    this._browserWindow.on('resize', this.positionWindow);\n\n    this.emit('before-load');\n\n    // If the user explicity set options.index to false, we don't loadURL\n    // https://github.com/maxogden/menubar/issues/255\n    if (this._options.index !== false) {\n      await this._browserWindow.loadURL(\n        this._options.index,\n        this._options.loadUrlOptions,\n      );\n    }\n    this.emit('after-create-window');\n  }\n\n  private windowClear(): void {\n    this._browserWindow = undefined;\n    this.emit('after-close');\n  }\n}\n","/**\n * Entry point of menubar\n * @example\n * ```typescript\n * import { menubar } from 'menubar';\n * ```\n */\n\n/** */\n\nimport { app } from 'electron';\n\nimport { Menubar } from './Menubar';\nimport type { Options } from './types';\n\nexport * from './util/getWindowPosition';\nexport { Menubar };\n\n/**\n * Factory function to create a menubar application\n *\n * @param options - Options for creating a menubar application, see\n * {@link Options}\n */\nexport function menubar(options?: Partial<Options>): Menubar {\n  return new Menubar(app, options);\n}\n"],"mappings":"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"}