|
@@ -1,14 +1,17 @@
|
|
|
import Logger from "../util/logger";
|
|
|
-import {BrowserWindow} from "electron";
|
|
|
+import { BrowserWindow, globalShortcut, Menu, Tray} from "electron";
|
|
|
import {CustomScheme} from "./CustomScheme";
|
|
|
import {getAvailablePort} from "./tools/port.ts";
|
|
|
import {FcServer, startServer} from "./server/httpServer.ts";
|
|
|
-import {AppWindow, AppConfig} from "../types/appConfig.ts";
|
|
|
+import {AppWindow, AppConfig, HotKeyConfig} from "../types/appConfig.ts";
|
|
|
import {randomId} from "../util/random.ts";
|
|
|
import {actionMap} from "../tools/IpcCmd.ts";
|
|
|
import BrowserWindowConstructorOptions = Electron.BrowserWindowConstructorOptions;
|
|
|
import {initIpc} from "./tools/ipcInit.ts";
|
|
|
import {initHook} from "./tools/hookInit.ts";
|
|
|
+import hook from "@/util/hook.ts";
|
|
|
+import path from "path";
|
|
|
+import Path from "path";
|
|
|
|
|
|
let logger = Logger.logger('controlWindow', 'info');
|
|
|
|
|
@@ -21,6 +24,28 @@ let _appConfig: AppConfig;
|
|
|
let _winArr: AppWindow[] = [];
|
|
|
let checkTimer: NodeJS.Timeout;
|
|
|
let isExitAppTask = false;// 是否处于退出任务中
|
|
|
+
|
|
|
+const defaultWin : AppWindow = {
|
|
|
+ id: '',
|
|
|
+ sign: '',
|
|
|
+ parentSign: '',
|
|
|
+ type: '',
|
|
|
+ title: '未知窗口',
|
|
|
+ description: '窗口描述文件',
|
|
|
+ win: null,
|
|
|
+ isMain: false,
|
|
|
+ timer: null,// 等待销毁计时器
|
|
|
+ hide: false,// 是否隐藏
|
|
|
+ isConnected: false,// 是否已经建立连接
|
|
|
+ isUsed: false,// 是否被使用中,用于复用窗口
|
|
|
+ destroyWait: 30,
|
|
|
+ style: {
|
|
|
+ width: 0,
|
|
|
+ height: 0,
|
|
|
+ x: 0,
|
|
|
+ y: 0
|
|
|
+ }
|
|
|
+}
|
|
|
function _generate_unique_window_id(){
|
|
|
let id = randomId();
|
|
|
let ind = -1;
|
|
@@ -111,29 +136,8 @@ function winTryConnect(): void {
|
|
|
function registerApp(newApp: Electron.App) {
|
|
|
_app = newApp;
|
|
|
}
|
|
|
-
|
|
|
function registerWin(windowConfig: AppWindow): AppWindow{
|
|
|
- let defaultWin : AppWindow = {
|
|
|
- id: '',
|
|
|
- sign: '',
|
|
|
- parentSign: '',
|
|
|
- type: '',
|
|
|
- title: '未知窗口',
|
|
|
- description: '窗口描述文件',
|
|
|
- win: null,
|
|
|
- isMain: false,
|
|
|
- timer: null,// 等待销毁计时器
|
|
|
- hide: false,// 是否隐藏
|
|
|
- isConnected: false,// 是否已经建立连接
|
|
|
- isUsed: false,// 是否被使用中,用于复用窗口
|
|
|
- destroyWait: 30,
|
|
|
- style: {
|
|
|
- width: 0,
|
|
|
- height: 0,
|
|
|
- x: 0,
|
|
|
- y: 0
|
|
|
- }
|
|
|
- }
|
|
|
+
|
|
|
let finalWindow = {...defaultWin, ...windowConfig }
|
|
|
finalWindow.id = _generate_unique_window_id();
|
|
|
finalWindow.sign = `${finalWindow.type}:${finalWindow.id}`;
|
|
@@ -149,10 +153,62 @@ function registerWin(windowConfig: AppWindow): AppWindow{
|
|
|
|
|
|
winTryConnect();
|
|
|
|
|
|
-
|
|
|
-
|
|
|
return finalWindow;
|
|
|
}
|
|
|
+function registerHotKey(hotKey: HotKeyConfig, mainWin: AppWindow){
|
|
|
+ if(mainWin.win == null){
|
|
|
+ logger.error(`注册快捷键失败,窗口${mainWin.sign}不存在`);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ // 注册快捷键
|
|
|
+ logger.info(`注册显示窗口快捷键 ${hotKey.show}`)
|
|
|
+ globalShortcut.register(hotKey.show, function() {
|
|
|
+ // 隐藏,与显示窗口
|
|
|
+ if(mainWin.win?.isVisible()){
|
|
|
+ hook.runHook(actionMap.hide.code, mainWin.sign).then(r => r)
|
|
|
+ }else{
|
|
|
+ hook.runHook(actionMap.show.code, mainWin.sign).then(r => r)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ logger.info(`最小化窗口快捷键 ${hotKey.min}`)
|
|
|
+ globalShortcut.register(hotKey.min, function() {
|
|
|
+ // 最小化窗口和恢复窗口
|
|
|
+ if (mainWin.win) {
|
|
|
+ if (!mainWin.win.isMinimized()) {
|
|
|
+ logger.info(`最小化窗口 ${mainWin.sign}`);
|
|
|
+ hook.runHook(actionMap.min.code, mainWin.sign).then(r => r)
|
|
|
+ } else {
|
|
|
+ hook.runHook(actionMap.restore.code, mainWin.sign).then(r => r)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ return true
|
|
|
+}
|
|
|
+function _createTray(app: Electron.App, mainWin: AppWindow){
|
|
|
+ const appPath = app.isPackaged ? path.dirname(app.getPath('exe')) : app.getAppPath();
|
|
|
+
|
|
|
+ logger.info(`[托盘挂载] appPath:${appPath}`);
|
|
|
+ // 创建系统托盘
|
|
|
+ const iconPath = Path.resolve( appPath,`/logo.ico`);
|
|
|
+ mainWin.tray = new Tray(iconPath);
|
|
|
+ mainWin.tray.setToolTip('fc-ele');
|
|
|
+ const contextMenu = Menu.buildFromTemplate([
|
|
|
+ {
|
|
|
+ label: '显示主窗口',
|
|
|
+ click: () => {
|
|
|
+ hook.runHook(actionMap.show.code, mainWin.sign).then(r => r)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '退出',
|
|
|
+ click: () => {
|
|
|
+ hook.runHook(actionMap.exitApp.code,mainWin.sign).then(r => r)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]);
|
|
|
+ // 载入托盘菜单
|
|
|
+ mainWin.tray.setContextMenu(contextMenu);
|
|
|
+}
|
|
|
|
|
|
function _createMainWindow(){
|
|
|
let MainUrl : string = `app://index.html`
|
|
@@ -169,7 +225,7 @@ function _createMainWindow(){
|
|
|
height: 620,
|
|
|
frame: false, //任务栏是否显示
|
|
|
show: true,
|
|
|
- transparent: false, //无边框
|
|
|
+ transparent: true, //无边框
|
|
|
resizable: false,// 禁止 重新设置窗口大小
|
|
|
maximizable: false, //禁止最大化
|
|
|
webPreferences: {
|
|
@@ -187,6 +243,39 @@ function _createMainWindow(){
|
|
|
mainWindow.webContents.openDevTools();
|
|
|
return mainWindow;
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+async function exit(){
|
|
|
+ logger.info(`[应用退出] 应用退出中....`);
|
|
|
+ if(!_app){
|
|
|
+ logger.error(`[应用退出] 无法找到主应用. 非常离奇的情况, 按理说不应该这样的`);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ isExitAppTask = true;
|
|
|
+ // fixme: 修复退出软件时,窗口不会关闭的问题. 以及引用问题
|
|
|
+ while(_winArr.length > 0){
|
|
|
+ let winObj = _winArr.pop() as AppWindow;
|
|
|
+ if(!winObj.win){
|
|
|
+ logger.error(`[应用退出] 无法找到窗口对象, 需要修复呢`);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // if(winObj.type === 'top'){
|
|
|
+ // // 从topWinArr 中移除窗口对象
|
|
|
+ // exitTopWin(winObj);
|
|
|
+ // }
|
|
|
+ // 移除所有win的监听事件
|
|
|
+ winObj.win.removeAllListeners();
|
|
|
+ winObj.win.close();
|
|
|
+ winObj.win.destroy();
|
|
|
+ winObj.win = null;
|
|
|
+ }
|
|
|
+ console.log(`退出软件`);
|
|
|
+ // 清理窗口
|
|
|
+ _app.quit();
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
export async function initApp(appConfig: AppConfig, app: Electron.App) : Promise<AppWindow | null>{
|
|
|
logger.info('start init control window');
|
|
|
let mainWindow : BrowserWindow = _createMainWindow();
|
|
@@ -215,49 +304,30 @@ export async function initApp(appConfig: AppConfig, app: Electron.App) : Promise
|
|
|
|
|
|
// 创建主窗口
|
|
|
let mainWin = registerWin({
|
|
|
+ ...defaultWin,
|
|
|
type: 'main',
|
|
|
title: '主进程窗口',
|
|
|
win: mainWindow,
|
|
|
isMain: true,
|
|
|
+
|
|
|
});
|
|
|
|
|
|
// 绑定主进程
|
|
|
registerApp(app)
|
|
|
|
|
|
+ // 注册托盘
|
|
|
+ _createTray(app, mainWin)
|
|
|
|
|
|
+ // 注册快捷键
|
|
|
+ if(registerHotKey(appConfig.hotKey, mainWin)){
|
|
|
+ logger.info(`[应用初始化] 快捷键注册完成`);
|
|
|
+ }
|
|
|
|
|
|
- return mainWin;
|
|
|
-}
|
|
|
|
|
|
|
|
|
-async function exit(){
|
|
|
- logger.info(`[应用退出] 应用退出中....`);
|
|
|
- if(!_app){
|
|
|
- logger.error(`[应用退出] 无法找到主应用. 非常离奇的情况, 按理说不应该这样的`);
|
|
|
- return 0;
|
|
|
- }
|
|
|
- isExitAppTask = true;
|
|
|
- // fixme: 修复退出软件时,窗口不会关闭的问题. 以及引用问题
|
|
|
- while(_winArr.length > 0){
|
|
|
- let winObj = _winArr.pop() as AppWindow;
|
|
|
- if(!winObj.win){
|
|
|
- logger.error(`[应用退出] 无法找到窗口对象, 需要修复呢`);
|
|
|
- continue;
|
|
|
- }
|
|
|
- // if(winObj.type === 'top'){
|
|
|
- // // 从topWinArr 中移除窗口对象
|
|
|
- // exitTopWin(winObj);
|
|
|
- // }
|
|
|
- // 移除所有win的监听事件
|
|
|
- winObj.win.removeAllListeners();
|
|
|
- winObj.win.close();
|
|
|
- winObj.win.destroy();
|
|
|
- winObj.win = null;
|
|
|
- }
|
|
|
- console.log(`退出软件`);
|
|
|
- // 清理窗口
|
|
|
- _app.quit();
|
|
|
- return 0;
|
|
|
+ logger.info(`[应用初始化] 初始化完成`);
|
|
|
+
|
|
|
+ return mainWin;
|
|
|
}
|
|
|
|
|
|
|