feat: add registerAccelerator flag to allow menu items to optionally skip accelerator registration (backport: 3-1-x) (#15892)

* feat: add registerAccelerator flag to allow menu items to skip registration

* docs: add docs for registerAccelerator
This commit is contained in:
Heilig Benedek 2019-01-29 23:58:45 +01:00 committed by Shelley Vohr
parent bb28fa8e8e
commit 6d5b225ac5
9 changed files with 43 additions and 7 deletions

View file

@ -41,6 +41,8 @@ void Menu::AfterInit(v8::Isolate* isolate) {
delegate.Get("isCommandIdEnabled", &is_enabled_); delegate.Get("isCommandIdEnabled", &is_enabled_);
delegate.Get("isCommandIdVisible", &is_visible_); delegate.Get("isCommandIdVisible", &is_visible_);
delegate.Get("getAcceleratorForCommandId", &get_accelerator_); delegate.Get("getAcceleratorForCommandId", &get_accelerator_);
delegate.Get("shouldRegisterAcceleratorForCommandId",
&should_register_accelerator_);
delegate.Get("executeCommand", &execute_command_); delegate.Get("executeCommand", &execute_command_);
delegate.Get("menuWillShow", &menu_will_show_); delegate.Get("menuWillShow", &menu_will_show_);
} }
@ -74,6 +76,12 @@ bool Menu::GetAcceleratorForCommandIdWithParams(
return mate::ConvertFromV8(isolate(), val, accelerator); return mate::ConvertFromV8(isolate(), val, accelerator);
} }
bool Menu::ShouldRegisterAcceleratorForCommandId(int command_id) const {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
return should_register_accelerator_.Run(GetWrapper(), command_id);
}
void Menu::ExecuteCommand(int command_id, int flags) { void Menu::ExecuteCommand(int command_id, int flags) {
v8::Locker locker(isolate()); v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate()); v8::HandleScope handle_scope(isolate());

View file

@ -51,6 +51,7 @@ class Menu : public mate::TrackableObject<Menu>,
int command_id, int command_id,
bool use_default_accelerator, bool use_default_accelerator,
ui::Accelerator* accelerator) const override; ui::Accelerator* accelerator) const override;
bool ShouldRegisterAcceleratorForCommandId(int command_id) const override;
void ExecuteCommand(int command_id, int event_flags) override; void ExecuteCommand(int command_id, int event_flags) override;
void MenuWillShow(ui::SimpleMenuModel* source) override; void MenuWillShow(ui::SimpleMenuModel* source) override;
@ -101,6 +102,7 @@ class Menu : public mate::TrackableObject<Menu>,
base::Callback<bool(v8::Local<v8::Value>, int)> is_visible_; base::Callback<bool(v8::Local<v8::Value>, int)> is_visible_;
base::Callback<v8::Local<v8::Value>(v8::Local<v8::Value>, int, bool)> base::Callback<v8::Local<v8::Value>(v8::Local<v8::Value>, int, bool)>
get_accelerator_; get_accelerator_;
base::Callback<bool(v8::Local<v8::Value>, int)> should_register_accelerator_;
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>, int)> base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>, int)>
execute_command_; execute_command_;
base::Callback<void(v8::Local<v8::Value>)> menu_will_show_; base::Callback<void(v8::Local<v8::Value>)> menu_will_show_;

View file

