Files
atom/src/application-delegate.js
2018-03-27 08:55:31 -04:00

406 lines
12 KiB
JavaScript

const {ipcRenderer, remote, shell} = require('electron')
const ipcHelpers = require('./ipc-helpers')
const {Disposable} = require('event-kit')
const getWindowLoadSettings = require('./get-window-load-settings')
module.exports =
class ApplicationDelegate {
constructor () {
this.pendingSettingsUpdateCount = 0
}
getWindowLoadSettings () { return getWindowLoadSettings() }
open (params) {
return ipcRenderer.send('open', params)
}
pickFolder (callback) {
const responseChannel = 'atom-pick-folder-response'
ipcRenderer.on(responseChannel, function (event, path) {
ipcRenderer.removeAllListeners(responseChannel)
return callback(path)
})
return ipcRenderer.send('pick-folder', responseChannel)
}
getCurrentWindow () {
return remote.getCurrentWindow()
}
closeWindow () {
return ipcHelpers.call('window-method', 'close')
}
async getTemporaryWindowState () {
const stateJSON = await ipcHelpers.call('get-temporary-window-state')
return JSON.parse(stateJSON)
}
setTemporaryWindowState (state) {
return ipcHelpers.call('set-temporary-window-state', JSON.stringify(state))
}
getWindowSize () {
const [width, height] = Array.from(remote.getCurrentWindow().getSize())
return {width, height}
}
setWindowSize (width, height) {
return ipcHelpers.call('set-window-size', width, height)
}
getWindowPosition () {
const [x, y] = Array.from(remote.getCurrentWindow().getPosition())
return {x, y}
}
setWindowPosition (x, y) {
return ipcHelpers.call('set-window-position', x, y)
}
centerWindow () {
return ipcHelpers.call('center-window')
}
focusWindow () {
return ipcHelpers.call('focus-window')
}
showWindow () {
return ipcHelpers.call('show-window')
}
hideWindow () {
return ipcHelpers.call('hide-window')
}
reloadWindow () {
return ipcHelpers.call('window-method', 'reload')
}
restartApplication () {
return ipcRenderer.send('restart-application')
}
minimizeWindow () {
return ipcHelpers.call('window-method', 'minimize')
}
isWindowMaximized () {
return remote.getCurrentWindow().isMaximized()
}
maximizeWindow () {
return ipcHelpers.call('window-method', 'maximize')
}
unmaximizeWindow () {
return ipcHelpers.call('window-method', 'unmaximize')
}
isWindowFullScreen () {
return remote.getCurrentWindow().isFullScreen()
}
setWindowFullScreen (fullScreen = false) {
return ipcHelpers.call('window-method', 'setFullScreen', fullScreen)
}
onDidEnterFullScreen (callback) {
return ipcHelpers.on(ipcRenderer, 'did-enter-full-screen', callback)
}
onDidLeaveFullScreen (callback) {
return ipcHelpers.on(ipcRenderer, 'did-leave-full-screen', callback)
}
async openWindowDevTools () {
// 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).
await new Promise(process.nextTick)
return ipcHelpers.call('window-method', 'openDevTools')
}
async closeWindowDevTools () {
// 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).
await new Promise(process.nextTick)
return ipcHelpers.call('window-method', 'closeDevTools')
}
async toggleWindowDevTools () {
// 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).
await new Promise(process.nextTick)
return ipcHelpers.call('window-method', 'toggleDevTools')
}
executeJavaScriptInWindowDevTools (code) {
return ipcRenderer.send('execute-javascript-in-dev-tools', code)
}
didClosePathWithWaitSession (path) {
return ipcHelpers.call('window-method', 'didClosePathWithWaitSession', path)
}
setWindowDocumentEdited (edited) {
return ipcHelpers.call('window-method', 'setDocumentEdited', edited)
}
setRepresentedFilename (filename) {
return ipcHelpers.call('window-method', 'setRepresentedFilename', filename)
}
addRecentDocument (filename) {
return ipcRenderer.send('add-recent-document', filename)
}
setRepresentedDirectoryPaths (paths) {
return ipcHelpers.call('window-method', 'setRepresentedDirectoryPaths', paths)
}
setAutoHideWindowMenuBar (autoHide) {
return ipcHelpers.call('window-method', 'setAutoHideMenuBar', autoHide)
}
setWindowMenuBarVisibility (visible) {
return remote.getCurrentWindow().setMenuBarVisibility(visible)
}
getPrimaryDisplayWorkAreaSize () {
return remote.screen.getPrimaryDisplay().workAreaSize
}
getUserDefault (key, type) {
return remote.systemPreferences.getUserDefault(key, type)
}
async setUserSettings (config, configFilePath) {
this.pendingSettingsUpdateCount++
try {
await ipcHelpers.call('set-user-settings', JSON.stringify(config), configFilePath)
} finally {
this.pendingSettingsUpdateCount--
}
}
onDidChangeUserSettings (callback) {
const outerCallback = (event, message, detail) => {
if (message === 'did-change-user-settings') {
if (this.pendingSettingsUpdateCount === 0) callback(detail)
}
}
ipcRenderer.on('message', outerCallback)
return new Disposable(() => ipcRenderer.removeListener('message', outerCallback))
}
onDidFailToReadUserSettings (callback) {
const outerCallback = (event, message, detail) => {
if (message === 'did-fail-to-read-user-settings') callback(detail)
}
ipcRenderer.on('message', outerCallback)
return new Disposable(() => ipcRenderer.removeListener('message', outerCallback))
}
confirm (options, callback) {
if (typeof callback === 'function') {
// Async version: pass options directly to Electron but set sane defaults
options = Object.assign({type: 'info', normalizeAccessKeys: true}, options)
remote.dialog.showMessageBox(remote.getCurrentWindow(), options, callback)
} else {
// Legacy sync version: options can only have `message`,
// `detailedMessage` (optional), and buttons array or object (optional)
let {message, detailedMessage, buttons} = options
let buttonLabels
if (!buttons) buttons = {}
if (Array.isArray(buttons)) {
buttonLabels = buttons
} else {
buttonLabels = Object.keys(buttons)
}
const chosen = remote.dialog.showMessageBox(remote.getCurrentWindow(), {
type: 'info',
message,
detail: detailedMessage,
buttons: buttonLabels,
normalizeAccessKeys: true
})
if (Array.isArray(buttons)) {
return chosen
} else {
const callback = buttons[buttonLabels[chosen]]
if (typeof callback === 'function') return callback()
}
}
}
showMessageDialog (params) {}
showSaveDialog (options, callback) {
if (typeof callback === 'function') {
// Async
this.getCurrentWindow().showSaveDialog(options, callback)
} else {
// Sync
if (typeof options === 'string') {
options = {defaultPath: options}
}
return this.getCurrentWindow().showSaveDialog(options)
}
}
playBeepSound () {
return shell.beep()
}
onDidOpenLocations (callback) {
const outerCallback = (event, message, detail) => {
if (message === 'open-locations') callback(detail)
}
ipcRenderer.on('message', outerCallback)
return new Disposable(() => ipcRenderer.removeListener('message', outerCallback))
}
onUpdateAvailable (callback) {
const outerCallback = (event, message, detail) => {
// TODO: Yes, this is strange that `onUpdateAvailable` is listening for
// `did-begin-downloading-update`. We currently have no mechanism to know
// if there is an update, so begin of downloading is a good proxy.
if (message === 'did-begin-downloading-update') callback(detail)
}
ipcRenderer.on('message', outerCallback)
return new Disposable(() => ipcRenderer.removeListener('message', outerCallback))
}
onDidBeginDownloadingUpdate (callback) {
return this.onUpdateAvailable(callback)
}
onDidBeginCheckingForUpdate (callback) {
const outerCallback = (event, message, detail) => {
if (message === 'checking-for-update') callback(detail)
}
ipcRenderer.on('message', outerCallback)
return new Disposable(() => ipcRenderer.removeListener('message', outerCallback))
}
onDidCompleteDownloadingUpdate (callback) {
const outerCallback = (event, message, detail) => {
// TODO: We could rename this event to `did-complete-downloading-update`
if (message === 'update-available') callback(detail)
}
ipcRenderer.on('message', outerCallback)
return new Disposable(() => ipcRenderer.removeListener('message', outerCallback))
}
onUpdateNotAvailable (callback) {
const outerCallback = (event, message, detail) => {
if (message === 'update-not-available') callback(detail)
}
ipcRenderer.on('message', outerCallback)
return new Disposable(() => ipcRenderer.removeListener('message', outerCallback))
}
onUpdateError (callback) {
const outerCallback = (event, message, detail) => {
if (message === 'update-error') callback(detail)
}
ipcRenderer.on('message', outerCallback)
return new Disposable(() => ipcRenderer.removeListener('message', outerCallback))
}
onApplicationMenuCommand (handler) {
const outerCallback = (event, ...args) => handler(...args)
ipcRenderer.on('command', outerCallback)
return new Disposable(() => ipcRenderer.removeListener('command', outerCallback))
}
onContextMenuCommand (handler) {
const outerCallback = (event, ...args) => handler(...args)
ipcRenderer.on('context-command', outerCallback)
return new Disposable(() => ipcRenderer.removeListener('context-command', outerCallback))
}
onURIMessage (handler) {
const outerCallback = (event, ...args) => handler(...args)
ipcRenderer.on('uri-message', outerCallback)
return new Disposable(() => ipcRenderer.removeListener('uri-message', outerCallback))
}
onDidRequestUnload (callback) {
const outerCallback = async (event, message) => {
const shouldUnload = await callback(event)
ipcRenderer.send('did-prepare-to-unload', shouldUnload)
}
ipcRenderer.on('prepare-to-unload', outerCallback)
return new Disposable(() => ipcRenderer.removeListener('prepare-to-unload', outerCallback))
}
onDidChangeHistoryManager (callback) {
const outerCallback = (event, message) => callback(event)
ipcRenderer.on('did-change-history-manager', outerCallback)
return new Disposable(() => ipcRenderer.removeListener('did-change-history-manager', outerCallback))
}
didChangeHistoryManager () {
return ipcRenderer.send('did-change-history-manager')
}
openExternal (url) {
return shell.openExternal(url)
}
checkForUpdate () {
return ipcRenderer.send('command', 'application:check-for-update')
}
restartAndInstallUpdate () {
return ipcRenderer.send('command', 'application:install-update')
}
getAutoUpdateManagerState () {
return ipcRenderer.sendSync('get-auto-update-manager-state')
}
getAutoUpdateManagerErrorMessage () {
return ipcRenderer.sendSync('get-auto-update-manager-error')
}
emitWillSavePath (path) {
return ipcHelpers.call('will-save-path', path)
}
emitDidSavePath (path) {
return ipcHelpers.call('did-save-path', path)
}
resolveProxy (requestId, url) {
return ipcRenderer.send('resolve-proxy', requestId, url)
}
onDidResolveProxy (callback) {
const outerCallback = (event, requestId, proxy) => callback(requestId, proxy)
ipcRenderer.on('did-resolve-proxy', outerCallback)
return new Disposable(() => ipcRenderer.removeListener('did-resolve-proxy', outerCallback))
}
}