| Index: mash/wm/accelerator_registrar_impl.cc
|
| diff --git a/mash/wm/accelerator_registrar_impl.cc b/mash/wm/accelerator_registrar_impl.cc
|
| index 1b9da28e7b7641156a0a35fabda2cc6b264832c2..1e2df773d3e59830c4a1f1b734c4ee198d0025b9 100644
|
| --- a/mash/wm/accelerator_registrar_impl.cc
|
| +++ b/mash/wm/accelerator_registrar_impl.cc
|
| @@ -8,36 +8,52 @@
|
| #include <utility>
|
|
|
| #include "base/bind.h"
|
| -#include "components/mus/public/interfaces/window_tree_host.mojom.h"
|
| +#include "components/mus/public/cpp/window_manager_delegate.h"
|
| +#include "mash/wm/root_window_controller.h"
|
| +#include "mash/wm/window_manager.h"
|
| +#include "mash/wm/window_manager_application.h"
|
|
|
| namespace mash {
|
| namespace wm {
|
|
|
| namespace {
|
| const int kAcceleratorIdMask = 0xffff;
|
| +
|
| +void OnAcceleratorAdded(bool result) {}
|
| +void CallAddAcceleratorCallback(
|
| + const mus::mojom::AcceleratorRegistrar::AddAcceleratorCallback& callback,
|
| + bool result) {
|
| + callback.Run(result);
|
| }
|
|
|
| +} // namespace
|
| +
|
| +struct AcceleratorRegistrarImpl::Accelerator {
|
| + mus::mojom::EventMatcherPtr event_matcher;
|
| + AddAcceleratorCallback callback;
|
| + bool callback_used = false;
|
| +};
|
| +
|
| AcceleratorRegistrarImpl::AcceleratorRegistrarImpl(
|
| - mus::mojom::WindowTreeHost* host,
|
| + WindowManagerApplication* wm_app,
|
| uint32_t accelerator_namespace,
|
| mojo::InterfaceRequest<AcceleratorRegistrar> request,
|
| const DestroyCallback& destroy_callback)
|
| - : host_(host),
|
| + : wm_app_(wm_app),
|
| binding_(this, std::move(request)),
|
| accelerator_namespace_(accelerator_namespace & 0xffff),
|
| destroy_callback_(destroy_callback) {
|
| + wm_app_->AddRootWindowsObserver(this);
|
| binding_.set_connection_error_handler(base::Bind(
|
| &AcceleratorRegistrarImpl::OnBindingGone, base::Unretained(this)));
|
| }
|
|
|
| -AcceleratorRegistrarImpl::~AcceleratorRegistrarImpl() {
|
| - for (uint32_t accelerator_id : accelerator_ids_)
|
| - host_->RemoveAccelerator(accelerator_id);
|
| - destroy_callback_.Run(this);
|
| +void AcceleratorRegistrarImpl::Destroy() {
|
| + delete this;
|
| }
|
|
|
| bool AcceleratorRegistrarImpl::OwnsAccelerator(uint32_t accelerator_id) const {
|
| - return !!accelerator_ids_.count(accelerator_id);
|
| + return !!accelerators_.count(accelerator_id);
|
| }
|
|
|
| void AcceleratorRegistrarImpl::ProcessAccelerator(uint32_t accelerator_id,
|
| @@ -47,6 +63,12 @@ void AcceleratorRegistrarImpl::ProcessAccelerator(uint32_t accelerator_id,
|
| std::move(event));
|
| }
|
|
|
| +AcceleratorRegistrarImpl::~AcceleratorRegistrarImpl() {
|
| + wm_app_->RemoveRootWindowsObserver(this);
|
| + RemoveAllAccelerators();
|
| + destroy_callback_.Run(this);
|
| +}
|
| +
|
| uint32_t AcceleratorRegistrarImpl::ComputeAcceleratorId(
|
| uint32_t accelerator_id) const {
|
| return (accelerator_namespace_ << 16) | (accelerator_id & kAcceleratorIdMask);
|
| @@ -56,7 +78,7 @@ void AcceleratorRegistrarImpl::OnBindingGone() {
|
| binding_.Unbind();
|
| // If there's no outstanding accelerators for this connection, then destroy
|
| // it.
|
| - if (accelerator_ids_.empty())
|
| + if (accelerators_.empty())
|
| delete this;
|
| }
|
|
|
| @@ -70,8 +92,31 @@ void AcceleratorRegistrarImpl::OnHandlerGone() {
|
| return;
|
| }
|
| accelerator_handler_.reset();
|
| - for (uint32_t accelerator_id : accelerator_ids_)
|
| - host_->RemoveAccelerator(accelerator_id);
|
| + RemoveAllAccelerators();
|
| +}
|
| +
|
| +void AcceleratorRegistrarImpl::AddAcceleratorToRoot(
|
| + RootWindowController* root,
|
| + uint32_t namespaced_accelerator_id) {
|
| + Accelerator& accelerator = accelerators_[namespaced_accelerator_id];
|
| + AddAcceleratorCallback callback = accelerator.callback_used
|
| + ? base::Bind(&OnAcceleratorAdded)
|
| + : accelerator.callback;
|
| + // Ensure we only notify the callback once (as happens with mojoms).
|
| + accelerator.callback_used = true;
|
| + root->window_manager()->window_manager_client()->AddAccelerator(
|
| + namespaced_accelerator_id, accelerator.event_matcher.Clone(),
|
| + base::Bind(&CallAddAcceleratorCallback, callback));
|
| +}
|
| +
|
| +void AcceleratorRegistrarImpl::RemoveAllAccelerators() {
|
| + for (const auto& pair : accelerators_) {
|
| + for (RootWindowController* root : wm_app_->GetRootControllers()) {
|
| + root->window_manager()->window_manager_client()->RemoveAccelerator(
|
| + pair.first);
|
| + }
|
| + }
|
| + accelerators_.clear();
|
| }
|
|
|
| void AcceleratorRegistrarImpl::SetHandler(
|
| @@ -92,23 +137,35 @@ void AcceleratorRegistrarImpl::AddAccelerator(
|
| return;
|
| }
|
| uint32_t namespaced_accelerator_id = ComputeAcceleratorId(accelerator_id);
|
| - accelerator_ids_.insert(namespaced_accelerator_id);
|
| - host_->AddAccelerator(namespaced_accelerator_id, std::move(matcher),
|
| - callback);
|
| + accelerators_[namespaced_accelerator_id].event_matcher = matcher->Clone();
|
| + accelerators_[namespaced_accelerator_id].callback = callback;
|
| + accelerators_[namespaced_accelerator_id].callback_used = false;
|
| + for (RootWindowController* root : wm_app_->GetRootControllers())
|
| + AddAcceleratorToRoot(root, namespaced_accelerator_id);
|
| }
|
|
|
| void AcceleratorRegistrarImpl::RemoveAccelerator(uint32_t accelerator_id) {
|
| uint32_t namespaced_accelerator_id = ComputeAcceleratorId(accelerator_id);
|
| - if (!accelerator_ids_.count(namespaced_accelerator_id))
|
| + auto iter = accelerators_.find(namespaced_accelerator_id);
|
| + if (iter == accelerators_.end())
|
| return;
|
| - host_->RemoveAccelerator(namespaced_accelerator_id);
|
| - accelerator_ids_.erase(namespaced_accelerator_id);
|
| + for (RootWindowController* root : wm_app_->GetRootControllers()) {
|
| + root->window_manager()->window_manager_client()->RemoveAccelerator(
|
| + namespaced_accelerator_id);
|
| + }
|
| + accelerators_.erase(iter);
|
| // 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 (accelerator_ids_.empty() && !binding_.is_bound())
|
| + if (accelerators_.empty() && !binding_.is_bound())
|
| delete this;
|
| }
|
|
|
| +void AcceleratorRegistrarImpl::OnRootWindowControllerAdded(
|
| + RootWindowController* controller) {
|
| + for (const auto& pair : accelerators_)
|
| + AddAcceleratorToRoot(controller, pair.first);
|
| +}
|
| +
|
| } // namespace wm
|
| } // namespace mash
|
|
|