Embedding arbitrary web content is problematic when it comes to keyboard shortcuts because:
- Web content can steal app shortcuts (see e.g. brave/browser-laptop#4407)
- Blocked web content (e.g. a focused `<webview>` performing expensive computation) will also prevent app shortcuts from firing immediately

To fix this, we need a way to _always_ handle certain shortcuts in the main process. I think the most flexible solution would be something like this:

``` js
app.addProtectedShortcut('CmdOrCtrl+Tab', (event) => {
  event.preventDefault();
});
```

We could then implement:

``` cpp
bool CommonWebContentsDelegate::PreHandleKeyboardEvent(
    content::WebContents* source,
    const content::NativeWebKeyboardEvent& event,
    bool* is_keyboard_shortcut) {
  return /* event is protected shortcut and the handler called preventDefault */;
}
```

@zcbenz Thoughts? I'm happy to work on this if we come up with a reasonable approach.

atom/browser/api/atom_api_web_contents.cc
Emit("will-destroy");
  
  RemoveFromWeakMap();
  
  
  MarkDestroyed();
  Emit("destroyed");
  
  base::MessageLoop::current()->PostTask(FROM_HERE, GetDestroyClosure());
}
void WebContents::NavigationEntryCommitted(
    const content::LoadCommittedDetails& details) {
  Emit("navigation-entry-commited", details.entry->GetURL(),
       details.is_in_page, details.did_replace_entry);
}
int64_t WebContents::GetID() const {
  int64_t process_id = web_contents()->GetRenderProcessHost()->GetID();
  int64_t routing_id = web_contents()->GetRoutingID();
  int64_t rv = (process_id << 32) + routing_id;
  return rv;
}
int WebContents::GetProcessID() const {
  return web_contents()->GetRenderProcessHost()->GetID();
}
WebContents::Type WebContents::GetType() const {
  return type_;
}
bool WebContents::Equal(const WebContents* web_contents) const {