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 |