mirror of
https://github.com/atom/atom.git
synced 2026-02-08 21:55:05 -05:00
Wait for browser process to acknowledge window manipulation IPC requests
We need to avoid using the module for synchronous IPC on startup, but in some cases, we need to know when our asynchronous IPC messages have taken effect. Now, methods like and return Promises that indicate when the message has been processed.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
_ = require 'underscore-plus'
|
||||
{ipcRenderer, remote, shell, webFrame} = require 'electron'
|
||||
ipcHelpers = require './ipc-helpers'
|
||||
{Disposable} = require 'event-kit'
|
||||
{getWindowLoadSettings, setWindowLoadSettings} = require './window-load-settings-helpers'
|
||||
|
||||
@@ -26,26 +27,26 @@ class ApplicationDelegate
|
||||
{width, height}
|
||||
|
||||
setWindowSize: (width, height) ->
|
||||
remote.getCurrentWindow().setSize(width, height)
|
||||
ipcHelpers.call('set-window-size', width, height)
|
||||
|
||||
getWindowPosition: ->
|
||||
[x, y] = remote.getCurrentWindow().getPosition()
|
||||
{x, y}
|
||||
|
||||
setWindowPosition: (x, y) ->
|
||||
ipcRenderer.send("call-window-method", "setPosition", x, y)
|
||||
ipcHelpers.call('set-window-position', x, y)
|
||||
|
||||
centerWindow: ->
|
||||
ipcRenderer.send("call-window-method", "center")
|
||||
ipcHelpers.call('center-window')
|
||||
|
||||
focusWindow: ->
|
||||
ipcRenderer.send("call-window-method", "focus")
|
||||
ipcHelpers.call('focus-window')
|
||||
|
||||
showWindow: ->
|
||||
ipcRenderer.send("call-window-method", "show")
|
||||
ipcHelpers.call('show-window')
|
||||
|
||||
hideWindow: ->
|
||||
ipcRenderer.send("call-window-method", "hide")
|
||||
ipcHelpers.call('hide-window')
|
||||
|
||||
reloadWindow: ->
|
||||
ipcRenderer.send("call-window-method", "reload")
|
||||
|
||||
@@ -519,16 +519,17 @@ class AtomEnvironment extends Model
|
||||
|
||||
# Restore the window to its previous dimensions and show it.
|
||||
#
|
||||
# Also restores the full screen and maximized state on the next tick to
|
||||
# Restores the full screen and maximized state after the window has resized to
|
||||
# prevent resize glitches.
|
||||
displayWindow: ->
|
||||
dimensions = @restoreWindowDimensions()
|
||||
@show()
|
||||
@focus()
|
||||
|
||||
setImmediate =>
|
||||
@setFullScreen(true) if @workspace?.fullScreen
|
||||
@maximize() if dimensions?.maximized and process.platform isnt 'darwin'
|
||||
@restoreWindowDimensions().then (dimensions) =>
|
||||
steps = [
|
||||
@show(),
|
||||
@focus()
|
||||
]
|
||||
steps.push(@setFullScreen(true)) if @workspace.fullScreen
|
||||
steps.push(@maximize()) if dimensions?.maximized and process.platform isnt 'darwin'
|
||||
Promise.all(steps)
|
||||
|
||||
# Get the dimensions of this window.
|
||||
#
|
||||
@@ -556,12 +557,14 @@ class AtomEnvironment extends Model
|
||||
# * `width` The new width.
|
||||
# * `height` The new height.
|
||||
setWindowDimensions: ({x, y, width, height}) ->
|
||||
steps = []
|
||||
if width? and height?
|
||||
@setSize(width, height)
|
||||
steps.push(@setSize(width, height))
|
||||
if x? and y?
|
||||
@setPosition(x, y)
|
||||
steps.push(@setPosition(x, y))
|
||||
else
|
||||
@center()
|
||||
steps.push(@center())
|
||||
Promise.all(steps)
|
||||
|
||||
# Returns true if the dimensions are useable, false if they should be ignored.
|
||||
# Work around for https://github.com/atom/atom-shell/issues/473
|
||||
@@ -594,8 +597,7 @@ class AtomEnvironment extends Model
|
||||
dimensions = @state.windowDimensions
|
||||
unless @isValidDimensions(dimensions)
|
||||
dimensions = @getDefaultWindowDimensions()
|
||||
@setWindowDimensions(dimensions)
|
||||
dimensions
|
||||
@setWindowDimensions(dimensions).then -> dimensions
|
||||
|
||||
storeWindowDimensions: ->
|
||||
dimensions = @getWindowDimensions()
|
||||
|
||||
@@ -3,6 +3,7 @@ ApplicationMenu = require './application-menu'
|
||||
AtomProtocolHandler = require './atom-protocol-handler'
|
||||
AutoUpdateManager = require './auto-update-manager'
|
||||
StorageFolder = require '../storage-folder'
|
||||
ipcHelpers = require '../ipc-helpers'
|
||||
{BrowserWindow, Menu, app, dialog, ipcMain, shell} = require 'electron'
|
||||
fs = require 'fs-plus'
|
||||
path = require 'path'
|
||||
@@ -261,6 +262,24 @@ class AtomApplication
|
||||
@promptForPath "folder", (selectedPaths) ->
|
||||
event.sender.send(responseChannel, selectedPaths)
|
||||
|
||||
ipcHelpers.respondTo 'set-window-size', (win, width, height) ->
|
||||
win.setSize(width, height)
|
||||
|
||||
ipcHelpers.respondTo 'set-window-position', (win, x, y) ->
|
||||
win.setPosition(x, y)
|
||||
|
||||
ipcHelpers.respondTo 'center-window', (win) ->
|
||||
win.center()
|
||||
|
||||
ipcHelpers.respondTo 'focus-window', (win) ->
|
||||
win.focus()
|
||||
|
||||
ipcHelpers.respondTo 'show-window', (win) ->
|
||||
win.show()
|
||||
|
||||
ipcHelpers.respondTo 'hide-window', (win) ->
|
||||
win.hide()
|
||||
|
||||
ipcMain.on 'did-cancel-window-unload', =>
|
||||
@quitting = false
|
||||
|
||||
|
||||
@@ -23,11 +23,11 @@ module.exports = ({blobStore}) ->
|
||||
enablePersistence: true
|
||||
})
|
||||
|
||||
atom.displayWindow()
|
||||
atom.startEditorWindow()
|
||||
atom.displayWindow().then ->
|
||||
atom.startEditorWindow()
|
||||
|
||||
# Workaround for focus getting cleared upon window creation
|
||||
windowFocused = ->
|
||||
window.removeEventListener('focus', windowFocused)
|
||||
setTimeout (-> document.querySelector('atom-workspace').focus()), 0
|
||||
window.addEventListener('focus', windowFocused)
|
||||
# Workaround for focus getting cleared upon window creation
|
||||
windowFocused = ->
|
||||
window.removeEventListener('focus', windowFocused)
|
||||
setTimeout (-> document.querySelector('atom-workspace').focus()), 0
|
||||
window.addEventListener('focus', windowFocused)
|
||||
|
||||
40
src/ipc-helpers.js
Normal file
40
src/ipc-helpers.js
Normal file
@@ -0,0 +1,40 @@
|
||||
var ipcRenderer = null
|
||||
var ipcMain = null
|
||||
var BrowserWindow = null
|
||||
|
||||
exports.call = function (methodName, ...args) {
|
||||
if (!ipcRenderer) {
|
||||
ipcRenderer = require('electron').ipcRenderer
|
||||
}
|
||||
|
||||
var responseChannel = getResponseChannel(methodName)
|
||||
|
||||
return new Promise(function (resolve) {
|
||||
ipcRenderer.on(responseChannel, function (event, result) {
|
||||
ipcRenderer.removeAllListeners(responseChannel)
|
||||
resolve(result)
|
||||
})
|
||||
|
||||
ipcRenderer.send(methodName, ...args)
|
||||
})
|
||||
}
|
||||
|
||||
exports.respondTo = function (methodName, callback) {
|
||||
if (!ipcMain) {
|
||||
var electron = require('electron')
|
||||
ipcMain = electron.ipcMain
|
||||
BrowserWindow = electron.BrowserWindow
|
||||
}
|
||||
|
||||
var responseChannel = getResponseChannel(methodName)
|
||||
|
||||
ipcMain.on(methodName, 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'
|
||||
}
|
||||
Reference in New Issue
Block a user