Merge pull request #12759 from atom/ns-mb-dont-serialize-packages-when-deactivating

Don't interleave package serialization with package deactivations
This commit is contained in:
Max Brunsfeld
2016-09-22 14:08:02 -07:00
committed by GitHub
6 changed files with 75 additions and 58 deletions

View File

@@ -502,6 +502,7 @@ describe "PackageManager", ->
runs ->
expect(pack.mainModule.someNumber).not.toBe 77
pack.mainModule.someNumber = 77
atom.packages.serializePackage("package-with-serialization")
atom.packages.deactivatePackage("package-with-serialization")
spyOn(pack.mainModule, 'activate').andCallThrough()
waitsForPromise ->
@@ -899,6 +900,22 @@ describe "PackageManager", ->
expect(atom.packages.packageStates['package-with-serialization']).toEqual someNumber: 1
expect(console.error).toHaveBeenCalled()
describe "::deactivatePackages()", ->
it "deactivates all packages but does not serialize them", ->
[pack1, pack2] = []
waitsForPromise ->
atom.packages.activatePackage("package-with-deactivate").then (p) -> pack1 = p
atom.packages.activatePackage("package-with-serialization").then (p) -> pack2 = p
runs ->
spyOn(pack1.mainModule, 'deactivate')
spyOn(pack2.mainModule, 'serialize')
atom.packages.deactivatePackages()
expect(pack1.mainModule.deactivate).toHaveBeenCalled()
expect(pack2.mainModule.serialize).not.toHaveBeenCalled()
describe "::deactivatePackage(id)", ->
afterEach ->
atom.packages.unloadPackages()

View File

@@ -20,7 +20,7 @@ class ApplicationDelegate
remote.getCurrentWindow()
closeWindow: ->
ipcRenderer.send("call-window-method", "close")
ipcHelpers.call('window-method', 'close')
getTemporaryWindowState: ->
ipcHelpers.call('get-temporary-window-state').then (stateJSON) -> JSON.parse(stateJSON)
@@ -55,72 +55,55 @@ class ApplicationDelegate
ipcHelpers.call('hide-window')
reloadWindow: ->
ipcRenderer.send("call-window-method", "reload")
ipcHelpers.call('window-method', 'reload')
restartApplication: ->
ipcRenderer.send("restart-application")
minimizeWindow: ->
ipcRenderer.send("call-window-method", "minimize")
ipcHelpers.call('window-method', 'minimize')
isWindowMaximized: ->
remote.getCurrentWindow().isMaximized()
maximizeWindow: ->
ipcRenderer.send("call-window-method", "maximize")
ipcHelpers.call('window-method', 'maximize')
unmaximizeWindow: ->
ipcRenderer.send("call-window-method", "unmaximize")
ipcHelpers.call('window-method', 'unmaximize')
isWindowFullScreen: ->
remote.getCurrentWindow().isFullScreen()
setWindowFullScreen: (fullScreen=false) ->
ipcRenderer.send("call-window-method", "setFullScreen", fullScreen)
ipcHelpers.call('window-method', 'setFullScreen', fullScreen)
openWindowDevTools: ->
new Promise (resolve) ->
# Defer DevTools interaction to the next tick, because using them during
# event handling causes some wrong input events to be triggered on
# `TextEditorComponent` (Ref.: https://github.com/atom/atom/issues/9697).
process.nextTick ->
if remote.getCurrentWindow().isDevToolsOpened()
resolve()
else
remote.getCurrentWindow().once("devtools-opened", -> resolve())
ipcRenderer.send("call-window-method", "openDevTools")
# Defer DevTools interaction to the next tick, because using them during
# event handling causes some wrong input events to be triggered on
# `TextEditorComponent` (Ref.: https://github.com/atom/atom/issues/9697).
new Promise(process.nextTick).then(-> ipcHelpers.call('window-method', 'openDevTools'))
closeWindowDevTools: ->
new Promise (resolve) ->
# Defer DevTools interaction to the next tick, because using them during
# event handling causes some wrong input events to be triggered on
# `TextEditorComponent` (Ref.: https://github.com/atom/atom/issues/9697).
process.nextTick ->
unless remote.getCurrentWindow().isDevToolsOpened()
resolve()
else
remote.getCurrentWindow().once("devtools-closed", -> resolve())
ipcRenderer.send("call-window-method", "closeDevTools")
# Defer DevTools interaction to the next tick, because using them during
# event handling causes some wrong input events to be triggered on
# `TextEditorComponent` (Ref.: https://github.com/atom/atom/issues/9697).
new Promise(process.nextTick).then(-> ipcHelpers.call('window-method', 'closeDevTools'))
toggleWindowDevTools: ->
new Promise (resolve) =>
# Defer DevTools interaction to the next tick, because using them during
# event handling causes some wrong input events to be triggered on
# `TextEditorComponent` (Ref.: https://github.com/atom/atom/issues/9697).
process.nextTick =>
if remote.getCurrentWindow().isDevToolsOpened()
@closeWindowDevTools().then(resolve)
else
@openWindowDevTools().then(resolve)
# Defer DevTools interaction to the next tick, because using them during
# event handling causes some wrong input events to be triggered on
# `TextEditorComponent` (Ref.: https://github.com/atom/atom/issues/9697).
new Promise(process.nextTick).then(-> ipcHelpers.call('window-method', 'toggleDevTools'))
executeJavaScriptInWindowDevTools: (code) ->
ipcRenderer.send("execute-javascript-in-dev-tools", code)
setWindowDocumentEdited: (edited) ->
ipcRenderer.send("call-window-method", "setDocumentEdited", edited)
ipcHelpers.call('window-method', 'setDocumentEdited', edited)
setRepresentedFilename: (filename) ->
ipcRenderer.send("call-window-method", "setRepresentedFilename", filename)
ipcHelpers.call('window-method', 'setRepresentedFilename', filename)
addRecentDocument: (filename) ->
ipcRenderer.send("add-recent-document", filename)
@@ -131,7 +114,7 @@ class ApplicationDelegate
setWindowLoadSettings(loadSettings)
setAutoHideWindowMenuBar: (autoHide) ->
ipcRenderer.send("call-window-method", "setAutoHideMenuBar", autoHide)
ipcHelpers.call('window-method', 'setAutoHideMenuBar', autoHide)
setWindowMenuBarVisibility: (visible) ->
remote.getCurrentWindow().setMenuBarVisibility(visible)

