@raydiant/playlist-window-manager 0.0.0-test-26 → 0.0.0-test-28
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/.yarnrc.yml +2 -0
- package/build/BrowserViewRenderer.d.ts +1 -1
- package/build/BrowserViewRenderer.js +1 -5
- package/build/BrowserWindowRenderer.d.ts +0 -9
- package/build/BrowserWindowRenderer.js +16 -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 +26 -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,12 +62,9 @@ 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'),
|
|
76
70
|
},
|
|
@@ -81,28 +75,13 @@ export default class BrowserWindowRenderer
|
|
|
81
75
|
private logger: Logger;
|
|
82
76
|
|
|
83
77
|
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
|
-
|
|
78
|
+
this.offscreenWindow.setBounds(opts.bounds);
|
|
102
79
|
if (opts.proxySettings) {
|
|
103
80
|
this.proxySettings = opts.proxySettings;
|
|
104
81
|
}
|
|
105
82
|
|
|
83
|
+
this.logger = opts.logger;
|
|
84
|
+
|
|
106
85
|
if (opts.windowCrashHandler) {
|
|
107
86
|
this.windowCrashHandler = opts.windowCrashHandler;
|
|
108
87
|
}
|
|
@@ -115,21 +94,7 @@ export default class BrowserWindowRenderer
|
|
|
115
94
|
backgroundColor,
|
|
116
95
|
receiveMessageCallback,
|
|
117
96
|
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
|
-
);
|
|
97
|
+
}: CreateWindowOptions) {
|
|
133
98
|
const window: BrowserWindowRendererWindow = {
|
|
134
99
|
parentWindowId,
|
|
135
100
|
// If we are creating a child window and renderChildWindowsAsBrowserViews is true,
|
|
@@ -144,7 +109,6 @@ export default class BrowserWindowRenderer
|
|
|
144
109
|
: this.createOrGetPooledBrowserWindow(windowId, {
|
|
145
110
|
show: false,
|
|
146
111
|
frame: this.opts.frame,
|
|
147
|
-
fullscreen: isFullscreen(this.opts.bounds),
|
|
148
112
|
// NOTE: useWindowPool: true does not work with renderChildWindowsAsBrowserViews: false
|
|
149
113
|
// because the parent can't be changed after creating the BrowserWindow.
|
|
150
114
|
parent: parentWindowId
|
|
@@ -160,7 +124,14 @@ export default class BrowserWindowRenderer
|
|
|
160
124
|
// we are rendering child windows with BrowserWindow. BrowserWindows are positioned absolutely so
|
|
161
125
|
// to place them in the correct spot relative to their parent we need to add the main window's x / y.
|
|
162
126
|
// BrowserViews are relatively positioned so we don't need to do that.
|
|
163
|
-
bounds:
|
|
127
|
+
bounds:
|
|
128
|
+
parentWindowId && !this.opts.renderChildWindowsAsBrowserViews
|
|
129
|
+
? {
|
|
130
|
+
...bounds,
|
|
131
|
+
x: bounds.x + this.opts.bounds.x,
|
|
132
|
+
y: bounds.y + this.opts.bounds.y,
|
|
133
|
+
}
|
|
134
|
+
: bounds,
|
|
164
135
|
|
|
165
136
|
receiveMessageCallback: (
|
|
166
137
|
_: IpcMainEvent,
|
|
@@ -180,7 +151,10 @@ export default class BrowserWindowRenderer
|
|
|
180
151
|
);
|
|
181
152
|
},
|
|
182
153
|
|
|
183
|
-
renderProcessGoneCallback: (
|
|
154
|
+
renderProcessGoneCallback: (
|
|
155
|
+
_: Event,
|
|
156
|
+
details: RenderProcessGoneDetails
|
|
157
|
+
) => {
|
|
184
158
|
this.logger.error(
|
|
185
159
|
`Window received 'render-process-gone' event. Reason: ${details.reason}`,
|
|
186
160
|
{ windowId }
|
|
@@ -209,20 +183,9 @@ export default class BrowserWindowRenderer
|
|
|
209
183
|
|
|
210
184
|
if (window.view instanceof BrowserView) {
|
|
211
185
|
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
186
|
}
|
|
223
187
|
|
|
224
188
|
this.windows[windowId] = window;
|
|
225
|
-
this.windowsBounds[windowId] = lodash.cloneDeep(windowBounds);
|
|
226
189
|
// Listen for messages from window.
|
|
227
190
|
ipcMain.on(windowId, window.receiveMessageCallback);
|
|
228
191
|
|
|
@@ -234,49 +197,7 @@ export default class BrowserWindowRenderer
|
|
|
234
197
|
);
|
|
235
198
|
}
|
|
236
199
|
|
|
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
|
-
}
|
|
200
|
+
window.view.setBounds(window.bounds);
|
|
280
201
|
|
|
281
202
|
if (this.proxySettings) {
|
|
282
203
|
await window.view.webContents.session.setProxy(this.proxySettings);
|
|
@@ -304,95 +225,28 @@ export default class BrowserWindowRenderer
|
|
|
304
225
|
`Failed to update window bounds, missing window id '${windowId}'`
|
|
305
226
|
);
|
|
306
227
|
}
|
|
307
|
-
|
|
308
|
-
this.logger.info(
|
|
309
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts updateWindowBounds1: ${JSON.stringify(
|
|
310
|
-
bounds
|
|
311
|
-
)}`
|
|
312
|
-
);
|
|
313
228
|
window.bounds = bounds;
|
|
314
229
|
|
|
315
230
|
if (window.view instanceof BrowserWindow && window.parentWindowId) {
|
|
316
231
|
// Child BrowserWindows are absolutely positioned so we need to add the main windows
|
|
317
232
|
// x/y to when updating the child window's bounds.
|
|
318
|
-
|
|
233
|
+
window.view.setBounds({
|
|
319
234
|
...window.bounds,
|
|
320
235
|
x: window.bounds.x + this.opts.bounds.x,
|
|
321
236
|
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
|
-
);
|
|
237
|
+
});
|
|
340
238
|
} 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
|
-
);
|
|
239
|
+
window.view.setBounds(window.bounds);
|
|
352
240
|
}
|
|
353
241
|
}
|
|
354
242
|
|
|
355
243
|
public showWindow(windowId: string, isFocused: boolean) {
|
|
356
|
-
this.logger.info(
|
|
357
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts showWindow1: ${windowId}`
|
|
358
|
-
);
|
|
359
244
|
const window = this.getWindow(windowId);
|
|
360
|
-
|
|
361
|
-
if (!window || !windowBounds) {
|
|
245
|
+
if (!window) {
|
|
362
246
|
throw new Error(`Failed to show window, missing window id '${windowId}'`);
|
|
363
247
|
}
|
|
364
248
|
|
|
365
249
|
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
250
|
if (isFocused) {
|
|
397
251
|
window.view.show();
|
|
398
252
|
} else {
|
|
@@ -453,7 +307,6 @@ export default class BrowserWindowRenderer
|
|
|
453
307
|
}
|
|
454
308
|
|
|
455
309
|
delete this.windows[windowId];
|
|
456
|
-
delete this.windowsBounds[windowId];
|
|
457
310
|
|
|
458
311
|
if (this.opts.useWindowPool) {
|
|
459
312
|
this.logPoolStats();
|
|
@@ -502,125 +355,10 @@ export default class BrowserWindowRenderer
|
|
|
502
355
|
window.view.webContents.setAudioMuted(false);
|
|
503
356
|
}
|
|
504
357
|
|
|
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
358
|
private getWindow(windowId: string): BrowserWindowRendererWindow | null {
|
|
617
359
|
return this.windows[windowId];
|
|
618
360
|
}
|
|
619
361
|
|
|
620
|
-
private getWindowBounds(windowId: string): WindowBounds | null {
|
|
621
|
-
return this.windowsBounds[windowId];
|
|
622
|
-
}
|
|
623
|
-
|
|
624
362
|
private moveWindowOffscreen(window: BrowserWindowRendererWindow) {
|
|
625
363
|
if (!(window.view instanceof BrowserView)) {
|
|
626
364
|
throw new Error(
|
|
@@ -728,18 +466,6 @@ export default class BrowserWindowRenderer
|
|
|
728
466
|
}
|
|
729
467
|
}
|
|
730
468
|
|
|
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
469
|
return browserWindow;
|
|
744
470
|
}
|
|
745
471
|
|
|
@@ -747,13 +473,6 @@ export default class BrowserWindowRenderer
|
|
|
747
473
|
windowId: string,
|
|
748
474
|
browserWindow: BrowserWindow
|
|
749
475
|
) {
|
|
750
|
-
this.logger.info(
|
|
751
|
-
`playlist-window-manager/src/BrowserWindowRenderer.ts destroyOrUnloadPooledBrowserWindow1: ${JSON.stringify(
|
|
752
|
-
{
|
|
753
|
-
windowId,
|
|
754
|
-
}
|
|
755
|
-
)}`
|
|
756
|
-
);
|
|
757
476
|
if (this.opts.useWindowPool) {
|
|
758
477
|
this.hideWindow(windowId);
|
|
759
478
|
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
|
|