@lynker-desktop/electron-window-manager 0.0.9-alpha.50 → 0.0.9-alpha.51

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/main/index.js CHANGED
@@ -6,14 +6,14 @@ const md5 = require('md5');
6
6
  const PQueue = require('p-queue');
7
7
 
8
8
  function _interopNamespaceDefault(e) {
9
- const n = Object.create(null);
10
- if (e) {
11
- for (const k in e) {
12
- n[k] = e[k];
9
+ const n = Object.create(null);
10
+ if (e) {
11
+ for (const k in e) {
12
+ n[k] = e[k];
13
+ }
13
14
  }
14
- }
15
- n.default = e;
16
- return n;
15
+ n.default = e;
16
+ return n;
17
17
  }
18
18
 
19
19
  const remote__namespace = /*#__PURE__*/_interopNamespaceDefault(remote);
@@ -47,21 +47,30 @@ const enable = (win) => {
47
47
  remote__namespace.enable(win);
48
48
  };
49
49
  const initWebContentsVal = (win, preload) => {
50
- win.webContents.executeJavaScript(`
51
50
  try {
52
- const data = {
53
- __ELECTRON_WINDOW_MANAGER_WEB_CONTENTS_ID__: ${JSON.stringify(win.webContents.id)},
54
- __ELECTRON_WINDOW_MANAGER_TYPE__: ${JSON.stringify(win._type)},
55
- __ELECTRON_WINDOW_MANAGER_NAME__: ${JSON.stringify(win._name)},
56
- __ELECTRON_WINDOW_MANAGER_EXTRA_DATA__: ${JSON.stringify(win._extraData || '')},
57
- __ELECTRON_WINDOW_MANAGER_PRELOAD__: ${JSON.stringify(preload)},
58
- __ELECTRON_WINDOW_MANAGER_INIT_URL__: ${JSON.stringify(win._initUrl || '')}
59
- };
60
- Object.entries(data).forEach(([key, value]) => {
61
- window[key] = value;
62
- });
63
- } catch (error) {}
64
- `);
51
+ if (!win?.webContents || win.webContents.isDestroyed()) {
52
+ return;
53
+ }
54
+ const webContentsId = win.webContents.id;
55
+ win.webContents.executeJavaScript(`
56
+ try {
57
+ const data = {
58
+ __ELECTRON_WINDOW_MANAGER_WEB_CONTENTS_ID__: ${JSON.stringify(webContentsId)},
59
+ __ELECTRON_WINDOW_MANAGER_TYPE__: ${JSON.stringify(win._type)},
60
+ __ELECTRON_WINDOW_MANAGER_NAME__: ${JSON.stringify(win._name)},
61
+ __ELECTRON_WINDOW_MANAGER_EXTRA_DATA__: ${JSON.stringify(win._extraData || '')},
62
+ __ELECTRON_WINDOW_MANAGER_PRELOAD__: ${JSON.stringify(preload)},
63
+ __ELECTRON_WINDOW_MANAGER_INIT_URL__: ${JSON.stringify(win._initUrl || '')}
64
+ };
65
+ Object.entries(data).forEach(([key, value]) => {
66
+ window[key] = value;
67
+ });
68
+ } catch (error) {}
69
+ `);
70
+ }
71
+ catch (error) {
72
+ // 忽略错误,webContents 可能已销毁
73
+ }
65
74
  };
