From 953c36b6d3d691db982c85158277ab485fdd6d4c Mon Sep 17 00:00:00 2001 From: star knight <64941905+starknt@users.noreply.github.com> Date: Sun, 20 Oct 2024 22:47:05 +0800 Subject: [PATCH] =?UTF-8?q?bugfix:=20Windows=E6=93=8D=E4=BD=9C=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=EF=BC=8C=E5=BC=80=E7=9D=80DS=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E9=87=8D=E5=90=AF=E7=94=B5=E8=84=91=E5=90=8E=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E4=B8=8A=E7=BD=91=E7=9A=84=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=20(#377)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 113fd100bd986f2dad8e69da9041caaa14760f2b) --- packages/gui/package.json | 4 +- packages/gui/src/background.js | 18 ++- packages/gui/src/background/powerMonitor.js | 135 ++++++++++++++++++++ packages/gui/vue.config.js | 21 +++ 4 files changed, 175 insertions(+), 3 deletions(-) create mode 100644 packages/gui/src/background/powerMonitor.js diff --git a/packages/gui/package.json b/packages/gui/package.json index ae24c9bc6c..6d6a5aeafc 100644 --- a/packages/gui/package.json +++ b/packages/gui/package.json @@ -23,6 +23,8 @@ "dependencies": { "@docmirror/dev-sidecar": "^1.8.8", "@docmirror/mitmproxy": "^1.8.8", + "@mihomo-party/sysproxy": "^2.0.4", + "@natmri/platform-napi": "0.0.7", "adm-zip": "^0.5.5", "ant-design-vue": "^1.6.5", "compressing": "^1.5.1", @@ -52,9 +54,9 @@ "@vue/eslint-config-standard": "^5.1.2", "babel-eslint": "^10.1.0", "electron": "^17.4.11", + "electron-builder": "^23.0.3", "electron-devtools-installer": "^3.1.0", "electron-icon-builder": "^2.0.1", - "electron-builder": "^23.0.3", "eslint": "^6.7.2", "eslint-plugin-import": "^2.20.2", "eslint-plugin-node": "^11.1.0", diff --git a/packages/gui/src/background.js b/packages/gui/src/background.js index 9bab6aea61..2e7da09ea3 100644 --- a/packages/gui/src/background.js +++ b/packages/gui/src/background.js @@ -1,12 +1,15 @@ 'use strict' /* global __static */ import path from 'path' -import { app, protocol, BrowserWindow, Menu, Tray, ipcMain, dialog, powerMonitor, nativeImage, nativeTheme, globalShortcut } from 'electron' +import { app, protocol, BrowserWindow, Menu, Tray, ipcMain, dialog, nativeImage, nativeTheme, globalShortcut } from 'electron' +import { powerMonitor } from './background/powerMonitor' import { createProtocol } from 'vue-cli-plugin-electron-builder/lib' import backend from './bridge/backend' import DevSidecar from '@docmirror/dev-sidecar' import log from './utils/util.log' import minimist from 'minimist' + +const isWindows = process.platform === 'win32' // eslint-disable-next-line no-unused-vars const isMac = process.platform === 'darwin' // import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer' @@ -187,6 +190,11 @@ function createWindow (startHideWindow) { Menu.setApplicationMenu(null) win.setMenu(null) + // !!IMPORTANT + if (isWindows) { + powerMonitor.setupMainWindow(win) + } + if (process.env.WEBPACK_DEV_SERVER_URL) { // Load the url of the dev server if in development mode win.loadURL(process.env.WEBPACK_DEV_SERVER_URL) @@ -443,8 +451,14 @@ if (!isFirstInstance) { } powerMonitor.on('shutdown', async (e) => { - e.preventDefault() + if (e) { + e.preventDefault() + } log.info('系统关机,恢复代理设置') + if (isWindows) { + const Sysproxy = require('@mihomo-party/sysproxy') + Sysproxy.triggerManualProxy(false, '', 0, '') + } await quit() }) }) diff --git a/packages/gui/src/background/powerMonitor.js b/packages/gui/src/background/powerMonitor.js new file mode 100644 index 0000000000..dd8b9acbcd --- /dev/null +++ b/packages/gui/src/background/powerMonitor.js @@ -0,0 +1,135 @@ +import { powerMonitor as _powerMonitor } from 'electron' +import { setMainWindowHandle, insertWndProcHook, removeWndProcHook, releaseShutdownBlock, acquireShutdownBlock } from '@natmri/platform-napi' + +class PowerMonitor { + constructor () { + this.setup = false + this._listeners = [] + this._shutdownCallback = null + } + + /** + * @param {BrowserWindow} window + */ + setupMainWindow (window) { + if (!this.setup) { + setMainWindowHandle(window.getNativeWindowHandle().readBigInt64LE()) + this.setup = true + } + } + + addListener (event, listener) { + return this.on(event, listener) + } + + removeListener (event, listener) { + return this.off(event, listener) + } + + removeAllListeners (event) { + if (event === 'shutdown' && process.platform === 'win32') { + this._listeners = [] + if (this._shutdownCallback) { + removeWndProcHook() + releaseShutdownBlock() + this._shutdownCallback = null + } + } else { + return _powerMonitor.removeAllListeners(event) + } + } + + on (event, listener) { + if (event === 'shutdown' && process.platform === 'win32') { + if (!this._shutdownCallback) { + this._shutdownCallback = async () => { + await Promise.all(this._listeners.map((fn) => fn())) + releaseShutdownBlock() + } + insertWndProcHook(this._shutdownCallback) + acquireShutdownBlock('正在停止 DevSidecar 代理') + } + this._listeners.push(listener) + } else { + return _powerMonitor.on(event, listener) + } + } + + off (event, listener) { + if (event === 'shutdown' && process.platform === 'win32') { + this._listeners = this._listeners.filter((fn) => fn !== listener) + } else { + return _powerMonitor.off(event, listener) + } + } + + once (event, listener) { + if (event === 'shutdown' && process.platform === 'win32') { + return this.on(event, listener) + } else { + return _powerMonitor.once(event, listener) + } + } + + emit (event, ...args) { + return _powerMonitor.emit(event, ...args) + } + + eventNames () { + return _powerMonitor.eventNames() + } + + getMaxListeners () { + return _powerMonitor.getMaxListeners() + } + + listeners (event) { + return _powerMonitor.listeners(event) + } + + rawListeners (event) { + return _powerMonitor.rawListeners(event) + } + + listenerCount (event, listener) { + return _powerMonitor.listenerCount(event, listener) + } + + /** + * @returns {boolean} + */ + get onBatteryPower () { + return _powerMonitor.onBatteryPower + } + + /** + * @param {number} idleThreshold + * @returns {'active'|'idle'|'locked'|'unknown'} + */ + getSystemIdleState (idleThreshold) { + return _powerMonitor.getSystemIdleState(idleThreshold) + } + + /** + * @returns {number} + */ + getSystemIdleTime () { + return _powerMonitor.getSystemIdleTime() + } + + /** + * @returns {'unknown'|'nominal'|'fair'|'serious'|'critical'} + */ + getCurrentThermalState () { + return _powerMonitor.getCurrentThermalState() + } + + /** + * @returns {boolean} + */ + isOnBatteryPower () { + return _powerMonitor.isOnBatteryPower() + } +} + +export const powerMonitor = new PowerMonitor() diff --git a/packages/gui/vue.config.js b/packages/gui/vue.config.js index 9cdb055f85..816a2658bf 100644 --- a/packages/gui/vue.config.js +++ b/packages/gui/vue.config.js @@ -32,6 +32,27 @@ module.exports = { }, pluginOptions: { electronBuilder: { + externals: [ + '@mihomo-party/sysproxy', + '@mihomo-party/sysproxy-win32-ia32-msvc', + '@mihomo-party/sysproxy-win32-x64-msvc', + '@mihomo-party/sysproxy-win32-arm64-msvc', + '@mihomo-party/sysproxy-linux-x64-gnu', + '@mihomo-party/sysproxy-linux-arm64-gnu', + '@mihomo-party/sysproxy-darwin-x64', + '@mihomo-party/sysproxy-darwin-arm64', + '@natmri/platform-napi', + "@natmri/platform-napi-win32-x64-msvc", + "@natmri/platform-napi-darwin-x64", + "@natmri/platform-napi-linux-x64-gnu", + "@natmri/platform-napi-darwin-arm64", + "@natmri/platform-napi-linux-arm64-gnu", + "@natmri/platform-napi-linux-arm64-musl", + "@natmri/platform-napi-win32-arm64-msvc", + "@natmri/platform-napi-linux-arm-gnueabihf", + "@natmri/platform-napi-linux-x64-musl", + "@natmri/platform-napi-win32-ia32-msvc" + ], nodeIntegration: true, // Provide an array of files that, when changed, will recompile the main process and restart Electron // Your main process file will be added by default