fix: click-through HUD, tray icon fallback, toggle shortcut, ESC handler
- hud.js: setIgnoreMouseEvents when inactive, alwaysOnTop only when active, backgroundColor #00000000, no visibleOnAllWorkspaces, toggleHud export - tray.js: onToggle callback, isEmpty() fallback icon, click toggles - preload.js: ESC listener at capture phase — works without HUD page changes - main.js: Cmd+Shift+F toggles, import toggleHud, pass onToggle to tray Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>main
parent
1189f6000c
commit
dc7e888ee3
|
|
@ -5,6 +5,7 @@ const HUD_URL = process.env.FOX_HUD_URL || 'https://fox.pxo.at/hud';
|
|||
let hudWindow = null;
|
||||
let hudLoaded = false;
|
||||
let pendingShow = false;
|
||||
let hudActive = false;
|
||||
|
||||
function createHud() {
|
||||
const { width, height } = screen.getPrimaryDisplay().workAreaSize;
|
||||
|
|
@ -16,7 +17,8 @@ function createHud() {
|
|||
y: 0,
|
||||
frame: false,
|
||||
transparent: true,
|
||||
alwaysOnTop: true,
|
||||
backgroundColor: '#00000000',
|
||||
alwaysOnTop: false,
|
||||
show: false,
|
||||
skipTaskbar: true,
|
||||
hasShadow: false,
|
||||
|
|
@ -29,14 +31,14 @@ function createHud() {
|
|||
},
|
||||
});
|
||||
|
||||
hudWindow.setAlwaysOnTop(true, 'screen-saver');
|
||||
hudWindow.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true });
|
||||
// Unsichtbar und click-through bis aktiv
|
||||
hudWindow.setIgnoreMouseEvents(true);
|
||||
|
||||
hudWindow.webContents.once('did-finish-load', () => {
|
||||
hudLoaded = true;
|
||||
if (pendingShow) {
|
||||
pendingShow = false;
|
||||
hudWindow.webContents.send('hud-show');
|
||||
_activateHud();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -46,28 +48,47 @@ function createHud() {
|
|||
hudWindow = null;
|
||||
hudLoaded = false;
|
||||
pendingShow = false;
|
||||
hudActive = false;
|
||||
});
|
||||
|
||||
return hudWindow;
|
||||
}
|
||||
|
||||
function _activateHud() {
|
||||
hudActive = true;
|
||||
hudWindow.setIgnoreMouseEvents(false);
|
||||
hudWindow.setAlwaysOnTop(true, 'screen-saver');
|
||||
hudWindow.webContents.send('hud-show');
|
||||
}
|
||||
|
||||
function showHud() {
|
||||
if (!hudWindow) createHud();
|
||||
hudWindow.show();
|
||||
hudWindow.focus();
|
||||
if (hudLoaded) {
|
||||
hudWindow.webContents.send('hud-show');
|
||||
_activateHud();
|
||||
} else {
|
||||
pendingShow = true;
|
||||
}
|
||||
}
|
||||
|
||||
function hideHud() {
|
||||
if (!hudWindow) return;
|
||||
if (!hudWindow || !hudActive) return;
|
||||
hudActive = false;
|
||||
hudWindow.setAlwaysOnTop(false);
|
||||
hudWindow.setIgnoreMouseEvents(true);
|
||||
hudWindow.webContents.send('hud-hide');
|
||||
setTimeout(() => {
|
||||
if (hudWindow) hudWindow.hide();
|
||||
}, 600);
|
||||
}
|
||||
|
||||
module.exports = { createHud, showHud, hideHud };
|
||||
function toggleHud() {
|
||||
if (hudActive) {
|
||||
hideHud();
|
||||
} else {
|
||||
showHud();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { createHud, showHud, hideHud, toggleHud };
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
const { app, ipcMain, globalShortcut, nativeTheme } = require('electron');
|
||||
const { createTray } = require('./tray');
|
||||
const { createHud, showHud, hideHud } = require('./hud');
|
||||
const { createHud, showHud, hideHud, toggleHud } = require('./hud');
|
||||
const { startWakeword, stopWakeword } = require('./wakeword');
|
||||
const { executeMacCommand } = require('./mac-agent');
|
||||
const axios = require('axios');
|
||||
|
|
@ -19,12 +19,13 @@ app.whenReady().then(() => {
|
|||
createHud();
|
||||
|
||||
createTray({
|
||||
onShow: showHud,
|
||||
onToggle: toggleHud,
|
||||
onHide: hideHud,
|
||||
onQuit: () => app.quit(),
|
||||
});
|
||||
|
||||
globalShortcut.register('CommandOrControl+Shift+F', showHud);
|
||||
// Cmd+Shift+F togglet HUD
|
||||
globalShortcut.register('CommandOrControl+Shift+F', toggleHud);
|
||||
|
||||
startWakeword({ onWake: showHud });
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
const { contextBridge, ipcRenderer } = require('electron');
|
||||
|
||||
// ESC schließt HUD — funktioniert unabhängig vom HUD-JavaScript
|
||||
window.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape') ipcRenderer.send('hide-hud');
|
||||
}, true);
|
||||
|
||||
contextBridge.exposeInMainWorld('foxBridge', {
|
||||
sendMessage: (text) => ipcRenderer.send('send-message', text),
|
||||
hideHud: () => ipcRenderer.send('hide-hud'),
|
||||
|
|
|
|||
|
|
@ -3,22 +3,31 @@ const path = require('path');
|
|||
|
||||
let tray = null;
|
||||
|
||||
function createTray({ onShow, onHide, onQuit }) {
|
||||
function createTray({ onToggle, onHide, onQuit }) {
|
||||
const iconPath = path.join(__dirname, '../assets/fox-tray.png');
|
||||
const icon = nativeImage.createFromPath(iconPath);
|
||||
let icon = nativeImage.createFromPath(iconPath);
|
||||
|
||||
if (icon.isEmpty()) {
|
||||
console.warn('[Tray] Icon nicht gefunden:', iconPath, '— Fallback auf leeres Icon');
|
||||
// Minimales 1x1 schwarzes Template-PNG als Fallback
|
||||
icon = nativeImage.createFromDataURL(
|
||||
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=='
|
||||
);
|
||||
}
|
||||
|
||||
icon.setTemplateImage(true);
|
||||
|
||||
tray = new Tray(icon);
|
||||
tray.setToolTip('Fox');
|
||||
|
||||
tray.setContextMenu(Menu.buildFromTemplate([
|
||||
{ label: 'Fox öffnen', accelerator: 'Cmd+Shift+F', click: onShow },
|
||||
{ label: 'Fox öffnen/schließen', accelerator: 'Cmd+Shift+F', click: onToggle },
|
||||
{ label: 'Fox verstecken', click: onHide },
|
||||
{ type: 'separator' },
|
||||
{ label: 'Beenden', click: onQuit },
|
||||
]));
|
||||
|
||||
tray.on('click', onShow);
|
||||
tray.on('click', onToggle);
|
||||
|
||||
return tray;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue