Skip to content

Linux autostart: an unpacked AppImage starts its AppRun - #348

Merged
fylorn merged 2 commits into
ThinkWatchProject:devfrom
sunnysab:fix/autostart-extracted-appimage
Oct 20, 2026
Merged

fylorn merged 2 commits into
ThinkWatchProject:devfrom
sunnysab:fix/autostart-extracted-appimage

Conversation

@sunnysab

@sunnysab sunnysab commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

What happens

On an install whose AppImage was unpacked — the AUR thinkwatch-lite-bin package, or anyone who ran --appimage-extract — turning on Launch at login fails with:

The location of the AppImage file could not be determined (APPIMAGE is not set)

The toggle never turns on, and there is no way to get past it.

Why

The bundler patches a bundle marker into the binary, and tauri::utils::platform::bundle_type() reads it. Unpacking the AppImage does not remove that marker, so an unpacked copy still reports BundleType::AppImage — but $APPIMAGE is only set by the AppImage runtime when it mounts the image. Starting AppRun directly (what the AUR package does) never sets it.

autostart::linux::program branched on the marker alone, so it asked for $APPIMAGE, found nothing, and returned the error above.

update::linux_kind already draws this distinction for the updater: marker and a non-empty $APPIMAGE means AppImage, anything else is a development build. desktop_entry::appimage does the same. Only the autostart path missed it.

A .deb/.rpm built from the same tree would hit it too; Linux just does not ship those.

The fix

Ask for $APPIMAGE only when it is really there, and otherwise point the entry at current_exe() — the installed binary, which is what the user started. The bundle marker is left alone, so gateway::bundled_core still finds twcore and update::linux_kind still refuses to self-update this copy.

The pure part now takes the bundle type and $APPIMAGE as arguments, exactly like update::linux_kind, so the branch is testable on any platform.

Verification

New unit test the_bundle_marker_alone_is_not_an_appimage covers: marker + $APPIMAGE → the AppImage file; marker + no/empty/relative $APPIMAGE → the running binary; no marker → the running binary; neither → an error.

I could not run the full cargo test here (no WebKitGTK dev libraries on this machine), so the branch logic was checked with rustfmt plus a standalone replica of program; CI will do the real compile.

I have read the CLA Document and I hereby sign the CLA

A package that unpacks the AppImage and starts its AppRun (the AUR
thinkwatch-lite-bin, --appimage-extract) keeps the bundle marker the
bundler patched into the binary, but no AppImage runtime ever set
$APPIMAGE for it. `program` trusted the marker, asked for $APPIMAGE,
found nothing and refused to write the entry — "The location of the
AppImage file could not be determined (APPIMAGE is not set)" — so the
launch-at-login toggle never turned on.

Ask for $APPIMAGE only when it is actually there; otherwise point the
entry at current_exe, the same line `update::linux_kind` draws for the
updater.

The pure part now takes the bundle type and $APPIMAGE as arguments, like
`update::linux_kind`, so the new test runs everywhere.
Copilot AI balanced review requested due to automatic review settings October 19, 2026 07:29

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@sunnysab

Copy link
Copy Markdown
Contributor Author

recheck

@sunnysab

Copy link
Copy Markdown
Contributor Author

I have read the CLA Document and I hereby sign the CLA

github-actions Bot added a commit that referenced this pull request Oct 20, 2026
An unpacked AppImage keeps the bundle marker but has no $APPIMAGE, and
the previous commit pointed the entry at the running binary for it.
Started that way it skips AppRun, which changes into usr/ and puts the
bundled libraries first. The bundled WebKit needs both: the bundler
rewrites /usr to ././ in it, so it looks for its helper processes
relative to the working directory, and a session manager starts
autostart entries from somewhere else. Point the entry at
<AppDir>/AppRun instead, which is also what the AUR package's launcher
starts, and at the binary only when there is no AppRun next to it.

The mounted-AppImage check (the marker plus an absolute $APPIMAGE) now
lives in one place, update::mounted_appimage, used by the updater, the
menu entry and autostart. linux_kind used to accept any non-empty value.

The new tests use Unix paths and a temporary AppDir, so they are
#[cfg(unix)] like the module's other path tests: on Windows "/home/..."
is not absolute.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@fylorn

fylorn commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

Thanks for tracking this down, and for the clear write-up. Using the bundle marker without $APPIMAGE as the signal is right. Pointing the entry at the bare binary, though, would most likely start the app at login without what AppRun sets up:

  • AppRun changes into $APPDIR/usr and puts the bundled libraries first on LD_LIBRARY_PATH.
  • At bundle time /usr is rewritten to ././ in the bundled WebKit, so WebKit looks for WebKitWebProcess and WebKitNetworkProcess relative to the working directory. A session manager starts autostart entries from somewhere else (usually $HOME), so the window would likely come up blank.

I pushed a follow-up commit (798a34a) to this branch:

  • For an unpacked AppImage, the entry now starts <AppDir>/AppRun, which is also what your package's /usr/bin/thinkwatch-lite runs. It falls back to the binary only when there is no AppRun next to it.
  • The mounted-AppImage check (the marker plus an absolute $APPIMAGE) now lives in one place, update::mounted_appimage. The updater, the menu entry and autostart all use it.
  • The new tests are #[cfg(unix)]. On Windows /home/... is not an absolute path, so they would fail there.

Could you give it a quick try on Arch? With the app quit, start it the way the entry would, first the old way and then the new one:

cd ~ && /opt/thinkwatch-lite-bin/usr/bin/thinkwatch-lite --autostart
cd ~ && /opt/thinkwatch-lite-bin/AppRun --autostart

The second should open a working window from the tray. If it does, we'll merge this, and it will ship in the next release.

@sunnysab

Copy link
Copy Markdown
Contributor Author

Tested on Arch Linux with KDE/Wayland using the installed AUR package (thinkwatch-lite-bin 2026.10.21-1). The results support the AppRun change:

  • Starting /opt/thinkwatch-lite-bin/usr/bin/thinkwatch-lite --autostart from $HOME starts the background instance, but opening its window crashes it with:
    Unable to spawn a new child process: Failed to spawn child process “././/lib/x86_64-linux-gnu/webkit2gtk-4.1/WebKitNetworkProcess” (No such file or directory)
    
  • Starting /opt/thinkwatch-lite-bin/AppRun --autostart from $HOME works: its working directory becomes /opt/thinkwatch-lite-bin/usr, both WebKitNetworkProcess and WebKitWebProcess start successfully, and the window renders the application logo and connection-status text rather than a blank page.

One qualification on the test setup: my agent session depends on the currently running ThinkWatch gateway, so I left that instance untouched. I tested each launcher in a separate D-Bus session with temporary XDG/data directories and an intentionally unreachable remote target, so no second local gateway was started. After the --autostart launch, I opened the test window via a second invocation (the single-instance callback), rather than a tray click. The AppRun window rendered correctly; its disconnected state was expected for that test target. All test instances have been cleaned up.

This verifies the launcher/runtime behavior with the installed package, not a build of 798a34a or an actual login/autostart-toggle end-to-end test. Using AppRun instead of the bare binary is confirmed by this comparison. Thanks for the follow-up fix!

@fylorn fylorn changed the title Linux autostart: an unpacked AppImage points at its binary Linux autostart: an unpacked AppImage starts its AppRun Oct 20, 2026
@fylorn
fylorn merged commit 9240b73 into ThinkWatchProject:dev Oct 20, 2026
6 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 20, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants