Chromium Code Reviews| Index: chrome/browser/chromeos/input_method/input_method_manager.cc |
| diff --git a/chrome/browser/chromeos/input_method/input_method_manager.cc b/chrome/browser/chromeos/input_method/input_method_manager.cc |
| index 5cf84c749da8e03d55865d2cf461dc418e2e90ef..7b3ce8e9538f51475060c2f600e703963432596c 100644 |
| --- a/chrome/browser/chromeos/input_method/input_method_manager.cc |
| +++ b/chrome/browser/chromeos/input_method/input_method_manager.cc |
| @@ -42,9 +42,58 @@ namespace { |
| const char kIBusDaemonPath[] = "/usr/bin/ibus-daemon"; |
| // For hotkey handling. |
| -enum HotkeyEvents { |
| +enum HotkeyEvent { |
| kPreviousInputMethod = 0, |
| kNextInputMethod, |
| + kJapaneseInputMethod, |
| + kJapaneseLayout, |
| + kJapaneseInputMethodOrLayout, |
| + kKoreanInputMethodOrLayout, |
| +}; |
| + |
| +// Engine specific hotkeys. |
| +const struct EngineSpecificHotkeySetting { |
| + const char* input_method_ids[2]; |
| + int event_id; |
| + KeySym keysym; |
| + uint32 modifiers; |
| + bool trigger_on_press; |
|
mazda
2011/09/12 10:02:54
What happens if trigger_on_press is false?
Yusuke Sato
2011/09/12 11:46:05
IME or layout is changed on key release. The Shift
mazda
2011/09/12 11:57:31
Thanks.
Probably it's better to add comment since
Yusuke Sato
2011/09/12 12:02:14
Done.
|
| +} kEngineSpecificHotkeySettings[] = { |
| + { |
| + { "mozc-jp" }, |
| + kJapaneseInputMethod, |
| + XK_Henkan, |
| + 0x0, |
| + true, |
| + }, |
| + { |
| + { "xkb:jp::jpn" }, |
| + kJapaneseLayout, |
| + XK_Muhenkan, |
| + 0x0, |
| + true, |
| + }, |
| + { |
| + { "mozc-jp", "xkb:jp::jpn" }, |
| + kJapaneseInputMethodOrLayout, |
| + XK_Zenkaku_Hankaku, |
| + 0x0, |
| + true, |
| + }, |
| + { |
| + { "mozc-hangul", "xkb:kr:kr104:kor" }, |
| + kKoreanInputMethodOrLayout, |
| + XK_Hangul, |
| + 0x0, |
| + true, |
| + }, |
| + { |
| + { "mozc-hangul", "xkb:kr:kr104:kor" }, |
| + kKoreanInputMethodOrLayout, |
| + XK_space, |
| + ShiftMask, |
| + true, |
| + }, |
| }; |
| // Finds a property which has |new_prop.key| from |prop_list|, and replaces the |
| @@ -104,6 +153,19 @@ class InputMethodManagerImpl : public HotkeyManager::Observer, |
| ibus_controller_->AddObserver(this); |
| ibus_controller_->Connect(); |
| + // Initialize engine_hotkeys_. |
| + for (size_t i = 0; i < arraysize(kEngineSpecificHotkeySettings); ++i) { |
| + const char* const* input_method_ids = |
| + kEngineSpecificHotkeySettings[i].input_method_ids; |
| + const size_t input_method_ids_len = |
| + arraysize(kEngineSpecificHotkeySettings[i].input_method_ids); |
| + for (size_t j = 0; j < input_method_ids_len && input_method_ids[j]; ++j) { |
| + engine_hotkeys_.insert(std::make_pair( |
| + input_method_ids[j], &kEngineSpecificHotkeySettings[i])); |
| + } |
| + } |
| + |
| + // Register global input method hotkeys: Control+space and Shift+Alt. |
| InitHotkeyManager(); |
| } |
| @@ -223,6 +285,7 @@ class InputMethodManagerImpl : public HotkeyManager::Observer, |
| config_name == language_prefs::kPreloadEnginesConfigName && |
| value.type == ImeConfigValue::kValueTypeStringList) { |
| active_input_method_ids_ = value.string_list_value; |
| + UpdateEngineSpecificHotkeys(); |
|
mazda
2011/09/12 10:02:54
Is it OK that UpdateEngineSpecificHotkeys is calle
Yusuke Sato
2011/09/12 11:46:05
For now it's okay since hotkey information for an
|
| std::map<std::string, InputMethodDescriptor>::const_iterator ix; |
| for (ix = extra_input_method_ids_.begin(); |
| @@ -349,16 +412,21 @@ class InputMethodManagerImpl : public HotkeyManager::Observer, |
| } |
| virtual void HotkeyPressed(HotkeyManager* manager, int event_id) { |
| - switch (HotkeyEvents(event_id)) { |
| + const HotkeyEvent event = HotkeyEvent(event_id); |
| + switch (event) { |
| case kPreviousInputMethod: |
| SwitchToPreviousInputMethod(); |
| break; |
| case kNextInputMethod: |
| SwitchToNextInputMethod(); |
| break; |
| + case kJapaneseInputMethod: |
| + case kJapaneseLayout: |
| + case kJapaneseInputMethodOrLayout: |
| + case kKoreanInputMethodOrLayout: |
| + SwitchToInputMethod(event); |
|
mazda
2011/09/12 10:02:54
default case.
Yusuke Sato
2011/09/12 11:46:05
Since HotkeyEvent is an enum, adding default: is n
|
| + break; |
| } |
| - // TODO(yusukes): handle engine specific hotkeys like Henkan, Muhenkan, and |
| - // Hangul. |
| } |
| static InputMethodManagerImpl* GetInstance() { |
| @@ -961,12 +1029,30 @@ class InputMethodManagerImpl : public HotkeyManager::Observer, |
| XK_Meta_R, |
| ShiftMask | Mod1Mask, |
| false); |
| + // Engine specific hotkeys will be added in SetImeConfig(). |
| - // TODO(yusukes): Support engine specific hotkeys like XK_Henkan, Muhenkan, |
| - // and Hangul. |
| hotkey_manager_.AddObserver(this); |
| } |
| + void UpdateEngineSpecificHotkeys() { |
| + // Remove all engine specific hotkeys first. |
| + for (size_t i = 0; i < arraysize(kEngineSpecificHotkeySettings); ++i) { |
| + hotkey_manager_.RemoveHotkey(kEngineSpecificHotkeySettings[i].event_id); |
| + } |
| + for (size_t i = 0; i < active_input_method_ids_.size(); ++i) { |
| + typedef std::map<std::string, |
| + const EngineSpecificHotkeySetting*>::const_iterator Iter; |
| + std::pair<Iter, Iter> result = engine_hotkeys_.equal_range( |
| + active_input_method_ids_[i]); |
| + for (Iter iter = result.first; iter != result.second; ++iter) { |
| + hotkey_manager_.AddHotkey(iter->second->event_id, |
| + iter->second->keysym, |
| + iter->second->modifiers, |
| + iter->second->trigger_on_press); |
| + } |
| + } |
| + } |
| + |
| // Handles "Shift+Alt" hotkey. |
| void SwitchToNextInputMethod() { |
| // Sanity checks. |
| @@ -1019,6 +1105,72 @@ class InputMethodManagerImpl : public HotkeyManager::Observer, |
| } |
| } |
| + // Handles engine specific hotkeys like XK_Henkan. |
| + void SwitchToInputMethod(HotkeyEvent event) { |
| + // Sanity check. |
| + if (active_input_method_ids_.empty()) { |
| + LOG(ERROR) << "active input method is empty"; |
| + return; |
| + } |
| + |
| + const char* const* input_method_ids_to_switch = NULL; |
| + size_t input_method_ids_to_switch_len = 0; |
| + |
| + // Get the list of input method ids for |event_id|. For example, get |
| + // { "mozc-hangul", "xkb:kr:kr104:kor" } for kKoreanInputMethodOrLayout. |
| + switch (event) { |
| + case kPreviousInputMethod: |
| + case kNextInputMethod: { |
| + break; |
|
mazda
2011/09/12 10:02:54
Are these two error case?
Yusuke Sato
2011/09/12 11:46:05
added a comment.
|
| + } |
| + case kJapaneseInputMethod: |
| + case kJapaneseLayout: |
| + case kJapaneseInputMethodOrLayout: |
| + case kKoreanInputMethodOrLayout: { |
| + const size_t index = static_cast<size_t>(event) - 2; |
|
Zachary Kuznia
2011/09/12 09:48:07
This line looks scary. Please give it a reassurin
Yusuke Sato
2011/09/12 11:46:05
Probably this was too error-prone. I've written th
|
| + DCHECK(event == kEngineSpecificHotkeySettings[index].event_id); |
| + input_method_ids_to_switch = |
| + kEngineSpecificHotkeySettings[index].input_method_ids; |
| + input_method_ids_to_switch_len = |
| + arraysize(kEngineSpecificHotkeySettings[index].input_method_ids); |
| + break; |
| + } |
| + } |
| + if (!input_method_ids_to_switch) { |
|
mazda
2011/09/12 10:02:54
How about moving this to the default case of the s
Yusuke Sato
2011/09/12 11:46:05
ditto. I prefer not to use default: in order to ke
|
| + LOG(ERROR) << "Unknown event: " << event; |
| + return; |
| + } |
| + |
| + // Obtain the intersection of input_method_ids_to_switch and |
| + // active_input_method_ids_. The order of IDs in active_input_method_ids_ is |
| + // preserved. |
| + std::vector<std::string> ids; |
| + for (size_t i = 0; i < input_method_ids_to_switch_len; ++i) { |
| + const char* id = input_method_ids_to_switch[i]; |
| + if (id && std::find(active_input_method_ids_.begin(), |
| + active_input_method_ids_.end(), |
| + id) != active_input_method_ids_.end()) { |
| + ids.push_back(id); |
| + } |
| + } |
| + if (ids.empty()) { |
| + LOG(ERROR) << "No input method for " << event << " is active"; |
| + return; |
| + } |
| + |
| + // If current_input_method_ is not in ids, switch to ids[0]. If |
| + // current_input_method_ is ids[N], switch to ids[N+1]. |
| + std::vector<std::string>::const_iterator iter = |
| + std::find(ids.begin(), ids.end(), current_input_method_.id()); |
| + if (iter != ids.end()) { |
| + ++iter; |
| + } |
| + if (iter == ids.end()) { |
| + iter = ids.begin(); |
| + } |
| + ChangeInputMethod(*iter); |
| + } |
| + |
| // A reference to the language api, to allow callbacks when the input method |
| // status changes. |
| IBusController* ibus_controller_; |
| @@ -1088,6 +1240,10 @@ class InputMethodManagerImpl : public HotkeyManager::Observer, |
| // those created by extension. |
| std::map<std::string, InputMethodDescriptor> extra_input_method_ids_; |
| + // A muitlmap from input method id to engine specific hotkey information. |
| + // e.g. "mozc-jp" to XK_ZenkakuHankaku, "mozc-jp" to XK_Henkan. |
| + std::multimap<std::string, |
| + const EngineSpecificHotkeySetting*> engine_hotkeys_; |
| // An object which detects Control+space and Shift+Alt key presses. |
| HotkeyManager hotkey_manager_; |