| Index: ash/mus/accelerators/accelerator_registrar_impl.cc
|
| diff --git a/ash/mus/accelerators/accelerator_registrar_impl.cc b/ash/mus/accelerators/accelerator_registrar_impl.cc
|
| index f43d1c656988f6c5fbf07d79c96d6a110af3c8aa..ded2528b8c0d8a6cb716171fdee5a9050913dced 100644
|
| --- a/ash/mus/accelerators/accelerator_registrar_impl.cc
|
| +++ b/ash/mus/accelerators/accelerator_registrar_impl.cc
|
| @@ -7,11 +7,14 @@
|
| #include <stdint.h>
|
| #include <utility>
|
|
|
| +#include "ash/common/accelerators/accelerator_controller.h"
|
| +#include "ash/common/wm_shell.h"
|
| #include "ash/mus/accelerators/accelerator_ids.h"
|
| #include "ash/mus/root_window_controller.h"
|
| #include "ash/mus/window_manager.h"
|
| #include "base/bind.h"
|
| #include "services/ui/public/cpp/window_manager_delegate.h"
|
| +#include "ui/events/event.h"
|
|
|
| namespace ash {
|
| namespace mus {
|
| @@ -24,6 +27,33 @@ void CallAddAcceleratorCallback(
|
| callback.Run(result);
|
| }
|
|
|
| +// Returns true if |event_matcher| corresponds to matching an Accelerator.
|
| +bool IsMatcherForKeyAccelerator(const ui::mojom::EventMatcher& event_matcher) {
|
| + return (
|
| + event_matcher.accelerator_phase ==
|
| + ui::mojom::AcceleratorPhase::PRE_TARGET &&
|
| + event_matcher.type_matcher &&
|
| + (event_matcher.type_matcher->type == ui::mojom::EventType::KEY_PRESSED ||
|
| + event_matcher.type_matcher->type ==
|
| + ui::mojom::EventType::KEY_RELEASED) &&
|
| + event_matcher.key_matcher && event_matcher.flags_matcher);
|
| +}
|
| +
|
| +// Converts |event_matcher| into the ui::Accelerator it matches. Only valid if
|
| +// IsMatcherForKeyAccelerator() returns true.
|
| +ui::Accelerator EventMatcherToAccelerator(
|
| + const ui::mojom::EventMatcher& event_matcher) {
|
| + DCHECK(IsMatcherForKeyAccelerator(event_matcher));
|
| + ui::Accelerator accelerator(
|
| + static_cast<ui::KeyboardCode>(event_matcher.key_matcher->keyboard_code),
|
| + event_matcher.flags_matcher->flags);
|
| + accelerator.set_type(event_matcher.type_matcher->type ==
|
| + ui::mojom::EventType::KEY_PRESSED
|
| + ? ui::ET_KEY_PRESSED
|
| + : ui::ET_KEY_RELEASED);
|
| + return accelerator;
|
| +}
|
| +
|
| } // namespace
|
|
|
| AcceleratorRegistrarImpl::AcceleratorRegistrarImpl(
|
| @@ -69,7 +99,7 @@ void AcceleratorRegistrarImpl::OnBindingGone() {
|
| binding_.Unbind();
|
| // If there's no outstanding accelerators for this connection, then destroy
|
| // it.
|
| - if (accelerators_.empty())
|
| + if (accelerators_.empty() && keyboard_accelerator_to_id_.empty())
|
| delete this;
|
| }
|
|
|
| @@ -90,9 +120,48 @@ void AcceleratorRegistrarImpl::RemoveAllAccelerators() {
|
| for (uint32_t accelerator : accelerators_)
|
| window_manager_->window_manager_client()->RemoveAccelerator(accelerator);
|
|
|
| + WmShell::Get()->accelerator_controller()->UnregisterAll(this);
|
| + keyboard_accelerator_to_id_.clear();
|
| + id_to_keyboard_accelerator_.clear();
|
| +
|
| accelerators_.clear();
|
| }
|
|
|
| +bool AcceleratorRegistrarImpl::AddAcceleratorForKeyBinding(
|
| + uint32_t accelerator_id,
|
| + const ::ui::mojom::EventMatcher& matcher,
|
| + const AddAcceleratorCallback& callback) {
|
| + if (!IsMatcherForKeyAccelerator(matcher))
|
| + return false;
|
| +
|
| + const ui::Accelerator accelerator = EventMatcherToAccelerator(matcher);
|
| + if (keyboard_accelerator_to_id_.count(accelerator)) {
|
| + callback.Run(false);
|
| + return true;
|
| + }
|
| +
|
| + AcceleratorController* accelerator_controller =
|
| + WmShell::Get()->accelerator_controller();
|
| + // TODO(sky): reenable this when we decide on the future of AppDriver.
|
| + // http://crbug.com/631836.
|
| + /*
|
| + if (accelerator_controller->IsRegistered(accelerator)) {
|
| + DVLOG(1) << "Attempt to register accelerator that is already registered";
|
| + callback.Run(false);
|
| + // Even though we're not registering the accelerator it's a key that should
|
| + // be handled as an accelerator, so return true.
|
| + return true;
|
| + }
|
| + */
|
| +
|
| + const uint16_t local_id = GetAcceleratorLocalId(accelerator_id);
|
| + keyboard_accelerator_to_id_[accelerator] = local_id;
|
| + id_to_keyboard_accelerator_[local_id] = accelerator;
|
| + accelerator_controller->Register(accelerator, this);
|
| + callback.Run(true);
|
| + return true;
|
| +}
|
| +
|
| void AcceleratorRegistrarImpl::SetHandler(
|
| ::ui::mojom::AcceleratorHandlerPtr handler) {
|
| accelerator_handler_ = std::move(handler);
|
| @@ -110,8 +179,22 @@ void AcceleratorRegistrarImpl::AddAccelerator(
|
| DVLOG(1) << "AddAccelerator failed because of bogus id";
|
| return;
|
| }
|
| +
|
| uint32_t namespaced_accelerator_id = ComputeAcceleratorId(
|
| accelerator_namespace_, static_cast<uint16_t>(accelerator_id));
|
| +
|
| + if (accelerators_.count(namespaced_accelerator_id) ||
|
| + id_to_keyboard_accelerator_.count(
|
| + GetAcceleratorLocalId(namespaced_accelerator_id))) {
|
| + callback.Run(false);
|
| + DVLOG(1) << "AddAccelerator failed because id already in use "
|
| + << accelerator_id;
|
| + return;
|
| + }
|
| +
|
| + if (AddAcceleratorForKeyBinding(accelerator_id, *matcher, callback))
|
| + return;
|
| +
|
| accelerators_.insert(namespaced_accelerator_id);
|
| window_manager_->window_manager_client()->AddAccelerator(
|
| namespaced_accelerator_id, std::move(matcher),
|
| @@ -122,6 +205,15 @@ void AcceleratorRegistrarImpl::RemoveAccelerator(uint32_t accelerator_id) {
|
| if (accelerator_id > 0xFFFF)
|
| return;
|
|
|
| + const uint16_t local_id = GetAcceleratorLocalId(accelerator_id);
|
| + auto iter = id_to_keyboard_accelerator_.find(local_id);
|
| + if (iter != id_to_keyboard_accelerator_.end()) {
|
| + WmShell::Get()->accelerator_controller()->Unregister(iter->second, this);
|
| + keyboard_accelerator_to_id_.erase(iter->second);
|
| + id_to_keyboard_accelerator_.erase(iter);
|
| + return;
|
| + }
|
| +
|
| uint32_t namespaced_accelerator_id = ComputeAcceleratorId(
|
| accelerator_namespace_, static_cast<uint16_t>(accelerator_id));
|
| if (accelerators_.erase(namespaced_accelerator_id) == 0)
|
| @@ -132,8 +224,10 @@ void AcceleratorRegistrarImpl::RemoveAccelerator(uint32_t accelerator_id) {
|
| // If the registrar is not bound anymore (i.e. the client can no longer
|
| // install new accelerators), and the last accelerator has been removed, then
|
| // there's no point keeping this alive anymore.
|
| - if (accelerators_.empty() && !binding_.is_bound())
|
| + if (accelerators_.empty() && keyboard_accelerator_to_id_.empty() &&
|
| + !binding_.is_bound()) {
|
| delete this;
|
| + }
|
| }
|
|
|
| ui::mojom::EventResult AcceleratorRegistrarImpl::OnAccelerator(
|
| @@ -148,5 +242,22 @@ void AcceleratorRegistrarImpl::OnWindowTreeClientDestroyed() {
|
| delete this;
|
| }
|
|
|
| +bool AcceleratorRegistrarImpl::AcceleratorPressed(
|
| + const ui::Accelerator& accelerator) {
|
| + auto iter = keyboard_accelerator_to_id_.find(accelerator);
|
| + DCHECK(iter != keyboard_accelerator_to_id_.end());
|
| + const ui::KeyEvent key_event(accelerator.type(), accelerator.key_code(),
|
| + accelerator.modifiers());
|
| + // TODO(moshayedi): crbug.com/617167. Don't clone even once we map
|
| + // mojom::Event directly to ui::Event.
|
| + accelerator_handler_->OnAccelerator(iter->second,
|
| + ui::Event::Clone(key_event));
|
| + return true;
|
| +}
|
| +
|
| +bool AcceleratorRegistrarImpl::CanHandleAccelerators() const {
|
| + return true;
|
| +}
|
| +
|
| } // namespace mus
|
| } // namespace ash
|
|
|