Chromium Code Reviews| Index: athena/screen/screen_manager_impl.cc |
| diff --git a/athena/screen/screen_manager_impl.cc b/athena/screen/screen_manager_impl.cc |
| index 744f0762926d2f2cd48641ea56265e173181a443..ac856229841a9878deba888e896fc38f3c64fa22 100644 |
| --- a/athena/screen/screen_manager_impl.cc |
| +++ b/athena/screen/screen_manager_impl.cc |
| @@ -16,6 +16,7 @@ |
| #include "ui/aura/layout_manager.h" |
| #include "ui/aura/window.h" |
| #include "ui/aura/window_property.h" |
| +#include "ui/aura/window_targeter.h" |
| #include "ui/aura/window_tree_host.h" |
| #include "ui/wm/core/base_focus_rules.h" |
| #include "ui/wm/core/capture_controller.h" |
| @@ -29,6 +30,12 @@ DEFINE_OWNED_WINDOW_PROPERTY_KEY(ScreenManager::ContainerParams, |
| ScreenManager* instance = NULL; |
| +bool DoesGrabInput(aura::Window* container) { |
|
oshima
2014/07/24 18:12:48
Or GrabsInput (whichever you like).
Jun Mukai
2014/07/24 18:57:25
Done.
|
| + ScreenManager::ContainerParams* params = |
| + container->GetProperty(kContainerParamsKey); |
| + return params && params->grab_inputs; |
| +} |
| + |
| class AthenaFocusRules : public wm::BaseFocusRules { |
| public: |
| AthenaFocusRules() {} |
| @@ -40,6 +47,23 @@ class AthenaFocusRules : public wm::BaseFocusRules { |
| window->GetProperty(kContainerParamsKey); |
| return params && params->can_activate_children; |
| } |
| + virtual bool CanActivateWindow(aura::Window* window) const OVERRIDE { |
| + // Check if other containers have 'grab_inputs' fields. |
| + bool other_has_grab = false; |
| + if (window) { |
| + const aura::Window::Windows& containers = |
| + window->GetRootWindow()->children(); |
| + for (size_t i = 0; i < containers.size(); ++i) { |
| + ScreenManager::ContainerParams* params = |
| + containers[i]->GetProperty(kContainerParamsKey); |
| + if (!containers[i]->Contains(window) && params && params->grab_inputs) { |
| + other_has_grab = true; |
| + break; |
| + } |
|
oshima
2014/07/24 18:12:48
I wonder if we need to allow a window in higher z-
Jun Mukai
2014/07/24 18:57:26
Done.
|
| + } |
| + } |
| + return !other_has_grab && BaseFocusRules::CanActivateWindow(window); |
| + } |
| private: |
| DISALLOW_COPY_AND_ASSIGN(AthenaFocusRules); |
| @@ -101,6 +125,57 @@ class AthenaScreenPositionClient : public aura::client::ScreenPositionClient { |
| DISALLOW_COPY_AND_ASSIGN(AthenaScreenPositionClient); |
| }; |
| +class AthenaEventTargeter : public aura::WindowTargeter, |
| + public aura::WindowObserver { |
| + public: |
| + AthenaEventTargeter(aura::Window* container) |
|
oshima
2014/07/24 18:12:48
nit: explicit
Jun Mukai
2014/07/24 18:57:26
Done.
|
| + : container_(container) { |
| + container_->AddObserver(this); |
| + } |
| + |
| + virtual ~AthenaEventTargeter() { |
| + // Removed before the container is removed. |
| + if (container_) |
| + container_->RemoveObserver(this); |
| + } |
| + |
| + private: |
| + // aura::WindowTargeter: |
| + virtual bool SubtreeCanAcceptEvent( |
| + ui::EventTarget* target, |
| + const ui::LocatedEvent& event) const OVERRIDE { |
| + aura::Window* window = static_cast<aura::Window*>(target); |
| + const aura::Window::Windows& containers = |
| + container_->GetRootWindow()->children(); |
| + aura::Window::Windows::const_iterator iter = |
| + std::find(containers.begin(), containers.end(), container_); |
| + DCHECK(iter != containers.end()); |
| + for (; iter != containers.end(); ++iter) { |
| + if ((*iter)->Contains(window)) |
| + return true; |
| + } |
| + return false; |
| + } |
| + |
| + // aura::WindowObserver: |
| + virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { |
| + aura::Window* root_window = container_->GetRootWindow(); |
| + DCHECK_EQ(window, container_); |
| + DCHECK_EQ( |
| + this, static_cast<ui::EventTarget*>(root_window)->GetEventTargeter()); |
| + |
| + container_->RemoveObserver(this); |
| + container_ = NULL; |
| + |
| + // This will remove myself. |
| + root_window->SetEventTargeter(scoped_ptr<ui::EventTargeter>()); |
| + } |
| + |
| + aura::Window* container_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(AthenaEventTargeter); |
| +}; |
| + |
| class ScreenManagerImpl : public ScreenManager { |
| public: |
| explicit ScreenManagerImpl(aura::Window* root_window); |
| @@ -208,6 +283,18 @@ aura::Window* ScreenManagerImpl::CreateContainer( |
| #endif |
| container->SetProperty(kContainerParamsKey, new ContainerParams(params)); |
| + |
| + // If another container is already grabbing the input, SetEventTargeter |
| + // implicitly release the grabbing and remove the EventTargeter instance. |
| + // TODO(mukai|oshima): think about the ideal behavior of multiple grabbing |
| + // and implement it. |
| + if (params.grab_inputs) { |
| + DCHECK(std::find_if(children.begin(), children.end(), &DoesGrabInput) |
| + == children.end()); |
|
oshima
2014/07/24 18:12:48
add message << "input has already been grabbed by
Jun Mukai
2014/07/24 18:57:26
Done.
|
| + root_window_->SetEventTargeter( |
| + scoped_ptr<ui::EventTargeter>(new AthenaEventTargeter(container))); |
| + } |
| + |
| root_window_->AddChild(container); |
| aura::Window::Windows::const_iterator iter = |
| @@ -229,7 +316,10 @@ void ScreenManagerImpl::SetBackgroundImage(const gfx::ImageSkia& image) { |
| ScreenManager::ContainerParams::ContainerParams(const std::string& n, |
| int priority) |
| - : name(n), can_activate_children(false), z_order_priority(priority) { |
| + : name(n), |
| + can_activate_children(false), |
| + grab_inputs(false), |
| + z_order_priority(priority) { |
| } |
| // static |