- Fix duplicate tray icon on macOS when hiding to tray
- Fix tray not showing in background mode on macOS
- Fix hide to tray broken on Windows/Linux
- Fix Shutdown button in web UI not working
This commit is contained in:
decolua 2026-05-16 14:06:56 +07:00
parent 30ff4e3fb0
commit 593c788c75
6 changed files with 43 additions and 16 deletions

View file

@ -1,3 +1,11 @@
# v0.4.50 (2026-05-16)
## Fixes
- Fix duplicate tray icon on macOS when hiding to tray
- Fix tray not showing in background mode on macOS
- Fix hide to tray broken on Windows/Linux
- Fix Shutdown button in web UI not working
# v0.4.49 (2026-05-16)
## Features

View file

@ -694,29 +694,48 @@ function startServer(latestVersion) {
await startTerminalUI(port);
// Loop continues, show menu again
} else if (choice === "hide") {
// Hide to tray: keep the CURRENT process alive (it already owns a
// macOS GUI session so NSStatusItem works). Spawning a detached child
// puts it outside the login session → systray silently fails on macOS.
const { clearScreen } = require("./src/cli/utils/display");
clearScreen();
// Survive terminal close — SIGHUP is sent when the launching shell exits
process.removeAllListeners("SIGHUP");
process.on("SIGHUP", () => {});
// Enable auto startup on OS boot
try {
const { enableAutoStart } = require("./src/cli/tray/autostart");
enableAutoStart(__filename);
} catch (e) { }
console.log(`\n🔔 9Router is running in tray (PID: ${process.pid})`);
if (process.platform === "darwin") {
// macOS: keep current process alive — spawning a detached child puts
// it outside the login session so NSStatusItem silently fails.
process.removeAllListeners("SIGHUP");
process.on("SIGHUP", () => {});
console.log(`\n⏳ Switching to tray mode... (icon already visible in menu bar)`);
console.log(`🔔 9Router is running in tray (PID: ${process.pid})`);
console.log(` Server: http://${displayHost}:${port}`);
console.log(`\n💡 You can close this terminal. Right-click tray icon to quit.\n`);
// Tray icon already running (initTrayIcon was called above at startup).
// Nothing more to do — event loop keeps process alive via tray + server.
// Tray already init'd at startup — just keep event loop alive.
return;
}
// Windows/Linux: spawn detached bgProcess (systray works fine in child)
console.log(`\n⏳ Starting background process... (tray icon will appear in ~3s)`);
const bgProcess = spawn(process.execPath, [__filename, "--tray", "--skip-update", "-p", port.toString()], {
detached: true,
stdio: "ignore",
windowsHide: true,
env: { ...process.env }
});
bgProcess.unref();
console.log(`🔔 9Router is now running in background (PID: ${bgProcess.pid})`);
console.log(` Server: http://${displayHost}:${port}`);
console.log(`\n💡 You can close this terminal. Right-click tray icon to quit.\n`);
// cleanup() kills server so bgProcess can claim the port fresh
cleanup();
process.exit(0);
} else if (choice === "exit") {
isShuttingDown = true;
console.log("\nExiting...");

View file

@ -1,6 +1,6 @@
{
"name": "9router",
"version": "0.4.49",
"version": "0.4.50",
"description": "9Router CLI - Start and manage 9Router server",
"bin": {
"9router": "./cli.js"

View file

@ -1,6 +1,6 @@
{
"name": "9router-app",
"version": "0.4.49",
"version": "0.4.50",
"description": "9Router web dashboard",
"private": true,
"scripts": {

View file

@ -98,13 +98,13 @@
"Console Log": "Nhật ký Console",
"System": "Hệ thống",
"Debug": "Gỡ lỗi",
"Shutdown": "Tắt máy",
"Shutdown": "Tắt ứng dụng",
"Close Proxy": "Đóng Proxy",
"Are you sure you want to close the proxy server?": "Bạn có chắc chắn muốn đóng máy chủ proxy không?",
"Server Disconnected": "Máy chủ đã ngắt kết nối",
"The proxy server has been stopped.": "Máy chủ proxy đã bị dừng.",
"Reload Page": "Tải lại trang",
"Service is running in terminal. You can close this web page. Shutdown will stop the service.": "Dịch vụ đang chạy trong terminal. Bạn có thể đóng trang web này. Tắt máy sẽ dừng dịch vụ.",
"Service is running in terminal. You can close this web page. Shutdown will stop the service.": "Dịch vụ đang chạy trong terminal. Bạn có thể đóng trang web này. Tắt ứng dụng sẽ dừng dịch vụ.",
"Manage your AI provider connections": "Quản lý kết nối nhà cung cấp AI của bạn",
"Model combos with fallback": "Kết hợp mô hình với dự phòng",
"Monitor your API usage, token consumption, and request logs": "Theo dõi việc sử dụng API, tiêu thụ token và nhật ký yêu cầu",

View file

@ -109,7 +109,7 @@ export default function Sidebar({ onClose }) {
const handleShutdown = async () => {
setIsShuttingDown(true);
try {
await fetch("/api/shutdown", { method: "POST" });
await fetch("/api/version/shutdown", { method: "POST" });
} catch (e) {
// Expected to fail as server shuts down; ignore error
}