| Index: ui/aura/root_window.cc
|
| ===================================================================
|
| --- ui/aura/root_window.cc (revision 114098)
|
| +++ ui/aura/root_window.cc (working copy)
|
| @@ -14,7 +14,6 @@
|
| #include "base/string_number_conversions.h"
|
| #include "base/string_split.h"
|
| #include "ui/aura/aura_switches.h"
|
| -#include "ui/aura/client/activation_client.h"
|
| #include "ui/aura/client/drag_drop_client.h"
|
| #include "ui/aura/client/stacking_client.h"
|
| #include "ui/aura/client/tooltip_client.h"
|
| @@ -70,6 +69,20 @@
|
| virtual void AddChildToDefaultParent(Window* window) OVERRIDE {
|
| root_window_->AddChild(window);
|
| }
|
| + virtual bool CanActivateWindow(Window* window) const OVERRIDE {
|
| + return window->parent() == root_window_;
|
| + }
|
| + virtual Window* GetTopmostWindowToActivate(Window* ignore) const OVERRIDE {
|
| + Window::Windows::const_reverse_iterator i;
|
| + for (i = root_window_->children().rbegin();
|
| + i != root_window_->children().rend();
|
| + ++i) {
|
| + if (*i == ignore)
|
| + continue;
|
| + return *i;
|
| + }
|
| + return NULL;
|
| + }
|
|
|
| RootWindow* root_window_;
|
|
|
| @@ -234,6 +247,55 @@
|
| SetHostSize(size);
|
| }
|
|
|
| +void RootWindow::SetActiveWindow(Window* window, Window* to_focus) {
|
| + if (!window)
|
| + return;
|
| + // The stacking client may impose rules on what window configurations can be
|
| + // activated or deactivated.
|
| + if (!stacking_client_->CanActivateWindow(window))
|
| + return;
|
| + // The window may not be activate-able.
|
| + if (!window->CanActivate())
|
| + return;
|
| + // Nothing may actually have changed.
|
| + if (active_window_ == window)
|
| + return;
|
| +
|
| + Window* old_active = active_window_;
|
| + active_window_ = window;
|
| + // Invoke OnLostActive after we've changed the active window. That way if the
|
| + // delegate queries for active state it doesn't think the window is still
|
| + // active.
|
| + if (old_active && old_active->delegate())
|
| + old_active->delegate()->OnLostActive();
|
| + if (active_window_) {
|
| + active_window_->parent()->StackChildAtTop(active_window_);
|
| + if (active_window_->delegate())
|
| + active_window_->delegate()->OnActivated();
|
| + active_window_->GetFocusManager()->SetFocusedWindow(
|
| + to_focus ? to_focus : active_window_);
|
| + }
|
| + FOR_EACH_OBSERVER(RootWindowObserver, observers_,
|
| + OnActiveWindowChanged(active_window_));
|
| +}
|
| +
|
| +void RootWindow::ActivateTopmostWindow() {
|
| + SetActiveWindow(stacking_client_->GetTopmostWindowToActivate(NULL), NULL);
|
| +}
|
| +
|
| +void RootWindow::Deactivate(Window* window) {
|
| + // The stacking client may impose rules on what window configurations can be
|
| + // activated or deactivated.
|
| + if (!window || !stacking_client_->CanActivateWindow(window))
|
| + return;
|
| + if (active_window_ != window)
|
| + return;
|
| +
|
| + Window* to_activate = stacking_client_->GetTopmostWindowToActivate(window);
|
| + if (to_activate)
|
| + SetActiveWindow(to_activate, NULL);
|
| +}
|
| +
|
| void RootWindow::WindowInitialized(Window* window) {
|
| FOR_EACH_OBSERVER(RootWindowObserver, observers_,
|
| OnWindowInitialized(window));
|
| @@ -255,17 +317,25 @@
|
| capture_window_ = NULL;
|
| if (touch_event_handler_ == window)
|
| touch_event_handler_ = NULL;
|
| +
|
| + if (in_destructor_ || window != active_window_)
|
| + return;
|
| +
|
| + // Reset active_window_ before invoking SetActiveWindow so that we don't
|
| + // attempt to notify it while running its destructor.
|
| + active_window_ = NULL;
|
| + SetActiveWindow(stacking_client_->GetTopmostWindowToActivate(window), NULL);
|
| }
|
|
|
| MessageLoop::Dispatcher* RootWindow::GetDispatcher() {
|
| return host_.get();
|
| }
|
|
|
| -void RootWindow::AddRootWindowObserver(RootWindowObserver* observer) {
|
| +void RootWindow::AddObserver(RootWindowObserver* observer) {
|
| observers_.AddObserver(observer);
|
| }
|
|
|
| -void RootWindow::RemoveRootWindowObserver(RootWindowObserver* observer) {
|
| +void RootWindow::RemoveObserver(RootWindowObserver* observer) {
|
| observers_.RemoveObserver(observer);
|
| }
|
|
|
| @@ -336,8 +406,10 @@
|
| ALLOW_THIS_IN_INITIALIZER_LIST(
|
| stacking_client_(new DefaultStackingClient(this))),
|
| ALLOW_THIS_IN_INITIALIZER_LIST(schedule_paint_factory_(this)),
|
| + active_window_(NULL),
|
| mouse_button_flags_(0),
|
| last_cursor_(kCursorNull),
|
| + in_destructor_(false),
|
| screen_(new ScreenAura),
|
| capture_window_(NULL),
|
| mouse_pressed_handler_(NULL),
|
| @@ -362,6 +434,7 @@
|
| }
|
|
|
| RootWindow::~RootWindow() {
|
| + in_destructor_ = true;
|
| // Make sure to destroy the compositor before terminating so that state is
|
| // cleared and we don't hit asserts.
|
| compositor_ = NULL;
|
| @@ -498,28 +571,15 @@
|
| }
|
|
|
| void RootWindow::SetFocusedWindow(Window* focused_window) {
|
| - if (focused_window == focused_window_)
|
| + if (focused_window == focused_window_ ||
|
| + (focused_window && !focused_window->CanFocus())) {
|
| return;
|
| - if (focused_window && !focused_window->CanFocus())
|
| - return;
|
| - // The NULL-check of |focused)window| is essential here before asking the
|
| - // activation client, since it is valid to clear the focus by calling
|
| - // SetFocusedWindow() to NULL.
|
| - if (focused_window && ActivationClient::GetActivationClient() &&
|
| - !ActivationClient::GetActivationClient()->CanFocusWindow(
|
| - focused_window)) {
|
| - return;
|
| }
|
| -
|
| if (focused_window_ && focused_window_->delegate())
|
| focused_window_->delegate()->OnBlur();
|
| focused_window_ = focused_window;
|
| if (focused_window_ && focused_window_->delegate())
|
| focused_window_->delegate()->OnFocus();
|
| - if (focused_window_) {
|
| - FOR_EACH_OBSERVER(RootWindowObserver, observers_,
|
| - OnWindowFocused(focused_window_));
|
| - }
|
| }
|
|
|
| Window* RootWindow::GetFocusedWindow() {
|
|
|