@raydiant/playlist-window-manager 0.0.0-test-27 → 0.0.0-test-29
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/build/BrowserViewRenderer.d.ts +1 -1
- package/build/BrowserViewRenderer.js +1 -5
- package/build/BrowserWindowRenderer.d.ts +0 -9
- package/build/BrowserWindowRenderer.js +18 -174
- package/build/PlaylistWindowManager.d.ts +6 -1
- package/build/PlaylistWindowManager.js +39 -2
- package/build/PresentationWindow.d.ts +8 -1
- package/build/PresentationWindow.js +101 -9
- package/build/PresentationWindow.test.js +99 -0
- package/build/testUtils.js +1 -0
- package/build/types.d.ts +20 -1
- package/package.json +6 -8
- package/src/BrowserViewRenderer.ts +1 -18
- package/src/BrowserWindowRenderer.ts +28 -307
- package/src/PlaylistWindowManager.ts +59 -13
- package/src/PresentationWindow.test.ts +112 -0
- package/src/PresentationWindow.ts +128 -34
- package/src/testUtils.ts +1 -0
- package/src/types.ts +24 -1
- package/tasks/npm-publish.sh +1 -1
- package/build/boundUtils.d.ts +0 -3
- package/build/boundUtils.js +0 -16
- package/src/boundUtils.ts +0 -21
|
@@ -3,12 +3,11 @@ import {
|
|
|
3
3
|
BrowserWindow,
|
|
4
4
|
BrowserView,
|
|
5
5
|
ipcMain,
|
|
6
|
-
screen,
|
|
7
6
|
IpcMainEvent,
|
|
8
7
|
Event,
|
|
9
|
-
Details,
|
|
10
8
|
BrowserWindowConstructorOptions,
|
|
11
9
|
BrowserViewConstructorOptions,
|
|
10
|
+
RenderProcessGoneDetails,
|
|
12
11
|
} from 'electron';
|
|
13
12
|
import {
|
|
14
13
|
PresentationWindowRenderer,
|
|
@@ -16,9 +15,7 @@ import {
|
|
|
16
15
|
WindowBounds,
|
|
17
16
|
Logger,
|
|
18
17
|
} from './types';
|
|
19
|
-
import lodash from 'lodash';
|
|
20
18
|
import WindowUnresponsiveError from './WindowUnresponsiveError';
|
|
21
|
-
import { areBoundsEqual, isFullscreen } from './boundUtils';
|
|
22
19
|
|
|
23
20
|
interface ProxySettings {
|
|
24
21
|
proxyRules: string;
|
|
@@ -35,7 +32,10 @@ interface BrowserWindowRendererWindow {
|
|
|
35
32
|
payload?: any
|
|
36
33
|
) => void;
|
|
37
34
|
unresponsiveCallback: () => void;
|
|
38
|
-
renderProcessGoneCallback: (
|
|
35
|
+
renderProcessGoneCallback: (
|
|
36
|
+
event: Event,
|
|
37
|
+
details: RenderProcessGoneDetails
|
|
38
|
+
) => void;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
interface BrowserWindowRendererOptions {
|
|
@@ -55,9 +55,6 @@ export default class BrowserWindowRenderer
|
|
|
55
55
|
private windows: {
|
|
56
56
|
[windowId: string]: BrowserWindowRendererWindow;
|
|
57
57
|
} = {};
|
|
58
|
-
private windowsBounds: {
|
|
59
|
-
[windowId: string]: WindowBounds;
|
|
60
|
-
} = {};
|
|
61
58
|
private windowCrashHandler: (reason: string) => void = (_: string) => {};
|
|
62
59
|
|
|
63
60
|
private browserWindowPool = new WindowPool<BrowserWindow>();
|
|
@@ -65,14 +62,12 @@ export default class BrowserWindowRenderer
|
|
|
65
62
|
|
|
66
63
|
// Create a hidden window to preload BrowserViews.
|
|
67
64
|
private offscreenWindow = new BrowserWindow({
|
|
68
|
-
...this.opts.bounds,
|
|
69
65
|
show: false,
|
|
70
66
|
frame: this.opts.frame,
|
|
71
67
|
hasShadow: this.opts.hasShadow,
|
|
72
|
-
useContentSize: true,
|
|
73
|
-
fullscreen: isFullscreen(this.opts.bounds),
|
|
74
68
|
webPreferences: {
|
|
75
69
|
preload: path.join(__dirname, 'preload.js'),
|
|
70
|
+
contextIsolation: false,
|
|
76
71
|
},
|
|
77
72
|
});
|
|
78
73
|
|
|
@@ -81,28 +76,13 @@ export default class BrowserWindowRenderer
|
|
|
81
76
|
private logger: Logger;
|
|
82
77
|
|
|
83
78
|
constructor(private opts: BrowserWindowRendererOptions) {
|
|
84
|
-
this.
|
|
85
|
-
opts.logger.info(
|
|
86
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts constructor1 ${JSON.stringify(
|
|
87
|
-
opts.bounds
|
|
88
|
-
)}`
|
|
89
|
-
);
|
|
90
|
-
this.setWindowOrViewBounds(this.offscreenWindow, opts.bounds);
|
|
91
|
-
opts.logger.info(
|
|
92
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts constructor2 ${JSON.stringify(
|
|
93
|
-
{
|
|
94
|
-
fullscreen: this.offscreenWindow.isFullScreen(),
|
|
95
|
-
bounds: this.offscreenWindow.getBounds(),
|
|
96
|
-
normalBounds: this.offscreenWindow.getNormalBounds(),
|
|
97
|
-
contentBounds: this.offscreenWindow.getContentBounds(),
|
|
98
|
-
}
|
|
99
|
-
)}`
|
|
100
|
-
);
|
|
101
|
-
|
|
79
|
+
this.offscreenWindow.setBounds(opts.bounds);
|
|
102
80
|
if (opts.proxySettings) {
|
|
103
81
|
this.proxySettings = opts.proxySettings;
|
|
104
82
|
}
|
|
105
83
|
|
|
84
|
+
this.logger = opts.logger;
|
|
85
|
+
|
|
106
86
|
if (opts.windowCrashHandler) {
|
|
107
87
|
this.windowCrashHandler = opts.windowCrashHandler;
|
|
108
88
|
}
|
|
@@ -115,21 +95,7 @@ export default class BrowserWindowRenderer
|
|
|
115
95
|
backgroundColor,
|
|
116
96
|
receiveMessageCallback,
|
|
117
97
|
errorCallback,
|
|
118
|
-
}: CreateWindowOptions)
|
|
119
|
-
const windowBounds =
|
|
120
|
-
parentWindowId && !this.opts.renderChildWindowsAsBrowserViews
|
|
121
|
-
? {
|
|
122
|
-
...bounds,
|
|
123
|
-
x: bounds.x + this.opts.bounds.x,
|
|
124
|
-
y: bounds.y + this.opts.bounds.y,
|
|
125
|
-
}
|
|
126
|
-
: bounds;
|
|
127
|
-
|
|
128
|
-
this.logger.info(
|
|
129
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts createWindow1: ${JSON.stringify(
|
|
130
|
-
windowBounds
|
|
131
|
-
)}`
|
|
132
|
-
);
|
|
98
|
+
}: CreateWindowOptions) {
|
|
133
99
|
const window: BrowserWindowRendererWindow = {
|
|
134
100
|
parentWindowId,
|
|
135
101
|
// If we are creating a child window and renderChildWindowsAsBrowserViews is true,
|
|
@@ -144,7 +110,6 @@ export default class BrowserWindowRenderer
|
|
|
144
110
|
: this.createOrGetPooledBrowserWindow(windowId, {
|
|
145
111
|
show: false,
|
|
146
112
|
frame: this.opts.frame,
|
|
147
|
-
fullscreen: isFullscreen(this.opts.bounds),
|
|
148
113
|
// NOTE: useWindowPool: true does not work with renderChildWindowsAsBrowserViews: false
|
|
149
114
|
// because the parent can't be changed after creating the BrowserWindow.
|
|
150
115
|
parent: parentWindowId
|
|
@@ -154,13 +119,21 @@ export default class BrowserWindowRenderer
|
|
|
154
119
|
hasShadow: this.opts.hasShadow,
|
|
155
120
|
webPreferences: {
|
|
156
121
|
preload: path.join(__dirname, 'preload.js'),
|
|
122
|
+
contextIsolation: false,
|
|
157
123
|
},
|
|
158
124
|
}),
|
|
159
125
|
// If we are creating a child window and renderChildWindowsAsBrowserViews is false that means
|
|
160
126
|
// we are rendering child windows with BrowserWindow. BrowserWindows are positioned absolutely so
|
|
161
127
|
// to place them in the correct spot relative to their parent we need to add the main window's x / y.
|
|
162
128
|
// BrowserViews are relatively positioned so we don't need to do that.
|
|
163
|
-
bounds:
|
|
129
|
+
bounds:
|
|
130
|
+
parentWindowId && !this.opts.renderChildWindowsAsBrowserViews
|
|
131
|
+
? {
|
|
132
|
+
...bounds,
|
|
133
|
+
x: bounds.x + this.opts.bounds.x,
|
|
134
|
+
y: bounds.y + this.opts.bounds.y,
|
|
135
|
+
}
|
|
136
|
+
: bounds,
|
|
164
137
|
|
|
165
138
|
receiveMessageCallback: (
|
|
166
139
|
_: IpcMainEvent,
|
|
@@ -180,7 +153,10 @@ export default class BrowserWindowRenderer
|
|
|
180
153
|
);
|
|
181
154
|
},
|
|
182
155
|
|
|
183
|
-
renderProcessGoneCallback: (
|
|
156
|
+
renderProcessGoneCallback: (
|
|
157
|
+
_: Event,
|
|
158
|
+
details: RenderProcessGoneDetails
|
|
159
|
+
) => {
|
|
184
160
|
this.logger.error(
|
|
185
161
|
`Window received 'render-process-gone' event. Reason: ${details.reason}`,
|
|
186
162
|
{ windowId }
|
|
@@ -209,20 +185,9 @@ export default class BrowserWindowRenderer
|
|
|
209
185
|
|
|
210
186
|
if (window.view instanceof BrowserView) {
|
|
211
187
|
this.moveWindowOffscreen(window);
|
|
212
|
-
this.logger.info(
|
|
213
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts createWindow2: ${JSON.stringify(
|
|
214
|
-
{
|
|
215
|
-
fullscreen: this.offscreenWindow.isFullScreen(),
|
|
216
|
-
bounds: this.offscreenWindow.getBounds(),
|
|
217
|
-
normalBounds: this.offscreenWindow.getNormalBounds(),
|
|
218
|
-
contentBounds: this.offscreenWindow.getContentBounds(),
|
|
219
|
-
}
|
|
220
|
-
)}`
|
|
221
|
-
);
|
|
222
188
|
}
|
|
223
189
|
|
|
224
190
|
this.windows[windowId] = window;
|
|
225
|
-
this.windowsBounds[windowId] = lodash.cloneDeep(windowBounds);
|
|
226
191
|
// Listen for messages from window.
|
|
227
192
|
ipcMain.on(windowId, window.receiveMessageCallback);
|
|
228
193
|
|
|
@@ -234,49 +199,7 @@ export default class BrowserWindowRenderer
|
|
|
234
199
|
);
|
|
235
200
|
}
|
|
236
201
|
|
|
237
|
-
|
|
238
|
-
this.logger.info(
|
|
239
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts createWindow4: ${JSON.stringify(
|
|
240
|
-
{
|
|
241
|
-
newBounds: window.bounds,
|
|
242
|
-
fullscreen: window.view.isFullScreen(),
|
|
243
|
-
bounds: window.view.getBounds(),
|
|
244
|
-
contentBounds: window.view.getContentBounds(),
|
|
245
|
-
normalBounds: window.view.getNormalBounds(),
|
|
246
|
-
}
|
|
247
|
-
)}`
|
|
248
|
-
);
|
|
249
|
-
} else {
|
|
250
|
-
this.logger.info(
|
|
251
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts createWindow5: ${JSON.stringify(
|
|
252
|
-
{
|
|
253
|
-
newBounds: window.bounds,
|
|
254
|
-
bounds: window.view.getBounds(),
|
|
255
|
-
}
|
|
256
|
-
)}`
|
|
257
|
-
);
|
|
258
|
-
}
|
|
259
|
-
this.setWindowOrViewBounds(window.view, window.bounds);
|
|
260
|
-
if (window.view instanceof BrowserWindow) {
|
|
261
|
-
this.logger.info(
|
|
262
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts createWindow7: ${JSON.stringify(
|
|
263
|
-
{
|
|
264
|
-
fullscreen: window.view.isFullScreen(),
|
|
265
|
-
bounds: window.view.getBounds(),
|
|
266
|
-
contentBounds: window.view.getContentBounds(),
|
|
267
|
-
normalBounds: window.view.getNormalBounds(),
|
|
268
|
-
}
|
|
269
|
-
)}`
|
|
270
|
-
);
|
|
271
|
-
} else {
|
|
272
|
-
this.logger.info(
|
|
273
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts createWindow8: ${JSON.stringify(
|
|
274
|
-
{
|
|
275
|
-
bounds: window.view.getBounds(),
|
|
276
|
-
}
|
|
277
|
-
)}`
|
|
278
|
-
);
|
|
279
|
-
}
|
|
202
|
+
window.view.setBounds(window.bounds);
|
|
280
203
|
|
|
281
204
|
if (this.proxySettings) {
|
|
282
205
|
await window.view.webContents.session.setProxy(this.proxySettings);
|
|
@@ -304,95 +227,28 @@ export default class BrowserWindowRenderer
|
|
|
304
227
|
`Failed to update window bounds, missing window id '${windowId}'`
|
|
305
228
|
);
|
|
306
229
|
}
|
|
307
|
-
|
|
308
|
-
this.logger.info(
|
|
309
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts updateWindowBounds1: ${JSON.stringify(
|
|
310
|
-
bounds
|
|
311
|
-
)}`
|
|
312
|
-
);
|
|
313
230
|
window.bounds = bounds;
|
|
314
231
|
|
|
315
232
|
if (window.view instanceof BrowserWindow && window.parentWindowId) {
|
|
316
233
|
// Child BrowserWindows are absolutely positioned so we need to add the main windows
|
|
317
234
|
// x/y to when updating the child window's bounds.
|
|
318
|
-
|
|
235
|
+
window.view.setBounds({
|
|
319
236
|
...window.bounds,
|
|
320
237
|
x: window.bounds.x + this.opts.bounds.x,
|
|
321
238
|
y: window.bounds.y + this.opts.bounds.y,
|
|
322
|
-
};
|
|
323
|
-
this.logger.info(
|
|
324
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts updateWindowBounds2: ${JSON.stringify(
|
|
325
|
-
newBounds
|
|
326
|
-
)}`
|
|
327
|
-
);
|
|
328
|
-
this.setWindowOrViewBounds(window.view, newBounds);
|
|
329
|
-
|
|
330
|
-
this.logger.info(
|
|
331
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts updateWindowBounds3: ${JSON.stringify(
|
|
332
|
-
{
|
|
333
|
-
fullscreen: window.view.isFullScreen(),
|
|
334
|
-
bounds: window.view.getBounds(),
|
|
335
|
-
normalBounds: window.view.getNormalBounds(),
|
|
336
|
-
contentBounds: window.view.getContentBounds(),
|
|
337
|
-
}
|
|
338
|
-
)}`
|
|
339
|
-
);
|
|
239
|
+
});
|
|
340
240
|
} else {
|
|
341
|
-
|
|
342
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts updateWindowBounds4: ${JSON.stringify(
|
|
343
|
-
window.bounds
|
|
344
|
-
)}`
|
|
345
|
-
);
|
|
346
|
-
this.setWindowOrViewBounds(window.view, window.bounds);
|
|
347
|
-
this.logger.info(
|
|
348
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts updateWindowBounds5: ${JSON.stringify(
|
|
349
|
-
window.view.getBounds()
|
|
350
|
-
)}`
|
|
351
|
-
);
|
|
241
|
+
window.view.setBounds(window.bounds);
|
|
352
242
|
}
|
|
353
243
|
}
|
|
354
244
|
|
|
355
245
|
public showWindow(windowId: string, isFocused: boolean) {
|
|
356
|
-
this.logger.info(
|
|
357
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts showWindow1: ${windowId}`
|
|
358
|
-
);
|
|
359
246
|
const window = this.getWindow(windowId);
|
|
360
|
-
|
|
361
|
-
if (!window || !windowBounds) {
|
|
247
|
+
if (!window) {
|
|
362
248
|
throw new Error(`Failed to show window, missing window id '${windowId}'`);
|
|
363
249
|
}
|
|
364
250
|
|
|
365
251
|
if (window.view instanceof BrowserWindow) {
|
|
366
|
-
this.logger.info(
|
|
367
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts showWindow2: ${JSON.stringify(
|
|
368
|
-
{
|
|
369
|
-
fullscreen: window.view.isFullScreen(),
|
|
370
|
-
isMaximized: window.view.isMaximized(),
|
|
371
|
-
bounds: window.view.getBounds(),
|
|
372
|
-
windowBounds: windowBounds,
|
|
373
|
-
normalBounds: window.view.getNormalBounds(),
|
|
374
|
-
contentBounds: window.view.getContentBounds(),
|
|
375
|
-
}
|
|
376
|
-
)}`
|
|
377
|
-
);
|
|
378
|
-
if (!areBoundsEqual(window.view.getBounds(), windowBounds)) {
|
|
379
|
-
this.logger.info(
|
|
380
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts showWindow3: setWindowOrViewBounds`
|
|
381
|
-
);
|
|
382
|
-
this.setWindowOrViewBounds(window.view, windowBounds);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
this.logger.info(
|
|
386
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts showWindow4: ${JSON.stringify(
|
|
387
|
-
{
|
|
388
|
-
fullscreen: window.view.isFullScreen(),
|
|
389
|
-
isMaximized: window.view.isMaximized(),
|
|
390
|
-
bounds: window.view.getBounds(),
|
|
391
|
-
normalBounds: window.view.getNormalBounds(),
|
|
392
|
-
contentBounds: window.view.getContentBounds(),
|
|
393
|
-
}
|
|
394
|
-
)}`
|
|
395
|
-
);
|
|
396
252
|
if (isFocused) {
|
|
397
253
|
window.view.show();
|
|
398
254
|
} else {
|
|
@@ -453,7 +309,6 @@ export default class BrowserWindowRenderer
|
|
|
453
309
|
}
|
|
454
310
|
|
|
455
311
|
delete this.windows[windowId];
|
|
456
|
-
delete this.windowsBounds[windowId];
|
|
457
312
|
|
|
458
313
|
if (this.opts.useWindowPool) {
|
|
459
314
|
this.logPoolStats();
|
|
@@ -502,125 +357,10 @@ export default class BrowserWindowRenderer
|
|
|
502
357
|
window.view.webContents.setAudioMuted(false);
|
|
503
358
|
}
|
|
504
359
|
|
|
505
|
-
/**
|
|
506
|
-
* This function is designed to solve missing 1px issue.
|
|
507
|
-
* If we set 1920x1080 bounds on 1920x1080 display
|
|
508
|
-
* then the actual BrowserWindow resolution would be
|
|
509
|
-
* 1919x1079.
|
|
510
|
-
*/
|
|
511
|
-
private setWindowOrViewBounds(
|
|
512
|
-
window: BrowserWindow | BrowserView,
|
|
513
|
-
bounds: WindowBounds
|
|
514
|
-
) {
|
|
515
|
-
if (window instanceof BrowserView) {
|
|
516
|
-
this.logger.info(
|
|
517
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts setWindowOrViewBounds1: ${JSON.stringify(
|
|
518
|
-
{
|
|
519
|
-
windowBounds: window.getBounds(),
|
|
520
|
-
bounds,
|
|
521
|
-
}
|
|
522
|
-
)}`
|
|
523
|
-
);
|
|
524
|
-
window.setBounds(bounds);
|
|
525
|
-
return;
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
this.logger.info(
|
|
529
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts setWindowOrViewBounds2: ${JSON.stringify(
|
|
530
|
-
{
|
|
531
|
-
newBounds: bounds,
|
|
532
|
-
fullscreen: window.isFullScreen(),
|
|
533
|
-
isMaximized: window.isMaximized(),
|
|
534
|
-
bounds: window.getBounds(),
|
|
535
|
-
contentBounds: window.getContentBounds(),
|
|
536
|
-
normalBounds: window.getNormalBounds(),
|
|
537
|
-
}
|
|
538
|
-
)}`
|
|
539
|
-
);
|
|
540
|
-
|
|
541
|
-
// calling setBounds or setFullscreen may introduce -1px resolution error
|
|
542
|
-
// so we try to avoid unnecessary calls
|
|
543
|
-
if (areBoundsEqual(window.getBounds(), bounds)) {
|
|
544
|
-
this.logger.info(
|
|
545
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts setWindowOrViewBounds3: bounds are equal`
|
|
546
|
-
);
|
|
547
|
-
return;
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
if (isFullscreen(bounds) !== window.isFullScreen()) {
|
|
551
|
-
this.logger.info(
|
|
552
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts setWindowOrViewBounds4: setFullScreen`
|
|
553
|
-
);
|
|
554
|
-
window.setFullScreen(isFullscreen(bounds));
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
this.logger.info(
|
|
558
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts setWindowOrViewBounds5: ${JSON.stringify(
|
|
559
|
-
{
|
|
560
|
-
fullscreen: window.isFullScreen(),
|
|
561
|
-
isMaximized: window.isMaximized(),
|
|
562
|
-
bounds: window.getBounds(),
|
|
563
|
-
contentBounds: window.getContentBounds(),
|
|
564
|
-
normalBounds: window.getNormalBounds(),
|
|
565
|
-
}
|
|
566
|
-
)}`
|
|
567
|
-
);
|
|
568
|
-
|
|
569
|
-
if (!areBoundsEqual(window.getBounds(), bounds)) {
|
|
570
|
-
this.logger.info(
|
|
571
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts setWindowOrViewBounds6: setBounds`
|
|
572
|
-
);
|
|
573
|
-
window.setBounds(bounds);
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
this.logger.info(
|
|
577
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts setWindowOrViewBounds7: ${JSON.stringify(
|
|
578
|
-
{
|
|
579
|
-
fullscreen: window.isFullScreen(),
|
|
580
|
-
isMaximized: window.isMaximized(),
|
|
581
|
-
bounds: window.getBounds(),
|
|
582
|
-
contentBounds: window.getContentBounds(),
|
|
583
|
-
normalBounds: window.getNormalBounds(),
|
|
584
|
-
}
|
|
585
|
-
)}`
|
|
586
|
-
);
|
|
587
|
-
|
|
588
|
-
if (window.isFullScreen() && !isFullscreen(window.getBounds())) {
|
|
589
|
-
this.logger.info(
|
|
590
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts setWindowOrViewBounds8: maximize: ${JSON.stringify(
|
|
591
|
-
{
|
|
592
|
-
fullscreen: window.isFullScreen(),
|
|
593
|
-
isMaximized: window.isMaximized(),
|
|
594
|
-
bounds: window.getBounds(),
|
|
595
|
-
contentBounds: window.getContentBounds(),
|
|
596
|
-
normalBounds: window.getNormalBounds(),
|
|
597
|
-
}
|
|
598
|
-
)}`
|
|
599
|
-
);
|
|
600
|
-
window.maximize();
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
this.logger.info(
|
|
604
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts setWindowOrViewBounds9: ${JSON.stringify(
|
|
605
|
-
{
|
|
606
|
-
fullscreen: window.isFullScreen(),
|
|
607
|
-
isMaximized: window.isMaximized(),
|
|
608
|
-
bounds: window.getBounds(),
|
|
609
|
-
contentBounds: window.getContentBounds(),
|
|
610
|
-
normalBounds: window.getNormalBounds(),
|
|
611
|
-
}
|
|
612
|
-
)}`
|
|
613
|
-
);
|
|
614
|
-
}
|
|
615
|
-
|
|
616
360
|
private getWindow(windowId: string): BrowserWindowRendererWindow | null {
|
|
617
361
|
return this.windows[windowId];
|
|
618
362
|
}
|
|
619
363
|
|
|
620
|
-
private getWindowBounds(windowId: string): WindowBounds | null {
|
|
621
|
-
return this.windowsBounds[windowId];
|
|
622
|
-
}
|
|
623
|
-
|
|
624
364
|
private moveWindowOffscreen(window: BrowserWindowRendererWindow) {
|
|
625
365
|
if (!(window.view instanceof BrowserView)) {
|
|
626
366
|
throw new Error(
|
|
@@ -728,18 +468,6 @@ export default class BrowserWindowRenderer
|
|
|
728
468
|
}
|
|
729
469
|
}
|
|
730
470
|
|
|
731
|
-
this.logger.info(
|
|
732
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts createOrGetPooledBrowserWindow1: ${JSON.stringify(
|
|
733
|
-
{
|
|
734
|
-
screen: screen.getPrimaryDisplay().bounds,
|
|
735
|
-
fullscreen: browserWindow.isFullScreen(),
|
|
736
|
-
bounds: browserWindow.getBounds(),
|
|
737
|
-
contentBounds: browserWindow.getContentBounds(),
|
|
738
|
-
normalBounds: browserWindow.getNormalBounds(),
|
|
739
|
-
}
|
|
740
|
-
)}`
|
|
741
|
-
);
|
|
742
|
-
|
|
743
471
|
return browserWindow;
|
|
744
472
|
}
|
|
745
473
|
|
|
@@ -747,13 +475,6 @@ export default class BrowserWindowRenderer
|
|
|
747
475
|
windowId: string,
|
|
748
476
|
browserWindow: BrowserWindow
|
|
749
477
|
) {
|
|
750
|
-
this.logger.info(
|
|
751
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts destroyOrUnloadPooledBrowserWindow1: ${JSON.stringify(
|
|
752
|
-
{
|
|
753
|
-
windowId,
|
|
754
|
-
}
|
|
755
|
-
)}`
|
|
756
|
-
);
|
|
757
478
|
if (this.opts.useWindowPool) {
|
|
758
479
|
this.hideWindow(windowId);
|
|
759
480
|
await browserWindow.webContents.loadURL('about:blank');
|
|
@@ -9,6 +9,10 @@ import {
|
|
|
9
9
|
Logger,
|
|
10
10
|
WorkerState,
|
|
11
11
|
AnalyticsEvent,
|
|
12
|
+
Charge,
|
|
13
|
+
ChargeRequest,
|
|
14
|
+
ChargeResponse,
|
|
15
|
+
Terminal,
|
|
12
16
|
} from './types';
|
|
13
17
|
import PresentationWindow from './PresentationWindow';
|
|
14
18
|
import PlaylistWindowManagerState from './PlaylistWindowManagerState';
|
|
@@ -67,6 +71,9 @@ export interface PlaylistWindowManagerOptions {
|
|
|
67
71
|
|
|
68
72
|
// Called when the current window wants to disable the interrupt lock
|
|
69
73
|
onDisableInterruptLock?: () => void;
|
|
74
|
+
|
|
75
|
+
// Called when a window needs the current terminal object.
|
|
76
|
+
getTerminal?: () => Terminal | null;
|
|
70
77
|
}
|
|
71
78
|
|
|
72
79
|
// Wait at least 3 seconds before restarting or moving onto the next window
|
|
@@ -84,12 +91,12 @@ export default class PlaylistWindowManager extends EventEmitter {
|
|
|
84
91
|
private overrideNextPresentation: RE.NextPresentationID | null = null;
|
|
85
92
|
private currentWindow: PresentationWindow | null = null;
|
|
86
93
|
private nextWindow: PresentationWindow | null = null;
|
|
87
|
-
private hasPendingInterrupt = false;
|
|
94
|
+
private hasPendingInterrupt: boolean = false;
|
|
88
95
|
private ruleEngine: RE.RuleEngine | null = null;
|
|
89
96
|
private state: PlaylistWindowManagerState | null = null;
|
|
90
97
|
private renderer: PresentationWindowRenderer | null = null;
|
|
91
|
-
private restartCurrentWindowOnEnd = false;
|
|
92
|
-
private shouldHardRestart = false;
|
|
98
|
+
private restartCurrentWindowOnEnd: boolean = false;
|
|
99
|
+
private shouldHardRestart: boolean = false;
|
|
93
100
|
private currentWindowError: null | Error = null;
|
|
94
101
|
private interruptCheckTimeout: ReturnType<typeof setTimeout> | null = null;
|
|
95
102
|
private currentPresentationCompleteTimeout: ReturnType<
|
|
@@ -98,8 +105,8 @@ export default class PlaylistWindowManager extends EventEmitter {
|
|
|
98
105
|
private lastCompleteAt: Date | null = null;
|
|
99
106
|
private bounds?: WindowBounds;
|
|
100
107
|
private themeOverride?: Theme;
|
|
101
|
-
private forceMute = false;
|
|
102
|
-
private isFocused = false;
|
|
108
|
+
private forceMute: boolean = false;
|
|
109
|
+
private isFocused: boolean = false;
|
|
103
110
|
|
|
104
111
|
private workerState: WorkerState = {};
|
|
105
112
|
|
|
@@ -344,7 +351,6 @@ export default class PlaylistWindowManager extends EventEmitter {
|
|
|
344
351
|
}
|
|
345
352
|
|
|
346
353
|
public updateBounds(bounds: WindowBounds) {
|
|
347
|
-
// TODO log bounds
|
|
348
354
|
this.bounds = bounds;
|
|
349
355
|
if (this.currentWindow) {
|
|
350
356
|
this.currentWindow.updateBounds(this.bounds);
|
|
@@ -397,7 +403,7 @@ export default class PlaylistWindowManager extends EventEmitter {
|
|
|
397
403
|
}
|
|
398
404
|
}
|
|
399
405
|
|
|
400
|
-
public async show(isFocused = true) {
|
|
406
|
+
public async show(isFocused: boolean = true) {
|
|
401
407
|
if (this.currentWindow) {
|
|
402
408
|
// Save the focused state so we know if preloaded windows should be
|
|
403
409
|
// focused when swapped for the current.
|
|
@@ -441,6 +447,43 @@ export default class PlaylistWindowManager extends EventEmitter {
|
|
|
441
447
|
}
|
|
442
448
|
}
|
|
443
449
|
|
|
450
|
+
public sendChargeResponse(response: ChargeResponse) {
|
|
451
|
+
// Send charge response to the current window. The window will check if
|
|
452
|
+
// has a matching request id and if so, send the response to the app.
|
|
453
|
+
if (this.currentWindow) {
|
|
454
|
+
this.currentWindow.sendChargeResponse(response);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// Send charge response to the next window.
|
|
458
|
+
if (this.nextWindow) {
|
|
459
|
+
this.nextWindow.sendChargeResponse(response);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
public sendCharge(charge: Charge) {
|
|
464
|
+
// Send charge to the current window.
|
|
465
|
+
if (this.currentWindow) {
|
|
466
|
+
this.currentWindow.sendCharge(charge);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// Send charge to the next window.
|
|
470
|
+
if (this.nextWindow) {
|
|
471
|
+
this.nextWindow.sendCharge(charge);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
public sendTerminal(terminal: Terminal | null) {
|
|
476
|
+
// Send terminal to the current window.
|
|
477
|
+
if (this.currentWindow) {
|
|
478
|
+
this.currentWindow.sendTerminal(terminal);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// Send terminal to the next window.
|
|
482
|
+
if (this.nextWindow) {
|
|
483
|
+
this.nextWindow.sendTerminal(terminal);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
444
487
|
private createWindow(pr: RE.NextPresentationID): PresentationWindow {
|
|
445
488
|
const {
|
|
446
489
|
readyTimeoutDurationSeconds,
|
|
@@ -480,12 +523,6 @@ export default class PlaylistWindowManager extends EventEmitter {
|
|
|
480
523
|
|
|
481
524
|
const windowId = uuidv4();
|
|
482
525
|
|
|
483
|
-
logger.info(
|
|
484
|
-
`playlist-window-manager/src/PlaylistWindowManager.ts createWindow1 ${JSON.stringify(
|
|
485
|
-
this.bounds
|
|
486
|
-
)}`
|
|
487
|
-
);
|
|
488
|
-
|
|
489
526
|
return new PresentationWindow({
|
|
490
527
|
windowManager: this,
|
|
491
528
|
renderer: this.renderer,
|
|
@@ -511,6 +548,7 @@ export default class PlaylistWindowManager extends EventEmitter {
|
|
|
511
548
|
globalRule: this.ruleEngine.globalRule,
|
|
512
549
|
isPreview,
|
|
513
550
|
workerState: this.workerState,
|
|
551
|
+
getTerminal: this.options.getTerminal,
|
|
514
552
|
});
|
|
515
553
|
}
|
|
516
554
|
|
|
@@ -530,6 +568,7 @@ export default class PlaylistWindowManager extends EventEmitter {
|
|
|
530
568
|
this.currentWindow.onEnableInterruptLock(this.handleEnableInterruptLock);
|
|
531
569
|
this.currentWindow.onDisableInterruptLock(this.handleDisableInterruptLock);
|
|
532
570
|
this.currentWindow.onAnalyticsEvent(this.handleAnalyticsEvent);
|
|
571
|
+
this.currentWindow.onChargeRequest(this.handleChargeRequest);
|
|
533
572
|
|
|
534
573
|
await this.currentWindow.load();
|
|
535
574
|
}
|
|
@@ -702,6 +741,7 @@ export default class PlaylistWindowManager extends EventEmitter {
|
|
|
702
741
|
this.handleDisableInterruptLock
|
|
703
742
|
);
|
|
704
743
|
this.currentWindow.onAnalyticsEvent(this.handleAnalyticsEvent);
|
|
744
|
+
this.currentWindow.onChargeRequest(this.handleChargeRequest);
|
|
705
745
|
}
|
|
706
746
|
|
|
707
747
|
// Play new current window.
|
|
@@ -771,6 +811,12 @@ export default class PlaylistWindowManager extends EventEmitter {
|
|
|
771
811
|
this.emitCurrentWindowEvent('window_analytics_event', event);
|
|
772
812
|
};
|
|
773
813
|
|
|
814
|
+
private handleChargeRequest = (request: ChargeRequest) => {
|
|
815
|
+
// Emit the event on the current window. Only the current window should
|
|
816
|
+
// send charge requests since the next window is not visible.
|
|
817
|
+
this.emitCurrentWindowEvent('window_charge_request', request);
|
|
818
|
+
};
|
|
819
|
+
|
|
774
820
|
private handleCurrentPresentationComplete = async () => {
|
|
775
821
|
const { logger } = this.options;
|
|
776
822
|
|