feat: allow registering multiple shortcuts (#15542)
This PR allows for multiple global shortcuts to be registered such that triggering any of them calls the same callback.
This commit is contained in:
parent
20a540e680
commit
e9ba26f50e
4 changed files with 61 additions and 2 deletions
|
@ -5,6 +5,7 @@
|
|||
#include "atom/browser/api/atom_api_global_shortcut.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/native_mate_converters/accelerator_converter.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
|
@ -38,6 +39,24 @@ void GlobalShortcut::OnKeyPressed(const ui::Accelerator& accelerator) {
|
|||
accelerator_callback_map_[accelerator].Run();
|
||||
}
|
||||
|
||||
bool GlobalShortcut::RegisterAll(
|
||||
const std::vector<ui::Accelerator>& accelerators,
|
||||
const base::Closure& callback) {
|
||||
std::vector<ui::Accelerator> registered;
|
||||
for (auto& accelerator : accelerators) {
|
||||
GlobalShortcutListener* listener = GlobalShortcutListener::GetInstance();
|
||||
if (!listener->RegisterAccelerator(accelerator, this)) {
|
||||
// unregister all shortcuts if any failed
|
||||
UnregisterSome(registered);
|
||||
return false;
|
||||
}
|
||||
|
||||
registered.push_back(accelerator);
|
||||
accelerator_callback_map_[accelerator] = callback;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GlobalShortcut::Register(const ui::Accelerator& accelerator,
|
||||
const base::Closure& callback) {
|
||||
if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator(accelerator,
|
||||
|
@ -58,6 +77,13 @@ void GlobalShortcut::Unregister(const ui::Accelerator& accelerator) {
|
|||
this);
|
||||
}
|
||||
|
||||
void GlobalShortcut::UnregisterSome(
|
||||
const std::vector<ui::Accelerator>& accelerators) {
|
||||
for (auto& accelerator : accelerators) {
|
||||
Unregister(accelerator);
|
||||
}
|
||||
}
|
||||
|
||||
bool GlobalShortcut::IsRegistered(const ui::Accelerator& accelerator) {
|
||||
return ContainsKey(accelerator_callback_map_, accelerator);
|
||||
}
|
||||
|
@ -77,6 +103,7 @@ void GlobalShortcut::BuildPrototype(v8::Isolate* isolate,
|
|||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "GlobalShortcut"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("registerAll", &GlobalShortcut::RegisterAll)
|
||||
.SetMethod("register", &GlobalShortcut::Register)
|
||||
.SetMethod("isRegistered", &GlobalShortcut::IsRegistered)
|
||||
.SetMethod("unregister", &GlobalShortcut::Unregister)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "base/callback.h"
|
||||
|
@ -33,10 +34,13 @@ class GlobalShortcut : public extensions::GlobalShortcutListener::Observer,
|
|||
private:
|
||||
typedef std::map<ui::Accelerator, base::Closure> AcceleratorCallbackMap;
|
||||
|
||||
bool RegisterAll(const std::vector<ui::Accelerator>& accelerators,
|
||||
const base::Closure& callback);
|
||||
bool Register(const ui::Accelerator& accelerator,
|
||||
const base::Closure& callback);
|
||||
bool IsRegistered(const ui::Accelerator& accelerator);
|
||||
void Unregister(const ui::Accelerator& accelerator);
|
||||
void UnregisterSome(const std::vector<ui::Accelerator>& accelerators);
|
||||
void UnregisterAll();
|
||||
|
||||
// GlobalShortcutListener::Observer implementation.
|
||||
|
|
|
@ -54,6 +54,17 @@ When the accelerator is already taken by other applications, this call will
|
|||
silently fail. This behavior is intended by operating systems, since they don't
|
||||
want applications to fight for global shortcuts.
|
||||
|
||||
### `globalShortcut.registerAll(accelerators, callback)`
|
||||
|
||||
* `accelerators` String[] - an array of [Accelerator](accelerator.md)s.
|
||||
* `callback` Function
|
||||
|
||||
Registers a global shortcut of all `accelerator` items in `accelerators`. The `callback` is called when any of the registered shortcuts are pressed by the user.
|
||||
|
||||
When a given accelerator is already taken by other applications, this call will
|
||||
silently fail. This behavior is intended by operating systems, since they don't
|
||||
want applications to fight for global shortcuts.
|
||||
|
||||
### `globalShortcut.isRegistered(accelerator)`
|
||||
|
||||
* `accelerator` [Accelerator](accelerator.md)
|
||||
|
|
|
@ -18,8 +18,8 @@ describe('globalShortcut module', () => {
|
|||
globalShortcut.unregisterAll()
|
||||
})
|
||||
|
||||
it('can register and unregister accelerators', () => {
|
||||
const accelerator = 'CommandOrControl+A+B+C'
|
||||
it('can register and unregister single accelerators', () => {
|
||||
const accelerator = 'CmdOrCtrl+A+B+C'
|
||||
|
||||
expect(globalShortcut.isRegistered(accelerator)).to.be.false()
|
||||
globalShortcut.register(accelerator, () => {})
|
||||
|
@ -33,4 +33,21 @@ describe('globalShortcut module', () => {
|
|||
globalShortcut.unregisterAll()
|
||||
expect(globalShortcut.isRegistered(accelerator)).to.be.false()
|
||||
})
|
||||
|
||||
it('can register and unregister multiple accelerators', () => {
|
||||
const accelerators = ['CmdOrCtrl+X', 'CmdOrCtrl+Y']
|
||||
|
||||
expect(globalShortcut.isRegistered(accelerators[0])).to.be.false()
|
||||
expect(globalShortcut.isRegistered(accelerators[1])).to.be.false()
|
||||
|
||||
globalShortcut.registerAll(accelerators, () => {})
|
||||
|
||||
expect(globalShortcut.isRegistered(accelerators[0])).to.be.true()
|
||||
expect(globalShortcut.isRegistered(accelerators[1])).to.be.true()
|
||||
|
||||
globalShortcut.unregisterAll()
|
||||
|
||||
expect(globalShortcut.isRegistered(accelerators[0])).to.be.false()
|
||||
expect(globalShortcut.isRegistered(accelerators[1])).to.be.false()
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue