@flighthq/host-electron 0.5.1-next.920.da8f530 → 0.6.0

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.
Files changed (137) hide show
  1. package/README.md +2 -2
  2. package/dist/contract.d.ts +19 -24
  3. package/dist/contract.d.ts.map +1 -1
  4. package/dist/contract.js +18 -24
  5. package/dist/contract.js.map +1 -1
  6. package/dist/electronApp.d.ts +62 -34
  7. package/dist/electronApp.d.ts.map +1 -1
  8. package/dist/electronApp.js +175 -234
  9. package/dist/electronApp.js.map +1 -1
  10. package/dist/electronClipboard.d.ts +7 -5
  11. package/dist/electronClipboard.d.ts.map +1 -1
  12. package/dist/electronClipboard.js +91 -66
  13. package/dist/electronClipboard.js.map +1 -1
  14. package/dist/electronDefaultHostGroups.d.ts +59 -0
  15. package/dist/electronDefaultHostGroups.d.ts.map +1 -0
  16. package/dist/electronDefaultHostGroups.js +109 -0
  17. package/dist/electronDefaultHostGroups.js.map +1 -0
  18. package/dist/electronDialog.d.ts +12 -9
  19. package/dist/electronDialog.d.ts.map +1 -1
  20. package/dist/electronDialog.js +28 -21
  21. package/dist/electronDialog.js.map +1 -1
  22. package/dist/electronIpc.d.ts +13 -11
  23. package/dist/electronIpc.d.ts.map +1 -1
  24. package/dist/electronIpc.js +32 -26
  25. package/dist/electronIpc.js.map +1 -1
  26. package/dist/electronMenu.d.ts +12 -6
  27. package/dist/electronMenu.d.ts.map +1 -1
  28. package/dist/electronMenu.js +41 -30
  29. package/dist/electronMenu.js.map +1 -1
  30. package/dist/electronMenuTemplate.d.ts +2 -1
  31. package/dist/electronMenuTemplate.d.ts.map +1 -1
  32. package/dist/electronMenuTemplate.js.map +1 -1
  33. package/dist/electronNotification.d.ts +25 -7
  34. package/dist/electronNotification.d.ts.map +1 -1
  35. package/dist/electronNotification.js +39 -16
  36. package/dist/electronNotification.js.map +1 -1
  37. package/dist/electronPlatform.d.ts +5 -3
  38. package/dist/electronPlatform.d.ts.map +1 -1
  39. package/dist/electronPlatform.js +9 -7
  40. package/dist/electronPlatform.js.map +1 -1
  41. package/dist/electronPower.d.ts +22 -11
  42. package/dist/electronPower.d.ts.map +1 -1
  43. package/dist/electronPower.js +48 -59
  44. package/dist/electronPower.js.map +1 -1
  45. package/dist/electronProtocol.d.ts +16 -8
  46. package/dist/electronProtocol.d.ts.map +1 -1
  47. package/dist/electronProtocol.js +45 -28
  48. package/dist/electronProtocol.js.map +1 -1
  49. package/dist/electronRegister.d.ts +5 -7
  50. package/dist/electronRegister.d.ts.map +1 -1
  51. package/dist/electronRegister.js +72 -99
  52. package/dist/electronRegister.js.map +1 -1
  53. package/dist/electronScreen.d.ts +7 -6
  54. package/dist/electronScreen.d.ts.map +1 -1
  55. package/dist/electronScreen.js +17 -14
  56. package/dist/electronScreen.js.map +1 -1
  57. package/dist/electronShell.d.ts +16 -8
  58. package/dist/electronShell.d.ts.map +1 -1
  59. package/dist/electronShell.js +50 -43
  60. package/dist/electronShell.js.map +1 -1
  61. package/dist/electronShortcut.d.ts +6 -4
  62. package/dist/electronShortcut.d.ts.map +1 -1
  63. package/dist/electronShortcut.js +16 -10
  64. package/dist/electronShortcut.js.map +1 -1
  65. package/dist/electronStorage.d.ts +5 -3
  66. package/dist/electronStorage.d.ts.map +1 -1
  67. package/dist/electronStorage.js +9 -7
  68. package/dist/electronStorage.js.map +1 -1
  69. package/dist/electronTray.d.ts +38 -21
  70. package/dist/electronTray.d.ts.map +1 -1
  71. package/dist/electronTray.js +110 -76
  72. package/dist/electronTray.js.map +1 -1
  73. package/dist/electronUpdater.d.ts +6 -3
  74. package/dist/electronUpdater.d.ts.map +1 -1
  75. package/dist/electronUpdater.js +10 -7
  76. package/dist/electronUpdater.js.map +1 -1
  77. package/dist/electronWindow.d.ts +23 -7
  78. package/dist/electronWindow.d.ts.map +1 -1
  79. package/dist/electronWindow.js +234 -152
  80. package/dist/electronWindow.js.map +1 -1
  81. package/dist/index.d.ts +19 -1
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +18 -1
  84. package/dist/index.js.map +1 -1
  85. package/dist/types/ElectronApi.d.ts +393 -0
  86. package/dist/types/ElectronApi.d.ts.map +1 -0
  87. package/dist/types/ElectronApi.js +20 -0
  88. package/dist/types/ElectronApi.js.map +1 -0
  89. package/dist/types/ElectronAppCapabilitiesFor.d.ts +8 -0
  90. package/dist/types/ElectronAppCapabilitiesFor.d.ts.map +1 -0
  91. package/dist/types/ElectronAppCapabilitiesFor.js +2 -0
  92. package/dist/types/ElectronAppCapabilitiesFor.js.map +1 -0
  93. package/dist/types/ElectronHost.d.ts +43 -0
  94. package/dist/types/ElectronHost.d.ts.map +1 -0
  95. package/dist/types/ElectronHost.js +2 -0
  96. package/dist/types/ElectronHost.js.map +1 -0
  97. package/dist/types/ElectronHostGroups.d.ts +85 -0
  98. package/dist/types/ElectronHostGroups.d.ts.map +1 -0
  99. package/dist/types/ElectronHostGroups.js +2 -0
  100. package/dist/types/ElectronHostGroups.js.map +1 -0
  101. package/dist/types/ElectronHostOptions.d.ts +7 -0
  102. package/dist/types/ElectronHostOptions.d.ts.map +1 -0
  103. package/dist/types/ElectronHostOptions.js +2 -0
  104. package/dist/types/ElectronHostOptions.js.map +1 -0
  105. package/dist/types/ElectronProtocolCapabilities.d.ts +3 -0
  106. package/dist/types/ElectronProtocolCapabilities.d.ts.map +1 -0
  107. package/dist/types/ElectronProtocolCapabilities.js +2 -0
  108. package/dist/types/ElectronProtocolCapabilities.js.map +1 -0
  109. package/dist/types/ElectronTrayCapabilitiesFor.d.ts +7 -0
  110. package/dist/types/ElectronTrayCapabilitiesFor.d.ts.map +1 -0
  111. package/dist/types/ElectronTrayCapabilitiesFor.js +2 -0
  112. package/dist/types/ElectronTrayCapabilitiesFor.js.map +1 -0
  113. package/dist/types/index.d.ts +7 -0
  114. package/dist/types/index.d.ts.map +1 -0
  115. package/dist/types/index.js +7 -0
  116. package/dist/types/index.js.map +1 -0
  117. package/package.json +42 -21
  118. package/src/electronApp.test.ts +158 -131
  119. package/src/electronClipboard.test.ts +40 -13
  120. package/src/electronDefaultHostGroups.test.ts +148 -0
  121. package/src/electronDialog.test.ts +55 -53
  122. package/src/electronHostTreeShaking.test.ts +51 -0
  123. package/src/electronIpc.test.ts +47 -66
  124. package/src/electronMenu.test.ts +61 -47
  125. package/src/electronMenuTemplate.test.ts +1 -1
  126. package/src/electronNotification.test.ts +71 -21
  127. package/src/electronPlatform.test.ts +17 -12
  128. package/src/electronPower.test.ts +112 -88
  129. package/src/electronProtocol.test.ts +68 -35
  130. package/src/electronRegister.test.ts +280 -26
  131. package/src/electronScreen.test.ts +34 -25
  132. package/src/electronShell.test.ts +99 -59
  133. package/src/electronShortcut.test.ts +22 -19
  134. package/src/electronStorage.test.ts +26 -24
  135. package/src/electronTray.test.ts +225 -109
  136. package/src/electronUpdater.test.ts +26 -19
  137. package/src/electronWindow.test.ts +229 -101
