fix(electron): require TerminalEmulator category for terminal appId on Linux
desktopEntryMatchesApp used a loose substring match that accepted any desktop entry whose Exec line mentioned a terminal launcher. A non- terminal app launched via xdg-terminal-exec (e.g. a TUI helper) was mis-attributed to the generic 'terminal' appId, so 'Open in Terminal' launched the helper script and the picker showed the helper's icon. For appId === 'terminal' only, require Categories=TerminalEmulator; ghostty/iterm2 keep name-based matching. The xdg-terminal-exec / gnome-terminal / konsole / xfce4-terminal / x-terminal-emulator fallback chain is unchanged, so non-conformant custom terminal entries still launch. Adds a shared isTerminalEmulatorEntry predicate used by both buildLinuxOpenSpecs (launch) and buildLinuxInstalledApps (icon). Smoke test gains a generic helper-app fixture (non-terminal app whose Exec uses xdg-terminal-exec) plus a TerminalEmulator entry, with assertions that the helper script is never launched and the terminal emulator's icon resolves instead of the helper's. Two byte-distinct PNGs keep the icon assertion a real discriminator.
This commit is contained in:
@@ -234,6 +234,11 @@ const commandExists = (program, env = process.env) => {
|
||||
|
||||
const findEntry = (entries, appId, appName) => entries.find((entry) => desktopEntryMatchesApp(entry, appName, appId)) || null;
|
||||
|
||||
const isTerminalEmulatorEntry = (entry) => {
|
||||
const categories = Array.isArray(entry?.categories) ? entry.categories : [];
|
||||
return categories.some((category) => normalizeComparable(category) === 'terminalemulator');
|
||||
};
|
||||
|
||||
export const buildLinuxOpenSpecs = ({ targetPath, appId, appName, targetKind = 'path', entries = [], env = process.env }) => {
|
||||
if (appId === 'finder') {
|
||||
return [{ kind: 'default', targetKind, targetPath }];
|
||||
@@ -241,7 +246,9 @@ export const buildLinuxOpenSpecs = ({ targetPath, appId, appName, targetKind = '
|
||||
const specs = [];
|
||||
if (TERMINAL_APP_IDS.has(appId)) {
|
||||
const directory = targetKind === 'file' ? path.dirname(targetPath) : targetPath;
|
||||
const terminalEntry = findEntry(entries, appId, appName);
|
||||
const terminalEntry = appId === 'terminal'
|
||||
? entries.find(isTerminalEmulatorEntry) || null
|
||||
: findEntry(entries, appId, appName);
|
||||
if (terminalEntry) {
|
||||
const spec = buildCommandFromDesktopExec(terminalEntry, directory);
|
||||
if (spec) specs.push(spec);
|
||||
@@ -515,7 +522,7 @@ export const buildLinuxInstalledApps = async (apps, options = {}) => {
|
||||
...FILE_MANAGER_ICON_FALLBACKS,
|
||||
], { ...options, env });
|
||||
} else if (normalizeComparable(name) === 'terminal') {
|
||||
const terminalEntry = findEntry(entries, 'terminal', name)
|
||||
const terminalEntry = entries.find(isTerminalEmulatorEntry)
|
||||
|| findEntry(entries, 'ghostty', 'Ghostty');
|
||||
iconDataUrl = resolveIconDataUrlForName([
|
||||
terminalEntry?.icon,
|
||||
|
||||
Reference in New Issue
Block a user