View File

@@ -12,12 +12,12 @@ exports.on = function (emitter, eventName, callback) {
})
}
exports.call = function (methodName, ...args) {
exports.call = function (channel, ...args) {
if (!ipcRenderer) {
ipcRenderer = require('electron').ipcRenderer
}
var responseChannel = getResponseChannel(methodName)
var responseChannel = getResponseChannel(channel)
return new Promise(function (resolve) {
ipcRenderer.on(responseChannel, function (event, result) {
@@ -25,26 +25,26 @@ exports.call = function (methodName, ...args) {
resolve(result)
})
ipcRenderer.send(methodName, ...args)
ipcRenderer.send(channel, ...args)
})
}
exports.respondTo = function (methodName, callback) {
exports.respondTo = function (channel, callback) {
if (!ipcMain) {
var electron = require('electron')
ipcMain = electron.ipcMain
BrowserWindow = electron.BrowserWindow
}
var responseChannel = getResponseChannel(methodName)
var responseChannel = getResponseChannel(channel)
return exports.on(ipcMain, methodName, function (event, ...args) {
return exports.on(ipcMain, channel, function (event, ...args) {
var browserWindow = BrowserWindow.fromWebContents(event.sender)
var result = callback(browserWindow, ...args)
event.sender.send(responseChannel, result)
})
}
function getResponseChannel (methodName) {
return 'ipc-helpers-' + methodName + '-response'
function getResponseChannel (channel) {
return 'ipc-helpers-' + channel + '-response'
}

View File

@@ -259,7 +259,7 @@ class AtomApplication
# A request from the associated render process to open a new render process.
@disposable.add ipcHelpers.on ipcMain, 'open', (event, options) =>
window = @windowForEvent(event)
window = @atomWindowForEvent(event)
if options?
if typeof options.pathsToOpen is 'string'
options.pathsToOpen = [options.pathsToOpen]
@@ -293,9 +293,8 @@ class AtomApplication
win = BrowserWindow.fromWebContents(event.sender)
win.emit(command, args...)
@disposable.add ipcHelpers.on ipcMain, 'call-window-method', (event, method, args...) ->
win = BrowserWindow.fromWebContents(event.sender)
win[method](args...)
@disposable.add ipcHelpers.respondTo 'window-method', (browserWindow, method, args...) =>
@atomWindowForBrowserWindow(browserWindow)?[method](args...)
@disposable.add ipcHelpers.on ipcMain, 'pick-folder', (event, responseChannel) =>
@promptForPath "folder", (selectedPaths) ->
@@ -353,11 +352,11 @@ class AtomApplication
event.returnValue = @autoUpdateManager.getErrorMessage()
@disposable.add ipcHelpers.on ipcMain, 'will-save-path', (event, path) =>
@fileRecoveryService.willSavePath(@windowForEvent(event), path)
@fileRecoveryService.willSavePath(@atomWindowForEvent(event), path)
event.returnValue = true
@disposable.add ipcHelpers.on ipcMain, 'did-save-path', (event, path) =>
@fileRecoveryService.didSavePath(@windowForEvent(event), path)
@fileRecoveryService.didSavePath(@atomWindowForEvent(event), path)
event.returnValue = true
setupDockMenu: ->
@@ -428,9 +427,11 @@ class AtomApplication
atomWindow.devMode is devMode and atomWindow.containsPaths(pathsToOpen)
# Returns the {AtomWindow} for the given ipcMain event.
windowForEvent: ({sender}) ->
window = BrowserWindow.fromWebContents(sender)
_.find @windows, ({browserWindow}) -> window is browserWindow
atomWindowForEvent: ({sender}) ->
@atomWindowForBrowserWindow(BrowserWindow.fromWebContents(sender))
atomWindowForBrowserWindow: (browserWindow) ->
@windows.find((atomWindow) -> atomWindow.browserWindow is browserWindow)
# Public: Returns the currently focused {AtomWindow} or undefined if none.
focusedWindow: ->

View File

@@ -236,8 +236,14 @@ class AtomWindow
maximize: -> @browserWindow.maximize()
unmaximize: -> @browserWindow.unmaximize()
restore: -> @browserWindow.restore()
setFullScreen: (fullScreen) -> @browserWindow.setFullScreen(fullScreen)
setAutoHideMenuBar: (autoHideMenuBar) -> @browserWindow.setAutoHideMenuBar(autoHideMenuBar)
handlesAtomCommands: ->
not @isSpecWindow() and @isWebViewFocused()
@@ -257,3 +263,13 @@ class AtomWindow
@loadedPromise
toggleDevTools: -> @browserWindow.toggleDevTools()
openDevTools: -> @browserWindow.openDevTools()
closeDevTools: -> @browserWindow.closeDevTools()
setDocumentEdited: (documentEdited) -> @browserWindow.setDocumentEdited(documentEdited)
setRepresentedFilename: (representedFilename) -> @browserWindow.setRepresentedFilename(representedFilename)
copy: -> @browserWindow.copy()

View File

@@ -486,15 +486,15 @@ class PackageManager
# Deactivate all packages
deactivatePackages: ->
@config.transact =>
@deactivatePackage(pack.name) for pack in @getLoadedPackages()
@deactivatePackage(pack.name, true) for pack in @getLoadedPackages()
return
@unobserveDisabledPackages()
@unobservePackagesWithKeymapsDisabled()
# Deactivate the package with the given name
deactivatePackage: (name) ->
deactivatePackage: (name, suppressSerialization) ->
pack = @getLoadedPackage(name)
@serializePackage(pack) if @isPackageActive(pack.name)
@serializePackage(pack) if not suppressSerialization and @isPackageActive(pack.name)
pack.deactivate()
delete @activePackages[pack.name]
delete @activatingPackages[pack.name]