66
75
  class WindowsManager {
67
76
  /**
@@ -272,14 +281,18 @@ class WindowsManager {
272
281
  log('error', '预加载 BW 设置 remote 失败', error);
273
282
  }
274
283
  try {
275
- // @ts-ignore
276
- instance._id = instance.webContents.id;
284
+ const webContentsId = instance.webContents?.id;
285
+ if (webContentsId !== undefined) {
286
+ // @ts-ignore
287
+ instance._id = webContentsId;
288
+ }
277
289
  }
278
290
  catch (error) {
279
291
  log('error', '预加载 BW 设置 _id 失败', error);
280
292
  }
281
293
  // @ts-ignore
282
- log('log', '创建预BW: ', instance._id, this.preloadWebContentsConfig?.url);
294
+ const webContentsId = instance.webContents?.id;
295
+ log('log', '创建预BW: ', webContentsId, this.preloadWebContentsConfig?.url);
283
296
  // instance.webContents.once('did-finish-load', () => {
284
297
  // resolve(instance as BWItem);
285
298
  // });
@@ -326,8 +339,11 @@ class WindowsManager {
326
339
  log('error', '预加载 BV 设置 remote 失败', error);
327
340
  }
328
341
  try {
329
- // @ts-ignore
330
- instance._id = instance.webContents.id;
342
+ const webContentsId = instance.webContents?.id;
343
+ if (webContentsId !== undefined) {
344
+ // @ts-ignore
345
+ instance._id = webContentsId;
346
+ }
331
347
  // 设置默认zIndex层级
332
348
  instance._zIndex = 0;
333
349
  }
@@ -335,7 +351,8 @@ class WindowsManager {
335
351
  log('error', '预加载 BV 设置 _id 失败', error);
336
352
  }
337
353
  // @ts-ignore
338
- log('log', '创建预BV: ', instance._id, this.preloadWebContentsConfig?.url);
354
+ const webContentsId = instance.webContents?.id;
355
+ log('log', '创建预BV: ', webContentsId, this.preloadWebContentsConfig?.url);
339
356
  // instance.webContents.once('did-finish-load', () => {
340
357
  // resolve(instance as BVItem);
341
358
  // });
@@ -431,7 +448,7 @@ class WindowsManager {
431
448
  }
432
449
  if (preloadWin) {
433
450
  const win = preloadWin;
434
- log('log', `${name} 使用预加载窗口(${type})`, win._id);
451
+ log('log', `${name} 使用预加载窗口(${type})`, this._getWebContentsId(win));
435
452
  win._type = type;
436
453
  win._name = options.name || 'anonymous';
437
454
  win._extraData = `${options?.extraData || ''}`;
@@ -601,15 +618,12 @@ class WindowsManager {
601
618
  // 停止加载
602
619
  // window.webContents?.stop?.();
603
620
  // @ts-ignore
604
- try {
605
- window.id = Number(`${window.id || window.webContents.id}`);
606
- }
607
- catch (error) {
608
- // log('error', 'set id: ', error)
609
- }
610
621
  // @ts-ignore
611
622
  try {
612
- window._id = Number(`${window.id || window.webContents.id}`);
623
+ const webContentsId = this._getWebContentsId(window);
624
+ if (webContentsId !== undefined) {
625
+ window._id = Number(`${webContentsId}`);
626
+ }
613
627
  }
614
628
  catch (error) {
615
629
  // log('error', 'set id: ', error)
@@ -620,7 +634,7 @@ class WindowsManager {
620
634
  window._initUrl = `${options?.url || ''}`;
621
635
  // 设置zIndex层级
622
636
  window._zIndex = options.zIndex ?? 0;
623
- log('log', 'create 5: ', window.id, window._id, window._name);
637
+ log('log', 'create 5: ', this._getWebContentsId(window), window._name);
624
638
  if (loadingView?.url && loadingView?.url !== 'about:blank') {
625
639
  if (type === 'BW') {
626
640
  // @ts-ignore
@@ -733,8 +747,10 @@ class WindowsManager {
733
747
  // this.windows.delete(window.id || window._id)
734
748
  // })
735
749
  window.webContents.on('destroyed', () => {
736
- const winId = window.id || window._id;
737
- this.windows.delete(winId);
750
+ const winId = this._getWebContentsId(window);
751
+ if (winId !== undefined) {
752
+ this.windows.delete(winId);
753
+ }
738
754
  // 同步清理名称索引
739
755
  this.windowsByName.delete(window._name);
740
756
  });
@@ -750,9 +766,11 @@ class WindowsManager {
750
766
  }
751
767
  // @ts-ignore
752
768
  window.on('closed', () => {
753
- log('log', 'closed', window.id, window._name);
754
- const winId = window.id || window._id;
755
- this.windows.delete(winId);
769
+ const winId = this._getWebContentsId(window);
770
+ log('log', 'closed', winId, window._name);
771
+ if (winId !== undefined) {
772
+ this.windows.delete(winId);
773
+ }
756
774
  // 同步清理名称索引
757
775
  this.windowsByName.delete(window._name);
758
776
  });
@@ -761,18 +779,20 @@ class WindowsManager {
761
779
  parentWin?.addBrowserView(window);
762
780
  log('log', 'create - addBrowserView');
763
781
  }
764
- const winId = window.id || window._id || window.webContents.id;
765
- this.windows.set(winId, window);
766
- // 同步更新名称索引
767
- this.windowsByName.set(window._name, winId);
782
+ const winId = this._getWebContentsId(window);
783
+ if (winId !== undefined) {
784
+ this.windows.set(winId, window);
785
+ // 同步更新名称索引
786
+ this.windowsByName.set(window._name, winId);
787
+ }
768
788
  log('log', 'create', this.windows.keys());
769
789
  // 初始化值
770
790
  window.webContents.on('did-finish-load', () => {
771
- log('log', 'did-finish-load', window.webContents.id);
791
+ log('log', 'did-finish-load', this._getWebContentsId(window));
772
792
  initWebContentsVal(window, `${preload || ''}`);
773
793
  });
774
794
  window.webContents.on('did-start-loading', () => {
775
- log('log', 'did-start-loading', window.webContents.id);
795
+ log('log', 'did-start-loading', this._getWebContentsId(window));
776
796
  initWebContentsVal(window, `${preload || ''}`);
777
797
  });
778
798
  if (type === 'BW') {
@@ -973,6 +993,24 @@ class WindowsManager {
973
993
  return true;
974
994
  }
975
995
  }
996
+ /**
997
+ * 安全地获取窗口的 webContents.id
998
+ * 如果 webContents 已销毁,返回 undefined
999
+ */
1000
+ _getWebContentsId(win) {
1001
+ try {
1002
+ if (!win || !win.webContents) {
1003
+ return undefined;
1004
+ }
1005
+ if (win.webContents.isDestroyed()) {
1006
+ return undefined;
1007
+ }
1008
+ return win.webContents.id;
1009
+ }
1010
+ catch {
1011
+ return undefined;
1012
+ }
1013
+ }
976
1014
  /**
977
1015
  * 判断是否本地/内网IP
978
1016
  */
@@ -1004,16 +1042,8 @@ class WindowsManager {
1004
1042
  log('log', 'get', idOrName);
1005
1043
  let win;
1006
1044
  if (typeof idOrName === 'number') {
1007
- // 按 ID 查找(O(1)
1045
+ // 按 ID 查找(O(1)),使用 webContents.id
1008
1046
  win = this.windows.get(idOrName);
1009
- // 如果找不到,尝试按 _id 查找
1010
- if (!win) {
1011
- this.windows.forEach(w => {
1012
- if (w._id === idOrName) {
1013
- win = w;
1014
- }
1015
- });
1016
- }
1017
1047
  }
1018
1048
  else if (typeof idOrName === 'string') {
1019
1049
  // 按名称查找(O(1),使用索引)
@@ -1026,8 +1056,11 @@ class WindowsManager {
1026
1056
  this.windows.forEach(w => {
1027
1057
  if (w._name === idOrName) {
1028
1058
  win = w;
1029
- // 更新索引
1030
- this.windowsByName.set(idOrName, w.id || w._id);
1059
+ // 更新索引,使用 webContents.id
1060
+ const webContentsId = this._getWebContentsId(w);
1061
+ if (webContentsId !== undefined) {
1062
+ this.windowsByName.set(idOrName, webContentsId);
1063
+ }
1031
1064
  }
1032
1065
  });
1033
1066
  }
@@ -1038,7 +1071,7 @@ class WindowsManager {
1038
1071
  }
1039
1072
  // 窗口已销毁,触发清理
1040
1073
  if (win) {
1041
- const winId = win.id || win._id;
1074
+ const winId = this._getWebContentsId(win);
1042
1075
  if (winId !== undefined) {
1043
1076
  this.windows.delete(winId);
1044
1077
  }
@@ -1081,8 +1114,10 @@ class WindowsManager {
1081
1114
  if (!win) {
1082
1115
  return false;
1083
1116
  }
1084
- const winId = win.id || win._id;
1085
- this.windows.delete(winId);
1117
+ const winId = this._getWebContentsId(win);
1118
+ if (winId !== undefined) {
1119
+ this.windows.delete(winId);
1120
+ }
1086
1121
  if (win._name) {
1087
1122
  this.windowsByName.delete(win._name);
1088
1123
  }
@@ -1168,9 +1203,11 @@ class WindowsManager {
1168
1203
  }
1169
1204
  // 更新名称索引
1170
1205
  const oldName = win._name;
1171
- const winId = win.id || win._id;
1172
- this.windowsByName.delete(oldName);
1173
- this.windowsByName.set(newName, winId);
1206
+ const winId = this._getWebContentsId(win);
1207
+ if (winId !== undefined) {
1208
+ this.windowsByName.delete(oldName);
1209
+ this.windowsByName.set(newName, winId);
1210
+ }
1174
1211
  // 修改名字并同步 webContents
1175
1212
  win._name = newName;
1176
1213
  initWebContentsVal(win, `${this.preload || ''}`);
@@ -1329,7 +1366,7 @@ class WindowsManager {
1329
1366
  extraData: `${url}`
1330
1367
  });
1331
1368
  return new Promise((resolve, reject) => {
1332
- const winId = bv.id || bv._id;
1369
+ const winId = this._getWebContentsId(bv);
1333
1370
  if (!winId) {
1334
1371
  reject(new Error('Failed to get window ID'));
1335
1372
  return;
@@ -1353,7 +1390,7 @@ class WindowsManager {
1353
1390
  }
1354
1391
  catch (error) {
1355
1392
  if (bv) {
1356
- const winId = bv.id || bv._id;
1393
+ const winId = this._getWebContentsId(bv);
1357
1394
  if (winId) {
1358
1395
  this.close(winId);
1359
1396
  }
@@ -1406,7 +1443,7 @@ class WindowsManager {
1406
1443
  const views = window.getBrowserViews() || [];
1407
1444
  if (views.length <= 1)
1408
1445
  return;
1409
- log('log', 'sortBrowserViews', views?.map(i => i.webContents.id));
1446
+ log('log', 'sortBrowserViews', views?.map(i => this._getWebContentsId(i)));
1410
1447
  // 创建排序后的视图数组(不修改原数组)
1411
1448
  const sortedViews = [...views].sort((a, b) => {
1412
1449
  const zIndexA = a._zIndex ?? 0;
@@ -1418,18 +1455,22 @@ class WindowsManager {
1418
1455
  for (let i = 0; i < views.length; i++) {
1419
1456
  const view = views[i];
1420
1457
  const sortedView = sortedViews[i];
1421
- if (!view || !sortedView || view.webContents.id !== sortedView.webContents.id) {
1458
+ const viewId = this._getWebContentsId(view);
1459
+ const sortedViewId = this._getWebContentsId(sortedView);
1460
+ if (!view || !sortedView || viewId !== sortedViewId) {
1422
1461
  needsReorder = true;
1423
1462
  break;
1424
1463
  }
1425
1464
  }
1426
- log('log', 'sortBrowserViews needsReorder', needsReorder, sortedViews?.map(i => i.webContents.id));
1465
+ log('log', 'sortBrowserViews needsReorder', needsReorder, sortedViews?.map(i => this._getWebContentsId(i)));
1427
1466
  // 如果已经按正确顺序排列,则不需要重新排序
1428
1467
  if (!needsReorder)
1429
1468
  return;
1430
1469
  // 移除所有BrowserView(排除刚添加的视图,避免不必要的操作)
1470
+ const addViewId = this._getWebContentsId(addView);
1431
1471
  views.forEach(view => {
1432
- if (addView?.webContents?.id !== view.webContents.id) {
1472
+ const viewId = this._getWebContentsId(view);
1473
+ if (addViewId !== viewId) {
1433
1474
  try {
1434
1475
  // @ts-ignore
1435
1476
  window.removeBrowserView(view, false);
@@ -1506,8 +1547,9 @@ const initialize = (preload, loadingViewUrl, errorViewUrl, preloadWebContentsCon
1506
1547
  if (findWin?._type === 'BV' && opt.data.zIndex) {
1507
1548
  findWin._zIndex = opt.data.zIndex;
1508
1549
  }
1550
+ const winId = wm._getWebContentsId(findWin);
1509
1551
  return {
1510
- winId: Number(`${findWin?.id || findWin?._id || -1}`),
1552
+ winId: Number(`${winId || -1}`),
1511
1553
  winName: `${findWin?._name || ''}`,
1512
1554
  winType: `${findWin?._type || ''}`,
1513
1555
  winExtraData: `${findWin?._extraData || ''}`,
@@ -1516,8 +1558,9 @@ const initialize = (preload, loadingViewUrl, errorViewUrl, preloadWebContentsCon
1516
1558
  };
1517
1559
  }
1518
1560
  const res = await wm.create(opt.data);
1561
+ const winId = wm._getWebContentsId(res);
1519
1562
  return {
1520
- winId: Number(`${res.id || res._id || -1}`),
1563
+ winId: Number(`${winId || -1}`),
1521
1564
  winName: `${res?._name || ''}`,
1522
1565
  winType: `${res?._type || ''}`,
1523
1566
  winExtraData: `${res?._extraData || ''}`,
@@ -1528,8 +1571,9 @@ const initialize = (preload, loadingViewUrl, errorViewUrl, preloadWebContentsCon
1528
1571
  if (data?.type === 'get') {
1529
1572
  const opt = data;
1530
1573
  const res = wm.get(opt?.data);
1574
+ const winId = wm._getWebContentsId(res);
1531
1575
  return {
1532
- winId: Number(`${res?.id || res?._id || -1}`),
1576
+ winId: Number(`${winId || -1}`),
1533
1577
  winName: `${res?._name || ''}`,
1534
1578
  winType: `${res?._type || ''}`,
1535
1579
  winExtraData: `${res?._extraData || ''}`,
@@ -1541,7 +1585,7 @@ const initialize = (preload, loadingViewUrl, errorViewUrl, preloadWebContentsCon
1541
1585
  const res = wm.getAll();
1542
1586
  const obj = {};
1543
1587
  res.forEach(i => {
1544
- const winId = i.id || i._id;
1588
+ const winId = wm._getWebContentsId(i);
1545
1589
  if (winId !== undefined) {
1546
1590
  obj[winId] = {
1547
1591
  winId: Number(`${winId}`),
@@ -1568,8 +1612,9 @@ const initialize = (preload, loadingViewUrl, errorViewUrl, preloadWebContentsCon
1568
1612
  const opt = data;
1569
1613
  const res = wm.rename(opt.data.idOrName, opt.data.newName);
1570
1614
  if (res) {
1615
+ const winId = wm._getWebContentsId(res);
1571
1616
  return {
1572
- winId: Number(`${res?.id || res?._id || -1}`),
1617
+ winId: Number(`${winId || -1}`),
1573
1618
  winName: `${res?._name || ''}`,
1574
1619
  winType: `${res?._type || ''}`,
1575
1620
  winExtraData: `${res?._extraData || ''}`,
@@ -1583,8 +1628,9 @@ const initialize = (preload, loadingViewUrl, errorViewUrl, preloadWebContentsCon
1583
1628
  const opt = data;
1584
1629
  const res = wm.reInitUrl(opt.data.idOrName, opt.data.url);
1585
1630
  if (res) {
1631
+ const winId = wm._getWebContentsId(res);
1586
1632
  return {
1587
- winId: Number(`${res?.id || res?._id || -1}`),
1633
+ winId: Number(`${winId || -1}`),
1588
1634
  winName: `${res?._name || ''}`,
1589
1635
  winType: `${res?._type || ''}`,
1590
1636
  winExtraData: `${res?._extraData || ''}`,
@@ -1598,7 +1644,7 @@ const initialize = (preload, loadingViewUrl, errorViewUrl, preloadWebContentsCon
1598
1644
  const opt = data;
1599
1645
  const res = await wm.getWindowForWebContentsId(opt.data);
1600
1646
  if (res) {
1601
- return res?.id;
1647
+ return wm._getWebContentsId(res);
1602
1648
  }
1603
1649
  return undefined;
1604
1650
  }