Skip to content

Comments

feat: add Flatpak packaging support#548

Open
GabeDuarteM wants to merge 19 commits intocjpais:mainfrom
GabeDuarteM:feature/add-flatpak-support
Open

feat: add Flatpak packaging support#548
GabeDuarteM wants to merge 19 commits intocjpais:mainfrom
GabeDuarteM:feature/add-flatpak-support

Conversation

@GabeDuarteM
Copy link
Contributor

@GabeDuarteM GabeDuarteM commented Jan 7, 2026

Before Submitting This PR

Please confirm you have done the following:

Human Written Description

Added Flatpak support and CI infrastructure to build it, implement an autostart module to add support for flatpak (The exec of the .desktop files are slightly different from the existing ones, so we needed to adapt), implemented some checks to make sure the tray icons also work on flatpak, enabled enigo only when we're in x11 (otherwise the app was failing to start on wayland's flatpak).
Also had to change the CSS for the close icon on "visual feedback overlay", since on flatpak occasionally it would spawn two close icons, one where it should be, and another one outside the pill. I couldn't figure out why, and it wasn't consistently happening too, so I hid the render of whatever is outside the pill. My theory is that it may be related to WEBKIT_DISABLE_DMABUF_RENDERER=1, but without it the whole app doesn't render at all, just a black/white screen (depending on your dark settings config)

We still need to do some work on the manifest to add some screenshots and maybe wire the changelog into it, then we can submit it to flathub

Related Issues/Discussions

Discussion: #254

Community Feedback

#254

