feat(macos): launch as an agent app so no dock tile is ever created - #3117
Merged
Conversation
Gitify shipped without LSUIElement, so the app started as a regular dock app and relied on electron-menubar's runtime `app.dock.hide()` to transform it into an accessory app. Measured on macOS 26, that leaves a 150-3000ms window where the dock tile genuinely exists, and macOS can silently drop the transform, stranding the icon until the next launch (#3069). Declaring LSUIElement makes the process start as an accessory app, so there is no tile and no transform to lose.
|
This was referenced Jul 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
Follow-up to #3100 after reports that the dock icon was still showing on
v7.1.1, so the startup re-hide added in gitify-app/electron-menubar#123 treated a symptom rather than the cause. This declaresLSUIElementin the macOSInfo.plistso the process is born as an accessory app and no dock tile ever exists.Root cause
Gitify shipped without
LSUIElement, so macOS launched it as a regular dock app. Hiding the icon depended entirely onelectron-menubarcallingapp.dock.hide()atapp.ready, which runsTransformProcessType(kProcessTransformToUIElementApplication)after the tile is already on screen. That transform is asynchronous and can be silently dropped, and when it is, the icon stays for the whole session, which is why a restart was the only fix.Measured on the shipped
v7.1.1build by sampling the activation policy from outside the process (lsappinfo info -only ApplicationType -app Gitify) from launch:v7.1.1(/Applications, as shipped)Foreground@ +128ms →UIElement@ +529msForeground@ +137ms →UIElement@ +3150msForeground@ +119ms →UIElement@ +392msForeground@ +119ms →UIElement@ +272msLSUIElement: trueUIElement@ +110ms, neverForegroundLSUIElement: true, repeat ×3UIElementfrom first sample, neverForegroundForegroundisNSApplicationActivationPolicyRegular, i.e. the dock tile is real and visible. Every unpatched launch passes through it for 150ms-3s; that is the window in which the transform can be lost. WithLSUIElementthe window does not exist.Fix
mac.extendInfo.LSUIElement: trueinelectron-builder.js. One key, macOS only; Windows and Linux packaging is untouched.The
electron-menubarstartup re-hide stays as-is and is still worth having:pnpm devruns againstnode_modules/electron/dist/Electron.app, whoseInfo.plistwe don't control, and other consumers ofshowDockIcon: falsemay not setLSUIElement. It just stops being the only line of defence for packaged builds.The dialog-close re-hides that #3100 added in
updater.ts/first-run.tsare removed here: withLSUIElementthey are dead code on packaged builds (both call sites are packaged-only, the updater skips unpacked apps and the first-run prompt skips dev mode), and the live test below confirms parentless dialogs no longer pull an agent app into the Dock. Their tests go with them.Verification
Packaged this branch (
electron-builder --mac dir --arm64), ad-hoc signed it, and ran it:Contents/Info.plistcontainsLSUIElement = true;CFBundleIdentifier,LSApplicationCategoryTypeand thegitify/gitify-devCFBundleURLTypesare intact.Foreground(UIElement@ +83ms, first sample).main:second-instance→ forward,main:gotTheLock→ quit inmain.log).UIElementfor the whole time it is up (sampled every 500ms for 6s), as does an externalactivate.pnpm checkclean,tsc --noEmitclean, full suite green (1202 tests).No test is added for the fix itself: it is a single build-config literal, and asserting
config.mac.extendInfo.LSUIElement === truein a unit test would only restate it. The behaviour it fixes is only observable in a packaged macOS bundle, which is what the measurements above cover.Closes #3069