Browse Source

Fix: shortcuts interferes with Chrome/Safari/Firefox

added: mousetrap to handle shortcuts
pull/2574/head
Vulich Fernando 6 years ago
parent
commit
4ad7edc4ea
  1. 145
      app/Application.js
  2. 52
      app/ux/WebView.js
  3. 4
      app/view/main/Main.js
  4. 11
      electron/main.js
  5. 3
      electron/menu.js
  6. 5
      package-lock.json
  7. 1
      package.json
  8. 16
      resources/js/rambox-service-api.js

145
app/Application.js

@ -27,6 +27,7 @@ Ext.define('Rambox.Application', {
,launch: function () { ,launch: function () {
const isOnline = require('is-online'); const isOnline = require('is-online');
const Mousetrap = require('mousetrap');
(async () => { (async () => {
await isOnline().then(res => { await isOnline().then(res => {
var hideNoConnection = ipc.sendSync('getConfig').hideNoConnectionDialog var hideNoConnection = ipc.sendSync('getConfig').hideNoConnectionDialog
@ -121,140 +122,58 @@ Ext.define('Rambox.Application', {
// Check for updates // Check for updates
if ( require('electron').remote.process.argv.indexOf('--without-update') === -1 ) Rambox.app.checkUpdate(true); if ( require('electron').remote.process.argv.indexOf('--without-update') === -1 ) Rambox.app.checkUpdate(true);
// Add shortcuts to switch services using CTRL + Number
document.keyMapping = new Ext.util.KeyMap({
target: document
,binding: [
{
key: "\t"
,ctrl: true
,alt: false
,shift: false
,handler: function(key) {
var tabPanel = Ext.cq1('app-main');
var activeIndex = tabPanel.items.indexOf(tabPanel.getActiveTab());
var i = activeIndex + 1;
// "cycle" (go to the start) when the end is reached or the end is the spacer "tbfill" // Shortcuts
if (i === tabPanel.items.items.length || i === tabPanel.items.items.length - 1 && tabPanel.items.items[i].id === 'tbfill') i = 0; const platform = require('electron').remote.process.platform;
// Prevents default behaviour of Mousetrap, that prevents shortcuts in textareas
// skip spacer Mousetrap.prototype.stopCallback = function(e, element, combo) {
while (tabPanel.items.items[i].id === 'tbfill') i++; return false;
};
tabPanel.setActiveTab(i); // Add shortcuts to switch services using CTRL + Number
} Mousetrap.bind(platform === 'darwin' ? ["command+1","command+2","command+3","command+4","command+5","command+6","command+7","command+8","command+9"] : ["ctrl+1","ctrl+2","ctrl+3","ctrl+4","ctrl+5","ctrl+6","ctrl+7","ctrl+8","ctrl+9"], function(e, combo) { // GROUPS
}
,{
key: "f"
,ctrl: false
,alt: true
,shift: true
,handler: function(key) {
var currentTab = Ext.cq1('app-main').getActiveTab();
if ( currentTab.getWebView ) currentTab.showSearchBox(true);
}
}
,{
key: "\t"
,ctrl: true
,alt: false
,shift: true
,handler: function(key) {
var tabPanel = Ext.cq1('app-main'); var tabPanel = Ext.cq1('app-main');
var activeIndex = tabPanel.items.indexOf(tabPanel.getActiveTab()); var arg = parseInt(e.key);
var i = activeIndex - 1; if ( arg >= tabPanel.items.indexOf(Ext.getCmp('tbfill')) ) arg++;
if ( i < 0 ) i = tabPanel.items.items.length - 1; tabPanel.setActiveTab(arg);
while ( tabPanel.items.items[i].id === 'tbfill' || i < 0 ) i--; });
tabPanel.setActiveTab( i ); // Add shortcut to main tab (ctrl+,)
} Mousetrap.bind(platform === 'darwin' ? 'command+,' : 'ctrl+,', (e, combo) => {
} Ext.cq1('app-main').setActiveTab(0);
,{ });
key: Ext.event.Event.PAGE_DOWN // Add shortcuts to navigate through services
,ctrl: true Mousetrap.bind(['ctrl+tab', 'ctrl+pagedown'], (e, combo) => {
,alt: false
,shift: false
,handler: function(key) {
var tabPanel = Ext.cq1('app-main'); var tabPanel = Ext.cq1('app-main');
var activeIndex = tabPanel.items.indexOf(tabPanel.getActiveTab()); var activeIndex = tabPanel.items.indexOf(tabPanel.getActiveTab());
var i = activeIndex + 1; var i = activeIndex + 1;
// "cycle" (go to the start) when the end is reached or the end is the spacer "tbfill" // "cycle" (go to the start) when the end is reached or the end is the spacer "tbfill"
if (i === tabPanel.items.items.length || i === tabPanel.items.items.length - 1 && tabPanel.items.items[i].id === 'tbfill') i = 0; if (i === tabPanel.items.items.length || i === tabPanel.items.items.length - 1 && tabPanel.items.items[i].id === 'tbfill') i = 0;
// skip spacer // skip spacer
while (tabPanel.items.items[i].id === 'tbfill') i++; while (tabPanel.items.items[i].id === 'tbfill') i++;
tabPanel.setActiveTab(i); tabPanel.setActiveTab(i);
} });
} Mousetrap.bind(['ctrl+shift+tab', 'ctrl+pageup'], (e, combo) => {
,{
key: Ext.event.Event.PAGE_UP
,ctrl: true
,alt: false
,shift: false
,handler: function(key) {
var tabPanel = Ext.cq1('app-main'); var tabPanel = Ext.cq1('app-main');
var activeIndex = tabPanel.items.indexOf(tabPanel.getActiveTab()); var activeIndex = tabPanel.items.indexOf(tabPanel.getActiveTab());
var i = activeIndex - 1; var i = activeIndex - 1;
if ( i < 0 ) i = tabPanel.items.items.length - 1; if ( i < 0 ) i = tabPanel.items.items.length - 1;
while ( tabPanel.items.items[i].id === 'tbfill' || i < 0 ) i--; while ( tabPanel.items.items[i].id === 'tbfill' || i < 0 ) i--;
tabPanel.setActiveTab(i); tabPanel.setActiveTab(i);
} });
} // Add shortcut to search inside a service
,{ Mousetrap.bind(process.platform === 'darwin' ? ['command+alt+f'] : ['shift+alt+f'], (e, combo) => {
key: [Ext.event.Event.NUM_PLUS, Ext.event.Event.NUM_MINUS, 187, 189] var currentTab = Ext.cq1('app-main').getActiveTab();
,ctrl: true if ( currentTab.getWebView ) currentTab.showSearchBox(true);
,alt: false });
,shift: false // Add shortcut to Do Not Disturb
,handler: function(key) { Mousetrap.bind(platform === 'darwin' ? ["command+d"] : ["shift+alt+d"], function(e, combo) {
var tabPanel = Ext.cq1('app-main');
if ( tabPanel.items.indexOf(tabPanel.getActiveTab()) === 0 ) return false;
key === Ext.event.Event.NUM_PLUS || key === 187 ? tabPanel.getActiveTab().zoomIn() : tabPanel.getActiveTab().zoomOut();
}
}
,{
key: [Ext.event.Event.NUM_ZERO, '0']
,ctrl: true
,alt: false
,shift: false
,handler: function(key) {
var tabPanel = Ext.cq1('app-main');
if ( tabPanel.items.indexOf(tabPanel.getActiveTab()) === 0 ) return false;
tabPanel.getActiveTab().resetZoom();
}
}
,{
key: 188 // comma
,ctrl: true
,alt: false
,handler: function(key) {
Ext.cq1('app-main').setActiveTab(0);
}
}
,{
key: 'd'
,ctrl: false
,alt: true
,shift: true
,handler: function(key) {
var btn = Ext.getCmp('disturbBtn'); var btn = Ext.getCmp('disturbBtn');
btn.toggle(); btn.toggle();
Ext.cq1('app-main').getController().dontDisturb(btn, true); Ext.cq1('app-main').getController().dontDisturb(btn, true);
} });
} // Add shortcut to Lock Rambox
,{ Mousetrap.bind(platform === 'darwin' ? ['command+alt+l'] : ['shift+alt+l'], (e, combo) => {
key: 'l'
,ctrl: false
,alt: true
,shift: true
,handler: function(key) {
var btn = Ext.getCmp('lockRamboxBtn'); var btn = Ext.getCmp('lockRamboxBtn');
Ext.cq1('app-main').getController().lockRambox(btn); Ext.cq1('app-main').getController().lockRambox(btn);
}
}
]
}); });
// Mouse Wheel zooming // Mouse Wheel zooming

52
app/ux/WebView.js

@ -504,6 +504,34 @@ Ext.define('Rambox.ux.WebView',{
webview.executeJavaScript(js_inject).then(result => {} ).catch(err => { console.log(err) }) webview.executeJavaScript(js_inject).then(result => {} ).catch(err => { console.log(err) })
}); });
webview.getWebContents().on('before-input-event', (event, input) => {
if (input.type !== 'keyDown') return;
var modifiers = [];
if ( input.shift ) modifiers.push('shift');
if ( input.control ) modifiers.push('control');
if ( input.alt ) modifiers.push('alt');
if ( input.meta ) modifiers.push('meta');
if ( input.isAutoRepeat ) modifiers.push('isAutoRepeat');
if ( input.key === 'Tab' && !(modifiers && modifiers.length) ) return;
// Maps special keys to fire the correct event in Mac OS
if ( require('electron').remote.process.platform === 'darwin' ) {
var keys = [];
keys['ƒ'] = 'f'; // Search
input.key = keys[input.key] ? keys[input.key] : input.key;
}
if ( input.key === 'F11' || input.key === 'F12' || input.key === 'q' || (input.key === 'F1' && modifiers.includes('control'))) return;
require('electron').remote.getCurrentWebContents().sendInputEvent({
type: input.type,
keyCode: input.key,
modifiers: modifiers
});
})
webview.addEventListener('ipc-message', function(event) { webview.addEventListener('ipc-message', function(event) {
var channel = event.channel; var channel = event.channel;
@ -517,30 +545,6 @@ Ext.define('Rambox.ux.WebView',{
case 'rambox.showWindowAndActivateTab': case 'rambox.showWindowAndActivateTab':
showWindowAndActivateTab(event); showWindowAndActivateTab(event);
break; break;
case 'keydown':
handleKeydown(event.args[0])
break;
}
/**
* Handles 'keydown' messages.
* Allow to handle shortcuts.
*/
function handleKeydown(event) {
var emulatedKeyboardEvent = new KeyboardEvent('keydown', {
code: event.code,
key: event.code.substring(0, 5) === 'Digit' ? event.code.substring(5, 6) : event.key,
shiftKey: event.shiftKey,
altKey: event.altKey,
ctrlKey: event.ctrlKey,
metaKey: event.metaKey,
repeat: event.repeat,
keyCode: event.keyCode,
charCode: event.charCode
});
emulatedKeyboardEvent.getKey = function() {
return this.keyCode || this.charCode // fake function, normally used by Ext.js, simply returning keyCode
}
document.keyMapping.handleTargetEvent(emulatedKeyboardEvent) // we directly trigger handleTargetEvent. That's a private method normally. We can't fire the event directly with document.dispatch, unfortunately
} }
/** /**
* Handles 'rambox.clearUnreadCount' messages. * Handles 'rambox.clearUnreadCount' messages.

4
app/view/main/Main.js

@ -243,7 +243,7 @@ Ext.define('Rambox.view.main.Main', {
{ {
glyph: JSON.parse(localStorage.getItem('dontDisturb')) ? 'xf1f7@FontAwesome' : 'xf0f3@FontAwesome' glyph: JSON.parse(localStorage.getItem('dontDisturb')) ? 'xf1f7@FontAwesome' : 'xf0f3@FontAwesome'
,text: locale['app.main[16]']+': '+(JSON.parse(localStorage.getItem('dontDisturb')) ? locale['app.window[20]'] : locale['app.window[21]']) ,text: locale['app.main[16]']+': '+(JSON.parse(localStorage.getItem('dontDisturb')) ? locale['app.window[20]'] : locale['app.window[21]'])
,tooltip: locale['app.main[17]']+'<br/><b>'+locale['app.main[18]']+': Alt + Shift + D</b>' ,tooltip: locale['app.main[17]']+'<br/><b>'+locale['app.main[18]']+(require('electron').remote.process.platform === 'darwin' ? 'Cmd + D</b>' : ': Alt + Shift + D</b>')
,enableToggle: true ,enableToggle: true
,handler: 'dontDisturb' ,handler: 'dontDisturb'
,reference: 'disturbBtn' ,reference: 'disturbBtn'
@ -253,7 +253,7 @@ Ext.define('Rambox.view.main.Main', {
,{ ,{
glyph: 'xf023@FontAwesome' glyph: 'xf023@FontAwesome'
,text: locale['app.main[19]'] ,text: locale['app.main[19]']
,tooltip: locale['app.main[20]']+'<br/><b>'+locale['app.main[18]']+': Alt + Shift + L</b>' ,tooltip: locale['app.main[20]']+'<br/><b>'+locale['app.main[18]']+(require('electron').remote.process.platform === 'darwin' ? 'Cmd + Alt + L</b>' : ': Alt + Shift + L</b>')
,handler: 'lockRambox' ,handler: 'lockRambox'
,id: 'lockRamboxBtn' ,id: 'lockRamboxBtn'
},'-' },'-'

11
electron/main.js

@ -1,6 +1,6 @@
'use strict'; 'use strict';
const {app, protocol, BrowserWindow, dialog, shell, Menu, ipcMain, nativeImage, session, globalShortcut} = require('electron'); const {app, protocol, BrowserWindow, dialog, shell, Menu, ipcMain, nativeImage, session} = require('electron');
// Tray // Tray
const tray = require('./tray'); const tray = require('./tray');
// AutoLaunch // AutoLaunch
@ -479,15 +479,6 @@ if ( config.get('disable_gpu') ) app.disableHardwareAcceleration();
// initialization and is ready to create browser windows. // initialization and is ready to create browser windows.
app.on('ready', function() { app.on('ready', function() {
config.get('master_password') ? createMasterPasswordWindow() : createWindow(); config.get('master_password') ? createMasterPasswordWindow() : createWindow();
globalShortcut.register('CommandOrControl+1', () => { mainWindow.webContents.send('shortcut:tab', 1); })
globalShortcut.register('CommandOrControl+2', () => { mainWindow.webContents.send('shortcut:tab', 2); })
globalShortcut.register('CommandOrControl+3', () => { mainWindow.webContents.send('shortcut:tab', 3); })
globalShortcut.register('CommandOrControl+4', () => { mainWindow.webContents.send('shortcut:tab', 4); })
globalShortcut.register('CommandOrControl+5', () => { mainWindow.webContents.send('shortcut:tab', 5); })
globalShortcut.register('CommandOrControl+6', () => { mainWindow.webContents.send('shortcut:tab', 6); })
globalShortcut.register('CommandOrControl+7', () => { mainWindow.webContents.send('shortcut:tab', 7); })
globalShortcut.register('CommandOrControl+8', () => { mainWindow.webContents.send('shortcut:tab', 8); })
globalShortcut.register('CommandOrControl+9', () => { mainWindow.webContents.send('shortcut:tab', 9); })
}); });
// Quit when all windows are closed. // Quit when all windows are closed.

3
electron/menu.js

@ -178,14 +178,17 @@ module.exports = function(config) {
}, },
{ {
label: 'Zoom In', label: 'Zoom In',
accelerator: 'Ctrl+Plus',
click(item, win) { win.webContents.send('zoomin-webview')} click(item, win) { win.webContents.send('zoomin-webview')}
}, },
{ {
label: 'Zoom Out', label: 'Zoom Out',
accelerator: 'Ctrl+-',
click(item, win) { win.webContents.send('zoomout-webview')} click(item, win) { win.webContents.send('zoomout-webview')}
}, },
{ {
label: 'Reset Zoom', label: 'Reset Zoom',
accelerator: 'Ctrl+0',
click(item, win) { win.webContents.send('resetzoom-webview')} click(item, win) { win.webContents.send('resetzoom-webview')}
} }
] ]

5
package-lock.json generated

@ -4041,6 +4041,11 @@
} }
} }
}, },
"mousetrap": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/mousetrap/-/mousetrap-1.6.3.tgz",
"integrity": "sha512-bd+nzwhhs9ifsUrC2tWaSgm24/oo2c83zaRyZQF06hYA6sANfsXHtnZ19AbbbDXCDzeH5nZBSQ4NvCjgD62tJA=="
},
"ms": { "ms": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",

1
package.json

@ -205,6 +205,7 @@
"electron-updater": "4.1.2", "electron-updater": "4.1.2",
"is-online": "^8.2.0", "is-online": "^8.2.0",
"mime": "^2.3.1", "mime": "^2.3.1",
"mousetrap": "^1.6.3",
"request": "^2.88.0", "request": "^2.88.0",
"request-promise": "^4.2.2", "request-promise": "^4.2.2",
"rimraf": "2.6.1", "rimraf": "2.6.1",

16
resources/js/rambox-service-api.js

@ -55,19 +55,3 @@ window.rambox.contextMenuBuilder = new ContextMenuBuilder();
window.rambox.contextMenuListener = new ContextMenuListener(function(event, info) { window.rambox.contextMenuListener = new ContextMenuListener(function(event, info) {
window.rambox.contextMenuBuilder.showPopupMenu(info); window.rambox.contextMenuBuilder.showPopupMenu(info);
}); });
document.addEventListener("keydown", (event) => {
if (event.type !== 'keydown' || event.key === 'z' || event.key === 'a' ) return; // event used by default
var msg = {
code: event.code,
key: event.key,
shiftKey: event.shiftKey,
altKey: event.altKey,
ctrlKey: event.ctrlKey,
metaKey: event.metaKey,
repeat: event.repeat,
keyCode: event.keyCode,
charCode: event.charCode
};
ipcRenderer.sendToHost('keydown', msg)
});

Loading…
Cancel
Save