[EXPERIMENTAL] linux apps support
This commit is contained in:
parent
d4996988d9
commit
e7636afe3d
20 changed files with 1377 additions and 101 deletions
|
|
@ -9,7 +9,9 @@ const library = require('../library')
|
|||
const wines = require('../wines')
|
||||
const prefixes = require('../prefixes')
|
||||
const runner = require('../runner')
|
||||
const { extractIconFromExe } = require('../icons')
|
||||
const linuxrunner = require('../linuxrunner')
|
||||
const { createSandboxProbe } = require('../sandbox')
|
||||
const { extractIconFromExe, iconFromLinuxApp } = require('../icons')
|
||||
const { createGamesService, sendToWindow } = require('./games')
|
||||
const shortcuts = require('../shortcuts')
|
||||
const openwith = require('../openwith')
|
||||
|
|
@ -34,13 +36,15 @@ function clearIconDir(id, keep) {
|
|||
} catch {}
|
||||
}
|
||||
|
||||
function extractGameIcon(id, exePath) {
|
||||
const out = path.join(iconDir(id), 'icon.ico')
|
||||
const res = extractIconFromExe(exePath, out)
|
||||
function extractGameIcon(id, exePath, kind) {
|
||||
const isLinux = kind === 'linux'
|
||||
// the Linux helper picks the extension itself (png/svg), the PE one is ico
|
||||
const out = path.join(iconDir(id), isLinux ? 'icon' : 'icon.ico')
|
||||
const res = isLinux ? iconFromLinuxApp(exePath, out) : extractIconFromExe(exePath, out)
|
||||
// on failure nothing is cleared, so the previous icon survives a wrong exe
|
||||
if (res.ok) {
|
||||
clearIconDir(id, 'icon.ico')
|
||||
library.updateGame(id, { iconSource: out })
|
||||
clearIconDir(id, path.basename(res.path))
|
||||
library.updateGame(id, { iconSource: res.path })
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
|
@ -48,7 +52,16 @@ function extractGameIcon(id, exePath) {
|
|||
// --- registration -----------------------------------------------------------
|
||||
|
||||
function registerIpc({ getWindow, onGamesChanged }) {
|
||||
const games = createGamesService({ getWindow, onGamesChanged })
|
||||
// one probe per launcher, cached: it decides bwrap vs plain run
|
||||
const sandbox = createSandboxProbe()
|
||||
const games = createGamesService({ getWindow, onGamesChanged, sandbox })
|
||||
|
||||
// sandbox --------------------------------------------------------------------
|
||||
ipcMain.handle('sandbox:status', async () => sandbox.status() || (await sandbox.probe()))
|
||||
ipcMain.handle('sandbox:probe', async () => {
|
||||
sandbox.invalidate()
|
||||
return sandbox.probe()
|
||||
})
|
||||
|
||||
// i18n ---------------------------------------------------------------------
|
||||
ipcMain.handle('i18n:list', async () => {
|
||||
|
|
@ -107,6 +120,12 @@ function registerIpc({ getWindow, onGamesChanged }) {
|
|||
return prefixes.deletePrefix(name, data => sendToWindow(getWindow(), 'import:progress', data))
|
||||
})
|
||||
ipcMain.handle('prefixes:rename', (e, oldName, newName) => prefixInUse(oldName) || prefixes.renamePrefix(oldName, newName))
|
||||
// The seeded desktop config is ours to drop (app data is not a seed), but a
|
||||
// running app would lose the files under its feet.
|
||||
ipcMain.handle('prefixes:resetLinuxConfig', (e, name) => {
|
||||
if (!prefixes.listPrefixes().prefixes.some(p => p.name === name)) return { ok: false, error: 'notFound' }
|
||||
return prefixInUse(name) || linuxrunner.resetSeededConfig(name)
|
||||
})
|
||||
ipcMain.handle('prefixes:setDefault', (e, name) => {
|
||||
// switching the default would silently move apps that follow it
|
||||
const defs = prefixes.listPrefixes()
|
||||
|
|
@ -175,7 +194,7 @@ function registerIpc({ getWindow, onGamesChanged }) {
|
|||
ipcMain.handle('games:extractIcon', (e, id) => {
|
||||
const game = library.getGame(id)
|
||||
if (!game || !game.exePath) return { ok: false, error: 'bad-request' }
|
||||
return extractGameIcon(id, game.exePath)
|
||||
return extractGameIcon(id, game.exePath, game.kind)
|
||||
})
|
||||
// use the exe the field holds (maybe picked but not saved yet)
|
||||
ipcMain.handle('games:autoIcon', (e, id, exePath) => {
|
||||
|
|
@ -183,7 +202,19 @@ function registerIpc({ getWindow, onGamesChanged }) {
|
|||
if (!game) return { ok: false, error: 'bad-request' }
|
||||
const exe = exePath || game.exePath
|
||||
if (!exe) return { ok: false, error: 'bad-request' }
|
||||
return extractGameIcon(id, exe)
|
||||
return extractGameIcon(id, exe, game.kind)
|
||||
})
|
||||
// Linux apps keep their data next to the prefix's Windows side
|
||||
ipcMain.handle('games:openDataFolder', async (e, id) => {
|
||||
const game = library.getGame(id)
|
||||
if (!library.isLinuxGame(game)) return { ok: false, error: 'not-linux' }
|
||||
try {
|
||||
const root = linuxrunner.ensureLinuxPfx(library.prefixNameForGame(game))
|
||||
const err = await shell.openPath(root)
|
||||
return err ? { ok: false, error: err } : { ok: true, path: root }
|
||||
} catch (err) {
|
||||
return errorResult(err)
|
||||
}
|
||||
})
|
||||
|
||||
// "Open with PLWL" ------------------------------------------------------------------
|
||||
|
|
@ -226,9 +257,9 @@ function registerIpc({ getWindow, onGamesChanged }) {
|
|||
})
|
||||
return res.canceled || !res.filePaths[0] ? null : res.filePaths[0]
|
||||
})
|
||||
ipcMain.handle('games:import', async (e, srcDir, mode) => {
|
||||
ipcMain.handle('games:import', async (e, srcDir, mode, kind) => {
|
||||
try {
|
||||
return await games.import(getWindow(), srcDir, mode)
|
||||
return await games.import(getWindow(), srcDir, mode, kind)
|
||||
} catch (err) {
|
||||
return errorResult(err)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue