mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 14:15:24 +00:00
feat: themed title bar for the desktop app (#1690)
This commit is contained in:
1 parent
368a8eb415
commit
e7d6d481df
8 files changed
+435
-2
No files matched your search
@@ -31,6 +31,10 @@ const { quitApp } = require("./app-quit.cjs");
|
||||
const { selectLinuxPasswordStore } = require("./linux-password-store.cjs");
|
||||
// Saved by the file manager after the user picks an editor in a file dialog.
|
||||
const EXTERNAL_EDITOR_SETTING = "fileManager.externalEditorPath";
|
||||
|
||||
// The height of the title bar the app draws itself. The renderer uses the
|
||||
// same number, so the bar and the window controls always line up.
|
||||
const TITLE_BAR_HEIGHT = 40;
|
||||
const { isExternalLoginUrl, isCallbackPort } = require("./external-login.cjs");
|
||||
|
||||
// The main process's Node.js networking (the global `fetch`) only
|
||||
@@ -1327,12 +1331,27 @@ function createWindow() {
|
||||
? "macOS"
|
||||
: "Linux";
|
||||
|
||||
const isMac = process.platform === "darwin";
|
||||
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 1200,
|
||||
height: 800,
|
||||
minWidth: 800,
|
||||
minHeight: 600,
|
||||
title: "Termix",
|
||||
// The app draws its own title bar so it follows the active theme. macOS
|
||||
// keeps the traffic lights on top of it, Windows and Linux get the
|
||||
// native controls as an overlay whose colors the renderer keeps in sync.
|
||||
titleBarStyle: isMac ? "hiddenInset" : "hidden",
|
||||
...(isMac
|
||||
? { trafficLightPosition: { x: 14, y: 16 } }
|
||||
: {
|
||||
titleBarOverlay: {
|
||||
color: "#0f0f14",
|
||||
symbolColor: "#e6e6ea",
|
||||
height: TITLE_BAR_HEIGHT,
|
||||
},
|
||||
}),
|
||||
icon: path.join(
|
||||
appRoot,
|
||||
"public",
|
||||
@@ -1545,6 +1564,16 @@ function createWindow() {
|
||||
}
|
||||
});
|
||||
|
||||
const sendTitleBarVisible = () => {
|
||||
if (!mainWindow || mainWindow.isDestroyed()) return;
|
||||
mainWindow.webContents.send(
|
||||
"title-bar-visible-changed",
|
||||
titleBarVisible(mainWindow),
|
||||
);
|
||||
};
|
||||
mainWindow.on("enter-full-screen", sendTitleBarVisible);
|
||||
mainWindow.on("leave-full-screen", sendTitleBarVisible);
|
||||
|
||||
mainWindow.on("closed", () => {
|
||||
embeddedViews.destroyAll();
|
||||
mainWindow = null;
|
||||
@@ -1574,10 +1603,50 @@ ipcMain.handle("get-app-version", () => {
|
||||
return app.getVersion();
|
||||
});
|
||||
|
||||
/** The window an IPC call came from, so the main window and the extra
|
||||
* windows (isolated views, sign-in) can each answer for themselves. */
|
||||
function windowFor(event) {
|
||||
const win = BrowserWindow.fromWebContents(event.sender);
|
||||
if (win && !win.isDestroyed()) return win;
|
||||
if (mainWindow && !mainWindow.isDestroyed()) return mainWindow;
|
||||
return null;
|
||||
}
|
||||
|
||||
ipcMain.handle("get-platform", () => {
|
||||
return process.platform;
|
||||
});
|
||||
|
||||
// Whether the app-drawn title bar shows in the window that asks. Only the
|
||||
// main window hides the native bar, and in full screen macOS hides the
|
||||
// traffic lights, so the bar goes away there too.
|
||||
function titleBarVisible(win) {
|
||||
return !!win && win === mainWindow && !win.isFullScreen();
|
||||
}
|
||||
|
||||
ipcMain.handle("get-title-bar-visible", (event) => {
|
||||
return titleBarVisible(windowFor(event));
|
||||
});
|
||||
|
||||
// The renderer sends the colors of the active theme so the window controls
|
||||
// the system draws (Windows and Linux) match the app.
|
||||
ipcMain.handle("set-title-bar-overlay", (event, colors) => {
|
||||
const win = windowFor(event);
|
||||
if (!win || process.platform === "darwin") return;
|
||||
const options = {};
|
||||
if (typeof colors?.color === "string" && colors.color) {
|
||||
options.color = colors.color;
|
||||
}
|
||||
if (typeof colors?.symbolColor === "string" && colors.symbolColor) {
|
||||
options.symbolColor = colors.symbolColor;
|
||||
}
|
||||
if (Object.keys(options).length === 0) return;
|
||||
try {
|
||||
win.setTitleBarOverlay(options);
|
||||
} catch (error) {
|
||||
logToFile("setTitleBarOverlay failed:", error);
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle("get-embedded-server-status", () => {
|
||||
return {
|
||||
running:
|
||||
|
||||
@@ -32,6 +32,19 @@ contextBridge.exposeInMainWorld("electronAPI", {
|
||||
webFrame.setZoomFactor(Math.min(2, Math.max(0.5, value)));
|
||||
},
|
||||
getPlatform: () => ipcRenderer.invoke("get-platform"),
|
||||
|
||||
// Whether the app-drawn title bar shows in this window, and when it changes
|
||||
// (full screen hides it).
|
||||
getTitleBarVisible: () => ipcRenderer.invoke("get-title-bar-visible"),
|
||||
onTitleBarVisibleChange: (callback) => {
|
||||
const listener = (_event, visible) => callback(visible);
|
||||
ipcRenderer.on("title-bar-visible-changed", listener);
|
||||
return () =>
|
||||
ipcRenderer.removeListener("title-bar-visible-changed", listener);
|
||||
},
|
||||
// Keeps the window controls the system draws in the colors of the theme.
|
||||
setTitleBarOverlay: (colors) =>
|
||||
ipcRenderer.invoke("set-title-bar-overlay", colors),
|
||||
getEmbeddedServerStatus: () =>
|
||||
ipcRenderer.invoke("get-embedded-server-status"),
|
||||
|
||||
|
||||
Reference in new issue
Block a user