Testing

  • Built the flatpak image and installed it
  • App's overall design looks identical to the AppImage's version
  • Shortcuts working properly through sigkill (can't test the other methods since they don't work on my distro)
  • Autostart, Start hidden, Overlay working properly
  • Unfortunately I couldn't test my changes on AppImage (can't build it on arch, not even on main), or deb/rpm/macos/windows (don't have those systems). Would be great if someone with those systems could also check if everything is still working fine, at least for deb/rpm/macos
  • Need to check if the CI is working fine

If you wanna help testing locally, you can run:

  • bun run tauri build --bundles deb
  • ./scripts/build-flatpak.sh
  • flatpak install --user handy_0.6.10_x86_64.flatpak
  • flatpak run com.pais.handy

Screenshots/Videos (if applicable)

2026-01-07.11-21-31.mp4

- Add Flatpak manifest and build infrastructure for Linux distribution
- Implement custom autostart module for Flatpak (handles flatpak run command)
- Fix tray icon visibility in Flatpak sandbox by using shared temp directory
- Make Enigo optional on Wayland, falling back to native tools (wtype)
- Add retry logic with exponential backoff for CI release asset downloads
- Restrict icon_as_template to macOS only to prevent Linux display issues
- Include patches for building libayatana-appindicator dependencies
@cjpais
Copy link
Owner

cjpais commented Jan 7, 2026

Thank you for this. It's gonna take me a while to review and probably distribute mainly because I don't have a machine to test on. However, I will run a test build soon to see if people are able to test the flatpak generally and see if it works nicely

@github-actions
Copy link

github-actions bot commented Jan 7, 2026

🧪 Test Build Ready

Build artifacts for PR #548 are available for testing.

Download artifacts from workflow run

Artifacts expire after 30 days.

@arpagon
Copy link

arpagon commented Jan 7, 2026

Thanks @GabeDuarteM for this PR! 🙏

I actually attempted to add Flatpak support a few weeks ago but didn't have time to finish getting it working. Your PR saved me a lot of work!

I tested it today and it works great! 🎉 The app builds and runs perfectly via Flatpak with all functionality working as expected.

One small fix needed for runtime:

The build was completing successfully, but the app was crashing at runtime because it couldn't find the ayatana libraries. I fixed it by adding this line to finish-args in com.pais.handy.yaml:

finish-args:
  # ... existing args ...
  - --env=LD_LIBRARY_PATH=/app/lib:/app/lib64

I also made a few minor build-time adjustments to fix linking issues:

  • Removed premature cleanup of /lib/pkgconfig from libdbusmenu, ayatana-ido, and libayatana-indicator modules
  • Added PKG_CONFIG_PATH and ldflags: -L/app/lib64 to libayatana-indicator and libayatana-appindicator build options

With these changes, everything compiles and runs perfectly on my system (Ubuntu 24.04 with Wayland).

Build environment:

  • Rust 1.92.0
  • GNOME Platform/SDK 48
  • All system dependencies installed per BUILD.md

Great work on this! 👏

- Add LD_LIBRARY_PATH for ayatana libraries to be found at runtime
- Add PKG_CONFIG_PATH and ldflags for libayatana-indicator/appindicator builds
- Remove premature /lib/pkgconfig cleanup to allow dependency resolution
- Fix overlay duplicate icon rendering by adding overflow:hidden and position:relative
@GabeDuarteM
Copy link
Contributor Author

@arpagon Thanks a lot for the feedback! I've applied the changes you mentioned, can you test if it now builds and runs the flatpak on your machine too?

Also, since you're on ubuntu, it would help a lot if you could also test out the deb and the appimage versions, (if you can build it successfully), if you don't mind of course 😄

can be tested by running bun run tauri build --bundles deb and bun run tauri build --bundles appimage, respectively. This will generate the binaries on src-tauri/target/release/bundle/deb

@cjpais
Copy link
Owner

cjpais commented Jan 10, 2026

One concern I have with this is that when we release new versions this will also need to be maintained. Is there any way we can do this with CI as well? I'm curious if you've had any look into that as a potential option.

Flatpak sandboxing prevents direct filesystem access to the autostart
directory. This switches to the XDG Background portal for Flatpak builds,
which is the proper way to request autostart permissions in sandboxed
environments.

Changes:
- Use org.freedesktop.portal.Background.RequestBackground via gdbus
- Remove unnecessary filesystem and portal permissions from manifest
- Handle autostart toggle errors in the frontend with user feedback
- Add flathub.json to restrict builds to x86_64
- Update metainfo URLs and install LICENSE file
@GabeDuarteM
Copy link
Contributor Author

GabeDuarteM commented Jan 11, 2026

@cjpais Yes, the CI is already set up on .github/workflows/build-flatpak.yml and will build the app into a .flatpak file, which we can use to distribute, and will automatically on each release and upload it as a release artifact. Or at least, theoretically, since it is a CI change, and I can't reliably test this locally. We might still need a few back and forth testing this flow.

The workflow:

  1. release.yml triggers build-flatpak.yml after Tauri builds complete
  2. Downloads the .deb from the release
  3. Builds Flatpak with flatpak-builder
  4. Uploads .flatpak bundle to the release

One improvement we could do is to upload the .deb as a build artifact to eliminate the downloading from release part, will probably make this more reliable, I just didn't want to touch the existing CI too much since I can't test (but if you prefer, I can explore this path too)

Other than that, if we want this package on flathub, we also need to:

Only for the Initial Submission (One-time)

  1. Add screenshots of the app to src-tauri/flatpak/com.pais.handy.metainfo.xml, so it can show on the flathub store. Let me know if you have some images in mind, or if I should take some myself 😄
  2. Fork flathub/flathub repo on GitHub
  3. Create a branch from new-pr (not master)
  4. Add the manifest files (just the Flatpak manifest + metainfo)
  5. Open a PR against new-pr branch
  6. Wait for Flathub reviewers check it
  7. After approval, they create a new repo flathub/com.pais.handy and give you write access

You can check more details here: https://docs.flathub.org/docs/for-app-authors/submission

After that its mostly the update process, which can be automated by adding the following to the com.pais.handy.yaml on the flatpak repo they hand to you (not on cjpais/Handy's repo, otherwise we won't be able to build it locally):

  - type: file
    url: https://github.com/cjpais/Handy/releases/download/v0.6.10/Handy_0.6.10_amd64.deb
    sha256: 7a94f1b17d0b761b570996ed4679a24390dbe7114275c057d392d0742be58769
    dest-filename: handy.deb
    x-checker-data:
      type: json
      url: https://api.github.com/repos/cjpais/Handy/releases/latest
      version-query: .tag_name | sub("^v"; "")
      url-query: .assets[] | select(.name | endswith("_amd64.deb")) | .browser_download_url
      is-main-source: true
      release-url-template: https://github.com/cjpais/Handy/releases/tag/v$version

The x-checker-data is for their update bot to detect when we release a new version on github, it should take the asset ending with _amd64.deb and open a PR on the flathub repo to release it (which can also be automated to auto-merge, to be completely hands-off), updating the URL and SHA256 with the new values


I've also just made a few changes to make it pass the flathub linter:

  • Made it wayland-first, with x11 as fallback
    • Because of this, on some environments, depending on the portals available, it may display a gnome-like titlebar even when its not using gnome. This doesn't happen on KDE environments, but e.g. on hyprland it does. The appimage avoids this by running it in xwayland and setting some additional env flags, which is not ideal when we can run it directly as wayland. At first, I did the same on the flatpak version to stay 100% looking the same, but the flathub linter forbids doing that (has to be either x11, or wayland with x11 fallback), so I reverted it. Nothing major changed, aside from the titlebar (top is appimage, bottom is flatpak):
    • image
    • Tested those changes on Hyprland (the error shows fine) and on a Fedora VM I had laying around (the autostart shortcut gets created successfully)
  • Adjusted the autostart handling to do it using desktop portals
    • flathub also forbids needing the autostart permission, unless when we ask for an exception for this with reasonable arguments. We had this to properly generate the .desktop files no matter the environment we were in, but due to that constraint, I've changed to use the portal instead. Because of this, environments that do not implement the portal will not work with this setting (I've added an UI alert when we can't call the portal). This should work OOTB with major environments like KDE and gnome, but on some wlroots environments the setting will fail, and as a user, you will need to add it to autostart yourself.
    • This also allowed us to remove the GTK theme filesystem mounts and some portal talk-names from the Flatpak permissions (these were only needed for the X11 theming workaround)
    • Tested this on both hyprland (flatpak) and the fedora VM (rpm and flatpak), works on both

@cjpais
Copy link
Owner

cjpais commented Jan 13, 2026

Thank you so much for this, I will review again when I get a chance and try to pull in. Thank you so much for helping to support the Linux community it's much appreciated!

return Ok(());
}

