# Flatpak manifest — the Tauri Wondershot bundle (one install, real menu integration). # # Local build + run (needs the .deb next to this file, named wondershot.deb): # npm run tauri build -- --bundles deb --features bgremove # cp src-tauri/target/release/bundle/deb/Wondershot_*_amd64.deb \ # packaging/flatpak/wondershot.deb # flatpak-builder --user --install --force-clean build-dir \ # packaging/flatpak/io.github.jackmusick.wondershot.yml # flatpak run io.github.jackmusick.wondershot # # Distributable single-file bundle — ALWAYS pass --runtime-repo, or the # bundle can't resolve org.gnome.Platform on machines that don't already # have it (fresh installs fail with "runtime ... not found"): # flatpak-builder --user --force-clean --repo=REPO build-dir # flatpak build-bundle \ # --runtime-repo=https://dl.flathub.org/repo/flathub.flatpakrepo \ # REPO wondershot.flatpak io.github.jackmusick.wondershot # # Like wonderblob's manifest, this does NOT compile Rust/JS in the sandbox — # it unpacks the prebuilt .deb and relies on org.gnome.Platform for # webkit2gtk-4.1. The KDE runtime ships GTK3+libsoup3 but NOT webkit, so the # GNOME runtime is the practical webview host; KWin scripting + portals still # work via the host D-Bus regardless of runtime. ffmpeg/x264/wl-clipboard/ # onnxruntime/u2net are added as modules because the GNOME runtime doesn't # ship them and Wondershot shells out to / loads them at runtime. app-id: io.github.jackmusick.wondershot runtime: org.gnome.Platform runtime-version: '49' sdk: org.gnome.Sdk command: wondershot # Build leftovers that must not ship: ffmpeg/x264 install static archives, # headers, pkg-config and debug data alongside the .so's we actually use — # ~200 MB of dead weight in the bundle. (Cleanup happens at finalize, so the # module build caches stay valid.) cleanup: - /include - /lib/*.a - /lib/*.la - /lib/pkgconfig - /lib/cmake - /lib/debug - /share/ffmpeg/examples - /share/man - /share/doc finish-args: - --share=ipc # Network: AI endpoint test/inference + cloud sharing (S3/Azure/OneDrive # Graph). The host (unsandboxed) app had this implicitly. - --share=network - --socket=wayland - --socket=fallback-x11 # --device=all (not just dri): the camera bubble's getUserMedia needs the # webcam (/dev/video*); dri alone only covers the GPU render node. - --device=all # Recorder: portal ScreenCast negotiates the PipeWire stream - --filesystem=xdg-run/pipewire-0 - --socket=pulseaudio # Library lives wherever the user configured it (e.g. ~/Sync/Screenshots) + # watched video dirs + the shared ~/.config/wondershot/wondershot.conf. The # non-Flatpak install had full home access; a screenshot manager genuinely # needs the user's chosen folders, so grant home rather than guess subpaths. - --filesystem=home # KWin scripting (auto-size-to-window); host D-Bus, runtime-independent - --talk-name=org.kde.KWin # Run the HOST's Spectacle (its rectangular drag-selection UI) for captures via # flatpak-spawn --host — the sandbox has no spectacle. - --talk-name=org.freedesktop.Flatpak # Portals (screenshot/screencast) ride the session bus - --talk-name=org.freedesktop.portal.Desktop - --talk-name=org.freedesktop.portal.OpenURI # System tray (StatusNotifierItem). The Qt app got a tray for free via Qt's # native SNI; Tauri needs the bundled libayatana-appindicator (modules below) # AND bus access to KDE Plasma's watcher, plus the right to own its own # StatusNotifierItem-- name. Without these the icon never appears. - --talk-name=org.kde.StatusNotifierWatcher - --talk-name=org.freedesktop.StatusNotifierWatcher # The tray item registers a dynamic bus name org.kde.StatusNotifierItem--. # Flatpak only wildcards on dot boundaries (the "-*" form is rejected), so own # the org.kde.* subtree — the narrowest valid grant that covers the live name. - --own-name=org.kde.* # AI background removal downloads u2net to ~/.cache/wondershot on first use # (168 MB — deliberately NOT bundled; it would dominate the bundle size). modules: # libx264: not in the GNOME SDK; ffmpeg below (and the video render path) # needs it. Commit-pinned tarball (stable branch head). - name: x264 config-opts: - --enable-shared - --disable-cli sources: - type: archive url: https://code.videolan.org/videolan/x264/-/archive/b35605ace3ddf7c1a5d67a2eb553f034aef41d55/x264-b35605ace3ddf7c1a5d67a2eb553f034aef41d55.tar.bz2 sha256: 6eeb82934e69fd51e043bd8c5b0d152839638d1ce7aa4eea65a3fedcf83ff224 # ffmpeg CLI: Wondershot's video commands spawn the binary. - name: ffmpeg config-opts: - --disable-debug - --disable-doc - --disable-ffplay - --enable-gpl - --enable-libx264 - --enable-shared sources: - type: archive url: https://ffmpeg.org/releases/ffmpeg-7.1.tar.xz sha256: 40973d44970dbc83ef302b0609f2e74982be2d85916dd2ee7472d30678a7abe6 # wl-clipboard: provides wl-copy. On Wayland the compositor grants the # selection only to a focused client; our auto-copy runs with the window # hidden. wl-copy holds the selection via data-control, focus-independent. - name: wl-clipboard buildsystem: meson # The GNOME SDK's meson auto-detects fish/zsh and installs completions to # absolute system dirs (/usr/share/fish/...) outside the build prefix, which # is read-only in the flatpak sandbox. Disable them — wl-copy is all we need. config-opts: - -Dfishcompletiondir=no - -Dzshcompletiondir=no sources: - type: archive url: https://github.com/bugaevc/wl-clipboard/archive/refs/tags/v2.2.1.tar.gz sha256: 6eb8081207fb5581d1d82c4bcd9587205a31a3d47bea3ebeb7f41aa1143783eb # onnxruntime: prebuilt shared lib for ort's load-dynamic backend. ort # rc.12 targets ORT 1.24 (api-24); 1.26 is forward-compatible. The system # loader finds libonnxruntime.so in /app/lib (ORT_DYLIB_PATH left unset). - name: onnxruntime buildsystem: simple build-commands: - install -Dm755 lib/libonnxruntime.so.1.26.0 /app/lib/libonnxruntime.so.1.26.0 - ln -s libonnxruntime.so.1.26.0 /app/lib/libonnxruntime.so sources: - type: archive url: https://github.com/microsoft/onnxruntime/releases/download/v1.26.0/onnxruntime-linux-x64-1.26.0.tgz sha256: 1254da24fb389cf39dc0ff3451ab48301740ffbfcbaf646849df92f80ee92c57 # u2net model: NOT bundled — the app downloads it (sha256-verified) to # ~/.cache/wondershot/u2net.onnx on the first Remove BG (commands::bg_model_download). # System tray: the GNOME runtime ships no appindicator library, so tray-icon's # dlopen("libayatana-appindicator3.so.1") panics (caught → silent "no tray"). # Build the Ayatana appindicator stack into /app/lib so the dlopen succeeds. # Order matters: intltool → libdbusmenu → libayatana-indicator → libayatana-appindicator. # intltool: the GNOME SDK dropped it (deprecated), but libdbusmenu's 2016 # autotools hard-requires it. Build-only — stripped from the bundle. - name: intltool cleanup: - '*' sources: - type: archive url: https://launchpad.net/intltool/trunk/0.51.0/+download/intltool-0.51.0.tar.gz sha256: 67c74d94196b153b774ab9f89b2fa6c6ba79352407037c8c14d5aeb334e959cd - name: libdbusmenu buildsystem: autotools # libdbusmenu's Makefiles have a broken valgrind probe that aborts the build; # the HAVE_VALGRIND_* env override is the well-known fix. -Wno-error keeps its # ancient (2016) source compiling under the modern SDK's strict gcc. build-options: cflags: '-Wno-error' env: HAVE_VALGRIND_TRUE: '' HAVE_VALGRIND_FALSE: '#' config-opts: - --with-gtk=3 - --disable-dumper - --disable-static - --disable-tests - --disable-gtk-doc - --disable-vala - --enable-introspection=no sources: - type: archive url: https://launchpad.net/libdbusmenu/16.04/16.04.0/+download/libdbusmenu-16.04.0.tar.gz sha256: b9cc4a2acd74509435892823607d966d424bd9ad5d0b00938f27240a1bfa878a - name: ayatana-ido buildsystem: cmake-ninja config-opts: - -DENABLE_GTKDOC=NO sources: - type: archive url: https://github.com/AyatanaIndicators/ayatana-ido/archive/refs/tags/0.10.4.tar.gz sha256: bd59abd5f1314e411d0d55ce3643e91cef633271f58126be529de5fb71c5ab38 - name: libayatana-indicator buildsystem: cmake-ninja config-opts: - -DENABLE_GTKDOC=NO sources: - type: archive url: https://github.com/AyatanaIndicators/libayatana-indicator/archive/refs/tags/0.9.4.tar.gz sha256: a18d3c682e29afd77db24366f8475b26bda22b0e16ff569a2ec71cd6eb4eac95 - name: libayatana-appindicator buildsystem: cmake-ninja config-opts: - -DENABLE_BINDINGS_MONO=NO - -DENABLE_BINDINGS_VALA=NO - -DENABLE_GTKDOC=NO sources: - type: archive url: https://github.com/AyatanaIndicators/libayatana-appindicator/archive/refs/tags/0.5.93.tar.gz sha256: cbefed7a918a227bf71286246e237fcd3a9c8499b3eaac4897811a869409edf0 # The Tauri app: unpack the prebuilt .deb (ar -> data.tar.* -> usr/ tree). - name: wondershot buildsystem: simple build-commands: - ar x wondershot.deb - mkdir -p deb-root - tar -xf data.tar.* -C deb-root - install -Dm755 deb-root/usr/bin/wondershot ${FLATPAK_DEST}/bin/wondershot # Desktop file, renamed to the app-id with Icon= pointed at the app-id. # Ensure Exec passes URLs (%U) and the wondershot:// scheme is handled — # the interactive OneDrive sign-in redirects to wondershot://auth and the # OS protocol handler must relaunch this app with the callback URL. - | src_desktop=$(ls deb-root/usr/share/applications/*.desktop | head -n1) sed -e 's/^Icon=.*/Icon=io.github.jackmusick.wondershot/' \ -e 's/^Exec=\([^ %]*\).*/Exec=\1 %U/' "$src_desktop" \ > ${FLATPAK_ID}.desktop grep -q '^MimeType=' ${FLATPAK_ID}.desktop \ && sed -i 's|^MimeType=.*|&x-scheme-handler/wondershot;|' ${FLATPAK_ID}.desktop \ || echo 'MimeType=x-scheme-handler/wondershot;' >> ${FLATPAK_ID}.desktop install -Dm644 ${FLATPAK_ID}.desktop \ ${FLATPAK_DEST}/share/applications/${FLATPAK_ID}.desktop # Icons: copy every size/format the deb shipped, renamed to the app-id. - | for icon in $(find deb-root/usr/share/icons -type f); do dir=$(dirname "$icon" | sed 's|deb-root/usr/share/icons|share/icons|') ext="${icon##*.}" install -Dm644 "$icon" "${FLATPAK_DEST}/${dir}/${FLATPAK_ID}.${ext}" done sources: - type: file path: wondershot.deb