Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/arc/ime/arc_ime_service.h" | 5 #include "components/arc/ime/arc_ime_service.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 77 ui::InputMethod* test_input_method) { | 77 ui::InputMethod* test_input_method) { |
| 78 test_input_method_ = test_input_method; | 78 test_input_method_ = test_input_method; |
| 79 } | 79 } |
| 80 | 80 |
| 81 void ArcImeService::SetArcWindowDetectorForTesting( | 81 void ArcImeService::SetArcWindowDetectorForTesting( |
| 82 std::unique_ptr<ArcWindowDetector> detector) { | 82 std::unique_ptr<ArcWindowDetector> detector) { |
| 83 arc_window_detector_ = std::move(detector); | 83 arc_window_detector_ = std::move(detector); |
| 84 } | 84 } |
| 85 | 85 |
| 86 ui::InputMethod* ArcImeService::GetInputMethod() { | 86 ui::InputMethod* ArcImeService::GetInputMethod() { |
| 87 if (focused_arc_window_.windows().empty()) | |
| 88 return nullptr; | |
| 89 | |
| 87 if (test_input_method_) | 90 if (test_input_method_) |
| 88 return test_input_method_; | 91 return test_input_method_; |
| 89 if (focused_arc_window_.windows().empty()) | |
| 90 return nullptr; | |
| 91 return focused_arc_window_.windows().front()->GetHost()->GetInputMethod(); | 92 return focused_arc_window_.windows().front()->GetHost()->GetInputMethod(); |
| 92 } | 93 } |
| 93 | 94 |
| 94 //////////////////////////////////////////////////////////////////////////////// | 95 //////////////////////////////////////////////////////////////////////////////// |
| 95 // Overridden from aura::EnvObserver: | 96 // Overridden from aura::EnvObserver: |
| 96 | 97 |
| 97 void ArcImeService::OnWindowInitialized(aura::Window* new_window) { | 98 void ArcImeService::OnWindowInitialized(aura::Window* new_window) { |
| 98 if (arc_window_detector_->IsArcWindow(new_window)) { | 99 if (arc_window_detector_->IsArcWindow(new_window)) { |
| 99 if (!is_focus_observer_installed_) { | 100 if (!is_focus_observer_installed_) { |
| 100 exo::WMHelper::GetInstance()->AddFocusObserver(this); | 101 exo::WMHelper::GetInstance()->AddFocusObserver(this); |
| 101 is_focus_observer_installed_ = true; | 102 is_focus_observer_installed_ = true; |
| 102 } | 103 } |
| 103 } | 104 } |
| 104 keyboard::KeyboardController* keyboard_controller = | 105 keyboard::KeyboardController* keyboard_controller = |
| 105 keyboard::KeyboardController::GetInstance(); | 106 keyboard::KeyboardController::GetInstance(); |
| 106 if (keyboard_controller && keyboard_controller_ != keyboard_controller) { | 107 if (keyboard_controller && keyboard_controller_ != keyboard_controller) { |
| 107 // Registering |this| as an observer only once per KeyboardController. | 108 // Registering |this| as an observer only once per KeyboardController. |
| 108 keyboard_controller_ = keyboard_controller; | 109 keyboard_controller_ = keyboard_controller; |
| 109 keyboard_controller_->AddObserver(this); | 110 keyboard_controller_->AddObserver(this); |
| 110 } | 111 } |
| 111 } | 112 } |
| 112 | 113 |
| 113 //////////////////////////////////////////////////////////////////////////////// | 114 //////////////////////////////////////////////////////////////////////////////// |
| 114 // Overridden from exo::WMHelper::FocusChangeObserver: | 115 // Overridden from exo::WMHelper::FocusChangeObserver: |
| 115 | 116 |
| 116 void ArcImeService::OnWindowFocused(aura::Window* gained_focus, | 117 void ArcImeService::OnWindowFocused(aura::Window* gained_focus, |
| 117 aura::Window* lost_focus) { | 118 aura::Window* lost_focus) { |
| 118 // The Aura focus may or may not be on sub-window of the toplevel ARC++ frame. | 119 // The Aura focus may or may not be on sub-window of the toplevel ARC++ frame. |
| 119 // To handle all cases, judge the state by always climbing up to the toplevel. | 120 // To handle all cases, judge the state by always climbing up to the toplevel. |
| 120 gained_focus = gained_focus ? gained_focus->GetToplevelWindow() : nullptr; | 121 gained_focus = gained_focus ? gained_focus->GetToplevelWindow() : nullptr; |
| 121 lost_focus = lost_focus ? lost_focus->GetToplevelWindow() : nullptr; | 122 lost_focus = lost_focus ? lost_focus->GetToplevelWindow() : nullptr; |
| 122 if (lost_focus == gained_focus) | 123 if (lost_focus == gained_focus) |
| 123 return; | 124 return; |
| 124 | 125 |
| 125 const bool detach = (lost_focus && focused_arc_window_.Contains(lost_focus)); | 126 const bool detach = (lost_focus && focused_arc_window_.Contains(lost_focus)); |
| 126 const bool attach = | 127 const bool attach = |
| 127 (gained_focus && arc_window_detector_->IsArcTopLevelWindow(gained_focus)); | 128 (gained_focus && arc_window_detector_->IsArcTopLevelWindow(gained_focus)); |
| 129 | |
| 130 // GetInputMethod() retrieves the input method associated to | |
| 131 // |forcused_arc_window_|. Hence, to get the object we are detaching from, we | |
| 132 // must call the method before updating the forcused ARC window. | |
| 133 ui::InputMethod* const detaching_ime = detach ? GetInputMethod() : nullptr; | |
| 134 | |
| 128 if (detach) | 135 if (detach) |
| 129 focused_arc_window_.Remove(lost_focus); | 136 focused_arc_window_.Remove(lost_focus); |
| 130 if (attach) | 137 if (attach) |
| 131 focused_arc_window_.Add(gained_focus); | 138 focused_arc_window_.Add(gained_focus); |
| 132 | 139 |
| 140 ui::InputMethod* const attaching_ime = attach ? GetInputMethod() : nullptr; | |
| 141 | |
| 133 // Notify to the input method, either when this service is detached or | 142 // Notify to the input method, either when this service is detached or |
| 134 // attached. Do nothing when the focus is moving between ARC windows, | 143 // attached. Do nothing when the focus is moving between ARC windows, |
| 135 // to avoid unpexpected context reset in ARC. | 144 // to avoid unpexpected context reset in ARC. |
| 136 ui::InputMethod* const input_method = GetInputMethod(); | 145 if (detaching_ime != attaching_ime) { |
|
hidehiko
2016/12/14 09:25:27
I'm now slightly confused. If IME is attached to t
kinaba
2016/12/14 12:12:56
On ChromeOS as of now, all windows share the same
hidehiko
2016/12/14 15:27:22
I understood. Thank you for detailed explanation.
kinaba
2016/12/15 00:58:41
I totally agree with your concern. Added a TODO co
| |
| 137 if (input_method) { | 146 if (detaching_ime) |
| 138 if (detach && !attach) | 147 detaching_ime->DetachTextInputClient(this); |
| 139 input_method->DetachTextInputClient(this); | 148 if (attaching_ime) |
| 140 if (!detach && attach) | 149 attaching_ime->SetFocusedTextInputClient(this); |
| 141 input_method->SetFocusedTextInputClient(this); | |
| 142 } | 150 } |
| 143 } | 151 } |
| 144 | 152 |
| 145 //////////////////////////////////////////////////////////////////////////////// | 153 //////////////////////////////////////////////////////////////////////////////// |
| 146 // Overridden from arc::ArcImeBridge::Delegate | 154 // Overridden from arc::ArcImeBridge::Delegate |
| 147 | 155 |
| 148 void ArcImeService::OnTextInputTypeChanged(ui::TextInputType type) { | 156 void ArcImeService::OnTextInputTypeChanged(ui::TextInputType type) { |
| 149 if (ime_type_ == type) | 157 if (ime_type_ == type) |
| 150 return; | 158 return; |
| 151 ime_type_ = type; | 159 ime_type_ = type; |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 338 base::i18n::TextDirection direction) { | 346 base::i18n::TextDirection direction) { |
| 339 return false; | 347 return false; |
| 340 } | 348 } |
| 341 | 349 |
| 342 bool ArcImeService::IsTextEditCommandEnabled( | 350 bool ArcImeService::IsTextEditCommandEnabled( |
| 343 ui::TextEditCommand command) const { | 351 ui::TextEditCommand command) const { |
| 344 return false; | 352 return false; |
| 345 } | 353 } |
| 346 | 354 |
| 347 } // namespace arc | 355 } // namespace arc |
| OLD | NEW |