// Initialize EnigoState - this always succeeds but may contain None on Wayland
Copy link
Owner

Choose a reason for hiding this comment

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

is this a merge issue, not sure why these files got changed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep, ended up removing the enigo changes I made, they were not needed anymore.

I also simplified the tray icons to remove the manual patches I had copied before and rely instead on the shared-modules submodule (which contain the same patches, but at least we don't need to maintain them here 😄 )

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually, my bad, about enigo we do need to make it optional still on flatpak, otherwise it fails to initialize it (it worked before because I tested the wrong binary 🙈). I've changed it so we try to check first if better tools are available (wtype, etc), and only as a last resort, if really needed, we initialize enigo

Replace the copied build patches with the flathub shared-modules
submodule instead. Also simplify Enigo initialization by removing the
optional wrapper pattern.
The flatpak-build directory contains symbolic links that cause Vite
to crash with ELOOP (too many symbolic links) errors during dev mode.
This change allows the paste functionality to work in sandboxed
environments like Flatpak where Enigo may not be available or functional.

When wtype, dotool, ydotool, or xdotool are available, Enigo
initialization is skipped entirely. The paste functions now accept
an optional Enigo reference and gracefully fall back to native tools
when Enigo is not present.
src/bindings.ts Outdated
Comment on lines 619 to 620
* Stub implementation for non-macOS platforms
* Always returns false since laptop detection is macOS-specific
Copy link
Contributor Author

Choose a reason for hiding this comment

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

not sure why this is changing, but its changing automatically when I run the tauri dev command. I can manually remove it if its an issue

Copy link
Owner

Choose a reason for hiding this comment

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

it changes between linux/macOS when running the dev build, I probably need to run it on my machine and remove

@cjpais
Copy link
Owner

cjpais commented Feb 5, 2026

hopefully I can look at this soon I would like to merge it

@GabeDuarteM
Copy link
Contributor Author

Awesome to hear! I'll also take a look at this again when I have some time to pull main into here and solve the conflicts

…-support

# Conflicts:
#	src-tauri/src/clipboard.rs
#	src-tauri/src/shortcut/mod.rs
The upstream merge introduced gtk-layer-shell as a mandatory Linux
dependency for Wayland overlay support, but it wasn't included in the
Flatpak manifest, causing a missing shared library error at runtime.

Also fix build-flatpak.sh to pick the newest .deb when multiple versions
are present in the output directory.
@GabeDuarteM
Copy link
Contributor Author

I merged main into it, should be good now. I also noticed the tests were failing, investigated a bit and its unrelated to my changes, but in any case, I've opened #719 to fix it, feel free to take a look into it

@cjpais cjpais closed this in #719 Feb 5, 2026
@GabeDuarteM
Copy link
Contributor Author

I think this was closed by mistake when I referenced it on #719 😅

@cjpais
Copy link
Owner

cjpais commented Feb 6, 2026

def, we need this open lol

the auto closing of issues is annoying ill see if i can stop it

@cjpais cjpais reopened this Feb 6, 2026
@cjpais
Copy link
Owner

cjpais commented Feb 16, 2026

@GabeDuarteM is this more or less ready to go after a rebase> I'm willing to just merge it and run into issues in prod as long as you can help address them

@GabeDuarteM
Copy link
Contributor Author

@cjpais I've been using this flatpak version since I've opened the pr with no issues so I believe it should be good to go. The things that might break are of course from other envs I couldn't test (appimage/windows/macos), and the CI flow itself.

And of course, if you need help with anything feel free to ping me 😄 I can take another look into the conflicts soon-ish

Doing it this way avoids having version incompatibilities between the
flatpak env and the env where the app was built
@GabeDuarteM
Copy link
Contributor Author

@cjpais I've rebased and did some changes to the build script to make it a bit more resilient to environment differences. Since I use arch and the flatpak runs in a gnome-like environment, some of the packages I have locally are later versions then than the ones available in the flatpak env, causing errors when running. This was solved it by making the local build script also build the app inside the flatpak env.

For the normal release this should be fine since the app will be built on ubuntu anyway, but again, if something goes sour, feel free to ping me. Should be good to go now 😄

@cjpais
Copy link
Owner

cjpais commented Feb 19, 2026

I want to merge this, but can you do a review of all the files submitted and why the changes were necessary. When I look through the change set I see a lot of things which make sense for adding Flatpak support, but also a bunch of other files with small changes and I don't know the reason for them and I'm worried they will cause regressions..

I'm sorry I've not done a detailed review myself yet, I just really don't want to break things for people

@GabeDuarteM
Copy link
Contributor Author

Of course, no worries! Most of the changes are mentioned on the PR more in detail, but I can give an overview:

Regarding enigo, it breaks on flatpak when we try to instantiate it, so we have to make it optional and only instantiate it when needed.

There are also some changes to autostart (since flatpak needs special treatment due to the filesystem sandbox) and to the tray icon, since due to the filesystem sandbox it was unable to get the tray icon properly.

The CSS changes are just to fix the double close button appearing on the floating overlay when you're speaking, its hacky, but I spent quite some time trying to figure out why... I assume its some sort of webview rendering bug, but couldn't find anything regarding it. But in the end, this just clips whatever is outside the overlay, so shouldn't break anything

On the settings store I moved the autostart logic to src/components/settings/AutostartToggle.tsx, since I wanted to make it a bit nicer when the UI setting fails (with the default logic it just fails silently)

And lastly, the git submodule is for us to get the shared flatpak patches to the systray libraries and others, so they behave well on flatpak too

Let me know if you're curious about anything in specific

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.

3 participants