fix: resolve Arch/Wayland tray issues by enabling Ozone Wayland and hardening icon resolution paths
This commit is contained in:
@@ -16,6 +16,12 @@ const isDev = !app.isPackaged;
|
||||
|
||||
app.name = "Ultimate Ban Tracker";
|
||||
|
||||
// Force Wayland/Ozone support if on Linux
|
||||
if (process.platform === 'linux') {
|
||||
app.commandLine.appendSwitch('enable-features', 'UseOzonePlatform');
|
||||
app.commandLine.appendSwitch('ozone-platform', 'wayland');
|
||||
}
|
||||
|
||||
// Load environment variables
|
||||
dotenv.config({ path: path.join(app.getAppPath(), '..', '.env') });
|
||||
|
||||
@@ -89,35 +95,64 @@ const initBackend = () => {
|
||||
|
||||
// --- System Tray ---
|
||||
const createTray = () => {
|
||||
console.log('[Tray] Initializing...');
|
||||
|
||||
const possiblePaths = [
|
||||
'/usr/share/pixmaps/ultimate-ban-tracker.png',
|
||||
path.join(process.resourcesPath, 'assets-build', 'icon.png'),
|
||||
path.join(app.getAppPath(), 'assets-build', 'icon.png'),
|
||||
path.join(__dirname, '..', 'assets-build', 'icon.png')
|
||||
'/usr/share/pixmaps/ultimate-ban-tracker.png', // Priority 1: System installed
|
||||
path.join(process.resourcesPath, 'assets-build', 'icon.png'), // Priority 2: Unpacked resources
|
||||
path.join(app.getAppPath(), 'assets-build', 'icon.png'), // Priority 3: Internal ASAR (Fallback)
|
||||
path.join(__dirname, '..', 'assets-build', 'icon.png') // Priority 4: Dev
|
||||
];
|
||||
|
||||
let iconPath = '';
|
||||
for (const p of possiblePaths) { if (p && fs.existsSync(p)) { iconPath = p; break; } }
|
||||
for (const p of possiblePaths) {
|
||||
console.log(`[Tray] Checking path: ${p}`);
|
||||
if (p && fs.existsSync(p)) {
|
||||
iconPath = p;
|
||||
console.log(`[Tray] Found icon at: ${p}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!iconPath) { try { tray = new Tray(nativeImage.createEmpty()); } catch (e) {} return; }
|
||||
if (!iconPath) {
|
||||
console.warn('[Tray] FAILED: No icon file found on disk. Using empty fallback.');
|
||||
try { tray = new Tray(nativeImage.createEmpty()); } catch (e) {}
|
||||
} else {
|
||||
try {
|
||||
const icon = nativeImage.createFromPath(iconPath).resize({ width: 16, height: 16 });
|
||||
tray = new Tray(icon);
|
||||
console.log('[Tray] Tray object created successfully');
|
||||
} catch (e: any) {
|
||||
console.error(`[Tray] Failed to create Tray object: ${e.message}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const icon = nativeImage.createFromPath(iconPath).resize({ width: 16, height: 16 });
|
||||
tray = new Tray(icon);
|
||||
if (tray) {
|
||||
tray.setToolTip('Ultimate Ban Tracker');
|
||||
if (process.platform === 'linux') tray.setIgnoreMouseEvents(false);
|
||||
tray.on('click', () => { if (mainWindow) { mainWindow.show(); mainWindow.focus(); } });
|
||||
|
||||
// Initial menu build
|
||||
updateTrayMenu();
|
||||
|
||||
const config = store.get('serverConfig');
|
||||
if (config?.theme) setAppIcon(config.theme);
|
||||
} catch (e: any) { console.error(`[Tray] Error: ${e.message}`); }
|
||||
}
|
||||
};
|
||||
|
||||
const updateTrayMenu = () => {
|
||||
if (!tray) return;
|
||||
if (!tray) {
|
||||
console.warn('[Tray] Cannot update menu: Tray is null');
|
||||
return;
|
||||
}
|
||||
|
||||
const accounts = store.get('accounts') as Account[];
|
||||
const config = store.get('serverConfig');
|
||||
const contextMenu = Menu.buildFromTemplate([
|
||||
|
||||
console.log(`[Tray] Building menu with ${accounts.length} accounts...`);
|
||||
|
||||
const menuTemplate: any[] = [
|
||||
{ label: `Ultimate Ban Tracker v${app.getVersion()}`, enabled: false },
|
||||
{ type: 'separator' },
|
||||
{
|
||||
@@ -125,34 +160,83 @@ const updateTrayMenu = () => {
|
||||
submenu: accounts.length > 0 ? accounts.map(acc => ({
|
||||
label: `${acc.personaName} ${acc.loginName ? `(${acc.loginName})` : ''}`,
|
||||
enabled: !!acc.loginName,
|
||||
click: () => handleSwitchAccount(acc.loginName)
|
||||
})) : [{ label: 'No accounts found', enabled: false }]
|
||||
click: () => {
|
||||
console.log(`[Tray] Switching to account: ${acc.loginName}`);
|
||||
handleSwitchAccount(acc.loginName);
|
||||
}
|
||||
})) : [{ label: 'No accounts tracked', enabled: false }]
|
||||
},
|
||||
{
|
||||
label: 'Sync Now',
|
||||
enabled: !!config?.enabled,
|
||||
click: () => {
|
||||
console.log('[Tray] Manual sync requested');
|
||||
syncAccounts(true);
|
||||
}
|
||||
},
|
||||
{ label: 'Sync Now', enabled: !!config?.enabled, click: () => syncAccounts(true) },
|
||||
{ type: 'separator' },
|
||||
{ label: 'Show Dashboard', click: () => { if (mainWindow) { mainWindow.show(); mainWindow.focus(); } } },
|
||||
{ label: 'Quit', click: () => {
|
||||
(app as any).isQuitting = true;
|
||||
if (tray) tray.destroy();
|
||||
app.quit();
|
||||
} }
|
||||
]);
|
||||
tray.setContextMenu(contextMenu);
|
||||
{
|
||||
label: 'Show Dashboard',
|
||||
click: () => {
|
||||
console.log('[Tray] Showing dashboard');
|
||||
if (mainWindow) {
|
||||
mainWindow.show();
|
||||
mainWindow.focus();
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Quit',
|
||||
click: () => {
|
||||
console.log('[Tray] Quitting application via menu');
|
||||
(app as any).isQuitting = true;
|
||||
if (tray) tray.destroy();
|
||||
app.quit();
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
try {
|
||||
const contextMenu = Menu.buildFromTemplate(menuTemplate);
|
||||
tray.setContextMenu(contextMenu);
|
||||
console.log('[Tray] Menu updated and attached');
|
||||
} catch (e: any) {
|
||||
console.error(`[Tray] Failed to build or set context menu: ${e.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
const setAppIcon = (themeName: string = 'steam') => {
|
||||
console.log(`[AppIcon] Setting icon for theme: ${themeName}`);
|
||||
const possiblePaths = [
|
||||
path.join(__dirname, '..', 'assets-build', 'icons', `${themeName}.svg`),
|
||||
path.join(app.getAppPath(), 'assets-build', 'icons', `${themeName}.svg`),
|
||||
path.join(__dirname, '..', 'assets-build', 'icons', `${themeName}.svg`),
|
||||
path.join(process.resourcesPath, 'assets-build', 'icons', `${themeName}.svg`),
|
||||
'/usr/share/pixmaps/ultimate-ban-tracker.png'
|
||||
];
|
||||
|
||||
let iconPath = '';
|
||||
for (const p of possiblePaths) { if (fs.existsSync(p)) { iconPath = p; break; } }
|
||||
if (!iconPath) return;
|
||||
const icon = nativeImage.createFromPath(iconPath);
|
||||
if (tray) tray.setImage(icon.resize({ width: 16, height: 16 }));
|
||||
if (mainWindow) mainWindow.setIcon(icon);
|
||||
updateTrayMenu();
|
||||
for (const p of possiblePaths) { if (p && fs.existsSync(p)) { iconPath = p; break; } }
|
||||
|
||||
if (!iconPath) {
|
||||
console.warn(`[AppIcon] No themed icon found for ${themeName}`);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const icon = nativeImage.createFromPath(iconPath);
|
||||
if (tray) {
|
||||
tray.setImage(icon.resize({ width: 16, height: 16 }));
|
||||
console.log('[AppIcon] Tray icon updated');
|
||||
}
|
||||
if (mainWindow) {
|
||||
mainWindow.setIcon(icon);
|
||||
console.log('[AppIcon] Window icon updated');
|
||||
}
|
||||
// Re-build menu to ensure everything is consistent
|
||||
updateTrayMenu();
|
||||
} catch (e: any) {
|
||||
console.error(`[AppIcon] Failed to apply themed icon: ${e.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
// --- Steam Logic ---
|
||||
|
||||
Reference in New Issue
Block a user