diff options
author | bruthig <bruthig@chromium.org> | 2015-06-05 08:33:21 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-06-05 15:33:59 +0000 |
commit | 5681d88c96e685a4e469105e8fcb382dc9893c9a (patch) | |
tree | 8b3dea83daba769e1cdf9f4c9b3f46dadd7d09c3 /ui | |
parent | 74f13dc2b62abb34e947093fe2600f9c539e60ef (diff) | |
download | chromium_src-5681d88c96e685a4e469105e8fcb382dc9893c9a.zip chromium_src-5681d88c96e685a4e469105e8fcb382dc9893c9a.tar.gz chromium_src-5681d88c96e685a4e469105e8fcb382dc9893c9a.tar.bz2 |
Added an ActivationReason parameter to ActivationChangeObserver::OnWindowActivated(...).
TEST=FocusControllerApiTest.DuplicateActivationEvents
TEST=FocusControllerApiTest.ActivationEvents
TEST=FocusControllerMouseEventTest.DuplicateActivationEvents
TEST=FocusControllerMouseEventTest.ActivationEvents
TEST=FocusControllerGestureEventTest.DuplicateActivationEvents
TEST=FocusControllerGestureEventTest.ActivationEvents
TEST=FocusControllerHideTest.ActivationEvents
TEST=FocusControllerDestructionTest.ActivationEvents
TEST=FocusControllerRemovalTest.ActivationEvents
BUG=489813, 489814
Review URL: https://codereview.chromium.org/1151133003
Cr-Commit-Position: refs/heads/master@{#333048}
Diffstat (limited to 'ui')
-rw-r--r-- | ui/views/controls/menu/menu_message_loop_aura.cc | 6 | ||||
-rw-r--r-- | ui/views/widget/desktop_aura/desktop_native_widget_aura.cc | 6 | ||||
-rw-r--r-- | ui/views/widget/desktop_aura/desktop_native_widget_aura.h | 6 | ||||
-rw-r--r-- | ui/views/widget/native_widget_aura.cc | 6 | ||||
-rw-r--r-- | ui/views/widget/native_widget_aura.h | 6 | ||||
-rw-r--r-- | ui/wm/core/default_activation_client.cc | 46 | ||||
-rw-r--r-- | ui/wm/core/default_activation_client.h | 5 | ||||
-rw-r--r-- | ui/wm/core/focus_controller.cc | 103 | ||||
-rw-r--r-- | ui/wm/core/focus_controller.h | 38 | ||||
-rw-r--r-- | ui/wm/core/focus_controller_unittest.cc | 54 | ||||
-rw-r--r-- | ui/wm/core/shadow_controller.cc | 11 | ||||
-rw-r--r-- | ui/wm/core/shadow_controller.h | 6 | ||||
-rw-r--r-- | ui/wm/public/activation_change_observer.h | 20 |
13 files changed, 215 insertions, 98 deletions
diff --git a/ui/views/controls/menu/menu_message_loop_aura.cc b/ui/views/controls/menu/menu_message_loop_aura.cc index 6a16296..3ed3328 100644 --- a/ui/views/controls/menu/menu_message_loop_aura.cc +++ b/ui/views/controls/menu/menu_message_loop_aura.cc @@ -60,8 +60,10 @@ class ActivationChangeObserverImpl ~ActivationChangeObserverImpl() override { Cleanup(); } // aura::client::ActivationChangeObserver: - void OnWindowActivated(aura::Window* gained_active, - aura::Window* lost_active) override { + void OnWindowActivated( + aura::client::ActivationChangeObserver::ActivationReason reason, + aura::Window* gained_active, + aura::Window* lost_active) override { if (!controller_->drag_in_progress()) controller_->CancelAll(); } diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc index c82ced7..33629f9 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc @@ -1111,8 +1111,10 @@ bool DesktopNativeWidgetAura::ShouldActivate() const { // DesktopNativeWidgetAura, aura::client::ActivationChangeObserver // implementation: -void DesktopNativeWidgetAura::OnWindowActivated(aura::Window* gained_active, - aura::Window* lost_active) { +void DesktopNativeWidgetAura::OnWindowActivated( + aura::client::ActivationChangeObserver::ActivationReason reason, + aura::Window* gained_active, + aura::Window* lost_active) { DCHECK(content_window_ == gained_active || content_window_ == lost_active); if (gained_active == content_window_ && restore_focus_on_activate_) { restore_focus_on_activate_ = false; diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h index e92aa84..0419fab 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h @@ -213,8 +213,10 @@ class VIEWS_EXPORT DesktopNativeWidgetAura bool ShouldActivate() const override; // Overridden from aura::client::ActivationChangeObserver: - void OnWindowActivated(aura::Window* gained_active, - aura::Window* lost_active) override; + void OnWindowActivated( + aura::client::ActivationChangeObserver::ActivationReason reason, + aura::Window* gained_active, + aura::Window* lost_active) override; // Overridden from aura::client::FocusChangeObserver: void OnWindowFocused(aura::Window* gained_focus, diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc index bf113e6..92ff22a 100644 --- a/ui/views/widget/native_widget_aura.cc +++ b/ui/views/widget/native_widget_aura.cc @@ -936,8 +936,10 @@ bool NativeWidgetAura::ShouldActivate() const { //////////////////////////////////////////////////////////////////////////////// // NativeWidgetAura, aura::client::ActivationChangeObserver implementation: -void NativeWidgetAura::OnWindowActivated(aura::Window* gained_active, - aura::Window* lost_active) { +void NativeWidgetAura::OnWindowActivated( + aura::client::ActivationChangeObserver::ActivationReason, + aura::Window* gained_active, + aura::Window* lost_active) { DCHECK(window_ == gained_active || window_ == lost_active); if (GetWidget()->GetFocusManager()) { if (window_ == gained_active) diff --git a/ui/views/widget/native_widget_aura.h b/ui/views/widget/native_widget_aura.h index 40a9c47..6c38c3e 100644 --- a/ui/views/widget/native_widget_aura.h +++ b/ui/views/widget/native_widget_aura.h @@ -177,8 +177,10 @@ class VIEWS_EXPORT NativeWidgetAura bool ShouldActivate() const override; // Overridden from aura::client::ActivationChangeObserver: - void OnWindowActivated(aura::Window* gained_active, - aura::Window* lost_active) override; + void OnWindowActivated( + aura::client::ActivationChangeObserver::ActivationReason reason, + aura::Window* gained_active, + aura::Window* lost_active) override; // Overridden from aura::client::FocusChangeObserver: void OnWindowFocused(aura::Window* gained_focus, diff --git a/ui/wm/core/default_activation_client.cc b/ui/wm/core/default_activation_client.cc index 20c0d79..2a2c23d 100644 --- a/ui/wm/core/default_activation_client.cc +++ b/ui/wm/core/default_activation_client.cc @@ -40,7 +40,7 @@ class DefaultActivationClient::Deleter : public aura::WindowObserver { // DefaultActivationClient, public: DefaultActivationClient::DefaultActivationClient(aura::Window* root_window) - : last_active_(NULL) { + : last_active_(nullptr) { aura::client::SetActivationClient(root_window, this); new Deleter(this, root_window); } @@ -59,6 +59,14 @@ void DefaultActivationClient::RemoveObserver( } void DefaultActivationClient::ActivateWindow(aura::Window* window) { + ActivateWindowImpl(aura::client::ActivationChangeObserver::ActivationReason:: + ACTIVATION_CLIENT, + window); +} + +void DefaultActivationClient::ActivateWindowImpl( + aura::client::ActivationChangeObserver::ActivationReason reason, + aura::Window* window) { aura::Window* last_active = GetActiveWindow(); if (last_active == window) return; @@ -69,41 +77,45 @@ void DefaultActivationClient::ActivateWindow(aura::Window* window) { window->parent()->StackChildAtTop(window); window->AddObserver(this); - FOR_EACH_OBSERVER(aura::client::ActivationChangeObserver, - observers_, - OnWindowActivated(window, last_active)); + FOR_EACH_OBSERVER(aura::client::ActivationChangeObserver, observers_, + OnWindowActivated(reason, window, last_active)); aura::client::ActivationChangeObserver* observer = aura::client::GetActivationChangeObserver(last_active); - if (observer) - observer->OnWindowActivated(window, last_active); + if (observer) { + observer->OnWindowActivated(reason, window, last_active); + } observer = aura::client::GetActivationChangeObserver(window); - if (observer) - observer->OnWindowActivated(window, last_active); + if (observer) { + observer->OnWindowActivated(reason, window, last_active); + } } void DefaultActivationClient::DeactivateWindow(aura::Window* window) { aura::client::ActivationChangeObserver* observer = aura::client::GetActivationChangeObserver(window); - if (observer) - observer->OnWindowActivated(NULL, window); + if (observer) { + observer->OnWindowActivated(aura::client::ActivationChangeObserver:: + ActivationReason::ACTIVATION_CLIENT, + nullptr, window); + } if (last_active_) ActivateWindow(last_active_); } aura::Window* DefaultActivationClient::GetActiveWindow() { if (active_windows_.empty()) - return NULL; + return nullptr; return active_windows_.back(); } aura::Window* DefaultActivationClient::GetActivatableWindow( aura::Window* window) { - return NULL; + return nullptr; } aura::Window* DefaultActivationClient::GetToplevelWindow(aura::Window* window) { - return NULL; + return nullptr; } bool DefaultActivationClient::CanActivateWindow(aura::Window* window) const { @@ -115,14 +127,16 @@ bool DefaultActivationClient::CanActivateWindow(aura::Window* window) const { void DefaultActivationClient::OnWindowDestroyed(aura::Window* window) { if (window == last_active_) - last_active_ = NULL; + last_active_ = nullptr; if (window == GetActiveWindow()) { active_windows_.pop_back(); aura::Window* next_active = GetActiveWindow(); if (next_active && aura::client::GetActivationChangeObserver(next_active)) { - aura::client::GetActivationChangeObserver(next_active)->OnWindowActivated( - next_active, NULL); + aura::client::GetActivationChangeObserver(next_active) + ->OnWindowActivated(aura::client::ActivationChangeObserver:: + ActivationReason::WINDOW_DISPOSITION_CHANGED, + next_active, nullptr); } return; } diff --git a/ui/wm/core/default_activation_client.h b/ui/wm/core/default_activation_client.h index b5511457..894bccff 100644 --- a/ui/wm/core/default_activation_client.h +++ b/ui/wm/core/default_activation_client.h @@ -11,6 +11,7 @@ #include "base/logging.h" #include "base/observer_list.h" #include "ui/aura/window_observer.h" +#include "ui/wm/public/activation_change_observer.h" #include "ui/wm/public/activation_client.h" #include "ui/wm/wm_export.h" @@ -51,6 +52,10 @@ class WM_EXPORT DefaultActivationClient : public aura::client::ActivationClient, ~DefaultActivationClient() override; void RemoveActiveWindow(aura::Window* window); + void ActivateWindowImpl( + aura::client::ActivationChangeObserver::ActivationReason reason, + aura::Window* window); + // This class explicitly does NOT store the active window in a window property // to make sure that ActivationChangeObserver is not treated as part of the // aura API. Assumptions to that end will cause tests that use this client to diff --git a/ui/wm/core/focus_controller.cc b/ui/wm/core/focus_controller.cc index 446e82c..1fee190 100644 --- a/ui/wm/core/focus_controller.cc +++ b/ui/wm/core/focus_controller.cc @@ -103,38 +103,9 @@ void FocusController::RemoveObserver( } void FocusController::FocusWindow(aura::Window* window) { - if (window && - (window->Contains(focused_window_) || window->Contains(active_window_))) { - return; - } - - // Focusing a window also activates its containing activatable window. Note - // that the rules could redirect activation activation and/or focus. - aura::Window* focusable = rules_->GetFocusableWindow(window); - aura::Window* activatable = - focusable ? rules_->GetActivatableWindow(focusable) : NULL; - - // We need valid focusable/activatable windows in the event we're not clearing - // focus. "Clearing focus" is inferred by whether or not |window| passed to - // this function is non-NULL. - if (window && (!focusable || !activatable)) - return; - DCHECK((focusable && activatable) || !window); - - // Activation change observers may change the focused window. If this happens - // we must not adjust the focus below since this will clobber that change. - aura::Window* last_focused_window = focused_window_; - if (!updating_activation_) - SetActiveWindow(window, activatable); - - // If the window's ActivationChangeObserver shifted focus to a valid window, - // we don't want to focus the window we thought would be focused by default. - bool activation_changed_focus = last_focused_window != focused_window_; - if (!updating_focus_ && (!activation_changed_focus || !focused_window_)) { - if (active_window_ && focusable) - DCHECK(active_window_->Contains(focusable)); - SetFocusedWindow(focusable); - } + FocusAndActivateWindow(aura::client::ActivationChangeObserver:: + ActivationReason::ACTIVATION_CLIENT, + window); } void FocusController::ResetFocusWithinActiveWindow(aura::Window* window) { @@ -213,6 +184,43 @@ void FocusController::OnWindowHierarchyChanged( //////////////////////////////////////////////////////////////////////////////// // FocusController, private: +void FocusController::FocusAndActivateWindow( + aura::client::ActivationChangeObserver::ActivationReason reason, + aura::Window* window) { + if (window && + (window->Contains(focused_window_) || window->Contains(active_window_))) { + return; + } + + // Focusing a window also activates its containing activatable window. Note + // that the rules could redirect activation activation and/or focus. + aura::Window* focusable = rules_->GetFocusableWindow(window); + aura::Window* activatable = + focusable ? rules_->GetActivatableWindow(focusable) : NULL; + + // We need valid focusable/activatable windows in the event we're not clearing + // focus. "Clearing focus" is inferred by whether or not |window| passed to + // this function is non-NULL. + if (window && (!focusable || !activatable)) + return; + DCHECK((focusable && activatable) || !window); + + // Activation change observers may change the focused window. If this happens + // we must not adjust the focus below since this will clobber that change. + aura::Window* last_focused_window = focused_window_; + if (!updating_activation_) + SetActiveWindow(reason, window, activatable); + + // If the window's ActivationChangeObserver shifted focus to a valid window, + // we don't want to focus the window we thought would be focused by default. + bool activation_changed_focus = last_focused_window != focused_window_; + if (!updating_focus_ && (!activation_changed_focus || !focused_window_)) { + if (active_window_ && focusable) + DCHECK(active_window_->Contains(focusable)); + SetFocusedWindow(focusable); + } +} + void FocusController::SetFocusedWindow(aura::Window* window) { if (updating_focus_ || window == focused_window_) return; @@ -268,8 +276,10 @@ void FocusController::SetFocusedWindow(aura::Window* window) { text_input_focus_manager->FocusTextInputClient(NULL); } -void FocusController::SetActiveWindow(aura::Window* requested_window, - aura::Window* window) { +void FocusController::SetActiveWindow( + aura::client::ActivationChangeObserver::ActivationReason reason, + aura::Window* requested_window, + aura::Window* window) { if (updating_activation_) return; @@ -310,19 +320,19 @@ void FocusController::SetActiveWindow(aura::Window* requested_window, if (window_tracker.Contains(lost_activation)) { observer = aura::client::GetActivationChangeObserver(lost_activation); if (observer) - observer->OnWindowActivated(active_window_, lost_activation); + observer->OnWindowActivated(reason, active_window_, lost_activation); } observer = aura::client::GetActivationChangeObserver(active_window_); if (observer) { observer->OnWindowActivated( - active_window_, + reason, active_window_, window_tracker.Contains(lost_activation) ? lost_activation : NULL); } - FOR_EACH_OBSERVER(aura::client::ActivationChangeObserver, - activation_observers_, - OnWindowActivated(active_window_, - window_tracker.Contains(lost_activation) ? - lost_activation : NULL)); + FOR_EACH_OBSERVER( + aura::client::ActivationChangeObserver, activation_observers_, + OnWindowActivated( + reason, active_window_, + window_tracker.Contains(lost_activation) ? lost_activation : NULL)); } void FocusController::WindowLostFocusFromDispositionChange( @@ -335,7 +345,9 @@ void FocusController::WindowLostFocusFromDispositionChange( // that process so there's no point in updating focus independently. if (window == active_window_) { aura::Window* next_activatable = rules_->GetNextActivatableWindow(window); - SetActiveWindow(NULL, next_activatable); + SetActiveWindow(aura::client::ActivationChangeObserver::ActivationReason:: + WINDOW_DISPOSITION_CHANGED, + NULL, next_activatable); if (!(active_window_ && active_window_->Contains(focused_window_))) SetFocusedWindow(next_activatable); } else if (window->Contains(focused_window_)) { @@ -348,8 +360,11 @@ void FocusController::WindowFocusedFromInputEvent(aura::Window* window) { // Only focus |window| if it or any of its parents can be focused. Otherwise // FocusWindow() will focus the topmost window, which may not be the // currently focused one. - if (rules_->CanFocusWindow(GetToplevelWindow(window))) - FocusWindow(window); + if (rules_->CanFocusWindow(GetToplevelWindow(window))) { + FocusAndActivateWindow( + aura::client::ActivationChangeObserver::ActivationReason::INPUT_EVENT, + window); + } } } // namespace wm diff --git a/ui/wm/core/focus_controller.h b/ui/wm/core/focus_controller.h index be04b49..e00f0b6 100644 --- a/ui/wm/core/focus_controller.h +++ b/ui/wm/core/focus_controller.h @@ -12,6 +12,7 @@ #include "ui/aura/client/focus_client.h" #include "ui/aura/window_observer.h" #include "ui/events/event_handler.h" +#include "ui/wm/public/activation_change_observer.h" #include "ui/wm/public/activation_client.h" #include "ui/wm/wm_export.h" @@ -24,16 +25,19 @@ class FocusRules; // only one focused and one active window at a time. When focus or activation // changes notifications are sent using the // aura::client::Focus/ActivationChangeObserver interfaces. -// Changes to focus and activation can be from three sources: -// . the Aura Client API (implemented here in aura::client::ActivationClient). -// (The FocusController must be set as the ActivationClient implementation -// for all RootWindows). -// . input events (implemented here in ui::EventHandler). -// (The FocusController must be registered as a pre-target handler for -// the applicable environment owner, either a RootWindow or another type). -// . Window disposition changes (implemented here in aura::WindowObserver). -// (The FocusController registers itself as an observer of the active and -// focused windows). +// Changes to focus and activation can be from three sources. The source can be +// determined by the ActivationReason parameter in +// ActivationChangeObserver::OnWindowActivated(...). +// . ActivationReason::ACTIVATION_CLIENT: The Aura Client API (implemented here +// in aura::client::ActivationClient). (The FocusController must be set as the +// ActivationClient implementation for all RootWindows). +// . ActivationReason::INPUT_EVENT: Input events (implemented here in +// ui::EventHandler). (The FocusController must be registered as a pre-target +// handler for the applicable environment owner, either a RootWindow or +// another type). +// . ActivationReason::WINDOW_DISPOSITION_CHANGED: Window disposition changes +// (implemented here in aura::WindowObserver). (The FocusController registers +// itself as an observer of the active and focused windows). class WM_EXPORT FocusController : public aura::client::ActivationClient, public aura::client::FocusClient, public ui::EventHandler, @@ -75,18 +79,26 @@ class WM_EXPORT FocusController : public aura::client::ActivationClient, void OnWindowHierarchyChanging(const HierarchyChangeParams& params) override; void OnWindowHierarchyChanged(const HierarchyChangeParams& params) override; + // Internal implementation that coordinates window focus and activation + // changes. + void FocusAndActivateWindow( + aura::client::ActivationChangeObserver::ActivationReason reason, + aura::Window* window); + // Internal implementation that sets the focused window, fires events etc. // This function must be called with a valid focusable window. void SetFocusedWindow(aura::Window* window); // Internal implementation that sets the active window, fires events etc. // This function must be called with a valid |activatable_window|. - // |requested window| refers to the window that was passed in to an external + // |requested_window| refers to the window that was passed in to an external // request (e.g. FocusWindow or ActivateWindow). It may be NULL, e.g. if // SetActiveWindow was not called by an external request. |activatable_window| // refers to the actual window to be activated, which may be different. - void SetActiveWindow(aura::Window* requested_window, - aura::Window* activatable_window); + void SetActiveWindow( + aura::client::ActivationChangeObserver::ActivationReason reason, + aura::Window* requested_window, + aura::Window* activatable_window); // Called when a window's disposition changed such that it and its hierarchy // are no longer focusable/activatable. |next| is a valid window that is used diff --git a/ui/wm/core/focus_controller_unittest.cc b/ui/wm/core/focus_controller_unittest.cc index 84c691f..a8bddb3 100644 --- a/ui/wm/core/focus_controller_unittest.cc +++ b/ui/wm/core/focus_controller_unittest.cc @@ -33,7 +33,8 @@ class FocusNotificationObserver : public aura::client::ActivationChangeObserver, public aura::client::FocusChangeObserver { public: FocusNotificationObserver() - : activation_changed_count_(0), + : last_activation_reason_(ActivationReason::ACTIVATION_CLIENT), + activation_changed_count_(0), focus_changed_count_(0), reactivation_count_(0), reactivation_requested_window_(NULL), @@ -44,6 +45,9 @@ class FocusNotificationObserver : public aura::client::ActivationChangeObserver, EXPECT_EQ(activation_changed_count, activation_changed_count_); EXPECT_EQ(focus_changed_count, focus_changed_count_); } + ActivationReason last_activation_reason() const { + return last_activation_reason_; + } int reactivation_count() const { return reactivation_count_; } @@ -56,8 +60,10 @@ class FocusNotificationObserver : public aura::client::ActivationChangeObserver, private: // Overridden from aura::client::ActivationChangeObserver: - void OnWindowActivated(aura::Window* gained_active, + void OnWindowActivated(ActivationReason reason, + aura::Window* gained_active, aura::Window* lost_active) override { + last_activation_reason_ = reason; ++activation_changed_count_; } void OnAttemptToReactivateWindow(aura::Window* request_active, @@ -73,6 +79,7 @@ class FocusNotificationObserver : public aura::client::ActivationChangeObserver, ++focus_changed_count_; } + ActivationReason last_activation_reason_; int activation_changed_count_; int focus_changed_count_; int reactivation_count_; @@ -115,7 +122,8 @@ class RecordingActivationAndFocusChangeObserver } // Overridden from aura::client::ActivationChangeObserver: - void OnWindowActivated(aura::Window* gained_active, + void OnWindowActivated(ActivationReason reason, + aura::Window* gained_active, aura::Window* lost_active) override { if (lost_active && lost_active == deleter_->GetDeletedWindow()) was_notified_with_deleted_window_ = true; @@ -158,7 +166,8 @@ class DeleteOnLoseActivationChangeObserver : } // Overridden from aura::client::ActivationChangeObserver: - void OnWindowActivated(aura::Window* gained_active, + void OnWindowActivated(ActivationReason reason, + aura::Window* gained_active, aura::Window* lost_active) override { if (window_ && lost_active == window_) { delete lost_active; @@ -303,7 +312,8 @@ class FocusShiftingActivationObserver private: // Overridden from aura::client::ActivationChangeObserver: - void OnWindowActivated(aura::Window* gained_active, + void OnWindowActivated(ActivationReason reason, + aura::Window* gained_active, aura::Window* lost_active) override { // Shift focus to a child. This should prevent the default focusing from // occurring in FocusController::FocusWindow(). @@ -499,6 +509,11 @@ class FocusControllerDirectTestBase : public FocusControllerTestBase { // Input events do not change focus if the window can not be focused. virtual bool IsInputEvent() = 0; + // Returns the expected ActivationReason caused by calling the + // ActivatedWindowDirect(...) or DeactivateWindowDirect(...) methods. + virtual aura::client::ActivationChangeObserver::ActivationReason + GetExpectedActivationReason() const = 0; + void FocusWindowById(int id) { aura::Window* window = root_window()->GetChildById(id); DCHECK(window); @@ -579,6 +594,8 @@ class FocusControllerDirectTestBase : public FocusControllerTestBase { ActivateWindowById(2); root_observer.ExpectCounts(1, 1); + EXPECT_EQ(GetExpectedActivationReason(), + root_observer.last_activation_reason()); observer1.ExpectCounts(1, 1); observer2.ExpectCounts(1, 1); } @@ -895,6 +912,12 @@ class FocusControllerApiTest : public FocusControllerDirectTestBase { DeactivateWindow(window); } bool IsInputEvent() override { return false; } + // Overridden from FocusControllerDirectTestBase: + aura::client::ActivationChangeObserver::ActivationReason + GetExpectedActivationReason() const override { + return aura::client::ActivationChangeObserver::ActivationReason:: + ACTIVATION_CLIENT; + } DISALLOW_COPY_AND_ASSIGN(FocusControllerApiTest); }; @@ -937,7 +960,13 @@ class FocusControllerMouseEventTest : public FocusControllerDirectTestBase { ui::test::EventGenerator generator(root_window(), next_activatable); generator.ClickLeftButton(); } + // Overridden from FocusControllerDirectTestBase: bool IsInputEvent() override { return true; } + aura::client::ActivationChangeObserver::ActivationReason + GetExpectedActivationReason() const override { + return aura::client::ActivationChangeObserver::ActivationReason:: + INPUT_EVENT; + } DISALLOW_COPY_AND_ASSIGN(FocusControllerMouseEventTest); }; @@ -963,6 +992,11 @@ class FocusControllerGestureEventTest : public FocusControllerDirectTestBase { generator.GestureTapAt(window->bounds().CenterPoint()); } bool IsInputEvent() override { return true; } + aura::client::ActivationChangeObserver::ActivationReason + GetExpectedActivationReason() const override { + return aura::client::ActivationChangeObserver::ActivationReason:: + INPUT_EVENT; + } DISALLOW_COPY_AND_ASSIGN(FocusControllerGestureEventTest); }; @@ -978,6 +1012,14 @@ class FocusControllerImplicitTestBase : public FocusControllerTestBase { return parent_ ? window->parent() : window; } + // Returns the expected ActivationReason caused by calling the + // ActivatedWindowDirect(...) or DeactivateWindowDirect(...) methods. + aura::client::ActivationChangeObserver::ActivationReason + GetExpectedActivationReason() const { + return aura::client::ActivationChangeObserver::ActivationReason:: + WINDOW_DISPOSITION_CHANGED; + } + // Change the disposition of |window| in such a way as it will lose focus. virtual void ChangeWindowDisposition(aura::Window* window) = 0; @@ -1038,6 +1080,8 @@ class FocusControllerImplicitTestBase : public FocusControllerTestBase { ChangeWindowDisposition(w2); root_observer.ExpectCounts(1, 1); + EXPECT_EQ(GetExpectedActivationReason(), + root_observer.last_activation_reason()); observer2.ExpectCounts(1, 1); observer3.ExpectCounts(1, 1); } diff --git a/ui/wm/core/shadow_controller.cc b/ui/wm/core/shadow_controller.cc index 9ba88d3..1e5dd49 100644 --- a/ui/wm/core/shadow_controller.cc +++ b/ui/wm/core/shadow_controller.cc @@ -113,7 +113,8 @@ class ShadowController::Impl : ~Impl() override; // Forwarded from ShadowController. - void OnWindowActivated(aura::Window* gained_active, + void OnWindowActivated(ActivationReason reason, + aura::Window* gained_active, aura::Window* lost_active); // Checks if |window| is visible and contains a property requesting a shadow. @@ -183,7 +184,8 @@ void ShadowController::Impl::OnWindowDestroyed(aura::Window* window) { observer_manager_.Remove(window); } -void ShadowController::Impl::OnWindowActivated(aura::Window* gained_active, +void ShadowController::Impl::OnWindowActivated(ActivationReason reason, + aura::Window* gained_active, aura::Window* lost_active) { if (gained_active) { Shadow* shadow = GetShadowForWindow(gained_active); @@ -271,9 +273,10 @@ ShadowController::~ShadowController() { activation_client_->RemoveObserver(this); } -void ShadowController::OnWindowActivated(aura::Window* gained_active, +void ShadowController::OnWindowActivated(ActivationReason reason, + aura::Window* gained_active, aura::Window* lost_active) { - impl_->OnWindowActivated(gained_active, lost_active); + impl_->OnWindowActivated(reason, gained_active, lost_active); } // ShadowController::TestApi --------------------------------------------------- diff --git a/ui/wm/core/shadow_controller.h b/ui/wm/core/shadow_controller.h index 360a997..b307c02 100644 --- a/ui/wm/core/shadow_controller.h +++ b/ui/wm/core/shadow_controller.h @@ -51,8 +51,10 @@ class WM_EXPORT ShadowController : ~ShadowController() override; // aura::client::ActivationChangeObserver overrides: - void OnWindowActivated(aura::Window* gained_active, - aura::Window* lost_active) override; + void OnWindowActivated( + aura::client::ActivationChangeObserver::ActivationReason reason, + aura::Window* gained_active, + aura::Window* lost_active) override; private: class Impl; diff --git a/ui/wm/public/activation_change_observer.h b/ui/wm/public/activation_change_observer.h index 68d5b8a..57f9d27 100644 --- a/ui/wm/public/activation_change_observer.h +++ b/ui/wm/public/activation_change_observer.h @@ -14,11 +14,23 @@ namespace client { class AURA_EXPORT ActivationChangeObserver { public: - // Called when |active| gains focus, or there is no active window - // (|active| is NULL in this case.) |old_active| refers to the + // The reason or cause of a window activation change. + enum class ActivationReason { + // When a window is activated due to a call to the ActivationClient API. + ACTIVATION_CLIENT, + // When a user clicks or taps a window in the 2-dimensional screen space. + INPUT_EVENT, + // When a new window is activated as a side effect of a window + // disposition changing. + WINDOW_DISPOSITION_CHANGED, + }; + + // Called when |gained_active| gains focus, or there is no active window + // (|gained_active| is NULL in this case.) |lost_active| refers to the // previous active window or NULL if there was no previously active - // window. - virtual void OnWindowActivated(Window* gained_active, + // window. |reason| specifies the cause of the activation change. + virtual void OnWindowActivated(ActivationReason reason, + Window* gained_active, Window* lost_active) = 0; // Called when during window activation the currently active window is |