Skip to content

fix(linux): nativeImage for window icon; hicolor theme for panel/launcher icon#615

Merged
nerdCopter merged 4 commits into
emuflight:masterfrom
nerdCopter:fix/linux-titlebar-icon
Jun 25, 2026
Merged

fix(linux): nativeImage for window icon; hicolor theme for panel/launcher icon#615
nerdCopter merged 4 commits into
emuflight:masterfrom
nerdCopter:fix/linux-titlebar-icon

Conversation

@nerdCopter

@nerdCopter nerdCopter commented Jun 25, 2026

Copy link
Copy Markdown
Member

AI Generated pull-request

Summary

  • main.js — use nativeImage.createFromPath() on Linux for BrowserWindow({ icon }). Passing a raw path string silently fails when the app is asar-packaged: fs.existsSync returns true for virtual asar paths (Electron patches fs), but the OS window manager receives the path string directly and cannot read inside the archive. nativeImage reads the PNG into memory within Electron's asar-aware process and passes the decoded image object instead.
  • forge.config.js + scripts/ — add Debian postinst/prerm scripts that install/remove the icon in /usr/share/icons/hicolor/128x128/apps/. maker-deb installs only to /usr/share/pixmaps/ (legacy GTK fallback); XDG desktop environments (XFCE, GNOME, KDE) resolve Icon=emuflight-configurator via the hicolor theme, so the panel launcher icon was blank without it. All icon operations are guarded with || true so any filesystem or permission failure is non-fatal and never aborts dpkg.

Closes #614
Ref: #609 (comment)

Test plan

  • yarn make:dev produces a .deb without errors
  • sudo dpkg -i installs cleanly; /usr/share/icons/hicolor/128x128/apps/emuflight-configurator.png present after install
  • XFCE panel launcher shows the EmuFlight icon without manual icon selection (verified)
  • GNOME/KDE panel launcher shows the EmuFlight icon (same hicolor mechanism; not verified)
  • sudo dpkg -r emuflight-configurator uninstalls cleanly; hicolor icon removed
  • yarn dev still shows correct taskbar icon on Linux

nerdCopter and others added 3 commits June 25, 2026 13:07
BrowserWindow's icon option requires a real filesystem path on Linux;
the OS window manager cannot read from inside an asar archive. Even
though Electron patches fs.existsSync to return true for asar-internal
paths, the path string passed to the native BrowserWindow constructor is
not resolved by Electron's asar shim, so the window icon silently
disappears in the installed .deb.

Switching to nativeImage.createFromPath() on Linux reads the PNG data
into memory inside the Electron process (which is asar-aware), then
passes the decoded image object to BrowserWindow. This works in both
dev mode (yarn dev) and the packaged app without requiring asarUnpack.

Closes emuflight#614
Ref: emuflight#609 (comment)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
maker-deb installs the app icon only to /usr/share/pixmaps/ (legacy
location). XFCE panel, GNOME, and KDE resolve Icon= names via the XDG
hicolor theme (/usr/share/icons/hicolor/) rather than pixmaps, so the
panel launcher icon shows as blank even though the .desktop file has
the correct Icon=emuflight-configurator entry.

Add Debian postinst/prerm scripts (via electron-installer-debian's
options.scripts) that copy the icon to
/usr/share/icons/hicolor/128x128/apps/ on install and remove it on
uninstall, running gtk-update-icon-cache after each operation.

Fixes: XFCE (and other XDG DE) panel launcher showing no icon.
Related: emuflight#614

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
A failure in postinst/prerm must not abort dpkg installation or removal.
Icon placement is cosmetic — the app functions fully without it.
Add || true to the install and rm commands so any filesystem or
permission error is silently ignored rather than propagating as a
dpkg error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Debian packaging now runs post-install and pre-removal scripts that manage the hicolor icon and refresh the icon cache. The Electron main process now loads the Linux window icon with nativeImage.createFromPath() instead of returning a filesystem path.

Changes

Debian icon packaging and runtime loading

Layer / File(s) Summary
Debian icon hooks
forge.config.js, scripts/deb-postinst.sh, scripts/deb-prerm.sh
Debian maker configuration now runs post-install and pre-removal scripts that copy or remove the icon under hicolor and refresh the icon cache when gtk-update-icon-cache is available.
Linux window icon loading
main.js
main.js imports nativeImage and uses it for the Linux icon candidate in getWindowIconPath(), returning undefined when the loaded image is empty.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the Linux icon fix and Debian icon handling added in this PR.
Linked Issues check ✅ Passed The changes address #614 by using nativeImage for the Linux window icon and Debian icon scripts, matching the stated objective.
Out of Scope Changes check ✅ Passed The Debian lifecycle scripts and forge config changes are directly tied to the Linux icon fixes and do not add unrelated scope.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@main.js`:
- Around line 76-78: The Linux icon selection in the main icon-loading logic
stops too early when NativeImage.createFromPath returns an empty image, so later
fallback candidates are never tried. Update the candidate-scanning flow in the
icon resolution code around nativeImage.createFromPath and the Linux branch so
an empty img is treated like a failed candidate and the loop continues to the
next path instead of returning undefined immediately.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5c59950c-9c35-4500-a403-eab83eff8efe

📥 Commits

Reviewing files that changed from the base of the PR and between 4f47350 and 349dbb5.

📒 Files selected for processing (4)
  • forge.config.js
  • main.js
  • scripts/deb-postinst.sh
  • scripts/deb-prerm.sh
📜 Review details
⏰ Context from checks skipped due to timeout. (6)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: build (macos-26-intel, macos-x86_64)
  • GitHub Check: build (ubuntu-24.04, linux-x64)
  • GitHub Check: build (macos-26, macos-arm64)
  • GitHub Check: build (windows-2022, windows-x64, x64)
  • GitHub Check: build (windows-2022, windows-ia32, ia32)
🔇 Additional comments (3)
forge.config.js (1)

104-110: LGTM!

scripts/deb-postinst.sh (1)

1-13: LGTM!

scripts/deb-prerm.sh (1)

1-9: LGTM!

Comment thread main.js Outdated
If a Linux icon path exists (fs.existsSync) but the file is unreadable
or corrupt, nativeImage.createFromPath() returns an empty NativeImage.
Returning undefined immediately skips all remaining fallback candidates.
Use continue so the loop advances to the next path instead.

Addresses: emuflight#615 (review)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@nerdCopter nerdCopter merged commit 0529e1e into emuflight:master Jun 25, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(linux): app window titlebar icon missing in installed .deb — asar packaging blocks BrowserWindow from reading icon at runtime

1 participant