Back to Imageglass

ImageGlass AppImage

source/__assets/linux/appimage/README.md

10.0.6.9066.3 KB
Original Source

ImageGlass AppImage

Files used to build and distribute ImageGlass as an AppImage.

FilePurpose
io.github.d2phap.imageglass.desktopDesktop entry for the AppDir. Same as the Flatpak one except Exec=AppRun %F — an AppImage installs nothing on PATH.
ig-appimage-integrateOptional desktop integration: offers, on first run, to add a launcher entry + icons to ~/.local/share.
README.mdThis file.

Everything else is generated by the pack script and not committed: AppRun, .DirIcon, the icons (copied from __assets/logo_c_512.png / logo_c.svg), the X-AppImage-* version keys, and the AppDir itself. The AppStream metadata is shared with the Flatpak — the script reads ../flatpak/io.github.d2phap.imageglass.metainfo.xml, because it describes the app rather than the packaging, and Flathub's stricter validator keeps it honest for both.

Build script: ../script-pack-linux-x64-appimage.sh (VS Code task: pack-linux-x64-appimage).

Build

bash
bash __assets/linux/script-pack-linux-x64-appimage.sh

No prerequisites: the script publishes a fresh AOT build itself and downloads appimagetool into __artifacts/tools/ on first run (no distro packages it). It prints the download's sha256 — pin it on later runs so a moving continuous tag cannot swap the tool silently:

bash
APPIMAGETOOL_SHA256=<hex> bash __assets/linux/script-pack-linux-x64-appimage.sh

Output: __artifacts/bundle/ImageGlass_<version>_linux-x64.AppImage.

appimagetool prints AppStream upstream metadata is missing on every run. It is looking for the legacy <app-id>.appdata.xml; we ship the modern <app-id>.metainfo.xml, which is what the AppStream spec, Flathub and the desktop integration tools want, and which appstreamcli validate accepts. The warning is expected — do not "fix" it by adding a duplicate .appdata.xml.

Other env overrides: GPG_KEY (sign the image), COMP (zstd default, xz, gzip), APPIMAGETOOL (use your own copy), NO_APPSTREAM=1, SKIP_PUBLISH=1 (debug only — it can ship stale code under a new version number).

Runtime requirements

Unlike the Flatpak, which ships its own runtime, an AppImage runs against the host glibc and host libraries. The script prints the glibc floor of the shipped binaries on every run; check it before a release.

The host must provide:

  • X11: libX11.so.6, libICE.so.6, libSM.so.6, libXcursor.so.1, libXext.so.6, libXi.so.6, libXrandr.so.2 (release builds pin .UseX11(), so Wayland goes through XWayland)
  • Rendering: libGL.so.1, libfontconfig.so.1
  • .NET globalization: libicuuc, libicui18n (DOTNET_ICU_VERSION_OVERRIDE is the escape hatch on an exotic distro)
  • Optional, per feature: xdg-utils (xdg-open), glib2 (gdbus), cups-client (lpr, printing), one of paplay/pw-play/aplay/ffplay (notification sound), xdg-desktop-portal (set as wallpaper)

Debian/Ubuntu: sudo apt install libx11-6 libice6 libsm6 libfontconfig1. Fedora/RHEL: sudo dnf install libX11 libICE libSM fontconfig.

libgdiplus is not required, despite appearing in Avalonia's install line — that line targets Avalonia XPF, which uses System.Drawing. ImageGlass renders through SkiaSharp.

libgomp.so.1 (needed by the Magick codecs) is the only library bundled, and it is used only when the host has none — LD_LIBRARY_PATH is searched before ld.so.cache, so an unconditional entry would shadow the host's own glibc-matched copy.

Nothing else is bundled on purpose: libGL is coupled to the host's GPU driver, libfontconfig must see the user's font configuration, and both are on the AppImage excludelist.

Settings

Settings live in ~/.local/share/ImageGlass, shared with the tarball install. The mount is read-only, so portable mode is never used and .igportable must never ship inside the image (the script asserts this — the app would abort at startup). For the same reason a machine-wide igconfig.admin.json or a Pro license can only be deployed to ~/.local/share/ImageGlass, never next to the app.

Desktop integration

AppImages do not install themselves. The app asks, not the packaging: Quick Setup shows an "Applications menu" step on a first run, and Settings > File type associations has an "Applications menu" group with Register / Unregister that is always available (Quick Setup does not run for someone upgrading from the tarball, since both share ~/.local/share/ImageGlass, nor for someone who hits Skip). Both call ig-appimage-integrate --install, so the Desktop Entry escaping lives in one place.

Registering is an unmanaged setting, and the UI says so: the .desktop entry and the icons are written to ~/.local/share, outside anything the app owns, so deleting the .AppImage cannot remove them. TryExec= does keep a stale entry from showing (GLib refuses to load an entry whose TryExec is missing), but the files remain — unregister before deleting the image.

The installed entry is the only state; there is no marker file. AppRun runs --maybe on every launch, which does one thing: re-point an already-registered entry after the .AppImage is moved or renamed. It never prompts and never registers on its own — a blocking dialog launched from inside the image would hold the read-only mount open after the app exits.

Manual control, from inside the mounted or extracted image:

bash
usr/bin/ig-appimage-integrate --install   # or --remove

Gear Lever and AppImageLauncher can manage the image instead; they write their own entry and are unaffected by the above.

Distribute on GitHub Releases

Upload the .AppImage to the release matching the tag (<IgVersion>[-<IgReleaseType>]). Users download it, chmod +x, and run it — no installer, no root.

bash
GPG_KEY="<your-key-id-or-email>" bash __assets/linux/script-pack-linux-x64-appimage.sh

Signing is optional. AppImage signature-verification tooling is rarely installed, so publish the sha256 the script prints — that is the check most people will actually run.

If the image will not start on an older host, it is almost always the glibc floor; the error is version 'GLIBC_2.xx' not found. A FUSE-less host needs:

bash
./ImageGlass_<version>_linux-x64.AppImage --appimage-extract-and-run