123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343 |
- import * as electron from 'electron'
- import { app, BrowserWindow, desktopCapturer, ipcMain, Menu, Notification, screen, shell, Tray } from 'electron'
- import path, { join } from 'path'
- import { electronApp, is, optimizer } from '@electron-toolkit/utils'
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore
- import { useCheckUpdate } from './useCheckUpdate'
- import vimConfig from '/src/renderer/src/config/VimConfig'
- //刷新托盘定时器
- let flashIconTimer: NodeJS.Timeout | null = null
- let cutWindow: BrowserWindow | null = null
- const iconPath =
- process.platform === 'win32' ? '../../resources/icon.ico' : '../../resources/icon.png'
- const emptyIconPath =
- process.platform === 'win32' ? '../../resources/empty.ico' : '../../resources/empty.png'
- let appIcon: Electron.Tray | null = null
- function createWindow(): void {
- // Create the browser window.
- const mainWindow = new BrowserWindow({
- show: false,
- autoHideMenuBar: true,
- webPreferences: {
- contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
- webSecurity: true,
- nodeIntegration: true, // 解决require is not defined问题
- webviewTag: true, // 解决webview无法显示问题
- preload: join(__dirname, '../preload/index.js'),
- sandbox: false
- },
- useContentSize: true,
- width: 1000,
- height: 600,
- frame: false
- })
- mainWindow.on('ready-to-show', () => {
- mainWindow.show()
- useCheckUpdate(app)
- })
- // 处理窗口失去焦点事件
- mainWindow.on('blur', () => {
- mainWindow.webContents.send('BLUR', true)
- })
- // 处理窗口获得焦点事件
- mainWindow.on('focus', () => {
- mainWindow.webContents.send('FOCUS', false)
- })
- /**
- * 系统休眠
- */
- electron.powerMonitor.on('suspend', () => {
- mainWindow.webContents.send('SLEEP')
- })
- /**
- * 系统唤醒
- */
- electron.powerMonitor.on('resume', () => {
- mainWindow.webContents.send('RESUME')
- })
- mainWindow.webContents.setWindowOpenHandler((details) => {
- shell.openExternal(details.url).then()
- return { action: 'deny' }
- })
- // HMR for renderer base on electron-vite cli.
- // Load the remote URL for development or the local html file for production.
- if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
- mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL']).then()
- } else {
- mainWindow.loadFile(join(__dirname, '../renderer/index.html')).then()
- }
- ipcMain.on('min', () => {
- mainWindow.minimize()
- })
- ipcMain.on('openURL', (e: Electron.IpcMainEvent, url: string) => {
- e.preventDefault()
- shell.openExternal(url).then()
- })
- ipcMain.on('max', () => {
- if (mainWindow.isMaximized()) {
- mainWindow.unmaximize()
- } else {
- mainWindow.maximize()
- }
- })
- // 只是隐藏任务栏
- ipcMain.on('close', () => {
- hideMain(mainWindow)
- })
- // 闪烁任务栏
- ipcMain.on('flashFrame', () => {
- //没有聚焦
- if (!mainWindow.isFocused()) {
- mainWindow.flashFrame(true)
- }
- })
- /**
- * 发生系统通知
- * @param content 通知内容
- * @param url 点击通知跳转的url
- */
- ipcMain.on(
- 'NOTIFICATION',
- (e: Electron.IpcMainEvent, content: string, url: string | undefined) => {
- e.preventDefault()
- if (!mainWindow.isFocused()) {
- new Notification({
- title: vimConfig.name,
- body: content,
- timeoutType: 'never'
- })
- .on('click', (event) => {
- event.preventDefault()
- showMain(mainWindow)
- if (url) {
- shell.openExternal(url).then()
- }
- })
- .show()
- }
- }
- )
- appIcon = createTray(mainWindow, iconPath)
- // 闪烁任务栏
- ipcMain.on('flashIcon', () => {
- if (!mainWindow.isVisible()) {
- clearFlashIconTimer()
- let count = 0
- flashIconTimer = setInterval(() => {
- count++
- if (appIcon) {
- if (count % 2 === 0) {
- appIcon.setImage(path.join(__dirname, emptyIconPath))
- } else {
- appIcon.setImage(path.join(__dirname, iconPath))
- }
- }
- }, 500)
- }
- })
- ipcMain.on('clearFlashIcon', () => {
- clearFlashIconTimer()
- if (appIcon) {
- appIcon.setImage(path.join(__dirname, iconPath))
- }
- })
- // 获取设备窗口信息
- ipcMain.handle('getSource', async () => {
- const sources = await desktopCapturer.getSources({
- types: ['screen'],
- thumbnailSize: getSize()
- })
- //当前的屏幕id
- const { id } = screen.getDisplayNearestPoint(screen.getCursorScreenPoint())
- //多屏情况下,只截图当前的屏幕
- return sources.find((source) => source.display_id === id + '') ?? sources[0]
- })
- /**
- * 点击截屏弹出截屏窗口
- */
- ipcMain.on('OPEN_CUT_SCREEN', async (event, args) => {
- event.preventDefault()
- closeCutWindow()
- if (args) {
- mainWindow.hide()
- }
- await createCutWindow()
- if (cutWindow) {
- cutWindow.show()
- }
- })
- /**
- * 截屏事件
- */
- ipcMain.on('CUT_SCREEN', async (e, cutInfo) => {
- e.preventDefault()
- closeCutWindow()
- mainWindow.webContents.send('GET_CUT_INFO', cutInfo)
- mainWindow.show()
- })
- /**
- * 关闭截屏窗口
- */
- ipcMain.on('CLOSE_CUT_SCREEN', async () => {
- closeCutWindow()
- mainWindow.show()
- })
- }
- /**
- * 隐藏窗口,隐藏任务栏
- */
- function hideMain(win: BrowserWindow) {
- win.setSkipTaskbar(true)
- win.hide()
- }
- /**
- * 清除图片闪烁的定时器
- */
- function clearFlashIconTimer() {
- if (flashIconTimer) {
- clearInterval(flashIconTimer)
- if (appIcon) {
- appIcon.setImage(path.join(__dirname, iconPath))
- }
- }
- }
- /**
- * 获取截屏的size
- */
- function getSize() {
- const { size, scaleFactor } = screen.getDisplayNearestPoint(screen.getCursorScreenPoint())
- return {
- width: Math.floor(size.width * scaleFactor),
- height: Math.floor(size.height * scaleFactor)
- }
- }
- /**
- * 创建一个截屏窗口
- */
- async function createCutWindow() {
- cutWindow = new BrowserWindow({
- useContentSize: true,
- autoHideMenuBar: true,
- movable: false,
- frame: false,
- resizable: false,
- hasShadow: false,
- transparent: true,
- fullscreen: true,
- simpleFullscreen: true,
- alwaysOnTop: false,
- webPreferences: {
- contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
- webSecurity: false,
- nodeIntegration: true, // 解决require is not defined问题
- webviewTag: true, // 解决webview无法显示问题
- preload: join(__dirname, '../preload/index.js'),
- sandbox: false
- }
- })
- const cutPage = process.platform === 'win32' ? 'cutWin32' : 'cutLinux'
- if (process.env['ELECTRON_RENDERER_URL']) {
- await cutWindow.loadURL(`${process.env['ELECTRON_RENDERER_URL']}#/${cutPage}`)
- if (!process.env.IS_TEST) cutWindow.webContents.openDevTools()
- } else {
- await cutWindow.loadFile(join(__dirname, '../renderer/index.html'), { hash: cutPage })
- }
- cutWindow.maximize()
- cutWindow.setFullScreen(true)
- }
- function closeCutWindow() {
- cutWindow && cutWindow.close()
- cutWindow = null
- }
- app.whenReady().then(() => {
- electronApp.setAppUserModelId('com.electron')
- app.on('browser-window-created', (_, window) => {
- optimizer.watchWindowShortcuts(window)
- })
- createWindow()
- app.on('activate', () => {
- if (BrowserWindow.getAllWindows().length === 0) createWindow()
- })
- })
- app.on('window-all-closed', () => {
- if (process.platform !== 'darwin') {
- app.quit()
- }
- })
- app.on('browser-window-focus', () => {
- clearFlashIconTimer()
- })
- /**
- * 创建托盘图标
- * @param win
- * @param iconPath
- */
- function createTray(win: BrowserWindow, iconPath: string) {
- // 托盘
- const appIcon = new Tray(path.join(__dirname, iconPath))
- const contextMenu = Menu.buildFromTemplate([
- {
- label: '显示',
- click: () => {
- showMain(win)
- }
- },
- {
- label: '退出',
- click: () => {
- app.quit()
- }
- }
- ])
- appIcon.setToolTip(vimConfig.name)
- appIcon.setContextMenu(contextMenu)
- appIcon.on('click', () => {
- showMain(win)
- })
- return appIcon
- }
- /**
- * 展示窗口,打开任务栏
- */
- function showMain(win: BrowserWindow) {
- win.setSkipTaskbar(false)
- win.show()
- clearFlashIconTimer()
- }
|