Add webContents.setIgnoreMenuShortcuts()

This allows you to disable application menu shortcut handling on a per
web contents basis.
This commit is contained in:
Birunthan Mohanathas 2017-06-25 12:01:05 -07:00
parent 3abeb6e2bc
commit f20f87829b
8 changed files with 60 additions and 18 deletions

View file

@ -581,10 +581,11 @@ bool WebContents::PreHandleKeyboardEvent(
const content::NativeWebKeyboardEvent& event,
bool* is_keyboard_shortcut) {
if (event.type() == blink::WebInputEvent::Type::RawKeyDown ||
event.type() == blink::WebInputEvent::Type::KeyUp)
event.type() == blink::WebInputEvent::Type::KeyUp) {
return Emit("before-input-event", event);
else
} else {
return false;
}
}
void WebContents::EnterFullscreenModeForTab(content::WebContents* source,
@ -1240,6 +1241,10 @@ void WebContents::UnregisterServiceWorker(
callback);
}
void WebContents::SetIgnoreMenuShortcuts(bool ignore) {
set_ignore_menu_shortcuts(ignore);
}
void WebContents::SetAudioMuted(bool muted) {
web_contents()->SetAudioMuted(muted);
}
@ -1763,12 +1768,12 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetMethod("closeDevTools", &WebContents::CloseDevTools)
.SetMethod("isDevToolsOpened", &WebContents::IsDevToolsOpened)
.SetMethod("isDevToolsFocused", &WebContents::IsDevToolsFocused)
.SetMethod("enableDeviceEmulation",
&WebContents::EnableDeviceEmulation)
.SetMethod("disableDeviceEmulation",
&WebContents::DisableDeviceEmulation)
.SetMethod("enableDeviceEmulation", &WebContents::EnableDeviceEmulation)
.SetMethod("disableDeviceEmulation", &WebContents::DisableDeviceEmulation)
.SetMethod("toggleDevTools", &WebContents::ToggleDevTools)
.SetMethod("inspectElement", &WebContents::InspectElement)
.SetMethod("setIgnoreMenuShortcuts",
&WebContents::SetIgnoreMenuShortcuts)
.SetMethod("setAudioMuted", &WebContents::SetAudioMuted)
.SetMethod("isAudioMuted", &WebContents::IsAudioMuted)
.SetMethod("undo", &WebContents::Undo)
@ -1789,8 +1794,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetMethod("tabTraverse", &WebContents::TabTraverse)
.SetMethod("_send", &WebContents::SendIPCMessage)
.SetMethod("sendInputEvent", &WebContents::SendInputEvent)
.SetMethod("beginFrameSubscription",
&WebContents::BeginFrameSubscription)
.SetMethod("beginFrameSubscription", &WebContents::BeginFrameSubscription)
.SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription)
.SetMethod("startDrag", &WebContents::StartDrag)
.SetMethod("setSize", &WebContents::SetSize)

View file

@ -117,6 +117,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
void InspectServiceWorker();
void HasServiceWorker(const base::Callback<void(bool)>&);
void UnregisterServiceWorker(const base::Callback<void(bool)>&);
void SetIgnoreMenuShortcuts(bool ignore);
void SetAudioMuted(bool muted);
bool IsAudioMuted();
void Print(mate::Arguments* args);

View file

@ -149,7 +149,8 @@ bool IsDevToolsFileSystemAdded(
} // namespace
CommonWebContentsDelegate::CommonWebContentsDelegate()
: html_fullscreen_(false),
: ignore_menu_shortcuts_(false),
html_fullscreen_(false),
native_fullscreen_(false),
devtools_file_system_indexer_(new DevToolsFileSystemIndexer) {
}

View file

@ -53,6 +53,10 @@ class CommonWebContentsDelegate
NativeWindow* owner_window() const { return owner_window_.get(); }
void set_ignore_menu_shortcuts(bool ignore) {
ignore_menu_shortcuts_ = ignore;
}
bool is_html_fullscreen() const { return html_fullscreen_; }
protected:
@ -137,6 +141,8 @@ class CommonWebContentsDelegate
// The window that this WebContents belongs to.
base::WeakPtr<NativeWindow> owner_window_;
bool ignore_menu_shortcuts_;
// Whether window is fullscreened by HTML5 api.
bool html_fullscreen_;

View file

@ -27,14 +27,16 @@ void CommonWebContentsDelegate::HandleKeyboardEvent(
if (event.windowsKeyCode == ui::VKEY_ESCAPE && is_html_fullscreen())
ExitFullscreenModeForTab(source);
// Send the event to the menu before sending it to the window
if (event.os_event.type == NSKeyDown &&
[[NSApp mainMenu] performKeyEquivalent:event.os_event])
return;
if (!ignore_menu_shortcuts_) {
// Send the event to the menu before sending it to the window
if (event.os_event.type == NSKeyDown &&
[[NSApp mainMenu] performKeyEquivalent:event.os_event])
return;
if (event.os_event.window &&
[event.os_event.window isKindOfClass:[EventDispatchingWindow class]])
[event.os_event.window redispatchKeyEvent:event.os_event];
if (event.os_event.window &&
[event.os_event.window isKindOfClass:[EventDispatchingWindow class]])
[event.os_event.window redispatchKeyEvent:event.os_event];
}
}
} // namespace atom

View file

@ -23,7 +23,7 @@ void CommonWebContentsDelegate::HandleKeyboardEvent(
ExitFullscreenModeForTab(source);
// Let the NativeWindow handle other parts.
if (owner_window())
if (!ignore_menu_shortcuts_ && owner_window())
owner_window()->HandleKeyboardEvent(source, event);
}

View file

@ -288,7 +288,22 @@ Returns:
Emitted before dispatching the `keydown` and `keyup` events in the page.
Calling `event.preventDefault` will prevent the page `keydown`/`keyup` events
from being dispatched.
and the menu shortcuts.
To only prevent the menu shortcuts, use
[`setIgnoreMenuShortcuts`](#contentssetignoremenushortcuts):
```javascript
const {BrowserWindow} = require('electron')
let win = new BrowserWindow({width: 800, height: 600})
win.webContents.on('before-input-event', (event, input) => {
// For example, only enable application menu keyboard shortcuts when
// Ctrl/Cmd are down.
win.webContents.setIgnoreMenuShortcuts(!input.control && !input.meta)
})
```
#### Event: 'devtools-opened'
@ -730,6 +745,12 @@ contents.executeJavaScript('fetch("https://jsonplaceholder.typicode.com/users/1"
})
```
#### `contents.setIgnoreMenuShortcuts(ignore)`
* `ignore` Boolean
Ignore application menu shortcuts while this web contents is focused.
#### `contents.setAudioMuted(muted)`
* `muted` Boolean

View file

@ -582,6 +582,13 @@ describe('webContents module', function () {
})
})
describe('setIgnoreMenuShortcuts()', function () {
it('does not throw', function () {
assert.equal(w.webContents.setIgnoreMenuShortcuts(true))
assert.equal(w.webContents.setIgnoreMenuShortcuts(false))
})
})
describe('destroy()', () => {
let server