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

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: Add a TODO comment on confusing usage of GetInputMethod 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
« no previous file with comments | « no previous file | components/arc/ime/arc_ime_service_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // TODO(kinaba): Implicit dependency in GetInputMethod as described below is
131 // confusing. Consider getting InputMethod directly from lost_ or gained_focus
132 // variables. For that, we need to change how to inject testing InputMethod.
133 //
134 // GetInputMethod() retrieves the input method associated to
135 // |forcused_arc_window_|. Hence, to get the object we are detaching from, we
136 // must call the method before updating the forcused ARC window.
137 ui::InputMethod* const detaching_ime = detach ? GetInputMethod() : nullptr;
138
128 if (detach) 139 if (detach)
129 focused_arc_window_.Remove(lost_focus); 140 focused_arc_window_.Remove(lost_focus);
130 if (attach) 141 if (attach)
131 focused_arc_window_.Add(gained_focus); 142 focused_arc_window_.Add(gained_focus);
132 143
144 ui::InputMethod* const attaching_ime = attach ? GetInputMethod() : nullptr;
145
133 // Notify to the input method, either when this service is detached or 146 // Notify to the input method, either when this service is detached or
134 // attached. Do nothing when the focus is moving between ARC windows, 147 // attached. Do nothing when the focus is moving between ARC windows,
135 // to avoid unpexpected context reset in ARC. 148 // to avoid unpexpected context reset in ARC.
136 ui::InputMethod* const input_method = GetInputMethod(); 149 if (detaching_ime != attaching_ime) {
137 if (input_method) { 150 if (detaching_ime)
138 if (detach && !attach) 151 detaching_ime->DetachTextInputClient(this);
139 input_method->DetachTextInputClient(this); 152 if (attaching_ime)
140 if (!detach && attach) 153 attaching_ime->SetFocusedTextInputClient(this);
141 input_method->SetFocusedTextInputClient(this);
142 } 154 }
143 } 155 }
144 156
145 //////////////////////////////////////////////////////////////////////////////// 157 ////////////////////////////////////////////////////////////////////////////////
146 // Overridden from arc::ArcImeBridge::Delegate 158 // Overridden from arc::ArcImeBridge::Delegate
147 159
148 void ArcImeService::OnTextInputTypeChanged(ui::TextInputType type) { 160 void ArcImeService::OnTextInputTypeChanged(ui::TextInputType type) {
149 if (ime_type_ == type) 161 if (ime_type_ == type)
150 return; 162 return;
151 ime_type_ = type; 163 ime_type_ = type;
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 base::i18n::TextDirection direction) { 350 base::i18n::TextDirection direction) {
339 return false; 351 return false;
340 } 352 }
341 353
342 bool ArcImeService::IsTextEditCommandEnabled( 354 bool ArcImeService::IsTextEditCommandEnabled(
343 ui::TextEditCommand command) const { 355 ui::TextEditCommand command) const {
344 return false; 356 return false;
345 } 357 }
346 358
347 } // namespace arc 359 } // namespace arc
OLDNEW
« no previous file with comments | « no previous file | components/arc/ime/arc_ime_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698