summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbryeung@chromium.org <bryeung@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-17 12:32:51 +0000
committerbryeung@chromium.org <bryeung@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-17 12:32:51 +0000
commite0f71136250261a6bb464dd56edbe549dbd9fa5a (patch)
treee67ed33152ac2df76e7a6711393afd03f9f1d508
parenta8126e8c6c7b5e8fbed2c7c161a567dc81a93a92 (diff)
downloadchromium_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.cc1
-rw-r--r--chrome/browser/chromeos/input_method/textinput_test_helper.cc4
-rw-r--r--chrome/browser/chromeos/input_method/textinput_test_helper.h2
-rw-r--r--ui/base/ime/input_method_base.cc3
-rw-r--r--ui/base/ime/input_method_observer.h4
-rw-r--r--ui/base/ime/mock_input_method.h1
-rw-r--r--ui/keyboard/keyboard_controller.cc117
-rw-r--r--ui/keyboard/keyboard_controller.h20
-rw-r--r--ui/keyboard/keyboard_controller_unittest.cc62
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());