-
Notifications
You must be signed in to change notification settings - Fork 69
/
WindowManager.ts
148 lines (133 loc) · 4.45 KB
/
WindowManager.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import { app, BrowserWindow as BrowserWindowElectron, ipcMain } from "electron"
import * as path from "path"
import AppUpdater from "./AppUpdater"
import { WebContentsSignal, WindowEvent } from "./electronEventSignals"
import { DEFAULT_URL, StateManager, WindowItem } from "./StateManager"
export const WINDOW_NAVIGATED = "windowNavigated"
export default class WindowManager {
private stateManager = new StateManager()
private windows: Array<Electron.BrowserWindow> = []
constructor() {
app.on("window-all-closed", () => {
// restore default set of windows
this.stateManager.restoreWindows()
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform == 'darwin') {
// reopen initial window
this.openWindows()
}
else {
app.quit()
}
})
}
private static saveWindowState(window: Electron.BrowserWindow, descriptor: WindowItem): void {
if (window.isMaximized()) {
delete descriptor.width
delete descriptor.height
delete descriptor.x
delete descriptor.y
}
else {
const bounds = window.getBounds()
descriptor.width = bounds.width
descriptor.height = bounds.height
descriptor.x = bounds.x
descriptor.y = bounds.y
}
}
private registerWindowEventHandlers(window: Electron.BrowserWindow, descriptor: WindowItem): void {
window.on("close", () => {
WindowManager.saveWindowState(window, descriptor)
const url = window.webContents.getURL()
if (!isUrlInvalid(url)) {
descriptor.url = url
}
this.stateManager.save()
})
window.on("closed", (event: WindowEvent) => {
const index = this.windows.indexOf(event.sender)
console.assert(index >= 0)
this.windows.splice(index, 1)
})
window.on("app-command", (e: any, command: string) => {
// navigate the window back when the user hits their mouse back button
if (command === "browser-backward") {
if (window.webContents.canGoBack()) {
window.webContents.goBack()
}
}
else if (command === "browser-forward") {
if (window.webContents.canGoForward()) {
window.webContents.goForward()
}
}
})
const webContents = window.webContents
// cannot find way to listen url change in pure JS
new WebContentsSignal(webContents)
.navigated((event, url) => {
ipcMain.emit(WINDOW_NAVIGATED, event.sender, url)
webContents.send("maybeUrlChanged", url)
})
.navigatedInPage((event, url) => {
ipcMain.emit(WINDOW_NAVIGATED, event.sender, url)
webContents.send("maybeUrlChanged", url)
})
}
openWindows(): void {
let descriptors = this.stateManager.getWindows()
if (descriptors == null || descriptors.length === 0) {
this.stateManager.restoreWindows()
descriptors = this.stateManager.getWindows()
}
for (const descriptor of descriptors) {
if (isUrlInvalid(descriptor.url)) {
// was error on load
descriptor.url = DEFAULT_URL
}
const options: Electron.BrowserWindowConstructorOptions = {
// to avoid visible maximizing
show: false,
webPreferences: {
preload: path.join(__dirname, "autoSignIn.js"),
// fix jquery issue (https://github.com/atom/electron/issues/254), and in any case node integration is not required
nodeIntegration: false,
}
}
let isMaximized = false
if (descriptor.width != null && descriptor.height != null) {
options.width = descriptor.width
options.height = descriptor.height
isMaximized = false
}
if (descriptor.x != null && descriptor.y != null) {
options.x = descriptor.x
options.y = descriptor.y
isMaximized = false
}
const window = new BrowserWindowElectron(options)
if (isMaximized) {
window.maximize()
}
window.loadURL(descriptor.url)
window.show()
this.registerWindowEventHandlers(window, descriptor)
this.windows.push(window)
}
new AppUpdater()
}
focusFirstWindow(): void {
if (this.windows.length > 0) {
const window = this.windows[0]
if (window.isMinimized()) {
window.restore()
}
window.focus()
}
}
}
function isUrlInvalid(url: string): boolean {
return url == null || url.length === 0 || url == "about:blank"
}