[linux apps] fix drag-n-drop & opening files

This commit is contained in:
olcxja 2026-10-08 13:59:08 +02:00
commit f4e770a7db
3 changed files with 80 additions and 5 deletions

View file

@ -46,6 +46,8 @@ A native app runs with its **own home folder**: `HOME`, `XDG_CONFIG_HOME`, `XDG_
When **bubblewrap** is installed *and* usable (PLWL probes it with a real run, not `which bwrap` — Ubuntu's AppArmor profile kills it even when it is installed), the two sandboxed levels also give the app its own namespaces: `/` is mounted read-only, so only **its home folder and its own app folder stay writable** — anything else fails with `EROFS`. Relaxed adds exactly one mount on top of that profile (the writable host filesystem described below); everything else on this page is the same at both levels. The app folder is included on purpose: portable apps keep their logs and data next to themselves (Prism Launcher refuses to start otherwise). System trees are never handed out writable, not even when the app itself lives in one. Screens, audio (X11/Wayland, PulseAudio/PipeWire), gamepads and networking keep working. `XDG_RUNTIME_DIR` stays the host's, so the session bus is shared — the sandbox is not airtight, and the UI says so rather than pretending.
A file your desktop hands the app — a drag-and-drop from your file manager, a file picked in a file dialog — is named by its **real path** (`/home/you/Downloads/mod.jar`), and inside the sandbox that name is the app's own redirected home. At **Relaxed** your home folders are linked back into the app at those very paths, through the writable mount, so the drop opens where it lies and a save lands on your real file; at **Isolated** there is no view to link into, and what reaches the app there is only what the launcher hands it, as a copy (see the levels below).
The redirected home starts with a **copy of your desktop preferences** — `kdeglobals`, the GTK 3/4 settings and `user-dirs.dirs` — so the app keeps your theme instead of falling back to its built-in light look. The copy keeps following your host as long as the app has not changed it: a theme change arrives on the next launch, and the moment the app writes its own version, PLWL never touches it again. Your own **fonts, icons, themes and colour schemes are not copied but mounted read-only** inside the sandbox and added to `XDG_DATA_DIRS`, so they follow the host live and nothing can be written back to your `~`.
**Anything the app wants to open is opened by your own desktop.** A **link** goes to the host's xdg-desktop-portal, so it lands in the browser you actually chose instead of one resolved in here, where the default association and its `.desktop` file are behind the redirected home — that used to mean a system browser you never picked, or nothing at all. Both routes reach the portal: `xdg-open` itself (what Qt, Prism and Electron call) and GIO's in-process resolution (`gtk_show_uri`). A **folder or a document** (Prism's *Open Pack Folder*, a text file, a drop) takes the other route: the app leaves the target in its own home, PLWL picks it up, translates the path back out of the sandbox and opens it with your `xdg-open` — so it arrives in your file manager, and a scheme nothing handles gets your desktop's own *Choose an application* dialog rather than a guess. On a machine without a portal nothing is changed — a link then behaves exactly as it did before. A KDE-native app that resolves the link in-process through KIO (Dolphin, Kate) is the one path still left out: it asks KDE's own handler database, which has no answer in here (measured: `kde-open` opens nothing and reports success).
@ -59,8 +61,8 @@ Some apps draw their window icon themselves, which Wayland does not allow — Mi
Per app you choose the **Isolation** level — what the app gets besides its own home folder:
- **None** — a plain run. The app sees your real filesystem exactly as any other program of yours does: what a shortcut hands it works, including into an app that is already running.
- **Relaxed** — the sandbox *plus* your whole filesystem mounted writable at `/tmp/plwl-fs-root`. A document handed over behaves natively — it opens where the app was told it is, it can be saved, and it also reaches an app that is already running, because the mount is there from the first second of every run. The price is real and the UI says it: at this level the app can change anything your user can.
- **Isolated** — the sandbox without that mount. The system stays read-only, and a document handed over is **copied** first, into `plwl-handoff` inside the app's own home folder; the app works on that copy (so the original cannot be touched), and a copy big enough to be noticed shows a progress popup in the launcher.
- **Relaxed** — the sandbox *plus* your whole filesystem mounted writable at `/tmp/plwl-fs-root`. A document handed over behaves natively — it opens where the app was told it is, it can be saved, and it also reaches an app that is already running, because the mount is there from the first second of every run. Your home folders are linked back into the app through that mount, so a file you drag onto the app, or pick in its own dialog, opens at its real path too. The price is real and the UI says it: at this level the app can change anything your user can.
- **Isolated** — the sandbox without that mount. The system stays read-only, and a document handed over is **copied** first, into `plwl-handoff` inside the app's own home folder; the app works on that copy (so the original cannot be touched), and a copy big enough to be noticed shows a progress popup in the launcher. There is no view of your home here, so a drop from your desktop or a file picked in a dialog cannot reach the app — only what the launcher hands over does, as that copy.
- **Automatic** (default) — Relaxed where bubblewrap works, None where it does not.
An explicit Relaxed or Isolated on a machine without a working bubblewrap **refuses to start** instead of quietly dropping the promise; Automatic is the one level allowed to weaken itself. What the app really ran as is always visible: a badge on the library card, a `[plwl] isolation: …` line in the app log, and a status card in Settings with **Check again**. When bwrap is missing, PLWL says so once instead of quietly launching without it.