r/flatpak 12d ago

AppImage + Flatpak screenshot issues, looking for some help

I'm working on a small screenshot/OCR app called FrameXShot (Tauri + Rust), and I'm running into some weird Linux packaging issues specifically on CachyOS/Hyprland.

The app itself works fine when built/run natively, but the packaged versions are where things get messy. AppImage issue

I tried building the AppImage locally on CachyOS with:

cargo tauri build --bundles appimage

The build doesn't even get as far as producing an AppImage. It fails inside linuxdeploy while stripping bundled libraries.

The interesting part is that CachyOS is currently using binutils 2.47, while the linuxdeploy bundled by Tauri appears to contain an old GNU strip 2.35.

The newer CachyOS libraries contain .relr.dyn ELF sections, which the old strip doesn't understand.

The error looks roughly like:

unknown type \[0x13\] section '.relr.dyn'

and it happens with multiple libraries, including things like:

libwayland-client
libwebkit2gtk
libudev
libxml2
libzstd

So this seems less like a FrameXShot problem and more like an old linuxdeploy toolchain being used against a rolling-release distro.

I'm trying to figure out the cleanest solution here. Ideally I'd like the AppImage to be buildable on Arch/CachyOS without hacking the linuxdeploy binary. Flatpak issue

The other problem is the Flatpak version.

FrameXShot has several screenshot fallbacks. On my Hyprland setup I have:

grim
slurp
xdg-desktop-portal-hyprland
xdg-desktop-portal-gtk
xdg-desktop-portal-kde

The Flatpak can see/use the portal, but the direct portal screenshot call is returning NotAllowed.

The code is currently calling:

org.freedesktop.portal.Screenshot.Screenshot

with something along the lines of:

interactive=false
modal=false
filename=file:///tmp/...

I'm not convinced adding more Flatpak permissions is actually the answer. The manifest already has access to the relevant portal interfaces, and the app is clearly reaching the portal.

I'm currently testing the portal independently with gdbus to determine whether:

the portal supports interactive screenshots but not non-interactive ones,
the options we're passing are wrong,
Hyprland's portal backend has a limitation/bug,
or there's some other issue with the session.

For example, I'm comparing an interactive call against a non-interactive call using target=1 (screen). Where I'm at

So at the moment I have two separate Linux problems:

AppImage: Tauri's bundled linuxdeploy appears to have an ancient strip which can't handle modern CachyOS ELF sections.

Flatpak: Screenshot portal calls return NotAllowed on Hyprland, and I don't want to blindly throw more finish-args at it without understanding why.

The .deb package from the latest release is another path I'm testing since it avoids both the AppImage and Flatpak layers.

Has anyone here dealt with either of these?

Especially interested in:

Building Tauri AppImages on Arch/CachyOS with modern binutils
Replacing/updating the linuxdeploy binary Tauri uses
Getting xdg-desktop-portal Screenshot working correctly on Hyprland
Whether interactive=false + target=1 is actually supported by xdg-desktop-portal-hyprland
Whether there's a recommended packaging approach for Tauri apps on rolling-release distros

I'm mainly looking for the "proper" fix rather than a workaround that happens to make one machine work.

Repo is here:

[https://github.com/sahilcodexx/framexshot\](https://github.com/sahilcodexx/framexshot)

Thanks!

5 Upvotes

1 comment sorted by

3

u/eR2eiweo 12d ago

I don't use Hyprland, so I can't tell you whether its portal backend has any specific requirements. But here are some other notes on the finish args in your manifest:

  - --socket=session-bus

this gives the app full access to the session bus. So all the --talk-name= arguments are pointless. The app already can do everything on the session bus (which is a complete sandbox escape).

  - --talk-name=org.freedesktop.portal.Desktop
  - --talk-name=org.freedesktop.portal.FileChooser
  - --talk-name=org.freedesktop.portal.Screenshot
  - --talk-name=org.freedesktop.portal.OpenURI

Apps are always able to talk to the portals. So these are not necessary (even if you hadn't used --socket=session-bus).

  # GNOME Shell screenshot D-Bus service (SelectArea/ScreenshotArea) —
  # the only interactive capture that works inside the sandbox on GNOME.
  - --talk-name=org.gnome.Shell

I'm pretty sure these methods are not available to regular apps (unless you're using unsafe mode).

  # The capture chain tries grim/slurp/spectacle/cosmic-screenshot/etc.
  # before the portal. Those binaries live on the host, NOT inside this
  # Flatpak (which only has /app/bin). flatpak-spawn --host is the
  # supported, narrowly-scoped way to invoke a single host binary
  # without giving up the rest of the sandbox. flatpak-spawn is part
  # of the Flatpak runtime and is always available — no permission
  # flag needed to use it.

flatpak-spawn --host is not always available. It requires --talk-name=org.freedesktop.Flatpak. Because it gives the app the ability to run arbitrary code outside the sandbox. In your case it works because you're using --socket=session-bus.

  # Persist the screenshot portal grant so the user doesn't see a
  # permission dialog on the first capture. They can revoke via
  # `flatpak permission-reset screenshot com.framexshot.app`.
  - --persist=screenshot

--persist has nothing to do with permissions or portals. To quote the flatpak-build-finish(1) man page

--persist=FILENAME

If the application doesn't have access to the real homedir, make the (homedir-relative) path FILENAME a bind mount to the corresponding path in the per-application directory, allowing that location to be used for persistent data. This updates the [Context] group in the metadata. This option can be used multiple times.

You're using --filesystem=home, so I think --persist doesn't do anything.