Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(813)

Side by Side Diff: components/arc/ime/arc_ime_service.cc

Issue 2570623005: ARC IME: Fix crash on shutdown due to wrong focus management. (Closed)
Patch Set: Fix test Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « no previous file | components/arc/ime/arc_ime_service_unittest.cc » ('j') | components/arc/ime/arc_ime_service_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698