diff --git a/appicons/icons/mac/icon.icns b/appicons/icons/mac/icon.icns index ae2b34c..180b321 100644 Binary files a/appicons/icons/mac/icon.icns and b/appicons/icons/mac/icon.icns differ diff --git a/appicons/icons/png/1024x1024.png b/appicons/icons/png/1024x1024.png index ece694a..b7016a3 100644 Binary files a/appicons/icons/png/1024x1024.png and b/appicons/icons/png/1024x1024.png differ diff --git a/appicons/icons/png/128x128.png b/appicons/icons/png/128x128.png index 38728ab..b6a3661 100644 Binary files a/appicons/icons/png/128x128.png and b/appicons/icons/png/128x128.png differ diff --git a/appicons/icons/png/16x16.png b/appicons/icons/png/16x16.png index 1dfd000..5c36d87 100644 Binary files a/appicons/icons/png/16x16.png and b/appicons/icons/png/16x16.png differ diff --git a/appicons/icons/png/24x24.png b/appicons/icons/png/24x24.png index 3772d7c..936a4bc 100644 Binary files a/appicons/icons/png/24x24.png and b/appicons/icons/png/24x24.png differ diff --git a/appicons/icons/png/256x256.png b/appicons/icons/png/256x256.png index 84079cd..856ead7 100644 Binary files a/appicons/icons/png/256x256.png and b/appicons/icons/png/256x256.png differ diff --git a/appicons/icons/png/32x32.png b/appicons/icons/png/32x32.png index be79911..d18caad 100644 Binary files a/appicons/icons/png/32x32.png and b/appicons/icons/png/32x32.png differ diff --git a/appicons/icons/png/48x48.png b/appicons/icons/png/48x48.png index 7ba93d3..e0f94b7 100644 Binary files a/appicons/icons/png/48x48.png and b/appicons/icons/png/48x48.png differ diff --git a/appicons/icons/png/512x512.png b/appicons/icons/png/512x512.png index 912b2d1..08fde8c 100644 Binary files a/appicons/icons/png/512x512.png and b/appicons/icons/png/512x512.png differ diff --git a/appicons/icons/png/64x64.png b/appicons/icons/png/64x64.png index d2f9890..dd8e729 100644 Binary files a/appicons/icons/png/64x64.png and b/appicons/icons/png/64x64.png differ diff --git a/appicons/icons/win/icon.ico b/appicons/icons/win/icon.ico index f8f0cdc..32ee66e 100644 Binary files a/appicons/icons/win/icon.ico and b/appicons/icons/win/icon.ico differ diff --git a/appicons/trimsp-icon-modern.svg b/appicons/trimsp-icon-modern.svg new file mode 100644 index 0000000..0db8770 --- /dev/null +++ b/appicons/trimsp-icon-modern.svg @@ -0,0 +1,50 @@ + + + TRIMSP-NL Workbench icon + An orange particle trajectory stopping as a spin-polarized muon inside a layered teal target. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/icon.png b/icon.png index d8b9e3e..b7016a3 100644 Binary files a/icon.png and b/icon.png differ diff --git a/main.js b/main.js index 9176b8f..489fd06 100644 --- a/main.js +++ b/main.js @@ -1,12 +1,50 @@ const path = require('path'); const fs = require('fs'); -const { app, BrowserWindow, Menu, dialog, ipcMain } = require('electron'); +const { spawnSync } = require('child_process'); +const { app, BrowserWindow, Menu, dialog, ipcMain, nativeImage } = require('electron'); let currentWorkPath = process.cwd(); const startupOptions = parseStartupOptions(process.argv); -// Keep the internal Linux window class stable for existing desktop launchers. -app.setName('TrimSP'); +// Packaged builds retain the class expected by installed desktop launchers. +// A distinct development class prevents npm start from inheriting the icon +// cached for an older system installation of TrimSP. +app.setName(app.isPackaged ? 'TrimSP' : 'TrimSPDev'); +if (process.platform === 'linux' && !app.isPackaged) { + // KDE resolves taskbar icons through matching desktop entries and ignores + // Electron's development-window icon. Keep a hidden per-user entry tied + // to this checkout so npm start uses the current repository artwork. + try { + const dataHome = process.env.XDG_DATA_HOME || path.join(app.getPath('home'), '.local', 'share'); + const applicationsDir = path.join(dataHome, 'applications'); + const desktopFile = path.join(applicationsDir, 'trimsp-dev.desktop'); + const executable = process.execPath.replace(/"/g, '\\"'); + const projectPath = __dirname.replace(/"/g, '\\"'); + const iconPath = path.join(__dirname, 'icon.png'); + const desktopContent = [ + '[Desktop Entry]', + 'Type=Application', + 'Name=TRIMSP-NL Workbench (Development)', + `Exec="${executable}" "${projectPath}"`, + `Icon=${iconPath}`, + `X-TrimSP-Icon-MTime=${fs.statSync(iconPath).mtimeMs}`, + 'StartupWMClass=TrimSPDev', + 'NoDisplay=true', + 'Categories=Science;', + '', + ].join('\n'); + fs.mkdirSync(applicationsDir, {recursive: true}); + if (!fs.existsSync(desktopFile) || fs.readFileSync(desktopFile, 'utf8') !== desktopContent) { + fs.writeFileSync(desktopFile, desktopContent, 'utf8'); + // KDE caches desktop identities and icons; refresh that user cache only + // when this entry changes. Other desktops safely ignore ENOENT here. + spawnSync('kbuildsycoca6', ['--noincremental'], {stdio: 'ignore'}); + } + app.setDesktopName('trimsp-dev.desktop'); + } catch (error) { + console.warn('Could not register the development desktop entry:', error); + } +} function parseStartupOptions(argv) { const options = { @@ -152,10 +190,11 @@ function getWindowIconPath() { } function createWindow () { + const windowIcon = nativeImage.createFromPath(getWindowIconPath()); const win = new BrowserWindow({ width: 1000, height: 610, - icon: getWindowIconPath(), + icon: windowIcon, webPreferences: { contextIsolation: false, nodeIntegration: true, @@ -164,6 +203,13 @@ function createWindow () { } }) + // Pass a native image explicitly for Linux panels that can use the window + // icon directly. KDE resolves the development icon through the matching + // desktop entry registered above. + if (process.platform === 'linux' && !windowIcon.isEmpty()) { + win.setIcon(windowIcon); + } + let template = [ { label: 'File',