mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-10-10 05:06:07 +08:00
fix(win-management): Track windowKey changes, add assertions
This commit is contained in:
parent
e238258dcb
commit
c1c7705f09
2 changed files with 63 additions and 49 deletions
|
@ -24,35 +24,22 @@ export default class WindowLauncher {
|
||||||
safeMode: appOpts.safeMode,
|
safeMode: appOpts.safeMode,
|
||||||
resizable: true,
|
resizable: true,
|
||||||
windowType: WindowLauncher.EMPTY_WINDOW,
|
windowType: WindowLauncher.EMPTY_WINDOW,
|
||||||
|
bootstrapScript: require.resolve("../secondary-window-bootstrap"),
|
||||||
resourcePath: appOpts.resourcePath,
|
resourcePath: appOpts.resourcePath,
|
||||||
configDirPath: appOpts.configDirPath,
|
configDirPath: appOpts.configDirPath,
|
||||||
}
|
}
|
||||||
this.hotWindow = new NylasWindow(this._hotWindowOpts());
|
this.createHotWindow();
|
||||||
|
|
||||||
if (DEBUG_SHOW_HOT_WINDOW) {
|
|
||||||
this.hotWindow.showWhenLoaded()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
newWindow(options) {
|
newWindow(options) {
|
||||||
const opts = Object.assign({}, this.defaultWindowOpts, options);
|
const opts = Object.assign({}, this.defaultWindowOpts, options);
|
||||||
|
|
||||||
let win;
|
let win;
|
||||||
if (opts.bootstrapScript) {
|
if (this._mustUseColdWindow(opts)) {
|
||||||
win = new NylasWindow(opts)
|
|
||||||
} else {
|
|
||||||
opts.bootstrapScript = this._secondaryWindowBootstrap()
|
|
||||||
if (this._unableToModifyHotWindow(opts) || opts.coldStartOnly) {
|
|
||||||
// Useful for the Worker Window: A secondary window that shouldn't
|
|
||||||
// be hot-loaded
|
|
||||||
win = new NylasWindow(opts)
|
win = new NylasWindow(opts)
|
||||||
} else {
|
} else {
|
||||||
win = this.hotWindow;
|
win = this.hotWindow;
|
||||||
|
this.createHotWindow();
|
||||||
// Regenerate the hot window.
|
|
||||||
this.hotWindow = new NylasWindow(this._hotWindowOpts());
|
|
||||||
if (DEBUG_SHOW_HOT_WINDOW) {
|
|
||||||
this.hotWindow.showWhenLoaded()
|
|
||||||
}
|
|
||||||
|
|
||||||
const newLoadSettings = Object.assign({}, win.loadSettings(), opts)
|
const newLoadSettings = Object.assign({}, win.loadSettings(), opts)
|
||||||
if (newLoadSettings.windowType === WindowLauncher.EMPTY_WINDOW) {
|
if (newLoadSettings.windowType === WindowLauncher.EMPTY_WINDOW) {
|
||||||
|
@ -62,9 +49,10 @@ export default class WindowLauncher {
|
||||||
// Reset the loaded state and update the load settings.
|
// Reset the loaded state and update the load settings.
|
||||||
// This will fire `NylasEnv::populateHotWindow` and reload the
|
// This will fire `NylasEnv::populateHotWindow` and reload the
|
||||||
// packages.
|
// packages.
|
||||||
|
win.windowKey = opts.windowKey;
|
||||||
win.setLoadSettings(newLoadSettings);
|
win.setLoadSettings(newLoadSettings);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!opts.hidden) {
|
if (!opts.hidden) {
|
||||||
// NOTE: In the case of a cold window, this will show it once
|
// NOTE: In the case of a cold window, this will show it once
|
||||||
// loaded. If it's a hotWindow, since hotWindows have a
|
// loaded. If it's a hotWindow, since hotWindows have a
|
||||||
|
@ -76,6 +64,13 @@ export default class WindowLauncher {
|
||||||
return win
|
return win
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createHotWindow() {
|
||||||
|
this.hotWindow = new NylasWindow(this._hotWindowOpts());
|
||||||
|
if (DEBUG_SHOW_HOT_WINDOW) {
|
||||||
|
this.hotWindow.showWhenLoaded()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Note: This method calls `browserWindow.destroy()` which closes
|
// Note: This method calls `browserWindow.destroy()` which closes
|
||||||
// windows without waiting for them to load or firing window lifecycle
|
// windows without waiting for them to load or firing window lifecycle
|
||||||
// events. This is necessary for the app to quit promptly on Linux.
|
// events. This is necessary for the app to quit promptly on Linux.
|
||||||
|
@ -87,21 +82,19 @@ export default class WindowLauncher {
|
||||||
// Some properties, like the `frame` or `toolbar` can't be updated once
|
// Some properties, like the `frame` or `toolbar` can't be updated once
|
||||||
// a window has been setup. If we detect this case we have to bootup a
|
// a window has been setup. If we detect this case we have to bootup a
|
||||||
// plain NylasWindow instead of using a hot window.
|
// plain NylasWindow instead of using a hot window.
|
||||||
_unableToModifyHotWindow(opts) {
|
_mustUseColdWindow(opts) {
|
||||||
return this.defaultWindowOpts.frame !== (!!opts.frame)
|
const {bootstrapScript, frame} = this.defaultWindowOpts;
|
||||||
}
|
|
||||||
|
|
||||||
_secondaryWindowBootstrap() {
|
const usesOtherBootstrap = opts.bootstrapScript !== bootstrapScript;
|
||||||
if (!this._bootstrap) {
|
const usesOtherFrame = (!!opts.frame) !== frame;
|
||||||
this._bootstrap = require.resolve("../secondary-window-bootstrap")
|
const requestsColdStart = opts.coldStartOnly;
|
||||||
}
|
|
||||||
return this._bootstrap
|
return usesOtherBootstrap || usesOtherFrame || requestsColdStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
_hotWindowOpts() {
|
_hotWindowOpts() {
|
||||||
const hotWindowOpts = Object.assign({}, this.defaultWindowOpts);
|
const hotWindowOpts = Object.assign({}, this.defaultWindowOpts);
|
||||||
hotWindowOpts.packageLoadingDeferred = true;
|
hotWindowOpts.packageLoadingDeferred = true;
|
||||||
hotWindowOpts.bootstrapScript = this._secondaryWindowBootstrap();
|
|
||||||
hotWindowOpts.hidden = DEBUG_SHOW_HOT_WINDOW;
|
hotWindowOpts.hidden = DEBUG_SHOW_HOT_WINDOW;
|
||||||
return hotWindowOpts
|
return hotWindowOpts
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,9 @@ class WindowManager
|
||||||
# window to not work and may even prevent window closure (like in the
|
# window to not work and may even prevent window closure (like in the
|
||||||
# case of the composer)
|
# case of the composer)
|
||||||
@_registerWindow(@windowLauncher.hotWindow)
|
@_registerWindow(@windowLauncher.hotWindow)
|
||||||
|
@_didCreateNewWindow(@windowLauncher.hotWindow)
|
||||||
|
|
||||||
get: (winId) -> @_windows[winId]
|
get: (windowKey) -> @_windows[windowKey]
|
||||||
|
|
||||||
getOpenWindows: ->
|
getOpenWindows: ->
|
||||||
values = []
|
values = []
|
||||||
|
@ -37,12 +38,26 @@ class WindowManager
|
||||||
|
|
||||||
newWindow: (options={}) ->
|
newWindow: (options={}) ->
|
||||||
win = @windowLauncher.newWindow(options)
|
win = @windowLauncher.newWindow(options)
|
||||||
|
|
||||||
|
existingKey = @_registeredKeyForWindow(win)
|
||||||
|
delete @_windows[existingKey] if existingKey
|
||||||
@_registerWindow(win)
|
@_registerWindow(win)
|
||||||
|
|
||||||
|
if not existingKey
|
||||||
|
@_didCreateNewWindow(win)
|
||||||
|
|
||||||
return win
|
return win
|
||||||
|
|
||||||
_registerWindow: (win) =>
|
_registerWindow: (win) =>
|
||||||
|
unless win.windowKey
|
||||||
|
throw new Error("WindowManager: You must provide a windowKey")
|
||||||
|
|
||||||
|
if @_windows[win.windowKey]
|
||||||
|
throw new Error("WindowManager: Attempting to register a new window for an existing windowKey (#{win.windowKey}). Use `get()` to retrieve the existing window instead.")
|
||||||
|
|
||||||
@_windows[win.windowKey] = win
|
@_windows[win.windowKey] = win
|
||||||
|
|
||||||
|
_didCreateNewWindow: (win) =>
|
||||||
win.browserWindow.on "closed", =>
|
win.browserWindow.on "closed", =>
|
||||||
delete @_windows[win.windowKey]
|
delete @_windows[win.windowKey]
|
||||||
@quitWinLinuxIfNoWindows()
|
@quitWinLinuxIfNoWindows()
|
||||||
|
@ -52,8 +67,14 @@ class WindowManager
|
||||||
# the browserWindow to unregister itself
|
# the browserWindow to unregister itself
|
||||||
global.application.applicationMenu.addWindow(win.browserWindow)
|
global.application.applicationMenu.addWindow(win.browserWindow)
|
||||||
|
|
||||||
ensureWindow: (winId, extraOpts) ->
|
_registeredKeyForWindow: (win) =>
|
||||||
win = @_windows[winId]
|
for key, otherWin of @_windows
|
||||||
|
if win is otherWin
|
||||||
|
return key
|
||||||
|
return null
|
||||||
|
|
||||||
|
ensureWindow: (windowKey, extraOpts) ->
|
||||||
|
win = @_windows[windowKey]
|
||||||
if win
|
if win
|
||||||
return if win.loadSettings().hidden
|
return if win.loadSettings().hidden
|
||||||
if win.isMinimized()
|
if win.isMinimized()
|
||||||
|
@ -64,21 +85,21 @@ class WindowManager
|
||||||
else
|
else
|
||||||
win.focus()
|
win.focus()
|
||||||
else
|
else
|
||||||
@newWindow(@_coreWindowOpts(winId, extraOpts))
|
@newWindow(@_coreWindowOpts(windowKey, extraOpts))
|
||||||
|
|
||||||
sendToWindow: (winId, args...) ->
|
sendToWindow: (windowKey, args...) ->
|
||||||
if not @_windows[winId]
|
if not @_windows[windowKey]
|
||||||
throw new Error("Can't find window: #{winId}")
|
throw new Error("Can't find window: #{windowKey}")
|
||||||
@_windows[winId].sendMessage(args...)
|
@_windows[windowKey].sendMessage(args...)
|
||||||
|
|
||||||
sendToAllWindows: (msg, {except}, args...) ->
|
sendToAllWindows: (msg, {except}, args...) ->
|
||||||
for winId, win of @_windows
|
for windowKey, win of @_windows
|
||||||
continue if win.browserWindow == except
|
continue if win.browserWindow == except
|
||||||
continue unless win.browserWindow.webContents
|
continue unless win.browserWindow.webContents
|
||||||
win.browserWindow.webContents.send(msg, args...)
|
win.browserWindow.webContents.send(msg, args...)
|
||||||
|
|
||||||
closeAllWindows: ->
|
closeAllWindows: ->
|
||||||
win.close() for winId, win of @_windows
|
win.close() for windowKey, win of @_windows
|
||||||
|
|
||||||
cleanupBeforeAppQuit: -> @windowLauncher.cleanupBeforeAppQuit()
|
cleanupBeforeAppQuit: -> @windowLauncher.cleanupBeforeAppQuit()
|
||||||
|
|
||||||
|
@ -104,7 +125,7 @@ class WindowManager
|
||||||
|
|
||||||
focusedWindow: -> _.find(@_windows, (win) -> win.isFocused())
|
focusedWindow: -> _.find(@_windows, (win) -> win.isFocused())
|
||||||
|
|
||||||
_coreWindowOpts: (winId, extraOpts={}) ->
|
_coreWindowOpts: (windowKey, extraOpts={}) ->
|
||||||
coreWinOpts = {}
|
coreWinOpts = {}
|
||||||
coreWinOpts[WindowManager.MAIN_WINDOW] =
|
coreWinOpts[WindowManager.MAIN_WINDOW] =
|
||||||
windowKey: WindowManager.MAIN_WINDOW
|
windowKey: WindowManager.MAIN_WINDOW
|
||||||
|
@ -149,7 +170,7 @@ class WindowManager
|
||||||
devMode: true,
|
devMode: true,
|
||||||
toolbar: false
|
toolbar: false
|
||||||
|
|
||||||
defaultOptions = coreWinOpts[winId] ? {}
|
defaultOptions = coreWinOpts[windowKey] ? {}
|
||||||
|
|
||||||
return Object.assign({}, defaultOptions, extraOpts)
|
return Object.assign({}, defaultOptions, extraOpts)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue