Merge pull request #11966 from electron/documentation-overhaul

Documentation Overhaul
This commit is contained in:
Vanessa Yuen 2018-02-21 20:51:52 +01:00 committed by GitHub
commit 8e51659237
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 1251 additions and 663 deletions

View file

@ -14,35 +14,89 @@ an issue:
* [Electron FAQ](faq.md)
## Guides
## Guides and Tutorials
* [Setting up the Development Environment](tutorial/development-environment.md)
* [Setting up macOS](tutorial/development-environment.md#setting-up-macos)
* [Setting up Windows](tutorial/development-environment.md#setting-up-windows)
* [Setting up Linux](tutorial/development-environment.md#setting-up-linux)
* [Choosing an Editor](tutorial/development-environment.md#a-good-editor)
* [Creating your First App](tutorial/first-app.md)
* [Installing Electron](tutorial/first-app.md#installing-electron)
* [Electron Development in a Nutshell](tutorial/first-app.md#electron-development-in-a-nutshell)
* [Running Your App](tutorial/first-app.md#running-your-app)
* [Boilerplates and CLIs](tutorial/boilerplates-and-clis.md)
* [Boilerplate vs CLI](tutorial/boilerplates-and-clis.md#boilerplate-vs-cli)
* [electron-forge](tutorial/boilerplates-and-clis.md#electron-forge)
* [electron-builder](tutorial/boilerplates-and-clis.md#electron-builder)
* [electron-react-boilerplate](tutorial/boilerplates-and-clis.md#electron-react-boilerplate)
* [Other Tools and Boilerplates](tutorial/boilerplates-and-clis.md#other-tools-and-boilerplates)
* [Application Architecture](tutorial/application-architecture.md)
* [Main and Renderer Processes](tutorial/application-architecture.md#main-and-renderer-processes)
* [Using Electron's APIs](tutorial/application-architecture.md#using-electron-apis)
* [Using Node.js APIs](tutorial/application-architecture.md#using-node.js-apis)
* [Using Native Node.js Modules](tutorial/using-native-node-modules.md)
* [Inter-Process Communication](tutorial/application-architecture.md#)
* Adding Features to Your App
* [Notifications](tutorial/notifications.md)
* [Recent Documents](tutorial/desktop-environment-integration.md#recent-documents-windows-mac-os)
* [Application Progress](tutorial/progress-bar.md)
* [Custom Dock Menu](tutorial/desktop-environment-integration.md#custom-dock-menu-mac-os)
* [Custom Windows Taskbar](tutorial/windows-taskbar.md)
* [Custom Linux Desktop Actions](tutorial/linux-desktop-actions.md)
* [Keyboard Shortcuts](tutorial/keyboard-shortcuts.md)
* [Offline/Online Detection](tutorial/online-offline-events.md)
* [Represented File for macOS BrowserWindows](tutorial/represented-file.md)
* [Native File Drag & Drop](tutorial/native-file-drag-drop.md)
* [Application Accessibility](tutorial/accessibility.md)
* [Spectron](tutorial/accessibility.md#spectron)
* [Devtron](tutorial/accessibility.md#devtron)
* [Enabling Accessibility](tutorial/accessibility.md#enabling-accessibility)
* [Application Testing and Debugging](tutorial/application-debugging.md)
* [Debugging the Main Process](tutorial/debugging-main-process.md)
* [Using Selenium and WebDriver](tutorial/using-selenium-and-webdriver.md)
* [Testing on Headless CI Systems (Travis, Jenkins)](tutorial/testing-on-headless-ci.md)
* [DevTools Extension](tutorial/devtools-extension.md)
* [Application Distribution](tutorial/application-distribution.md)
* [Supported Platforms](tutorial/supported-platforms.md)
* [Mac App Store](tutorial/mac-app-store-submission-guide.md)
* [Windows Store](tutorial/windows-store-guide.md)
* [Snapcraft](tutorial/snapcraft.md)
* [Application Security](tutorial/security.md)
* [Reporting Security Issues](tutorial/security.md#reporting-security-issues)
* [Chromium Security Issues and Upgrades](tutorial/security.md#chromium-security-issues-and-upgrades)
* [Electron Security Warnings](tutorial/security.md#electron-security-warnings)
* [Security Checklist](tutorial/security.md#checklist-security-recommendations)
* [Application Updates](tutorial/updates.md)
* [Deploying an Update Server](tutorial/updates.md#deploying-an-update-server)
* [Implementing Updates in Your App](tutorial/updates.md#implementing-updates-in-your-app)
* [Applying Updates](tutorial/updates.md#applying-updates)
## Detailed Tutorials
These individual tutorials expand on topics discussed in the guide above.
* [In Detail: Installing Electron](tutorial/installation.md)
* [Global versus Local Installation](tutorial/installation.md#global-versus-local-installation)
* [Proxies](tutorial/installation.md#proxies)
* [Custom Mirrors and Caches](tutorial/installation.md#custom-mirrors-and-caches)
* [Troubleshooting](tutorial/installation.md#troubleshooting)
* [In Detail: Electron's Versioning Scheme](tutorial/electron-versioning.md)
* [semver](tutorial/electron-versioning.md#semver)
* [Stabilization Branches](tutorial/electron-versioning.md#stabilization-branches)
* [Beta Releases and Bug Fixes](tutorial/electron-versioning.md#beta-releases-and-bug-fixes)
* [In Detail: Packaging App Source Code with asar](tutorial/application-packaging.md)
* [Generating asar Archives](tutorial/application-packaging.md#generating-asar-archives)
* [Using asar Archives](tutorial/application-packaging.md#using-asar-archives)
* [Limitations](tutorial/application-packaging.md#limitations-of-the-node-api)
* [Adding Unpacked Files to asar Archives](tutorial/application-packaging.md#adding-unpacked-files-to-asar-archives)
* [In Detail: Using Pepper Flash Plugin](tutorial/using-pepper-flash-plugin.md)
* [In Detail: Using Widevine CDM Plugin](tutorial/using-widevine-cdm-plugin.md)
* [Offscreen Rendering](tutorial/offscreen-rendering.md)
---
* [Glossary of Terms](glossary.md)
* [Supported Platforms](tutorial/supported-platforms.md)
* [Security](tutorial/security.md)
* [Versioning](tutorial/electron-versioning.md)
* [Application Distribution](tutorial/application-distribution.md)
* [Mac App Store Submission Guide](tutorial/mac-app-store-submission-guide.md)
* [Windows Store Guide](tutorial/windows-store-guide.md)
* [Snapcraft Guide](tutorial/snapcraft-guide.md)
* [Application Packaging](tutorial/application-packaging.md)
* [Using Native Node Modules](tutorial/using-native-node-modules.md)
* [Debugging Main Process](tutorial/debugging-main-process.md)
* [Using Selenium and WebDriver](tutorial/using-selenium-and-webdriver.md)
* [DevTools Extension](tutorial/devtools-extension.md)
* [Using Pepper Flash Plugin](tutorial/using-pepper-flash-plugin.md)
* [Using Widevine CDM Plugin](tutorial/using-widevine-cdm-plugin.md)
* [Testing on Headless CI Systems (Travis, Jenkins)](tutorial/testing-on-headless-ci.md)
* [Offscreen Rendering](tutorial/offscreen-rendering.md)
* [Keyboard Shortcuts](tutorial/keyboard-shortcuts.md)
* [Updating Applications](tutorial/updates.md)
## Tutorials
* [Quick Start](tutorial/quick-start.md)
* [Desktop Environment Integration](tutorial/desktop-environment-integration.md)
* [Online/Offline Event Detection](tutorial/online-offline-events.md)
* [REPL](tutorial/repl.md)
* [Native Notifications](tutorial/notifications.md)
## API References

View file

@ -1,16 +1,24 @@
# Accessibility
Making accessible applications is important and we're happy to introduce new functionality to [Devtron](https://electronjs.org/devtron) and [Spectron](https://electronjs.org/spectron) that gives developers the opportunity to make their apps better for everyone.
Making accessible applications is important and we're happy to introduce new
functionality to [Devtron][devtron] and [Spectron][spectron] that gives
developers the opportunity to make their apps better for everyone.
---
Accessibility concerns in Electron applications are similar to those of websites because they're both ultimately HTML. With Electron apps, however, you can't use the online resources for accessibility audits because your app doesn't have a URL to point the auditor to.
Accessibility concerns in Electron applications are similar to those of
websites because they're both ultimately HTML. With Electron apps, however,
you can't use the online resources for accessibility audits because your app
doesn't have a URL to point the auditor to.
These new features bring those auditing tools to your Electron app. You can choose to add audits to your tests with Spectron or use them within DevTools with Devtron. Read on for a summary of the tools or checkout our [accessibility documentation](https://electronjs.org/docs/tutorial/accessibility) for more information.
These new features bring those auditing tools to your Electron app. You can
choose to add audits to your tests with Spectron or use them within DevTools
with Devtron. Read on for a summary of the tools.
## Spectron
In the testing framework Spectron, you can now audit each window and `<webview>` tag in your application. For example:
In the testing framework Spectron, you can now audit each window and `<webview>`
tag in your application. For example:
```javascript
app.client.auditAccessibility().then(function (audit) {
@ -20,31 +28,43 @@ app.client.auditAccessibility().then(function (audit) {
})
```
You can read more about this feature in [Spectron's documentation](https://github.com/electron/spectron#accessibility-testing).
You can read more about this feature in [Spectron's documentation][spectron-a11y].
## Devtron
In Devtron, there is a new accessibility tab which will allow you to audit a page in your app, sort and filter the results.
In Devtron, there is a new accessibility tab which will allow you to audit a
page in your app, sort and filter the results.
![devtron screenshot](https://cloud.githubusercontent.com/assets/1305617/17156618/9f9bcd72-533f-11e6-880d-389115f40a2a.png)
![devtron screenshot][devtron-screenshot]
Both of these tools are using the [Accessibility Developer Tools](https://github.com/GoogleChrome/accessibility-developer-tools) library built by Google for Chrome. You can learn more about the accessibility audit rules this library uses on that [repository's wiki](https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules).
Both of these tools are using the [Accessibility Developer Tools][a11y-devtools]
library built by Google for Chrome. You can learn more about the accessibility
audit rules this library uses on that [repository's wiki][a11y-devtools-wiki].
If you know of other great accessibility tools for Electron, add them to the [accessibility documentation](https://electronjs.org/docs/tutorial/accessibility) with a pull request.
If you know of other great accessibility tools for Electron, add them to the
accessibility documentation with a pull request.
## Enabling Accessibility
Electron applications keep accessibility disabled by default for performance reasons but there are multiple ways to enable it.
Electron applications keep accessibility disabled by default for performance
reasons but there are multiple ways to enable it.
### Inside Application
By using [`app.setAccessibilitySupportEnabled(enabled)`](../api/app.md#appsetaccessibilitysupportenabledenabled-macos-windows), you can expose accessibility switch to users in the application preferences. User's system assistive utilities have priority over this setting and will override it.
By using [`app.setAccessibilitySupportEnabled(enabled)`][setAccessibilitySupportEnabled],
you can expose accessibility switch to users in the application preferences.
User's system assistive utilities have priority over this setting and will
override it.
### Assistive Technology
Electron application will enable accessibility automatically when it detects assistive technology (Windows) or VoiceOver (macOS). See Chrome's [accessibility documentation](https://www.chromium.org/developers/design-documents/accessibility#TOC-How-Chrome-detects-the-presence-of-Assistive-Technology) for more details.
Electron application will enable accessibility automatically when it detects
assistive technology (Windows) or VoiceOver (macOS). See Chrome's
[accessibility documentation][a11y-docs] for more details.
On macOS, third-party assistive technology can switch accessibility inside Electron applications by setting the attribute `AXManualAccessibility` programmatically:
On macOS, third-party assistive technology can switch accessibility inside
Electron applications by setting the attribute `AXManualAccessibility`
programmatically:
```objc
CFStringRef kAXManualAccessibility = CFSTR("AXManualAccessibility");
@ -60,3 +80,12 @@ CFStringRef kAXManualAccessibility = CFSTR("AXManualAccessibility");
CFRelease(appRef);
}
```
[devtron]: https://electronjs.org/devtron
[devtron-screenshot]: https://cloud.githubusercontent.com/assets/1305617/17156618/9f9bcd72-533f-11e6-880d-389115f40a2a.png
[spectron]: https://electronjs.org/spectron
[spectron-a11y]: https://github.com/electron/spectron#accessibility-testing
[a11y-docs]: https://www.chromium.org/developers/design-documents/accessibility#TOC-How-Chrome-detects-the-presence-of-Assistive-Technology
[a11y-devtools]: https://github.com/GoogleChrome/accessibility-developer-tools
[a11y-devtools-wiki]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules
[setAccessibilitySupportEnabled]: ../api/app.md#appsetaccessibilitysupportenabledenabled-macos-windows

View file

@ -0,0 +1,142 @@
# Electron Application Architecture
Before we can dive into Electron's APIs, we need to discuss the two process
types available in Electron. They are fundamentally different and important to
understand.
## Main and Renderer Processes
In Electron, the process that runs `package.json`'s `main` script is called
__the main process__. The script that runs in the main process can display a
GUI by creating web pages. An Electron app always has one main process, but
never more.
Since Electron uses Chromium for displaying web pages, Chromium's
multi-process architecture is also used. Each web page in Electron runs in
its own process, which is called __the renderer process__.
In normal browsers, web pages usually run in a sandboxed environment and are not
allowed access to native resources. Electron users, however, have the power to
use Node.js APIs in web pages allowing lower level operating system
interactions.
### Differences Between Main Process and Renderer Process
The main process creates web pages by creating `BrowserWindow` instances. Each
`BrowserWindow` instance runs the web page in its own renderer process. When a
`BrowserWindow` instance is destroyed, the corresponding renderer process
is also terminated.
The main process manages all web pages and their corresponding renderer
processes. Each renderer process is isolated and only cares about the web page
running in it.
In web pages, calling native GUI related APIs is not allowed because managing
native GUI resources in web pages is very dangerous and it is easy to leak
resources. If you want to perform GUI operations in a web page, the renderer
process of the web page must communicate with the main process to request that
the main process perform those operations.
> #### Aside: Communication Between Processes
> In Electron, we have several ways to communicate between the main process
and renderer processes. Like [`ipcRenderer`](../api/ipc-renderer.md) and
[`ipcMain`](../api/ipc-main.md) modules for sending messages, and the
[remote](../api/remote.md) module for RPC style communication. There is also
an FAQ entry on [how to share data between web pages][share-data].
## Using Electron APIs
Electron offers a number of APIs that support the development of a desktop
application in both the main process and the renderer process. In both
processes, you'd access Electron's APIs by requiring its included module:
```javascript
const electron = require('electron')
```
All Electron APIs are assigned a process type. Many of them can only be
used from the main process, some of them only from a renderer process,
some from both. The documentation for the individual API will clearly
state which process they can be used from.
A window in Electron is for instance created using the `BrowserWindow`
class. It is only available in the main process.
```javascript
// This will work in the main process, but be `undefined` in a
// renderer process:
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
```
Since communication between the processes is possible, a renderer process
can call upon the main process to perform tasks. Electron comes with a
module called `remote` that exposes APIs usually only available on the
main process. In order to create a `BrowserWindow` from a renderer process,
we'd use the remote as a middle-man:
```javascript
// This will work in a renderer process, but be `undefined` in the
// main process:
const { remote } = require('electron')
const { BrowserWindow } = remote
const win = new BrowserWindow()
```
## Using Node.js APIs
Electron exposes full access to Node.js both in the main and the renderer
process. This has two important implications:
1) All APIs available in Node.js are available in Electron. Calling the
following code from an Electron app works:
```javascript
const fs = require('fs')
const root = fs.readdirSync('/')
// This will print all files at the root-level of the disk,
// either '/' or 'C:\'.
console.log(root)
```
As you might already be able to guess, this has important security implications
if you ever attempt to load remote content. You can find more information and
guidance on loading remote content in our [security documentation][security].
2) You can use Node.js modules in your application. Pick your favorite npm
module. npm offers currently the world's biggest repository of open-source
code  the ability to use well-maintained and tested code that used to be
reserved for server applications is one of the key features of Electron.
As an example, to use the official AWS SDK in your application, you'd first
install it as a dependency:
```sh
npm install --save aws-sdk
```
Then, in your Electron app, simply require and use the module as if you were
building a Node.js application:
```javascript
// A ready-to-use S3 Client
const S3 = require('aws-sdk/clients/s3')
```
There is one important caveat: Native Node.js modules (that is, modules that
require compilation of native code before they can be used) will need to be
compiled to be used with Electron.
The vast majority of Node.js modules are _not_ native. Only 400 out of the
~650.000 modules are native. However, if you do need native modules, please
consult [this guide on how to recompile them for Electron][native-node] (it's
easy).
[node-docs]: https://nodejs.org/en/docs/
[security]: ./security.md
[native-node]: ./using-native-node-modules.md
[share-data]: ../faq.md#how-to-share-data-between-web-pages

View file

@ -0,0 +1,38 @@
# Application Debugging
Whenever your Electron application is not behaving the way you wanted it to,
an array of debugging tools might help you find coding errors, performance
bottlenecks, or optimization opportunities.
## Renderer Process
The most comprehensive tool to debug individual renderer processes is the
Chromium Developer Toolset. It is available for all renderer processes,
including instances of `BrowserWindow`, `BrowserView`, and `WebView`. You
can open them programmatically by calling the `openDevTools()` API on the
`webContents` of the instance:
```javascript
const { BrowserWindow } = require('electron')
let win = new BrowserWindow()
win.webContents.openDevTools()
```
Google offers [excellent documentation for their developer tools][devtools].
We recommend that you make yourself familiar with them - they are usually one
of the most powerful utilities in any Electron Developer's tool belt.
## Main Process
Debugging the main process is a bit trickier, since you cannot simply open
developer tools for them. The Chromium Developer Tools can [be used
to debug Electron's main process][node-inspect] thanks to a closer collaboration
between Google / Chrome and Node.js, but you might encounter oddities like
`require` not being present in the console.
For more information, see the [Debugging the Main Process documentation][main-debug].
[node-inspect]: https://nodejs.org/en/docs/inspector/
[devtools]: https://developer.chrome.com/devtools
[main-debug]: ./debugging-main-process.md

View file

@ -5,7 +5,12 @@ path names on Windows, slightly speed up `require` and conceal your source code
from cursory inspection, you can choose to package your app into an [asar][asar]
archive with little changes to your source code.
## Generating `asar` Archive
Most users will get this feature for free, since it's supported out of the box
by [`electron-packager`][electron-packager], [`electron-forge`][electron-forge],
and [`electron-builder`][electron-builder]. If you are not using any of these
tools, read on.
## Generating `asar` Archives
An [asar][asar] archive is a simple tar-like format that concatenates files
into a single file. Electron can read arbitrary files from it without unpacking
@ -71,8 +76,9 @@ require('/path/to/example.asar/dir/module.js')
You can also display a web page in an `asar` archive with `BrowserWindow`:
```javascript
const {BrowserWindow} = require('electron')
let win = new BrowserWindow({width: 800, height: 600})
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.loadURL('file:///path/to/example.asar/static/index.html')
```
@ -164,22 +170,26 @@ and `command`s are executed under shell. There is no reliable way to determine
whether a command uses a file in asar archive, and even if we do, we can not be
sure whether we can replace the path in command without side effects.
## Adding Unpacked Files in `asar` Archive
## Adding Unpacked Files to `asar` Archives
As stated above, some Node APIs will unpack the file to filesystem when
calling, apart from the performance issues, it could also lead to false alerts
of virus scanners.
As stated above, some Node APIs will unpack the file to the filesystem when
called. Apart from the performance issues, various anti-virus scanners might
be triggered by this behavior.
To work around this, you can unpack some files creating archives by using the
`--unpack` option, an example of excluding shared libraries of native modules
is:
As a workaround, you can leave various files unpacked using the `--unpack` option.
In the following example, shared libaries of native Node.js modules will not be
packed:
```sh
$ asar pack app app.asar --unpack *.node
```
After running the command, apart from the `app.asar`, there is also an
`app.asar.unpacked` folder generated which contains the unpacked files, you
should copy it together with `app.asar` when shipping it to users.
After running the command, you will notice that a folder named `app.asar.unpacked`
was created together with the `app.asar` file. It contains the unpacked files
and should be shipped together with the `app.asar` archive.
[asar]: https://github.com/electron/asar
[electron-packager]: https://github.com/electron-userland/electron-packager
[electron-forge]: https://github.com/electron-userland/electron-forge
[electron-builder]: https://github.com/electron-userland/electron-builder

View file

@ -0,0 +1,74 @@
# Boilerplates and CLIs
Electron development is un-opinionated - there is no "one true way" to develop,
build, package, or release an Electron application. Additional features for
Electron, both for build- and run-time, can usually be found on
[npm][npm-modules] in individual packages, allowing developers to build both
the app and build pipeline they need.
That level of modularity and extendability ensures that all developers working
with Electron, both big and small in team-size, are never restricted in what
they can or cannot do at any time during their development lifecycle. However,
for many developers, one of the community-driven boilerplates or command line
tools might make it dramatically easier to compile, package, and release an
app.
## Boilerplate vs CLI
A boilerplate is simply a starting point - a canvas, so to speak - from which
you build your application. They usually come in the form of a repository you
can clone and customize to your heart's content.
A command line tool on the other hand continues to support you throughout the
development and release. They are more helpful and supportive but enforce
guidelines on how your code should be structured and built. *Especially for
beginners, using a command line tool is likely to be helpful*.
## electron-forge
A "complete tool for building modern Electron applications". Electron Forge
unifies the existing (and well maintained) build tools for Electron development
into a simple, easy to use package so that anyone can jump right in to Electron
development.
Forge comes with [ready-to-use templates][forge-templates] for popular
frameworks like React, Vue, or Angular. It uses the same core modules used by the
greater Electron community (like [`electron-packager`][electron-packager])  
changes made by Electron maintainers (like Slack) benefit Forge's users, too.
You can find more information and documentation on [electronforge.io][forge].
## electron-builder
A "complete solution to package and build a ready-for-distribution Electron app"
that focuses on an integrated experience. [`electron-builder`][builder] adds one
single dependency focused on simplicity and manages all further requirements
internally.
`electron-builder` replaces features and modules used by the Electron
maintainers (such as the auto-updater) with custom ones. They are generally
tighter integrated but will have less in common with popular Electron apps
like Atom, Visual Studio Code, or Slack.
You can find more information and documentation in [the repository][builder].
## electron-react-boilerplate
If you don't want any tools but simply a solid boilerplate to build from,
CT Lin's [`electron-react-boilerplate`][boilerplate] might be worth
a look. It's quite popular in the community and uses `electron-builder`
internally.
## Other Tools and Boilerplates
The ["Awesome Electron" list][awesome] contains more tools and boilerplates
to choose from. If you find the length of the list intimidating, don't
forget that adding tools as you go along is a valid approach, too.
[npm-modules]: https://www.npmjs.com/search?q=electron
[forge]: https://electronforge.io/
[forge-templates]: https://electronforge.io/templates
[builder]: https://github.com/electron-userland/electron-builder
[electron-packager]: https://github.com/electron-userland/electron-packager
[boilerplate]: https://github.com/chentsulin/electron-react-boilerplate
[awesome]: https://github.com/sindresorhus/awesome-electron#boilerplates

View file

@ -10,344 +10,24 @@ environments with Electron APIs.
## Notifications
See [Notifications](notifications.md)
See the [Notifications documentation](notifications.md).
## Recent documents (Windows & macOS)
## Recent Documents
Windows and macOS provide easy access to a list of recent documents opened by
the application via JumpList or dock menu, respectively.
See [Recent Documents documentation](recent-documents.md).
__JumpList:__
## Progress Bar
![JumpList Recent Files](https://cloud.githubusercontent.com/assets/2289/23446924/11a27b98-fdfc-11e6-8485-cc3b1e86b80a.png)
See the [Progress Bar documentation](progress-bar.md).
__Application dock menu:__
## Unity Launcher
<img src="https://cloud.githubusercontent.com/assets/639601/5069610/2aa80758-6e97-11e4-8cfb-c1a414a10774.png" height="353" width="428" >
See the [Unity Launcher documentation](unity-launcher.md).
To add a file to recent documents, you can use the
[app.addRecentDocument][addrecentdocument] API:
## Represented File for macOS Window
```javascript
const {app} = require('electron')
app.addRecentDocument('/Users/USERNAME/Desktop/work.type')
```
And you can use [app.clearRecentDocuments][clearrecentdocuments] API to empty
the recent documents list:
```javascript
const {app} = require('electron')
app.clearRecentDocuments()
```
### Windows Notes
In order to be able to use this feature on Windows, your application has to be
registered as a handler of the file type of the document, otherwise the file
won't appear in JumpList even after you have added it. You can find everything
on registering your application in [Application Registration][app-registration].
When a user clicks a file from the JumpList, a new instance of your application
will be started with the path of the file added as a command line argument.
### macOS Notes
When a file is requested from the recent documents menu, the `open-file` event
of `app` module will be emitted for it.
## Custom Dock Menu (macOS)
macOS enables developers to specify a custom menu for the dock, which usually
contains some shortcuts for commonly used features of your application:
__Dock menu of Terminal.app:__
<img src="https://cloud.githubusercontent.com/assets/639601/5069962/6032658a-6e9c-11e4-9953-aa84006bdfff.png" height="354" width="341" >
To set your custom dock menu, you can use the `app.dock.setMenu` API, which is
only available on macOS:
```javascript
const {app, Menu} = require('electron')
const dockMenu = Menu.buildFromTemplate([
{label: 'New Window', click () { console.log('New Window') }},
{label: 'New Window with Settings',
submenu: [
{label: 'Basic'},
{label: 'Pro'}
]
},
{label: 'New Command...'}
])
app.dock.setMenu(dockMenu)
```
## User Tasks (Windows)
On Windows you can specify custom actions in the `Tasks` category of JumpList,
as quoted from MSDN:
> Applications define tasks based on both the program's features and the key
> things a user is expected to do with them. Tasks should be context-free, in
> that the application does not need to be running for them to work. They
> should also be the statistically most common actions that a normal user would
> perform in an application, such as compose an email message or open the
> calendar in a mail program, create a new document in a word processor, launch
> an application in a certain mode, or launch one of its subcommands. An
> application should not clutter the menu with advanced features that standard
> users won't need or one-time actions such as registration. Do not use tasks
> for promotional items such as upgrades or special offers.
>
> It is strongly recommended that the task list be static. It should remain the
> same regardless of the state or status of the application. While it is
> possible to vary the list dynamically, you should consider that this could
> confuse the user who does not expect that portion of the destination list to
> change.
__Tasks of Internet Explorer:__
![IE](http://i.msdn.microsoft.com/dynimg/IC420539.png)
Unlike the dock menu in macOS which is a real menu, user tasks in Windows work
like application shortcuts such that when user clicks a task, a program will be
executed with specified arguments.
To set user tasks for your application, you can use
[app.setUserTasks][setusertaskstasks] API:
```javascript
const {app} = require('electron')
app.setUserTasks([
{
program: process.execPath,
arguments: '--new-window',
iconPath: process.execPath,
iconIndex: 0,
title: 'New Window',
description: 'Create a new window'
}
])
```
To clean your tasks list, just call `app.setUserTasks` with an empty array:
```javascript
const {app} = require('electron')
app.setUserTasks([])
```
The user tasks will still show even after your application closes, so the icon
and program path specified for a task should exist until your application is
uninstalled.
## Thumbnail Toolbars
On Windows you can add a thumbnail toolbar with specified buttons in a taskbar
layout of an application window. It provides users a way to access to a
particular window's command without restoring or activating the window.
From MSDN, it's illustrated:
> This toolbar is simply the familiar standard toolbar common control. It has a
> maximum of seven buttons. Each button's ID, image, tooltip, and state are defined
> in a structure, which is then passed to the taskbar. The application can show,
> enable, disable, or hide buttons from the thumbnail toolbar as required by its
> current state.
>
> For example, Windows Media Player might offer standard media transport controls
> such as play, pause, mute, and stop.
__Thumbnail toolbar of Windows Media Player:__
![player](https://i-msdn.sec.s-msft.com/dynimg/IC420540.png)
You can use [BrowserWindow.setThumbarButtons][setthumbarbuttons] to set
thumbnail toolbar in your application:
```javascript
const {BrowserWindow} = require('electron')
const path = require('path')
let win = new BrowserWindow({
width: 800,
height: 600
})
win.setThumbarButtons([
{
tooltip: 'button1',
icon: path.join(__dirname, 'button1.png'),
click () { console.log('button1 clicked') }
},
{
tooltip: 'button2',
icon: path.join(__dirname, 'button2.png'),
flags: ['enabled', 'dismissonclick'],
click () { console.log('button2 clicked.') }
}
])
```
To clean thumbnail toolbar buttons, just call `BrowserWindow.setThumbarButtons`
with an empty array:
```javascript
const {BrowserWindow} = require('electron')
let win = new BrowserWindow()
win.setThumbarButtons([])
```
## Unity Launcher Shortcuts (Linux)
In Unity, you can add custom entries to its launcher via modifying the
`.desktop` file, see [Adding Shortcuts to a Launcher][unity-launcher].
__Launcher shortcuts of Audacious:__
![audacious](https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles?action=AttachFile&do=get&target=shortcuts.png)
## Progress Bar in Taskbar (Windows, macOS, Unity)
On Windows a taskbar button can be used to display a progress bar. This enables
a window to provide progress information to the user without the user having to
switch to the window itself.
On macOS the progress bar will be displayed as a part of the dock icon.
The Unity DE also has a similar feature that allows you to specify the progress
bar in the launcher.
__Progress bar in taskbar button:__
![Taskbar Progress Bar](https://cloud.githubusercontent.com/assets/639601/5081682/16691fda-6f0e-11e4-9676-49b6418f1264.png)
To set the progress bar for a Window, you can use the
[BrowserWindow.setProgressBar][setprogressbar] API:
```javascript
const {BrowserWindow} = require('electron')
let win = new BrowserWindow()
win.setProgressBar(0.5)
```
## Icon Overlays in Taskbar (Windows)
On Windows a taskbar button can use a small overlay to display application
status, as quoted from MSDN:
> Icon overlays serve as a contextual notification of status, and are intended
> to negate the need for a separate notification area status icon to communicate
> that information to the user. For instance, the new mail status in Microsoft
> Outlook, currently shown in the notification area, can now be indicated
> through an overlay on the taskbar button. Again, you must decide during your
> development cycle which method is best for your application. Overlay icons are
> intended to supply important, long-standing status or notifications such as
> network status, messenger status, or new mail. The user should not be
> presented with constantly changing overlays or animations.
__Overlay on taskbar button:__
![Overlay on taskbar button](https://i-msdn.sec.s-msft.com/dynimg/IC420441.png)
To set the overlay icon for a window, you can use the
[BrowserWindow.setOverlayIcon][setoverlayicon] API:
```javascript
const {BrowserWindow} = require('electron')
let win = new BrowserWindow()
win.setOverlayIcon('path/to/overlay.png', 'Description for overlay')
```
## Flash Frame (Windows)
On Windows you can highlight the taskbar button to get the user's attention.
This is similar to bouncing the dock icon on macOS.
From the MSDN reference documentation:
> Typically, a window is flashed to inform the user that the window requires
> attention but that it does not currently have the keyboard focus.
To flash the BrowserWindow taskbar button, you can use the
[BrowserWindow.flashFrame][flashframe] API:
```javascript
const {BrowserWindow} = require('electron')
let win = new BrowserWindow()
win.once('focus', () => win.flashFrame(false))
win.flashFrame(true)
```
Don't forget to call the `flashFrame` method with `false` to turn off the flash. In
the above example, it is called when the window comes into focus, but you might
use a timeout or some other event to disable it.
## Represented File of Window (macOS)
On macOS a window can set its represented file, so the file's icon can show in
the title bar and when users Command-Click or Control-Click on the title a path
popup will show.
You can also set the edited state of a window so that the file icon can indicate
whether the document in this window has been modified.
__Represented file popup menu:__
<img src="https://cloud.githubusercontent.com/assets/639601/5082061/670a949a-6f14-11e4-987a-9aaa04b23c1d.png" height="232" width="663" >
To set the represented file of window, you can use the
[BrowserWindow.setRepresentedFilename][setrepresentedfilename] and
[BrowserWindow.setDocumentEdited][setdocumentedited] APIs:
```javascript
const {BrowserWindow} = require('electron')
let win = new BrowserWindow()
win.setRepresentedFilename('/etc/passwd')
win.setDocumentEdited(true)
```
See the [Represented File documentation](represented-file.md).
## Dragging files out of the window
For certain kinds of apps that manipulate on files, it is important to be able
to drag files from Electron to other apps. To implement this feature in your
app, you need to call `webContents.startDrag(item)` API on `ondragstart` event.
In web page:
```html
<a href="#" id="drag">item</a>
<script type="text/javascript" charset="utf-8">
document.getElementById('drag').ondragstart = (event) => {
event.preventDefault()
ipcRenderer.send('ondragstart', '/path/to/item')
}
</script>
```
In the main process:
```javascript
const {ipcMain} = require('electron')
ipcMain.on('ondragstart', (event, filePath) => {
event.sender.startDrag({
file: filePath,
icon: '/path/to/icon.png'
})
})
```
[addrecentdocument]: ../api/app.md#appaddrecentdocumentpath-macos-windows
[clearrecentdocuments]: ../api/app.md#appclearrecentdocuments-macos-windows
[setusertaskstasks]: ../api/app.md#appsetusertaskstasks-windows
[setprogressbar]: ../api/browser-window.md#winsetprogressbarprogress
[setoverlayicon]: ../api/browser-window.md#winsetoverlayiconoverlay-description-windows
[setrepresentedfilename]: ../api/browser-window.md#winsetrepresentedfilenamefilename-macos
[setdocumentedited]: ../api/browser-window.md#winsetdocumenteditededited-macos
[app-registration]: https://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx
[unity-launcher]: https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles#Adding_shortcuts_to_a_launcher
[setthumbarbuttons]: ../api/browser-window.md#winsetthumbarbuttonsbuttons-windows
[tray-balloon]: ../api/tray.md#traydisplayballoonoptions-windows
[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx
[notification-spec]: https://developer.gnome.org/notification-spec/
[flashframe]: ../api/browser-window.md#winflashframeflag
See the [Native File Drag & Drop documentation](native-file-drag-drop.md).

View file

@ -0,0 +1,117 @@
# Developer Environment
Electron development is essentially Node.js development. To turn your operating
system into an environment capable of building desktop apps with Electron,
you will merely need Node.js, npm, a code editor of your choice, and a
rudimentary understanding of your operating system's command line client.
## Setting up macOS
> Electron supports Mac OS X 10.9 (and all versions named macOS) and up. Apple
does not allow running macOS in virtual machines unless the host computer is
already an Apple computer, so if you find yourself in need of a Mac, consider
using a cloud service that rents access to Macs (like [MacInCloud][macincloud]
or [xcloud](https://xcloud.me)).
First, install a recent version of Node.js. We recommend that you install
either the latest `LTS` or `Current` version available. Visit
[the Node.js download page][node-download] and select the `macOS Installer`.
While Homebrew is an offered option, but we recommend against it - many tools
will be incompatible with the way Homebrew installs Node.js.
Once downloaded, execute the installer and let the installation wizard guide
you through the installation.
Once installed, confirm that everything works as expected. Find the macOS
`Terminal` application in your `/Applications/Utilities` folder (or by
simply search for the word `Terminal` in Spotlight). Open up `Terminal`
or another command line client of your choice and confirm that both `node`
and `npm` are available:
```sh
# This command should print the version of Node.js
node -v
# This command should print the version of npm
npm -v
```
If both commands printed a version number, you are all set! Before you get
started, you might want to install a [code editor](#a-good-editor) suited
for JavaScript development.
## Setting up Windows
> Electron supports Windows 7 and later versions  attempting to develop Electron
applications on earlier versions of Windows will not work. Microsoft provides
free [virtual machine images with Windows 10][windows-vm] for developers.
First, install a recent version of Node.js. We recommend that you install
either the latest `LTS` or `Current` version available. Visit
[the Node.js download page][node-download] and select the `Windows Installer`.
Once downloaded, execute the installer and let the installation wizard guide
you through the installation.
On the screen that allows you to configure the installation, make sure to
select the `Node.js runtime`, `npm package manager`, and `Add to PATH`
options.
Once installed, confirm that everything works as expected. Find the Windows
PowerShell by simply opening the Start Menu and typing `PowerShell`. Open
up `PowerShell` or another command line client of your choice and confirm that
both `node` and `npm` are available:
```powershell
# This command should print the version of Node.js
node -v
# This command should print the version of npm
npm -v
```
If both commands printed a version number, you are all set! Before you get
started, you might want to install a [code editor](#a-good-editor) suited
for JavaScript development.
## Setting up Linux
> Generally speaking, Electron supports Ubuntu 12.04, Fedora 21, Debian 8
and later.
First, install a recent version of Node.js. Depending on your Linux
distribution, the installation steps might differ. Assuming that you normally
install software using a package manager like `apt` or `pacman`, use the
official [Node.js guidance on installing on Linux][node-package].
You're running Linux, so you likely already know how to operate a command line
client. Open up your favorite client and confirm that both `node` and `npm`
are available globally:
```sh
# This command should print the version of Node.js
node -v
# This command should print the version of npm
npm -v
```
If both commands printed a version number, you are all set! Before you get
started, you might want to install a [code editor](#a-good-editor) suited
for JavaScript development.
## A Good Editor
We might suggest two free popular editors built in Electron:
GitHub's [Atom][atom] and Microsoft's [Visual Studio Code][code]. Both of
them have excellent JavaScript support.
If you are one of the many developers with a strong preference, know that
virtually all code editors and IDEs these days support JavaScript.
[macincloud]: https://www.macincloud.com/
[xcloud]: https://xcloud.me
[node-download]: https://nodejs.org/en/download/
[node-package]: https://nodejs.org/en/download/package-manager/
[atom]: https://atom.io/
[code]: https://code.visualstudio.com/
[windows-vm]: https://developer.microsoft.com/en-us/windows/downloads/virtual-machines

235
docs/tutorial/first-app.md Normal file
View file

@ -0,0 +1,235 @@
# Writing Your First Electron App
Electron enables you to create desktop applications with pure JavaScript by
providing a runtime with rich native (operating system) APIs. You could see it
as a variant of the Node.js runtime that is focused on desktop applications
instead of web servers.
This doesn't mean Electron is a JavaScript binding to graphical user interface
(GUI) libraries. Instead, Electron uses web pages as its GUI, so you could also
see it as a minimal Chromium browser, controlled by JavaScript.
**Note**: This example is also available as a repository you can
[download and run immediately](#trying-this-example).
As far as development is concerned, an Electron application is essentially a
Node.js application. The starting point is a `package.json` that is identical
to that of a Node.js module. A most basic Electron app would have the following
folder structure:
```text
your-app/
├── package.json
├── main.js
└── index.html
```
Create a new empty folder for your new Electron application. Open up your
command line client and run `npm init` from that very folder.
```sh
npm init
```
npm will guide you through creating a basic `package.json` file. The script
specified by the `main` field is the startup script of your app, which will
run the main process. An example of your `package.json` might look like this:
```json
{
"name": "your-app",
"version": "0.1.0",
"main": "main.js"
}
```
__Note__: If the `main` field is not present in `package.json`, Electron will
attempt to load an `index.js` (just like Node.js itself). If this was actually
a simple Node application, you would add a `start` script that instructs `node`
to execute the current package:
```json
{
"name": "your-app",
"version": "0.1.0",
"main": "main.js",
"scripts": {
"start": "node ."
}
}
```
Turning this Node application into an Electron application is quite simple - we
merely replace the `node` runtime with the `electron` runtime.
```json
{
"name": "your-app",
"version": "0.1.0",
"main": "main.js",
"scripts": {
"start": "electron ."
}
}
```
## Installing Electron
At this point, you'll need to install `electron` itself. The recommended way
of doing so is to install it as a development dependency in your app, which
allows you to work on multiple apps with different Electron versions. To do so,
run the following command from your app's directory:
```sh
npm install --save-dev electron
```
Other means for installing Electron exist. Please consult the
[installation guide](installation.md) to learn about use with proxies, mirrors,
and custom caches.
## Electron Development in a Nutshell
Electron apps are developed in JavaScript using the same principals and methods
found in Node.js development. All APIs and features found in Electron are
accessible through the `electron` module, which can be required like any other
Node.js module:
```javascript
const electron = require('electron')
```
The `electron` module exposes features in namespaces. As examples, the lifecycle
of the application is managed through `electron.app`, windows can be created
using the `electron.BrowserWindow` class. A simple `main.js` file might just wait
for the application to be ready and open a window:
```javascript
const {app, BrowserWindow} = require('electron')
function createWindow () {
// Create the browser window.
win = new BrowserWindow({width: 800, height: 600})
// and load the index.html of the app.
win.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}))
}
app.on('ready', createWindow)
```
The `main.js` should create windows and handle all the system events your
application might encounter. A more complete version of the above example
might open developer tools, handle the window being closed, or re-create
windows on macOS if the user clicks on the app's icon in the dock.
```javascript
const {app, BrowserWindow} = require('electron')
const path = require('path')
const url = require('url')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win
function createWindow () {
// Create the browser window.
win = new BrowserWindow({width: 800, height: 600})
// and load the index.html of the app.
win.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}))
// Open the DevTools.
win.webContents.openDevTools()
// Emitted when the window is closed.
win.on('closed', () => {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
win = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', () => {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (win === null) {
createWindow()
}
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
```
Finally the `index.html` is the web page you want to show:
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</body>
</html>
```
## Running Your App
Once you've created your initial `main.js`, `index.html`, and `package.json`
files, you can try your app by running `npm start` from your application's
directory.
## Trying this Example
Clone and run the code in this tutorial by using the
[`electron/electron-quick-start`][quick-start] repository.
**Note**: Running this requires [Git](https://git-scm.com).
```sh
# Clone the repository
$ git clone https://github.com/electron/electron-quick-start
# Go into the repository
$ cd electron-quick-start
# Install dependencies
$ npm install
# Run the app
$ npm start
```
For a list of boilerplates and tools to kick-start your development process,
see the [Boilerplates and CLIs documentation][boilerplates].
[share-data]: ../faq.md#how-to-share-data-between-web-pages
[quick-start]: https://github.com/electron/electron-quick-start
[boilerplates]: ./boilerplates-and-clis.md

View file

@ -1,8 +1,6 @@
# Installation
> Tips for installing Electron
To install prebuilt Electron binaries, use [`npm`](https://docs.npmjs.com/).
To install prebuilt Electron binaries, use [`npm`][npm].
The preferred method is to install Electron as a development dependency in your
app:
@ -10,9 +8,8 @@ app:
npm install electron --save-dev
```
See the
[Electron versioning doc](electron-versioning.md)
for info on how to manage Electron versions in your apps.
See the [Electron versioning doc][versioning] for info on how to
manage Electron versions in your apps.
## Global Installation
@ -41,11 +38,12 @@ npm install --platform=win32 electron
## Proxies
If you need to use an HTTP proxy you can [set these environment variables](https://github.com/request/request/tree/f0c4ec061141051988d1216c24936ad2e7d5c45d#controlling-proxy-behaviour-using-environment-variables).
If you need to use an HTTP proxy you can [set these environment variables][proxy-env].
## Custom Mirrors and Caches
During installation, the `electron` module will call out to [`electron-download`](https://github.com/electron-userland/electron-download) to download prebuilt
binaries of Electron for your platform. It will do so by contacting GitHub's
During installation, the `electron` module will call out to
[`electron-download`][electron-download] to download prebuilt binaries of
Electron for your platform. It will do so by contacting GitHub's
release download page (`https://github.com/electron/electron/releases/tag/v$VERSION`,
where `$VERSION` is the exact version of Electron).
@ -111,19 +109,21 @@ network problems. The best resolution is to try switching networks, or
just wait a bit and try installing again.
You can also attempt to download Electron directly from
[electron/electron/releases](https://github.com/electron/electron/releases)
[electron/electron/releases][releases]
if installing via `npm` is failing.
If installation fails with an `EACCESS` error you may need to
[fix your npm permissions](https://docs.npmjs.com/getting-started/fixing-npm-permissions).
[fix your npm permissions][npm-permissions].
If the above error persists, the [unsafe-perm](https://docs.npmjs.com/misc/config#unsafe-perm) flag may need to be set to true:
If the above error persists, the [unsafe-perm][unsafe-perm] flag may need to be
set to true:
```sh
sudo npm install electron --unsafe-perm=true
```
On slower networks, it may be advisable to use the `--verbose` flag in order to show download progress:
On slower networks, it may be advisable to use the `--verbose` flag in order to
show download progress:
```sh
npm install --verbose electron
@ -131,3 +131,11 @@ npm install --verbose electron
If you need to force a re-download of the asset and the SHASUM file set the
`force_no_cache` environment variable to `true`.
[npm]: https://docs.npmjs.com
[versioning]: ./electron-versioning.md
[releases]: https://github.com/electron/electron/releases
[proxy-env]: https://github.com/request/request/tree/f0c4ec061141051988d1216c24936ad2e7d5c45d#controlling-proxy-behaviour-using-environment-variables
[electron-download]: https://github.com/electron-userland/electron-download
[npm-permissions]: https://docs.npmjs.com/getting-started/fixing-npm-permissions
[unsafe-perm]: https://docs.npmjs.com/misc/config#unsafe-perm

View file

@ -0,0 +1,41 @@
# Custom Linux Desktop Launcher Actions
On many Linux environments, you can add custom entries to its launcher
by modifying the `.desktop` file. For Canonical's Unity documentation,
see [Adding Shortcuts to a Launcher][unity-launcher]. For details on a
more generic implementation, see the [freedesktop.org Specification][spec].
__Launcher shortcuts of Audacious:__
![audacious][audacious-launcher]
Generally speaking, shortcuts are added by providing a `Name` and `Exec`
property for each entry in the shortcuts menu. Unity will execute the
`Exec` field once clicked by the user. The format is as follows:
```text
Actions=PlayPause;Next;Previous
[Desktop Action PlayPause]
Name=Play-Pause
Exec=audacious -t
OnlyShowIn=Unity;
[Desktop Action Next]
Name=Next
Exec=audacious -f
OnlyShowIn=Unity;
[Desktop Action Previous]
Name=Previous
Exec=audacious -r
OnlyShowIn=Unity;
```
Unity's preferred way of telling your application what to do is to use
parameters. You can find these in your app in the global variable
`process.argv`.
[unity-launcher]: https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles#Adding_shortcuts_to_a_launcher
[audacious-launcher]: https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles?action=AttachFile&do=get&target=shortcuts.png
[spec]: https://specifications.freedesktop.org/desktop-entry-spec/1.1/ar01s11.html

View file

@ -0,0 +1,41 @@
# MacOS Dock
Electron has APIs to configure the app's icon in the macOS Dock. A macOS-only
API exists to create a [a custom dock menu](#custom-dock-menu-mac-os), but
Electron also uses the app's dock icon to implement cross-platform features
like [recent documents][recent-documents] and
[application progress][progress-bar].
The custom dock is commonly used to add shortcuts to tasks the user wouldn't
want to open the whole app window for.
__Dock menu of Terminal.app:__
![Dock Menu][dock-menu-image]
To set your custom dock menu, you can use the `app.dock.setMenu` API, which is
only available on macOS:
```javascript
const { app, Menu } = require('electron')
const dockMenu = Menu.buildFromTemplate([
{
label: 'New Window',
click () { console.log('New Window') }
}, {
label: 'New Window with Settings',
submenu: [
{ label: 'Basic' },
{ label: 'Pro' }
]
},
{ label: 'New Command...' }
])
app.dock.setMenu(dockMenu)
```
[dock-menu-image]: https://cloud.githubusercontent.com/assets/639601/5069962/6032658a-6e9c-11e4-9953-aa84006bdfff.png
[recent-documents]: ./recent-documents.md
[progress-bar]: ./progress-bar.md

View file

@ -0,0 +1,37 @@
# Native File Drag & Drop
Certain kinds of applications that manipulate files might want to support
the operating system's native file drag & drop feature. Dragging files into
web content is common and supported by many websites. Electron additionally
supports dragging files and content out from web content into the operating
system's world.
To implement this feature in your app, you need to call `webContents.startDrag(item)`
API in response to the `ondragstart` event.
In your renderer process, handle the `ondragstart` event and forward the
information to your main process.
```html
<a href="#" id="drag">item</a>
<script type="text/javascript" charset="utf-8">
document.getElementById('drag').ondragstart = (event) => {
event.preventDefault()
ipcRenderer.send('ondragstart', '/path/to/item')
}
</script>
```
Then, in the main process, augment the event with a path to the file that is
being dragged and an icon.
```javascript
const { ipcMain } = require('electron')
ipcMain.on('ondragstart', (event, filePath) => {
event.sender.startDrag({
file: filePath,
icon: '/path/to/icon.png'
})
})
```

View file

@ -14,7 +14,7 @@ performance loss.
**Note:** An offscreen window is always created as a [Frameless Window](../api/frameless-window.md).
## Two modes of rendering
## Rendering Modes
### GPU accelerated
@ -35,17 +35,19 @@ To enable this mode GPU acceleration has to be disabled by calling the
## Usage
``` javascript
const {app, BrowserWindow} = require('electron')
const { app, BrowserWindow } = require('electron')
app.disableHardwareAcceleration()
let win
app.once('ready', () => {
win = new BrowserWindow({
webPreferences: {
offscreen: true
}
})
win.loadURL('http://github.com')
win.webContents.on('paint', (event, dirty, image) => {
// updateBitmap(dirty, image.getBitmap())

View file

@ -0,0 +1,35 @@
# Progress Bar in Taskbar (Windows, macOS, Unity)
On Windows a taskbar button can be used to display a progress bar. This enables
a window to provide progress information to the user without the user having to
switch to the window itself.
On macOS the progress bar will be displayed as a part of the dock icon.
The Unity DE also has a similar feature that allows you to specify the progress
bar in the launcher.
__Progress bar in taskbar button:__
![Taskbar Progress Bar][taskbar-progress-image]
All three cases are covered by the same API - the `setProgressBar()` method
available on instances of `BrowserWindows`. Call it with a number between `0`
and `1` to indicate your progress. If you have a long-running task that's
currently at 63% towards completion, you'd call it with `setProgressBar(0.63)`.
Generally speaking, setting the parameter to a value below zero (like `-1`)
will remove the progress bar while setting it to a value higher than one
(like `2`) will switch the progress bar to intermediate mode.
See the [API documentation for more options and modes][setprogressbar].
```javascript
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.setProgressBar(0.5)
```
[taskbar-progress-image]: https://cloud.githubusercontent.com/assets/639601/5081682/16691fda-6f0e-11e4-9676-49b6418f1264.png
[setprogressbar]: ../api/browser-window.md#winsetprogressbarprogress

View file

@ -5,246 +5,18 @@ providing a runtime with rich native (operating system) APIs. You could see it
as a variant of the Node.js runtime that is focused on desktop applications
instead of web servers.
This doesn't mean Electron is a JavaScript binding to graphical user interface
(GUI) libraries. Instead, Electron uses web pages as its GUI, so you could also
see it as a minimal Chromium browser, controlled by JavaScript.
The old "Quick Start" document that used to live here has been split up into
two documents:
### Main Process
* To check out how a simple Electron app is built, see
[Writing Your First Electron App][first-app]
* To check out the process architecture, see
[Main and Renderer Processes][processes].
In Electron, the process that runs `package.json`'s `main` script is called
__the main process__. The script that runs in the main process can display a GUI
by creating web pages.
If you just came here to learn about Electron, check out the
[official guides][readme].
### Renderer Process
[first-app]: ./first-app.md
[processes]: ./application-architecture.md#main-and-renderer-processes
[readme]: ../README.md
Since Electron uses Chromium for displaying web pages, Chromium's
multi-process architecture is also used. Each web page in Electron runs in
its own process, which is called __the renderer process__.
In normal browsers, web pages usually run in a sandboxed environment and are not
allowed access to native resources. Electron users, however, have the power to
use Node.js APIs in web pages allowing lower level operating system
interactions.
### Differences Between Main Process and Renderer Process
The main process creates web pages by creating `BrowserWindow` instances. Each
`BrowserWindow` instance runs the web page in its own renderer process. When a
`BrowserWindow` instance is destroyed, the corresponding renderer process
is also terminated.
The main process manages all web pages and their corresponding renderer
processes. Each renderer process is isolated and only cares about the web page
running in it.
In web pages, calling native GUI related APIs is not allowed because managing
native GUI resources in web pages is very dangerous and it is easy to leak
resources. If you want to perform GUI operations in a web page, the renderer
process of the web page must communicate with the main process to request that
the main process perform those operations.
In Electron, we have several ways to communicate between the main process and
renderer processes. Like [`ipcRenderer`](../api/ipc-renderer.md) and
[`ipcMain`](../api/ipc-main.md) modules for sending messages, and the
[remote](../api/remote.md) module for RPC style communication. There is also
an FAQ entry on [how to share data between web pages][share-data].
## Write your First Electron App
Generally, an Electron app is structured like this:
```text
your-app/
├── package.json
├── main.js
└── index.html
```
The format of `package.json` is exactly the same as that of Node's modules, and
the script specified by the `main` field is the startup script of your app,
which will run the main process. An example of your `package.json` might look
like this:
```json
{
"name" : "your-app",
"version" : "0.1.0",
"main" : "main.js"
}
```
__Note__: If the `main` field is not present in `package.json`, Electron will
attempt to load an `index.js`.
The `main.js` should create windows and handle system events, a typical
example being:
```javascript
const {app, BrowserWindow} = require('electron')
const path = require('path')
const url = require('url')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win
function createWindow () {
// Create the browser window.
win = new BrowserWindow({width: 800, height: 600})
// and load the index.html of the app.
win.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}))
// Open the DevTools.
win.webContents.openDevTools()
// Emitted when the window is closed.
win.on('closed', () => {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
win = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', () => {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (win === null) {
createWindow()
}
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
```
Finally the `index.html` is the web page you want to show:
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</body>
</html>
```
## Run your app
Once you've created your initial `main.js`, `index.html`, and `package.json` files,
you'll probably want to try running your app locally to test it and make sure it's
working as expected.
### `electron`
[`electron`](https://github.com/electron-userland/electron-prebuilt) is
an `npm` module that contains pre-compiled versions of Electron.
If you've installed it globally with `npm`, then you will only need to run the
following in your app's source directory:
```sh
electron .
```
If you've installed it locally, then run:
#### macOS / Linux
```sh
$ ./node_modules/.bin/electron .
```
#### Windows
```sh
$ .\node_modules\.bin\electron .
```
#### Node v8.2.0 and later
```sh
$ npx electron .
```
### Manually Downloaded Electron Binary
If you downloaded Electron manually, you can also use the included
binary to execute your app directly.
#### macOS
```sh
$ ./Electron.app/Contents/MacOS/Electron your-app/
```
#### Linux
```sh
$ ./electron/electron your-app/
```
#### Windows
```sh
$ .\electron\electron.exe your-app\
```
`Electron.app` here is part of the Electron's release package, you can download
it from [here](https://github.com/electron/electron/releases).
### Run as a distribution
After you're done writing your app, you can create a distribution by
following the [Application Distribution](./application-distribution.md) guide
and then executing the packaged app.
### Try this Example
Clone and run the code in this tutorial by using the [`electron/electron-quick-start`](https://github.com/electron/electron-quick-start)
repository.
**Note**: Running this requires [Git](https://git-scm.com) and [Node.js](https://nodejs.org/en/download/) (which includes [npm](https://npmjs.org)) on your system.
```sh
# Clone the repository
$ git clone https://github.com/electron/electron-quick-start
# Go into the repository
$ cd electron-quick-start
# Install dependencies
$ npm install
# Run the app
$ npm start
```
For more example apps, see the
[list of boilerplates](https://electronjs.org/community#boilerplates)
created by the awesome electron community.
[share-data]: ../faq.md#how-to-share-data-between-web-pages

View file

@ -0,0 +1,48 @@
# Recent Documents (Windows & macOS)
Windows and macOS provide easy access to a list of recent documents opened by
the application via JumpList or dock menu, respectively.
__JumpList:__
![JumpList Recent Files][jumplist-image]
__Application dock menu:__
![macOS Dock Menu][dock-menu-image]
To add a file to recent documents, you can use the
[app.addRecentDocument][addrecentdocument] API:
```javascript
const { app } = require('electron')
app.addRecentDocument('/Users/USERNAME/Desktop/work.type')
```
And you can use [app.clearRecentDocuments][clearrecentdocuments] API to empty
the recent documents list:
```javascript
const { app } = require('electron')
app.clearRecentDocuments()
```
## Windows Notes
In order to be able to use this feature on Windows, your application has to be
registered as a handler of the file type of the document, otherwise the file
won't appear in JumpList even after you have added it. You can find everything
on registering your application in [Application Registration][app-registration].
When a user clicks a file from the JumpList, a new instance of your application
will be started with the path of the file added as a command line argument.
## macOS Notes
When a file is requested from the recent documents menu, the `open-file` event
of `app` module will be emitted for it.
[jumplist-image]: https://cloud.githubusercontent.com/assets/2289/23446924/11a27b98-fdfc-11e6-8485-cc3b1e86b80a.png
[dock-menu-image]: https://cloud.githubusercontent.com/assets/639601/5069610/2aa80758-6e97-11e4-8cfb-c1a414a10774.png
[addrecentdocument]: ../api/app.md#appaddrecentdocumentpath-macos-windows
[clearrecentdocuments]: ../api/app.md#appclearrecentdocuments-macos-windows

View file

@ -0,0 +1,28 @@
# Represented File for macOS BrowserWindows
On macOS a window can set its represented file, so the file's icon can show in
the title bar and when users Command-Click or Control-Click on the title a path
popup will show.
You can also set the edited state of a window so that the file icon can indicate
whether the document in this window has been modified.
__Represented file popup menu:__
![Represented File][represented-image]
To set the represented file of window, you can use the
[BrowserWindow.setRepresentedFilename][setrepresentedfilename] and
[BrowserWindow.setDocumentEdited][setdocumentedited] APIs:
```javascript
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.setRepresentedFilename('/etc/passwd')
win.setDocumentEdited(true)
```
[represented-image]: https://cloud.githubusercontent.com/assets/639601/5082061/670a949a-6f14-11e4-987a-9aaa04b23c1d.png
[setrepresentedfilename]: ../api/browser-window.md#winsetrepresentedfilenamefilename-macos
[setdocumentedited]: ../api/browser-window.md#winsetdocumenteditededited-macos

View file

@ -489,16 +489,16 @@ const mainWindow = new BrowserWindow()
_Recommendation is Electron's default_
If you are using [`WebViews`](web-view), you might need the pages and scripts
If you are using [`WebViews`][web-view], you might need the pages and scripts
loaded in your `<webview>` tag to open new windows. The `allowpopups` attribute
enables them to create new [`BrowserWindows`](browser-window) using the
enables them to create new [`BrowserWindows`][browser-window] using the
`window.open()` method. `WebViews` are otherwise not allowed to create new
windows.
### Why?
If you do not need popups, you are better off not allowing the creation of
new [`BrowserWindows`](browser-window) by default. This follows the principle
new [`BrowserWindows`][browser-window] by default. This follows the principle
of minimally required access: Don't let a website create new popups unless
you know it needs that feature.
@ -519,7 +519,7 @@ A WebView created in a renderer process that does not have Node.js integration
enabled will not be able to enable integration itself. However, a WebView will
always create an independent renderer process with its own `webPreferences`.
It is a good idea to control the creation of new [`WebViews`](web-view) from
It is a good idea to control the creation of new [`WebViews`][web-view] from
the main process and to verify that their webPreferences do not disable
security features.
@ -531,11 +531,11 @@ website even if Node.js integration is otherwise disabled.
Electron enables developers to disable various security features that control
a renderer process. In most cases, developers do not need to disable any of
those features - and you should therefore not allow different configurations
for newly created [`<WebView>`](web-view) tags.
for newly created [`<WebView>`][web-view] tags.
### How?
Before a [`<WebView>`](web-view) tag is attached, Electron will fire the
Before a [`<WebView>`][web-view] tag is attached, Electron will fire the
`will-attach-webview` event on the hosting `webContents`. Use the event to
prevent the creation of WebViews with possibly insecure options.
@ -562,4 +562,4 @@ is to display a website, a browser will be a more secure option.
[browser-window]: ../api/browser-window.md
[browser-view]: ../api/browser-view.md
[web-view]: ../api/web-view
[web-view]: ../api/web-view.md

View file

@ -5,25 +5,31 @@ officially supported one is taking advantage of the built-in
[Squirrel](https://github.com/Squirrel) framework and
Electron's [autoUpdater](../api/auto-updater.md) module.
## Deploying an update server
## Deploying an Update Server
To get started, you first need to deploy a server that the
[autoUpdater](../api/auto-updater.md) module will download new updates from.
Depending on your needs, you can choose from one of these:
- [Hazel](https://github.com/zeit/hazel) Update server for private or open-source apps. Can be deployed for free on [Now](https://zeit.co/now) (using a single command), pulls from [GitHub Releases](https://help.github.com/articles/creating-releases/) and leverages the power of GitHub's CDN.
- [Nuts](https://github.com/GitbookIO/nuts) Also uses
[GitHub Releases](https://help.github.com/articles/creating-releases/),
but caches app updates on disk and supports private repositories.
- [electron-release-server](https://github.com/ArekSredzki/electron-release-server) Provides a dashboard for handling releases
- [Nucleus](https://github.com/atlassian/nucleus) A complete update server for Electron apps maintained by Atlassian. Supports multiple applications and channels; uses a static file store to minify server cost.
- [Hazel][hazel] Update server for private or open-source apps which can be
deployed for free on [Now][now]. It pulls from [GitHub Releases][gh-releases]
and leverages the power of GitHub's CDN.
- [Nuts][nuts] Also uses [GitHub Releases][gh-releases], but caches app
updates on disk and supports private repositories.
- [electron-release-server][electron-release-server] Provides a dashboard for
handling releases and does not require releases to originate on GitHub.
- [Nucleus][nucleus] A complete update server for Electron apps maintained by
Atlassian. Supports multiple applications and channels; uses a static file store
to minify server cost.
If your app is packaged with [electron-builder][electron-builder-lib] you can use the
If your app is packaged with [`electron-builder`][electron-builder-lib] you can use the
[electron-updater] module, which does not require a server and allows for updates
from S3, GitHub or any other static file host.
from S3, GitHub or any other static file host. This sidesteps Electron's built-in
update mechanism, meaning that the rest of this documentation will not apply to
`electron-builder`'s updater.
## Implementing updates in your app
## Implementing Updates in Your App
Once you've deployed your update server, continue with importing the required
modules in your code. The following code might vary for different server
@ -35,14 +41,14 @@ your packaged app, and not in development. You can use
[electron-is-dev](https://github.com/sindresorhus/electron-is-dev) to check for
the environment.
```js
const {app, autoUpdater, dialog} = require('electron')
```javascript
const { app, autoUpdater, dialog } = require('electron')
```
Next, construct the URL of the update server and tell
[autoUpdater](../api/auto-updater.md) about it:
```js
```javascript
const server = 'https://your-deployment-url.com'
const feed = `${server}/update/${process.platform}/${app.getVersion()}`
@ -51,25 +57,25 @@ autoUpdater.setFeedURL(feed)
As the final step, check for updates. The example below will check every minute:
```js
```javascript
setInterval(() => {
autoUpdater.checkForUpdates()
}, 60000)
```
Once your application is [packaged](../tutorial/application-distribution.md),
it will receive an update for each new
it will receive an update for each new
[GitHub Release](https://help.github.com/articles/creating-releases/) that you
publish.
## Applying updates
## Applying Updates
Now that you've configured the basic update mechanism for your application, you
need to ensure that the user will get notified when there's an update. This
can be achieved using the autoUpdater API
[events](../api/auto-updater.md#events):
```js
```javascript
autoUpdater.on('update-downloaded', (event, releaseNotes, releaseName) => {
const dialogOpts = {
type: 'info',
@ -89,7 +95,7 @@ Also make sure that errors are
[being handled](../api/auto-updater.md#event-error). Here's an example
for logging them to `stderr`:
```js
```javascript
autoUpdater.on('error', message => {
console.error('There was a problem updating the application')
console.error(message)
@ -98,3 +104,9 @@ autoUpdater.on('error', message => {
[electron-builder-lib]: https://github.com/electron-userland/electron-builder
[electron-updater]: https://www.electron.build/auto-update
[now]: https://zeit.co/now
[hazel]: https://github.com/zeit/hazel
[nuts]: https://github.com/GitbookIO/nuts
[gh-releases]: https://help.github.com/articles/creating-releases/
[electron-release-server]: https://github.com/ArekSredzki/electron-release-server
[nucleus]: https://github.com/atlassian/nucleus

View file

@ -151,7 +151,7 @@ You will receive two files: `DesktopAppConverter.zip` and `BaseImage-14316.wim`.
Once installation succeeded, you can move on to compiling your Electron app.
[windows-sdk]: https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk
[app-converter]: https://www.microsoft.com/en-us/download/details.aspx?id=51691
[app-converter]: https://docs.microsoft.com/en-us/windows/uwp/porting/desktop-to-uwp-run-desktop-app-converter
[add-appxpackage]: https://technet.microsoft.com/en-us/library/hh856048.aspx
[electron-packager]: https://github.com/electron-userland/electron-packager
[electron-windows-store]: https://github.com/catalystcode/electron-windows-store

View file

@ -0,0 +1,185 @@
# Windows Taskbar
Electron has APIs to configure the app's icon in the Windows taskbar. Supported
are the [creation of a `JumpList`](#jumplist),
[custom thumbnails and toolbars](#thumbnail-toolbars),
[icon overlays](#icon-overlays-in-taskbar-windows), and the so-called
["Flash Frame" effect](#flash-frame), but
Electron also uses the app's dock icon to implement cross-platform features
like [recent documents][recent-documents] and
[application progress][progress-bar].
## JumpList
Windows allows apps to define a custom context menu that shows up when users
right-click the app's icon in the task bar. That context menu is called
`JumpList`. You specify custom actions in the `Tasks` category of JumpList,
as quoted from MSDN:
> Applications define tasks based on both the program's features and the key
> things a user is expected to do with them. Tasks should be context-free, in
> that the application does not need to be running for them to work. They
> should also be the statistically most common actions that a normal user would
> perform in an application, such as compose an email message or open the
> calendar in a mail program, create a new document in a word processor, launch
> an application in a certain mode, or launch one of its subcommands. An
> application should not clutter the menu with advanced features that standard
> users won't need or one-time actions such as registration. Do not use tasks
> for promotional items such as upgrades or special offers.
>
> It is strongly recommended that the task list be static. It should remain the
> same regardless of the state or status of the application. While it is
> possible to vary the list dynamically, you should consider that this could
> confuse the user who does not expect that portion of the destination list to
> change.
__Tasks of Internet Explorer:__
![IE](http://i.msdn.microsoft.com/dynimg/IC420539.png)
Unlike the dock menu in macOS which is a real menu, user tasks in Windows work
like application shortcuts such that when user clicks a task, a program will be
executed with specified arguments.
To set user tasks for your application, you can use
[app.setUserTasks][setusertaskstasks] API:
```javascript
const { app } = require('electron')
app.setUserTasks([
{
program: process.execPath,
arguments: '--new-window',
iconPath: process.execPath,
iconIndex: 0,
title: 'New Window',
description: 'Create a new window'
}
])
```
To clean your tasks list, just call `app.setUserTasks` with an empty array:
```javascript
const { app } = require('electron')
app.setUserTasks([])
```
The user tasks will still show even after your application closes, so the icon
and program path specified for a task should exist until your application is
uninstalled.
## Thumbnail Toolbars
On Windows you can add a thumbnail toolbar with specified buttons in a taskbar
layout of an application window. It provides users a way to access to a
particular window's command without restoring or activating the window.
From MSDN, it's illustrated:
> This toolbar is simply the familiar standard toolbar common control. It has a
> maximum of seven buttons. Each button's ID, image, tooltip, and state are defined
> in a structure, which is then passed to the taskbar. The application can show,
> enable, disable, or hide buttons from the thumbnail toolbar as required by its
> current state.
>
> For example, Windows Media Player might offer standard media transport controls
> such as play, pause, mute, and stop.
__Thumbnail toolbar of Windows Media Player:__
![player](https://i-msdn.sec.s-msft.com/dynimg/IC420540.png)
You can use [BrowserWindow.setThumbarButtons][setthumbarbuttons] to set
thumbnail toolbar in your application:
```javascript
const { BrowserWindow } = require('electron')
const path = require('path')
const win = new BrowserWindow()
win.setThumbarButtons([
{
tooltip: 'button1',
icon: path.join(__dirname, 'button1.png'),
click () { console.log('button1 clicked') }
}, {
tooltip: 'button2',
icon: path.join(__dirname, 'button2.png'),
flags: ['enabled', 'dismissonclick'],
click () { console.log('button2 clicked.') }
}
])
```
To clean thumbnail toolbar buttons, just call `BrowserWindow.setThumbarButtons`
with an empty array:
```javascript
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.setThumbarButtons([])
```
## Icon Overlays in Taskbar
On Windows a taskbar button can use a small overlay to display application
status, as quoted from MSDN:
> Icon overlays serve as a contextual notification of status, and are intended
> to negate the need for a separate notification area status icon to communicate
> that information to the user. For instance, the new mail status in Microsoft
> Outlook, currently shown in the notification area, can now be indicated
> through an overlay on the taskbar button. Again, you must decide during your
> development cycle which method is best for your application. Overlay icons are
> intended to supply important, long-standing status or notifications such as
> network status, messenger status, or new mail. The user should not be
> presented with constantly changing overlays or animations.
__Overlay on taskbar button:__
![Overlay on taskbar button](https://i-msdn.sec.s-msft.com/dynimg/IC420441.png)
To set the overlay icon for a window, you can use the
[BrowserWindow.setOverlayIcon][setoverlayicon] API:
```javascript
const {BrowserWindow} = require('electron')
let win = new BrowserWindow()
win.setOverlayIcon('path/to/overlay.png', 'Description for overlay')
```
## Flash Frame
On Windows you can highlight the taskbar button to get the user's attention.
This is similar to bouncing the dock icon on macOS.
From the MSDN reference documentation:
> Typically, a window is flashed to inform the user that the window requires
> attention but that it does not currently have the keyboard focus.
To flash the BrowserWindow taskbar button, you can use the
[BrowserWindow.flashFrame][flashframe] API:
```javascript
const {BrowserWindow} = require('electron')
let win = new BrowserWindow()
win.once('focus', () => win.flashFrame(false))
win.flashFrame(true)
```
Don't forget to call the `flashFrame` method with `false` to turn off the flash. In
the above example, it is called when the window comes into focus, but you might
use a timeout or some other event to disable it.
[setthumbarbuttons]: ../api/browser-window.md#winsetthumbarbuttonsbuttons-windows
[setusertaskstasks]: ../api/app.md#appsetusertaskstasks-windows
[setoverlayicon]: ../api/browser-window.md#winsetoverlayiconoverlay-description-windows
[flashframe]: ../api/browser-window.md#winflashframeflag
[recent-documents]: ./recent-documents.md
[progress-bar]: ./progress-bar.md