Index: mojo/services/window_manager/window_manager_app.cc |
diff --git a/mojo/services/window_manager/window_manager_app.cc b/mojo/services/window_manager/window_manager_app.cc |
index dc60fdd849b90ad63de9268e2780b75a65a2799e..f8380dd436733ddf827374875a40ac4fc3a492ac 100644 |
--- a/mojo/services/window_manager/window_manager_app.cc |
+++ b/mojo/services/window_manager/window_manager_app.cc |
@@ -5,21 +5,82 @@ |
#include "mojo/services/window_manager/window_manager_app.h" |
#include "base/message_loop/message_loop.h" |
+#include "base/stl_util.h" |
#include "mojo/aura/aura_init.h" |
#include "mojo/aura/window_tree_host_mojo.h" |
#include "mojo/public/cpp/application/application_connection.h" |
#include "mojo/services/public/cpp/view_manager/node.h" |
#include "mojo/services/public/cpp/view_manager/view_manager.h" |
#include "mojo/services/window_manager/window_manager_service_impl.h" |
+#include "ui/aura/window.h" |
+#include "ui/aura/window_property.h" |
#include "ui/wm/core/capture_controller.h" |
+#include "ui/wm/core/focus_controller.h" |
+#include "ui/wm/core/focus_rules.h" |
+#include "ui/wm/public/activation_client.h" |
+ |
+DECLARE_WINDOW_PROPERTY_TYPE(mojo::view_manager::Node*); |
namespace mojo { |
+namespace { |
+ |
+DEFINE_WINDOW_PROPERTY_KEY(view_manager::Node*, kNodeKey, NULL); |
+ |
+view_manager::Id GetIdForWindow(aura::Window* window) { |
+ return window ? window->GetProperty(kNodeKey)->id() : 0; |
+} |
+ |
+class WMFocusRules : public wm::FocusRules { |
+ public: |
+ WMFocusRules() {} |
+ virtual ~WMFocusRules() {} |
+ |
+ private: |
+ // Overridden from wm::FocusRules: |
+ virtual bool IsToplevelWindow(aura::Window* window) const MOJO_OVERRIDE { |
+ return true; |
+ } |
+ virtual bool CanActivateWindow(aura::Window* window) const MOJO_OVERRIDE { |
+ return true; |
+ } |
+ virtual bool CanFocusWindow(aura::Window* window) const MOJO_OVERRIDE { |
+ return true; |
+ } |
+ virtual aura::Window* GetToplevelWindow( |
+ aura::Window* window) const MOJO_OVERRIDE { |
+ return window; |
+ } |
+ virtual aura::Window* GetActivatableWindow( |
+ aura::Window* window) const MOJO_OVERRIDE { |
+ return window; |
+ } |
+ virtual aura::Window* GetFocusableWindow( |
+ aura::Window* window) const MOJO_OVERRIDE { |
+ return window; |
+ } |
+ virtual aura::Window* GetNextActivatableWindow( |
+ aura::Window* ignore) const MOJO_OVERRIDE { |
+ return NULL; |
+ } |
+ |
+ DISALLOW_COPY_AND_ASSIGN(WMFocusRules); |
+}; |
+ |
+} // namespace |
//////////////////////////////////////////////////////////////////////////////// |
// WindowManagerApp, public: |
WindowManagerApp::WindowManagerApp() : view_manager_(NULL), root_(NULL) {} |
-WindowManagerApp::~WindowManagerApp() {} |
+WindowManagerApp::~WindowManagerApp() { |
+ // TODO(beng): Figure out if this should be done in |
+ // OnViewManagerDisconnected(). |
+ STLDeleteValues(&node_id_to_window_map_); |
+ if (focus_client_.get()) |
+ focus_client_->RemoveObserver(this); |
+ if (activation_client_) |
+ activation_client_->RemoveObserver(this); |
+} |
void WindowManagerApp::AddConnection(WindowManagerServiceImpl* connection) { |
DCHECK(connections_.find(connection) == connections_.end()); |
@@ -37,12 +98,31 @@ view_manager::Id WindowManagerApp::OpenWindow() { |
return node->id(); |
} |
+view_manager::Id WindowManagerApp::OpenWindowWithURL(const String& url) { |
+ view_manager::Node* node = view_manager::Node::Create(view_manager_); |
+ root_->AddChild(node); |
+ node->Embed(url); |
+ return node->id(); |
+} |
+ |
void WindowManagerApp::SetCapture(view_manager::Id node) { |
capture_client_->capture_client()->SetCapture(GetWindowForNodeId(node)); |
// TODO(beng): notify connected clients that capture has changed, probably |
// by implementing some capture-client observer. |
} |
+void WindowManagerApp::FocusWindow(view_manager::Id node) { |
+ aura::Window* window = GetWindowForNodeId(node); |
+ DCHECK(window); |
+ focus_client_->FocusWindow(window); |
+} |
+ |
+void WindowManagerApp::ActivateWindow(view_manager::Id node) { |
+ aura::Window* window = GetWindowForNodeId(node); |
+ DCHECK(window); |
+ activation_client_->ActivateWindow(window); |
+} |
+ |
bool WindowManagerApp::IsReady() const { |
return view_manager_ && root_; |
} |
@@ -69,11 +149,21 @@ void WindowManagerApp::OnRootAdded(view_manager::ViewManager* view_manager, |
DCHECK(!view_manager_ && !root_); |
view_manager_ = view_manager; |
root_ = root; |
+ root_->AddObserver(this); |
window_tree_host_.reset(new WindowTreeHostMojo(root_, this)); |
+ RegisterSubtree(root_->id(), window_tree_host_->window()); |
+ |
capture_client_.reset( |
new wm::ScopedCaptureClient(window_tree_host_->window())); |
+ wm::FocusController* focus_controller = |
+ new wm::FocusController(new WMFocusRules); |
+ activation_client_ = focus_controller; |
+ focus_client_.reset(focus_controller); |
+ |
+ focus_client_->AddObserver(this); |
+ activation_client_->AddObserver(this); |
// TODO(beng): Create the universe. |
@@ -86,11 +176,36 @@ void WindowManagerApp::OnRootAdded(view_manager::ViewManager* view_manager, |
void WindowManagerApp::OnViewManagerDisconnected( |
view_manager::ViewManager* view_manager) { |
DCHECK_EQ(view_manager_, view_manager); |
+ root_->RemoveObserver(this); |
+ root_ = NULL; |
view_manager_ = NULL; |
base::MessageLoop::current()->Quit(); |
} |
//////////////////////////////////////////////////////////////////////////////// |
+// WindowManagerApp, view_manager::NodeObserver implementation: |
+ |
+void WindowManagerApp::OnTreeChanged( |
+ const view_manager::NodeObserver::TreeChangeParams& params) { |
+ DCHECK_EQ(params.receiver, root_); |
+ DCHECK(params.old_parent || params.new_parent); |
+ if (!params.target) |
+ return; |
+ |
+ if (params.new_parent) { |
+ if (node_id_to_window_map_.find(params.target->id()) == |
+ node_id_to_window_map_.end()) { |
+ NodeIdToWindowMap::const_iterator it = |
+ node_id_to_window_map_.find(params.new_parent->id()); |
+ DCHECK(it != node_id_to_window_map_.end()); |
+ RegisterSubtree(params.target->id(), it->second); |
+ } |
+ } else if (params.old_parent) { |
+ UnregisterSubtree(params.target->id()); |
+ } |
+} |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
// WindowManagerApp, WindowTreeHostMojoDelegate implementation: |
void WindowManagerApp::CompositorContentsChanged(const SkBitmap& bitmap) { |
@@ -99,12 +214,60 @@ void WindowManagerApp::CompositorContentsChanged(const SkBitmap& bitmap) { |
} |
//////////////////////////////////////////////////////////////////////////////// |
+// WindowManagerApp, aura::client::FocusChangeObserver implementation: |
+ |
+void WindowManagerApp::OnWindowFocused(aura::Window* gained_focus, |
+ aura::Window* lost_focus) { |
+ for (Connections::const_iterator it = connections_.begin(); |
+ it != connections_.end(); ++it) { |
+ (*it)->NotifyNodeFocused(GetIdForWindow(gained_focus), |
+ GetIdForWindow(lost_focus)); |
+ } |
+} |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
+// WindowManagerApp, aura::client::ActivationChangeObserver implementation: |
+ |
+void WindowManagerApp::OnWindowActivated(aura::Window* gained_active, |
+ aura::Window* lost_active) { |
+ for (Connections::const_iterator it = connections_.begin(); |
+ it != connections_.end(); ++it) { |
+ (*it)->NotifyWindowActivated(GetIdForWindow(gained_active), |
+ GetIdForWindow(lost_active)); |
+ } |
+} |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
// WindowManagerApp, private: |
aura::Window* WindowManagerApp::GetWindowForNodeId( |
view_manager::Id node) const { |
- NOTIMPLEMENTED(); |
- return NULL; |
+ NodeIdToWindowMap::const_iterator it = node_id_to_window_map_.find(node); |
+ return it != node_id_to_window_map_.end() ? it->second : NULL; |
+} |
+ |
+void WindowManagerApp::RegisterSubtree(view_manager::Id id, |
+ aura::Window* parent) { |
+ view_manager::Node* node = view_manager_->GetNodeById(id); |
+ DCHECK(node_id_to_window_map_.find(id) == node_id_to_window_map_.end()); |
+ aura::Window* window = new aura::Window(NULL); |
+ window->SetProperty(kNodeKey, node); |
+ parent->AddChild(window); |
+ node_id_to_window_map_[id] = window; |
+ view_manager::Node::Children::const_iterator it = node->children().begin(); |
+ for (; it != node->children().end(); ++it) |
+ RegisterSubtree((*it)->id(), window); |
+} |
+ |
+void WindowManagerApp::UnregisterSubtree(view_manager::Id id) { |
+ view_manager::Node* node = view_manager_->GetNodeById(id); |
+ NodeIdToWindowMap::const_iterator it = node_id_to_window_map_.find(id); |
+ DCHECK(it != node_id_to_window_map_.end()); |
+ scoped_ptr<aura::Window> window(it->second); |
+ node_id_to_window_map_.erase(it); |
+ view_manager::Node::Children::const_iterator child = node->children().begin(); |
+ for (; child != node->children().end(); ++child) |
+ UnregisterSubtree((*child)->id()); |
} |
//////////////////////////////////////////////////////////////////////////////// |