@@ -1,73 +1,39 @@
1
- import { notifyWindowClosed } from '@flighthq/application/contract';
2
- import { allocateEntity, finishEntity } from '@flighthq/entity/contract';
1
+ import { notifyWindowClosed } from '@flighthq/app/contract';
3
2
  import { emitSignal } from '@flighthq/signals/contract';
4
- export function createElectronWindowBackend(electron) {
5
- const out = allocateEntity();
6
- initializeElectronWindowBackend(out, electron);
7
- return finishEntity(out);
8
- }
9
- // Returns the ApplicationWindow mapped to the given Electron BrowserWindow id, or null when unknown.
10
- // Allows tray/menu/protocol handlers to resolve a native window id back into a Flight window entity.
11
- export function getApplicationWindowForElectronId(id) {
12
- return _windowsById.get(id) ?? null;
13
- }
14
- // The Electron BrowserWindow backing a Flight window opened via openWindow, or null if not (yet)
15
- // opened. The escape hatch a host app needs to do Electron-specific things the seam doesn't cover —
16
- // most importantly loadFile/loadURL to put content in the window. Host-adapter-only by design.
17
- export function getElectronBrowserWindow(win) {
18
- return _windows.get(win) ?? null;
19
- }
20
- // Returns the Electron BrowserWindow id for a Flight window, or -1 when the window is not mapped.
21
- // Useful for tray/menu click handlers that receive a native window id and need to resolve back to an
22
- // ApplicationWindow; pair with getApplicationWindowForElectronId.
23
- export function getElectronWindowId(win) {
24
- return _windows.get(win)?.id ?? -1;
25
- }
26
- // Maps Flight's WindowBackend onto Electron's BrowserWindow, one BrowserWindow per ApplicationWindow.
27
- // open() constructs the real OS window from WindowOptions and wires BrowserWindow OS events back to
28
- // the entity: each native event mutates the matching ApplicationWindow field and emits its signal, so
29
- // user-driven state changes (minimize, move, focus, …) flow through the same signals the command
30
- // functions emit. Other methods look up the BrowserWindow and no-op when it is absent (already closed
31
- // or never opened). Risky native calls are wrapped so a destroyed window cannot throw across the seam.
32
- export function initializeElectronWindowBackend(out, electron) {
33
- out.attach = (win, handle, ownership) => {
34
- if (!isElectronBrowserWindow(handle))
35
- return false;
36
- return attachElectronWindow(win, handle, ownership);
37
- };
38
- out.open = (win, options) => {
39
- if (_windowRecords.has(win))
40
- return true;
41
- const bw = new electron.BrowserWindow({
42
- title: options.title,
43
- x: options.x,
44
- y: options.y,
45
- width: options.width,
46
- height: options.height,
47
- resizable: options.resizable,
48
- alwaysOnTop: options.alwaysOnTop,
49
- fullscreen: options.fullscreen,
50
- show: options.visible,
51
- minWidth: options.minWidth,
52
- minHeight: options.minHeight,
53
- maxWidth: options.maxWidth,
54
- maxHeight: options.maxHeight,
55
- frame: options.frame,
56
- transparent: options.transparent,
57
- });
58
- if (attachElectronWindow(win, bw, 'flight'))
59
- return true;
60
- try {
61
- bw.close();
62
- }
63
- catch {
64
- /* construction succeeded but attachment failed */
65
- }
66
- return false;
67
- };
68
- out.close = (win) => {
69
- detachElectronWindow(win, true);
3
+ // Maps Flight's window capability slots onto Electron's BrowserWindow, one BrowserWindow per
4
+ // AppWindow. open() constructs the real OS window from WindowOptions and wires BrowserWindow OS
5
+ // events back to the entity: each native event mutates the matching AppWindow field and emits
6
+ // its signal, so user-driven state changes (minimize, move, focus, …) flow through the same signals the
7
+ // command functions emit. Other methods look up the BrowserWindow and no-op when it is absent (already
8
+ // closed or never opened). Risky native calls are wrapped so a destroyed window cannot throw across the
9
+ // seam.
10
+ //
11
+ // Electron covers every window capability slot. It omits the subscribe hooks inside geometry, lifecycle
12
+ // and visibility (subscribeMove, subscribeResize, subscribeClose, subscribeVisibility): an attached
13
+ // BrowserWindow's OS events are wired straight to the window's own signals in attachElectronWindow, so a
14
+ // second host-side subscription would report every change twice.
15
+ export function electronHostWindow(electron) {
16
+ return {
17
+ appearance: electronHostWindowAppearance(),
18
+ attach: electronHostWindowAttach(),
19
+ attention: electronHostWindowAttention(),
20
+ contentProtection: electronHostWindowContentProtection(),
21
+ focus: electronHostWindowFocus(),
22
+ fullscreen: electronHostWindowFullscreen(),
23
+ geometry: electronHostWindowGeometry(),
24
+ hierarchy: electronHostWindowHierarchy(),
25
+ lifecycle: electronHostWindowLifecycle(electron),
26
+ progress: electronHostWindowProgress(),
27
+ shadow: electronHostWindowShadow(),
28
+ shell: electronHostWindowShell(),
29
+ sizeConstraints: electronHostWindowSizeConstraints(),
30
+ state: electronHostWindowState(),
31
+ visibility: electronHostWindowVisibility(),
32
+ zOrder: electronHostWindowZOrder(),
70
33
  };
34
+ }
35
+ export function electronHostWindowAppearance() {
36
+ const out = {};
71
37
  out.setTitle = (win, title) => {
72
38
  const bw = _windows.get(win);
73
39
  if (bw === undefined)
@@ -79,121 +45,158 @@ export function initializeElectronWindowBackend(out, electron) {
79
45
  /* window already destroyed */
80
46
  }
81
47
  };
82
- out.setPosition = (win, x, y) => {
48
+ out.setIcon = (win, icon) => {
83
49
  const bw = _windows.get(win);
84
50
  if (bw === undefined)
85
51
  return;
86
52
  try {
87
- bw.setPosition(x, y);
53
+ bw.setIcon(icon);
88
54
  }
89
55
  catch {
90
56
  /* window already destroyed */
91
57
  }
92
58
  };
93
- out.setSize = (win, width, height) => {
59
+ out.setOpacity = (win, opacity) => {
94
60
  const bw = _windows.get(win);
95
61
  if (bw === undefined)
96
62
  return;
97
63
  try {
98
- bw.setSize(width, height);
64
+ bw.setOpacity(opacity);
99
65
  }
100
66
  catch {
101
67
  /* window already destroyed */
102
68
  }
103
69
  };
104
- out.getBounds = (win, out) => {
70
+ return out;
71
+ }
72
+ export function electronHostWindowAttach() {
73
+ const out = {};
74
+ out.attach = (win, handle, ownership) => {
75
+ if (!isElectronBrowserWindow(handle))
76
+ return false;
77
+ return attachElectronWindow(win, handle, ownership);
78
+ };
79
+ return out;
80
+ }
81
+ export function electronHostWindowAttention() {
82
+ const out = {};
83
+ out.requestAttention = (win, attention) => {
105
84
  const bw = _windows.get(win);
106
- if (bw === undefined) {
107
- out.x = win.x;
108
- out.y = win.y;
109
- out.width = win.width;
110
- out.height = win.height;
111
- return out;
112
- }
85
+ if (bw === undefined)
86
+ return;
113
87
  try {
114
- const bounds = bw.getBounds();
115
- out.x = bounds.x;
116
- out.y = bounds.y;
117
- out.width = bounds.width;
118
- out.height = bounds.height;
88
+ bw.flashFrame(attention);
119
89
  }
120
90
  catch {
121
- out.x = win.x;
122
- out.y = win.y;
123
- out.width = win.width;
124
- out.height = win.height;
91
+ /* window already destroyed */
125
92
  }
126
- return out;
127
93
  };
128
- out.minimize = (win) => {
94
+ out.flashWindowFrame = (win) => {
129
95
  const bw = _windows.get(win);
130
96
  if (bw === undefined)
131
97
  return;
132
98
  try {
133
- bw.minimize();
99
+ bw.flashFrame(true);
134
100
  }
135
101
  catch {
136
102
  /* window already destroyed */
137
103
  }
138
104
  };
139
- out.maximize = (win) => {
105
+ return out;
106
+ }
107
+ export function electronHostWindowContentProtection() {
108
+ const out = {};
109
+ out.setContentProtection = (win, enabled) => {
140
110
  const bw = _windows.get(win);
141
111
  if (bw === undefined)
142
112
  return;
143
113
  try {
144
- bw.maximize();
114
+ bw.setContentProtection(enabled);
145
115
  }
146
116
  catch {
147
117
  /* window already destroyed */
148
118
  }
149
119
  };
150
- out.restore = (win) => {
120
+ return out;
121
+ }
122
+ export function electronHostWindowFocus() {
123
+ const out = {};
124
+ out.focus = (win) => {
151
125
  const bw = _windows.get(win);
152
126
  if (bw === undefined)
153
127
  return;
154
128
  try {
155
- if (bw.isMinimized())
156
- bw.restore();
157
- else
158
- bw.unmaximize();
129
+ bw.focus();
159
130
  }
160
131
  catch {
161
132
  /* window already destroyed */
162
133
  }
163
134
  };
164
- out.focus = (win) => {
135
+ return out;
136
+ }
137
+ export function electronHostWindowFullscreen() {
138
+ const out = {};
139
+ out.setFullscreen = (win, fullscreen) => {
165
140
  const bw = _windows.get(win);
166
141
  if (bw === undefined)
167
142
  return;
168
143
  try {
169
- bw.focus();
144
+ bw.setFullScreen(fullscreen);
170
145
  }
171
146
  catch {
172
147
  /* window already destroyed */
173
148
  }
174
149
  };
175
- out.show = (win) => {
150
+ return out;
151
+ }
152
+ export function electronHostWindowGeometry() {
153
+ const out = {};
154
+ out.setPosition = (win, x, y) => {
176
155
  const bw = _windows.get(win);
177
156
  if (bw === undefined)
178
157
  return;
179
158
  try {
180
- bw.show();
159
+ bw.setPosition(x, y);
181
160
  }
182
161
  catch {
183
162
  /* window already destroyed */
184
163
  }
185
164
  };
186
- out.hide = (win) => {
165
+ out.setSize = (win, width, height) => {
187
166
  const bw = _windows.get(win);
188
167
  if (bw === undefined)
189
168
  return;
190
169
  try {
191
- bw.hide();
170
+ bw.setSize(width, height);
192
171
  }
193
172
  catch {
194
173
  /* window already destroyed */
195
174
  }
196
175
  };
176
+ out.getBounds = (win, out) => {
177
+ const bw = _windows.get(win);
178
+ if (bw === undefined) {
179
+ out.x = win.x;
180
+ out.y = win.y;
181
+ out.width = win.width;
182
+ out.height = win.height;
183
+ return out;
184
+ }
185
+ try {
186
+ const bounds = bw.getBounds();
187
+ out.x = bounds.x;
188
+ out.y = bounds.y;
189
+ out.width = bounds.width;
190
+ out.height = bounds.height;
191
+ }
192
+ catch {
193
+ out.x = win.x;
194
+ out.y = win.y;
195
+ out.width = win.width;
196
+ out.height = win.height;
197
+ }
198
+ return out;
199
+ };
197
200
  out.center = (win) => {
198
201
  const bw = _windows.get(win);
199
202
  if (bw === undefined)
@@ -205,183 +208,262 @@ export function initializeElectronWindowBackend(out, electron) {
205
208
  /* window already destroyed */
206
209
  }
207
210
  };
208
- out.setResizable = (win, resizable) => {
211
+ return out;
212
+ }
213
+ export function electronHostWindowHierarchy() {
214
+ const out = {};
215
+ out.setParent = (win, parent) => {
209
216
  const bw = _windows.get(win);
210
217
  if (bw === undefined)
211
218
  return;
219
+ const parentBw = parent === null ? null : (_windows.get(parent) ?? null);
212
220
  try {
213
- bw.setResizable(resizable);
221
+ bw.setParentWindow(parentBw);
214
222
  }
215
223
  catch {
216
224
  /* window already destroyed */
217
225
  }
218
226
  };
219
- out.setAlwaysOnTop = (win, alwaysOnTop) => {
220
- const bw = _windows.get(win);
221
- if (bw === undefined)
222
- return;
227
+ return out;
228
+ }
229
+ export function electronHostWindowLifecycle(electron) {
230
+ const out = {};
231
+ out.open = (win, options) => {
232
+ if (_windowRecords.has(win))
233
+ return true;
234
+ const bw = new electron.BrowserWindow({
235
+ title: options.title,
236
+ x: options.x,
237
+ y: options.y,
238
+ width: options.width,
239
+ height: options.height,
240
+ resizable: options.resizable,
241
+ alwaysOnTop: options.alwaysOnTop,
242
+ fullscreen: options.fullscreen,
243
+ show: options.visible,
244
+ minWidth: options.minWidth,
245
+ minHeight: options.minHeight,
246
+ maxWidth: options.maxWidth,
247
+ maxHeight: options.maxHeight,
248
+ frame: options.frame,
249
+ transparent: options.transparent,
250
+ });
251
+ if (attachElectronWindow(win, bw, 'flight'))
252
+ return true;
223
253
  try {
224
- bw.setAlwaysOnTop(alwaysOnTop);
254
+ bw.close();
225
255
  }
226
256
  catch {
227
- /* window already destroyed */
257
+ /* construction succeeded but attachment failed */
228
258
  }
259
+ return false;
229
260
  };
230
- out.setMinimumSize = (win, width, height) => {
261
+ out.close = (win) => {
262
+ detachElectronWindow(win, true);
263
+ };
264
+ return out;
265
+ }
266
+ export function electronHostWindowProgress() {
267
+ const out = {};
268
+ out.setProgress = (win, progress) => {
231
269
  const bw = _windows.get(win);
232
270
  if (bw === undefined)
233
271
  return;
234
272
  try {
235
- bw.setMinimumSize(width, height);
273
+ bw.setProgressBar(progress);
236
274
  }
237
275
  catch {
238
276
  /* window already destroyed */
239
277
  }
240
278
  };
241
- out.setMaximumSize = (win, width, height) => {
279
+ return out;
280
+ }
281
+ export function electronHostWindowShadow() {
282
+ const out = {};
283
+ out.setHasShadow = (win, hasShadow) => {
242
284
  const bw = _windows.get(win);
243
285
  if (bw === undefined)
244
286
  return;
245
287
  try {
246
- bw.setMaximumSize(width, height);
288
+ bw.setHasShadow(hasShadow);
247
289
  }
248
290
  catch {
249
291
  /* window already destroyed */
250
292
  }
251
293
  };
252
- out.setFullscreen = (win, fullscreen) => {
294
+ return out;
295
+ }
296
+ export function electronHostWindowShell() {
297
+ const out = {};
298
+ out.setSkipTaskbar = (win, skip) => {
253
299
  const bw = _windows.get(win);
254
300
  if (bw === undefined)
255
301
  return;
256
302
  try {
257
- bw.setFullScreen(fullscreen);
303
+ bw.setSkipTaskbar(skip);
258
304
  }
259
305
  catch {
260
306
  /* window already destroyed */
261
307
  }
262
308
  };
263
- out.setIcon = (win, icon) => {
309
+ out.setMenuBarVisible = (win, visible) => {
264
310
  const bw = _windows.get(win);
265
311
  if (bw === undefined)
266
312
  return;
267
313
  try {
268
- bw.setIcon(icon);
314
+ bw.setMenuBarVisibility(visible);
269
315
  }
270
316
  catch {
271
317
  /* window already destroyed */
272
318
  }
273
319
  };
274
- out.setOpacity = (win, opacity) => {
320
+ return out;
321
+ }
322
+ export function electronHostWindowSizeConstraints() {
323
+ const out = {};
324
+ out.setMinimumSize = (win, width, height) => {
275
325
  const bw = _windows.get(win);
276
326
  if (bw === undefined)
277
327
  return;
278
328
  try {
279
- bw.setOpacity(opacity);
329
+ bw.setMinimumSize(width, height);
280
330
  }
281
331
  catch {
282
332
  /* window already destroyed */
283
333
  }
284
334
  };
285
- out.setSkipTaskbar = (win, skip) => {
335
+ out.setMaximumSize = (win, width, height) => {
286
336
  const bw = _windows.get(win);
287
337
  if (bw === undefined)
288
338
  return;
289
339
  try {
290
- bw.setSkipTaskbar(skip);
340
+ bw.setMaximumSize(width, height);
291
341
  }
292
342
  catch {
293
343
  /* window already destroyed */
294
344
  }
295
345
  };
296
- out.setMenuBarVisible = (win, visible) => {
346
+ out.setResizable = (win, resizable) => {
297
347
  const bw = _windows.get(win);
298
348
  if (bw === undefined)
299
349
  return;
300
350
  try {
301
- bw.setMenuBarVisibility(visible);
351
+ bw.setResizable(resizable);
302
352
  }
303
353
  catch {
304
354
  /* window already destroyed */
305
355
  }
306
356
  };
307
- out.setParent = (win, parent) => {
357
+ return out;
358
+ }
359
+ export function electronHostWindowState() {
360
+ const out = {};
361
+ out.minimize = (win) => {
308
362
  const bw = _windows.get(win);
309
363
  if (bw === undefined)
310
364
  return;
311
- const parentBw = parent === null ? null : (_windows.get(parent) ?? null);
312
365
  try {
313
- bw.setParentWindow(parentBw);
366
+ bw.minimize();
314
367
  }
315
368
  catch {
316
369
  /* window already destroyed */
317
370
  }
318
371
  };
319
- out.setProgress = (win, progress) => {
372
+ out.maximize = (win) => {
320
373
  const bw = _windows.get(win);
321
374
  if (bw === undefined)
322
375
  return;
323
376
  try {
324
- bw.setProgressBar(progress);
377
+ bw.maximize();
325
378
  }
326
379
  catch {
327
380
  /* window already destroyed */
328
381
  }
329
382
  };
330
- out.requestAttention = (win, attention) => {
383
+ out.restore = (win) => {
331
384
  const bw = _windows.get(win);
332
385
  if (bw === undefined)
333
386
  return;
334
387
  try {
335
- bw.flashFrame(attention);
388
+ if (bw.isMinimized())
389
+ bw.restore();
390
+ else
391
+ bw.unmaximize();
336
392
  }
337
393
  catch {
338
394
  /* window already destroyed */
339
395
  }
340
396
  };
341
- out.setContentProtection = (win, enabled) => {
397
+ return out;
398
+ }
399
+ export function electronHostWindowVisibility() {
400
+ const out = {};
401
+ out.show = (win) => {
342
402
  const bw = _windows.get(win);
343
403
  if (bw === undefined)
344
404
  return;
345
405
  try {
346
- bw.setContentProtection(enabled);
406
+ bw.show();
347
407
  }
348
408
  catch {
349
409
  /* window already destroyed */
350
410
  }
351
411
  };
352
- out.flashWindowFrame = (win) => {
412
+ out.hide = (win) => {
353
413
  const bw = _windows.get(win);
354
414
  if (bw === undefined)
355
415
  return;
356
416
  try {
357
- bw.flashFrame(true);
417
+ bw.hide();
358
418
  }
359
419
  catch {
360
420
  /* window already destroyed */
361
421
  }
362
422
  };
363
- out.setHasShadow = (win, hasShadow) => {
423
+ return out;
424
+ }
425
+ export function electronHostWindowZOrder() {
426
+ const out = {};
427
+ out.setAlwaysOnTop = (win, alwaysOnTop) => {
364
428
  const bw = _windows.get(win);
365
429
  if (bw === undefined)
366
430
  return;
367
431
  try {
368
- bw.setHasShadow(hasShadow);
432
+ bw.setAlwaysOnTop(alwaysOnTop);
369
433
  }
370
434
  catch {
371
435
  /* window already destroyed */
372
436
  }
373
437
  };
438
+ return out;
439
+ }
440
+ // Returns the AppWindow mapped to the given Electron BrowserWindow id, or null when unknown.
441
+ // Allows tray/menu/protocol handlers to resolve a native window id back into a Flight window entity.
442
+ export function getAppWindowForElectronId(id) {
443
+ return _windowsById.get(id) ?? null;
444
+ }
445
+ // The Electron BrowserWindow backing a Flight window opened via openWindow, or null if not (yet)
446
+ // opened. The escape hatch a host app needs to do Electron-specific things the seam doesn't cover —
447
+ // most importantly loadFile/loadURL to put content in the window. Host-adapter-only by design.
448
+ export function getElectronBrowserWindow(win) {
449
+ return _windows.get(win) ?? null;
450
+ }
451
+ // Returns the Electron BrowserWindow id for a Flight window, or -1 when the window is not mapped.
452
+ // Useful for tray/menu click handlers that receive a native window id and need to resolve back to an
453
+ // AppWindow; pair with getAppWindowForElectronId.
454
+ export function getElectronWindowId(win) {
455
+ return _windows.get(win)?.id ?? -1;
374
456
  }
375
- export function resetElectronWindowBackendForTest() {
457
+ export function resetElectronHostWindowForTest() {
376
458
  _windows = new WeakMap();
377
459
  _windowRecords = new WeakMap();
378
460
  _windowsById.clear();
379
461
  }
380
- // Side table mapping each Flight ApplicationWindow to its Electron BrowserWindow, kept off the public
462
+ // Side table mapping each Flight AppWindow to its Electron BrowserWindow, kept off the public
381
463
  // entity. Entries are removed on close so a stale BrowserWindow is never reused.
382
464
  let _windows = new WeakMap();
383
465
  let _windowRecords = new WeakMap();
384
- // Reverse lookup by Electron BrowserWindow id for getApplicationWindowForElectronId. Maintained in
466
+ // Reverse lookup by Electron BrowserWindow id for getAppWindowForElectronId. Maintained in
385
467
  // lockstep with _windows; entries are removed on close as well.
386
468
  const _windowsById = new Map();
387
469
  function attachElectronWindow(win, handle, ownership) {
@@ -399,44 +481,44 @@ function attachElectronWindow(win, handle, ownership) {
399
481
  const bounds = handle.getBounds();
400
482
  win.x = bounds.x;
401
483
  win.y = bounds.y;
402
- emitSignal(win.onMove);
484
+ emitSignal(win.onMove, undefined);
403
485
  });
404
486
  addElectronWindowListener(record, 'resize', () => {
405
487
  const bounds = handle.getBounds();
406
488
  win.width = bounds.width;
407
489
  win.height = bounds.height;
408
- emitSignal(win.onResize);
490
+ emitSignal(win.onResize, undefined);
409
491
  });
410
492
  addElectronWindowListener(record, 'minimize', () => {
411
493
  win.minimized = true;
412
- emitSignal(win.onMinimize);
494
+ emitSignal(win.onMinimize, undefined);
413
495
  });
414
496
  addElectronWindowListener(record, 'maximize', () => {
415
497
  win.maximized = true;
416
- emitSignal(win.onMaximize);
498
+ emitSignal(win.onMaximize, undefined);
417
499
  });
418
500
  const onUnmaximize = () => {
419
501
  win.minimized = false;
420
502
  win.maximized = false;
421
- emitSignal(win.onRestore);
503
+ emitSignal(win.onRestore, undefined);
422
504
  };
423
505
  addElectronWindowListener(record, 'unmaximize', onUnmaximize);
424
506
  addElectronWindowListener(record, 'restore', onUnmaximize);
425
507
  addElectronWindowListener(record, 'enter-full-screen', () => {
426
508
  win.fullscreen = true;
427
- emitSignal(win.onFullscreenChanged);
509
+ emitSignal(win.onFullscreenChanged, undefined);
428
510
  });
429
511
  addElectronWindowListener(record, 'leave-full-screen', () => {
430
512
  win.fullscreen = false;
431
- emitSignal(win.onFullscreenChanged);
513
+ emitSignal(win.onFullscreenChanged, undefined);
432
514
  });
433
515
  addElectronWindowListener(record, 'focus', () => {
434
516
  win.focused = true;
435
- emitSignal(win.onFocusIn);
517
+ emitSignal(win.onFocusIn, undefined);
436
518
  });
437
519
  addElectronWindowListener(record, 'blur', () => {
438
520
  win.focused = false;
439
- emitSignal(win.onFocusOut);
521
+ emitSignal(win.onFocusOut, undefined);
440
522
  });
441
523
  addElectronWindowListener(record, 'closed', () => {
442
524
  detachElectronWindow(win, false);