Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2060)

Unified Diff: athena/screen/screen_manager_impl.cc

Issue 414903002: Introduce 'grab_inputs' property for athena container. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « athena/screen/public/screen_manager.h ('k') | athena/screen/screen_manager_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..8522acfc7acd30404c8b2ce8aa0d88fad5963769 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,22 @@ DEFINE_OWNED_WINDOW_PROPERTY_KEY(ScreenManager::ContainerParams,
ScreenManager* instance = NULL;
+bool GrabsInput(aura::Window* container) {
+ ScreenManager::ContainerParams* params =
+ container->GetProperty(kContainerParamsKey);
+ return params && params->grab_inputs;
+}
+
+// Returns the container which contains |window|.
+aura::Window* GetContainer(aura::Window* window) {
+ // No containers for NULL or the root window itself.
+ if (!window || !window->parent())
+ return NULL;
+ if (window->parent()->IsRootWindow())
+ return window;
+ return GetContainer(window->parent());
+}
+
class AthenaFocusRules : public wm::BaseFocusRules {
public:
AthenaFocusRules() {}
@@ -40,6 +57,22 @@ class AthenaFocusRules : public wm::BaseFocusRules {
window->GetProperty(kContainerParamsKey);
return params && params->can_activate_children;
}
+ virtual bool CanActivateWindow(aura::Window* window) const OVERRIDE {
+ // Check if containers of higher z-order than |window| have 'grab_inputs'
+ // fields.
+ if (window) {
+ const aura::Window::Windows& containers =
+ window->GetRootWindow()->children();
+ aura::Window::Windows::const_iterator iter =
+ std::find(containers.begin(), containers.end(), GetContainer(window));
+ DCHECK(iter != containers.end());
+ for (++iter; iter != containers.end(); ++iter) {
+ if (GrabsInput(*iter))
+ return false;
+ }
+ }
+ return BaseFocusRules::CanActivateWindow(window);
+ }
private:
DISALLOW_COPY_AND_ASSIGN(AthenaFocusRules);
@@ -101,6 +134,57 @@ class AthenaScreenPositionClient : public aura::client::ScreenPositionClient {
DISALLOW_COPY_AND_ASSIGN(AthenaScreenPositionClient);
};
+class AthenaEventTargeter : public aura::WindowTargeter,
+ public aura::WindowObserver {
+ public:
+ explicit AthenaEventTargeter(aura::Window* container)
+ : 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 +292,19 @@ 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(), &GrabsInput)
+ == children.end())
+ << "input has already been grabbed by another container";
+ root_window_->SetEventTargeter(
+ scoped_ptr<ui::EventTargeter>(new AthenaEventTargeter(container)));
+ }
+
root_window_->AddChild(container);
aura::Window::Windows::const_iterator iter =
@@ -229,7 +326,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
« no previous file with comments | « athena/screen/public/screen_manager.h ('k') | athena/screen/screen_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698