diff --git a/lib/controllers/conflict-controller.js b/lib/controllers/conflict-controller.js index f51e1236f..82408b606 100644 --- a/lib/controllers/conflict-controller.js +++ b/lib/controllers/conflict-controller.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import {remote} from 'electron'; -const {Menu, MenuItem} = remote; +const {Menu, MenuItem} = require('electron').remote; import {autobind} from '../helpers'; import {OURS, BASE, THEIRS} from '../models/conflicts/source'; @@ -83,7 +83,7 @@ export default class ConflictController extends React.Component { click: this.props.dismiss, })); - menu.popup(remote.getCurrentWindow()); + menu.popup(); } render() { diff --git a/lib/controllers/issueish-list-controller.js b/lib/controllers/issueish-list-controller.js index 93ebfa9b6..d15226be9 100644 --- a/lib/controllers/issueish-list-controller.js +++ b/lib/controllers/issueish-list-controller.js @@ -5,7 +5,7 @@ import {EndpointPropType} from '../prop-types'; import IssueishListView from '../views/issueish-list-view'; import Issueish from '../models/issueish'; import {shell, remote} from 'electron'; -const {Menu, MenuItem} = remote; +const {Menu, MenuItem} = require('electron').remote; import {addEvent} from '../reporter-proxy'; const StatePropType = PropTypes.oneOf(['EXPECTED', 'PENDING', 'SUCCESS', 'ERROR', 'FAILURE']); @@ -91,7 +91,7 @@ export class BareIssueishListController extends React.Component { } openOnGitHub = async url => { - await shell.openExternal(url); + await atom.applicationDelegate.openExternal(url); addEvent('open-issueish-in-browser', {package: 'github', component: this.constructor.name}); } @@ -108,7 +108,7 @@ export class BareIssueishListController extends React.Component { click: () => this.openOnGitHub(issueish.getGitHubURL()), })); - menu.popup(remote.getCurrentWindow()); + menu.popup(); } render() { diff --git a/lib/controllers/issueish-searches-controller.js b/lib/controllers/issueish-searches-controller.js index 4d1d79b06..5883c68ad 100644 --- a/lib/controllers/issueish-searches-controller.js +++ b/lib/controllers/issueish-searches-controller.js @@ -1,7 +1,5 @@ import React from 'react'; import PropTypes from 'prop-types'; -import {shell} from 'electron'; - import {RemotePropType, RemoteSetPropType, BranchSetPropType, EndpointPropType} from '../prop-types'; import Search from '../models/search'; import IssueishSearchContainer from '../containers/issueish-search-container'; @@ -115,6 +113,6 @@ export default class IssueishSearchesController extends React.Component { onOpenSearch = async search => { const searchURL = search.getWebURL(this.props.remote); - await shell.openExternal(searchURL); + await atom.applicationDelegate.openExternal(searchURL); } } diff --git a/lib/controllers/remote-controller.js b/lib/controllers/remote-controller.js index f0a38cc49..456fc64ee 100644 --- a/lib/controllers/remote-controller.js +++ b/lib/controllers/remote-controller.js @@ -1,7 +1,5 @@ import React from 'react'; import PropTypes from 'prop-types'; -import {shell} from 'electron'; - import {incrementCounter} from '../reporter-proxy'; import {RemotePropType, RemoteSetPropType, BranchSetPropType, EndpointPropType, TokenPropType} from '../prop-types'; import IssueishSearchesController from './issueish-searches-controller'; @@ -67,7 +65,7 @@ export default class RemoteController extends React.Component { createPrUrl += '/compare/' + encodeURIComponent(currentBranch.getName()); createPrUrl += '?expand=1'; - await shell.openExternal(createPrUrl); + await atom.applicationDelegate.openExternal(createPrUrl); incrementCounter('create-pull-request'); } } diff --git a/lib/controllers/root-controller.js b/lib/controllers/root-controller.js index 7ba6779ae..c8dd38394 100644 --- a/lib/controllers/root-controller.js +++ b/lib/controllers/root-controller.js @@ -1,7 +1,5 @@ import fs from 'fs-extra'; import path from 'path'; -import {remote} from 'electron'; - import React, {Fragment} from 'react'; import PropTypes from 'prop-types'; import {CompositeDisposable} from 'event-kit'; @@ -500,7 +498,8 @@ export default class RootController extends React.Component { const url = 'https://clients2.google.com/service/update2/crx?' + `response=redirect&x=id%3D${id}%26uc&prodversion=32`; - const extensionFolder = path.resolve(remote.app.getPath('userData'), `extensions/${id}`); + const {ipcRenderer} = require('electron'); + const extensionFolder = path.resolve(ipcRenderer.sendSync('atom-app-get-path-sync', 'userData'), `extensions/${id}`); const extensionFile = `${extensionFolder}.crx`; await fs.ensureDir(path.dirname(extensionFile)); const response = await fetch(url, {method: 'GET'}); diff --git a/lib/git-shell-out-strategy.js b/lib/git-shell-out-strategy.js index b56cdcd64..589909961 100644 --- a/lib/git-shell-out-strategy.js +++ b/lib/git-shell-out-strategy.js @@ -3,8 +3,6 @@ import os from 'os'; import childProcess from 'child_process'; import fs from 'fs-extra'; import util from 'util'; -import {remote} from 'electron'; - import {CompositeDisposable} from 'event-kit'; import {GitProcess} from 'dugite'; import {parse as parseDiff} from 'what-the-diff'; @@ -88,7 +86,7 @@ export default class GitShellOutStrategy { this.workerManager = options.workerManager; if (headless === null) { - headless = !remote.getCurrentWindow().isVisible(); + headless = !(require('electron').remote.getCurrentWindow().isVisible()); } } diff --git a/lib/models/event-logger.js b/lib/models/event-logger.js index 289057e10..14bba993d 100644 --- a/lib/models/event-logger.js +++ b/lib/models/event-logger.js @@ -1,6 +1,4 @@ import path from 'path'; -import {remote} from 'electron'; - let headless = null; export default class EventLogger { @@ -10,7 +8,7 @@ export default class EventLogger { this.shortDirectory = ''; if (headless === null) { - headless = !remote.getCurrentWindow().isVisible(); + headless = !(require('electron').remote.getCurrentWindow().isVisible()); } } diff --git a/lib/views/actionable-review-view.js b/lib/views/actionable-review-view.js index 888837db6..ff59f996e 100644 --- a/lib/views/actionable-review-view.js +++ b/lib/views/actionable-review-view.js @@ -7,7 +7,7 @@ import AtomTextEditor from '../atom/atom-text-editor'; import RefHolder from '../models/ref-holder'; import {addEvent} from '../reporter-proxy'; import Commands, {Command} from '../atom/commands'; -const {Menu, MenuItem} = remote; +const {Menu, MenuItem} = require('electron').remote; export default class ActionableReviewView extends React.Component { static propTypes = { @@ -128,12 +128,12 @@ export default class ActionableReviewView extends React.Component { const url = 'https://github.com/contact/report-content?report=' + `${encodeURIComponent(author)}&content_url=${encodeURIComponent(commentUrl)}`; - await shell.openExternal(url); + await atom.applicationDelegate.openExternal(url); addEvent('report-abuse', {package: 'github', component: this.constructor.name}); } openOnGitHub = async url => { - await shell.openExternal(url); + await atom.applicationDelegate.openExternal(url); addEvent('open-comment-in-browser', {package: 'github', component: this.constructor.name}); } @@ -159,6 +159,6 @@ export default class ActionableReviewView extends React.Component { click: () => this.reportAbuse(content.url, author.login), })); - menu.popup(remote.getCurrentWindow()); + menu.popup(); } } diff --git a/lib/views/issueish-link.js b/lib/views/issueish-link.js index 80571c1ba..f14fef047 100644 --- a/lib/views/issueish-link.js +++ b/lib/views/issueish-link.js @@ -1,6 +1,4 @@ import url from 'url'; -import {shell} from 'electron'; - import React from 'react'; import PropTypes from 'prop-types'; @@ -45,7 +43,7 @@ export function openIssueishLinkInNewTab(url, options = {}) { } export async function openLinkInBrowser(uri) { - await shell.openExternal(uri); + await atom.applicationDelegate.openExternal(uri); addEvent('open-issueish-in-browser', {package: 'github', from: 'issueish-link'}); } diff --git a/lib/views/staging-view.js b/lib/views/staging-view.js index fa73b425f..0ab5000ba 100644 --- a/lib/views/staging-view.js +++ b/lib/views/staging-view.js @@ -1,6 +1,6 @@ import {Disposable, CompositeDisposable} from 'event-kit'; import {remote} from 'electron'; -const {Menu, MenuItem} = remote; +const {Menu, MenuItem} = require('electron').remote; import {File} from 'atom'; import React, {Fragment} from 'react'; import PropTypes from 'prop-types'; @@ -644,7 +644,7 @@ export default class StagingView extends React.Component { click: () => this.props.resolveAsTheirs(conflictPaths), })); - menu.popup(remote.getCurrentWindow()); + menu.popup(); } showActionsMenu(event) { @@ -673,7 +673,7 @@ export default class StagingView extends React.Component { enabled: this.props.hasUndoHistory, })); - menu.popup(remote.getCurrentWindow()); + menu.popup(); } resolveCurrentAsOurs() { diff --git a/lib/worker-manager.js b/lib/worker-manager.js index 17b958819..f7ff73927 100644 --- a/lib/worker-manager.js +++ b/lib/worker-manager.js @@ -2,7 +2,7 @@ import path from 'path'; import querystring from 'querystring'; import {remote, ipcRenderer as ipc} from 'electron'; -const {BrowserWindow} = remote; +const {BrowserWindow} = require('electron').remote; import {Emitter, Disposable, CompositeDisposable} from 'event-kit'; import {getPackageRoot, autobind} from './helpers'; @@ -153,7 +153,7 @@ export class Worker { } getWebContentsId() { - return remote.getCurrentWebContents().id; + return require('electron').ipcRenderer.sendSync('atom-get-web-contents-id-sync'); } executeOperation(operation) { diff --git a/lib/worker.js b/lib/worker.js index 7d3e1ad33..a2c1305fc 100644 --- a/lib/worker.js +++ b/lib/worker.js @@ -1,6 +1,6 @@ const qs = require('querystring'); -const {remote, ipcRenderer: ipc} = require('electron'); +const {ipcRenderer: ipc} = require('electron'); const {GitProcess} = require('dugite'); @@ -39,31 +39,24 @@ class AverageTracker { } const query = qs.parse(window.location.search.substr(1)); -const sourceWebContentsId = remote.getCurrentWindow().webContents.id; +const sourceWebContentsId = ipc.sendSync('atom-get-web-contents-id-sync'); const operationCountLimit = parseInt(query.operationCountLimit, 10); const averageTracker = new AverageTracker({limit: operationCountLimit}); const childPidsById = new Map(); +// Manager lifecycle is handled in main (register-renderer-ipc): if the +// manager renderer dies, worker windows are destroyed automatically. +const managerWebContentsId = parseInt(query.managerWebContentsId, 10); const destroyRenderer = () => { - if (!managerWebContents.isDestroyed()) { - managerWebContents.removeListener('crashed', destroyRenderer); - managerWebContents.removeListener('destroyed', destroyRenderer); - } - const win = remote.BrowserWindow.fromWebContents(remote.getCurrentWebContents()); - if (win && !win.isDestroyed()) { - win.destroy(); + try { + ipc.sendSync('atom-destroy-own-window-sync'); + } catch (e) { + /* ignore */ } }; -const managerWebContentsId = parseInt(query.managerWebContentsId, 10); -const managerWebContents = remote.webContents.fromId(managerWebContentsId); -if (managerWebContents && !managerWebContents.isDestroyed()) { - managerWebContents.on('crashed', destroyRenderer); - managerWebContents.on('destroyed', destroyRenderer); - window.onbeforeunload = () => { - managerWebContents.removeListener('crashed', destroyRenderer); - managerWebContents.removeListener('destroyed', destroyRenderer); - }; -} +window.onbeforeunload = () => { + // no-op: main owns parent/child lifecycle +}; const channelName = query.channelName; ipc.on(channelName, (event, {type, data}) => { @@ -77,7 +70,7 @@ ipc.on(channelName, (event, {type, data}) => { childPidsById.set(id, child.pid); child.on('error', err => { - event.sender.sendTo(managerWebContentsId, channelName, { + ipc.send('atom-wc-send', managerWebContentsId, channelName, { sourceWebContentsId, type: 'git-spawn-error', data: {id, err}, @@ -85,7 +78,7 @@ ipc.on(channelName, (event, {type, data}) => { }); child.stdin.on('error', err => { - event.sender.sendTo(managerWebContentsId, channelName, { + ipc.send('atom-wc-send', managerWebContentsId, channelName, { sourceWebContentsId, type: 'git-stdin-error', data: {id, stdin: options.stdin, err}, @@ -101,7 +94,7 @@ ipc.on(channelName, (event, {type, data}) => { execTime: performance.now() - spawnEnd, }; childPidsById.delete(id); - event.sender.sendTo(managerWebContentsId, channelName, { + ipc.send('atom-wc-send', managerWebContentsId, channelName, { sourceWebContentsId, type: 'git-data', data: { @@ -116,7 +109,7 @@ ipc.on(channelName, (event, {type, data}) => { execTime: performance.now() - spawnEnd, }; childPidsById.delete(id); - event.sender.sendTo(managerWebContentsId, channelName, { + ipc.send('atom-wc-send', managerWebContentsId, channelName, { sourceWebContentsId, type: 'git-data', data: { @@ -137,17 +130,17 @@ ipc.on(channelName, (event, {type, data}) => { // TODO: consider using this to avoid duplicate write operations upon crashing. // For now we won't do this to avoid clogging up ipc channel - // event.sender.sendTo(managerWebContentsId, channelName, {sourceWebContentsId, type: 'exec-started', data: {id}}); + // ipc.send('atom-wc-send', managerWebContentsId, channelName, {sourceWebContentsId, type: 'exec-started', data: {id}}); if (averageTracker.enoughData() && averageTracker.getAverage() > 20) { - event.sender.sendTo(managerWebContentsId, channelName, {type: 'slow-spawns'}); + ipc.send('atom-wc-send', managerWebContentsId, channelName, {type: 'slow-spawns'}); } } else if (type === 'git-cancel') { const {id} = data; const childPid = childPidsById.get(id); if (childPid !== undefined) { require('tree-kill')(childPid, 'SIGINT', () => { - event.sender.sendTo(managerWebContentsId, channelName, { + ipc.send('atom-wc-send', managerWebContentsId, channelName, { sourceWebContentsId, type: 'git-cancelled', data: {id, childPid}, @@ -160,4 +153,4 @@ ipc.on(channelName, (event, {type, data}) => { } }); -ipc.sendTo(managerWebContentsId, channelName, {sourceWebContentsId, type: 'renderer-ready', data: {pid: process.pid}}); +ipc.send('atom-wc-send', managerWebContentsId, channelName, {sourceWebContentsId, type: 'renderer-ready', data: {pid: process.pid}});