Merge pull request #613 from feross/fix-606
Fix IPC race condition in startup
This commit is contained in:
@@ -327,11 +327,11 @@ function buildDarwin (cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var dmg = appDmg(dmgOpts)
|
var dmg = appDmg(dmgOpts)
|
||||||
dmg.on('error', cb)
|
dmg.once('error', cb)
|
||||||
dmg.on('progress', function (info) {
|
dmg.on('progress', function (info) {
|
||||||
if (info.type === 'step-begin') console.log(info.title + '...')
|
if (info.type === 'step-begin') console.log(info.title + '...')
|
||||||
})
|
})
|
||||||
dmg.on('finish', function (info) {
|
dmg.once('finish', function (info) {
|
||||||
console.log('OS X: Created dmg.')
|
console.log('OS X: Created dmg.')
|
||||||
cb(null)
|
cb(null)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ function init () {
|
|||||||
|
|
||||||
ipc.init()
|
ipc.init()
|
||||||
|
|
||||||
app.on('will-finish-launching', function () {
|
app.once('will-finish-launching', function () {
|
||||||
crashReporter.init()
|
crashReporter.init()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ function init () {
|
|||||||
setTimeout(delayedInit, config.DELAYED_INIT)
|
setTimeout(delayedInit, config.DELAYED_INIT)
|
||||||
})
|
})
|
||||||
|
|
||||||
app.on('ipcReady', function () {
|
app.once('ipcReady', function () {
|
||||||
log('Command line args:', argv)
|
log('Command line args:', argv)
|
||||||
processArgv(argv)
|
processArgv(argv)
|
||||||
console.timeEnd('init')
|
console.timeEnd('init')
|
||||||
@@ -103,13 +103,12 @@ function onOpen (e, torrentId) {
|
|||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
if (app.ipcReady) {
|
if (app.ipcReady) {
|
||||||
windows.main.dispatch('onOpen', torrentId)
|
|
||||||
// Magnet links opened from Chrome won't focus the app without a setTimeout.
|
// Magnet links opened from Chrome won't focus the app without a setTimeout.
|
||||||
// The confirmation dialog Chrome shows causes Chrome to steal back the focus.
|
// The confirmation dialog Chrome shows causes Chrome to steal back the focus.
|
||||||
// Electron issue: https://github.com/atom/electron/issues/4338
|
// Electron issue: https://github.com/atom/electron/issues/4338
|
||||||
setTimeout(function () {
|
setTimeout(() => windows.main.show(), 100)
|
||||||
windows.main.show()
|
|
||||||
}, 100)
|
processArgv([ torrentId ])
|
||||||
} else {
|
} else {
|
||||||
argv.push(torrentId)
|
argv.push(torrentId)
|
||||||
}
|
}
|
||||||
@@ -117,7 +116,6 @@ function onOpen (e, torrentId) {
|
|||||||
|
|
||||||
function onAppOpen (newArgv) {
|
function onAppOpen (newArgv) {
|
||||||
newArgv = sliceArgv(newArgv)
|
newArgv = sliceArgv(newArgv)
|
||||||
console.log(newArgv)
|
|
||||||
|
|
||||||
if (app.ipcReady) {
|
if (app.ipcReady) {
|
||||||
log('Second app instance opened, but was prevented:', newArgv)
|
log('Second app instance opened, but was prevented:', newArgv)
|
||||||
@@ -134,7 +132,7 @@ function sliceArgv (argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function processArgv (argv) {
|
function processArgv (argv) {
|
||||||
var paths = []
|
var torrentIds = []
|
||||||
argv.forEach(function (arg) {
|
argv.forEach(function (arg) {
|
||||||
if (arg === '-n') {
|
if (arg === '-n') {
|
||||||
dialog.openSeedDirectory()
|
dialog.openSeedDirectory()
|
||||||
@@ -146,10 +144,10 @@ function processArgv (argv) {
|
|||||||
// Ignore OS X launchd "process serial number" argument
|
// Ignore OS X launchd "process serial number" argument
|
||||||
// Issue: https://github.com/feross/webtorrent-desktop/issues/214
|
// Issue: https://github.com/feross/webtorrent-desktop/issues/214
|
||||||
} else {
|
} else {
|
||||||
paths.push(arg)
|
torrentIds.push(arg)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (paths.length > 0) {
|
if (torrentIds.length > 0) {
|
||||||
windows.main.dispatch('onOpen', paths)
|
windows.main.dispatch('onOpen', torrentIds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,13 +25,12 @@ var vlcProcess
|
|||||||
function init () {
|
function init () {
|
||||||
var ipc = electron.ipcMain
|
var ipc = electron.ipcMain
|
||||||
|
|
||||||
ipc.on('ipcReady', function (e) {
|
ipc.once('ipcReady', function (e) {
|
||||||
windows.main.show()
|
|
||||||
app.ipcReady = true
|
app.ipcReady = true
|
||||||
app.emit('ipcReady')
|
app.emit('ipcReady')
|
||||||
})
|
})
|
||||||
|
|
||||||
ipc.on('ipcReadyWebTorrent', function (e) {
|
ipc.once('ipcReadyWebTorrent', function (e) {
|
||||||
app.ipcReadyWebTorrent = true
|
app.ipcReadyWebTorrent = true
|
||||||
log('sending %d queued messages from the main win to the webtorrent window',
|
log('sending %d queued messages from the main win to the webtorrent window',
|
||||||
messageQueueMainToWebTorrent.length)
|
messageQueueMainToWebTorrent.length)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ function log (...args) {
|
|||||||
if (app.ipcReady) {
|
if (app.ipcReady) {
|
||||||
windows.main.send('log', ...args)
|
windows.main.send('log', ...args)
|
||||||
} else {
|
} else {
|
||||||
app.on('ipcReady', () => windows.main.send('log', ...args))
|
app.once('ipcReady', () => windows.main.send('log', ...args))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,6 +25,6 @@ function error (...args) {
|
|||||||
if (app.ipcReady) {
|
if (app.ipcReady) {
|
||||||
windows.main.send('error', ...args)
|
windows.main.send('error', ...args)
|
||||||
} else {
|
} else {
|
||||||
app.on('ipcReady', () => windows.main.send('error', ...args))
|
app.once('ipcReady', () => windows.main.send('error', ...args))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ function init () {
|
|||||||
// No menu on the About window
|
// No menu on the About window
|
||||||
win.setMenu(null)
|
win.setMenu(null)
|
||||||
|
|
||||||
// TODO: can this be removed?
|
|
||||||
win.webContents.on('did-finish-load', function () {
|
win.webContents.on('did-finish-load', function () {
|
||||||
win.show()
|
win.show()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ function init () {
|
|||||||
icon: getIconPath(), // Window icon (Windows, Linux)
|
icon: getIconPath(), // Window icon (Windows, Linux)
|
||||||
minWidth: config.WINDOW_MIN_WIDTH,
|
minWidth: config.WINDOW_MIN_WIDTH,
|
||||||
minHeight: config.WINDOW_MIN_HEIGHT,
|
minHeight: config.WINDOW_MIN_HEIGHT,
|
||||||
show: false, // Hide window until renderer sends 'ipcReady'
|
|
||||||
title: config.APP_WINDOW_TITLE,
|
title: config.APP_WINDOW_TITLE,
|
||||||
titleBarStyle: 'hidden-inset', // Hide title bar (OS X)
|
titleBarStyle: 'hidden-inset', // Hide title bar (OS X)
|
||||||
useContentSize: true, // Specify web page size without OS chrome
|
useContentSize: true, // Specify web page size without OS chrome
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ table {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
background: rgb(40, 40, 40);
|
background: rgb(40, 40, 40);
|
||||||
animation: fadein 1s;
|
animation: fadein 0.5s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app:not(.is-focused) {
|
.app:not(.is-focused) {
|
||||||
|
|||||||
@@ -3,18 +3,9 @@ console.time('init')
|
|||||||
var crashReporter = require('../crash-reporter')
|
var crashReporter = require('../crash-reporter')
|
||||||
crashReporter.init()
|
crashReporter.init()
|
||||||
|
|
||||||
var electron = require('electron')
|
|
||||||
|
|
||||||
// Electron apps have two processes: a main process (node) runs first and starts
|
|
||||||
// a renderer process (essentially a Chrome window). We're in the renderer process,
|
|
||||||
// and this IPC channel receives from and sends messages to the main process
|
|
||||||
var ipcRenderer = electron.ipcRenderer
|
|
||||||
|
|
||||||
// Listen for messages from the main process
|
|
||||||
setupIpc()
|
|
||||||
|
|
||||||
var appConfig = require('application-config')('WebTorrent')
|
var appConfig = require('application-config')('WebTorrent')
|
||||||
var dragDrop = require('drag-drop')
|
var dragDrop = require('drag-drop')
|
||||||
|
var electron = require('electron')
|
||||||
var fs = require('fs-extra')
|
var fs = require('fs-extra')
|
||||||
var mainLoop = require('main-loop')
|
var mainLoop = require('main-loop')
|
||||||
var parallel = require('run-parallel')
|
var parallel = require('run-parallel')
|
||||||
@@ -46,6 +37,11 @@ var vdomLoop
|
|||||||
var state = State.getInitialState()
|
var state = State.getInitialState()
|
||||||
state.location.go({ url: 'home' }) // Add first page to location history
|
state.location.go({ url: 'home' }) // Add first page to location history
|
||||||
|
|
||||||
|
// Electron apps have two processes: a main process (node) runs first and starts
|
||||||
|
// a renderer process (essentially a Chrome window). We're in the renderer process,
|
||||||
|
// and this IPC channel receives from and sends messages to the main process
|
||||||
|
var ipcRenderer = electron.ipcRenderer
|
||||||
|
|
||||||
// All state lives in state.js. `state.saved` is read from and written to a file.
|
// All state lives in state.js. `state.saved` is read from and written to a file.
|
||||||
// All other state is ephemeral. First we load state.saved then initialize the app.
|
// All other state is ephemeral. First we load state.saved then initialize the app.
|
||||||
loadState(init)
|
loadState(init)
|
||||||
@@ -90,6 +86,9 @@ function init () {
|
|||||||
})
|
})
|
||||||
document.body.appendChild(vdomLoop.target)
|
document.body.appendChild(vdomLoop.target)
|
||||||
|
|
||||||
|
// Listen for messages from the main process
|
||||||
|
setupIpc()
|
||||||
|
|
||||||
// Calling update() updates the UI given the current state
|
// Calling update() updates the UI given the current state
|
||||||
// Do this at least once a second to give every file in every torrentSummary
|
// Do this at least once a second to give every file in every torrentSummary
|
||||||
// a progress bar and to keep the cursor in sync when playing a video
|
// a progress bar and to keep the cursor in sync when playing a video
|
||||||
@@ -106,9 +105,9 @@ function init () {
|
|||||||
window.addEventListener('focus', onFocus)
|
window.addEventListener('focus', onFocus)
|
||||||
window.addEventListener('blur', onBlur)
|
window.addEventListener('blur', onBlur)
|
||||||
|
|
||||||
// Done! Ideally we want to get here <100ms after the user clicks the app
|
|
||||||
sound.play('STARTUP')
|
sound.play('STARTUP')
|
||||||
|
|
||||||
|
// Done! Ideally we want to get here < 500ms after the user clicks the app
|
||||||
console.timeEnd('init')
|
console.timeEnd('init')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +138,7 @@ function render (state) {
|
|||||||
// Calls render() to go from state -> UI, then applies to vdom to the real DOM.
|
// Calls render() to go from state -> UI, then applies to vdom to the real DOM.
|
||||||
function update () {
|
function update () {
|
||||||
showOrHidePlayerControls()
|
showOrHidePlayerControls()
|
||||||
if (vdomLoop) vdomLoop.update(state)
|
vdomLoop.update(state)
|
||||||
updateElectron()
|
updateElectron()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,8 +457,6 @@ function isCasting () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setupIpc () {
|
function setupIpc () {
|
||||||
ipcRenderer.send('ipcReady')
|
|
||||||
|
|
||||||
ipcRenderer.on('log', (e, ...args) => console.log(...args))
|
ipcRenderer.on('log', (e, ...args) => console.log(...args))
|
||||||
ipcRenderer.on('error', (e, ...args) => console.error(...args))
|
ipcRenderer.on('error', (e, ...args) => console.error(...args))
|
||||||
|
|
||||||
@@ -486,13 +483,15 @@ function setupIpc () {
|
|||||||
ipcRenderer.on('wt-poster', (e, ...args) => torrentPosterSaved(...args))
|
ipcRenderer.on('wt-poster', (e, ...args) => torrentPosterSaved(...args))
|
||||||
ipcRenderer.on('wt-audio-metadata', (e, ...args) => torrentAudioMetadata(...args))
|
ipcRenderer.on('wt-audio-metadata', (e, ...args) => torrentAudioMetadata(...args))
|
||||||
ipcRenderer.on('wt-server-running', (e, ...args) => torrentServerRunning(...args))
|
ipcRenderer.on('wt-server-running', (e, ...args) => torrentServerRunning(...args))
|
||||||
|
|
||||||
|
ipcRenderer.send('ipcReady')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Starts all torrents that aren't paused on program startup
|
// Starts all torrents that aren't paused on program startup
|
||||||
function resumeTorrents () {
|
function resumeTorrents () {
|
||||||
state.saved.torrents
|
state.saved.torrents
|
||||||
.filter((x) => x.status !== 'paused')
|
.filter((torrentSummary) => torrentSummary.status !== 'paused')
|
||||||
.forEach((x) => startTorrentingSummary(x))
|
.forEach((torrentSummary) => startTorrentingSummary(torrentSummary))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates a single property in the UNSAVED prefs
|
// Updates a single property in the UNSAVED prefs
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ function getTorrentProgress () {
|
|||||||
function startServer (infoHash, index) {
|
function startServer (infoHash, index) {
|
||||||
var torrent = client.get(infoHash)
|
var torrent = client.get(infoHash)
|
||||||
if (torrent.ready) startServerFromReadyTorrent(torrent, index)
|
if (torrent.ready) startServerFromReadyTorrent(torrent, index)
|
||||||
else torrent.on('ready', () => startServerFromReadyTorrent(torrent, index))
|
else torrent.once('ready', () => startServerFromReadyTorrent(torrent, index))
|
||||||
}
|
}
|
||||||
|
|
||||||
function startServerFromReadyTorrent (torrent, index, cb) {
|
function startServerFromReadyTorrent (torrent, index, cb) {
|
||||||
|
|||||||
Reference in New Issue
Block a user