Skip to content

Commit

Permalink
重构:窗口打开、分离窗口逻辑优化,支持同时打开多个分离窗口
Browse files Browse the repository at this point in the history
  • Loading branch information
modstart committed Dec 19, 2024
1 parent 4c62652 commit f88296b
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 94 deletions.
3 changes: 3 additions & 0 deletions electron/declarations/electron.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@ declare module 'electron' {
_window?: any;
_plugin?: any;
}
interface BrowserWindow {
_name?: string;
}
}

210 changes: 119 additions & 91 deletions electron/mapi/manager/window/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,6 @@ export const ManagerWindow = {
})
},
async open(plugin: PluginRecord, action: ActionRecord, option?: {}) {
let view = mainWindowView
if (view) {
await this.close(view._plugin)
view = null
}
const size = AppRuntime.mainWindow.getSize()
AppRuntime.mainWindow.setSize(size[0], WindowConfig.mainHeight);
const {
nodeIntegration,
preloadBase,
Expand Down Expand Up @@ -176,7 +169,7 @@ export const ManagerWindow = {
windowSession.setPreloads([preloadBase]);
}
// console.log('preload', {preloadPluginDefault, preload})
view = new BrowserView({
const view = new BrowserView({
webPreferences: {
webSecurity: false,
nodeIntegration,
Expand All @@ -195,18 +188,9 @@ export const ManagerWindow = {
},
});
addBrowserViews(view)
// browserViews.push(view)
view._plugin = plugin
view._window = AppRuntime.mainWindow
mainWindowView = view
remoteMain.enable(view.webContents)
AppRuntime.mainWindow.addBrowserView(view);
if (rendererIsUrl(main)) {
view.webContents.loadURL(main).then()
} else {
view.webContents.loadFile(main).then()
}
DevToolsManager.register(`MainView.${plugin.name}`, view)
DevToolsManager.register(`PluginView.${plugin.name}`, view)
view.webContents.once('did-finish-load', async () => {
await executeDarkMode(view, {
isSystem: ManagerSystem.match(plugin.name)
Expand All @@ -222,56 +206,59 @@ export const ManagerWindow = {
view.webContents.setZoomFactor(zoom / 100)
}, 0)
})
view.webContents.once('dom-ready', async () => {
if (autoDetach) {
AppRuntime.mainWindow.setSize(size[0], WindowConfig.mainHeight)
view.setBounds({
x: 0,
y: WindowConfig.mainHeight,
width: width,
height: height,
})
} else {
AppRuntime.mainWindow.setSize(size[0], WindowConfig.mainHeight + height)
view.setBounds({
x: 0,
y: WindowConfig.mainHeight,
width: size[0],
height: height,
})
view.webContents.on('preload-error', (event, preloadPath, error) => {
Log.error('ManagerWindow.open.preload-error', error)
})
view.webContents.setWindowOpenHandler(({url}) => {
if (url.startsWith('https://') || url.startsWith('http://')) {
shell.openExternal(url)
}
return {action: 'deny'}
})
view.setAutoResize({width: true, height: true});
// console.log('ManagerWindow.open', {nodeIntegration, preload, main, width, height, autoDetach})
view.webContents.once('dom-ready', async () => {
const pluginParam = {}
const pluginState: PluginState = {
value: '',
placeholder: '',
}
await executeHooks(AppRuntime.mainWindow, 'PluginInit', {
plugin: plugin,
await executeHooks(view._window, 'PluginInit', {
plugin: view._plugin,
state: pluginState,
param: pluginParam
})
DevToolsManager.autoShow(view)
if (autoDetach) {
await this.detach()
}
});
view.webContents.on('preload-error', (event, preloadPath, error) => {
Log.error('ManagerWindow.open.preload-error', error)
})
view.webContents.setWindowOpenHandler(({url}) => {
if (url.startsWith('https://') || url.startsWith('http://')) {
shell.openExternal(url)
const windowOption = {
width, height,
pluginState: {
value: '',
placeholder: '',
}
return {action: 'deny'}
})
view.setAutoResize({width: true, height: true});
// mainWindowPlugin = plugin;
}
if (rendererIsUrl(main)) {
view.webContents.loadURL(main).then()
} else {
view.webContents.loadFile(main).then()
}
if (autoDetach) {
await this._showInDetachWindow(view, windowOption)
} else {
await this._showInMainWindow(view, windowOption)
}
const readyData = {}
readyData['actionName'] = action.name
readyData['actionMatch'] = action.runtime?.match
readyData['requestId'] = action.runtime?.requestId
// console.log('open.readyData', readyData)
await executePluginHooks(view, 'PluginReady', readyData)
if (autoDetach) {
if (!mainWindowView) {
// console.log('ManagerWindow.open.autoDetach.hide')
AppRuntime.mainWindow.hide()
}
}
},
async subInputChange(win: BrowserWindow, keywords: string) {
const view = win.getBrowserView()
Expand Down Expand Up @@ -301,28 +288,48 @@ export const ManagerWindow = {
})
}
},
async detach(option?: {}) {
// const bounds = AppRuntime.mainWindow.getBounds()
const view: BrowserView = mainWindowView
if (!view) {
throw 'MainViewNotFound'
async _showInMainWindow(view: BrowserView, option: {
pluginState: PluginState,
width: number,
height: number,
}) {
// console.log('showInMainWindow', view._plugin.name, option)
if (mainWindowView) {
await this.close(mainWindowView._plugin)
mainWindowView = null
}
const bounds = view.getBounds()
// console.log('view.bounds', view.getBounds())
const viewWidth = bounds.width
const viewHeight = bounds.height
AppRuntime.mainWindow.removeBrowserView(view);
mainWindowView = null
const pluginState: PluginState = await executeHooks(AppRuntime.mainWindow, 'PluginState')
view._window = AppRuntime.mainWindow
AppRuntime.mainWindow.setSize(WindowConfig.mainWidth, WindowConfig.mainHeight);
mainWindowView = view
AppRuntime.mainWindow.addBrowserView(view);
return new Promise((resolve, reject) => {
view.webContents.once('dom-ready', async () => {
AppRuntime.mainWindow.setSize(option.width, WindowConfig.mainHeight + option.height)
view.setBounds({
x: 0,
y: WindowConfig.mainHeight,
width: option.width,
height: option.height,
})
resolve(undefined)
})
})
},
async _showInDetachWindow(view: BrowserView, option: {
pluginState: PluginState,
width: number,
height: number,
}) {
const plugin = view._plugin
let alwaysOnTop = false;
let win = new BrowserWindow({
height: viewHeight + WindowConfig.detachWindowTitleHeight,
minHeight: viewHeight + WindowConfig.detachWindowTitleHeight,
width: viewWidth,
height: option.height + WindowConfig.detachWindowTitleHeight,
minHeight: option.height + WindowConfig.detachWindowTitleHeight,
width: option.width,
autoHideMenuBar: true,
titleBarStyle: 'hidden',
trafficLightPosition: {x: 10, y: 11},
title: view._plugin.title,
title: plugin.title,
resizable: true,
frame: false,
show: false,
Expand All @@ -345,7 +352,7 @@ export const ManagerWindow = {
preload: preloadDefault,
},
});
// console.log('DetachWindow', win._name)
win._name = `DetachWindow.${view._plugin.name}`
view._window = win
remoteMain.enable(win.webContents)
win.on('close', () => {
Expand All @@ -362,28 +369,6 @@ export const ManagerWindow = {
view && win.webContents?.focus();
});
DevToolsManager.register(`DetachWindow.${view._plugin.name}`, win)
const pluginJson = JSON.parse(JSON.stringify(view._plugin))
win.webContents.once('did-finish-load', async () => {
await executeDarkMode(win, {
isSystem: true
})
view.setAutoResize({width: true, height: true});
win.setBrowserView(view);
view.setBounds({
x: 0,
y: WindowConfig.detachWindowTitleHeight,
width: viewWidth,
height: viewHeight,
});
DevToolsManager.autoShow(win)
const pluginParam = {
alwaysOnTop
};
await executeHooks(win, 'PluginInit', {plugin: pluginJson, state: pluginState, param: pluginParam})
await executeHooks(AppRuntime.mainWindow, 'PluginDetached')
win.show()
AppRuntime.mainWindow.hide()
})
win.on('maximize', () => {
executeHooks(win, 'Maximize');
const display = screen.getDisplayMatching(win.getBounds());
Expand Down Expand Up @@ -433,8 +418,51 @@ export const ManagerWindow = {
win.webContents.setWindowOpenHandler(() => {
return {action: "deny"};
});
rendererLoadPath(win, 'page/detachWindow.html')
addDetachWindows(win)
const pluginJson = JSON.parse(JSON.stringify(view._plugin))
return new Promise((resolve, reject) => {
win.webContents.once('did-finish-load', async () => {
await executeDarkMode(win, {
isSystem: true
})
view.setAutoResize({width: true, height: true});
win.setBrowserView(view);
view.setBounds({
x: 0,
y: WindowConfig.detachWindowTitleHeight,
width: option.width,
height: option.height,
});
DevToolsManager.autoShow(win)
const pluginParam = {
alwaysOnTop
};
await executeHooks(win, 'PluginInit', {
plugin: pluginJson,
state: option.pluginState,
param: pluginParam
})
resolve(undefined)
win.show()
})
rendererLoadPath(win, 'page/detachWindow.html')
addDetachWindows(win)
})
},
async detach(option?: {}) {
if (!mainWindowView) {
throw 'MainViewNotFound'
}
const pluginState: PluginState = await executeHooks(AppRuntime.mainWindow, 'PluginState')
AppRuntime.mainWindow.removeBrowserView(mainWindowView);
const bounds = mainWindowView.getBounds()
await this._showInDetachWindow(mainWindowView, {
pluginState,
width: bounds.width,
height: bounds.height
})
mainWindowView = null
await executeHooks(AppRuntime.mainWindow, 'PluginDetached')
AppRuntime.mainWindow.hide()
},
async toggleDetachPluginAlwaysOnTop(view: BrowserView, alwaysOnTop: boolean, option?: {}) {
view._window.setAlwaysOnTop(alwaysOnTop)
Expand Down
3 changes: 1 addition & 2 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {ref} from "vue";
import MainSearch from "./pages/Main/MainSearch.vue";
import MainResult from "./pages/Main/MainResult.vue";
import {useManagerStore} from "./store/modules/manager";
import {PluginRecord} from "./types/Manager";
import {PluginRecord, PluginState} from "./types/Manager";
import {useLocale} from "./app/locale";
const manager = useManagerStore()
Expand All @@ -44,7 +44,6 @@ window.__page.onShow(() => {
window.__page.onPluginInit((data: {
plugin: PluginRecord,
param: {
id: string,
alwaysOnTop: boolean
}
}) => {
Expand Down
1 change: 0 additions & 1 deletion src/pages/PageDetachWindow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ window.__page.onPluginInit((data: {
plugin: PluginRecord,
state: PluginState,
param: {
// id: string,
alwaysOnTop: boolean
}
}) => {
Expand Down

0 comments on commit f88296b

Please sign in to comment.