Electron - alandrade21/docsCompartilhados GitHub Wiki
Documento com registros úteis para desenvolvimento na plataforma electron.
- Pós Instalação
- Electron com Angular
- Comandos para Compilar e Rodar
- Problemas
- Package.json
- Processos
- BrowserWindow
- IPC
- Unsafe Content
- Dialogs
- Menu
- Dicas de Estilização
- Shell
A partir do electron 5, após rodar o npm install
, vai em node_modules/electron/dist
e localiza o arquivo chrome-sandbox
. Roda os seguintes comandos:
sudo chown root:root chrome-sandbox
sudo chmod 4755 chrome-sandbox
Sem isso o electron não roda. Se rodar sem isso, vai dar o seguinte erro:
[18371:0715/222931.349917:FATAL:setuid_sandbox_host.cc(157)] The SUID sandbox helper binary was found, but is not configured correctly. Rather than run without sandboxing I'm aborting now. You need to make sure that /home/andre/Desenv/templates/angular-electron-sqlite-alandrade21/node_modules/electron/dist/chrome-sandbox is owned by root and has mode 4755.
No index html coloca ./
como base href, ao invés de /
.
Instala o electron no projeto
npm install electron --save-dev
Cria o arquivo main.js
na raiz do projeto. Qdo for carregar o index.html
usa:
const mainWindow = new BrowserWindow({});
mainWindow.loadURL(`file://${__dirname}/dist/<nome do projeto>/index.html`);
Para mais detalhes, veja o meu projeto angular-electron-boilerplate.
No arquivo package.json
:
-
Cria uma entrada
"main": "main.js"
logo abaixo de"version"
. -
Na seção de scripts cria dois scripts:
"electron": "electron ."
"electron-build": "ng build && electron ."
Para mais detalhes, veja o meu projeto angular-electron-boilerplate.
Com Angular 6, referenciando o electron dentro do angular, acontece um problema que não é possível referenciar as bibliotecas nativas do node. A solução:
- Em
index.html
, coloque o seguinte código:
<script>
var electron = require('electron');
</script>
Package,json tem 3 elementos obrigatórios: name (sem espaços), version e main (caminho para main.js
relativo ao package.json).
O processo principal (Main Process) é o que carrega o electron e dispara a janela principal.
O processo de renderer (Renderer Process) é criado para cada janela aberta (browser window), e é responsável por rodar o app web embarcado no electron.
Propriedades para criação:
{ width: ,
height: ,
minWidth: ,
minHeight: ,
maxWidth: ,
maxHeight: , // --> (todos acima aceitam números ou porcentagens)
resizeable: ,
movable: ,
minimizable: ,
closable: ,
focusable: ,
fullscreenable: , // --> (todos booleanos, alguns não são implementados em linux)
icon: path.join(_dirname, 'myapp.png'),
title: 'My Title',
fullscreen: false,
frame: true, // --> (frame false apaga a moldura da janela, com os botões de controle)
backgroundColor: '#eeeeee'}
Eventos win.on(' ', () => {})
: closed
, maximize
, minimize
, resize
, move
, show
, hide
.
win.on('ready-to-show', () => {
win.show();
}); // --> Esse código é comum para evitar o flicker de janelas que demoram demais pra carregar.
Métodos win. ()
: show
, hide
, focus
, close
.
No Renderer Process
electron.ipcRenderer.send('print-hello', 'John Doe');
No Main Process
electron.ipcMain.on('print-hello', (event, argument) => {
console.log(`hello, $argument}!`);
});
No Main Process
win.webContents.send('print-hello', 'John Doe');
No Renderer Process
electron.ipcRenderer.on('print-hello', (event, argument) => {
console.log(`hello, $argument}!`);
});
Toda vez que tiver que carregar uma página externa num app electron, considere essa página externa um unsafe content.
No objeto de criação da janela onde será aberto o unsafe content, adicione o seguinte:
new electron.BrowserWindow({
webPreferences: {
nodeIntegration: false, // (Essa opção não permite ao código carregado na janela acessar o node, ou seja, a browser window vai funcionar como um browser normal.)
javascript: false // (Essa opção desliga o suporte ao js na nova janela. Essa opção pode ser deixada ligada.)
}
});
4 tipos: Open file
, Save file
, Message
, Error
.
No Main:
electron.dialog.showErrorBox('oops!', 'Somethig Happened!');
No Renderer
electron.remote.dialog.showErrorBox('oops!', 'Somethig Happened!');
electron.remote.getCurrentWindow();
electron.remote.BrowserWindow.getAllWindows();
electron.remote.BrowserWindow.getFocusedWindow();
const currentWindow = electron.remote.getCurrentWindow();
electron.remote.dialog.showMessageBox( currentWindow, {
type: 'warning', // or none, info, error, question
title: '',
message: '',
detail: '',
icon: path.join(__dirname, 'danger.png'),
buttons: ['OK', 'Cancel'],
defaultId: 0, // Id do default button
cancelId: 1, // Id do cancel button
checkboxLabel: 'Don\'t warn me about this again',
checkboxChecked: false
}, (response, checkboxChecked) => {
if (response === 0) console.log('User clicked OK');
if (checkboxChecked) console.log('Checkbox checked');
});
const currentWindow = electron.remote.getCurrentWindow();
electron.remote.dialog.showOpenDialog(currentWindow, {
title: '',
buttonLabel: 'Load File',
filters: [
{name: "Pictures", extensions: ["png", "jpg", "gif"]},
{name: "All Files", extensions: ["*"]}
],
properties: ['openFile', 'openDirectory', 'multiSelections']
}, (selectedFiles) => {
selectedFiles.forEach((selectedFile) => {
console.log(selectedFile);
});
});
const currentWindow = electron.remote.getCurrentWindow();
electron.remote.dialog.showSaveDialog(currentWindow, {
title: '',
buttonLabel: 'OK',
filters: [
{name: "Pictures", extensions: ["png", "jpg", "gif"]}
]
}, (filePath) => {
console.log(filePath);
});
Tipos de itens de menu: normal
, separator
, submenu
, checkbox
, radio
.
{
type: 'normal',
label: '',
accelerator: 'CommandOrControl+Shift+A',
enabled: true,
visible: true,
click: () => {}
}
{ type: 'separator' }
{
label: '',
type: 'submenu',
submenu: [
{ type: 'normal', label: ''}
{ type: 'checkbox', label: '', checked: true}
...
]
}
{
type: 'checkbox',
label: '',
enabled: true,
visible: true,
checked: true,
click: (item) => {
if(item.checked) {
} else {
}
}
}
[
{type: 'radio', label: ''},
{type: 'radio', label: '', checked: true},
...
]
Mods: Command
, Control
, CommandOrControl
, Alt
, Option
, AltGr
, Shift
, Super
.
Keys: Space
, Tab
, Backspace
, Delete
, Insert
, Enter
, Up
, Down
, Left
, Right
, Escape
.
const myMenu = electron.Menu.buildFromTemplate([{...}, {...}, ...]);
electron.Menu.setApplicationMenu(myMenu);
Faz isso só depois de app ready.
const myMenu = electron.Menu.buildFromTemplate([{...}, {...}, ...]);
window.addEventListener('contextmenu', () => {
myMenu.popup(electron.remote.getCurrentWindow());
});
-
Button Outlines: Tira com css
button:focus { outline: none !important; }
-
User selections: Tira com css no elemento que não quer deixar selecionar
user-select: none;
Por exemplo, numa sidebar:
#sidebar { ... user-select: none; }
-
Browser zoom: Limita no
index.html
, cria uma seção de script e coloca:<script> const electron = require('electron'); electron.webFrame.setZoomLevelLimits(1, 1); </script>
const result = electron.shell.openExternal('');
Retorna um booleano. Recebe um endereço web, um arquivo via file://
, ou um e-mail mailto:
.
const result = electron.shell.openFile('');
Recebe o path para o arquivo. Não precisa colocar file://
.
const result = electron.shell.showItemInFolder('');
Recebe o path para o arquivo.
const result = electron.shell.moveItemToTrash('');
Recebe o path para o arquivo.