Browse Source

Add webContents.setIgnoreMenuShortcuts()

This allows you to disable application menu shortcut handling on a per
web contents basis.
Birunthan Mohanathas 7 years ago
parent
commit
f20f87829b

+ 12 - 8
atom/browser/api/atom_api_web_contents.cc

@@ -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)

+ 1 - 0
atom/browser/api/atom_api_web_contents.h

@@ -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);

+ 2 - 1
atom/browser/common_web_contents_delegate.cc

@@ -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) {
 }

+ 6 - 0
atom/browser/common_web_contents_delegate.h

@@ -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_;
 

+ 10 - 8
atom/browser/common_web_contents_delegate_mac.mm

@@ -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 (event.os_event.window &&
-      [event.os_event.window isKindOfClass:[EventDispatchingWindow class]])
-    [event.os_event.window redispatchKeyEvent:event.os_event];
+  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];
+  }
 }
 
 }  // namespace atom

+ 1 - 1
atom/browser/common_web_contents_delegate_views.cc

@@ -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);
 }
 

+ 22 - 1
docs/api/web-contents.md

@@ -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

+ 7 - 0
spec/api-web-contents-spec.js

@@ -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