diff options
author | bryeung@chromium.org <bryeung@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-17 12:32:51 +0000 |
---|---|---|
committer | bryeung@chromium.org <bryeung@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-17 12:32:51 +0000 |
commit | e0f71136250261a6bb464dd56edbe549dbd9fa5a (patch) | |
tree | e67ed33152ac2df76e7a6711393afd03f9f1d508 | |
parent | a8126e8c6c7b5e8fbed2c7c161a567dc81a93a92 (diff) | |
download | chromium_src-e0f71136250261a6bb464dd56edbe549dbd9fa5a.zip chromium_src-e0f71136250261a6bb464dd56edbe549dbd9fa5a.tar.gz chromium_src-e0f71136250261a6bb464dd56edbe549dbd9fa5a.tar.bz2 |
Delayed loading of the virtual keyboard.
Don't create the virtual keyboard until it is first shown. This helps
prevent some start-up races.
Also clean-up some of the object ownership between KeyboardController
and KeyboardLayoutManager. Each pointer exists in only one or the
other object now.
BUG=none
Review URL: https://codereview.chromium.org/13932030
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@194580 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ash/root_window_controller.cc | 1 | ||||
-rw-r--r-- | chrome/browser/chromeos/input_method/textinput_test_helper.cc | 4 | ||||
-rw-r--r-- | chrome/browser/chromeos/input_method/textinput_test_helper.h | 2 | ||||
-rw-r--r-- | ui/base/ime/input_method_base.cc | 3 | ||||
-rw-r--r-- | ui/base/ime/input_method_observer.h | 4 | ||||
-rw-r--r-- | ui/base/ime/mock_input_method.h | 1 | ||||
-rw-r--r-- | ui/keyboard/keyboard_controller.cc | 117 | ||||
-rw-r--r-- | ui/keyboard/keyboard_controller.h | 20 | ||||
-rw-r--r-- | ui/keyboard/keyboard_controller_unittest.cc | 62 |
9 files changed, 128 insertions, 86 deletions
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc index 6cefecc..6a8e815 100644 --- a/ash/root_window_controller.cc +++ b/ash/root_window_controller.cc @@ -512,6 +512,7 @@ void RootWindowController::InitKeyboard() { aura::Window* keyboard_container = keyboard_controller_->GetContainerWindow(); parent->AddChild(keyboard_container); + keyboard_container->SetBounds(parent->bounds()); } } diff --git a/chrome/browser/chromeos/input_method/textinput_test_helper.cc b/chrome/browser/chromeos/input_method/textinput_test_helper.cc index 7ddc0c3..2bf5712 100644 --- a/chrome/browser/chromeos/input_method/textinput_test_helper.cc +++ b/chrome/browser/chromeos/input_method/textinput_test_helper.cc @@ -78,6 +78,10 @@ void TextInputTestHelper::OnTextInputTypeChanged( MessageLoop::current()->Quit(); } +void TextInputTestHelper::OnInputMethodDestroyed( + const ui::InputMethod* input_method) { +} + void TextInputTestHelper::OnFocus() { focus_state_ = true; if (waiting_type_ == WAIT_ON_FOCUS) diff --git a/chrome/browser/chromeos/input_method/textinput_test_helper.h b/chrome/browser/chromeos/input_method/textinput_test_helper.h index d6aa8e7..27b4085 100644 --- a/chrome/browser/chromeos/input_method/textinput_test_helper.h +++ b/chrome/browser/chromeos/input_method/textinput_test_helper.h @@ -78,6 +78,8 @@ class TextInputTestHelper : public ui::MockInputMethod::Observer { virtual void OnCaretBoundsChanged(const ui::TextInputClient* client) OVERRIDE; virtual void OnTextInputStateChanged( const ui::TextInputClient* client) OVERRIDE; + virtual void OnInputMethodDestroyed( + const ui::InputMethod* input_method) OVERRIDE; // Represents waiting type of text input event. WaitImeEventType waiting_type_; diff --git a/ui/base/ime/input_method_base.cc b/ui/base/ime/input_method_base.cc index 934efe3..6972eed 100644 --- a/ui/base/ime/input_method_base.cc +++ b/ui/base/ime/input_method_base.cc @@ -18,6 +18,9 @@ InputMethodBase::InputMethodBase() } InputMethodBase::~InputMethodBase() { + FOR_EACH_OBSERVER(InputMethodObserver, + observer_list_, + OnInputMethodDestroyed(this)); } void InputMethodBase::SetDelegate(internal::InputMethodDelegate* delegate) { diff --git a/ui/base/ime/input_method_observer.h b/ui/base/ime/input_method_observer.h index 84de8af..195da9c 100644 --- a/ui/base/ime/input_method_observer.h +++ b/ui/base/ime/input_method_observer.h @@ -9,6 +9,7 @@ namespace ui { +class InputMethod; class TextInputClient; class UI_EXPORT InputMethodObserver { @@ -19,6 +20,9 @@ class UI_EXPORT InputMethodObserver { // - the TextInputClient is changed (e.g. by a change of focus) // - the TextInputType of the TextInputClient changes virtual void OnTextInputStateChanged(const TextInputClient* client) = 0; + + // Called when the observed InputMethod is being destroyed. + virtual void OnInputMethodDestroyed(const InputMethod* input_method) = 0; }; } // namespace ui diff --git a/ui/base/ime/mock_input_method.h b/ui/base/ime/mock_input_method.h index 5c67027..aaaab11 100644 --- a/ui/base/ime/mock_input_method.h +++ b/ui/base/ime/mock_input_method.h @@ -34,6 +34,7 @@ class UI_EXPORT MockInputMethod : NON_EXPORTED_BASE(public InputMethod) { // InputMethodObserver overrides virtual void OnTextInputStateChanged(const TextInputClient* client) = 0; + virtual void OnInputMethodDestroyed(const InputMethod* input_method) = 0; }; explicit MockInputMethod(internal::InputMethodDelegate* delegate); virtual ~MockInputMethod(); diff --git a/ui/keyboard/keyboard_controller.cc b/ui/keyboard/keyboard_controller.cc index cdecdc3..c948ca0 100644 --- a/ui/keyboard/keyboard_controller.cc +++ b/ui/keyboard/keyboard_controller.cc @@ -9,7 +9,6 @@ #include "ui/aura/window_delegate.h" #include "ui/base/hit_test.h" #include "ui/base/ime/input_method.h" -#include "ui/base/ime/input_method_base.h" #include "ui/base/ime/text_input_client.h" #include "ui/base/ime/text_input_type.h" #include "ui/gfx/path.h" @@ -28,38 +27,6 @@ gfx::Rect KeyboardBoundsFromWindowBounds(const gfx::Rect& window_bounds) { window_bounds.height() * kKeyboardHeightRatio); } -// LayoutManager for the virtual keyboard container. Manages a single window -// (the virtual keyboard) and keeps it positioned at the bottom of the -// container window. -class KeyboardLayoutManager : public aura::LayoutManager { - public: - KeyboardLayoutManager(aura::Window* owner, aura::Window* keyboard) - : owner_(owner), keyboard_(keyboard) {} - - // Overridden from aura::LayoutManager - virtual void OnWindowResized() OVERRIDE { - SetChildBoundsDirect(keyboard_, - KeyboardBoundsFromWindowBounds(owner_->bounds())); - } - virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE { - CHECK(child == keyboard_); - } - virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE {} - virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE {} - virtual void OnChildWindowVisibilityChanged(aura::Window* child, - bool visible) OVERRIDE {} - virtual void SetChildBounds(aura::Window* child, - const gfx::Rect& requested_bounds) OVERRIDE { - // Drop these: the size should only be set in OnWindowResized. - } - - private: - aura::Window* owner_; - aura::Window* keyboard_; - - DISALLOW_COPY_AND_ASSIGN(KeyboardLayoutManager); -}; - // The KeyboardWindowDelegate makes sure the keyboard-window does not get focus. // This is necessary to make sure that the synthetic key-events reach the target // window. @@ -110,16 +77,57 @@ class KeyboardWindowDelegate : public aura::WindowDelegate { namespace keyboard { +// LayoutManager for the virtual keyboard container. Manages a single window +// (the virtual keyboard) and keeps it positioned at the bottom of the +// owner window. +class KeyboardLayoutManager : public aura::LayoutManager { + public: + KeyboardLayoutManager(aura::Window* container) + : container_(container), keyboard_(NULL) { + CHECK(container_); + } + + // Overridden from aura::LayoutManager + virtual void OnWindowResized() OVERRIDE { + if (!keyboard_) + return; + SetChildBoundsDirect(keyboard_, + KeyboardBoundsFromWindowBounds(container_->bounds())); + } + virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE { + DCHECK(!keyboard_); + keyboard_ = child; + } + virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE {} + virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE {} + virtual void OnChildWindowVisibilityChanged(aura::Window* child, + bool visible) OVERRIDE {} + virtual void SetChildBounds(aura::Window* child, + const gfx::Rect& requested_bounds) OVERRIDE { + // Drop these: the size should only be set in OnWindowResized. + } + + private: + aura::Window* container_; + aura::Window* keyboard_; + + DISALLOW_COPY_AND_ASSIGN(KeyboardLayoutManager); +}; + KeyboardController::KeyboardController(KeyboardControllerProxy* proxy) - : proxy_(proxy), container_(NULL) { + : proxy_(proxy), + container_(NULL), + input_method_(NULL) { CHECK(proxy); - proxy_->GetInputMethod()->AddObserver(this); + input_method_ = proxy_->GetInputMethod(); + input_method_->AddObserver(this); } KeyboardController::~KeyboardController() { if (container_) container_->RemoveObserver(this); - proxy_->GetInputMethod()->RemoveObserver(this); + if (input_method_) + input_method_->RemoveObserver(this); } aura::Window* KeyboardController::GetContainerWindow() { @@ -128,17 +136,21 @@ aura::Window* KeyboardController::GetContainerWindow() { container_->SetName("KeyboardContainer"); container_->Init(ui::LAYER_NOT_DRAWN); container_->AddObserver(this); - - aura::Window* keyboard = proxy_->GetKeyboardWindow(); - keyboard->Show(); - - container_->SetLayoutManager( - new KeyboardLayoutManager(container_, keyboard)); - container_->AddChild(keyboard); + container_->SetLayoutManager(new KeyboardLayoutManager(container_)); } return container_; } +void KeyboardController::OnWindowParentChanged(aura::Window* window, + aura::Window* parent) { + OnTextInputStateChanged(proxy_->GetInputMethod()->GetTextInputClient()); +} + +void KeyboardController::OnWindowDestroying(aura::Window* window) { + DCHECK_EQ(container_, window); + container_ = NULL; +} + void KeyboardController::OnTextInputStateChanged( const ui::TextInputClient* client) { if (!container_) @@ -147,23 +159,24 @@ void KeyboardController::OnTextInputStateChanged( if (!client || client->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) { container_->Hide(); } else { + if (container_->children().empty()) { + aura::Window* keyboard = proxy_->GetKeyboardWindow(); + keyboard->Show(); + container_->AddChild(keyboard); + container_->layout_manager()->OnWindowResized(); + } container_->parent()->StackChildAtTop(container_); container_->Show(); } - // TODO(bryeung): whenever the TextInputClient changes we need to notify the // keyboard (with the TextInputType) so that it can reset it's state (e.g. // abandon compositions in progress) } -void KeyboardController::OnWindowParentChanged(aura::Window* window, - aura::Window* parent) { - OnTextInputStateChanged(proxy_->GetInputMethod()->GetTextInputClient()); -} - -void KeyboardController::OnWindowDestroying(aura::Window* window) { - DCHECK_EQ(container_, window); - container_ = NULL; +void KeyboardController::OnInputMethodDestroyed( + const ui::InputMethod* input_method) { + DCHECK_EQ(input_method_, input_method); + input_method_ = NULL; } } // namespace keyboard diff --git a/ui/keyboard/keyboard_controller.h b/ui/keyboard/keyboard_controller.h index 1a2b182..ca7d0ad 100644 --- a/ui/keyboard/keyboard_controller.h +++ b/ui/keyboard/keyboard_controller.h @@ -16,15 +16,17 @@ class Window; } namespace ui { +class InputMethod; class TextInputClient; } namespace keyboard { class KeyboardControllerProxy; +class KeyboardLayoutManager; -// Provides control of the virtual keyboard, including providing a container, -// managing object lifetimes and controlling visibility. +// Provides control of the virtual keyboard, including providing a container +// and controlling visibility. class KEYBOARD_EXPORT KeyboardController : public ui::InputMethodObserver, public aura::WindowObserver { public: @@ -36,18 +38,24 @@ class KEYBOARD_EXPORT KeyboardController : public ui::InputMethodObserver, // It is the responsibility of the caller to Show() the returned window. aura::Window* GetContainerWindow(); - // InputMethodObserver overrides - virtual void OnTextInputStateChanged( - const ui::TextInputClient* client) OVERRIDE; - private: + // For access to Observer methods for simulation. + friend class KeyboardControllerTest; + // aura::WindowObserver overrides virtual void OnWindowParentChanged(aura::Window* window, aura::Window* parent) OVERRIDE; virtual void OnWindowDestroying(aura::Window* window) OVERRIDE; + // InputMethodObserver overrides + virtual void OnTextInputStateChanged( + const ui::TextInputClient* client) OVERRIDE; + virtual void OnInputMethodDestroyed( + const ui::InputMethod* input_method) OVERRIDE; + scoped_ptr<KeyboardControllerProxy> proxy_; aura::Window* container_; + ui::InputMethod* input_method_; DISALLOW_COPY_AND_ASSIGN(KeyboardController); }; diff --git a/ui/keyboard/keyboard_controller_unittest.cc b/ui/keyboard/keyboard_controller_unittest.cc index d49136e..dd9eb60 100644 --- a/ui/keyboard/keyboard_controller_unittest.cc +++ b/ui/keyboard/keyboard_controller_unittest.cc @@ -49,33 +49,6 @@ class TestFocusController : public ui::EventHandler { DISALLOW_COPY_AND_ASSIGN(TestFocusController); }; -class KeyboardControllerTest : public testing::Test { - public: - KeyboardControllerTest() {} - virtual ~KeyboardControllerTest() {} - - virtual void SetUp() OVERRIDE { - aura_test_helper_.reset(new aura::test::AuraTestHelper(&message_loop_)); - aura_test_helper_->SetUp(); - ui::SetUpInputMethodFactoryForTesting(); - focus_controller_.reset(new TestFocusController(root_window())); - } - - virtual void TearDown() OVERRIDE { - aura_test_helper_->TearDown(); - } - - aura::RootWindow* root_window() { return aura_test_helper_->root_window(); } - - protected: - base::MessageLoopForUI message_loop_; - scoped_ptr<aura::test::AuraTestHelper> aura_test_helper_; - scoped_ptr<TestFocusController> focus_controller_; - - private: - DISALLOW_COPY_AND_ASSIGN(KeyboardControllerTest); -}; - class TestKeyboardControllerProxy : public KeyboardControllerProxy { public: TestKeyboardControllerProxy() @@ -176,6 +149,38 @@ class TestTextInputClient : public ui::TextInputClient { } // namespace +class KeyboardControllerTest : public testing::Test { + public: + KeyboardControllerTest() {} + virtual ~KeyboardControllerTest() {} + + virtual void SetUp() OVERRIDE { + aura_test_helper_.reset(new aura::test::AuraTestHelper(&message_loop_)); + aura_test_helper_->SetUp(); + ui::SetUpInputMethodFactoryForTesting(); + focus_controller_.reset(new TestFocusController(root_window())); + } + + virtual void TearDown() OVERRIDE { + aura_test_helper_->TearDown(); + } + + aura::RootWindow* root_window() { return aura_test_helper_->root_window(); } + + void ShowKeyboard(KeyboardController* controller) { + TestTextInputClient test_text_input_client(ui::TEXT_INPUT_TYPE_TEXT); + controller->OnTextInputStateChanged(&test_text_input_client); + } + + protected: + base::MessageLoopForUI message_loop_; + scoped_ptr<aura::test::AuraTestHelper> aura_test_helper_; + scoped_ptr<TestFocusController> focus_controller_; + + private: + DISALLOW_COPY_AND_ASSIGN(KeyboardControllerTest); +}; + TEST_F(KeyboardControllerTest, KeyboardSize) { KeyboardControllerProxy* proxy = new TestKeyboardControllerProxy(); KeyboardController controller(proxy); @@ -214,7 +219,8 @@ TEST_F(KeyboardControllerTest, ClickDoesNotFocusKeyboard) { root_window()->AddChild(keyboard_container.get()); keyboard_container->Show(); - root_window()->StackChildAtTop(keyboard_container.get()); + ShowKeyboard(&controller); + EXPECT_TRUE(window->IsVisible()); EXPECT_TRUE(keyboard_container->IsVisible()); EXPECT_TRUE(window->HasFocus()); |