try to improve link handling

This commit is contained in:
olcxja 2026-10-07 01:46:26 +02:00
commit 3f57682a9b
5 changed files with 30 additions and 14 deletions

View file

@ -252,13 +252,8 @@ function findIconFile(spec, baseDir) {
}
module.exports = {
ELF_MAGIC,
isElfBuffer,
isElfSync,
findLinuxExe,
parseDesktopEntry,
readDesktopEntry,
desktopExecPath,
desktopFileFor,
findIconFile,
pngOrSvg

View file

@ -450,6 +450,26 @@ function linuxPathFor(file) {
return abs
}
// The document a shortcut was handed. The sandbox cannot hand it over by
// itself: a file out of the user's home is buried under the prefix home, one
// out of /tmp sits behind the private tmpfs, and the rest of the machine is
// read-only. So it is mounted where the app was told it is, writable - the way
// a Wine app gets it as Z:\... and may save it. Prefix data needs nothing: it
// already is the app's own writable home.
function handedFileBinds({ openFile, root }) {
if (!openFile) return []
let abs = ''
try {
abs = fs.realpathSync(String(openFile))
if (!fs.statSync(abs).isFile()) return []
} catch {
// a path that is gone must not become a bind bwrap would refuse
return []
}
if (abs === root || abs.startsWith(root + path.sep)) return []
return [abs]
}
function bwrapSource() {
const devices = ['/dev/shm', '/dev/dri', '/dev/snd', '/dev/input'].filter(d => fs.existsSync(d))
const x11 = fs.existsSync('/tmp/.X11-unix') ? '/tmp/.X11-unix' : ''
@ -481,7 +501,7 @@ async function runLinuxGame({ game, sandbox, onExit, openFile, handoff = false }
if (chosen.backend === 'bwrap') {
const source = bwrapSource()
cmd = 'bwrap'
args = [...buildBwrapArgs({ dataRoot: root, user: source.user, devices: source.devices, x11: source.x11, runUser: source.runUser, shares: source.shares, appDir: writableAppDir(game), urlOpener: routing }), '--', exe, ...argList]
args = [...buildBwrapArgs({ dataRoot: root, user: source.user, devices: source.devices, x11: source.x11, runUser: source.runUser, shares: source.shares, appDir: writableAppDir(game), openFiles: handedFileBinds({ openFile, root }), urlOpener: routing }), '--', exe, ...argList]
header.push(`[plwl] HOME=${env.HOME}`)
}
@ -489,12 +509,7 @@ async function runLinuxGame({ game, sandbox, onExit, openFile, handoff = false }
}
module.exports = {
DATA_DIRS,
XDG_LAYOUT,
SYSTEM_DIRS,
DESKTOP_SEEDS,
DATA_SHARES,
X11_ENV,
SHIM_REL,
OPENER_REL,
MIME_REL,
@ -509,10 +524,10 @@ module.exports = {
ensureLinuxPfx,
resetSeededConfig,
dataShares,
syncDesktopConfig,
buildLinuxEnv,
pickBackend,
isolationLine,
linuxPathFor,
handedFileBinds,
runLinuxGame
}

View file

@ -115,6 +115,7 @@ function buildBwrapArgs({
etcRoot = '',
unshareNet = false,
appDir = '',
openFiles = [],
urlOpener = null
}) {
const xdgDir = sub => path.join(home, sub)
@ -152,6 +153,10 @@ function buildBwrapArgs({
'--bind', path.join(dataRoot, 'data'), xdgDir(path.join('.local', 'share')),
'--bind', path.join(dataRoot, 'cache'), xdgDir('.cache'),
'--bind', path.join(dataRoot, 'state'), xdgDir(path.join('.local', 'state')),
// a file handed over from the desktop, mounted where the app was told it
// is: the prefix home sits ON TOP of the user's real home and /tmp is
// emptied, so such a document would otherwise simply not be there
...openFiles.flatMap(file => ['--bind', file, file]),
// Wayland, PipeWire, PulseAudio and the session bus all live here
...(runUser ? ['--bind', runUser, runUser] : []),
...(etcRoot ? ['--bind', etcRoot, '/etc'] : []),
@ -164,4 +169,4 @@ function buildBwrapArgs({
]
}
module.exports = { createSandboxProbe, buildBwrapArgs, SHARE_ROOT, PROBE_TIMEOUT_MS }
module.exports = { createSandboxProbe, buildBwrapArgs, SHARE_ROOT }