super-productivity/build/linux/snap-wrapper.sh
Johannes Millan 297aeb30ab fix(electron): harden Snap+Wayland argv wrapper after multi-review
Address findings from code-reviewer + debugger-assistant +
refactor-specialist multi-review on 8e1c47ebc2:

- afterPack: read wrapper source before rename; on writeFile failure,
  roll the rename back so a broken intermediate state can't ship a
  package with no launcher. Strengthen idempotency check to require a
  shebang at binPath (both files alone no longer counts as "installed").
- wrapper: gate the X11 injection on \$SNAP_NAME = "superproductivity",
  not just \$SNAP set. An xdg-open from a sibling snap (e.g. Firefox)
  leaks \$SNAP into the child env, which previously would have silently
  forced XWayland on .deb/.rpm users. Derive BIN_DIR from \$SNAP
  directly when we are our snap, avoiding fragile \$0 resolution
  through snapd's wrapper chain. Stop argv scanning at -- so positional
  args that resemble --ozone-platform aren't misread as a user override.
- app-control: point app.relaunch() execPath at the sibling shell
  wrapper instead of the default process.execPath (which is the renamed
  ELF and would bypass the flag injection on a relaunched Snap+Wayland
  instance).
- Move build/snap-wrapper.sh -> build/linux/snap-wrapper.sh to match
  the existing build/linux/ layout convention.
- Update research doc §18 to reflect the tightened predicate and the
  relaunch fix.
2026-04-21 15:03:42 +02:00

50 lines
2 KiB
Bash
Executable file

#!/bin/sh
# Pre-Electron argv wrapper for Super Productivity on Linux.
#
# Forces --ozone-platform=x11 when launched inside *our* Snap sandbox on a
# Wayland session. This is load-bearing: the programmatic
# app.commandLine.appendSwitch('ozone-platform','x11') in electron/start-app.ts
# is not enough in practice — field reports on issue #7270 show Chromium's
# Ozone init dlopens libEGL/libgbm on the core22 Mesa path before
# appendSwitch is honored, which segfaults under host-vs-snap Mesa ABI
# drift. Putting the flag into argv before Electron's argv parser runs
# bypasses that.
#
# Same mechanism used by Signal Desktop and Mattermost Desktop snaps
# (snapcrafters/signal-desktop, snapcrafters/mattermost-desktop).
#
# Non-Snap launches (AppImage, .deb, .rpm) hit the passthrough branch so
# behavior for those targets is unchanged. The SNAP_NAME gate also protects
# .deb/.rpm installs invoked via xdg-open from *another* snap (where $SNAP
# leaks into the child env).
#
# See docs/research/snap-wayland-gpu-fix-research.md §18.
# Derive the real ELF path. Inside our snap confinement, $SNAP is the
# revision mount root and is more reliable than $0 resolution through
# snapd's wrapper chain. Elsewhere, resolve $0 through symlinks — this
# handles /usr/bin/superproductivity symlinks from .deb/.rpm installs.
if [ -n "$SNAP" ] && [ "$SNAP_NAME" = "superproductivity" ]; then
IS_OUR_SNAP=1
BIN_DIR="$SNAP"
else
IS_OUR_SNAP=
SELF=$(readlink -f "$0" 2>/dev/null || echo "$0")
BIN_DIR=$(dirname "$SELF")
fi
BIN="$BIN_DIR/superproductivity-bin"
# If the user already supplied --ozone-platform on argv, don't override.
# Stop scanning at -- so positional args aren't misread as flags.
for arg in "$@"; do
case "$arg" in
--) break ;;
--ozone-platform=* | --ozone-platform) exec "$BIN" "$@" ;;
esac
done
if [ -n "$IS_OUR_SNAP" ] && { [ "$XDG_SESSION_TYPE" = "wayland" ] || [ -n "$WAYLAND_DISPLAY" ]; }; then
exec "$BIN" --ozone-platform=x11 "$@"
fi
exec "$BIN" "$@"