mirror of
https://github.com/atom/atom.git
synced 2026-02-05 12:15:07 -05:00
Path opening and update signaling were both using the command-sending IPC mechanism, but neither is actually a command. This commit adds a second “message” channel with custom handling on the render process side for these messages, rather than attempting to route them through commands.
199 lines
6.1 KiB
CoffeeScript
199 lines
6.1 KiB
CoffeeScript
BrowserWindow = require 'browser-window'
|
|
app = require 'app'
|
|
path = require 'path'
|
|
fs = require 'fs'
|
|
url = require 'url'
|
|
_ = require 'underscore-plus'
|
|
{EventEmitter} = require 'events'
|
|
|
|
module.exports =
|
|
class AtomWindow
|
|
_.extend @prototype, EventEmitter.prototype
|
|
|
|
@iconPath: path.resolve(__dirname, '..', '..', 'resources', 'atom.png')
|
|
@includeShellLoadTime: true
|
|
|
|
browserWindow: null
|
|
loaded: null
|
|
isSpec: null
|
|
|
|
constructor: (settings={}) ->
|
|
{@resourcePath, pathToOpen, initialLine, initialColumn, @isSpec, @exitWhenDone, @safeMode} = settings
|
|
|
|
# Normalize to make sure drive letter case is consistent on Windows
|
|
@resourcePath = path.normalize(@resourcePath) if @resourcePath
|
|
|
|
@browserWindow = new BrowserWindow
|
|
show: false
|
|
title: 'Atom'
|
|
icon: @constructor.iconPath
|
|
'web-preferences':
|
|
'direct-write': false
|
|
'subpixel-font-scaling': false
|
|
global.atomApplication.addWindow(this)
|
|
|
|
@handleEvents()
|
|
|
|
loadSettings = _.extend({}, settings)
|
|
loadSettings.windowState ?= '{}'
|
|
loadSettings.appVersion = app.getVersion()
|
|
loadSettings.resourcePath = @resourcePath
|
|
|
|
# Only send to the first non-spec window created
|
|
if @constructor.includeShellLoadTime and not @isSpec
|
|
@constructor.includeShellLoadTime = false
|
|
loadSettings.shellLoadTime ?= Date.now() - global.shellStartTime
|
|
|
|
loadSettings.initialPath = pathToOpen
|
|
if fs.statSyncNoException(pathToOpen).isFile?()
|
|
loadSettings.initialPath = path.dirname(pathToOpen)
|
|
|
|
@browserWindow.loadSettings = loadSettings
|
|
@browserWindow.once 'window:loaded', =>
|
|
@emit 'window:loaded'
|
|
@loaded = true
|
|
|
|
@browserWindow.on 'project-path-changed', (@projectPath) =>
|
|
|
|
@browserWindow.loadUrl @getUrl(loadSettings)
|
|
@browserWindow.focusOnWebView() if @isSpec
|
|
|
|
@openPath(pathToOpen, initialLine, initialColumn)
|
|
|
|
getUrl: (loadSettingsObj) ->
|
|
# Ignore the windowState when passing loadSettings via URL, since it could
|
|
# be quite large.
|
|
loadSettings = _.clone(loadSettingsObj)
|
|
delete loadSettings['windowState']
|
|
|
|
url.format
|
|
protocol: 'file'
|
|
pathname: "#{@resourcePath}/static/index.html"
|
|
slashes: true
|
|
query: {loadSettings: JSON.stringify(loadSettings)}
|
|
|
|
hasProjectPath: -> @projectPath?.length > 0
|
|
|
|
getInitialPath: ->
|
|
@browserWindow.loadSettings.initialPath
|
|
|
|
setupContextMenu: ->
|
|
ContextMenu = null
|
|
|
|
@browserWindow.on 'context-menu', (menuTemplate) =>
|
|
ContextMenu ?= require './context-menu'
|
|
new ContextMenu(menuTemplate, this)
|
|
|
|
containsPath: (pathToCheck) ->
|
|
initialPath = @getInitialPath()
|
|
if not initialPath
|
|
false
|
|
else if not pathToCheck
|
|
false
|
|
else if pathToCheck is initialPath
|
|
true
|
|
else if fs.statSyncNoException(pathToCheck).isDirectory?()
|
|
false
|
|
else if pathToCheck.indexOf(path.join(initialPath, path.sep)) is 0
|
|
true
|
|
else
|
|
false
|
|
|
|
handleEvents: ->
|
|
@browserWindow.on 'closed', =>
|
|
global.atomApplication.removeWindow(this)
|
|
|
|
@browserWindow.on 'unresponsive', =>
|
|
return if @isSpec
|
|
|
|
dialog = require 'dialog'
|
|
chosen = dialog.showMessageBox @browserWindow,
|
|
type: 'warning'
|
|
buttons: ['Close', 'Keep Waiting']
|
|
message: 'Editor is not responding'
|
|
detail: 'The editor is not responding. Would you like to force close it or just keep waiting?'
|
|
@browserWindow.destroy() if chosen is 0
|
|
|
|
@browserWindow.webContents.on 'crashed', =>
|
|
global.atomApplication.exit(100) if @exitWhenDone
|
|
|
|
dialog = require 'dialog'
|
|
chosen = dialog.showMessageBox @browserWindow,
|
|
type: 'warning'
|
|
buttons: ['Close Window', 'Reload', 'Keep It Open']
|
|
message: 'The editor has crashed'
|
|
detail: 'Please report this issue to https://github.com/atom/atom'
|
|
switch chosen
|
|
when 0 then @browserWindow.destroy()
|
|
when 1 then @browserWindow.restart()
|
|
|
|
@setupContextMenu()
|
|
|
|
if @isSpec
|
|
# Workaround for https://github.com/atom/atom-shell/issues/380
|
|
# Don't focus the window when it is being blurred during close or
|
|
# else the app will crash on Windows.
|
|
if process.platform is 'win32'
|
|
@browserWindow.on 'close', => @isWindowClosing = true
|
|
|
|
# Spec window's web view should always have focus
|
|
@browserWindow.on 'blur', =>
|
|
@browserWindow.focusOnWebView() unless @isWindowClosing
|
|
|
|
openPath: (pathToOpen, initialLine, initialColumn) ->
|
|
if @loaded
|
|
@focus()
|
|
@sendMessage 'open-path', {pathToOpen, initialLine, initialColumn}
|
|
else
|
|
@browserWindow.once 'window:loaded', => @openPath(pathToOpen, initialLine, initialColumn)
|
|
|
|
sendMessage: (message, detail) ->
|
|
@browserWindow.webContents.send 'message', message, detail
|
|
|
|
sendCommand: (command, args...) ->
|
|
if @isSpecWindow()
|
|
unless global.atomApplication.sendCommandToFirstResponder(command)
|
|
switch command
|
|
when 'window:reload' then @reload()
|
|
when 'window:toggle-dev-tools' then @toggleDevTools()
|
|
when 'window:close' then @close()
|
|
else if @isWebViewFocused()
|
|
@sendCommandToBrowserWindow(command, args...)
|
|
else
|
|
unless global.atomApplication.sendCommandToFirstResponder(command)
|
|
@sendCommandToBrowserWindow(command, args...)
|
|
|
|
sendCommandToBrowserWindow: (command, args...) ->
|
|
action = if args[0]?.contextCommand then 'context-command' else 'command'
|
|
@browserWindow.webContents.send action, command, args...
|
|
|
|
getDimensions: ->
|
|
[x, y] = @browserWindow.getPosition()
|
|
[width, height] = @browserWindow.getSize()
|
|
{x, y, width, height}
|
|
|
|
close: -> @browserWindow.close()
|
|
|
|
focus: -> @browserWindow.focus()
|
|
|
|
minimize: -> @browserWindow.minimize()
|
|
|
|
maximize: -> @browserWindow.maximize()
|
|
|
|
restore: -> @browserWindow.restore()
|
|
|
|
handlesAtomCommands: ->
|
|
not @isSpecWindow() and @isWebViewFocused()
|
|
|
|
isFocused: -> @browserWindow.isFocused()
|
|
|
|
isMinimized: -> @browserWindow.isMinimized()
|
|
|
|
isWebViewFocused: -> @browserWindow.isWebViewFocused()
|
|
|
|
isSpecWindow: -> @isSpec
|
|
|
|
reload: -> @browserWindow.restart()
|
|
|
|
toggleDevTools: -> @browserWindow.toggleDevTools()
|