summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryusukes@google.com <yusukes@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-02 05:21:00 +0000
committeryusukes@google.com <yusukes@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-02 05:21:00 +0000
commite7bbbb61858e2029ecd216c5ea587e17f2ae9f9e (patch)
treefa408dd8d019278de83fbdef2ea64afd6811e7de
parent6da840ffba5ed810fadc8b1fe3edf65a2c65392b (diff)
downloadchromium_src-e7bbbb61858e2029ecd216c5ea587e17f2ae9f9e.zip
chromium_src-e7bbbb61858e2029ecd216c5ea587e17f2ae9f9e.tar.gz
chromium_src-e7bbbb61858e2029ecd216c5ea587e17f2ae9f9e.tar.bz2
Reduce CPU usage for input method switching.
- Move GetNumActiveInputMethods call from input_method_menu_button.cc to input_method_library.cc so that the IBus function is called only once even when multiple Chrome windows are available. - Improved InputMethodMenu::InputMethodChanged so that only the first input method button would update Preferences. - Remove ImePropertiesChanged callback. It's obsolete. BUG=chromium-os:8553 TEST=manually. Review URL: http://codereview.chromium.org/4162002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@67973 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chromeos/cros/input_method_library.cc28
-rw-r--r--chrome/browser/chromeos/cros/input_method_library.h21
-rw-r--r--chrome/browser/chromeos/login/keyboard_switch_menu.cc6
-rw-r--r--chrome/browser/chromeos/login/keyboard_switch_menu.h6
-rw-r--r--chrome/browser/chromeos/status/input_method_menu.cc35
-rw-r--r--chrome/browser/chromeos/status/input_method_menu.h25
-rw-r--r--chrome/browser/chromeos/status/input_method_menu_button.cc36
-rw-r--r--chrome/browser/chromeos/status/input_method_menu_button.h6
8 files changed, 117 insertions, 46 deletions
diff --git a/chrome/browser/chromeos/cros/input_method_library.cc b/chrome/browser/chromeos/cros/input_method_library.cc
index 1e6f15a..9b5316f 100644
--- a/chrome/browser/chromeos/cros/input_method_library.cc
+++ b/chrome/browser/chromeos/cros/input_method_library.cc
@@ -23,6 +23,7 @@
#include "chrome/common/notification_service.h"
namespace {
+
const char kIBusDaemonPath[] = "/usr/bin/ibus-daemon";
const char kCandidateWindowPath[] = "/opt/google/chrome/candidate_window";
@@ -290,7 +291,11 @@ class InputMethodLibraryImpl : public InputMethodLibrary,
}
if (active_input_methods_are_changed) {
- FOR_EACH_OBSERVER(Observer, observers_, ActiveInputMethodsChanged(this));
+ const size_t num_active_input_methods = GetNumActiveInputMethods();
+ FOR_EACH_OBSERVER(Observer, observers_,
+ ActiveInputMethodsChanged(this,
+ current_input_method_,
+ num_active_input_methods));
}
}
@@ -386,13 +391,29 @@ class InputMethodLibraryImpl : public InputMethodLibrary,
previous_input_method_ = current_input_method_;
current_input_method_ = new_input_method;
}
- FOR_EACH_OBSERVER(Observer, observers_, InputMethodChanged(this));
+ const size_t num_active_input_methods = GetNumActiveInputMethods();
+ FOR_EACH_OBSERVER(Observer, observers_,
+ InputMethodChanged(this,
+ previous_input_method_,
+ current_input_method_,
+ num_active_input_methods));
+
+ // Ask the first observer to update preferences. We should not ask every
+ // observer to do so. Otherwise, we'll end up updating preferences many
+ // times when many observers are attached (ex. many windows are opened),
+ // which is unnecessary and expensive.
+ ObserverListBase<Observer>::Iterator it(observers_);
+ Observer* first_observer = it.GetNext();
+ if (first_observer) {
+ first_observer->PreferenceUpdateNeeded(this,
+ previous_input_method_,
+ current_input_method_);
+ }
}
void RegisterProperties(const ImePropertyList& prop_list) {
// |prop_list| might be empty. This means "clear all properties."
current_ime_properties_ = prop_list;
- FOR_EACH_OBSERVER(Observer, observers_, ImePropertiesChanged(this));
}
void StartInputMethodProcesses() {
@@ -404,7 +425,6 @@ class InputMethodLibraryImpl : public InputMethodLibrary,
for (size_t i = 0; i < prop_list.size(); ++i) {
FindAndUpdateProperty(prop_list[i], &current_ime_properties_);
}
- FOR_EACH_OBSERVER(Observer, observers_, ImePropertiesChanged(this));
}
// Launches an input method procsess specified by the given command
diff --git a/chrome/browser/chromeos/cros/input_method_library.h b/chrome/browser/chromeos/cros/input_method_library.h
index f3bbe3c..7f55eea 100644
--- a/chrome/browser/chromeos/cros/input_method_library.h
+++ b/chrome/browser/chromeos/cros/input_method_library.h
@@ -26,14 +26,23 @@ class InputMethodLibrary {
public:
virtual ~Observer() = 0;
// Called when the current input method is changed.
- virtual void InputMethodChanged(InputMethodLibrary* obj) = 0;
-
- // Called when input method properties (see chromeos_input_method.h
- // for details) are changed.
- virtual void ImePropertiesChanged(InputMethodLibrary* obj) = 0;
+ virtual void InputMethodChanged(
+ InputMethodLibrary* obj,
+ const InputMethodDescriptor& previous_input_method,
+ const InputMethodDescriptor& current_input_method,
+ size_t num_active_input_methods) = 0;
// Called when the active input methods are changed.
- virtual void ActiveInputMethodsChanged(InputMethodLibrary* obj) = 0;
+ virtual void ActiveInputMethodsChanged(
+ InputMethodLibrary* obj,
+ const InputMethodDescriptor& current_input_method,
+ size_t num_active_input_methods) = 0;
+
+ // Called when the preferences have to be updated.
+ virtual void PreferenceUpdateNeeded(
+ InputMethodLibrary* obj,
+ const InputMethodDescriptor& previous_input_method,
+ const InputMethodDescriptor& current_input_method) = 0;
};
virtual ~InputMethodLibrary() {}
diff --git a/chrome/browser/chromeos/login/keyboard_switch_menu.cc b/chrome/browser/chromeos/login/keyboard_switch_menu.cc
index de2026b..ff11bee 100644
--- a/chrome/browser/chromeos/login/keyboard_switch_menu.cc
+++ b/chrome/browser/chromeos/login/keyboard_switch_menu.cc
@@ -24,8 +24,10 @@ KeyboardSwitchMenu::KeyboardSwitchMenu()
////////////////////////////////////////////////////////////////////////////////
// InputMethodMenu::InputMethodMenuHost implementation.
-void KeyboardSwitchMenu::UpdateUI(
- const std::wstring& name, const std::wstring& tooltip) {
+void KeyboardSwitchMenu::UpdateUI(const std::string& input_method_id,
+ const std::wstring& name,
+ const std::wstring& tooltip,
+ size_t num_active_input_methods) {
// Update all view hierarchies so that the new input method name is shown in
// the menu button.
views::Widget::NotifyLocaleChanged();
diff --git a/chrome/browser/chromeos/login/keyboard_switch_menu.h b/chrome/browser/chromeos/login/keyboard_switch_menu.h
index 64bd2aa..48c0982 100644
--- a/chrome/browser/chromeos/login/keyboard_switch_menu.h
+++ b/chrome/browser/chromeos/login/keyboard_switch_menu.h
@@ -23,8 +23,10 @@ class KeyboardSwitchMenu : public InputMethodMenu {
virtual ~KeyboardSwitchMenu() {}
// InputMethodMenu::InputMethodMenuHost implementation.
- virtual void UpdateUI(
- const std::wstring& name, const std::wstring& tooltip);
+ virtual void UpdateUI(const std::string& input_method_id,
+ const std::wstring& name,
+ const std::wstring& tooltip,
+ size_t num_active_input_methods);
virtual bool ShouldSupportConfigUI() { return false; }
virtual void OpenConfigUI() {}
diff --git a/chrome/browser/chromeos/status/input_method_menu.cc b/chrome/browser/chromeos/status/input_method_menu.cc
index 027f141..8260e087 100644
--- a/chrome/browser/chromeos/status/input_method_menu.cc
+++ b/chrome/browser/chromeos/status/input_method_menu.cc
@@ -378,16 +378,20 @@ void InputMethodMenu::RunMenu(
////////////////////////////////////////////////////////////////////////////////
// InputMethodLibrary::Observer implementation:
-void InputMethodMenu::InputMethodChanged(InputMethodLibrary* obj) {
+void InputMethodMenu::InputMethodChanged(
+ InputMethodLibrary* obj,
+ const InputMethodDescriptor& previous_input_method,
+ const InputMethodDescriptor& current_input_method,
+ size_t num_active_input_methods) {
UserMetrics::RecordAction(
UserMetricsAction("LanguageMenuButton_InputMethodChanged"));
+ UpdateUIFromInputMethod(current_input_method, num_active_input_methods);
+}
- const InputMethodDescriptor& previous_input_method =
- obj->previous_input_method();
- const InputMethodDescriptor& current_input_method =
- obj->current_input_method();
- UpdateUIFromInputMethod(current_input_method);
- // Update Chrome prefs as well.
+void InputMethodMenu::PreferenceUpdateNeeded(
+ InputMethodLibrary* obj,
+ const InputMethodDescriptor& previous_input_method,
+ const InputMethodDescriptor& current_input_method) {
if (is_browser_mode_) {
if (pref_service_) { // make sure we're not in unit tests.
// Sometimes (e.g. initial boot) |previous_input_method.id| is empty.
@@ -418,20 +422,21 @@ void InputMethodMenu::PrepareForMenuOpen() {
}
}
-void InputMethodMenu::ActiveInputMethodsChanged(InputMethodLibrary* obj) {
+void InputMethodMenu::ActiveInputMethodsChanged(
+ InputMethodLibrary* obj,
+ const InputMethodDescriptor& current_input_method,
+ size_t num_active_input_methods) {
// Update the icon if active input methods are changed. See also
- // comments in UpdateUI()
- UpdateUIFromInputMethod(obj->current_input_method());
-}
-
-void InputMethodMenu::ImePropertiesChanged(InputMethodLibrary* obj) {
+ // comments in UpdateUI() in input_method_menu_button.cc.
+ UpdateUIFromInputMethod(current_input_method, num_active_input_methods);
}
void InputMethodMenu::UpdateUIFromInputMethod(
- const InputMethodDescriptor& input_method) {
+ const InputMethodDescriptor& input_method,
+ size_t num_active_input_methods) {
const std::wstring name = GetTextForIndicator(input_method);
const std::wstring tooltip = GetTextForMenu(input_method);
- UpdateUI(name, tooltip);
+ UpdateUI(input_method.id, name, tooltip, num_active_input_methods);
}
void InputMethodMenu::RebuildModel() {
diff --git a/chrome/browser/chromeos/status/input_method_menu.h b/chrome/browser/chromeos/status/input_method_menu.h
index a132c87..a25ee36 100644
--- a/chrome/browser/chromeos/status/input_method_menu.h
+++ b/chrome/browser/chromeos/status/input_method_menu.h
@@ -63,9 +63,19 @@ class InputMethodMenu : public views::ViewMenuDelegate,
const gfx::Point& pt);
// InputMethodLibrary::Observer implementation.
- virtual void InputMethodChanged(InputMethodLibrary* obj);
- virtual void ImePropertiesChanged(InputMethodLibrary* obj);
- virtual void ActiveInputMethodsChanged(InputMethodLibrary* obj);
+ virtual void InputMethodChanged(
+ InputMethodLibrary* obj,
+ const InputMethodDescriptor& previous_input_method,
+ const InputMethodDescriptor& current_input_method,
+ size_t num_active_input_methods);
+ virtual void ActiveInputMethodsChanged(
+ InputMethodLibrary* obj,
+ const InputMethodDescriptor& current_input_method,
+ size_t num_active_input_methods);
+ virtual void PreferenceUpdateNeeded(
+ InputMethodLibrary* obj,
+ const InputMethodDescriptor& previous_input_method,
+ const InputMethodDescriptor& current_input_method);
// NotificationObserver implementation.
virtual void Observe(NotificationType type,
@@ -89,7 +99,8 @@ class InputMethodMenu : public views::ViewMenuDelegate,
protected:
// Parses |input_method| and then calls UpdateUI().
- void UpdateUIFromInputMethod(const InputMethodDescriptor& input_method);
+ void UpdateUIFromInputMethod(const InputMethodDescriptor& input_method,
+ size_t num_active_input_methods);
// Rebuilds model and menu2 objects in preparetion to open the menu.
void PrepareForMenuOpen();
@@ -102,8 +113,10 @@ class InputMethodMenu : public views::ViewMenuDelegate,
private:
// Updates UI of a container of the menu (e.g. the "US" menu button in the
// status area). Sub classes have to implement the interface for their own UI.
- virtual void UpdateUI(
- const std::wstring& name, const std::wstring& tooltip) = 0;
+ virtual void UpdateUI(const std::string& input_method_id, // e.g. "mozc"
+ const std::wstring& name, // e.g. "US", "INTL"
+ const std::wstring& tooltip,
+ size_t num_active_input_methods) = 0;
// Sub classes have to implement the interface. This interface should return
// true if the dropdown menu should show an item like "Customize languages
diff --git a/chrome/browser/chromeos/status/input_method_menu_button.cc b/chrome/browser/chromeos/status/input_method_menu_button.cc
index 1fb5fa2..bc714bc 100644
--- a/chrome/browser/chromeos/status/input_method_menu_button.cc
+++ b/chrome/browser/chromeos/status/input_method_menu_button.cc
@@ -7,6 +7,7 @@
#include <string>
#include "app/resource_bundle.h"
+#include "base/utf_string_conversions.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/cros/keyboard_library.h"
#include "chrome/browser/chromeos/input_method/input_method_util.h"
@@ -54,11 +55,16 @@ InputMethodMenuButton::InputMethodMenuButton(StatusAreaHost* host)
SetShowMultipleIconStates(false);
set_alignment(TextButton::ALIGN_CENTER);
+ chromeos::KeyboardLibrary* keyboard_library =
+ chromeos::CrosLibrary::Get()->GetKeyboardLibrary();
+ const std::string hardware_keyboard_id = // e.g. "xkb:us::eng"
+ keyboard_library->GetHardwareKeyboardLayoutName();
+
// Draw the default indicator "US". The default indicator "US" is used when
// |pref_service| is not available (for example, unit tests) or |pref_service|
// is available, but Chrome preferences are not available (for example,
// initial OS boot).
- InputMethodMenuButton::UpdateUI(L"US", L"");
+ InputMethodMenuButton::UpdateUI(hardware_keyboard_id, L"US", L"", 1);
}
////////////////////////////////////////////////////////////////////////////////
@@ -74,9 +80,21 @@ gfx::Size InputMethodMenuButton::GetPreferredSize() {
void InputMethodMenuButton::OnLocaleChanged() {
input_method::OnLocaleChanged();
+
+ chromeos::InputMethodLibrary* input_method_library =
+ chromeos::CrosLibrary::Get()->GetInputMethodLibrary();
const InputMethodDescriptor& input_method =
- CrosLibrary::Get()->GetInputMethodLibrary()->current_input_method();
- UpdateUIFromInputMethod(input_method);
+ input_method_library->current_input_method();
+
+ // In general, we should not call an input method API in the input method
+ // button classes (status/input_menu_button*.cc) for performance reasons (see
+ // http://crosbug.com/8284). However, since OnLocaleChanged is called only in
+ // OOBE/Login screen which does not have two or more Chrome windows, it's okay
+ // to call GetNumActiveInputMethods here.
+ const size_t num_active_input_methods =
+ input_method_library->GetNumActiveInputMethods();
+
+ UpdateUIFromInputMethod(input_method, num_active_input_methods);
Layout();
SchedulePaint();
}
@@ -84,16 +102,16 @@ void InputMethodMenuButton::OnLocaleChanged() {
////////////////////////////////////////////////////////////////////////////////
// InputMethodMenu::InputMethodMenuHost implementation:
-void InputMethodMenuButton::UpdateUI(
- const std::wstring& name, const std::wstring& tooltip) {
+void InputMethodMenuButton::UpdateUI(const std::string& input_method_id,
+ const std::wstring& name,
+ const std::wstring& tooltip,
+ size_t num_active_input_methods) {
// Hide the button only if there is only one input method, and the input
// method is a XKB keyboard layout. We don't hide the button for other
// types of input methods as these might have intra input method modes,
// like Hiragana and Katakana modes in Japanese input methods.
- scoped_ptr<InputMethodDescriptors> active_input_methods(
- CrosLibrary::Get()->GetInputMethodLibrary()->GetActiveInputMethods());
- if (active_input_methods->size() == 1 &&
- input_method::IsKeyboardLayout(active_input_methods->at(0).id) &&
+ if (num_active_input_methods == 1 &&
+ input_method::IsKeyboardLayout(input_method_id) &&
host_->IsBrowserMode()) {
// As the disabled color is set to invisible, disabling makes the
// button disappear.
diff --git a/chrome/browser/chromeos/status/input_method_menu_button.h b/chrome/browser/chromeos/status/input_method_menu_button.h
index d7375d3..3a232eb 100644
--- a/chrome/browser/chromeos/status/input_method_menu_button.h
+++ b/chrome/browser/chromeos/status/input_method_menu_button.h
@@ -29,8 +29,10 @@ class InputMethodMenuButton : public StatusAreaButton,
private:
// InputMethodMenu implementation.
- virtual void UpdateUI(
- const std::wstring& name, const std::wstring& tooltip);
+ virtual void UpdateUI(const std::string& input_method_id,
+ const std::wstring& name,
+ const std::wstring& tooltip,
+ size_t num_active_input_methods);
virtual bool ShouldSupportConfigUI();
virtual void OpenConfigUI();