From ecca7ddf99ad533076adc07da515f24fd8935469 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Tue, 21 Jan 2025 14:13:53 +0100 Subject: [PATCH] fix: menubar tray state (#156) --- .../dist/server/api/menuBar.js | 115 ++++++++------- .../js/electron-plugin/dist/server/state.js | 1 + .../electron-plugin/src/server/api/menuBar.ts | 133 ++++++++++-------- .../js/electron-plugin/src/server/state.ts | 4 +- 4 files changed, 143 insertions(+), 110 deletions(-) diff --git a/resources/js/electron-plugin/dist/server/api/menuBar.js b/resources/js/electron-plugin/dist/server/api/menuBar.js index 6095eff..2cfe44f 100644 --- a/resources/js/electron-plugin/dist/server/api/menuBar.js +++ b/resources/js/electron-plugin/dist/server/api/menuBar.js @@ -10,22 +10,22 @@ const router = express.Router(); router.post("/label", (req, res) => { res.sendStatus(200); const { label } = req.body; - state.activeMenuBar.tray.setTitle(label); + state.tray.setTitle(label); }); router.post("/tooltip", (req, res) => { res.sendStatus(200); const { tooltip } = req.body; - state.activeMenuBar.tray.setToolTip(tooltip); + state.tray.setToolTip(tooltip); }); router.post("/icon", (req, res) => { res.sendStatus(200); const { icon } = req.body; - state.activeMenuBar.tray.setImage(icon); + state.tray.setImage(icon); }); router.post("/context-menu", (req, res) => { res.sendStatus(200); const { contextMenu } = req.body; - state.activeMenuBar.tray.setContextMenu(buildMenu(contextMenu)); + state.tray.setContextMenu(buildMenu(contextMenu)); }); router.post("/show", (req, res) => { res.sendStatus(200); @@ -47,6 +47,9 @@ router.post("/create", (req, res) => { const tray = new Tray(icon || state.icon.replace("icon.png", "IconTemplate.png")); tray.setContextMenu(buildMenu(contextMenu)); tray.setToolTip(tooltip); + tray.setTitle(label); + eventsForTray(tray, onlyShowContextMenu, contextMenu, shouldSendCreatedEvent); + state.tray = tray; if (!showDockIcon) { app.dock.hide(); } @@ -80,66 +83,70 @@ router.post("/create", (req, res) => { state.activeMenuBar.on("after-create-window", () => { enable(state.activeMenuBar.window.webContents); }); - } - state.activeMenuBar.on("ready", () => { - state.activeMenuBar.tray.setTitle(label); - if (shouldSendCreatedEvent) { - notifyLaravel("events", { - event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarCreated" + state.activeMenuBar.on("ready", () => { + eventsForTray(state.activeMenuBar.tray, onlyShowContextMenu, contextMenu, shouldSendCreatedEvent); + state.tray = state.activeMenuBar.tray; + state.tray.setTitle(label); + state.activeMenuBar.on("hide", () => { + notifyLaravel("events", { + event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarHidden" + }); }); - } - state.activeMenuBar.on("hide", () => { - notifyLaravel("events", { - event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarHidden" + state.activeMenuBar.on("show", () => { + notifyLaravel("events", { + event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarShown" + }); }); }); - state.activeMenuBar.on("show", () => { - notifyLaravel("events", { - event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarShown" - }); + } +}); +function eventsForTray(tray, onlyShowContextMenu, contextMenu, shouldSendCreatedEvent) { + if (shouldSendCreatedEvent) { + notifyLaravel("events", { + event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarCreated" }); - state.activeMenuBar.tray.on("drop-files", (event, files) => { - notifyLaravel("events", { - event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarDroppedFiles", - payload: [ - files - ] - }); + } + tray.on("drop-files", (event, files) => { + notifyLaravel("events", { + event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarDroppedFiles", + payload: [ + files + ] }); - state.activeMenuBar.tray.on('click', (combo, bounds, position) => { - notifyLaravel('events', { - event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarClicked", - payload: { - combo, - bounds, - position, - }, - }); + }); + tray.on('click', (combo, bounds, position) => { + notifyLaravel('events', { + event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarClicked", + payload: { + combo, + bounds, + position, + }, }); - state.activeMenuBar.tray.on("right-click", (combo, bounds) => { - notifyLaravel("events", { - event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarRightClicked", - payload: { - combo, - bounds, - } - }); - if (!onlyShowContextMenu) { - state.activeMenuBar.hideWindow(); - state.activeMenuBar.tray.popUpContextMenu(buildMenu(contextMenu)); + }); + tray.on("right-click", (combo, bounds) => { + notifyLaravel("events", { + event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarRightClicked", + payload: { + combo, + bounds, } }); - state.activeMenuBar.tray.on('double-click', (combo, bounds) => { - notifyLaravel('events', { - event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarDoubleClicked", - payload: { - combo, - bounds, - }, - }); + if (!onlyShowContextMenu) { + state.activeMenuBar.hideWindow(); + tray.popUpContextMenu(buildMenu(contextMenu)); + } + }); + tray.on('double-click', (combo, bounds) => { + notifyLaravel('events', { + event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarDoubleClicked", + payload: { + combo, + bounds, + }, }); }); -}); +} function buildMenu(contextMenu) { let menu = Menu.buildFromTemplate([{ role: "quit" }]); if (contextMenu) { diff --git a/resources/js/electron-plugin/dist/server/state.js b/resources/js/electron-plugin/dist/server/state.js index 1331ffd..2f9bab8 100644 --- a/resources/js/electron-plugin/dist/server/state.js +++ b/resources/js/electron-plugin/dist/server/state.js @@ -25,6 +25,7 @@ function generateRandomString(length) { export default { electronApiPort: null, activeMenuBar: null, + tray: null, php: null, phpPort: null, phpIni: null, diff --git a/resources/js/electron-plugin/src/server/api/menuBar.ts b/resources/js/electron-plugin/src/server/api/menuBar.ts index d807f81..52260d2 100644 --- a/resources/js/electron-plugin/src/server/api/menuBar.ts +++ b/resources/js/electron-plugin/src/server/api/menuBar.ts @@ -14,7 +14,7 @@ router.post("/label", (req, res) => { const { label } = req.body; - state.activeMenuBar.tray.setTitle(label); + state.tray.setTitle(label); }); router.post("/tooltip", (req, res) => { @@ -22,7 +22,7 @@ router.post("/tooltip", (req, res) => { const { tooltip } = req.body; - state.activeMenuBar.tray.setToolTip(tooltip); + state.tray.setToolTip(tooltip); }); router.post("/icon", (req, res) => { @@ -30,7 +30,7 @@ router.post("/icon", (req, res) => { const { icon } = req.body; - state.activeMenuBar.tray.setImage(icon); + state.tray.setImage(icon); }); router.post("/context-menu", (req, res) => { @@ -38,7 +38,7 @@ router.post("/context-menu", (req, res) => { const { contextMenu } = req.body; - state.activeMenuBar.tray.setContextMenu(buildMenu(contextMenu)); + state.tray.setContextMenu(buildMenu(contextMenu)); }); router.post("/show", (req, res) => { @@ -84,14 +84,24 @@ router.post("/create", (req, res) => { if (onlyShowContextMenu) { + // Create a tray icon const tray = new Tray(icon || state.icon.replace("icon.png", "IconTemplate.png")); + // Set the context menu tray.setContextMenu(buildMenu(contextMenu)); tray.setToolTip(tooltip); + tray.setTitle(label); + + // Set the event listeners + send created event + eventsForTray(tray, onlyShowContextMenu, contextMenu, shouldSendCreatedEvent); + + // Set the tray to the state + state.tray = tray; if (!showDockIcon) { app.dock.hide(); } + } else { state.activeMenuBar = menubar({ icon: icon || state.icon.replace("icon.png", "IconTemplate.png"), @@ -122,76 +132,89 @@ router.post("/create", (req, res) => { state.activeMenuBar.on("after-create-window", () => { enable(state.activeMenuBar.window.webContents); }); - } - state.activeMenuBar.on("ready", () => { + state.activeMenuBar.on("ready", () => { + // Set the event listeners + eventsForTray(state.activeMenuBar.tray, onlyShowContextMenu, contextMenu, shouldSendCreatedEvent); - state.activeMenuBar.tray.setTitle(label); + // Set the tray to the state + state.tray = state.activeMenuBar.tray; - if (shouldSendCreatedEvent) { - notifyLaravel("events", { - event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarCreated" - }); - } + // Set the title + state.tray.setTitle(label); - state.activeMenuBar.on("hide", () => { - notifyLaravel("events", { - event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarHidden" + state.activeMenuBar.on("hide", () => { + notifyLaravel("events", { + event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarHidden" + }); }); - }); - state.activeMenuBar.on("show", () => { - notifyLaravel("events", { - event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarShown" + state.activeMenuBar.on("show", () => { + notifyLaravel("events", { + event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarShown" + }); }); + }); + } - state.activeMenuBar.tray.on("drop-files", (event, files) => { - notifyLaravel("events", { - event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarDroppedFiles", - payload: [ - files - ] - }); +}); + + + +function eventsForTray(tray, onlyShowContextMenu, contextMenu, shouldSendCreatedEvent) { + + if (shouldSendCreatedEvent) { + notifyLaravel("events", { + event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarCreated" }); + } - state.activeMenuBar.tray.on('click', (combo, bounds, position) => { - notifyLaravel('events', { - event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarClicked", - payload: { - combo, - bounds, - position, - }, - }); + tray.on("drop-files", (event, files) => { + notifyLaravel("events", { + event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarDroppedFiles", + payload: [ + files + ] }); + }); - state.activeMenuBar.tray.on("right-click", (combo, bounds) => { - notifyLaravel("events", { - event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarRightClicked", - payload: { - combo, - bounds, - } - }); + tray.on('click', (combo, bounds, position) => { + notifyLaravel('events', { + event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarClicked", + payload: { + combo, + bounds, + position, + }, + }); + }); - if (! onlyShowContextMenu) { - state.activeMenuBar.hideWindow(); - state.activeMenuBar.tray.popUpContextMenu(buildMenu(contextMenu)); + tray.on("right-click", (combo, bounds) => { + notifyLaravel("events", { + event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarRightClicked", + payload: { + combo, + bounds, } }); - state.activeMenuBar.tray.on('double-click', (combo, bounds) => { - notifyLaravel('events', { - event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarDoubleClicked", - payload: { - combo, - bounds, - }, - }); + if (!onlyShowContextMenu) { + state.activeMenuBar.hideWindow(); + tray.popUpContextMenu(buildMenu(contextMenu)); + } + }); + + tray.on('double-click', (combo, bounds) => { + notifyLaravel('events', { + event: "\\Native\\Laravel\\Events\\MenuBar\\MenuBarDoubleClicked", + payload: { + combo, + bounds, + }, }); }); -}); +} function buildMenu(contextMenu) { let menu = Menu.buildFromTemplate([{ role: "quit" }]); diff --git a/resources/js/electron-plugin/src/server/state.ts b/resources/js/electron-plugin/src/server/state.ts index 6afa314..11937f5 100644 --- a/resources/js/electron-plugin/src/server/state.ts +++ b/resources/js/electron-plugin/src/server/state.ts @@ -1,4 +1,4 @@ -import { BrowserWindow, UtilityProcess } from "electron"; +import {BrowserWindow, Tray, UtilityProcess} from "electron"; import Store from "electron-store"; import { notifyLaravel } from "./utils.js"; @@ -23,6 +23,7 @@ settingsStore.onDidAnyChange((newValue, oldValue) => { interface State { electronApiPort: number | null; activeMenuBar: any; + tray: Tray | null; php: string | null; phpPort: number | null; phpIni: any; @@ -52,6 +53,7 @@ function generateRandomString(length: number) { export default { electronApiPort: null, activeMenuBar: null, + tray: null, php: null, phpPort: null, phpIni: null,