diff options
author | yukishiino@chromium.org <yukishiino@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-08 23:51:52 +0000 |
---|---|---|
committer | yukishiino@chromium.org <yukishiino@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-08 23:51:52 +0000 |
commit | 8f374cee60e9d94a67f033e5573a948c87111251 (patch) | |
tree | 0770abe27fca8d61bf80d19d88c949f1ca5e15b6 /ui/wm/core | |
parent | 3ec9ed0d6beebbf753cc71c7a1d169af097c1cf9 (diff) | |
download | chromium_src-8f374cee60e9d94a67f033e5573a948c87111251.zip chromium_src-8f374cee60e9d94a67f033e5573a948c87111251.tar.gz chromium_src-8f374cee60e9d94a67f033e5573a948c87111251.tar.bz2 |
Redesigns the text input focus handling.
Introduces the new focus handling of text input behind a flag. Unless the flag is enabled, the behavior doesn't change. Once we confirm that the new design works well, we will remove the old text input focus handling code.
Here is a document that describes the approach.
https://docs.google.com/document/d/1tTcJJqh2SE8-9mEHjEzbILa_ebH96B9LCVKMuZ2p6gw/edit?usp=sharing
Notable change in ui/views/widget/desktop_aura/x11_desktop_handler.cc
The timing to update |current_window_| is changed so that the active widget has been changed before a callback function HandleNativeWidgetActivationChanged() is called.
In the new design, the active widget's focus manager controls the text input focus, so it's important that the active widget has been updated before HandleNativeWidgetActivationChanged gets called.
BUG=290701
TEST=Run chrome with --enable-text-input-focus-manager and ensure that text input in the omnibox, find bar, bookmark bubble, bookmark edit dialog, and web content work as expected when you change the text input focus by mouse clicks or tab key, also when you change the active window from/to other windows.
Review URL: https://codereview.chromium.org/173803002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269106 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/wm/core')
-rw-r--r-- | ui/wm/core/focus_controller.cc | 14 | ||||
-rw-r--r-- | ui/wm/core/focus_controller_unittest.cc | 61 |
2 files changed, 75 insertions, 0 deletions
diff --git a/ui/wm/core/focus_controller.cc b/ui/wm/core/focus_controller.cc index f4d3f3f..37af32e 100644 --- a/ui/wm/core/focus_controller.cc +++ b/ui/wm/core/focus_controller.cc @@ -10,6 +10,7 @@ #include "ui/aura/client/focus_change_observer.h" #include "ui/aura/env.h" #include "ui/aura/window_tracker.h" +#include "ui/base/ime/text_input_focus_manager.h" #include "ui/events/event.h" #include "ui/wm/core/focus_rules.h" #include "ui/wm/core/window_util.h" @@ -230,6 +231,15 @@ void FocusController::SetFocusedWindow(aura::Window* window) { base::AutoReset<bool> updating_focus(&updating_focus_, true); aura::Window* lost_focus = focused_window_; + + // |window| is going to get the focus, so reset the text input client. + // OnWindowFocused() may set a proper text input client if the implementation + // supports text input. + ui::TextInputFocusManager* text_input_focus_manager = + ui::TextInputFocusManager::GetInstance(); + if (window) + text_input_focus_manager->FocusTextInputClient(NULL); + // Allow for the window losing focus to be deleted during dispatch. If it is // deleted pass NULL to observers instead of a deleted window. aura::WindowTracker window_tracker; @@ -261,6 +271,10 @@ void FocusController::SetFocusedWindow(aura::Window* window) { focused_window_, window_tracker.Contains(lost_focus) ? lost_focus : NULL); } + + // Ensure that the text input client is reset when the window loses the focus. + if (!window) + text_input_focus_manager->FocusTextInputClient(NULL); } void FocusController::SetActiveWindow(aura::Window* requested_window, diff --git a/ui/wm/core/focus_controller_unittest.cc b/ui/wm/core/focus_controller_unittest.cc index d460100..d3b8183 100644 --- a/ui/wm/core/focus_controller_unittest.cc +++ b/ui/wm/core/focus_controller_unittest.cc @@ -16,6 +16,8 @@ #include "ui/aura/window.h" #include "ui/aura/window_event_dispatcher.h" #include "ui/aura/window_tracker.h" +#include "ui/base/ime/dummy_text_input_client.h" +#include "ui/base/ime/text_input_focus_manager.h" #include "ui/events/event_handler.h" #include "ui/wm/core/base_focus_rules.h" #include "ui/wm/core/wm_state.h" @@ -252,6 +254,25 @@ class ScopedTargetFocusNotificationObserver : public FocusNotificationObserver { DISALLOW_COPY_AND_ASSIGN(ScopedTargetFocusNotificationObserver); }; +class ScopedFocusedTextInputClientChanger + : public ScopedFocusNotificationObserver { + public: + ScopedFocusedTextInputClientChanger(aura::Window* root_window, + ui::TextInputClient* text_input_client) + : ScopedFocusNotificationObserver(root_window), + text_input_client_(text_input_client) {} + + private: + // Overridden from aura::client::FocusChangeObserver: + virtual void OnWindowFocused(aura::Window* gained_focus, + aura::Window* lost_focus) OVERRIDE { + ui::TextInputFocusManager::GetInstance()->FocusTextInputClient( + text_input_client_); + } + + ui::TextInputClient* text_input_client_; +}; + class FocusShiftingActivationObserver : public aura::client::ActivationChangeObserver { public: @@ -442,6 +463,7 @@ class FocusControllerTestBase : public aura::test::AuraTestBase { virtual void NoFocusChangeOnClickOnCaptureWindow() {} virtual void ChangeFocusWhenNothingFocusedAndCaptured() {} virtual void DontPassDeletedWindow() {} + virtual void FocusedTextInputClient() {} private: scoped_ptr<FocusController> focus_controller_; @@ -795,6 +817,41 @@ class FocusControllerDirectTestBase : public FocusControllerTestBase { } } + // Verifies if the focused text input client is cleared when a window gains + // or loses the focus. + virtual void FocusedTextInputClient() OVERRIDE { + ui::TextInputFocusManager* text_input_focus_manager = + ui::TextInputFocusManager::GetInstance(); + ui::DummyTextInputClient text_input_client; + ui::TextInputClient* null_text_input_client = NULL; + + EXPECT_EQ(null_text_input_client, + text_input_focus_manager->GetFocusedTextInputClient()); + + text_input_focus_manager->FocusTextInputClient(&text_input_client); + EXPECT_EQ(&text_input_client, + text_input_focus_manager->GetFocusedTextInputClient()); + FocusWindowById(1); + // The focused text input client gets cleared when a window gets focused + // unless any of observers sets the focused text input client. + EXPECT_EQ(null_text_input_client, + text_input_focus_manager->GetFocusedTextInputClient()); + + ScopedFocusedTextInputClientChanger text_input_focus_changer( + root_window(), &text_input_client); + EXPECT_EQ(null_text_input_client, + text_input_focus_manager->GetFocusedTextInputClient()); + FocusWindowById(2); + // |text_input_focus_changer| sets the focused text input client. + EXPECT_EQ(&text_input_client, + text_input_focus_manager->GetFocusedTextInputClient()); + + FocusWindow(NULL); + // The focused text input client gets cleared when a window loses the focus. + EXPECT_EQ(null_text_input_client, + text_input_focus_manager->GetFocusedTextInputClient()); + } + private: DISALLOW_COPY_AND_ASSIGN(FocusControllerDirectTestBase); }; @@ -1181,4 +1238,8 @@ FOCUS_CONTROLLER_TEST(FocusControllerApiTest, // See description above DontPassDeletedWindow() for details. FOCUS_CONTROLLER_TEST(FocusControllerApiTest, DontPassDeletedWindow); +// - Verifies that the focused text input client is cleard when the window focus +// changes. +ALL_FOCUS_TESTS(FocusedTextInputClient); + } // namespace wm |