@lynker-desktop/electron-window-manager 0.0.9-alpha.3 → 0.0.9-alpha.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -2
- package/common/index.d.ts +23 -0
- package/common/index.d.ts.map +1 -1
- package/esm/common/index.d.ts +23 -0
- package/esm/common/index.d.ts.map +1 -1
- package/esm/main/index.d.ts +50 -8
- package/esm/main/index.d.ts.map +1 -1
- package/esm/main/index.js +568 -125
- package/esm/main/index.js.map +1 -1
- package/esm/renderer/index.d.ts +5 -5
- package/esm/renderer/index.d.ts.map +1 -1
- package/esm/renderer/index.js +11 -9
- package/esm/renderer/index.js.map +1 -1
- package/main/index.d.ts +50 -8
- package/main/index.d.ts.map +1 -1
- package/main/index.js +568 -125
- package/main/index.js.map +1 -1
- package/package.json +2 -2
- package/renderer/index.d.ts +5 -5
- package/renderer/index.d.ts.map +1 -1
- package/renderer/index.js +12 -10
- package/renderer/index.js.map +1 -1
package/main/index.js
CHANGED
|
@@ -69,30 +69,50 @@ class WindowsManager {
|
|
|
69
69
|
* - 不带点的(如 example.com)只匹配主域名。
|
|
70
70
|
* - 'localhost'、'127.0.0.1'、'::1' 以及局域网 IP(如 192.168.x.x、10.x.x.x、172.16.x.x~172.31.x.x)都视为本地白名单。
|
|
71
71
|
*/
|
|
72
|
-
constructor(preload, loadingViewUrl, errorViewUrl,
|
|
72
|
+
constructor(preload, loadingViewUrl, errorViewUrl, preloadWebContentsConfig, webviewDomainWhiteList) {
|
|
73
|
+
// 预加载的窗口
|
|
73
74
|
this.preloadedBW = null;
|
|
75
|
+
// 预加载的窗口(无边框,有按钮)
|
|
74
76
|
this.preloadedBW_FramelessWithButtons = null;
|
|
77
|
+
// 预加载的窗口(无边框,无按钮)
|
|
75
78
|
this.preloadedBW_FramelessNoButtons = null;
|
|
79
|
+
// 预加载的浏览器视图
|
|
76
80
|
this.preloadedBV = null;
|
|
77
81
|
this.preloading = false;
|
|
78
82
|
this.webviewDomainWhiteList = [];
|
|
83
|
+
// 创建队列相关属性
|
|
84
|
+
this.createQueue = [];
|
|
85
|
+
this.isCreating = false;
|
|
86
|
+
/**
|
|
87
|
+
* 防抖的排序方法
|
|
88
|
+
* @param window 目标窗口
|
|
89
|
+
*/
|
|
90
|
+
this.sortBrowserViewsDebounced = lodash.debounce((window, view) => {
|
|
91
|
+
this._sortBrowserViews(window, view);
|
|
92
|
+
}, 50);
|
|
79
93
|
this.preload = preload;
|
|
80
94
|
this.windows = new Map();
|
|
81
95
|
this.loadingViewUrl = `${loadingViewUrl ?? ''}`;
|
|
82
96
|
this.errorViewUrl = `${errorViewUrl ?? ''}`;
|
|
83
|
-
this.
|
|
97
|
+
this.preloadWebContentsConfig = preloadWebContentsConfig;
|
|
84
98
|
this.webviewDomainWhiteList = webviewDomainWhiteList || [];
|
|
85
|
-
log('log', '
|
|
86
|
-
if (this.
|
|
87
|
-
electron.app.
|
|
88
|
-
this.
|
|
99
|
+
log('log', 'preloadWebContentsConfig: ', this.preloadWebContentsConfig);
|
|
100
|
+
if (this.preloadWebContentsConfig) {
|
|
101
|
+
electron.app.whenReady().then(() => {
|
|
102
|
+
if (this.preloadWebContentsConfig) {
|
|
103
|
+
this.setPreloadWebContentsConfig(this.preloadWebContentsConfig);
|
|
104
|
+
}
|
|
89
105
|
});
|
|
90
106
|
}
|
|
91
107
|
}
|
|
92
|
-
|
|
108
|
+
/**
|
|
109
|
+
* 设置预加载的webContents配置
|
|
110
|
+
* @param preloadWebContentsConfig 预加载的webContents配置
|
|
111
|
+
*/
|
|
112
|
+
setPreloadWebContentsConfig(preloadWebContentsConfig) {
|
|
93
113
|
try {
|
|
94
|
-
this.
|
|
95
|
-
if (this.
|
|
114
|
+
this.preloadWebContentsConfig = preloadWebContentsConfig;
|
|
115
|
+
if (this.preloadWebContentsConfig) {
|
|
96
116
|
this._preloadInstances();
|
|
97
117
|
}
|
|
98
118
|
else {
|
|
@@ -103,27 +123,65 @@ class WindowsManager {
|
|
|
103
123
|
}
|
|
104
124
|
}
|
|
105
125
|
catch (error) {
|
|
106
|
-
log('error', '
|
|
126
|
+
log('error', 'setPreloadWebContentsConfig error:', error);
|
|
107
127
|
}
|
|
108
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* 预加载实例
|
|
131
|
+
*/
|
|
109
132
|
async _preloadInstances() {
|
|
110
133
|
if (this.preloading)
|
|
111
134
|
return;
|
|
112
135
|
this.preloading = true;
|
|
113
136
|
try {
|
|
114
|
-
if (this.
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
137
|
+
if (this.preloadWebContentsConfig) {
|
|
138
|
+
log('log', 'preloadWebContentsConfig: ', this.preloadWebContentsConfig);
|
|
139
|
+
// 根据配置决定是否预加载普通窗口
|
|
140
|
+
if (this.preloadWebContentsConfig.enableBW !== false) {
|
|
141
|
+
if (!this.preloadedBW) {
|
|
142
|
+
this._createPreloadBW({}).then(i => {
|
|
143
|
+
this.preloadedBW = i;
|
|
144
|
+
log('log', 'init preloadedBW: ', !!this.preloadedBW);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// 根据配置决定是否预加载无边框有按钮的窗口
|
|
149
|
+
if (this.preloadWebContentsConfig.enableBW_FramelessWithButtons !== false) {
|
|
150
|
+
if (!this.preloadedBW_FramelessWithButtons) {
|
|
151
|
+
this._createPreloadBW({
|
|
152
|
+
frame: false,
|
|
153
|
+
// transparent: true,
|
|
154
|
+
autoHideMenuBar: true,
|
|
155
|
+
titleBarStyle: 'hidden',
|
|
156
|
+
}).then(i => {
|
|
157
|
+
this.preloadedBW_FramelessWithButtons = i;
|
|
158
|
+
log('log', 'init preloadedBW_FramelessWithButtons: ', !!this.preloadedBW_FramelessWithButtons);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// 根据配置决定是否预加载无边框无按钮的窗口
|
|
163
|
+
if (this.preloadWebContentsConfig.enableBW_FramelessNoButtons !== false) {
|
|
164
|
+
if (!this.preloadedBW_FramelessNoButtons) {
|
|
165
|
+
this._createPreloadBW({
|
|
166
|
+
frame: false,
|
|
167
|
+
// transparent: true,
|
|
168
|
+
autoHideMenuBar: true,
|
|
169
|
+
titleBarStyle: 'default',
|
|
170
|
+
}).then(i => {
|
|
171
|
+
this.preloadedBW_FramelessNoButtons = i;
|
|
172
|
+
log('log', 'init preloadedBW_FramelessNoButtons: ', !!this.preloadedBW_FramelessNoButtons);
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// 根据配置决定是否预加载浏览器视图
|
|
177
|
+
if (this.preloadWebContentsConfig.enableBV !== false) {
|
|
178
|
+
if (!this.preloadedBV) {
|
|
179
|
+
this._createPreloadBV().then(i => {
|
|
180
|
+
this.preloadedBV = i;
|
|
181
|
+
log('log', 'init preloadedBV: ', !!this.preloadedBV);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
127
185
|
}
|
|
128
186
|
}
|
|
129
187
|
catch (e) {
|
|
@@ -131,23 +189,32 @@ class WindowsManager {
|
|
|
131
189
|
}
|
|
132
190
|
this.preloading = false;
|
|
133
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* 创建预加载的窗口
|
|
194
|
+
* @param options 窗口选项
|
|
195
|
+
* @returns 预加载的窗口
|
|
196
|
+
*/
|
|
134
197
|
_createPreloadBW(options = {}) {
|
|
135
198
|
return new Promise((resolve) => {
|
|
136
199
|
const preload = this.preload;
|
|
137
|
-
const url = this.
|
|
138
|
-
if (this.
|
|
200
|
+
const url = this.preloadWebContentsConfig?.url;
|
|
201
|
+
if (this.preloadWebContentsConfig?.url) {
|
|
202
|
+
const webPreferences = (options.webPreferences || {});
|
|
139
203
|
const instance = new electron.BrowserWindow({
|
|
204
|
+
useContentSize: true,
|
|
140
205
|
show: false,
|
|
206
|
+
backgroundColor: '#ffffff',
|
|
141
207
|
...options,
|
|
142
208
|
webPreferences: {
|
|
209
|
+
...webPreferences,
|
|
143
210
|
webviewTag: true,
|
|
144
211
|
plugins: true,
|
|
145
212
|
nodeIntegration: true,
|
|
146
213
|
contextIsolation: false,
|
|
147
214
|
backgroundThrottling: false,
|
|
148
215
|
webSecurity: false,
|
|
149
|
-
preload: preload,
|
|
150
|
-
|
|
216
|
+
preload: webPreferences.preload || preload,
|
|
217
|
+
defaultEncoding: 'utf-8',
|
|
151
218
|
}
|
|
152
219
|
});
|
|
153
220
|
try {
|
|
@@ -164,31 +231,42 @@ class WindowsManager {
|
|
|
164
231
|
log('error', '预加载 BW 设置 _id 失败', error);
|
|
165
232
|
}
|
|
166
233
|
// @ts-ignore
|
|
167
|
-
log('log', '创建预BW: ', instance._id, this.
|
|
168
|
-
instance.webContents.once('did-finish-load', () => {
|
|
169
|
-
|
|
170
|
-
});
|
|
171
|
-
instance.webContents.once('did-fail-load', () => {
|
|
172
|
-
|
|
173
|
-
});
|
|
174
|
-
instance.loadURL(url
|
|
234
|
+
log('log', '创建预BW: ', instance._id, this.preloadWebContentsConfig?.url);
|
|
235
|
+
// instance.webContents.once('did-finish-load', () => {
|
|
236
|
+
// resolve(instance as BWItem);
|
|
237
|
+
// });
|
|
238
|
+
// instance.webContents.once('did-fail-load', () => {
|
|
239
|
+
// resolve(instance as BWItem);
|
|
240
|
+
// });
|
|
241
|
+
instance.loadURL(url ? `${url}` : 'about:blank');
|
|
242
|
+
resolve(instance);
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
resolve(null);
|
|
175
246
|
}
|
|
176
247
|
});
|
|
177
248
|
}
|
|
178
|
-
|
|
249
|
+
/**
|
|
250
|
+
* 创建预加载的浏览器视图
|
|
251
|
+
* @returns 预加载的浏览器视图
|
|
252
|
+
*/
|
|
253
|
+
_createPreloadBV(options = {}) {
|
|
179
254
|
return new Promise((resolve) => {
|
|
180
255
|
const preload = this.preload;
|
|
181
|
-
const url = this.
|
|
182
|
-
if (this.
|
|
256
|
+
const url = this.preloadWebContentsConfig?.url;
|
|
257
|
+
if (this.preloadWebContentsConfig?.url) {
|
|
258
|
+
const webPreferences = (options.webPreferences || {});
|
|
183
259
|
const instance = new electron.BrowserView({
|
|
184
260
|
webPreferences: {
|
|
261
|
+
...webPreferences,
|
|
185
262
|
webviewTag: true,
|
|
186
263
|
plugins: true,
|
|
187
264
|
nodeIntegration: true,
|
|
188
265
|
contextIsolation: false,
|
|
189
266
|
// backgroundThrottling: false,
|
|
190
267
|
webSecurity: false,
|
|
191
|
-
preload: preload,
|
|
268
|
+
preload: webPreferences.preload || preload,
|
|
269
|
+
defaultEncoding: 'utf-8',
|
|
192
270
|
}
|
|
193
271
|
});
|
|
194
272
|
try {
|
|
@@ -200,61 +278,130 @@ class WindowsManager {
|
|
|
200
278
|
try {
|
|
201
279
|
// @ts-ignore
|
|
202
280
|
instance._id = instance.webContents.id;
|
|
281
|
+
// 设置默认zIndex层级
|
|
282
|
+
instance._zIndex = 0;
|
|
203
283
|
}
|
|
204
284
|
catch (error) {
|
|
205
285
|
log('error', '预加载 BV 设置 _id 失败', error);
|
|
206
286
|
}
|
|
207
287
|
// @ts-ignore
|
|
208
|
-
log('log', '创建预BV: ', instance._id, this.
|
|
209
|
-
instance.webContents.once('did-finish-load', () => {
|
|
210
|
-
|
|
211
|
-
});
|
|
212
|
-
instance.webContents.once('did-fail-load', () => {
|
|
213
|
-
|
|
214
|
-
});
|
|
288
|
+
log('log', '创建预BV: ', instance._id, this.preloadWebContentsConfig?.url);
|
|
289
|
+
// instance.webContents.once('did-finish-load', () => {
|
|
290
|
+
// resolve(instance as BVItem);
|
|
291
|
+
// });
|
|
292
|
+
// instance.webContents.once('did-fail-load', () => {
|
|
293
|
+
// resolve(instance as BVItem);
|
|
294
|
+
// });
|
|
215
295
|
instance.webContents.loadURL(url || 'about:blank');
|
|
296
|
+
resolve(instance);
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
resolve(null);
|
|
216
300
|
}
|
|
217
301
|
});
|
|
218
302
|
}
|
|
219
303
|
create(options) {
|
|
304
|
+
return new Promise((resolve, reject) => {
|
|
305
|
+
// 将创建请求添加到队列
|
|
306
|
+
this.createQueue.push({ options, resolve, reject });
|
|
307
|
+
// 如果当前没有在创建,则开始处理队列
|
|
308
|
+
if (!this.isCreating) {
|
|
309
|
+
this.processCreateQueue();
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* 处理创建队列
|
|
315
|
+
*/
|
|
316
|
+
async processCreateQueue() {
|
|
317
|
+
if (this.isCreating || this.createQueue.length === 0) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
this.isCreating = true;
|
|
321
|
+
while (this.createQueue.length > 0) {
|
|
322
|
+
const { options, resolve, reject } = this.createQueue.shift();
|
|
323
|
+
try {
|
|
324
|
+
const window = await this._createWindow(options);
|
|
325
|
+
resolve(window);
|
|
326
|
+
}
|
|
327
|
+
catch (error) {
|
|
328
|
+
log('error', 'create window failed:', error);
|
|
329
|
+
reject(error);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
this.isCreating = false;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* 实际的窗口创建逻辑
|
|
336
|
+
*/
|
|
337
|
+
async _createWindow(options) {
|
|
220
338
|
let window;
|
|
221
|
-
const { usePreload = true, type = 'BW', name = 'anonymous', url, loadingView = { url: undefined }, errorView = { url: undefined }, browserWindow: browserWindowOptions, openDevTools = false, preventOriginClose = false, } = options;
|
|
339
|
+
const { usePreload = true, type = 'BW', name = 'anonymous', url, loadingView = { url: undefined }, errorView = { url: undefined }, browserWindow: browserWindowOptions, openDevTools = false, preventOriginClose = false, zIndex = 0, } = options;
|
|
222
340
|
options.type = type;
|
|
223
341
|
// 优先复用预创建实例
|
|
224
342
|
let preloadWin = null;
|
|
225
|
-
if (type === 'BW' && usePreload && this.
|
|
343
|
+
if (type === 'BW' && usePreload && this.preloadWebContentsConfig?.url) {
|
|
226
344
|
const bwOptions = browserWindowOptions || {};
|
|
227
|
-
if (bwOptions.frame === false
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
345
|
+
if (bwOptions.frame === false) {
|
|
346
|
+
if (bwOptions.titleBarStyle === 'default' || !bwOptions.titleBarStyle) {
|
|
347
|
+
if (this.preloadWebContentsConfig.enableBW_FramelessNoButtons !== false && this.preloadedBW_FramelessNoButtons) {
|
|
348
|
+
preloadWin = this.preloadedBW_FramelessNoButtons;
|
|
349
|
+
this.preloadedBW_FramelessNoButtons = await this._createPreloadBW({
|
|
350
|
+
frame: false,
|
|
351
|
+
// transparent: true,
|
|
352
|
+
titleBarStyle: 'default',
|
|
353
|
+
webPreferences: {
|
|
354
|
+
preload: bwOptions?.webPreferences?.preload || this.preload,
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
if (this.preloadWebContentsConfig.enableBW_FramelessWithButtons !== false && this.preloadedBW_FramelessWithButtons) {
|
|
361
|
+
preloadWin = this.preloadedBW_FramelessWithButtons;
|
|
362
|
+
this.preloadedBW_FramelessWithButtons = await this._createPreloadBW({
|
|
363
|
+
frame: false,
|
|
364
|
+
// transparent: true,
|
|
365
|
+
titleBarStyle: 'hidden',
|
|
366
|
+
webPreferences: {
|
|
367
|
+
preload: this.preload,
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
}
|
|
236
372
|
}
|
|
237
373
|
else {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
374
|
+
if (this.preloadWebContentsConfig.enableBW !== false && this.preloadedBW) {
|
|
375
|
+
preloadWin = this.preloadedBW;
|
|
376
|
+
this.preloadedBW = await this._createPreloadBW({
|
|
377
|
+
webPreferences: {
|
|
378
|
+
preload: bwOptions?.webPreferences?.preload || this.preload,
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
}
|
|
241
382
|
}
|
|
242
383
|
}
|
|
243
|
-
if (type === 'BV' && usePreload && this.
|
|
244
|
-
|
|
245
|
-
this.preloadedBV
|
|
246
|
-
|
|
384
|
+
if (type === 'BV' && usePreload && this.preloadWebContentsConfig?.url) {
|
|
385
|
+
const bvOptions = browserWindowOptions || {};
|
|
386
|
+
if (this.preloadWebContentsConfig.enableBV !== false && this.preloadedBV) {
|
|
387
|
+
preloadWin = this.preloadedBV;
|
|
388
|
+
this.preloadedBV = await this._createPreloadBV({
|
|
389
|
+
webPreferences: {
|
|
390
|
+
preload: bvOptions?.webPreferences?.preload || this.preload,
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
}
|
|
247
394
|
}
|
|
248
395
|
if (preloadWin) {
|
|
249
396
|
const win = preloadWin;
|
|
250
|
-
log('log', `${name}
|
|
397
|
+
log('log', `${name} 使用预加载窗口(${type})`, win._id);
|
|
251
398
|
win._type = 'BW';
|
|
252
399
|
win._name = options.name || 'anonymous';
|
|
253
400
|
win._extraData = `${options?.extraData || ''}`;
|
|
254
401
|
win._initUrl = `${options?.url || ''}`;
|
|
255
402
|
// @ts-ignore
|
|
256
|
-
win?.removeAllListeners && win?.removeAllListeners?.();
|
|
257
|
-
win.webContents.removeAllListeners && win.webContents.removeAllListeners();
|
|
403
|
+
// win?.removeAllListeners && win?.removeAllListeners?.();
|
|
404
|
+
// win.webContents.removeAllListeners && win.webContents.removeAllListeners();
|
|
258
405
|
if (type === 'BW') {
|
|
259
406
|
// @ts-ignore
|
|
260
407
|
this._applyBrowserWindowOptions(win, options);
|
|
@@ -262,27 +409,79 @@ class WindowsManager {
|
|
|
262
409
|
if (type === 'BV') {
|
|
263
410
|
this._applyBrowserViewOptions(win, options);
|
|
264
411
|
}
|
|
412
|
+
if (typeof this.preloadWebContentsConfig?.customLoadURL === 'function') {
|
|
413
|
+
try {
|
|
414
|
+
if (type === 'BW') {
|
|
415
|
+
// @ts-ignore
|
|
416
|
+
const originLoadURL = win.loadURL;
|
|
417
|
+
// @ts-ignore
|
|
418
|
+
win.loadURL = async (url) => {
|
|
419
|
+
return new Promise(async (resolve, reject) => {
|
|
420
|
+
try {
|
|
421
|
+
console.error('customLoadURL win.loadURL');
|
|
422
|
+
// @ts-ignore
|
|
423
|
+
await this.preloadWebContentsConfig.customLoadURL(url || 'about:blank', (url) => originLoadURL.call(win, url), win.webContents);
|
|
424
|
+
try {
|
|
425
|
+
win.emit('ready-to-show');
|
|
426
|
+
}
|
|
427
|
+
catch (error) {
|
|
428
|
+
log('error', 'emit ready-to-show event failed:', error);
|
|
429
|
+
}
|
|
430
|
+
resolve(undefined);
|
|
431
|
+
}
|
|
432
|
+
catch (error) {
|
|
433
|
+
reject(error);
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
const originWebContentsLoadURL = win.webContents.loadURL;
|
|
439
|
+
// @ts-ignore
|
|
440
|
+
win.webContents.loadURL = async (url) => {
|
|
441
|
+
return new Promise(async (resolve, reject) => {
|
|
442
|
+
try {
|
|
443
|
+
console.error('customLoadURL win.webContents.loadURL');
|
|
444
|
+
// @ts-ignore
|
|
445
|
+
await this.preloadWebContentsConfig.customLoadURL(url || 'about:blank', (url) => originWebContentsLoadURL.call(win.webContents, url), win.webContents);
|
|
446
|
+
try {
|
|
447
|
+
win.webContents.emit('ready-to-show');
|
|
448
|
+
}
|
|
449
|
+
catch (error) {
|
|
450
|
+
log('error', 'emit ready-to-show event failed:', error);
|
|
451
|
+
}
|
|
452
|
+
resolve(undefined);
|
|
453
|
+
}
|
|
454
|
+
catch (error) {
|
|
455
|
+
reject(error);
|
|
456
|
+
}
|
|
457
|
+
});
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
catch (error) {
|
|
461
|
+
console.error('customLoadURL error', error);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
265
464
|
window = win;
|
|
266
465
|
}
|
|
267
466
|
try {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
467
|
+
loadingView.url = `${loadingView?.url ?? this.loadingViewUrl}`;
|
|
468
|
+
lodash.merge(options, {
|
|
469
|
+
loadingView,
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
catch (error) {
|
|
473
|
+
log('error', 'loadingView error:', loadingView, this.loadingViewUrl);
|
|
474
|
+
}
|
|
475
|
+
try {
|
|
476
|
+
errorView.url = `${errorView?.url ?? this.errorViewUrl}`;
|
|
477
|
+
lodash.merge(options, {
|
|
478
|
+
errorView,
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
catch (error) {
|
|
482
|
+
log('error', 'errorView error:', errorView, this.errorViewUrl);
|
|
483
|
+
}
|
|
484
|
+
try {
|
|
286
485
|
let parentWin = undefined;
|
|
287
486
|
if (typeof browserWindowOptions?.parent === 'number') {
|
|
288
487
|
parentWin = electron.BrowserWindow.fromId(browserWindowOptions?.parent) || undefined;
|
|
@@ -310,6 +509,7 @@ class WindowsManager {
|
|
|
310
509
|
nativeWindowOpen: true,
|
|
311
510
|
webSecurity: false,
|
|
312
511
|
preload: preload,
|
|
512
|
+
defaultEncoding: 'utf-8',
|
|
313
513
|
}, browserWindowOptions?.webPreferences || {})
|
|
314
514
|
}))
|
|
315
515
|
: new electron.BrowserWindow(lodash.merge({
|
|
@@ -326,6 +526,7 @@ class WindowsManager {
|
|
|
326
526
|
nativeWindowOpen: true,
|
|
327
527
|
webSecurity: false,
|
|
328
528
|
preload: preload,
|
|
529
|
+
defaultEncoding: 'utf-8',
|
|
329
530
|
}, browserWindowOptions?.webPreferences || {})
|
|
330
531
|
}));
|
|
331
532
|
log('log', `${name} 不使用 ${type === 'BV' ? 'preloadedBV' : 'preloadedBW'}`, window?.webContents?.id);
|
|
@@ -336,6 +537,8 @@ class WindowsManager {
|
|
|
336
537
|
log('error', 'enable: ', error);
|
|
337
538
|
}
|
|
338
539
|
}
|
|
540
|
+
// 停止加载
|
|
541
|
+
// window.webContents?.stop?.();
|
|
339
542
|
// @ts-ignore
|
|
340
543
|
try {
|
|
341
544
|
window.id = Number(`${window.id || window.webContents.id}`);
|
|
@@ -354,6 +557,8 @@ class WindowsManager {
|
|
|
354
557
|
window._name = name;
|
|
355
558
|
window._extraData = `${options?.extraData || ''}`;
|
|
356
559
|
window._initUrl = `${options?.url || ''}`;
|
|
560
|
+
// 设置zIndex层级
|
|
561
|
+
window._zIndex = options.zIndex ?? 0;
|
|
357
562
|
log('log', 'create 5: ', window.id, window._id, window._name);
|
|
358
563
|
if (loadingView?.url) {
|
|
359
564
|
if (type === 'BW') {
|
|
@@ -364,7 +569,7 @@ class WindowsManager {
|
|
|
364
569
|
if (errorView?.url) {
|
|
365
570
|
if (type === 'BW') {
|
|
366
571
|
const showErrorView = lodash.debounce(() => {
|
|
367
|
-
const _url = window
|
|
572
|
+
const _url = window._initUrl;
|
|
368
573
|
/**
|
|
369
574
|
* 判断是否是错误视图
|
|
370
575
|
*/
|
|
@@ -378,16 +583,37 @@ class WindowsManager {
|
|
|
378
583
|
sessionStorage.setItem(key, "${_url}");
|
|
379
584
|
`);
|
|
380
585
|
}
|
|
381
|
-
},
|
|
586
|
+
}, 1000);
|
|
382
587
|
// @ts-ignore
|
|
383
588
|
window.webContents.on('did-fail-load', (event, errorCode, errorDescription, validatedURL, isMainFrame) => {
|
|
384
589
|
if (isMainFrame) {
|
|
385
590
|
showErrorView();
|
|
386
591
|
}
|
|
387
592
|
});
|
|
593
|
+
// 当开始加载时取消错误视图
|
|
388
594
|
window.webContents.on('did-start-loading', () => {
|
|
389
595
|
showErrorView.cancel();
|
|
390
596
|
});
|
|
597
|
+
// 当导航开始时取消错误视图
|
|
598
|
+
window.webContents.on('did-start-navigation', () => {
|
|
599
|
+
showErrorView.cancel();
|
|
600
|
+
});
|
|
601
|
+
// 当页面重新加载时取消错误视图
|
|
602
|
+
window.webContents.on('did-navigate', () => {
|
|
603
|
+
showErrorView.cancel();
|
|
604
|
+
});
|
|
605
|
+
// 当页面完成加载时取消错误视图
|
|
606
|
+
window.webContents.on('did-finish-load', () => {
|
|
607
|
+
showErrorView.cancel();
|
|
608
|
+
});
|
|
609
|
+
// 当窗口关闭时取消错误视图
|
|
610
|
+
window.webContents.on('close', () => {
|
|
611
|
+
showErrorView.cancel();
|
|
612
|
+
});
|
|
613
|
+
// 当窗口销毁时取消错误视图
|
|
614
|
+
window.webContents.on('destroyed', () => {
|
|
615
|
+
showErrorView.cancel();
|
|
616
|
+
});
|
|
391
617
|
}
|
|
392
618
|
}
|
|
393
619
|
window.webContents.on('did-attach-webview', (_event, webContents) => {
|
|
@@ -469,10 +695,6 @@ class WindowsManager {
|
|
|
469
695
|
parentWin?.addBrowserView(window);
|
|
470
696
|
log('log', 'create - addBrowserView');
|
|
471
697
|
}
|
|
472
|
-
// @ts-ignore
|
|
473
|
-
window.loadURL ? window.loadURL(options.url) : window.webContents.loadURL(options.url);
|
|
474
|
-
// @ts-ignore
|
|
475
|
-
window.focus ? window.focus() : window.webContents.focus();
|
|
476
698
|
this.windows.set(window.id || window._id || window.webContents.id, window);
|
|
477
699
|
log('log', 'create', this.windows.keys());
|
|
478
700
|
// 初始化值
|
|
@@ -542,29 +764,51 @@ class WindowsManager {
|
|
|
542
764
|
});
|
|
543
765
|
try {
|
|
544
766
|
const _addBrowserView = window.addBrowserView;
|
|
545
|
-
window.addBrowserView = (view) => {
|
|
767
|
+
window.addBrowserView = (view, isSort = false) => {
|
|
546
768
|
_addBrowserView.call(window, view);
|
|
547
769
|
handleBrowserViewFocus(view);
|
|
770
|
+
// 添加BrowserView后重新排序(如果未禁用自动排序)
|
|
771
|
+
log('log', 'addBrowserView-sort', isSort, window.getBrowserViews());
|
|
772
|
+
if (isSort) {
|
|
773
|
+
this.sortBrowserViewsDebounced(window, view);
|
|
774
|
+
}
|
|
548
775
|
};
|
|
549
776
|
const _removeBrowserView = window.removeBrowserView;
|
|
550
|
-
window.removeBrowserView = (view) => {
|
|
777
|
+
window.removeBrowserView = (view, isSort = false) => {
|
|
551
778
|
_removeBrowserView.call(window, view);
|
|
552
779
|
handleBrowserViewBlur(view);
|
|
780
|
+
// 移除BrowserView后重新排序(如果未禁用自动排序)
|
|
781
|
+
log('log', 'removeBrowserView-sort', isSort);
|
|
782
|
+
if (isSort) {
|
|
783
|
+
this.sortBrowserViewsDebounced(window, view);
|
|
784
|
+
}
|
|
553
785
|
};
|
|
554
786
|
const _setBrowserView = window.setBrowserView;
|
|
555
|
-
window.setBrowserView = (view) => {
|
|
787
|
+
window.setBrowserView = (view, isSort = false) => {
|
|
556
788
|
const views = window.getBrowserViews() || [];
|
|
557
789
|
for (const view of views) {
|
|
558
790
|
handleBrowserViewBlur(view);
|
|
559
791
|
}
|
|
560
792
|
_setBrowserView.call(window, view);
|
|
561
793
|
handleBrowserViewFocus(view);
|
|
794
|
+
log('log', 'setBrowserView-sort', isSort);
|
|
795
|
+
if (isSort) {
|
|
796
|
+
this.sortBrowserViewsDebounced(window, view);
|
|
797
|
+
}
|
|
562
798
|
};
|
|
563
799
|
}
|
|
564
800
|
catch (error) {
|
|
565
801
|
log('error', 'focus', error);
|
|
566
802
|
}
|
|
567
803
|
}
|
|
804
|
+
if (options.url) {
|
|
805
|
+
// @ts-ignore
|
|
806
|
+
window.loadURL ? window.loadURL(options.url) : window.webContents.loadURL(options.url);
|
|
807
|
+
if (options.browserWindow?.focusable !== false) {
|
|
808
|
+
window?.focus?.();
|
|
809
|
+
}
|
|
810
|
+
window?.webContents?.focus?.();
|
|
811
|
+
}
|
|
568
812
|
}
|
|
569
813
|
catch (error) {
|
|
570
814
|
log('error', 'create', error);
|
|
@@ -588,7 +832,7 @@ class WindowsManager {
|
|
|
588
832
|
}
|
|
589
833
|
const loadLoadingView = () => {
|
|
590
834
|
const [viewWidth, viewHeight] = window.getSize();
|
|
591
|
-
window.
|
|
835
|
+
window.addBrowserView(_loadingView);
|
|
592
836
|
_loadingView.setBounds({
|
|
593
837
|
x: 0,
|
|
594
838
|
y: 0,
|
|
@@ -628,7 +872,7 @@ class WindowsManager {
|
|
|
628
872
|
return;
|
|
629
873
|
}
|
|
630
874
|
if (_loadingView.webContents && !_loadingView.webContents.isDestroyed()) {
|
|
631
|
-
window.
|
|
875
|
+
window.addBrowserView(_loadingView);
|
|
632
876
|
}
|
|
633
877
|
else {
|
|
634
878
|
// if loadingView has been destroyed
|
|
@@ -828,6 +1072,86 @@ class WindowsManager {
|
|
|
828
1072
|
if (typeof browserWindowOptions.alwaysOnTop === 'boolean') {
|
|
829
1073
|
win.setAlwaysOnTop(browserWindowOptions.alwaysOnTop);
|
|
830
1074
|
}
|
|
1075
|
+
// 设置背景颜色
|
|
1076
|
+
if (typeof browserWindowOptions.backgroundColor === 'string') {
|
|
1077
|
+
win.setBackgroundColor(browserWindowOptions.backgroundColor);
|
|
1078
|
+
}
|
|
1079
|
+
// 居中
|
|
1080
|
+
if (browserWindowOptions?.center !== false) {
|
|
1081
|
+
win.center();
|
|
1082
|
+
}
|
|
1083
|
+
// 设置窗口移动
|
|
1084
|
+
if (typeof browserWindowOptions.movable === 'boolean') {
|
|
1085
|
+
win.setMovable(browserWindowOptions.movable);
|
|
1086
|
+
}
|
|
1087
|
+
// 设置窗口大小调整
|
|
1088
|
+
if (typeof browserWindowOptions.resizable === 'boolean') {
|
|
1089
|
+
win.setResizable(browserWindowOptions.resizable);
|
|
1090
|
+
}
|
|
1091
|
+
// 设置全屏模式
|
|
1092
|
+
if (typeof browserWindowOptions.fullscreenable === 'boolean') {
|
|
1093
|
+
win.setFullScreenable(browserWindowOptions.fullscreenable);
|
|
1094
|
+
}
|
|
1095
|
+
// 设置窗口阴影
|
|
1096
|
+
if (typeof browserWindowOptions.hasShadow === 'boolean') {
|
|
1097
|
+
win.setHasShadow(browserWindowOptions.hasShadow);
|
|
1098
|
+
}
|
|
1099
|
+
// 设置窗口最小尺寸
|
|
1100
|
+
if (typeof browserWindowOptions.minWidth === 'number' && typeof browserWindowOptions.minHeight === 'number') {
|
|
1101
|
+
win.setMinimumSize(browserWindowOptions.minWidth, browserWindowOptions.minHeight);
|
|
1102
|
+
}
|
|
1103
|
+
// 设置窗口最大尺寸
|
|
1104
|
+
if (typeof browserWindowOptions.maxWidth === 'number' && typeof browserWindowOptions.maxHeight === 'number') {
|
|
1105
|
+
win.setMaximumSize(browserWindowOptions.maxWidth, browserWindowOptions.maxHeight);
|
|
1106
|
+
}
|
|
1107
|
+
// 设置窗口位置
|
|
1108
|
+
if (typeof browserWindowOptions.x === 'number' && typeof browserWindowOptions.y === 'number') {
|
|
1109
|
+
win.setPosition(browserWindowOptions.x, browserWindowOptions.y);
|
|
1110
|
+
}
|
|
1111
|
+
// 设置窗口标题
|
|
1112
|
+
if (typeof browserWindowOptions.title === 'string') {
|
|
1113
|
+
win.setTitle(browserWindowOptions.title);
|
|
1114
|
+
}
|
|
1115
|
+
// 设置窗口图标
|
|
1116
|
+
if (typeof browserWindowOptions.icon === 'string') {
|
|
1117
|
+
win.setIcon(browserWindowOptions.icon);
|
|
1118
|
+
}
|
|
1119
|
+
// 设置窗口菜单栏可见性
|
|
1120
|
+
if (typeof browserWindowOptions.autoHideMenuBar === 'boolean') {
|
|
1121
|
+
win.setAutoHideMenuBar(browserWindowOptions.autoHideMenuBar);
|
|
1122
|
+
}
|
|
1123
|
+
// 设置窗口最小化按钮
|
|
1124
|
+
if (browserWindowOptions.minimizable === false) {
|
|
1125
|
+
win.setMinimizable(false);
|
|
1126
|
+
}
|
|
1127
|
+
// 设置窗口最大化按钮
|
|
1128
|
+
if (browserWindowOptions.maximizable === false) {
|
|
1129
|
+
win.setMaximizable(false);
|
|
1130
|
+
}
|
|
1131
|
+
// 设置窗口关闭按钮
|
|
1132
|
+
if (browserWindowOptions.closable === false) {
|
|
1133
|
+
win.setClosable(false);
|
|
1134
|
+
}
|
|
1135
|
+
// 设置窗口焦点
|
|
1136
|
+
if (browserWindowOptions.focusable === false) {
|
|
1137
|
+
win.setFocusable(false);
|
|
1138
|
+
}
|
|
1139
|
+
// 设置窗口全屏
|
|
1140
|
+
if (browserWindowOptions.fullscreen === true) {
|
|
1141
|
+
win.setFullScreen(true);
|
|
1142
|
+
}
|
|
1143
|
+
// 设置窗口背景材质
|
|
1144
|
+
if (typeof browserWindowOptions.vibrancy === 'string') {
|
|
1145
|
+
win.setVibrancy(browserWindowOptions.vibrancy);
|
|
1146
|
+
}
|
|
1147
|
+
// 设置窗口透明度
|
|
1148
|
+
if (typeof browserWindowOptions.opacity === 'number') {
|
|
1149
|
+
win.setOpacity(browserWindowOptions.opacity);
|
|
1150
|
+
}
|
|
1151
|
+
// 设置窗口显示状态
|
|
1152
|
+
if (browserWindowOptions.show === false) {
|
|
1153
|
+
win.hide();
|
|
1154
|
+
}
|
|
831
1155
|
// 可继续扩展其他动态属性
|
|
832
1156
|
}
|
|
833
1157
|
_applyBrowserViewOptions(view, options) {
|
|
@@ -843,12 +1167,26 @@ class WindowsManager {
|
|
|
843
1167
|
if (typeof browserWindowOptions.width === 'number' && typeof browserWindowOptions.height === 'number') {
|
|
844
1168
|
view.setBounds({ x: 0, y: 0, width: browserWindowOptions.width, height: browserWindowOptions.height });
|
|
845
1169
|
}
|
|
1170
|
+
// 设置视图位置
|
|
1171
|
+
if (typeof browserWindowOptions.x === 'number' && typeof browserWindowOptions.y === 'number') {
|
|
1172
|
+
const bounds = view.getBounds();
|
|
1173
|
+
view.setBounds({
|
|
1174
|
+
x: browserWindowOptions.x,
|
|
1175
|
+
y: browserWindowOptions.y,
|
|
1176
|
+
width: bounds.width,
|
|
1177
|
+
height: bounds.height
|
|
1178
|
+
});
|
|
1179
|
+
}
|
|
1180
|
+
// 设置视图背景颜色
|
|
1181
|
+
if (typeof browserWindowOptions.backgroundColor === 'string') {
|
|
1182
|
+
view.setBackgroundColor(browserWindowOptions.backgroundColor);
|
|
1183
|
+
}
|
|
846
1184
|
// 可继续扩展其他动态属性
|
|
847
1185
|
}
|
|
848
1186
|
// 生成一个bv 做为预加载资源窗口,加载完成后销毁
|
|
849
1187
|
async createPreloadWebContents(url) {
|
|
850
1188
|
return new Promise(async (resolve, reject) => {
|
|
851
|
-
let bv = this.create({
|
|
1189
|
+
let bv = await this.create({
|
|
852
1190
|
type: 'BV',
|
|
853
1191
|
url,
|
|
854
1192
|
name: `preload-web-contents-${md5(url)}`,
|
|
@@ -867,11 +1205,108 @@ class WindowsManager {
|
|
|
867
1205
|
bv.webContents.loadURL(url);
|
|
868
1206
|
});
|
|
869
1207
|
}
|
|
1208
|
+
async getWindowForWebContentsId(wcId) {
|
|
1209
|
+
const wc = electron.webContents.fromId(wcId);
|
|
1210
|
+
if (!wc)
|
|
1211
|
+
return undefined;
|
|
1212
|
+
// Case 1: BrowserView
|
|
1213
|
+
for (const win of electron.BrowserWindow.getAllWindows()) {
|
|
1214
|
+
for (const view of win.getBrowserViews()) {
|
|
1215
|
+
if (view.webContents.id === wcId) {
|
|
1216
|
+
return win;
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
// Case 2: WebView
|
|
1221
|
+
// webview 有 hostWebContents,指向它所在的 BrowserWindow 的 webContents
|
|
1222
|
+
if (wc.hostWebContents) {
|
|
1223
|
+
return electron.BrowserWindow.fromWebContents(wc.hostWebContents);
|
|
1224
|
+
}
|
|
1225
|
+
// Case 3: 普通 window 本身
|
|
1226
|
+
const win = electron.BrowserWindow.fromWebContents(wc);
|
|
1227
|
+
if (win)
|
|
1228
|
+
return win;
|
|
1229
|
+
return undefined;
|
|
1230
|
+
}
|
|
1231
|
+
/**
|
|
1232
|
+
* 手动对BrowserView进行排序
|
|
1233
|
+
* @param windowId 窗口ID或名称
|
|
1234
|
+
*/
|
|
1235
|
+
sortBrowserViews(windowId) {
|
|
1236
|
+
const window = this.get(windowId);
|
|
1237
|
+
if (window && window._type === 'BW') {
|
|
1238
|
+
this._sortBrowserViews(window);
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
/**
|
|
1242
|
+
* 对BrowserView进行排序
|
|
1243
|
+
* @param window 目标窗口
|
|
1244
|
+
*/
|
|
1245
|
+
_sortBrowserViews(window, addView) {
|
|
1246
|
+
try {
|
|
1247
|
+
const views = window.getBrowserViews() || [];
|
|
1248
|
+
if (views.length <= 1)
|
|
1249
|
+
return;
|
|
1250
|
+
log('log', 'sortBrowserViews', views?.map(i => i.webContents.id));
|
|
1251
|
+
// 按zIndex层级排序,数值小的在前
|
|
1252
|
+
const sortedViews = views.sort((a, b) => {
|
|
1253
|
+
const zIndexA = a._zIndex ?? 0;
|
|
1254
|
+
const zIndexB = b._zIndex ?? 0;
|
|
1255
|
+
return zIndexA - zIndexB;
|
|
1256
|
+
});
|
|
1257
|
+
// 检查是否已经按正确顺序排列
|
|
1258
|
+
let needsReorder = false;
|
|
1259
|
+
for (let i = 0; i < views.length; i++) {
|
|
1260
|
+
// @ts-ignore
|
|
1261
|
+
if (views[i].webContents.id !== sortedViews[i].webContents.id) {
|
|
1262
|
+
needsReorder = true;
|
|
1263
|
+
break;
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
log('log', 'sortBrowserViews needsReorder', needsReorder, sortedViews?.map(i => i.webContents.id));
|
|
1267
|
+
// 如果已经按正确顺序排列,则不需要重新排序
|
|
1268
|
+
if (!needsReorder)
|
|
1269
|
+
return;
|
|
1270
|
+
// 使用批量操作来减少闪烁
|
|
1271
|
+
// 临时隐藏窗口内容
|
|
1272
|
+
const wasVisible = window.isVisible();
|
|
1273
|
+
if (wasVisible) {
|
|
1274
|
+
// window.hide();
|
|
1275
|
+
}
|
|
1276
|
+
// 移除所有BrowserView
|
|
1277
|
+
views.forEach(view => {
|
|
1278
|
+
if (addView?.webContents?.id !== view.webContents.id) {
|
|
1279
|
+
// @ts-ignore
|
|
1280
|
+
window.removeBrowserView(view, false);
|
|
1281
|
+
}
|
|
1282
|
+
});
|
|
1283
|
+
// 按正确顺序重新添加
|
|
1284
|
+
sortedViews.forEach((view, index) => {
|
|
1285
|
+
if (index === 0) {
|
|
1286
|
+
// 第一个设置为当前视图
|
|
1287
|
+
// @ts-ignore
|
|
1288
|
+
window.setBrowserView(view, false);
|
|
1289
|
+
}
|
|
1290
|
+
else {
|
|
1291
|
+
// 其他视图添加到后面
|
|
1292
|
+
// @ts-ignore
|
|
1293
|
+
window.addBrowserView(view, false);
|
|
1294
|
+
}
|
|
1295
|
+
});
|
|
1296
|
+
// 恢复窗口显示
|
|
1297
|
+
if (wasVisible) {
|
|
1298
|
+
// window.show();
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
catch (error) {
|
|
1302
|
+
log('error', 'sortBrowserViews error:', error);
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
870
1305
|
}
|
|
871
1306
|
// @ts-ignore
|
|
872
1307
|
global['__ELECTRON_WINDOWS_MANAGER__'] = undefined;
|
|
873
1308
|
exports.isInitialized = false;
|
|
874
|
-
const initialize = (preload, loadingViewUrl, errorViewUrl,
|
|
1309
|
+
const initialize = (preload, loadingViewUrl, errorViewUrl, preloadWebContentsConfig, webviewDomainWhiteList) => {
|
|
875
1310
|
// @ts-ignore
|
|
876
1311
|
if (exports.isInitialized && global['__ELECTRON_WINDOWS_MANAGER__']) {
|
|
877
1312
|
// @ts-ignore
|
|
@@ -879,7 +1314,7 @@ const initialize = (preload, loadingViewUrl, errorViewUrl, preloadWebContentsUrl
|
|
|
879
1314
|
}
|
|
880
1315
|
exports.isInitialized = true;
|
|
881
1316
|
// @ts-ignore
|
|
882
|
-
const wm = global['__ELECTRON_WINDOWS_MANAGER__'] = new WindowsManager(preload, loadingViewUrl, errorViewUrl,
|
|
1317
|
+
const wm = global['__ELECTRON_WINDOWS_MANAGER__'] = new WindowsManager(preload, loadingViewUrl, errorViewUrl, preloadWebContentsConfig, webviewDomainWhiteList);
|
|
883
1318
|
eIpc.mainIPC.handleRenderer('__ELECTRON_WINDOW_MANAGER_IPC_CHANNEL__', async (data) => {
|
|
884
1319
|
if (data?.type === 'create') {
|
|
885
1320
|
const opt = data;
|
|
@@ -895,21 +1330,39 @@ const initialize = (preload, loadingViewUrl, errorViewUrl, preloadWebContentsUrl
|
|
|
895
1330
|
findWin.webContents.reload();
|
|
896
1331
|
}, 100);
|
|
897
1332
|
}
|
|
1333
|
+
if (opt.data.browserWindow?.parent) {
|
|
1334
|
+
try {
|
|
1335
|
+
if (findWin._type === 'BW') {
|
|
1336
|
+
findWin.setParentWindow(electron.BrowserWindow.fromId(Number(opt.data.browserWindow.parent)));
|
|
1337
|
+
}
|
|
1338
|
+
if (findWin._type === 'BV') {
|
|
1339
|
+
electron.BrowserWindow.fromId(Number(opt.data.browserWindow.parent))?.addBrowserView(findWin);
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
catch (error) {
|
|
1343
|
+
log('error', 'setParentWindow error:', error);
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
if (findWin?._type === 'BV' && opt.data.zIndex) {
|
|
1347
|
+
findWin._zIndex = opt.data.zIndex;
|
|
1348
|
+
}
|
|
898
1349
|
return {
|
|
899
1350
|
winId: Number(`${findWin?.id || findWin?._id || -1}`),
|
|
900
1351
|
winName: `${findWin?._name || ''}`,
|
|
901
1352
|
winType: `${findWin?._type || ''}`,
|
|
902
1353
|
winExtraData: `${findWin?._extraData || ''}`,
|
|
903
1354
|
winInitUrl: `${findWin?._initUrl || ''}`,
|
|
1355
|
+
winZIndex: `${findWin._zIndex || 0}`,
|
|
904
1356
|
};
|
|
905
1357
|
}
|
|
906
|
-
const res = wm.create(opt.data);
|
|
1358
|
+
const res = await wm.create(opt.data);
|
|
907
1359
|
return {
|
|
908
1360
|
winId: Number(`${res.id || res._id || -1}`),
|
|
909
1361
|
winName: `${res?._name || ''}`,
|
|
910
1362
|
winType: `${res?._type || ''}`,
|
|
911
1363
|
winExtraData: `${res?._extraData || ''}`,
|
|
912
1364
|
winInitUrl: `${res?._initUrl || ''}`,
|
|
1365
|
+
winZIndex: `${res?._zIndex || 0}`,
|
|
913
1366
|
};
|
|
914
1367
|
}
|
|
915
1368
|
if (data?.type === 'get') {
|
|
@@ -921,6 +1374,7 @@ const initialize = (preload, loadingViewUrl, errorViewUrl, preloadWebContentsUrl
|
|
|
921
1374
|
winType: `${res?._type || ''}`,
|
|
922
1375
|
winExtraData: `${res?._extraData || ''}`,
|
|
923
1376
|
winInitUrl: `${res?._initUrl || ''}`,
|
|
1377
|
+
winZIndex: `${res?._zIndex || 0}`,
|
|
924
1378
|
};
|
|
925
1379
|
}
|
|
926
1380
|
if (data?.type === 'getAll') {
|
|
@@ -934,6 +1388,7 @@ const initialize = (preload, loadingViewUrl, errorViewUrl, preloadWebContentsUrl
|
|
|
934
1388
|
winType: `${i?._type || ''}`,
|
|
935
1389
|
winExtraData: `${i?._extraData || ''}`,
|
|
936
1390
|
winInitUrl: `${i?._initUrl || ''}`,
|
|
1391
|
+
winZIndex: `${i?._zIndex || 0}`,
|
|
937
1392
|
};
|
|
938
1393
|
});
|
|
939
1394
|
return obj;
|
|
@@ -957,6 +1412,7 @@ const initialize = (preload, loadingViewUrl, errorViewUrl, preloadWebContentsUrl
|
|
|
957
1412
|
winType: `${res?._type || ''}`,
|
|
958
1413
|
winExtraData: `${res?._extraData || ''}`,
|
|
959
1414
|
winInitUrl: `${res?._initUrl || ''}`,
|
|
1415
|
+
winZIndex: `${res?._zIndex || 0}`,
|
|
960
1416
|
};
|
|
961
1417
|
}
|
|
962
1418
|
return undefined;
|
|
@@ -971,34 +1427,16 @@ const initialize = (preload, loadingViewUrl, errorViewUrl, preloadWebContentsUrl
|
|
|
971
1427
|
winType: `${res?._type || ''}`,
|
|
972
1428
|
winExtraData: `${res?._extraData || ''}`,
|
|
973
1429
|
winInitUrl: `${res?._initUrl || ''}`,
|
|
1430
|
+
winZIndex: `${res?._zIndex || 0}`,
|
|
974
1431
|
};
|
|
975
1432
|
}
|
|
976
1433
|
return undefined;
|
|
977
1434
|
}
|
|
978
|
-
if (data?.type === '
|
|
1435
|
+
if (data?.type === 'getWindowForWebContentsId') {
|
|
979
1436
|
const opt = data;
|
|
980
|
-
const
|
|
981
|
-
if (
|
|
982
|
-
|
|
983
|
-
if (!win) {
|
|
984
|
-
// 获取所有的 BrowserWindows
|
|
985
|
-
let allWindows = electron.BrowserWindow.getAllWindows();
|
|
986
|
-
// 遍历所有窗口,检查每个窗口的 BrowserView
|
|
987
|
-
for (let _win of allWindows) {
|
|
988
|
-
let views = _win.getBrowserViews();
|
|
989
|
-
// 遍历窗口的所有 BrowserView
|
|
990
|
-
for (let view of views) {
|
|
991
|
-
if (view.webContents === targetWebContents) {
|
|
992
|
-
win = _win;
|
|
993
|
-
break;
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
|
-
if (win)
|
|
997
|
-
break;
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
// @ts-ignore
|
|
1001
|
-
return win?.id || win?._id;
|
|
1437
|
+
const res = await wm.getWindowForWebContentsId(opt.data);
|
|
1438
|
+
if (res) {
|
|
1439
|
+
return res?.id;
|
|
1002
1440
|
}
|
|
1003
1441
|
return undefined;
|
|
1004
1442
|
}
|
|
@@ -1039,15 +1477,20 @@ const initialize = (preload, loadingViewUrl, errorViewUrl, preloadWebContentsUrl
|
|
|
1039
1477
|
return undefined;
|
|
1040
1478
|
}
|
|
1041
1479
|
// 是否开启预加载窗口
|
|
1042
|
-
if (data?.type === '
|
|
1480
|
+
if (data?.type === 'setPreloadWebContentsConfig') {
|
|
1043
1481
|
const opt = data;
|
|
1044
|
-
wm.
|
|
1482
|
+
wm.setPreloadWebContentsConfig(opt.data);
|
|
1045
1483
|
}
|
|
1046
1484
|
if (data?.type === 'createPreloadWebContents') {
|
|
1047
1485
|
const opt = data;
|
|
1048
1486
|
const res = await wm.createPreloadWebContents(opt.data);
|
|
1049
1487
|
return res;
|
|
1050
1488
|
}
|
|
1489
|
+
if (data?.type === 'sortBrowserViews') {
|
|
1490
|
+
const opt = data;
|
|
1491
|
+
wm.sortBrowserViews(opt.data);
|
|
1492
|
+
return true;
|
|
1493
|
+
}
|
|
1051
1494
|
return undefined;
|
|
1052
1495
|
});
|
|
1053
1496
|
return wm;
|