Skip to content

Commit

Permalink
feat: Add first-instance-ack event to the `app.requestSingleInstanc…
Browse files Browse the repository at this point in the history
…eLock()` flow (electron#31460)

* feat: Add onFirstInstanceAck event for requestSingleInstanceLock

* Add tests

* Apply patch fix

* Add back missing docs

* Rebase

* Listen for exit earlier in test

* Rebase
  • Loading branch information
rzhao271 authored and t57ser committed Jan 25, 2022
1 parent 57e4ef1 commit ae4786e
Show file tree
Hide file tree
Showing 7 changed files with 514 additions and 92 deletions.
38 changes: 37 additions & 1 deletion docs/api/app.md
Expand Up @@ -484,6 +484,7 @@ Returns:
* `argv` string[] - An array of the second instance's command line arguments
* `workingDirectory` string - The second instance's working directory
* `additionalData` unknown - A JSON object of additional data passed from the second instance
* `ackCallback` unknown - A function that can be used to send data back to the second instance

This event will be emitted inside the primary instance of your application
when a second instance has been executed and calls `app.requestSingleInstanceLock()`.
Expand All @@ -495,12 +496,35 @@ non-minimized.

**Note:** If the second instance is started by a different user than the first, the `argv` array will not include the arguments.

**Note:** `ackCallback` allows the user to send data back to the
second instance during the `app.requestSingleInstanceLock()` flow.
This callback can be used for cases where the second instance
needs to obtain additional information from the first instance
before quitting.

Currently, the limit on the message size is kMaxMessageLength,
or around 32kB. To be safe, keep the amount of data passed to 31kB at most.

In order to call the callback, `event.preventDefault()` must be called, first.
If the callback is not called in either case, `null` will be sent back.
If `event.preventDefault()` is not called, but `ackCallback` is called
by the user in the event, then the behaviour is undefined.

This event is guaranteed to be emitted after the `ready` event of `app`
gets emitted.

**Note:** Extra command line arguments might be added by Chromium,
such as `--original-process-start-time`.

### Event: 'first-instance-ack'

Returns:

* `event` Event
* `additionalData` unknown - A JSON object of additional data passed from the first instance, in response to the first instance's `second-instance` event.

This event will be emitted within the second instance during the call to `app.requestSingleInstanceLock()`, when the first instance calls the `ackCallback` provided by the `second-instance` event handler.

## Methods

The `app` object has the following methods:
Expand Down Expand Up @@ -959,21 +983,33 @@ starts:
const { app } = require('electron')
let myWindow = null

app.on('first-instance-ack', (event, additionalData) => {
// Print out the ack received from the first instance.
// Note this event handler must come before the requestSingleInstanceLock call.
// Expected output: '{"myAckKey":"myAckValue"}'
console.log(JSON.stringify(additionalData))
})

const additionalData = { myKey: 'myValue' }
const gotTheLock = app.requestSingleInstanceLock(additionalData)

if (!gotTheLock) {
app.quit()
} else {
app.on('second-instance', (event, commandLine, workingDirectory, additionalData) => {
// We must call preventDefault if we're sending back data.
event.preventDefault()
// Print out data received from the second instance.
console.log(additionalData)
// Expected output: '{"myKey":"myValue"}'
console.log(JSON.stringify(additionalData))

// Someone tried to run a second instance, we should focus our window.
if (myWindow) {
if (myWindow.isMinimized()) myWindow.restore()
myWindow.focus()
}
const ackData = { myAckKey: 'myAckValue' }
ackCallback(ackData)
})

// Create myWindow, load the rest of the app, etc...
Expand Down
2 changes: 1 addition & 1 deletion patches/chromium/.patches
Expand Up @@ -106,8 +106,8 @@ chore_do_not_use_chrome_windows_in_cryptotoken_webrequestsender.patch
process_singleton.patch
fix_expose_decrementcapturercount_in_web_contents_impl.patch
add_ui_scopedcliboardwriter_writeunsaferawdata.patch
feat_add_data_parameter_to_processsingleton.patch
mas_gate_private_enterprise_APIs.patch
load_v8_snapshot_in_browser_process.patch
fix_patch_out_permissions_checks_in_exclusive_access.patch
fix_aspect_ratio_with_max_size.patch
feat_add_data_transfer_to_requestsingleinstancelock.patch

0 comments on commit ae4786e

Please sign in to comment.