@ -78,6 +78,7 @@ void GenerateAcceleratorTable(AcceleratorTable* table,
GenerateAcceleratorTable(table, submodel); GenerateAcceleratorTable(table, submodel);
} else { } else {
ui::Accelerator accelerator; ui::Accelerator accelerator;
if (model->ShouldRegisterAcceleratorAt(i)) {
if (model->GetAcceleratorAtWithParams(i, true, &accelerator)) { if (model->GetAcceleratorAtWithParams(i, true, &accelerator)) {
MenuItem item = {i, model}; MenuItem item = {i, model};
(*table)[accelerator] = item; (*table)[accelerator] = item;
@ -85,6 +86,7 @@ void GenerateAcceleratorTable(AcceleratorTable* table,
} }
} }
} }
}
bool TriggerAcceleratorTableCommand(AcceleratorTable* table, bool TriggerAcceleratorTableCommand(AcceleratorTable* table,
const ui::Accelerator& accelerator) { const ui::Accelerator& accelerator) {

View file

@ -43,6 +43,14 @@ bool AtomMenuModel::GetAcceleratorAtWithParams(
return false; return false;
} }
bool AtomMenuModel::ShouldRegisterAcceleratorAt(int index) const {
if (delegate_) {
return delegate_->ShouldRegisterAcceleratorForCommandId(
GetCommandIdAt(index));
}
return true;
}
void AtomMenuModel::MenuWillClose() { void AtomMenuModel::MenuWillClose() {
ui::SimpleMenuModel::MenuWillClose(); ui::SimpleMenuModel::MenuWillClose();
for (Observer& observer : observers_) { for (Observer& observer : observers_) {

View file

@ -23,6 +23,9 @@ class AtomMenuModel : public ui::SimpleMenuModel {
bool use_default_accelerator, bool use_default_accelerator,
ui::Accelerator* accelerator) const = 0; ui::Accelerator* accelerator) const = 0;
virtual bool ShouldRegisterAcceleratorForCommandId(
int command_id) const = 0;
private: private:
// ui::SimpleMenuModel::Delegate: // ui::SimpleMenuModel::Delegate:
bool GetAcceleratorForCommandId( bool GetAcceleratorForCommandId(
@ -52,6 +55,7 @@ class AtomMenuModel : public ui::SimpleMenuModel {
bool GetAcceleratorAtWithParams(int index, bool GetAcceleratorAtWithParams(int index,
bool use_default_accelerator, bool use_default_accelerator,
ui::Accelerator* accelerator) const; ui::Accelerator* accelerator) const;
bool ShouldRegisterAcceleratorAt(int index) const;
// ui::SimpleMenuModel: // ui::SimpleMenuModel:
void MenuWillClose() override; void MenuWillClose() override;

View file

@ -27,6 +27,8 @@ See [`Menu`](menu.md) for examples.
* `visible` Boolean (optional) - If false, the menu item will be entirely hidden. * `visible` Boolean (optional) - If false, the menu item will be entirely hidden.
* `checked` Boolean (optional) - Should only be specified for `checkbox` or `radio` type * `checked` Boolean (optional) - Should only be specified for `checkbox` or `radio` type
menu items. menu items.
* `registerAccelerator` Boolean (optional) - If false, the accelerator won't be registered
with the system, but it will still be displayed. Defaults to true.
* `submenu` (MenuItemConstructorOptions[] | [Menu](menu.md)) (optional) - Should be specified for `submenu` type menu items. If * `submenu` (MenuItemConstructorOptions[] | [Menu](menu.md)) (optional) - Should be specified for `submenu` type menu items. If
`submenu` is specified, the `type: 'submenu'` can be omitted. If the value `submenu` is specified, the `type: 'submenu'` can be omitted. If the value
is not a [`Menu`](menu.md) then it will be automatically converted to one using is not a [`Menu`](menu.md) then it will be automatically converted to one using

View file

@ -14,12 +14,14 @@ const roles = {
copy: { copy: {
label: 'Copy', label: 'Copy',
accelerator: 'CommandOrControl+C', accelerator: 'CommandOrControl+C',
webContentsMethod: 'copy' webContentsMethod: 'copy',
registerAccelerator: false
}, },
cut: { cut: {
label: 'Cut', label: 'Cut',
accelerator: 'CommandOrControl+X', accelerator: 'CommandOrControl+X',
webContentsMethod: 'cut' webContentsMethod: 'cut',
registerAccelerator: false
}, },
delete: { delete: {
label: 'Delete', label: 'Delete',
@ -57,12 +59,14 @@ const roles = {
paste: { paste: {
label: 'Paste', label: 'Paste',
accelerator: 'CommandOrControl+V', accelerator: 'CommandOrControl+V',
webContentsMethod: 'paste' webContentsMethod: 'paste',
registerAccelerator: false
}, },
pasteandmatchstyle: { pasteandmatchstyle: {
label: 'Paste and Match Style', label: 'Paste and Match Style',
accelerator: 'Shift+CommandOrControl+V', accelerator: 'Shift+CommandOrControl+V',
webContentsMethod: 'pasteAndMatchStyle' webContentsMethod: 'pasteAndMatchStyle',
registerAccelerator: false
}, },
quit: { quit: {
get label () { get label () {
@ -241,6 +245,10 @@ exports.getDefaultAccelerator = (role) => {
if (roles.hasOwnProperty(role)) return roles[role].accelerator if (roles.hasOwnProperty(role)) return roles[role].accelerator
} }
exports.shouldRegisterAccelerator = (role) => {
return roles.hasOwnProperty(role) ? roles[role].registerAccelerator : true
}
exports.getDefaultSubmenu = (role) => { exports.getDefaultSubmenu = (role) => {
if (!roles.hasOwnProperty(role)) return if (!roles.hasOwnProperty(role)) return

View file

@ -36,6 +36,7 @@ const MenuItem = function (options) {
this.overrideProperty('enabled', true) this.overrideProperty('enabled', true)
this.overrideProperty('visible', true) this.overrideProperty('visible', true)
this.overrideProperty('checked', false) this.overrideProperty('checked', false)
this.overrideProperty('registerAccelerator', roles.shouldRegisterAccelerator(this.role))
if (!MenuItem.types.includes(this.type)) { if (!MenuItem.types.includes(this.type)) {
throw new Error(`Unknown menu item type: ${this.type}`) throw new Error(`Unknown menu item type: ${this.type}`)

View file

@ -24,6 +24,7 @@ const delegate = {
if (command.accelerator != null) return command.accelerator if (command.accelerator != null) return command.accelerator
if (useDefaultAccelerator) return command.getDefaultRoleAccelerator() if (useDefaultAccelerator) return command.getDefaultRoleAccelerator()
}, },
shouldRegisterAcceleratorForCommandId: (menu, id) => menu.commandsMap[id] ? menu.commandsMap[id].registerAccelerator : undefined,
executeCommand: (menu, event, id) => { executeCommand: (menu, event, id) => {
const command = menu.commandsMap[id] const command = menu.commandsMap[id]
if (!command) return if (!command) return