javascript - Gjør global snarvei konfigurerbar i Electron-app
Jeg pakket en webapp (en softphone) inn i en Electron-app for å dra nytte av noen automatiseringer jeg kan kode inn i appen med Electron.
Jeg bruker Electrons globalShortcut for å registrere en global hurtigtast for å bringe appen frem og fokusere på søkefeltet i webappen.
Men fordi kollegene mine også begynte å bruke appen, vil jeg gjøre den brukte globale snarveien konfigurerbar.
Siden jeg ikke har mulighet til å endre selve nettappen (den er vert av en tredjepart), har jeg ingen anelse om hvordan jeg skal lage en meny der en bruker kan sette opp snarveien.
Jeg vet at det finnes objektene menu og menuItem, men jeg vet ikke hvordan jeg skal be brukeren om en tast eller tastkombinasjon for å sette opp som globalShortcut ved å bruke dem.
Hvordan gjør jeg det?
Rediger:
For å klargjøre hva jeg forventer: Som jeg allerede har forklart, leter jeg etter en løsning som gjør det mulig å tilby en meny hvor man kan konfigurere en snarvei. Den menyen kan ligge i menylinje/verktøylinje eller kan settes inn i webdokumentet via javascript DOM-manipulering - kanskje bruke et iframe som siste utvei?
Enhver idé om hvordan man kan lagre innstillingen over app-omstarter blir også satt pris på.
Svar #1
Etter å ha sett dette spørsmålet gjorde jeg litt research på emnet ditt. Det første som slo meg var om Electron gir tilgang til å lytte til tastaturhendelser, men ifølge denne tråden stopper Electron-utviklerne Electron fra å være en keylogger. Så jeg har følgende metode for dette problemet. Jeg vet ikke om dette er de beste løsningene for dette scenarioet, men slik ser jeg at det kan gjøres. Dette er i utgangspunktet bygget rundt electron-store, hvor det kan brukes til å lagre brukerens definerte tastatursnarvei. Så appen kan hente den definerte tastatursnarveien fra butikken (hvis det ikke er konfigurert noen snarveier, bruker den standard tastatursnarvei som er angitt i skjemaet) og registrere en globalshortcut ved hjelp av den. Jeg har gitt trinnene for hvordan man implementerer det.
- Installer og konfigurer en standard nøkkelverdi ved hjelp av electron-store. Slik gjør du det
main.js
const Store = require('electron-store');
const schema = {
defaultKeyCombination: {
type: 'string',
default: 'CommandOrControl+Y'
}
}
const store = new Store({schema});
- Ved å importere denne
defaultKeyCombinationkan du registrere en global hurtigtast når appen er klar. (ikke glem å fjerne global hurtigtast når appen blir ødelagt)
app.on('ready', () => {
// Register a defaultKeyCombination shortcut listener.
globalShortcut.register(store.get('defaultKeyCombination'), () => {
// Do stuff when Y and either Command/Control is pressed.
})
})
Opprett og åpne et annet nettleservindu fra et menyklick (menylinje > alternativer > konfigurer) og la brukerne opprette/legge inn en akseleratormodifikator i inndatafeltet ved å bruke de tilgjengelige modifikatorene og tastaturkodene (det er bedre å vise disse i det nye vinduet under inndatafeltet); for eksempel: Brukeren kan legge inn en MODIFIER+KEY_CODE som
CmdOrCtrl+Ai inndatafeltet i nettleseren.Når brukeren trykker på
submit-knappen, send den inntastede tastaturkombinasjonen ved hjelp av IPCRenderer til hovedprosessen og sett butikkensdefaultKeyCombination-verdi til den mottatte verdien.Utøv IPC for å sende svar som sier til brukeren «Vennligst start appen på nytt» og vis det i et varsel eller lignende.
renderer-prosess
let args = "CmdOrCtrl+A"
ipcRenderer.send('set::keycombine',args)
ipcRenderer.on('done::keycombine', (event, arg) => {
// display message to restart the app
})
hovedprosess
ipcMain.on('set::keycombine', (event, arg) => {
console.log(arg) // prints "keycombine"
//setting the new value
store.set('defaultKeyCombination', arg)
// sending reply to renderer work is done
event.reply('done::keycombine')
})
Når appen startes på nytt, vil butikken laste inn den nye konfigurerte tastekombinasjonen og registrere en snarvei-hendelse ved å bruke den.
Dette er hva jeg fikk i tankene mens jeg gjorde denne lille undersøkelsen. Her fant jeg en nøkkelhendelseslytter kalt iohook, men dette er bare tilgjengelig for Electron 2.XX. I den ovennevnte prosessen kan det være feil og flytproblemer, jeg postet bare med litt kode for å få en idé.
Rediger 1:
Dette er mine prøver. På min index.html definerte jeg en knapp for å kalle set()-funksjonen. Du kan integrere et inntastingsfelt slik at du kan skrive inn kommandoene. Når nøkkelen er satt med lagringen, lastes den alltid med denne nye nøkkel-verdien med mindre brukeren endrer den. Du kan lese mer om electron-store her. Håper dette gir deg en idé :)
Main.js
const {app, BrowserWindow, ipcMain } = require('electron')
const Store = require('electron-store');
const schema = {
defaultKeyCombination: {
type: 'string',
default: 'CommandOrControl+Y'
}
}
const store = new Store({schema});
console.log(store.get("defaultKeyCombination"))
function createWindow () {
const window = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
window.loadFile('./index.html')
// window.loadURL("https://www.zap.co.il")
window.webContents.openDevTools()
}
ipcMain.on('set::keycombine', (event, arg) => {
console.log(arg) // prints "keycombine"
//setting the new value
store.set('defaultKeyCombination', arg)
// sending reply to renderer work is done with new key
event.reply('done::keycombine', store.get('defaultKeyCombination'))
})
app.wheReady().then(createWindow)
//app.on('ready', createWindow)
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()
}
})
Renderer.js
const { ipcRenderer } = require('electron')
function set() {
console.log("clicked")
let args = "CmdOrCtrl+A"
ipcRenderer.send('set::keycombine',args)
}
ipcRenderer.on('done::keycombine', (event, arg) => {
console.log("DONEEEEEEEEEE", arg)
})
Svar #2
La oss si hotkeySettings.html
<!DOCTYPE html>
<html lang="en">
<head> </head>
<body>
<input id="hotkey" onkeyup="keyUp(event)" />
<button id="save" onclick="saveHotkey()">save</button>
<script>
const storage = require("electron-json-storage");
async function loadHotkey() {
storage.get("hotkey", function (error, key) {
document.getElementById("hotkey").value = key;
});
}
async function saveHotkey() {
const { globalShortcut } = require("electron").remote;
const hotkey = document.getElementById("hotkey").value;
await storage.set("hotkey", hotkey);
globalShortcut.register(hotkey, () => {
console.log(hotkey, "key pressed");
});
}
function keyUp(event) {
const keyCode = event.keyCode;
const key = event.key;
const charCode = event.code;
if ((keyCode >= 16 && keyCode <= 18) || keyCode === 91) return;
const value = [];
event.ctrlKey ? value.push("Control") : null;
event.shiftKey ? value.push("Shift") : null;
event.isAlt ? value.push("Alt") : null;
value.push(key.toUpperCase());
document.getElementById("hotkey").value = value.join("+");
}
loadHotkey();
</script>
</body>
</html>
loadHotkey-funksjon: vil laste inn den tidligere registrerte hurtigtasten. Hurtigtasten er i appData.
saveHotKey-funksjon: vil registrere en ny hurtigtast basert på din input og lagre denne verdien til appData slik at den blir vedvarende.
På main.js
...
// Open this browserWindow when you click menuItem to see the registered hotkey
// And to update the hotkey
const hotkeySettingsWindow = new BrowserWindow({
height: 600,
width: 600,
webPreferences: {
nodeIntegration: true
}
})
hotkeySettingsWindow.loadFile('hotkeySettings.html')
