blob: 916799e2fbff8e0b9ec5ede679d8a8a1796a42a9 [file] [log] [blame]
Dave Tapuska9db80842017-07-24 17:24:261// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/renderer/input/widget_input_handler_impl.h"
6
7#include <utility>
8
9#include "base/bind.h"
10#include "base/logging.h"
11#include "content/common/input_messages.h"
12#include "content/renderer/gpu/render_widget_compositor.h"
13#include "content/renderer/ime_event_guard.h"
14#include "content/renderer/input/widget_input_handler_manager.h"
15#include "content/renderer/render_thread_impl.h"
16#include "content/renderer/render_widget.h"
17#include "third_party/WebKit/public/platform/Platform.h"
18#include "third_party/WebKit/public/platform/WebCoalescedInputEvent.h"
19#include "third_party/WebKit/public/platform/WebKeyboardEvent.h"
20#include "third_party/WebKit/public/platform/scheduler/renderer/renderer_scheduler.h"
21#include "third_party/WebKit/public/web/WebLocalFrame.h"
22
23namespace content {
24
25namespace {
26
Ryan Landay9387aa92017-08-16 23:16:5227blink::WebImeTextSpan::Type ConvertUiImeTextSpanTypeToBlinkType(
28 ui::ImeTextSpan::Type type) {
29 switch (type) {
30 case ui::ImeTextSpan::Type::kComposition:
31 return blink::WebImeTextSpan::Type::kComposition;
32 case ui::ImeTextSpan::Type::kSuggestion:
33 return blink::WebImeTextSpan::Type::kSuggestion;
34 }
35
36 NOTREACHED();
37 return blink::WebImeTextSpan::Type::kComposition;
38}
39
Ryan Landay9e42fd742017-08-12 01:59:1140std::vector<blink::WebImeTextSpan> ConvertUIImeTextSpansToBlinkImeTextSpans(
41 const std::vector<ui::ImeTextSpan>& ui_ime_text_spans) {
42 std::vector<blink::WebImeTextSpan> ime_text_spans;
43 for (const auto& ime_text_span : ui_ime_text_spans) {
44 blink::WebImeTextSpan blink_ime_text_span(
Ryan Landay9387aa92017-08-16 23:16:5245 ConvertUiImeTextSpanTypeToBlinkType(ime_text_span.type),
Ryan Landay9e42fd742017-08-12 01:59:1146 ime_text_span.start_offset, ime_text_span.end_offset,
Ryan Landayaf7a6022017-08-15 00:31:0147 ime_text_span.underline_color, ime_text_span.thick,
Ryan Landay9387aa92017-08-16 23:16:5248 ime_text_span.background_color,
49 ime_text_span.suggestion_highlight_color, ime_text_span.suggestions);
Ryan Landay9e42fd742017-08-12 01:59:1150 ime_text_spans.push_back(blink_ime_text_span);
Dave Tapuska9db80842017-07-24 17:24:2651 }
Ryan Landay9e42fd742017-08-12 01:59:1152 return ime_text_spans;
Dave Tapuska9db80842017-07-24 17:24:2653}
Ryan Landay9387aa92017-08-16 23:16:5254
Dave Tapuska65bb6ee82017-09-07 21:23:4155void RunClosureIfNotSwappedOut(base::WeakPtr<RenderWidget> render_widget,
56 base::OnceClosure closure) {
57 // Input messages must not be processed if the RenderWidget is in swapped out
58 // state.
59 if (!render_widget || render_widget->is_swapped_out())
60 return;
61 std::move(closure).Run();
62}
63
Dave Tapuska9db80842017-07-24 17:24:2664} // namespace
65
66WidgetInputHandlerImpl::WidgetInputHandlerImpl(
67 scoped_refptr<WidgetInputHandlerManager> manager,
68 scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
69 scoped_refptr<MainThreadEventQueue> input_event_queue,
70 base::WeakPtr<RenderWidget> render_widget)
71 : main_thread_task_runner_(main_thread_task_runner),
72 input_handler_manager_(manager),
73 input_event_queue_(input_event_queue),
74 render_widget_(render_widget),
75 binding_(this),
76 associated_binding_(this) {}
77
78WidgetInputHandlerImpl::~WidgetInputHandlerImpl() {}
79
80void WidgetInputHandlerImpl::SetAssociatedBinding(
81 mojom::WidgetInputHandlerAssociatedRequest request) {
82 associated_binding_.Bind(std::move(request));
83 associated_binding_.set_connection_error_handler(
tzik1076ee22017-08-25 04:03:5784 base::BindOnce(&WidgetInputHandlerImpl::Release, base::Unretained(this)));
Dave Tapuska9db80842017-07-24 17:24:2685}
86
87void WidgetInputHandlerImpl::SetBinding(
88 mojom::WidgetInputHandlerRequest request) {
89 binding_.Bind(std::move(request));
90 binding_.set_connection_error_handler(
tzik1076ee22017-08-25 04:03:5791 base::BindOnce(&WidgetInputHandlerImpl::Release, base::Unretained(this)));
Dave Tapuska9db80842017-07-24 17:24:2692}
93
94void WidgetInputHandlerImpl::SetFocus(bool focused) {
95 RunOnMainThread(
tzik1076ee22017-08-25 04:03:5796 base::BindOnce(&RenderWidget::OnSetFocus, render_widget_, focused));
Dave Tapuska9db80842017-07-24 17:24:2697}
98
99void WidgetInputHandlerImpl::MouseCaptureLost() {
100 RunOnMainThread(
tzik1076ee22017-08-25 04:03:57101 base::BindOnce(&RenderWidget::OnMouseCaptureLost, render_widget_));
Dave Tapuska9db80842017-07-24 17:24:26102}
103
104void WidgetInputHandlerImpl::SetEditCommandsForNextKeyEvent(
105 const std::vector<EditCommand>& commands) {
tzik1076ee22017-08-25 04:03:57106 RunOnMainThread(
107 base::BindOnce(&RenderWidget::OnSetEditCommandsForNextKeyEvent,
108 render_widget_, commands));
Dave Tapuska9db80842017-07-24 17:24:26109}
110
111void WidgetInputHandlerImpl::CursorVisibilityChanged(bool visible) {
tzik1076ee22017-08-25 04:03:57112 RunOnMainThread(base::BindOnce(&RenderWidget::OnCursorVisibilityChange,
113 render_widget_, visible));
Dave Tapuska9db80842017-07-24 17:24:26114}
115
116void WidgetInputHandlerImpl::ImeSetComposition(
117 const base::string16& text,
Ryan Landay9e42fd742017-08-12 01:59:11118 const std::vector<ui::ImeTextSpan>& ime_text_spans,
Dave Tapuska9db80842017-07-24 17:24:26119 const gfx::Range& range,
120 int32_t start,
121 int32_t end) {
Ryan Landay9e42fd742017-08-12 01:59:11122 RunOnMainThread(
tzik1076ee22017-08-25 04:03:57123 base::BindOnce(&RenderWidget::OnImeSetComposition, render_widget_, text,
124 ConvertUIImeTextSpansToBlinkImeTextSpans(ime_text_spans),
125 range, start, end));
Dave Tapuska9db80842017-07-24 17:24:26126}
127
128void WidgetInputHandlerImpl::ImeCommitText(
129 const base::string16& text,
Ryan Landay9e42fd742017-08-12 01:59:11130 const std::vector<ui::ImeTextSpan>& ime_text_spans,
Dave Tapuska9db80842017-07-24 17:24:26131 const gfx::Range& range,
132 int32_t relative_cursor_position) {
Ryan Landay9e42fd742017-08-12 01:59:11133 RunOnMainThread(
tzik1076ee22017-08-25 04:03:57134 base::BindOnce(&RenderWidget::OnImeCommitText, render_widget_, text,
135 ConvertUIImeTextSpansToBlinkImeTextSpans(ime_text_spans),
136 range, relative_cursor_position));
Dave Tapuska9db80842017-07-24 17:24:26137}
138
139void WidgetInputHandlerImpl::ImeFinishComposingText(bool keep_selection) {
tzik1076ee22017-08-25 04:03:57140 RunOnMainThread(base::BindOnce(&RenderWidget::OnImeFinishComposingText,
141 render_widget_, keep_selection));
Dave Tapuska9db80842017-07-24 17:24:26142}
143
144void WidgetInputHandlerImpl::RequestTextInputStateUpdate() {
tzik1076ee22017-08-25 04:03:57145 RunOnMainThread(base::BindOnce(&RenderWidget::OnRequestTextInputStateUpdate,
146 render_widget_));
Dave Tapuska9db80842017-07-24 17:24:26147}
148
149void WidgetInputHandlerImpl::RequestCompositionUpdates(bool immediate_request,
150 bool monitor_request) {
tzik1076ee22017-08-25 04:03:57151 RunOnMainThread(base::BindOnce(&RenderWidget::OnRequestCompositionUpdates,
152 render_widget_, immediate_request,
153 monitor_request));
Dave Tapuska9db80842017-07-24 17:24:26154}
155
156void WidgetInputHandlerImpl::DispatchEvent(
157 std::unique_ptr<content::InputEvent> event,
158 DispatchEventCallback callback) {
159 if (!event || !event->web_event) {
160 return;
161 }
162 input_handler_manager_->DispatchEvent(std::move(event), std::move(callback));
163}
164
165void WidgetInputHandlerImpl::DispatchNonBlockingEvent(
166 std::unique_ptr<content::InputEvent> event) {
167 DispatchEvent(std::move(event), DispatchEventCallback());
168}
169
170void WidgetInputHandlerImpl::RunOnMainThread(base::OnceClosure closure) {
171 if (input_event_queue_) {
Dave Tapuska65bb6ee82017-09-07 21:23:41172 input_event_queue_->QueueClosure(base::BindOnce(
173 &RunClosureIfNotSwappedOut, render_widget_, std::move(closure)));
Dave Tapuska9db80842017-07-24 17:24:26174 } else {
Dave Tapuska65bb6ee82017-09-07 21:23:41175 RunClosureIfNotSwappedOut(render_widget_, std::move(closure));
Dave Tapuska9db80842017-07-24 17:24:26176 }
177}
178
179void WidgetInputHandlerImpl::Release() {
180 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
181 // Close the binding on the compositor thread first before telling the main
182 // thread to delete this object.
183 associated_binding_.Close();
184 binding_.Close();
185 main_thread_task_runner_->PostTask(
tzik1076ee22017-08-25 04:03:57186 FROM_HERE, base::BindOnce(&WidgetInputHandlerImpl::Release,
187 base::Unretained(this)));
Dave Tapuska9db80842017-07-24 17:24:26188 return;
189 }
190 delete this;
191}
192
193} // namespace content