mirror of https://github.com/keeweb/keeweb
fix #348: configurable system-wide shortcuts
parent
3859beb543
commit
56d84e1d18
|
@ -291,6 +291,9 @@ const Launcher = {
|
|||
} else {
|
||||
this.pendingFileToOpen = file;
|
||||
}
|
||||
},
|
||||
setGlobalShortcuts(appSettings) {
|
||||
this.remoteApp().setGlobalShortcuts(appSettings);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ const Alerts = require('./alerts');
|
|||
const Locale = require('../util/locale');
|
||||
const Logger = require('../util/logger');
|
||||
const FeatureDetector = require('../util/feature-detector');
|
||||
const Shortcuts = require('../comp/shortcuts');
|
||||
const Otp = require('../util/otp');
|
||||
const QrCode = require('jsqrcode');
|
||||
|
||||
|
@ -14,7 +15,7 @@ const OtpQrReader = {
|
|||
fileInput: null,
|
||||
|
||||
read() {
|
||||
let screenshotKey = FeatureDetector.screenshotToClipboardShortcut();
|
||||
let screenshotKey = Shortcuts.screenshotToClipboardShortcut();
|
||||
if (screenshotKey) {
|
||||
screenshotKey = Locale.detSetupOtpAlertBodyWith.replace(
|
||||
'{}',
|
||||
|
@ -25,7 +26,7 @@ const OtpQrReader = {
|
|||
? ''
|
||||
: Locale.detSetupOtpAlertBodyWith.replace(
|
||||
'{}',
|
||||
'<code>' + FeatureDetector.actionShortcutSymbol() + 'V</code>'
|
||||
'<code>' + Shortcuts.actionShortcutSymbol() + 'V</code>'
|
||||
);
|
||||
OtpQrReader.startListenClipoard();
|
||||
const buttons = [
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
const FeatureDetector = require('../util/feature-detector');
|
||||
const Keys = require('../const/keys');
|
||||
const Format = require('../util/format');
|
||||
const AppSettingsModel = require('../models/app-settings-model');
|
||||
const Launcher = require('./launcher');
|
||||
|
||||
let allowedKeys;
|
||||
|
||||
function getAllowedKeys() {
|
||||
if (!allowedKeys) {
|
||||
allowedKeys = {};
|
||||
for (const [name, code] of Object.entries(Keys)) {
|
||||
const keyName = name.replace('DOM_VK_', '');
|
||||
if (/^([0-9A-Z]|F\d{1,2})$/.test(keyName)) {
|
||||
allowedKeys[code] = keyName;
|
||||
}
|
||||
}
|
||||
}
|
||||
return allowedKeys;
|
||||
}
|
||||
|
||||
const globalShortcuts = {
|
||||
copyPassword: { mac: 'Ctrl+Alt+C', all: 'Shift+Alt+C' },
|
||||
copyUser: { mac: 'Ctrl+Alt+B', all: 'Shift+Alt+B' },
|
||||
copyUrl: { mac: 'Ctrl+Alt+U', all: 'Shift+Alt+U' },
|
||||
autoType: { mac: 'Ctrl+Alt+T', all: 'Shift+Alt+T' }
|
||||
};
|
||||
|
||||
const Shortcuts = {
|
||||
keyEventToShortcut(event) {
|
||||
const modifiers = [];
|
||||
if (event.ctrlKey) {
|
||||
modifiers.push('Ctrl');
|
||||
}
|
||||
if (event.altKey) {
|
||||
modifiers.push('Alt');
|
||||
}
|
||||
if (event.shiftKey) {
|
||||
modifiers.push('Shift');
|
||||
}
|
||||
if (FeatureDetector.isMac && event.metaKey) {
|
||||
modifiers.push('Meta');
|
||||
}
|
||||
const keyName = getAllowedKeys()[event.which];
|
||||
return {
|
||||
value: modifiers.join('+') + '+' + (keyName || '…'),
|
||||
valid: modifiers.length > 0 && !!keyName
|
||||
};
|
||||
},
|
||||
presentShortcut(shortcutValue, formatting) {
|
||||
return shortcutValue
|
||||
.split(/\+/g)
|
||||
.map(part => {
|
||||
switch (part) {
|
||||
case 'Ctrl':
|
||||
return this.ctrlShortcutSymbol(formatting);
|
||||
case 'Alt':
|
||||
return this.altShortcutSymbol(formatting);
|
||||
case 'Shift':
|
||||
return this.shiftShortcutSymbol(formatting);
|
||||
case 'Meta':
|
||||
return this.actionShortcutSymbol(formatting);
|
||||
default:
|
||||
return part;
|
||||
}
|
||||
})
|
||||
.join('');
|
||||
},
|
||||
actionShortcutSymbol(formatting) {
|
||||
return FeatureDetector.isMac
|
||||
? '⌘'
|
||||
: formatting
|
||||
? '<span class="thin">ctrl + </span>'
|
||||
: 'ctrl+';
|
||||
},
|
||||
altShortcutSymbol(formatting) {
|
||||
return FeatureDetector.isMac
|
||||
? '⌥'
|
||||
: formatting
|
||||
? '<span class="thin">alt + </span>'
|
||||
: 'alt+';
|
||||
},
|
||||
shiftShortcutSymbol(formatting) {
|
||||
return FeatureDetector.isMac
|
||||
? '⇧'
|
||||
: formatting
|
||||
? '<span class="thin">shift + </span>'
|
||||
: 'shift+';
|
||||
},
|
||||
ctrlShortcutSymbol(formatting) {
|
||||
return FeatureDetector.isMac
|
||||
? '⌃'
|
||||
: formatting
|
||||
? '<span class="thin">ctrl + </span>'
|
||||
: 'ctrl+';
|
||||
},
|
||||
globalShortcutText(type, formatting) {
|
||||
return this.presentShortcut(this.globalShortcut(type), formatting);
|
||||
},
|
||||
globalShortcut(type) {
|
||||
const appSettingsShortcut = AppSettingsModel.instance.get(
|
||||
this.globalShortcutAppSettingsKey(type)
|
||||
);
|
||||
if (appSettingsShortcut) {
|
||||
return appSettingsShortcut;
|
||||
}
|
||||
const globalShortcut = globalShortcuts[type];
|
||||
if (globalShortcut) {
|
||||
if (FeatureDetector.isMac && globalShortcut.mac) {
|
||||
return globalShortcut.mac;
|
||||
}
|
||||
return globalShortcut.all;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
setGlobalShortcut(type, value) {
|
||||
if (!globalShortcuts[type]) {
|
||||
throw new Error('Bad shortcut: ' + type);
|
||||
}
|
||||
if (value) {
|
||||
AppSettingsModel.instance.set(this.globalShortcutAppSettingsKey(type), value);
|
||||
} else {
|
||||
AppSettingsModel.instance.unset(this.globalShortcutAppSettingsKey(type));
|
||||
}
|
||||
Launcher.setGlobalShortcuts(AppSettingsModel.instance.attributes);
|
||||
},
|
||||
globalShortcutAppSettingsKey(type) {
|
||||
return 'globalShortcut' + Format.capFirst(type);
|
||||
},
|
||||
screenshotToClipboardShortcut() {
|
||||
if (FeatureDetector.isiOS) {
|
||||
return 'Sleep+Home';
|
||||
}
|
||||
if (FeatureDetector.isMobile) {
|
||||
return '';
|
||||
}
|
||||
if (FeatureDetector.isMac) {
|
||||
return 'Command-Shift-Control-4';
|
||||
}
|
||||
if (FeatureDetector.isWindows) {
|
||||
return 'Alt+PrintScreen';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = Shortcuts;
|
|
@ -513,6 +513,7 @@
|
|||
"setShCopyUrlGlobal": "copy website (when the app is in background)",
|
||||
"setShAutoTypeGlobal": "auto-type (when the app is in background)",
|
||||
"setShLock": "lock database",
|
||||
"setShEdit": "Press a new key combination to set it as shortcut",
|
||||
|
||||
"setPlInstallTitle": "Install new plugins",
|
||||
"setPlInstallDesc": "KeeWeb plugins add features, themes, and languages to KeeWeb. Plugins run with the same privileges as KeeWeb, they can access and manage all your passwords. Never install plugins you don't trust.",
|
||||
|
|
|
@ -17,40 +17,6 @@ const FeatureDetector = {
|
|||
!/^http(s?):\/\/((localhost:8085)|((app|beta)\.keeweb\.info))/.test(location.href),
|
||||
needFixClicks: /Edge\/14/.test(navigator.appVersion),
|
||||
|
||||
actionShortcutSymbol(formatting) {
|
||||
return this.isMac ? '⌘' : formatting ? '<span class="thin">ctrl + </span>' : 'ctrl-';
|
||||
},
|
||||
altShortcutSymbol(formatting) {
|
||||
return this.isMac ? '⌥' : formatting ? '<span class="thin">alt + </span>' : 'alt-';
|
||||
},
|
||||
shiftShortcutSymbol(formatting) {
|
||||
return this.isMac ? '⇧' : formatting ? '<span class="thin">shift + </span>' : 'shift-';
|
||||
},
|
||||
globalShortcutSymbol(formatting) {
|
||||
return this.isMac
|
||||
? '⌃⌥'
|
||||
: formatting
|
||||
? '<span class="thin">shift+alt+</span>'
|
||||
: 'shift-alt-';
|
||||
},
|
||||
globalShortcutIsLarge() {
|
||||
return !this.isMac;
|
||||
},
|
||||
screenshotToClipboardShortcut() {
|
||||
if (this.isiOS) {
|
||||
return 'Sleep+Home';
|
||||
}
|
||||
if (this.isMobile) {
|
||||
return '';
|
||||
}
|
||||
if (this.isMac) {
|
||||
return 'Command-Shift-Control-4';
|
||||
}
|
||||
if (this.isWindows) {
|
||||
return 'Alt+PrintScreen';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
supportsTitleBarStyles() {
|
||||
return this.isMac;
|
||||
},
|
||||
|
|
|
@ -5,7 +5,7 @@ const Locale = require('../../util/locale');
|
|||
const AppSettingsModel = require('../../models/app-settings-model');
|
||||
const EntryPresenter = require('../../presenters/entry-presenter');
|
||||
const Scrollable = require('../../mixins/scrollable');
|
||||
const FeatureDetector = require('../../util/feature-detector');
|
||||
const Shortcuts = require('../../comp/shortcuts');
|
||||
const DropdownView = require('../dropdown-view');
|
||||
const Format = require('../../util/format');
|
||||
|
||||
|
@ -108,9 +108,9 @@ const AutoTypePopupView = Backbone.View.extend({
|
|||
filterText: this.model.filter.text,
|
||||
topMessage,
|
||||
itemsHtml,
|
||||
actionSymbol: FeatureDetector.actionShortcutSymbol(true),
|
||||
altSymbol: FeatureDetector.altShortcutSymbol(true),
|
||||
shiftSymbol: FeatureDetector.shiftShortcutSymbol(true),
|
||||
actionSymbol: Shortcuts.actionShortcutSymbol(true),
|
||||
altSymbol: Shortcuts.altShortcutSymbol(true),
|
||||
shiftSymbol: Shortcuts.shiftShortcutSymbol(true),
|
||||
keyEnter: Locale.keyEnter
|
||||
});
|
||||
document.activeElement.blur();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const Backbone = require('backbone');
|
||||
const FeatureDetector = require('../../util/feature-detector');
|
||||
const Shortcuts = require('../../comp/shortcuts');
|
||||
|
||||
const DetailsAttachmentView = Backbone.View.extend({
|
||||
template: require('templates/details/details-attachment.hbs'),
|
||||
|
@ -9,7 +9,7 @@ const DetailsAttachmentView = Backbone.View.extend({
|
|||
render(complete) {
|
||||
this.renderTemplate({}, true);
|
||||
const shortcut = this.$el.find('.details__attachment-preview-download-text-shortcut');
|
||||
shortcut.html(FeatureDetector.actionShortcutSymbol(false));
|
||||
shortcut.html(Shortcuts.actionShortcutSymbol(false));
|
||||
const blob = new Blob([this.model.getBinary()], { type: this.model.mimeType });
|
||||
const dataEl = this.$el.find('.details__attachment-preview-data');
|
||||
switch ((this.model.mimeType || '').split('/')[0]) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const Backbone = require('backbone');
|
||||
const AutoTypeHintView = require('../auto-type-hint-view');
|
||||
const Locale = require('../../util/locale');
|
||||
const FeatureDetector = require('../../util/feature-detector');
|
||||
const Shortcuts = require('../../comp/shortcuts');
|
||||
const AutoType = require('../../auto-type');
|
||||
|
||||
const DetailsAutoTypeView = Backbone.View.extend({
|
||||
|
@ -22,8 +22,8 @@ const DetailsAutoTypeView = Backbone.View.extend({
|
|||
|
||||
render() {
|
||||
const detAutoTypeShortcutsDesc = Locale.detAutoTypeShortcutsDesc
|
||||
.replace('{}', FeatureDetector.actionShortcutSymbol() + 'T')
|
||||
.replace('{}', FeatureDetector.globalShortcutSymbol() + 'T');
|
||||
.replace('{}', Shortcuts.actionShortcutSymbol() + 'T')
|
||||
.replace('{}', Shortcuts.globalShortcutText('autoType'));
|
||||
this.renderTemplate({
|
||||
enabled: this.model.getEffectiveEnableAutoType(),
|
||||
obfuscation: this.model.autoTypeObfuscation,
|
||||
|
|
|
@ -3,6 +3,7 @@ const Keys = require('../const/keys');
|
|||
const KeyHandler = require('../comp/key-handler');
|
||||
const DropdownView = require('./dropdown-view');
|
||||
const FeatureDetector = require('../util/feature-detector');
|
||||
const Shortcuts = require('../comp/shortcuts');
|
||||
const Format = require('../util/format');
|
||||
const Locale = require('../util/locale');
|
||||
const Comparators = require('../util/comparators');
|
||||
|
@ -139,7 +140,7 @@ const ListSearchView = Backbone.View.extend({
|
|||
: ' <span class="muted-color">(' +
|
||||
Locale.searchShiftClickOr +
|
||||
' ' +
|
||||
FeatureDetector.altShortcutSymbol(true) +
|
||||
Shortcuts.altShortcutSymbol(true) +
|
||||
'N)</span>';
|
||||
this.createOptions = [
|
||||
{ value: 'entry', icon: 'key', text: Format.capFirst(Locale.entry) + entryDesc },
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const Backbone = require('backbone');
|
||||
const OpenConfigView = require('../open-config-view');
|
||||
const FeatureDetector = require('../../util/feature-detector');
|
||||
const Shortcuts = require('../../comp/shortcuts');
|
||||
const PasswordGenerator = require('../../util/password-generator');
|
||||
const Alerts = require('../../comp/alerts');
|
||||
const Launcher = require('../../comp/launcher');
|
||||
|
@ -84,7 +84,7 @@ const SettingsFileView = Backbone.View.extend({
|
|||
storageProviders.sort((x, y) => (x.uipos || Infinity) - (y.uipos || Infinity));
|
||||
const backup = this.model.get('backup');
|
||||
this.renderTemplate({
|
||||
cmd: FeatureDetector.actionShortcutSymbol(true),
|
||||
cmd: Shortcuts.actionShortcutSymbol(true),
|
||||
supportFiles: !!Launcher,
|
||||
desktopLink: Links.Desktop,
|
||||
name: this.model.get('name'),
|
||||
|
|
|
@ -1,18 +1,98 @@
|
|||
const Backbone = require('backbone');
|
||||
const Locale = require('../../util/locale');
|
||||
const Keys = require('../../const/keys');
|
||||
const Launcher = require('../../comp/launcher');
|
||||
const Shortcuts = require('../../comp/shortcuts');
|
||||
const FeatureDetector = require('../../util/feature-detector');
|
||||
|
||||
const SettingsShortcutsView = Backbone.View.extend({
|
||||
template: require('templates/settings/settings-shortcuts.hbs'),
|
||||
|
||||
systemShortcuts: [
|
||||
'Meta+A',
|
||||
'Alt+A',
|
||||
'Alt+C',
|
||||
'Alt+D',
|
||||
'Meta+F',
|
||||
'Meta+C',
|
||||
'Meta+B',
|
||||
'Meta+U',
|
||||
'Meta+T',
|
||||
'Alt+N',
|
||||
'Meta+O',
|
||||
'Meta+S',
|
||||
'Meta+G',
|
||||
'Meta+,',
|
||||
'Meta+L'
|
||||
],
|
||||
|
||||
events: {
|
||||
'click button.shortcut': 'shortcutClick'
|
||||
},
|
||||
|
||||
render() {
|
||||
this.renderTemplate({
|
||||
cmd: FeatureDetector.actionShortcutSymbol(true),
|
||||
alt: FeatureDetector.altShortcutSymbol(true),
|
||||
global: FeatureDetector.globalShortcutSymbol(true),
|
||||
globalIsLarge: FeatureDetector.globalShortcutIsLarge(),
|
||||
globalShortcutsSupported: !!Launcher,
|
||||
autoTypeSupported: !!Launcher
|
||||
cmd: Shortcuts.actionShortcutSymbol(true),
|
||||
alt: Shortcuts.altShortcutSymbol(true),
|
||||
globalIsLarge: !FeatureDetector.isMac,
|
||||
autoTypeSupported: !!Launcher,
|
||||
globalShortcuts: Launcher
|
||||
? {
|
||||
copyPassword: Shortcuts.globalShortcutText('copyPassword', true),
|
||||
copyUser: Shortcuts.globalShortcutText('copyUser', true),
|
||||
copyUrl: Shortcuts.globalShortcutText('copyUrl', true),
|
||||
autoType: Shortcuts.globalShortcutText('autoType', true)
|
||||
}
|
||||
: undefined
|
||||
});
|
||||
},
|
||||
|
||||
shortcutClick(e) {
|
||||
const globalShortcutType = e.target.dataset.shortcut;
|
||||
|
||||
const shortcutEditor = $('<div/>').addClass('shortcut__editor');
|
||||
$('<div/>')
|
||||
.text(Locale.setShEdit)
|
||||
.appendTo(shortcutEditor);
|
||||
const shortcutEditorInput = $('<input/>')
|
||||
.addClass('shortcut__editor-input')
|
||||
.val(Shortcuts.globalShortcutText(globalShortcutType))
|
||||
.appendTo(shortcutEditor);
|
||||
if (!FeatureDetector.isMac) {
|
||||
shortcutEditorInput.addClass('shortcut__editor-input--large');
|
||||
}
|
||||
|
||||
shortcutEditor.insertAfter($(e.target).parent());
|
||||
shortcutEditorInput.focus();
|
||||
shortcutEditorInput.on('blur', () => shortcutEditor.remove());
|
||||
shortcutEditorInput.on('keypress', e => e.preventDefault());
|
||||
shortcutEditorInput.on('keydown', e => {
|
||||
e.preventDefault();
|
||||
e.stopImmediatePropagation();
|
||||
|
||||
if (e.which === Keys.DOM_VK_DELETE || e.which === Keys.DOM_VK_BACK_SPACE) {
|
||||
Shortcuts.setGlobalShortcut(globalShortcutType, undefined);
|
||||
this.render();
|
||||
return;
|
||||
}
|
||||
if (e.which === Keys.DOM_VK_ESCAPE) {
|
||||
shortcutEditorInput.blur();
|
||||
return;
|
||||
}
|
||||
|
||||
const shortcut = Shortcuts.keyEventToShortcut(e);
|
||||
const presentableShortcutText = Shortcuts.presentShortcut(shortcut.value);
|
||||
|
||||
shortcutEditorInput.val(presentableShortcutText);
|
||||
|
||||
const exists = this.systemShortcuts.includes(shortcut.text);
|
||||
shortcutEditorInput.toggleClass('input--error', exists);
|
||||
|
||||
const isValid = shortcut.valid && !exists;
|
||||
if (isValid) {
|
||||
Shortcuts.setGlobalShortcut(globalShortcutType, shortcut.value);
|
||||
this.render();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -26,16 +26,31 @@
|
|||
border: 1px solid var(--muted-color);
|
||||
display: inline-block;
|
||||
border-radius: $base-border-radius;
|
||||
width: 40px;
|
||||
width: 8em;
|
||||
text-align: center;
|
||||
padding: $base-padding;
|
||||
margin: 0 $base-padding-h $base-padding-v $base-padding-h;
|
||||
line-height: 1.5em;
|
||||
min-width: unset;
|
||||
box-sizing: border-box;
|
||||
vertical-align: baseline;
|
||||
&-large {
|
||||
width: 80px;
|
||||
width: 12em;
|
||||
}
|
||||
&:first-of-type {
|
||||
margin-left: 0;
|
||||
}
|
||||
&__editor {
|
||||
margin-bottom: $base-padding-v;
|
||||
&-input {
|
||||
text-align: center;
|
||||
margin: $base-padding-v 0 $medium-padding-v;
|
||||
width: 15em;
|
||||
&--large {
|
||||
width: 30em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__back-button {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<div><span class="shortcut">{{{cmd}}}B</span> {{res 'setShCopyUser'}}</div>
|
||||
<div><span class="shortcut">{{{cmd}}}U</span> {{res 'setShCopyUrl'}}</div>
|
||||
{{#if autoTypeSupported}}
|
||||
<div><span class="shortcut">{{{cmd}}}T</span> {{res 'setShAutoType'}}</div>
|
||||
<div><span class="shortcut">{{{cmd}}}T</span> {{res 'setShAutoType'}}</div>
|
||||
{{/if}}
|
||||
<div><span class="shortcut">↑</span> {{res 'setShPrev'}}</div>
|
||||
<div><span class="shortcut">↓</span> {{res 'setShNext'}}</div>
|
||||
|
@ -19,10 +19,14 @@
|
|||
<div><span class="shortcut">{{{cmd}}}G</span> {{res 'setShGen'}}</div>
|
||||
<div><span class="shortcut">{{{cmd}}},</span> {{res 'setShSet'}}</div>
|
||||
<div><span class="shortcut">{{{cmd}}}L</span> {{res 'setShLock'}}</div>
|
||||
{{#if globalShortcutsSupported}}
|
||||
<div><span class="shortcut {{#if globalIsLarge}}shortcut-large{{/if}}">{{{global}}}C</span> {{res 'setShCopyPassGlobal'}}</div>
|
||||
<div><span class="shortcut {{#if globalIsLarge}}shortcut-large{{/if}}">{{{global}}}B</span> {{res 'setShCopyUserGlobal'}}</div>
|
||||
<div><span class="shortcut {{#if globalIsLarge}}shortcut-large{{/if}}">{{{global}}}U</span> {{res 'setShCopyUrlGlobal'}}</div>
|
||||
<div><span class="shortcut {{#if globalIsLarge}}shortcut-large{{/if}}">{{{global}}}T</span> {{res 'setShAutoTypeGlobal'}}</div>
|
||||
{{#if globalShortcuts}}
|
||||
<div><button class="shortcut btn-silent {{#if globalIsLarge}}shortcut-large{{/if}}"
|
||||
data-shortcut="copyPassword">{{{globalShortcuts.copyPassword}}}</button> {{res 'setShCopyPassGlobal'}}</div>
|
||||
<div><button class="shortcut btn-silent {{#if globalIsLarge}}shortcut-large{{/if}}"
|
||||
data-shortcut="copyUser">{{{globalShortcuts.copyUser}}}</button> {{res 'setShCopyUserGlobal'}}</div>
|
||||
<div><button class="shortcut btn-silent {{#if globalIsLarge}}shortcut-large{{/if}}"
|
||||
data-shortcut="copyUrl">{{{globalShortcuts.copyUrl}}}</button> {{res 'setShCopyUrlGlobal'}}</div>
|
||||
<div><button class="shortcut btn-silent {{#if globalIsLarge}}shortcut-large{{/if}}"
|
||||
data-shortcut="autoType">{{{globalShortcuts.autoType}}}</button> {{res 'setShAutoTypeGlobal'}}</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -65,10 +65,11 @@ app.on('window-all-closed', () => {
|
|||
});
|
||||
app.on('ready', () => {
|
||||
appReady = true;
|
||||
const appSettings = readAppSettings() || {};
|
||||
setAppOptions();
|
||||
setSystemAppearance();
|
||||
createMainWindow();
|
||||
setGlobalShortcuts();
|
||||
createMainWindow(appSettings);
|
||||
setGlobalShortcuts(appSettings);
|
||||
subscribePowerEvents();
|
||||
deleteOldTempFiles();
|
||||
hookRequestHeaders();
|
||||
|
@ -135,6 +136,7 @@ app.getMainWindow = function() {
|
|||
return mainWindow;
|
||||
};
|
||||
app.emitBackboneEvent = emitBackboneEvent;
|
||||
app.setGlobalShortcuts = setGlobalShortcuts;
|
||||
|
||||
function setAppOptions() {
|
||||
app.commandLine.appendSwitch('disable-background-timer-throttling');
|
||||
|
@ -156,8 +158,7 @@ function setSystemAppearance() {
|
|||
}
|
||||
}
|
||||
|
||||
function createMainWindow() {
|
||||
const appSettings = readAppSettings() || {};
|
||||
function createMainWindow(appSettings) {
|
||||
const isMacDarkTheme = appSettings.theme === 'macdark';
|
||||
const windowOptions = {
|
||||
show: false,
|
||||
|
@ -396,23 +397,25 @@ function notifyOpenFile() {
|
|||
}
|
||||
}
|
||||
|
||||
function setGlobalShortcuts() {
|
||||
const shortcutModifiers = process.platform === 'darwin' ? 'Ctrl+Alt+' : 'Shift+Alt+';
|
||||
const shortcuts = {
|
||||
C: 'copy-password',
|
||||
B: 'copy-user',
|
||||
U: 'copy-url',
|
||||
T: 'auto-type'
|
||||
function setGlobalShortcuts(appSettings) {
|
||||
const defaultShortcutModifiers = process.platform === 'darwin' ? 'Ctrl+Alt+' : 'Shift+Alt+';
|
||||
const defaultShortcuts = {
|
||||
CopyPassword: { shortcut: defaultShortcutModifiers + 'C', event: 'copy-password' },
|
||||
CopyUser: { shortcut: defaultShortcutModifiers + 'B', event: 'copy-user' },
|
||||
CopyUrl: { shortcut: defaultShortcutModifiers + 'U', event: 'copy-url' },
|
||||
AutoType: { shortcut: defaultShortcutModifiers + 'T', event: 'auto-type' }
|
||||
};
|
||||
Object.keys(shortcuts).forEach(key => {
|
||||
const shortcut = shortcutModifiers + key;
|
||||
const eventName = shortcuts[key];
|
||||
electron.globalShortcut.unregisterAll();
|
||||
for (const [key, shortcutDef] of Object.entries(defaultShortcuts)) {
|
||||
const fromSettings = appSettings[`globalShortcut${key}`];
|
||||
const shortcut = fromSettings || shortcutDef.shortcut;
|
||||
const eventName = shortcutDef.event;
|
||||
try {
|
||||
electron.globalShortcut.register(shortcut, () => {
|
||||
emitBackboneEvent(eventName);
|
||||
});
|
||||
} catch (e) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function subscribePowerEvents() {
|
||||
|
|
|
@ -6,6 +6,7 @@ Release notes
|
|||
`+` #1243: auto-type any field
|
||||
`+` #1255: file format version and kdf selection in settings
|
||||
`*` #502: increased the default value of encryption rounds
|
||||
`+` #348: configurable system-wide shortcuts
|
||||
`*` devtools are now opened with alt-cmd-I
|
||||
`-` fix #764: multiple attachments display
|
||||
`-` fix multi-line fields display in history
|
||||
|
|
Loading…
Reference in New Issue