Merge lp:~chrisccoulson/oxide/refactor-webview-rwhv-interation into lp:~oxide-developers/oxide/oxide.trunk
- refactor-webview-rwhv-interation
- Merge into oxide.trunk
Status: | Merged |
---|---|
Merged at revision: | 1227 |
Proposed branch: | lp:~chrisccoulson/oxide/refactor-webview-rwhv-interation |
Merge into: | lp:~oxide-developers/oxide/oxide.trunk |
Diff against target: |
3849 lines (+1746/-856) 30 files modified
qt/core/browser/input/oxide_qt_input_method_context.cc (+424/-0) qt/core/browser/input/oxide_qt_input_method_context.h (+82/-0) qt/core/browser/input/oxide_qt_input_method_context_client.h (+36/-0) qt/core/browser/oxide_qt_web_view.cc (+16/-278) qt/core/browser/oxide_qt_web_view.h (+10/-19) qt/core/core.gyp (+6/-3) shared/browser/compositor/oxide_compositor.cc (+16/-30) shared/browser/compositor/oxide_compositor.h (+7/-27) shared/browser/compositor/oxide_compositor_client.h (+0/-2) shared/browser/compositor/oxide_compositor_observer.cc (+60/-0) shared/browser/compositor/oxide_compositor_observer.h (+49/-0) shared/browser/input/oxide_ime_bridge.cc (+31/-0) shared/browser/input/oxide_ime_bridge.h (+84/-0) shared/browser/input/oxide_ime_bridge_impl.cc (+157/-0) shared/browser/input/oxide_ime_bridge_impl.h (+69/-0) shared/browser/input/oxide_input_method_context.cc (+69/-0) shared/browser/input/oxide_input_method_context.h (+69/-0) shared/browser/input/oxide_input_method_context_observer.cc (+61/-0) shared/browser/input/oxide_input_method_context_observer.h (+49/-0) shared/browser/oxide_render_widget_host_view.cc (+120/-132) shared/browser/oxide_render_widget_host_view.h (+18/-16) shared/browser/oxide_render_widget_host_view_container.h (+35/-28) shared/browser/oxide_web_contents_view.cc (+45/-28) shared/browser/oxide_web_contents_view.h (+6/-2) shared/browser/oxide_web_view.cc (+139/-204) shared/browser/oxide_web_view.h (+30/-56) shared/browser/oxide_web_view_client.cc (+3/-13) shared/browser/oxide_web_view_client.h (+2/-17) shared/common/oxide_unowned_user_data.h (+41/-0) shared/shared.gyp (+12/-1) |
To merge this branch: | bzr merge lp:~chrisccoulson/oxide/refactor-webview-rwhv-interation |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Chris Coulson | Pending | ||
Review via email: mp+274723@code.launchpad.net |
Commit message
Description of the change
- 1222. By Chris Coulson
-
Merge from trunk
- 1223. By Chris Coulson
-
When a RWHV is hidden, make sure we hide its cc::Layer
- 1224. By Chris Coulson
-
Don't proxy EvictCurrentFrame up to the WebView. This already doesn't make sense, and we should have a separate algorithm for LayerTreeHost eviction when a WebView is hidden. The current implementation won't make sense when we have Interstitial views anyway
- 1225. By Chris Coulson
-
Create RWHVs with a container
- 1226. By Chris Coulson
-
Change the behaviour of RWHV::IsShowing, and make sure that when we create a new cc::Layer it has the correct visibility
- 1227. By Chris Coulson
-
Fix RWHV::HasFocus
- 1228. By Chris Coulson
-
Merge from trunk
- 1229. By Chris Coulson
-
Merge from trunk
- 1230. By Chris Coulson
-
Split IME related calls from WebViewClient in to new classes
- 1231. By Chris Coulson
-
Attach the IM context when creating a new webview
- 1232. By Chris Coulson
-
Remove an unused method from WebViewClient
- 1233. By Chris Coulson
-
Fix cursor updates to work with interstitial views
- 1234. By Chris Coulson
-
Fix a shutdown crash
- 1235. By Chris Coulson
-
Turn a couple of CHECKs in to DCHECKs
- 1236. By Chris Coulson
-
Actually observe the input method context
- 1237. By Chris Coulson
-
Add CompositorObserver and make RWHV use this, rather than relying on WebView to proxy DidCommit to it
- 1238. By Chris Coulson
-
Fix a -Wreorder warning
- 1239. By Chris Coulson
-
Don't call Show() or Hide() when setting the container
- 1240. By Chris Coulson
-
We only need to set the RWHV visibility / focus for the first view
Preview Diff
1 | === added directory 'qt/core/browser/input' |
2 | === added file 'qt/core/browser/input/oxide_qt_input_method_context.cc' |
3 | --- qt/core/browser/input/oxide_qt_input_method_context.cc 1970-01-01 00:00:00 +0000 |
4 | +++ qt/core/browser/input/oxide_qt_input_method_context.cc 2015-10-21 17:31:00 +0000 |
5 | @@ -0,0 +1,424 @@ |
6 | +// vim:expandtab:shiftwidth=2:tabstop=2: |
7 | +// Copyright (C) 2015 Canonical Ltd. |
8 | + |
9 | +// This library is free software; you can redistribute it and/or |
10 | +// modify it under the terms of the GNU Lesser General Public |
11 | +// License as published by the Free Software Foundation; either |
12 | +// version 2.1 of the License, or (at your option) any later version. |
13 | + |
14 | +// This library is distributed in the hope that it will be useful, |
15 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 | +// Lesser General Public License for more details. |
18 | + |
19 | +// You should have received a copy of the GNU Lesser General Public |
20 | +// License along with this library; if not, write to the Free Software |
21 | +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
22 | + |
23 | +#include "oxide_qt_input_method_context.h" |
24 | + |
25 | +#include <string> |
26 | +#include <vector> |
27 | + |
28 | +#include <QFocusEvent> |
29 | +#include <QGuiApplication> |
30 | +#include <QInputMethod> |
31 | +#include <QInputMethodEvent> |
32 | +#include <QRect> |
33 | +#include <QString> |
34 | +#include <QTextCharFormat> |
35 | +#include <QWindow> |
36 | + |
37 | +#include "base/strings/utf_string_conversions.h" |
38 | +#include "third_party/skia/include/core/SkColor.h" |
39 | +#include "third_party/WebKit/public/platform/WebColor.h" |
40 | +#include "third_party/WebKit/public/web/WebCompositionUnderline.h" |
41 | +#include "ui/base/ime/text_input_type.h" |
42 | +#include "ui/gfx/geometry/rect.h" |
43 | +#include "ui/gfx/range/range.h" |
44 | + |
45 | +#include "shared/browser/input/oxide_ime_bridge.h" |
46 | + |
47 | +#include "oxide_qt_input_method_context_client.h" |
48 | + |
49 | +namespace oxide { |
50 | +namespace qt { |
51 | + |
52 | +namespace { |
53 | + |
54 | +Qt::InputMethodHints QImHintsFromInputType(ui::TextInputType type) { |
55 | + switch (type) { |
56 | + case ui::TEXT_INPUT_TYPE_TEXT: |
57 | + case ui::TEXT_INPUT_TYPE_TEXT_AREA: |
58 | + case ui::TEXT_INPUT_TYPE_CONTENT_EDITABLE: |
59 | + return Qt::ImhPreferLowercase; |
60 | + case ui::TEXT_INPUT_TYPE_PASSWORD: |
61 | + return Qt::ImhHiddenText | Qt::ImhSensitiveData | |
62 | + Qt::ImhNoAutoUppercase | Qt::ImhPreferLowercase | |
63 | + Qt::ImhNoPredictiveText; |
64 | + case ui::TEXT_INPUT_TYPE_SEARCH: |
65 | + return Qt::ImhNoAutoUppercase | Qt::ImhPreferLowercase; |
66 | + case ui::TEXT_INPUT_TYPE_EMAIL: |
67 | + return Qt::ImhEmailCharactersOnly; |
68 | + case ui::TEXT_INPUT_TYPE_NUMBER: |
69 | + return Qt::ImhFormattedNumbersOnly; |
70 | + case ui::TEXT_INPUT_TYPE_TELEPHONE: |
71 | + return Qt::ImhDialableCharactersOnly; |
72 | + case ui::TEXT_INPUT_TYPE_URL: |
73 | + return Qt::ImhUrlCharactersOnly; |
74 | + case ui::TEXT_INPUT_TYPE_DATE: |
75 | + case ui::TEXT_INPUT_TYPE_MONTH: |
76 | + case ui::TEXT_INPUT_TYPE_WEEK: |
77 | + return Qt::ImhDate; |
78 | + case ui::TEXT_INPUT_TYPE_DATE_TIME: |
79 | + case ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL: |
80 | + case ui::TEXT_INPUT_TYPE_DATE_TIME_FIELD: |
81 | + return Qt::ImhDate | Qt::ImhTime; |
82 | + case ui::TEXT_INPUT_TYPE_TIME: |
83 | + return Qt::ImhTime; |
84 | + default: |
85 | + return Qt::ImhNone; |
86 | + } |
87 | +} |
88 | + |
89 | +} |
90 | + |
91 | +void InputMethodContext::OnInputPanelVisibilityChanged() { |
92 | +} |
93 | + |
94 | +bool InputMethodContext::ShouldShowInputPanel() const { |
95 | + if (!ime_bridge()) { |
96 | + return false; |
97 | + } |
98 | + |
99 | + if (ime_bridge()->text_input_type() != ui::TEXT_INPUT_TYPE_NONE && |
100 | + ime_bridge()->show_ime_if_needed() && |
101 | + ime_bridge()->focused_node_is_editable()) { |
102 | + return true; |
103 | + } |
104 | + |
105 | + return false; |
106 | +} |
107 | + |
108 | +bool InputMethodContext::ShouldHideInputPanel() const { |
109 | + if (!ime_bridge()) { |
110 | + return true; |
111 | + } |
112 | + |
113 | + if (ime_bridge()->text_input_type() == ui::TEXT_INPUT_TYPE_NONE && |
114 | + !ime_bridge()->focused_node_is_editable()) { |
115 | + return true; |
116 | + } |
117 | + |
118 | + return false; |
119 | +} |
120 | + |
121 | +void InputMethodContext::SetInputPanelVisibility(bool visible) { |
122 | + client_->SetInputMethodEnabled(visible); |
123 | + |
124 | + if (!visible) { |
125 | + has_input_method_state_ = false; |
126 | + } |
127 | + |
128 | + // Do not check whether the input method is currently visible here, to avoid |
129 | + // a possible race condition: if hide() and show() are called very quickly |
130 | + // in a row, when show() is called the hide() request might not have |
131 | + // completed yet, and isVisible() could return true. |
132 | + // See https://launchpad.net/bugs/1377755 |
133 | + QInputMethod* im = QGuiApplication::inputMethod(); |
134 | + if (im) { |
135 | + im->setVisible(visible); |
136 | + } |
137 | +} |
138 | + |
139 | +bool InputMethodContext::IsInputPanelVisible() const { |
140 | + QInputMethod* im = QGuiApplication::inputMethod(); |
141 | + if (!im) { |
142 | + return false; |
143 | + } |
144 | + |
145 | + return im->isVisible(); |
146 | +} |
147 | + |
148 | +void InputMethodContext::TextInputStateChanged() { |
149 | + if (!client_) { |
150 | + return; |
151 | + } |
152 | + |
153 | + if (!client_->HasFocus()) { |
154 | + return; |
155 | + } |
156 | + |
157 | + // Don't notify if type is none. See https://launchpad.net/bugs/1381083 |
158 | + if (ime_bridge() && |
159 | + ime_bridge()->text_input_type() != ui::TEXT_INPUT_TYPE_NONE) { |
160 | + QGuiApplication::inputMethod()->update( |
161 | + static_cast<Qt::InputMethodQueries>(Qt::ImQueryInput | Qt::ImHints)); |
162 | + } |
163 | + |
164 | + if (ShouldShowInputPanel()) { |
165 | + SetInputPanelVisibility(true); |
166 | + } else if (ShouldHideInputPanel()) { |
167 | + SetInputPanelVisibility(false); |
168 | + } |
169 | +} |
170 | + |
171 | +void InputMethodContext::SelectionBoundsChanged() { |
172 | + if (!client_) { |
173 | + return; |
174 | + } |
175 | + |
176 | + if (!client_->HasFocus()) { |
177 | + return; |
178 | + } |
179 | + |
180 | + QInputMethod* im = QGuiApplication::inputMethod(); |
181 | + if (!im) { |
182 | + return; |
183 | + } |
184 | + |
185 | + im->update(static_cast<Qt::InputMethodQueries>( |
186 | + Qt::ImCursorRectangle |
187 | + | Qt::ImCursorPosition |
188 | + | Qt::ImAnchorPosition |
189 | +#if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0) |
190 | + | Qt::ImTextBeforeCursor |
191 | + | Qt::ImTextAfterCursor |
192 | +#endif |
193 | + )); |
194 | +} |
195 | + |
196 | +void InputMethodContext::SelectionChanged() { |
197 | + if (!client_) { |
198 | + return; |
199 | + } |
200 | + |
201 | + if (!client_->HasFocus()) { |
202 | + return; |
203 | + } |
204 | + |
205 | + QInputMethod* im = QGuiApplication::inputMethod(); |
206 | + if (!im) { |
207 | + return; |
208 | + } |
209 | + |
210 | + im->update(static_cast<Qt::InputMethodQueries>( |
211 | + Qt::ImSurroundingText |
212 | + | Qt::ImCurrentSelection |
213 | +#if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0) |
214 | + | Qt::ImTextBeforeCursor |
215 | + | Qt::ImTextAfterCursor |
216 | +#endif |
217 | + )); |
218 | +} |
219 | + |
220 | +void InputMethodContext::CancelComposition() { |
221 | + if (!has_input_method_state_) { |
222 | + return; |
223 | + } |
224 | + |
225 | + QInputMethod* im = QGuiApplication::inputMethod(); |
226 | + if (!im) { |
227 | + return; |
228 | + } |
229 | + |
230 | + im->reset(); |
231 | +} |
232 | + |
233 | +void InputMethodContext::FocusedNodeChanged() { |
234 | + if (!client_) { |
235 | + return; |
236 | + } |
237 | + |
238 | + // Work around for https://launchpad.net/bugs/1323743 |
239 | + if (QGuiApplication::focusWindow() && |
240 | + QGuiApplication::focusWindow()->focusObject()) { |
241 | + QGuiApplication::focusWindow()->focusObjectChanged( |
242 | + QGuiApplication::focusWindow()->focusObject()); |
243 | + } |
244 | + |
245 | + if (ShouldHideInputPanel() && client_->HasFocus()) { |
246 | + SetInputPanelVisibility(false); |
247 | + } else if (!has_input_method_state_ && ShouldShowInputPanel()) { |
248 | + // See https://launchpad.net/bugs/1400372 |
249 | + SetInputPanelVisibility(true); |
250 | + } else if (has_input_method_state_ && |
251 | + ime_bridge() && |
252 | + ime_bridge()->focused_node_is_editable() && |
253 | + QGuiApplication::inputMethod()) { |
254 | + QGuiApplication::inputMethod()->reset(); |
255 | + } |
256 | +} |
257 | + |
258 | +InputMethodContext::InputMethodContext(InputMethodContextClient* client) |
259 | + : client_(client), |
260 | + has_input_method_state_(false) { |
261 | + QInputMethod* im = QGuiApplication::inputMethod(); |
262 | + if (im) { |
263 | + connect(im, SIGNAL(visibleChanged()), |
264 | + SLOT(OnInputPanelVisibilityChanged())); |
265 | + } |
266 | +} |
267 | + |
268 | +InputMethodContext::~InputMethodContext() { |
269 | + QInputMethod* im = QGuiApplication::inputMethod(); |
270 | + if (im) { |
271 | + im->disconnect(this); |
272 | + } |
273 | +} |
274 | + |
275 | +void InputMethodContext::DetachClient() { |
276 | + client_ = nullptr; |
277 | +} |
278 | + |
279 | +QVariant InputMethodContext::Query(Qt::InputMethodQuery query) const { |
280 | + switch (query) { |
281 | + case Qt::ImHints: |
282 | + if (!ime_bridge()) { |
283 | + return QVariant(QImHintsFromInputType(ui::TEXT_INPUT_TYPE_NONE)); |
284 | + } |
285 | + return QVariant(QImHintsFromInputType(ime_bridge()->text_input_type())); |
286 | + case Qt::ImCursorRectangle: { |
287 | + if (!ime_bridge()) { |
288 | + return QRect(); |
289 | + } |
290 | + // XXX: Is this in the right coordinate space? |
291 | + return QRect(ime_bridge()->caret_rect().x(), |
292 | + ime_bridge()->caret_rect().y(), |
293 | + ime_bridge()->caret_rect().width(), |
294 | + ime_bridge()->caret_rect().height()); |
295 | + } |
296 | + case Qt::ImCursorPosition: |
297 | + if (!ime_bridge()) { |
298 | + return 0; |
299 | + } |
300 | + return static_cast<int>(ime_bridge()->selection_cursor_position() & |
301 | + INT_MAX); |
302 | + case Qt::ImSurroundingText: |
303 | + if (!ime_bridge()) { |
304 | + return QString(); |
305 | + } |
306 | + return QString::fromStdString( |
307 | + base::UTF16ToUTF8(ime_bridge()->GetSelectionText())); |
308 | + case Qt::ImCurrentSelection: |
309 | + if (!ime_bridge()) { |
310 | + return QString(); |
311 | + } |
312 | + return QString::fromStdString( |
313 | + base::UTF16ToUTF8(ime_bridge()->GetSelectedText())); |
314 | + case Qt::ImAnchorPosition: |
315 | + if (!ime_bridge()) { |
316 | + return 0; |
317 | + } |
318 | + return static_cast<int>(ime_bridge()->selection_anchor_position() & |
319 | + INT_MAX); |
320 | +#if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0) |
321 | + case Qt::ImTextBeforeCursor: { |
322 | + if (!ime_bridge()) { |
323 | + return QString(); |
324 | + } |
325 | + std::string text = base::UTF16ToUTF8(ime_bridge()->GetSelectionText()); |
326 | + return QString::fromStdString( |
327 | + text.substr(0, ime_bridge()->selection_cursor_position())); |
328 | + } |
329 | + case Qt::ImTextAfterCursor: { |
330 | + if (!ime_bridge()) { |
331 | + return QString(); |
332 | + } |
333 | + std::string text = base::UTF16ToUTF8(ime_bridge()->GetSelectionText()); |
334 | + if (ime_bridge()->selection_cursor_position() > text.length()) { |
335 | + return QString(); |
336 | + } |
337 | + return QString::fromStdString( |
338 | + text.substr(ime_bridge()->selection_cursor_position(), |
339 | + std::string::npos)); |
340 | + } |
341 | +#endif |
342 | + default: |
343 | + break; |
344 | + } |
345 | + |
346 | + return QVariant(); |
347 | +} |
348 | + |
349 | +void InputMethodContext::FocusChanged(QFocusEvent* event) { |
350 | + if (!event->gotFocus()) { |
351 | + return; |
352 | + } |
353 | + |
354 | + if (!ShouldShowInputPanel()) { |
355 | + return; |
356 | + } |
357 | + |
358 | + SetInputPanelVisibility(true); |
359 | +} |
360 | + |
361 | +void InputMethodContext::HandleEvent(QInputMethodEvent* event) { |
362 | + QString commit_string = event->commitString(); |
363 | + |
364 | + if (!commit_string.isEmpty()) { |
365 | + gfx::Range replacement_range = gfx::Range::InvalidRange(); |
366 | + if (event->replacementLength() > 0) { |
367 | + replacement_range.set_start(event->replacementStart()); |
368 | + replacement_range.set_end(event->replacementStart() + |
369 | + event->replacementLength()); |
370 | + } |
371 | + if (ime_bridge()) { |
372 | + ime_bridge()->CommitText(base::UTF8ToUTF16(commit_string.toStdString()), |
373 | + replacement_range); |
374 | + } |
375 | + } |
376 | + |
377 | + QString preedit_string = event->preeditString(); |
378 | + |
379 | + std::vector<blink::WebCompositionUnderline> underlines; |
380 | + int cursor_position = -1; |
381 | + gfx::Range selection_range = gfx::Range::InvalidRange(); |
382 | + |
383 | + for (const auto& attribute : event->attributes()) { |
384 | + switch (attribute.type) { |
385 | + case QInputMethodEvent::Cursor: |
386 | + if (attribute.length > 0) { |
387 | + cursor_position = attribute.start; |
388 | + } |
389 | + break; |
390 | + case QInputMethodEvent::Selection: |
391 | + selection_range.set_start( |
392 | + qMin(attribute.start, (attribute.start + attribute.length))); |
393 | + selection_range.set_end( |
394 | + qMax(attribute.start, (attribute.start + attribute.length))); |
395 | + break; |
396 | + case QInputMethodEvent::TextFormat: { |
397 | + QTextCharFormat format = |
398 | + attribute.value.value<QTextFormat>().toCharFormat(); |
399 | + blink::WebColor color = format.underlineColor().rgba(); |
400 | + int start = qMin(attribute.start, (attribute.start + attribute.length)); |
401 | + int end = qMax(attribute.start, (attribute.start + attribute.length)); |
402 | + blink::WebCompositionUnderline underline( |
403 | + start, end, color, false, SK_ColorTRANSPARENT); |
404 | + underlines.push_back(underline); |
405 | + break; |
406 | + } |
407 | + default: |
408 | + break; |
409 | + } |
410 | + } |
411 | + |
412 | + if (!selection_range.IsValid()) { |
413 | + selection_range = |
414 | + gfx::Range(cursor_position > 0 ? |
415 | + cursor_position : |
416 | + preedit_string.length()); |
417 | + } |
418 | + |
419 | + if (ime_bridge()) { |
420 | + ime_bridge()->SetComposingText( |
421 | + base::UTF8ToUTF16(preedit_string.toStdString()), |
422 | + underlines, selection_range); |
423 | + } |
424 | + |
425 | + has_input_method_state_ = !preedit_string.isEmpty(); |
426 | +} |
427 | + |
428 | +} // namespace qt |
429 | +} // namespace oxide |
430 | |
431 | === added file 'qt/core/browser/input/oxide_qt_input_method_context.h' |
432 | --- qt/core/browser/input/oxide_qt_input_method_context.h 1970-01-01 00:00:00 +0000 |
433 | +++ qt/core/browser/input/oxide_qt_input_method_context.h 2015-10-21 17:31:00 +0000 |
434 | @@ -0,0 +1,82 @@ |
435 | +// vim:expandtab:shiftwidth=2:tabstop=2: |
436 | +// Copyright (C) 2015 Canonical Ltd. |
437 | + |
438 | +// This library is free software; you can redistribute it and/or |
439 | +// modify it under the terms of the GNU Lesser General Public |
440 | +// License as published by the Free Software Foundation; either |
441 | +// version 2.1 of the License, or (at your option) any later version. |
442 | + |
443 | +// This library is distributed in the hope that it will be useful, |
444 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
445 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
446 | +// Lesser General Public License for more details. |
447 | + |
448 | +// You should have received a copy of the GNU Lesser General Public |
449 | +// License along with this library; if not, write to the Free Software |
450 | +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
451 | + |
452 | +#ifndef _OXIDE_QT_CORE_BROWSER_INPUT_INPUT_METHOD_CONTEXT_H_ |
453 | +#define _OXIDE_QT_CORE_BROWSER_INPUT_INPUT_METHOD_CONTEXT_H_ |
454 | + |
455 | +#include <QObject> |
456 | +#include <QtGlobal> |
457 | +#include <QVariant> |
458 | + |
459 | +#include "base/macros.h" |
460 | + |
461 | +#include "shared/browser/input/oxide_input_method_context.h" |
462 | + |
463 | +QT_BEGIN_NAMESPACE |
464 | +class QFocusEvent; |
465 | +class QInputMethodEvent; |
466 | +QT_END_NAMESPACE |
467 | + |
468 | +namespace oxide { |
469 | +namespace qt { |
470 | + |
471 | +class InputMethodContextClient; |
472 | + |
473 | +class InputMethodContext : public QObject, |
474 | + public oxide::InputMethodContext { |
475 | + Q_OBJECT |
476 | + |
477 | + public: |
478 | + InputMethodContext(InputMethodContextClient* client); |
479 | + ~InputMethodContext() override; |
480 | + |
481 | + QVariant Query(Qt::InputMethodQuery query) const; |
482 | + |
483 | + // Null out |client_| to prevent calls back in to it during its destructor |
484 | + void DetachClient(); |
485 | + |
486 | + void FocusChanged(QFocusEvent* event); |
487 | + void HandleEvent(QInputMethodEvent* event); |
488 | + |
489 | + private Q_SLOTS: |
490 | + void OnInputPanelVisibilityChanged(); |
491 | + |
492 | + private: |
493 | + bool ShouldShowInputPanel() const; |
494 | + bool ShouldHideInputPanel() const; |
495 | + |
496 | + void SetInputPanelVisibility(bool visible); |
497 | + |
498 | + // oxide::InputMethodContext implementation |
499 | + bool IsInputPanelVisible() const override; |
500 | + void TextInputStateChanged() override; |
501 | + void SelectionBoundsChanged() override; |
502 | + void SelectionChanged() override; |
503 | + void CancelComposition() override; |
504 | + void FocusedNodeChanged() override; |
505 | + |
506 | + InputMethodContextClient* client_; // Owns us |
507 | + |
508 | + bool has_input_method_state_; |
509 | + |
510 | + DISALLOW_COPY_AND_ASSIGN(InputMethodContext); |
511 | +}; |
512 | + |
513 | +} // namespace qt |
514 | +} // namespace oxide |
515 | + |
516 | +#endif // _OXIDE_QT_CORE_BROWSER_INPUT_INPUT_METHOD_CONTEXT_H_ |
517 | |
518 | === added file 'qt/core/browser/input/oxide_qt_input_method_context_client.h' |
519 | --- qt/core/browser/input/oxide_qt_input_method_context_client.h 1970-01-01 00:00:00 +0000 |
520 | +++ qt/core/browser/input/oxide_qt_input_method_context_client.h 2015-10-21 17:31:00 +0000 |
521 | @@ -0,0 +1,36 @@ |
522 | +// vim:expandtab:shiftwidth=2:tabstop=2: |
523 | +// Copyright (C) 2015 Canonical Ltd. |
524 | + |
525 | +// This library is free software; you can redistribute it and/or |
526 | +// modify it under the terms of the GNU Lesser General Public |
527 | +// License as published by the Free Software Foundation; either |
528 | +// version 2.1 of the License, or (at your option) any later version. |
529 | + |
530 | +// This library is distributed in the hope that it will be useful, |
531 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
532 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
533 | +// Lesser General Public License for more details. |
534 | + |
535 | +// You should have received a copy of the GNU Lesser General Public |
536 | +// License along with this library; if not, write to the Free Software |
537 | +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
538 | + |
539 | +#ifndef _OXIDE_QT_CORE_BROWSER_INPUT_INPUT_METHOD_CONTEXT_CLIENT_H_ |
540 | +#define _OXIDE_QT_CORE_BROWSER_INPUT_INPUT_METHOD_CONTEXT_CLIENT_H_ |
541 | + |
542 | +namespace oxide { |
543 | +namespace qt { |
544 | + |
545 | +class InputMethodContextClient { |
546 | + public: |
547 | + virtual ~InputMethodContextClient() {} |
548 | + |
549 | + virtual bool HasFocus() const = 0; |
550 | + |
551 | + virtual void SetInputMethodEnabled(bool enabled) = 0; |
552 | +}; |
553 | + |
554 | +} // namespace qt |
555 | +} // namespace oxide |
556 | + |
557 | +#endif // _OXIDE_QT_CORE_BROWSER_INPUT_INPUT_METHOD_CONTEXT_CLIENT_H_ |
558 | |
559 | === modified file 'qt/core/browser/oxide_qt_web_view.cc' |
560 | --- qt/core/browser/oxide_qt_web_view.cc 2015-10-16 21:36:30 +0000 |
561 | +++ qt/core/browser/oxide_qt_web_view.cc 2015-10-21 17:31:00 +0000 |
562 | @@ -25,14 +25,12 @@ |
563 | #include <QCursor> |
564 | #include <QGuiApplication> |
565 | #include <QInputEvent> |
566 | -#include <QInputMethod> |
567 | #include <QKeyEvent> |
568 | +#include <QPixmap> |
569 | #include <QScreen> |
570 | #include <QString> |
571 | #include <QtDebug> |
572 | -#include <QTextCharFormat> |
573 | #include <QUrl> |
574 | -#include <QWindow> |
575 | |
576 | #include "base/logging.h" |
577 | #include "base/macros.h" |
578 | @@ -46,16 +44,12 @@ |
579 | #include "content/public/browser/navigation_controller.h" |
580 | #include "content/browser/web_contents/web_contents_impl.h" |
581 | #include "net/base/net_errors.h" |
582 | -#include "third_party/skia/include/core/SkColor.h" |
583 | -#include "third_party/WebKit/public/platform/WebColor.h" |
584 | #include "third_party/WebKit/public/platform/WebCursorInfo.h" |
585 | #include "third_party/WebKit/public/platform/WebTopControlsState.h" |
586 | -#include "ui/base/ime/text_input_type.h" |
587 | #include "ui/events/event.h" |
588 | #include "ui/gfx/geometry/point.h" |
589 | #include "ui/gfx/geometry/rect.h" |
590 | #include "ui/gfx/geometry/size.h" |
591 | -#include "ui/gfx/range/range.h" |
592 | #include "url/gurl.h" |
593 | |
594 | #include "qt/core/api/oxideqdownloadrequest.h" |
595 | @@ -74,6 +68,7 @@ |
596 | #include "qt/core/api/oxideqfindcontroller_p.h" |
597 | #include "qt/core/api/oxideqwebpreferences.h" |
598 | #include "qt/core/api/oxideqwebpreferences_p.h" |
599 | +#include "qt/core/browser/input/oxide_qt_input_method_context.h" |
600 | #include "qt/core/glue/oxide_qt_web_frame_proxy_client.h" |
601 | #include "qt/core/glue/oxide_qt_web_view_proxy_client.h" |
602 | #include "shared/browser/compositor/oxide_compositor_frame_data.h" |
603 | @@ -236,41 +231,6 @@ |
604 | return QCursor(cs); |
605 | } |
606 | |
607 | -Qt::InputMethodHints QImHintsFromInputType(ui::TextInputType type) { |
608 | - switch (type) { |
609 | - case ui::TEXT_INPUT_TYPE_TEXT: |
610 | - case ui::TEXT_INPUT_TYPE_TEXT_AREA: |
611 | - case ui::TEXT_INPUT_TYPE_CONTENT_EDITABLE: |
612 | - return Qt::ImhPreferLowercase; |
613 | - case ui::TEXT_INPUT_TYPE_PASSWORD: |
614 | - return Qt::ImhHiddenText | Qt::ImhSensitiveData | |
615 | - Qt::ImhNoAutoUppercase | Qt::ImhPreferLowercase | |
616 | - Qt::ImhNoPredictiveText; |
617 | - case ui::TEXT_INPUT_TYPE_SEARCH: |
618 | - return Qt::ImhNoAutoUppercase | Qt::ImhPreferLowercase; |
619 | - case ui::TEXT_INPUT_TYPE_EMAIL: |
620 | - return Qt::ImhEmailCharactersOnly; |
621 | - case ui::TEXT_INPUT_TYPE_NUMBER: |
622 | - return Qt::ImhFormattedNumbersOnly; |
623 | - case ui::TEXT_INPUT_TYPE_TELEPHONE: |
624 | - return Qt::ImhDialableCharactersOnly; |
625 | - case ui::TEXT_INPUT_TYPE_URL: |
626 | - return Qt::ImhUrlCharactersOnly; |
627 | - case ui::TEXT_INPUT_TYPE_DATE: |
628 | - case ui::TEXT_INPUT_TYPE_MONTH: |
629 | - case ui::TEXT_INPUT_TYPE_WEEK: |
630 | - return Qt::ImhDate; |
631 | - case ui::TEXT_INPUT_TYPE_DATE_TIME: |
632 | - case ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL: |
633 | - case ui::TEXT_INPUT_TYPE_DATE_TIME_FIELD: |
634 | - return Qt::ImhDate | Qt::ImhTime; |
635 | - case ui::TEXT_INPUT_TYPE_TIME: |
636 | - return Qt::ImhTime; |
637 | - default: |
638 | - return Qt::ImhNone; |
639 | - } |
640 | -} |
641 | - |
642 | static const char* STATE_SERIALIZER_MAGIC_NUMBER = "oxide"; |
643 | static uint16_t STATE_SERIALIZER_VERSION = 1; |
644 | |
645 | @@ -429,22 +389,12 @@ |
646 | QRect rect_; |
647 | }; |
648 | |
649 | -void WebView::OnInputPanelVisibilityChanged() { |
650 | - view_->InputPanelVisibilityChanged(); |
651 | -} |
652 | - |
653 | WebView::WebView(WebViewProxyClient* client, |
654 | OxideQSecurityStatus* security_status) |
655 | - : client_(client), |
656 | - has_input_method_state_(false), |
657 | + : input_method_context_(new InputMethodContext(this)), |
658 | + client_(client), |
659 | security_status_(security_status), |
660 | - frame_tree_torn_down_(false) { |
661 | - QInputMethod* im = QGuiApplication::inputMethod(); |
662 | - if (im) { |
663 | - connect(im, SIGNAL(visibleChanged()), |
664 | - SLOT(OnInputPanelVisibilityChanged())); |
665 | - } |
666 | -} |
667 | + frame_tree_torn_down_(false) {} |
668 | |
669 | float WebView::GetDeviceScaleFactor() const { |
670 | QScreen* screen = client_->GetScreen(); |
671 | @@ -455,48 +405,6 @@ |
672 | return GetDeviceScaleFactorFromQScreen(screen); |
673 | } |
674 | |
675 | -bool WebView::ShouldShowInputPanel() const { |
676 | - if (!view_) { |
677 | - // Can be called during WebView construction when |view_| is still null. |
678 | - return false; |
679 | - } |
680 | - |
681 | - if (view_->text_input_type() != ui::TEXT_INPUT_TYPE_NONE && |
682 | - view_->show_ime_if_needed() && view_->focused_node_is_editable()) { |
683 | - return true; |
684 | - } |
685 | - |
686 | - return false; |
687 | -} |
688 | - |
689 | -bool WebView::ShouldHideInputPanel() const { |
690 | - if (!view_) { |
691 | - // Can be called during WebView construction when |view_| is still null. |
692 | - return true; |
693 | - } |
694 | - |
695 | - if (view_->text_input_type() == ui::TEXT_INPUT_TYPE_NONE && |
696 | - !view_->focused_node_is_editable()) { |
697 | - return true; |
698 | - } |
699 | - |
700 | - return false; |
701 | -} |
702 | - |
703 | -void WebView::SetInputPanelVisibility(bool visible) { |
704 | - client_->SetInputMethodEnabled(visible); |
705 | - |
706 | - if (!visible) { |
707 | - has_input_method_state_ = false; |
708 | - } |
709 | - |
710 | - // Do not check whether the input method is currently visible here, to avoid |
711 | - // a possible race condition: if hide() and show() are called very quickly |
712 | - // in a row, when show() is called the hide() request might not have |
713 | - // completed yet, and isVisible() could return true. |
714 | - QGuiApplication::inputMethod()->setVisible(visible); |
715 | -} |
716 | - |
717 | void WebView::CommonInit(OxideQFindController* find_controller) { |
718 | content::WebContents* contents = view_->GetWebContents(); |
719 | |
720 | @@ -524,6 +432,10 @@ |
721 | OxideQWebPreferencesPrivate::get(p)->preferences()); |
722 | } |
723 | |
724 | +void WebView::SetInputMethodEnabled(bool enabled) { |
725 | + client_->SetInputMethodEnabled(enabled); |
726 | +} |
727 | + |
728 | blink::WebScreenInfo WebView::GetScreenInfo() const { |
729 | QScreen* screen = client_->GetScreen(); |
730 | if (!screen) { |
731 | @@ -549,15 +461,6 @@ |
732 | return client_->HasFocus(); |
733 | } |
734 | |
735 | -bool WebView::IsInputPanelVisible() const { |
736 | - QInputMethod* im = QGuiApplication::inputMethod(); |
737 | - if (!im) { |
738 | - return false; |
739 | - } |
740 | - |
741 | - return im->isVisible(); |
742 | -} |
743 | - |
744 | oxide::JavaScriptDialog* WebView::CreateJavaScriptDialog( |
745 | content::JavaScriptMessageType javascript_message_type) { |
746 | JavaScriptDialogProxyClient::Type type; |
747 | @@ -918,77 +821,8 @@ |
748 | client_->EvictCurrentFrame(); |
749 | } |
750 | |
751 | -void WebView::TextInputStateChanged() { |
752 | - if (!HasFocus()) { |
753 | - return; |
754 | - } |
755 | - |
756 | - if (view_->text_input_type() != ui::TEXT_INPUT_TYPE_NONE) { |
757 | - QGuiApplication::inputMethod()->update( |
758 | - static_cast<Qt::InputMethodQueries>(Qt::ImQueryInput | Qt::ImHints)); |
759 | - } |
760 | - |
761 | - if (ShouldShowInputPanel()) { |
762 | - SetInputPanelVisibility(true); |
763 | - } else if (ShouldHideInputPanel()) { |
764 | - SetInputPanelVisibility(false); |
765 | - } |
766 | -} |
767 | - |
768 | -void WebView::FocusedNodeChanged() { |
769 | - // Work around for https://launchpad.net/bugs/1323743 |
770 | - if (QGuiApplication::focusWindow() && |
771 | - QGuiApplication::focusWindow()->focusObject()) { |
772 | - QGuiApplication::focusWindow()->focusObjectChanged( |
773 | - QGuiApplication::focusWindow()->focusObject()); |
774 | - } |
775 | - |
776 | - if (ShouldHideInputPanel() && HasFocus()) { |
777 | - SetInputPanelVisibility(false); |
778 | - } else if (!has_input_method_state_ && ShouldShowInputPanel()) { |
779 | - SetInputPanelVisibility(true); |
780 | - } else if (has_input_method_state_ && view_->focused_node_is_editable()) { |
781 | - QGuiApplication::inputMethod()->reset(); |
782 | - } |
783 | -} |
784 | - |
785 | -void WebView::SelectionBoundsChanged() { |
786 | - if (!HasFocus()) { |
787 | - return; |
788 | - } |
789 | - |
790 | - QGuiApplication::inputMethod()->update( |
791 | - static_cast<Qt::InputMethodQueries>( |
792 | - Qt::ImCursorRectangle |
793 | - | Qt::ImCursorPosition |
794 | - | Qt::ImAnchorPosition |
795 | -#if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0) |
796 | - | Qt::ImTextBeforeCursor |
797 | - | Qt::ImTextAfterCursor |
798 | -#endif |
799 | - )); |
800 | -} |
801 | - |
802 | -void WebView::ImeCancelComposition() { |
803 | - if (has_input_method_state_) { |
804 | - QGuiApplication::inputMethod()->reset(); |
805 | - } |
806 | -} |
807 | - |
808 | -void WebView::SelectionChanged() { |
809 | - if (!HasFocus()) { |
810 | - return; |
811 | - } |
812 | - |
813 | - QGuiApplication::inputMethod()->update( |
814 | - static_cast<Qt::InputMethodQueries>( |
815 | - Qt::ImSurroundingText |
816 | - | Qt::ImCurrentSelection |
817 | -#if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0) |
818 | - | Qt::ImTextBeforeCursor |
819 | - | Qt::ImTextAfterCursor |
820 | -#endif |
821 | - )); |
822 | +oxide::InputMethodContext* WebView::GetInputMethodContext() const { |
823 | + return input_method_context_.get(); |
824 | } |
825 | |
826 | void WebView::UpdateCursor(const content::WebCursor& cursor) { |
827 | @@ -1189,10 +1023,7 @@ |
828 | } |
829 | |
830 | void WebView::handleFocusEvent(QFocusEvent* event) { |
831 | - if (event->gotFocus() && ShouldShowInputPanel()) { |
832 | - SetInputPanelVisibility(true); |
833 | - } |
834 | - |
835 | + input_method_context_->FocusChanged(event); |
836 | view_->FocusChanged(); |
837 | } |
838 | |
839 | @@ -1208,62 +1039,7 @@ |
840 | } |
841 | |
842 | void WebView::handleInputMethodEvent(QInputMethodEvent* event) { |
843 | - QString commit_string = event->commitString(); |
844 | - |
845 | - if (!commit_string.isEmpty()) { |
846 | - gfx::Range replacement_range = gfx::Range::InvalidRange(); |
847 | - if (event->replacementLength() > 0) { |
848 | - replacement_range.set_start(event->replacementStart()); |
849 | - replacement_range.set_end(event->replacementStart() + |
850 | - event->replacementLength()); |
851 | - } |
852 | - view_->ImeCommitText(base::UTF8ToUTF16(commit_string.toStdString()), |
853 | - replacement_range); |
854 | - } |
855 | - |
856 | - QString preedit_string = event->preeditString(); |
857 | - |
858 | - std::vector<blink::WebCompositionUnderline> underlines; |
859 | - int cursor_position = -1; |
860 | - gfx::Range selection_range = gfx::Range::InvalidRange(); |
861 | - |
862 | - Q_FOREACH (const QInputMethodEvent::Attribute& attribute, event->attributes()) { |
863 | - switch (attribute.type) { |
864 | - case QInputMethodEvent::Cursor: |
865 | - if (attribute.length > 0) { |
866 | - cursor_position = attribute.start; |
867 | - } |
868 | - break; |
869 | - case QInputMethodEvent::Selection: |
870 | - selection_range.set_start( |
871 | - qMin(attribute.start, (attribute.start + attribute.length))); |
872 | - selection_range.set_end( |
873 | - qMax(attribute.start, (attribute.start + attribute.length))); |
874 | - break; |
875 | - case QInputMethodEvent::TextFormat: { |
876 | - QTextCharFormat format = |
877 | - attribute.value.value<QTextFormat>().toCharFormat(); |
878 | - blink::WebColor color = format.underlineColor().rgba(); |
879 | - int start = qMin(attribute.start, (attribute.start + attribute.length)); |
880 | - int end = qMax(attribute.start, (attribute.start + attribute.length)); |
881 | - blink::WebCompositionUnderline underline( |
882 | - start, end, color, false, SK_ColorTRANSPARENT); |
883 | - underlines.push_back(underline); |
884 | - break; |
885 | - } |
886 | - default: |
887 | - break; |
888 | - } |
889 | - } |
890 | - |
891 | - if (!selection_range.IsValid()) { |
892 | - selection_range = gfx::Range( |
893 | - cursor_position > 0 ? cursor_position : preedit_string.length()); |
894 | - } |
895 | - view_->ImeSetComposingText(base::UTF8ToUTF16(preedit_string.toStdString()), |
896 | - underlines, selection_range); |
897 | - |
898 | - has_input_method_state_ = !preedit_string.isEmpty(); |
899 | + input_method_context_->HandleEvent(event); |
900 | } |
901 | |
902 | void WebView::handleKeyEvent(QKeyEvent* event) { |
903 | @@ -1313,42 +1089,7 @@ |
904 | } |
905 | |
906 | QVariant WebView::inputMethodQuery(Qt::InputMethodQuery query) const { |
907 | - switch (query) { |
908 | - case Qt::ImHints: |
909 | - return QVariant(QImHintsFromInputType(view_->text_input_type())); |
910 | - case Qt::ImCursorRectangle: { |
911 | - // XXX: Is this in the right coordinate space? |
912 | - return QRect(view_->caret_rect().x(), view_->caret_rect().y(), |
913 | - view_->caret_rect().width(), view_->caret_rect().height()); |
914 | - } |
915 | - case Qt::ImCursorPosition: |
916 | - return static_cast<int>(view_->selection_cursor_position() & INT_MAX); |
917 | - case Qt::ImSurroundingText: |
918 | - return QString::fromStdString(base::UTF16ToUTF8(view_->GetSelectionText())); |
919 | - case Qt::ImCurrentSelection: |
920 | - return QString::fromStdString(base::UTF16ToUTF8(view_->GetSelectedText())); |
921 | - case Qt::ImAnchorPosition: |
922 | - return static_cast<int>(view_->selection_anchor_position() & INT_MAX); |
923 | -#if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0) |
924 | - case Qt::ImTextBeforeCursor: { |
925 | - std::string text = base::UTF16ToUTF8(view_->GetSelectionText()); |
926 | - return QString::fromStdString( |
927 | - text.substr(0, view_->selection_cursor_position())); |
928 | - } |
929 | - case Qt::ImTextAfterCursor: { |
930 | - std::string text = base::UTF16ToUTF8(view_->GetSelectionText()); |
931 | - if (view_->selection_cursor_position() > text.length()) { |
932 | - return QString(); |
933 | - } |
934 | - return QString::fromStdString( |
935 | - text.substr(view_->selection_cursor_position(), std::string::npos)); |
936 | - } |
937 | -#endif |
938 | - default: |
939 | - break; |
940 | - } |
941 | - |
942 | - return QVariant(); |
943 | + return input_method_context_->Query(query); |
944 | } |
945 | |
946 | void WebView::goBack() { |
947 | @@ -1689,13 +1430,10 @@ |
948 | WebView::~WebView() { |
949 | DCHECK(frame_tree_torn_down_); |
950 | |
951 | + input_method_context_->DetachClient(); |
952 | + |
953 | oxide::PermissionRequestDispatcher::FromWebContents( |
954 | view_->GetWebContents())->set_client(nullptr); |
955 | - |
956 | - QInputMethod* im = QGuiApplication::inputMethod(); |
957 | - if (im) { |
958 | - im->disconnect(this); |
959 | - } |
960 | } |
961 | |
962 | // static |
963 | |
964 | === modified file 'qt/core/browser/oxide_qt_web_view.h' |
965 | --- qt/core/browser/oxide_qt_web_view.h 2015-10-16 21:36:30 +0000 |
966 | +++ qt/core/browser/oxide_qt_web_view.h 2015-10-21 17:31:00 +0000 |
967 | @@ -20,7 +20,6 @@ |
968 | |
969 | #include <QKeyEvent> |
970 | #include <QList> |
971 | -#include <QObject> |
972 | #include <QPointer> |
973 | #include <QSharedPointer> |
974 | #include <QtGlobal> |
975 | @@ -28,6 +27,7 @@ |
976 | #include "base/macros.h" |
977 | #include "base/memory/scoped_ptr.h" |
978 | |
979 | +#include "qt/core/browser/input/oxide_qt_input_method_context_client.h" |
980 | #include "qt/core/browser/oxide_qt_event_utils.h" |
981 | #include "qt/core/glue/oxide_qt_web_view_proxy.h" |
982 | #include "shared/browser/oxide_javascript_dialog_manager.h" |
983 | @@ -53,16 +53,15 @@ |
984 | namespace qt { |
985 | |
986 | class CompositorFrameHandle; |
987 | +class InputMethodContext; |
988 | class WebContext; |
989 | class WebViewProxyClient; |
990 | |
991 | -class WebView : public QObject, |
992 | +class WebView : public InputMethodContextClient, |
993 | public oxide::WebViewClient, |
994 | public oxide::PermissionRequestDispatcherClient, |
995 | public oxide::WebFrameTreeObserver, |
996 | public WebViewProxy { |
997 | - Q_OBJECT |
998 | - |
999 | public: |
1000 | WebView(WebViewProxyClient* client, |
1001 | OxideQFindController* find_controller, |
1002 | @@ -85,29 +84,24 @@ |
1003 | |
1004 | const oxide::SecurityStatus& GetSecurityStatus() const; |
1005 | |
1006 | - private Q_SLOTS: |
1007 | - void OnInputPanelVisibilityChanged(); |
1008 | - |
1009 | private: |
1010 | WebView(WebViewProxyClient* client, |
1011 | OxideQSecurityStatus* security_status); |
1012 | |
1013 | float GetDeviceScaleFactor() const; |
1014 | |
1015 | - bool ShouldShowInputPanel() const; |
1016 | - bool ShouldHideInputPanel() const; |
1017 | - void SetInputPanelVisibility(bool visible); |
1018 | - |
1019 | void CommonInit(OxideQFindController* find_controller); |
1020 | |
1021 | void EnsurePreferences(); |
1022 | |
1023 | + // InputMethodContextClient implementation |
1024 | + void SetInputMethodEnabled(bool enabled); |
1025 | + |
1026 | // oxide::WebViewClient implementation |
1027 | blink::WebScreenInfo GetScreenInfo() const override; |
1028 | gfx::Rect GetViewBoundsPix() const override; |
1029 | bool IsVisible() const override; |
1030 | bool HasFocus() const override; |
1031 | - bool IsInputPanelVisible() const override; |
1032 | oxide::JavaScriptDialog* CreateJavaScriptDialog( |
1033 | content::JavaScriptMessageType javascript_message_type) override; |
1034 | oxide::JavaScriptDialog* CreateBeforeUnloadDialog() override; |
1035 | @@ -169,11 +163,7 @@ |
1036 | oxide::FilePicker* CreateFilePicker(content::RenderViewHost* rvh) override; |
1037 | void SwapCompositorFrame() override; |
1038 | void EvictCurrentFrame() override; |
1039 | - void TextInputStateChanged() override; |
1040 | - void FocusedNodeChanged() override; |
1041 | - void SelectionBoundsChanged() override; |
1042 | - void ImeCancelComposition() override; |
1043 | - void SelectionChanged() override; |
1044 | + oxide::InputMethodContext* GetInputMethodContext() const override; |
1045 | void UpdateCursor(const content::WebCursor& cursor) override; |
1046 | void SecurityStatusChanged(const oxide::SecurityStatus& old) override; |
1047 | void OnCertificateError(scoped_ptr<oxide::CertificateError> error) override; |
1048 | @@ -293,12 +283,13 @@ |
1049 | |
1050 | void teardownFrameTree() override; |
1051 | |
1052 | + // This must outlive |view_| |
1053 | + scoped_ptr<InputMethodContext> input_method_context_; |
1054 | + |
1055 | scoped_ptr<oxide::WebView> view_; |
1056 | |
1057 | WebViewProxyClient* client_; |
1058 | |
1059 | - bool has_input_method_state_; |
1060 | - |
1061 | QPointer<OxideQSecurityStatus> security_status_; |
1062 | QList<ScriptMessageHandlerProxyHandle*> message_handlers_; |
1063 | |
1064 | |
1065 | === modified file 'qt/core/core.gyp' |
1066 | --- qt/core/core.gyp 2015-09-20 08:39:19 +0000 |
1067 | +++ qt/core/core.gyp 2015-10-21 17:31:00 +0000 |
1068 | @@ -61,13 +61,16 @@ |
1069 | ], |
1070 | 'sources': [ |
1071 | '<(INTERMEDIATE_DIR)/moc_oxide_qt_browser_platform_integration.cc', |
1072 | - '<(INTERMEDIATE_DIR)/moc_oxide_qt_web_view.cc', |
1073 | + '<(INTERMEDIATE_DIR)/moc_oxide_qt_input_method_context.cc', |
1074 | 'api/internal/oxideqmediacapturedevices_p.cc', |
1075 | 'api/internal/oxideqwebpreferences_p.cc', |
1076 | 'app/oxide_qt_main.cc', |
1077 | 'app/oxide_qt_main.h', |
1078 | 'app/oxide_qt_platform_delegate.cc', |
1079 | 'app/oxide_qt_platform_delegate.h', |
1080 | + 'browser/input/oxide_qt_input_method_context.cc', |
1081 | + 'browser/input/oxide_qt_input_method_context.h', |
1082 | + 'browser/input/oxide_qt_input_method_context_client.h', |
1083 | 'browser/oxide_qt_browser_platform_integration.cc', |
1084 | 'browser/oxide_qt_browser_platform_integration.h', |
1085 | 'browser/oxide_qt_browser_startup.cc', |
1086 | @@ -179,8 +182,8 @@ |
1087 | 'includes': [ 'moc.gypi' ] |
1088 | }, |
1089 | { |
1090 | - 'action_name': 'moc_oxide_qt_web_view.cc', |
1091 | - 'moc_input': 'browser/oxide_qt_web_view.h', |
1092 | + 'action_name': 'moc_oxide_qt_input_method_context.cc', |
1093 | + 'moc_input': 'browser/input/oxide_qt_input_method_context.h', |
1094 | 'includes': [ 'moc.gypi' ] |
1095 | }, |
1096 | ], |
1097 | |
1098 | === modified file 'shared/browser/compositor/oxide_compositor.cc' |
1099 | --- shared/browser/compositor/oxide_compositor.cc 2015-10-09 09:27:28 +0000 |
1100 | +++ shared/browser/compositor/oxide_compositor.cc 2015-10-21 17:31:00 +0000 |
1101 | @@ -40,6 +40,7 @@ |
1102 | #include "oxide_compositor_client.h" |
1103 | #include "oxide_compositor_frame_data.h" |
1104 | #include "oxide_compositor_frame_handle.h" |
1105 | +#include "oxide_compositor_observer.h" |
1106 | #include "oxide_compositor_output_surface_gl.h" |
1107 | #include "oxide_compositor_output_surface_software.h" |
1108 | #include "oxide_compositor_software_output_device.h" |
1109 | @@ -87,7 +88,6 @@ |
1110 | root_layer_(cc::Layer::Create(cc::LayerSettings())), |
1111 | proxy_(new CompositorThreadProxy(this)), |
1112 | next_output_surface_id_(1), |
1113 | - lock_count_(0), |
1114 | weak_factory_(this) { |
1115 | DCHECK(CalledOnValidThread()); |
1116 | } |
1117 | @@ -103,29 +103,6 @@ |
1118 | client_->CompositorSwapFrame(handle.get()); |
1119 | } |
1120 | |
1121 | -void Compositor::LockCompositor() { |
1122 | - DCHECK(CalledOnValidThread()); |
1123 | - if (lock_count_++ > 0) { |
1124 | - return; |
1125 | - } |
1126 | - |
1127 | - if (layer_tree_host_) { |
1128 | - layer_tree_host_->SetDeferCommits(true); |
1129 | - } |
1130 | -} |
1131 | - |
1132 | -void Compositor::UnlockCompositor() { |
1133 | - DCHECK(CalledOnValidThread()); |
1134 | - DCHECK(lock_count_ > 0); |
1135 | - if (--lock_count_ > 0) { |
1136 | - return; |
1137 | - } |
1138 | - |
1139 | - if (layer_tree_host_) { |
1140 | - layer_tree_host_->SetDeferCommits(false); |
1141 | - } |
1142 | -} |
1143 | - |
1144 | scoped_ptr<cc::OutputSurface> Compositor::CreateOutputSurface() { |
1145 | DCHECK(CalledOnValidThread()); |
1146 | |
1147 | @@ -155,6 +132,14 @@ |
1148 | return output.Pass(); |
1149 | } |
1150 | |
1151 | +void Compositor::AddObserver(CompositorObserver* observer) { |
1152 | + observers_.AddObserver(observer); |
1153 | +} |
1154 | + |
1155 | +void Compositor::RemoveObserver(CompositorObserver* observer) { |
1156 | + observers_.RemoveObserver(observer); |
1157 | +} |
1158 | + |
1159 | void Compositor::WillBeginMainFrame() {} |
1160 | void Compositor::BeginMainFrame(const cc::BeginFrameArgs& args) {} |
1161 | void Compositor::BeginMainFrameNotExpectedSoon() {} |
1162 | @@ -194,7 +179,7 @@ |
1163 | void Compositor::WillCommit() {} |
1164 | |
1165 | void Compositor::DidCommit() { |
1166 | - client_->CompositorDidCommit(); |
1167 | + FOR_EACH_OBSERVER(CompositorObserver, observers_, CompositorDidCommit()); |
1168 | } |
1169 | |
1170 | void Compositor::DidCommitAndDrawFrame() {} |
1171 | @@ -214,7 +199,7 @@ |
1172 | } |
1173 | |
1174 | Compositor::~Compositor() { |
1175 | - CHECK_EQ(lock_count_, 0U); |
1176 | + FOR_EACH_OBSERVER(CompositorObserver, observers_, OnCompositorDestruction()); |
1177 | proxy_->CompositorDestroyed(); |
1178 | } |
1179 | |
1180 | @@ -249,15 +234,15 @@ |
1181 | layer_tree_host_->SetVisible(true); |
1182 | layer_tree_host_->SetViewportSize(size_); |
1183 | layer_tree_host_->SetDeviceScaleFactor(device_scale_factor_); |
1184 | - |
1185 | - if (lock_count_ > 0) { |
1186 | - layer_tree_host_->SetDeferCommits(true); |
1187 | - } |
1188 | } |
1189 | } |
1190 | |
1191 | void Compositor::SetDeviceScaleFactor(float scale) { |
1192 | DCHECK(CalledOnValidThread()); |
1193 | + if (scale == device_scale_factor_) { |
1194 | + return; |
1195 | + } |
1196 | + |
1197 | device_scale_factor_ = scale; |
1198 | |
1199 | if (layer_tree_host_) { |
1200 | @@ -281,6 +266,7 @@ |
1201 | |
1202 | void Compositor::SetRootLayer(scoped_refptr<cc::Layer> layer) { |
1203 | DCHECK(CalledOnValidThread()); |
1204 | + |
1205 | root_layer_->RemoveAllChildren(); |
1206 | if (layer.get()) { |
1207 | root_layer_->AddChild(layer); |
1208 | |
1209 | === modified file 'shared/browser/compositor/oxide_compositor.h' |
1210 | --- shared/browser/compositor/oxide_compositor.h 2015-08-14 16:32:46 +0000 |
1211 | +++ shared/browser/compositor/oxide_compositor.h 2015-10-21 17:31:00 +0000 |
1212 | @@ -23,6 +23,7 @@ |
1213 | #include "base/memory/scoped_ptr.h" |
1214 | #include "base/memory/scoped_vector.h" |
1215 | #include "base/memory/weak_ptr.h" |
1216 | +#include "base/observer_list.h" |
1217 | #include "base/threading/non_thread_safe.h" |
1218 | #include "cc/trees/layer_tree_host_client.h" |
1219 | #include "ui/gfx/geometry/size.h" |
1220 | @@ -41,7 +42,7 @@ |
1221 | class CompositorClient; |
1222 | class CompositorFrameData; |
1223 | class CompositorFrameHandle; |
1224 | -class CompositorLock; |
1225 | +class CompositorObserver; |
1226 | class CompositorThreadProxy; |
1227 | |
1228 | class Compositor final : public cc::LayerTreeHostClient, |
1229 | @@ -63,18 +64,18 @@ |
1230 | FrameHandleVector returned_frames); |
1231 | |
1232 | private: |
1233 | - friend class CompositorLock; |
1234 | + friend class CompositorObserver; |
1235 | friend class CompositorThreadProxy; |
1236 | |
1237 | Compositor(CompositorClient* client); |
1238 | |
1239 | void SendSwapCompositorFrameToClient(scoped_ptr<CompositorFrameData> frame); |
1240 | |
1241 | - void LockCompositor(); |
1242 | - void UnlockCompositor(); |
1243 | - |
1244 | scoped_ptr<cc::OutputSurface> CreateOutputSurface(); |
1245 | |
1246 | + void AddObserver(CompositorObserver* observer); |
1247 | + void RemoveObserver(CompositorObserver* observer); |
1248 | + |
1249 | // cc::LayerTreeHostClient implementation |
1250 | void WillBeginMainFrame() final; |
1251 | void BeginMainFrame(const cc::BeginFrameArgs& args) final; |
1252 | @@ -112,34 +113,13 @@ |
1253 | |
1254 | uint32 next_output_surface_id_; |
1255 | |
1256 | - uint32 lock_count_; |
1257 | + base::ObserverList<CompositorObserver> observers_; |
1258 | |
1259 | base::WeakPtrFactory<Compositor> weak_factory_; |
1260 | |
1261 | DISALLOW_COPY_AND_ASSIGN(Compositor); |
1262 | }; |
1263 | |
1264 | -class CompositorLock final { |
1265 | - public: |
1266 | - CompositorLock(Compositor* compositor) |
1267 | - : compositor_(compositor) { |
1268 | - if (compositor_) { |
1269 | - compositor_->LockCompositor(); |
1270 | - } |
1271 | - } |
1272 | - |
1273 | - ~CompositorLock() { |
1274 | - if (compositor_) { |
1275 | - compositor_->UnlockCompositor(); |
1276 | - } |
1277 | - } |
1278 | - |
1279 | - private: |
1280 | - Compositor* compositor_; |
1281 | - |
1282 | - DISALLOW_COPY_AND_ASSIGN(CompositorLock); |
1283 | -}; |
1284 | - |
1285 | } // namespace oxide |
1286 | |
1287 | #endif // _OXIDE_SHARED_BROWSER_COMPOSITOR_COMPOSITOR_H_ |
1288 | |
1289 | === modified file 'shared/browser/compositor/oxide_compositor_client.h' |
1290 | --- shared/browser/compositor/oxide_compositor_client.h 2015-08-14 16:32:46 +0000 |
1291 | +++ shared/browser/compositor/oxide_compositor_client.h 2015-10-21 17:31:00 +0000 |
1292 | @@ -28,8 +28,6 @@ |
1293 | public: |
1294 | virtual ~CompositorClient() {} |
1295 | |
1296 | - virtual void CompositorDidCommit() = 0; |
1297 | - |
1298 | virtual void CompositorSwapFrame(CompositorFrameHandle* handle) = 0; |
1299 | }; |
1300 | |
1301 | |
1302 | === added file 'shared/browser/compositor/oxide_compositor_observer.cc' |
1303 | --- shared/browser/compositor/oxide_compositor_observer.cc 1970-01-01 00:00:00 +0000 |
1304 | +++ shared/browser/compositor/oxide_compositor_observer.cc 2015-10-21 17:31:00 +0000 |
1305 | @@ -0,0 +1,60 @@ |
1306 | +// vim:expandtab:shiftwidth=2:tabstop=2: |
1307 | +// Copyright (C) 2015 Canonical Ltd. |
1308 | + |
1309 | +// This library is free software; you can redistribute it and/or |
1310 | +// modify it under the terms of the GNU Lesser General Public |
1311 | +// License as published by the Free Software Foundation; either |
1312 | +// version 2.1 of the License, or (at your option) any later version. |
1313 | + |
1314 | +// This library is distributed in the hope that it will be useful, |
1315 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
1316 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1317 | +// Lesser General Public License for more details. |
1318 | + |
1319 | +// You should have received a copy of the GNU Lesser General Public |
1320 | +// License along with this library; if not, write to the Free Software |
1321 | +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1322 | + |
1323 | +#include "oxide_compositor_observer.h" |
1324 | + |
1325 | +#include "oxide_compositor.h" |
1326 | + |
1327 | +namespace oxide { |
1328 | + |
1329 | +CompositorObserver::CompositorObserver() |
1330 | + : compositor_(nullptr) {} |
1331 | + |
1332 | +CompositorObserver::CompositorObserver(Compositor* compositor) |
1333 | + : compositor_(compositor) { |
1334 | + if (compositor_) { |
1335 | + compositor_->AddObserver(this); |
1336 | + } |
1337 | +} |
1338 | + |
1339 | +void CompositorObserver::Observe(Compositor* compositor) { |
1340 | + if (compositor == compositor_) { |
1341 | + return; |
1342 | + } |
1343 | + |
1344 | + if (compositor_) { |
1345 | + compositor_->RemoveObserver(this); |
1346 | + } |
1347 | + compositor_ = compositor; |
1348 | + if (compositor_) { |
1349 | + compositor_->AddObserver(this); |
1350 | + } |
1351 | +} |
1352 | + |
1353 | +void CompositorObserver::OnCompositorDestruction() { |
1354 | + compositor_ = nullptr; |
1355 | +} |
1356 | + |
1357 | +CompositorObserver::~CompositorObserver() { |
1358 | + if (compositor_) { |
1359 | + compositor_->RemoveObserver(this); |
1360 | + } |
1361 | +} |
1362 | + |
1363 | +void CompositorObserver::CompositorDidCommit() {} |
1364 | + |
1365 | +} // namespace oxide |
1366 | |
1367 | === added file 'shared/browser/compositor/oxide_compositor_observer.h' |
1368 | --- shared/browser/compositor/oxide_compositor_observer.h 1970-01-01 00:00:00 +0000 |
1369 | +++ shared/browser/compositor/oxide_compositor_observer.h 2015-10-21 17:31:00 +0000 |
1370 | @@ -0,0 +1,49 @@ |
1371 | +// vim:expandtab:shiftwidth=2:tabstop=2: |
1372 | +// Copyright (C) 2015 Canonical Ltd. |
1373 | + |
1374 | +// This library is free software; you can redistribute it and/or |
1375 | +// modify it under the terms of the GNU Lesser General Public |
1376 | +// License as published by the Free Software Foundation; either |
1377 | +// version 2.1 of the License, or (at your option) any later version. |
1378 | + |
1379 | +// This library is distributed in the hope that it will be useful, |
1380 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
1381 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1382 | +// Lesser General Public License for more details. |
1383 | + |
1384 | +// You should have received a copy of the GNU Lesser General Public |
1385 | +// License along with this library; if not, write to the Free Software |
1386 | +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1387 | + |
1388 | +#ifndef _OXIDE_SHARED_BROWSER_COMPOSITOR_COMPOSITOR_OBSERVER_H_ |
1389 | +#define _OXIDE_SHARED_BROWSER_COMPOSITOR_COMPOSITOR_OBSERVER_H_ |
1390 | + |
1391 | +namespace oxide { |
1392 | + |
1393 | +class Compositor; |
1394 | + |
1395 | +class CompositorObserver { |
1396 | + public: |
1397 | + virtual ~CompositorObserver(); |
1398 | + |
1399 | + virtual void CompositorDidCommit(); |
1400 | + |
1401 | + protected: |
1402 | + CompositorObserver(); |
1403 | + CompositorObserver(Compositor* compositor); |
1404 | + |
1405 | + void Observe(Compositor* compositor); |
1406 | + |
1407 | + Compositor* compositor() const { return compositor_; } |
1408 | + |
1409 | + private: |
1410 | + friend class Compositor; |
1411 | + |
1412 | + void OnCompositorDestruction(); |
1413 | + |
1414 | + Compositor* compositor_; |
1415 | +}; |
1416 | + |
1417 | +} // namespace oxide |
1418 | + |
1419 | +#endif // _OXIDE_SHARED_BROWSER_COMPOSITOR_COMPOSITOR_OBSERVER_H_ |
1420 | |
1421 | === added directory 'shared/browser/input' |
1422 | === added file 'shared/browser/input/oxide_ime_bridge.cc' |
1423 | --- shared/browser/input/oxide_ime_bridge.cc 1970-01-01 00:00:00 +0000 |
1424 | +++ shared/browser/input/oxide_ime_bridge.cc 2015-10-21 17:31:00 +0000 |
1425 | @@ -0,0 +1,31 @@ |
1426 | +// vim:expandtab:shiftwidth=2:tabstop=2: |
1427 | +// Copyright (C) 2015 Canonical Ltd. |
1428 | + |
1429 | +// This library is free software; you can redistribute it and/or |
1430 | +// modify it under the terms of the GNU Lesser General Public |
1431 | +// License as published by the Free Software Foundation; either |
1432 | +// version 2.1 of the License, or (at your option) any later version. |
1433 | + |
1434 | +// This library is distributed in the hope that it will be useful, |
1435 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
1436 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1437 | +// Lesser General Public License for more details. |
1438 | + |
1439 | +// You should have received a copy of the GNU Lesser General Public |
1440 | +// License along with this library; if not, write to the Free Software |
1441 | +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1442 | + |
1443 | +#include "oxide_ime_bridge.h" |
1444 | + |
1445 | +namespace oxide { |
1446 | + |
1447 | +ImeBridge::ImeBridge() |
1448 | + : text_input_type_(ui::TEXT_INPUT_TYPE_NONE), |
1449 | + show_ime_if_needed_(false), |
1450 | + selection_cursor_position_(0), |
1451 | + selection_anchor_position_(0), |
1452 | + focused_node_is_editable_(false) {} |
1453 | + |
1454 | +ImeBridge::~ImeBridge() {} |
1455 | + |
1456 | +} // namespace oxide |
1457 | |
1458 | === added file 'shared/browser/input/oxide_ime_bridge.h' |
1459 | --- shared/browser/input/oxide_ime_bridge.h 1970-01-01 00:00:00 +0000 |
1460 | +++ shared/browser/input/oxide_ime_bridge.h 2015-10-21 17:31:00 +0000 |
1461 | @@ -0,0 +1,84 @@ |
1462 | +// vim:expandtab:shiftwidth=2:tabstop=2: |
1463 | +// Copyright (C) 2015 Canonical Ltd. |
1464 | + |
1465 | +// This library is free software; you can redistribute it and/or |
1466 | +// modify it under the terms of the GNU Lesser General Public |
1467 | +// License as published by the Free Software Foundation; either |
1468 | +// version 2.1 of the License, or (at your option) any later version. |
1469 | + |
1470 | +// This library is distributed in the hope that it will be useful, |
1471 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
1472 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1473 | +// Lesser General Public License for more details. |
1474 | + |
1475 | +// You should have received a copy of the GNU Lesser General Public |
1476 | +// License along with this library; if not, write to the Free Software |
1477 | +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1478 | + |
1479 | +#ifndef _OXIDE_SHARED_BROWSER_INPUT_IME_BRIDGE_H_ |
1480 | +#define _OXIDE_SHARED_BROWSER_INPUT_IME_BRIDGE_H_ |
1481 | + |
1482 | +#include <vector> |
1483 | + |
1484 | +#include "base/macros.h" |
1485 | +#include "base/strings/string16.h" |
1486 | +#include "third_party/WebKit/public/web/WebCompositionUnderline.h" |
1487 | +#include "ui/base/ime/text_input_type.h" |
1488 | +#include "ui/gfx/geometry/rect.h" |
1489 | + |
1490 | +namespace gfx { |
1491 | +class Range; |
1492 | +} |
1493 | + |
1494 | +namespace oxide { |
1495 | + |
1496 | +// This class contains state for a particular RWHV. InputMethodContext is |
1497 | +// connected to one ImeBridge |
1498 | +class ImeBridge { |
1499 | + public: |
1500 | + ImeBridge(); |
1501 | + virtual ~ImeBridge(); |
1502 | + |
1503 | + ui::TextInputType text_input_type() const { return text_input_type_; } |
1504 | + |
1505 | + bool show_ime_if_needed() const { return show_ime_if_needed_; } |
1506 | + |
1507 | + gfx::Rect caret_rect() const { return caret_rect_; } |
1508 | + |
1509 | + size_t selection_cursor_position() const { |
1510 | + return selection_cursor_position_; |
1511 | + } |
1512 | + |
1513 | + size_t selection_anchor_position() const { |
1514 | + return selection_anchor_position_; |
1515 | + } |
1516 | + |
1517 | + bool focused_node_is_editable() const { |
1518 | + return focused_node_is_editable_; |
1519 | + } |
1520 | + |
1521 | + virtual base::string16 GetSelectionText() const = 0; |
1522 | + virtual base::string16 GetSelectedText() const = 0; |
1523 | + |
1524 | + virtual void CommitText(const base::string16& text, |
1525 | + const gfx::Range& replacement_range) = 0; |
1526 | + virtual void SetComposingText( |
1527 | + const base::string16& text, |
1528 | + const std::vector<blink::WebCompositionUnderline>& underlines, |
1529 | + const gfx::Range& selection_range) = 0; |
1530 | + |
1531 | + protected: |
1532 | + ui::TextInputType text_input_type_; |
1533 | + bool show_ime_if_needed_; |
1534 | + gfx::Rect caret_rect_; |
1535 | + size_t selection_cursor_position_; |
1536 | + size_t selection_anchor_position_; |
1537 | + bool focused_node_is_editable_; |
1538 | + |
1539 | + private: |
1540 | + DISALLOW_COPY_AND_ASSIGN(ImeBridge); |
1541 | +}; |
1542 | + |
1543 | +} // namespace oxide |
1544 | + |
1545 | +#endif // _OXIDE_SHARED_BROWSER_INPUT_IME_BRIDGE_H_ |
1546 | |
1547 | === added file 'shared/browser/input/oxide_ime_bridge_impl.cc' |
1548 | --- shared/browser/input/oxide_ime_bridge_impl.cc 1970-01-01 00:00:00 +0000 |
1549 | +++ shared/browser/input/oxide_ime_bridge_impl.cc 2015-10-21 17:31:00 +0000 |
1550 | @@ -0,0 +1,157 @@ |
1551 | +// vim:expandtab:shiftwidth=2:tabstop=2: |
1552 | +// Copyright (C) 2015 Canonical Ltd. |
1553 | + |
1554 | +// This library is free software; you can redistribute it and/or |
1555 | +// modify it under the terms of the GNU Lesser General Public |
1556 | +// License as published by the Free Software Foundation; either |
1557 | +// version 2.1 of the License, or (at your option) any later version. |
1558 | + |
1559 | +// This library is distributed in the hope that it will be useful, |
1560 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
1561 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1562 | +// Lesser General Public License for more details. |
1563 | + |
1564 | +// You should have received a copy of the GNU Lesser General Public |
1565 | +// License along with this library; if not, write to the Free Software |
1566 | +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1567 | + |
1568 | +#include "oxide_ime_bridge_impl.h" |
1569 | + |
1570 | +#include "content/browser/renderer_host/render_widget_host_impl.h" |
1571 | +#include "content/public/browser/native_web_keyboard_event.h" |
1572 | +#include "third_party/WebKit/public/web/WebInputEvent.h" |
1573 | +#include "ui/events/keycodes/keyboard_codes.h" |
1574 | + |
1575 | +#include "shared/browser/oxide_render_widget_host_view.h" |
1576 | + |
1577 | +#include "oxide_input_method_context.h" |
1578 | + |
1579 | +namespace oxide { |
1580 | + |
1581 | +namespace { |
1582 | + |
1583 | +// Qt input methods don’t generate key events, but a lot of web pages out there |
1584 | +// rely on keydown and keyup events to e.g. perform search-as-you-type or |
1585 | +// enable/disable a submit button based on the contents of a text input field, |
1586 | +// so we send a fake pair of keydown/keyup events. |
1587 | +// This mimicks what is done in GtkIMContextWrapper::HandlePreeditChanged(…) |
1588 | +// and GtkIMContextWrapper::HandleCommit(…) |
1589 | +// (see content/browser/renderer_host/gtk_im_context_wrapper.cc). |
1590 | +void SendFakeCompositionKeyEvent(content::RenderWidgetHostImpl* host, |
1591 | + blink::WebInputEvent::Type type) { |
1592 | + content::NativeWebKeyboardEvent fake_event; |
1593 | + fake_event.windowsKeyCode = ui::VKEY_PROCESSKEY; |
1594 | + fake_event.skip_in_browser = true; |
1595 | + fake_event.type = type; |
1596 | + host->ForwardKeyboardEvent(fake_event); |
1597 | +} |
1598 | + |
1599 | +} |
1600 | + |
1601 | +base::string16 ImeBridgeImpl::GetSelectionText() const { |
1602 | + return rwhv_->selection_text(); |
1603 | +} |
1604 | + |
1605 | +base::string16 ImeBridgeImpl::GetSelectedText() const { |
1606 | + return rwhv_->GetSelectedText(); |
1607 | +} |
1608 | + |
1609 | +void ImeBridgeImpl::CommitText(const base::string16& text, |
1610 | + const gfx::Range& replacement_range) { |
1611 | + if (!rwhv_->host()) { |
1612 | + return; |
1613 | + } |
1614 | + |
1615 | + SendFakeCompositionKeyEvent(rwhv_->host(), blink::WebInputEvent::RawKeyDown); |
1616 | + rwhv_->host()->ImeConfirmComposition(text, replacement_range, false); |
1617 | + SendFakeCompositionKeyEvent(rwhv_->host(), blink::WebInputEvent::KeyUp); |
1618 | +} |
1619 | + |
1620 | +void ImeBridgeImpl::SetComposingText( |
1621 | + const base::string16& text, |
1622 | + const std::vector<blink::WebCompositionUnderline>& underlines, |
1623 | + const gfx::Range& selection_range) { |
1624 | + if (!rwhv_->host()) { |
1625 | + return; |
1626 | + } |
1627 | + |
1628 | + SendFakeCompositionKeyEvent(rwhv_->host(), blink::WebInputEvent::RawKeyDown); |
1629 | + rwhv_->host()->ImeSetComposition(text, |
1630 | + underlines, |
1631 | + selection_range.start(), |
1632 | + selection_range.end()); |
1633 | + SendFakeCompositionKeyEvent(rwhv_->host(), blink::WebInputEvent::KeyUp); |
1634 | +} |
1635 | + |
1636 | +ImeBridgeImpl::ImeBridgeImpl(RenderWidgetHostView* rwhv) |
1637 | + : rwhv_(rwhv), |
1638 | + context_(nullptr) {} |
1639 | + |
1640 | +ImeBridgeImpl::~ImeBridgeImpl() { |
1641 | + SetContext(nullptr); |
1642 | +} |
1643 | + |
1644 | +void ImeBridgeImpl::SetContext(InputMethodContext* context) { |
1645 | + if (context_) { |
1646 | + DCHECK_EQ(context_->ime_bridge(), this); |
1647 | + context_->SetImeBridge(nullptr); |
1648 | + } |
1649 | + context_ = context; |
1650 | + if (context_) { |
1651 | + DCHECK(!context_->ime_bridge()); |
1652 | + context_->SetImeBridge(this); |
1653 | + } |
1654 | +} |
1655 | + |
1656 | +void ImeBridgeImpl::TextInputStateChanged(ui::TextInputType type, |
1657 | + bool show_ime_if_needed) { |
1658 | + if (type == text_input_type_ && |
1659 | + show_ime_if_needed == show_ime_if_needed_) { |
1660 | + return; |
1661 | + } |
1662 | + |
1663 | + text_input_type_ = type; |
1664 | + show_ime_if_needed_ = show_ime_if_needed; |
1665 | + |
1666 | + if (!context_) { |
1667 | + return; |
1668 | + } |
1669 | + |
1670 | + context_->TextInputStateChanged(); |
1671 | +} |
1672 | + |
1673 | +void ImeBridgeImpl::SelectionBoundsChanged(const gfx::Rect& caret_rect, |
1674 | + size_t selection_cursor_position, |
1675 | + size_t selection_anchor_position) { |
1676 | + if (caret_rect == caret_rect_ && |
1677 | + selection_cursor_position == selection_cursor_position_ && |
1678 | + selection_anchor_position == selection_anchor_position_) { |
1679 | + return; |
1680 | + } |
1681 | + |
1682 | + caret_rect_ = caret_rect; |
1683 | + selection_cursor_position_ = selection_cursor_position; |
1684 | + selection_anchor_position_ = selection_anchor_position; |
1685 | + |
1686 | + if (!context_) { |
1687 | + return; |
1688 | + } |
1689 | + |
1690 | + context_->SelectionBoundsChanged(); |
1691 | +} |
1692 | + |
1693 | +void ImeBridgeImpl::FocusedNodeChanged(bool is_editable_node) { |
1694 | + if (is_editable_node == focused_node_is_editable_) { |
1695 | + return; |
1696 | + } |
1697 | + |
1698 | + focused_node_is_editable_ = is_editable_node; |
1699 | + |
1700 | + if (!context_) { |
1701 | + return; |
1702 | + } |
1703 | + |
1704 | + context_->FocusedNodeChanged(); |
1705 | +} |
1706 | + |
1707 | +} // namespace oxide |
1708 | |
1709 | === added file 'shared/browser/input/oxide_ime_bridge_impl.h' |
1710 | --- shared/browser/input/oxide_ime_bridge_impl.h 1970-01-01 00:00:00 +0000 |
1711 | +++ shared/browser/input/oxide_ime_bridge_impl.h 2015-10-21 17:31:00 +0000 |
1712 | @@ -0,0 +1,69 @@ |
1713 | +// vim:expandtab:shiftwidth=2:tabstop=2: |
1714 | +// Copyright (C) 2015 Canonical Ltd. |
1715 | + |
1716 | +// This library is free software; you can redistribute it and/or |
1717 | +// modify it under the terms of the GNU Lesser General Public |
1718 | +// License as published by the Free Software Foundation; either |
1719 | +// version 2.1 of the License, or (at your option) any later version. |
1720 | + |
1721 | +// This library is distributed in the hope that it will be useful, |
1722 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
1723 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1724 | +// Lesser General Public License for more details. |
1725 | + |
1726 | +// You should have received a copy of the GNU Lesser General Public |
1727 | +// License along with this library; if not, write to the Free Software |
1728 | +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1729 | + |
1730 | +#ifndef _OXIDE_SHARED_BROWSER_INPUT_IME_BRIDGE_IMPL_H_ |
1731 | +#define _OXIDE_SHARED_BROWSER_INPUT_IME_BRIDGE_IMPL_H_ |
1732 | + |
1733 | +#include "base/macros.h" |
1734 | +#include "ui/base/ime/text_input_type.h" |
1735 | + |
1736 | +#include "shared/browser/input/oxide_ime_bridge.h" |
1737 | + |
1738 | +namespace gfx { |
1739 | +class Rect; |
1740 | +} |
1741 | + |
1742 | +namespace oxide { |
1743 | + |
1744 | +class InputMethodContext; |
1745 | +class RenderWidgetHostView; |
1746 | + |
1747 | +class ImeBridgeImpl : public ImeBridge { |
1748 | + public: |
1749 | + ImeBridgeImpl(RenderWidgetHostView* rwhv); |
1750 | + ~ImeBridgeImpl() override; |
1751 | + |
1752 | + InputMethodContext* context() const { return context_; } |
1753 | + void SetContext(InputMethodContext* context); |
1754 | + |
1755 | + void TextInputStateChanged(ui::TextInputType type, |
1756 | + bool show_ime_if_needed); |
1757 | + void SelectionBoundsChanged(const gfx::Rect& caret_rect, |
1758 | + size_t selection_cursor_position, |
1759 | + size_t selection_anchor_position); |
1760 | + void FocusedNodeChanged(bool is_editable_node); |
1761 | + |
1762 | + private: |
1763 | + base::string16 GetSelectionText() const override; |
1764 | + base::string16 GetSelectedText() const override; |
1765 | + void CommitText(const base::string16& text, |
1766 | + const gfx::Range& replacement_range) override; |
1767 | + void SetComposingText( |
1768 | + const base::string16& text, |
1769 | + const std::vector<blink::WebCompositionUnderline>& underlines, |
1770 | + const gfx::Range& selection_range) override; |
1771 | + |
1772 | + RenderWidgetHostView* rwhv_; // Owns us |
1773 | + |
1774 | + InputMethodContext* context_; |
1775 | + |
1776 | + DISALLOW_COPY_AND_ASSIGN(ImeBridgeImpl); |
1777 | +}; |
1778 | + |
1779 | +} // namespace oxide |
1780 | + |
1781 | +#endif // _OXIDE_SHARED_BROWSER_INPUT_IME_BRIDGE_IMPL_H_ |
1782 | |
1783 | === added file 'shared/browser/input/oxide_input_method_context.cc' |
1784 | --- shared/browser/input/oxide_input_method_context.cc 1970-01-01 00:00:00 +0000 |
1785 | +++ shared/browser/input/oxide_input_method_context.cc 2015-10-21 17:31:00 +0000 |
1786 | @@ -0,0 +1,69 @@ |
1787 | +// vim:expandtab:shiftwidth=2:tabstop=2: |
1788 | +// Copyright (C) 2015 Canonical Ltd. |
1789 | + |
1790 | +// This library is free software; you can redistribute it and/or |
1791 | +// modify it under the terms of the GNU Lesser General Public |
1792 | +// License as published by the Free Software Foundation; either |
1793 | +// version 2.1 of the License, or (at your option) any later version. |
1794 | + |
1795 | +// This library is distributed in the hope that it will be useful, |
1796 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
1797 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1798 | +// Lesser General Public License for more details. |
1799 | + |
1800 | +// You should have received a copy of the GNU Lesser General Public |
1801 | +// License along with this library; if not, write to the Free Software |
1802 | +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1803 | + |
1804 | +#include "oxide_input_method_context.h" |
1805 | + |
1806 | +#include "oxide_input_method_context_observer.h" |
1807 | + |
1808 | +namespace oxide { |
1809 | + |
1810 | +void InputMethodContext::NotifyInputPanelVisibilityChanged() { |
1811 | + FOR_EACH_OBSERVER(InputMethodContextObserver, |
1812 | + observers_, |
1813 | + InputPanelVisibilityChanged()); |
1814 | +} |
1815 | + |
1816 | +void InputMethodContext::SetImeBridge(ImeBridge* bridge) { |
1817 | + ime_bridge_ = bridge; |
1818 | + |
1819 | + CancelComposition(); |
1820 | + |
1821 | + // XXX: This is a bit of a hammer |
1822 | + TextInputStateChanged(); |
1823 | + SelectionBoundsChanged(); |
1824 | + SelectionChanged(); |
1825 | + FocusedNodeChanged(); |
1826 | +} |
1827 | + |
1828 | +void InputMethodContext::AddObserver(InputMethodContextObserver* observer) { |
1829 | + observers_.AddObserver(observer); |
1830 | +} |
1831 | + |
1832 | +void InputMethodContext::RemoveObserver(InputMethodContextObserver* observer) { |
1833 | + observers_.RemoveObserver(observer); |
1834 | +} |
1835 | + |
1836 | +InputMethodContext::InputMethodContext() |
1837 | + : ime_bridge_(nullptr) {} |
1838 | + |
1839 | +InputMethodContext::~InputMethodContext() { |
1840 | + FOR_EACH_OBSERVER(InputMethodContextObserver, |
1841 | + observers_, |
1842 | + OnInputMethodContextDestruction()); |
1843 | +} |
1844 | + |
1845 | +bool InputMethodContext::IsInputPanelVisible() const { |
1846 | + return false; |
1847 | +} |
1848 | + |
1849 | +void InputMethodContext::TextInputStateChanged() {} |
1850 | +void InputMethodContext::SelectionBoundsChanged() {} |
1851 | +void InputMethodContext::SelectionChanged() {} |
1852 | +void InputMethodContext::CancelComposition() {} |
1853 | +void InputMethodContext::FocusedNodeChanged() {} |
1854 | + |
1855 | +} // namespace oxide |
1856 | |
1857 | === added file 'shared/browser/input/oxide_input_method_context.h' |
1858 | --- shared/browser/input/oxide_input_method_context.h 1970-01-01 00:00:00 +0000 |
1859 | +++ shared/browser/input/oxide_input_method_context.h 2015-10-21 17:31:00 +0000 |
1860 | @@ -0,0 +1,69 @@ |
1861 | +// vim:expandtab:shiftwidth=2:tabstop=2: |
1862 | +// Copyright (C) 2015 Canonical Ltd. |
1863 | + |
1864 | +// This library is free software; you can redistribute it and/or |
1865 | +// modify it under the terms of the GNU Lesser General Public |
1866 | +// License as published by the Free Software Foundation; either |
1867 | +// version 2.1 of the License, or (at your option) any later version. |
1868 | + |
1869 | +// This library is distributed in the hope that it will be useful, |
1870 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
1871 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1872 | +// Lesser General Public License for more details. |
1873 | + |
1874 | +// You should have received a copy of the GNU Lesser General Public |
1875 | +// License along with this library; if not, write to the Free Software |
1876 | +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1877 | + |
1878 | +#ifndef _OXIDE_SHARED_BROWSER_INPUT_INPUT_METHOD_CONTEXT_H_ |
1879 | +#define _OXIDE_SHARED_BROWSER_INPUT_INPUT_METHOD_CONTEXT_H_ |
1880 | + |
1881 | +#include "base/macros.h" |
1882 | +#include "base/observer_list.h" |
1883 | + |
1884 | +namespace oxide { |
1885 | + |
1886 | +class ImeBridge; |
1887 | +class ImeBridgeImpl; |
1888 | +class InputMethodContextObserver; |
1889 | + |
1890 | +// This class is the interface from ImeBridgeImpl to the toolkit provided |
1891 | +// input method context, and provides a way for the toolkit layer to access |
1892 | +// the currently connected ImeBridge |
1893 | +class InputMethodContext { |
1894 | + public: |
1895 | + InputMethodContext(); |
1896 | + virtual ~InputMethodContext(); |
1897 | + |
1898 | + virtual bool IsInputPanelVisible() const; |
1899 | + |
1900 | + virtual void TextInputStateChanged(); |
1901 | + virtual void SelectionBoundsChanged(); |
1902 | + virtual void SelectionChanged(); |
1903 | + virtual void CancelComposition(); |
1904 | + virtual void FocusedNodeChanged(); |
1905 | + |
1906 | + protected: |
1907 | + ImeBridge* ime_bridge() const { return ime_bridge_; } |
1908 | + |
1909 | + void NotifyInputPanelVisibilityChanged(); |
1910 | + |
1911 | + private: |
1912 | + friend class ImeBridgeImpl; |
1913 | + friend class InputMethodContextObserver; |
1914 | + |
1915 | + void SetImeBridge(ImeBridge* bridge); |
1916 | + |
1917 | + void AddObserver(InputMethodContextObserver* observer); |
1918 | + void RemoveObserver(InputMethodContextObserver* observer); |
1919 | + |
1920 | + ImeBridge* ime_bridge_; |
1921 | + |
1922 | + base::ObserverList<InputMethodContextObserver> observers_; |
1923 | + |
1924 | + DISALLOW_COPY_AND_ASSIGN(InputMethodContext); |
1925 | +}; |
1926 | + |
1927 | +} // namespace oxide |
1928 | + |
1929 | +#endif // _OXIDE_SHARED_BROWSER_INPUT_INPUT_METHOD_CONTEXT_H_ |
1930 | |
1931 | === added file 'shared/browser/input/oxide_input_method_context_observer.cc' |
1932 | --- shared/browser/input/oxide_input_method_context_observer.cc 1970-01-01 00:00:00 +0000 |
1933 | +++ shared/browser/input/oxide_input_method_context_observer.cc 2015-10-21 17:31:00 +0000 |
1934 | @@ -0,0 +1,61 @@ |
1935 | +// vim:expandtab:shiftwidth=2:tabstop=2: |
1936 | +// Copyright (C) 2015 Canonical Ltd. |
1937 | + |
1938 | +// This library is free software; you can redistribute it and/or |
1939 | +// modify it under the terms of the GNU Lesser General Public |
1940 | +// License as published by the Free Software Foundation; either |
1941 | +// version 2.1 of the License, or (at your option) any later version. |
1942 | + |
1943 | +// This library is distributed in the hope that it will be useful, |
1944 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
1945 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1946 | +// Lesser General Public License for more details. |
1947 | + |
1948 | +// You should have received a copy of the GNU Lesser General Public |
1949 | +// License along with this library; if not, write to the Free Software |
1950 | +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1951 | + |
1952 | +#include "oxide_input_method_context_observer.h" |
1953 | + |
1954 | +#include "oxide_input_method_context.h" |
1955 | + |
1956 | +namespace oxide { |
1957 | + |
1958 | +InputMethodContextObserver::InputMethodContextObserver() |
1959 | + : im_context_(nullptr) {} |
1960 | + |
1961 | +InputMethodContextObserver::InputMethodContextObserver( |
1962 | + InputMethodContext* context) |
1963 | + : im_context_(context) { |
1964 | + if (context) { |
1965 | + context->AddObserver(this); |
1966 | + } |
1967 | +} |
1968 | + |
1969 | +void InputMethodContextObserver::Observe(InputMethodContext* context) { |
1970 | + if (context == im_context_) { |
1971 | + return; |
1972 | + } |
1973 | + |
1974 | + if (im_context_) { |
1975 | + im_context_->RemoveObserver(this); |
1976 | + } |
1977 | + im_context_ = context; |
1978 | + if (im_context_) { |
1979 | + im_context_->AddObserver(this); |
1980 | + } |
1981 | +} |
1982 | + |
1983 | +void InputMethodContextObserver::OnInputMethodContextDestruction() { |
1984 | + im_context_ = nullptr; |
1985 | +} |
1986 | + |
1987 | +InputMethodContextObserver::~InputMethodContextObserver() { |
1988 | + if (im_context_) { |
1989 | + im_context_->RemoveObserver(this); |
1990 | + } |
1991 | +} |
1992 | + |
1993 | +void InputMethodContextObserver::InputPanelVisibilityChanged() {} |
1994 | + |
1995 | +} // namespace oxide |
1996 | |
1997 | === added file 'shared/browser/input/oxide_input_method_context_observer.h' |
1998 | --- shared/browser/input/oxide_input_method_context_observer.h 1970-01-01 00:00:00 +0000 |
1999 | +++ shared/browser/input/oxide_input_method_context_observer.h 2015-10-21 17:31:00 +0000 |
2000 | @@ -0,0 +1,49 @@ |
2001 | +// vim:expandtab:shiftwidth=2:tabstop=2: |
2002 | +// Copyright (C) 2015 Canonical Ltd. |
2003 | + |
2004 | +// This library is free software; you can redistribute it and/or |
2005 | +// modify it under the terms of the GNU Lesser General Public |
2006 | +// License as published by the Free Software Foundation; either |
2007 | +// version 2.1 of the License, or (at your option) any later version. |
2008 | + |
2009 | +// This library is distributed in the hope that it will be useful, |
2010 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
2011 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
2012 | +// Lesser General Public License for more details. |
2013 | + |
2014 | +// You should have received a copy of the GNU Lesser General Public |
2015 | +// License along with this library; if not, write to the Free Software |
2016 | +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
2017 | + |
2018 | +#ifndef _OXIDE_SHARED_BROWSER_INPUT_INPUT_METHOD_CONTEXT_OBSERVER_H_ |
2019 | +#define _OXIDE_SHARED_BROWSER_INPUT_INPUT_METHOD_CONTEXT_OBSERVER_H_ |
2020 | + |
2021 | +namespace oxide { |
2022 | + |
2023 | +class InputMethodContext; |
2024 | + |
2025 | +class InputMethodContextObserver { |
2026 | + public: |
2027 | + virtual ~InputMethodContextObserver(); |
2028 | + |
2029 | + virtual void InputPanelVisibilityChanged(); |
2030 | + |
2031 | + protected: |
2032 | + InputMethodContextObserver(); |
2033 | + InputMethodContextObserver(InputMethodContext* context); |
2034 | + |
2035 | + void Observe(InputMethodContext* context); |
2036 | + |
2037 | + InputMethodContext* im_context() const { return im_context_; } |
2038 | + |
2039 | + private: |
2040 | + friend class InputMethodContext; |
2041 | + |
2042 | + void OnInputMethodContextDestruction(); |
2043 | + |
2044 | + InputMethodContext* im_context_; |
2045 | +}; |
2046 | + |
2047 | +} // namespace oxide |
2048 | + |
2049 | +#endif // _OXIDE_SHARED_BROWSER_INPUT_INPUT_METHOD_CONTEXT_OBSERVER_H_ |
2050 | |
2051 | === modified file 'shared/browser/oxide_render_widget_host_view.cc' |
2052 | --- shared/browser/oxide_render_widget_host_view.cc 2015-09-29 08:25:11 +0000 |
2053 | +++ shared/browser/oxide_render_widget_host_view.cc 2015-10-21 17:31:00 +0000 |
2054 | @@ -40,13 +40,13 @@ |
2055 | #include "ui/gfx/geometry/size_conversions.h" |
2056 | |
2057 | #include "shared/browser/compositor/oxide_compositor.h" |
2058 | -#include "shared/browser/compositor/oxide_compositor_utils.h" |
2059 | +#include "shared/browser/input/oxide_input_method_context.h" |
2060 | |
2061 | #include "oxide_browser_platform_integration.h" |
2062 | #include "oxide_browser_process_main.h" |
2063 | #include "oxide_event_utils.h" |
2064 | #include "oxide_renderer_frame_evictor.h" |
2065 | -#include "oxide_render_widget_host_view_delegate.h" |
2066 | +#include "oxide_render_widget_host_view_container.h" |
2067 | |
2068 | namespace oxide { |
2069 | |
2070 | @@ -81,43 +81,35 @@ |
2071 | void RenderWidgetHostView::OnTextInputStateChanged( |
2072 | ui::TextInputType type, |
2073 | bool show_ime_if_needed) { |
2074 | - if (type != current_text_input_type_ || |
2075 | - show_ime_if_needed != show_ime_if_needed_) { |
2076 | - current_text_input_type_ = type; |
2077 | - show_ime_if_needed_ = show_ime_if_needed; |
2078 | - |
2079 | - if (delegate_) { |
2080 | - delegate_->TextInputStateChanged(current_text_input_type_, |
2081 | - show_ime_if_needed_); |
2082 | - } |
2083 | - } |
2084 | + ime_bridge_.TextInputStateChanged(type, show_ime_if_needed); |
2085 | } |
2086 | |
2087 | void RenderWidgetHostView::OnSelectionBoundsChanged( |
2088 | const gfx::Rect& anchor_rect, |
2089 | const gfx::Rect& focus_rect, |
2090 | bool is_anchor_first) { |
2091 | - caret_rect_ = gfx::UnionRects(anchor_rect, focus_rect); |
2092 | + gfx::Rect caret_rect = gfx::UnionRects(anchor_rect, focus_rect); |
2093 | + |
2094 | + size_t selection_cursor_position = 0; |
2095 | + size_t selection_anchor_position = 0; |
2096 | |
2097 | if (selection_range_.IsValid()) { |
2098 | if (is_anchor_first) { |
2099 | - selection_cursor_position_ = |
2100 | + selection_cursor_position = |
2101 | selection_range_.GetMax() - selection_text_offset_; |
2102 | - selection_anchor_position_ = |
2103 | + selection_anchor_position = |
2104 | selection_range_.GetMin() - selection_text_offset_; |
2105 | } else { |
2106 | - selection_cursor_position_ = |
2107 | + selection_cursor_position = |
2108 | selection_range_.GetMin() - selection_text_offset_; |
2109 | - selection_anchor_position_ = |
2110 | + selection_anchor_position = |
2111 | selection_range_.GetMax() - selection_text_offset_; |
2112 | } |
2113 | } |
2114 | |
2115 | - if (delegate_) { |
2116 | - delegate_->SelectionBoundsChanged(caret_rect_, |
2117 | - selection_cursor_position_, |
2118 | - selection_anchor_position_); |
2119 | - } |
2120 | + ime_bridge_.SelectionBoundsChanged(caret_rect, |
2121 | + selection_cursor_position, |
2122 | + selection_anchor_position); |
2123 | } |
2124 | |
2125 | void RenderWidgetHostView::SelectionChanged(const base::string16& text, |
2126 | @@ -136,17 +128,17 @@ |
2127 | |
2128 | content::RenderWidgetHostViewBase::SelectionChanged(text, offset, range); |
2129 | |
2130 | - if (delegate_) { |
2131 | - delegate_->SelectionChanged(); |
2132 | + if (ime_bridge_.context()) { |
2133 | + ime_bridge_.context()->SelectionChanged(); |
2134 | } |
2135 | } |
2136 | |
2137 | gfx::Size RenderWidgetHostView::GetPhysicalBackingSize() const { |
2138 | - if (!delegate_) { |
2139 | + if (!container_) { |
2140 | return gfx::Size(); |
2141 | } |
2142 | |
2143 | - return delegate_->GetViewSizePix(); |
2144 | + return container_->GetViewSizePix(); |
2145 | } |
2146 | |
2147 | bool RenderWidgetHostView::DoTopControlsShrinkBlinkSize() const { |
2148 | @@ -154,18 +146,15 @@ |
2149 | } |
2150 | |
2151 | float RenderWidgetHostView::GetTopControlsHeight() const { |
2152 | - if (!delegate_) { |
2153 | + if (!container_) { |
2154 | return 0.0f; |
2155 | } |
2156 | |
2157 | - return delegate_->GetLocationBarHeightDip(); |
2158 | + return container_->GetLocationBarHeightDip(); |
2159 | } |
2160 | |
2161 | void RenderWidgetHostView::FocusedNodeChanged(bool is_editable_node) { |
2162 | - focused_node_is_editable_ = is_editable_node; |
2163 | - if (delegate_) { |
2164 | - delegate_->FocusedNodeChanged(is_editable_node); |
2165 | - } |
2166 | + ime_bridge_.FocusedNodeChanged(is_editable_node); |
2167 | } |
2168 | |
2169 | void RenderWidgetHostView::OnSwapCompositorFrame( |
2170 | @@ -186,9 +175,6 @@ |
2171 | return; |
2172 | } |
2173 | |
2174 | - Compositor* compositor = delegate_ ? delegate_->GetCompositor() : nullptr; |
2175 | - CompositorLock lock(compositor); |
2176 | - |
2177 | if (output_surface_id != last_output_surface_id_) { |
2178 | resource_collection_->SetClient(nullptr); |
2179 | if (resource_collection_->LoseAllResources()) { |
2180 | @@ -228,10 +214,16 @@ |
2181 | frame_size != frame_provider_->frame_size() || |
2182 | frame_size_dip != last_frame_size_dip_) { |
2183 | DetachLayer(); |
2184 | + |
2185 | frame_provider_ = new cc::DelegatedFrameProvider(resource_collection_, |
2186 | frame_data.Pass()); |
2187 | layer_ = cc::DelegatedRendererLayer::Create(cc::LayerSettings(), |
2188 | frame_provider_); |
2189 | + layer_->SetIsDrawable(true); |
2190 | + layer_->SetContentsOpaque(true); |
2191 | + layer_->SetBounds(frame_size_dip); |
2192 | + layer_->SetHideLayerAndSubtree(!is_showing_); |
2193 | + |
2194 | AttachLayer(); |
2195 | } else { |
2196 | frame_provider_->SetFrameData(frame_data.Pass()); |
2197 | @@ -241,15 +233,12 @@ |
2198 | last_frame_size_dip_ = frame_size_dip; |
2199 | |
2200 | if (layer_.get()) { |
2201 | - layer_->SetIsDrawable(true); |
2202 | - layer_->SetContentsOpaque(true); |
2203 | - layer_->SetBounds(frame_size_dip); |
2204 | layer_->SetNeedsDisplayRect(damage_rect_dip); |
2205 | } |
2206 | |
2207 | if (frame_is_evicted_) { |
2208 | frame_is_evicted_ = false; |
2209 | - RendererFrameEvictor::GetInstance()->AddFrame(this, IsShowing()); |
2210 | + RendererFrameEvictor::GetInstance()->AddFrame(this, is_showing_); |
2211 | } |
2212 | |
2213 | compositor_frame_metadata_ = frame->metadata; |
2214 | @@ -267,6 +256,7 @@ |
2215 | gesture_provider_->SetDoubleTapSupportForPageEnabled( |
2216 | !has_fixed_page_scale && !has_mobile_viewport); |
2217 | |
2218 | + Compositor* compositor = container_->GetCompositor(); |
2219 | if (!compositor || !compositor->IsActive()) { |
2220 | RunAckCallbacks(); |
2221 | } |
2222 | @@ -291,12 +281,17 @@ |
2223 | const std::vector<content::WebPluginGeometry>& moves) {} |
2224 | |
2225 | void RenderWidgetHostView::UpdateCursor(const content::WebCursor& cursor) { |
2226 | - if (cursor.IsEqual(current_cursor_)) { |
2227 | - return; |
2228 | - } |
2229 | - |
2230 | - current_cursor_ = cursor; |
2231 | - UpdateCursorOnWebView(); |
2232 | + if (cursor.IsEqual(web_cursor_)) { |
2233 | + return; |
2234 | + } |
2235 | + |
2236 | + web_cursor_ = cursor; |
2237 | + |
2238 | + if (is_loading_) { |
2239 | + return; |
2240 | + } |
2241 | + |
2242 | + UpdateCurrentCursor(); |
2243 | } |
2244 | |
2245 | void RenderWidgetHostView::SetIsLoading(bool is_loading) { |
2246 | @@ -305,15 +300,15 @@ |
2247 | } |
2248 | |
2249 | is_loading_ = is_loading; |
2250 | - UpdateCursorOnWebView(); |
2251 | + UpdateCurrentCursor(); |
2252 | } |
2253 | |
2254 | void RenderWidgetHostView::ImeCancelComposition() { |
2255 | - if (!delegate_) { |
2256 | + if (!ime_bridge_.context()) { |
2257 | return; |
2258 | } |
2259 | |
2260 | - delegate_->ImeCancelComposition(); |
2261 | + ime_bridge_.context()->CancelComposition(); |
2262 | } |
2263 | |
2264 | void RenderWidgetHostView::RenderProcessGone(base::TerminationStatus status, |
2265 | @@ -354,13 +349,13 @@ |
2266 | } |
2267 | |
2268 | void RenderWidgetHostView::GetScreenInfo(blink::WebScreenInfo* result) { |
2269 | - if (!delegate_) { |
2270 | + if (!container_) { |
2271 | *result = |
2272 | BrowserPlatformIntegration::GetInstance()->GetDefaultScreenInfo(); |
2273 | return; |
2274 | } |
2275 | |
2276 | - *result = delegate_->GetScreenInfo(); |
2277 | + *result = container_->GetScreenInfo(); |
2278 | } |
2279 | |
2280 | bool RenderWidgetHostView::GetScreenColorProfile( |
2281 | @@ -412,11 +407,11 @@ |
2282 | } |
2283 | |
2284 | bool RenderWidgetHostView::HasFocus() const { |
2285 | - if (!delegate_) { |
2286 | + if (!container_) { |
2287 | return false; |
2288 | } |
2289 | |
2290 | - return delegate_->HasFocus(); |
2291 | + return container_->HasFocus(this); |
2292 | } |
2293 | |
2294 | bool RenderWidgetHostView::IsSurfaceAvailableForCopy() const { |
2295 | @@ -425,20 +420,22 @@ |
2296 | |
2297 | void RenderWidgetHostView::Show() { |
2298 | if (is_showing_) { |
2299 | - DCHECK(delegate_); |
2300 | - return; |
2301 | - } |
2302 | - |
2303 | - if (!delegate_) { |
2304 | - return; |
2305 | - } |
2306 | - |
2307 | + return; |
2308 | + } |
2309 | is_showing_ = true; |
2310 | |
2311 | + if (layer_.get()) { |
2312 | + layer_->SetHideLayerAndSubtree(false); |
2313 | + } |
2314 | + |
2315 | if (!frame_is_evicted_) { |
2316 | RendererFrameEvictor::GetInstance()->LockFrame(this); |
2317 | } |
2318 | |
2319 | + if (!host_ || !host_->is_hidden()) { |
2320 | + return; |
2321 | + } |
2322 | + |
2323 | host_->WasShown(ui::LatencyInfo()); |
2324 | } |
2325 | |
2326 | @@ -446,30 +443,36 @@ |
2327 | if (!is_showing_) { |
2328 | return; |
2329 | } |
2330 | - |
2331 | is_showing_ = false; |
2332 | |
2333 | + if (layer_.get()) { |
2334 | + layer_->SetHideLayerAndSubtree(true); |
2335 | + } |
2336 | + |
2337 | if (!frame_is_evicted_) { |
2338 | RendererFrameEvictor::GetInstance()->UnlockFrame(this); |
2339 | } |
2340 | |
2341 | + RunAckCallbacks(); |
2342 | + |
2343 | + if (!host_ || host_->is_hidden()) { |
2344 | + return; |
2345 | + } |
2346 | + |
2347 | host_->WasHidden(); |
2348 | - |
2349 | - RunAckCallbacks(); |
2350 | } |
2351 | |
2352 | bool RenderWidgetHostView::IsShowing() { |
2353 | - DCHECK(!is_showing_ || delegate_); |
2354 | - return is_showing_; |
2355 | + return is_showing_ && container_ && container_->IsVisible(); |
2356 | } |
2357 | |
2358 | gfx::Rect RenderWidgetHostView::GetViewBounds() const { |
2359 | gfx::Rect bounds; |
2360 | |
2361 | - if (!delegate_) { |
2362 | + if (!container_) { |
2363 | bounds = gfx::Rect(last_size_); |
2364 | } else { |
2365 | - bounds = delegate_->GetViewBoundsDip(); |
2366 | + bounds = container_->GetViewBoundsDip(); |
2367 | } |
2368 | |
2369 | if (DoTopControlsShrinkBlinkSize()) { |
2370 | @@ -485,6 +488,10 @@ |
2371 | |
2372 | void RenderWidgetHostView::UnlockMouse() {} |
2373 | |
2374 | +void RenderWidgetHostView::CompositorDidCommit() { |
2375 | + RunAckCallbacks(); |
2376 | +} |
2377 | + |
2378 | void RenderWidgetHostView::OnGestureEvent( |
2379 | const blink::WebGestureEvent& event) { |
2380 | if (!host_) { |
2381 | @@ -517,10 +524,6 @@ |
2382 | void RenderWidgetHostView::EvictCurrentFrame() { |
2383 | frame_is_evicted_ = true; |
2384 | DestroyDelegatedContent(); |
2385 | - |
2386 | - if (delegate_) { |
2387 | - delegate_->EvictCurrentFrame(); |
2388 | - } |
2389 | } |
2390 | |
2391 | void RenderWidgetHostView::UnusedResourcesAreAvailable() { |
2392 | @@ -529,19 +532,20 @@ |
2393 | } |
2394 | } |
2395 | |
2396 | -void RenderWidgetHostView::UpdateCursorOnWebView() { |
2397 | - if (!delegate_) { |
2398 | - return; |
2399 | - } |
2400 | - |
2401 | +void RenderWidgetHostView::UpdateCurrentCursor() { |
2402 | if (is_loading_) { |
2403 | content::WebCursor::CursorInfo busy_cursor_info( |
2404 | blink::WebCursorInfo::TypeWait); |
2405 | - content::WebCursor busy_cursor(busy_cursor_info); |
2406 | - delegate_->UpdateCursor(busy_cursor); |
2407 | + current_cursor_ = content::WebCursor(busy_cursor_info); |
2408 | } else { |
2409 | - delegate_->UpdateCursor(current_cursor_); |
2410 | - } |
2411 | + current_cursor_ = web_cursor_; |
2412 | + } |
2413 | + |
2414 | + if (!container_) { |
2415 | + return; |
2416 | + } |
2417 | + |
2418 | + container_->CursorChanged(); |
2419 | } |
2420 | |
2421 | void RenderWidgetHostView::DestroyDelegatedContent() { |
2422 | @@ -582,92 +586,76 @@ |
2423 | } |
2424 | |
2425 | void RenderWidgetHostView::AttachLayer() { |
2426 | - if (!delegate_) { |
2427 | + if (!container_) { |
2428 | return; |
2429 | } |
2430 | if (!layer_.get()) { |
2431 | return; |
2432 | } |
2433 | |
2434 | - delegate_->GetCompositor()->SetRootLayer(layer_.get()); |
2435 | + container_->AttachLayer(layer_); |
2436 | } |
2437 | |
2438 | void RenderWidgetHostView::DetachLayer() { |
2439 | - if (!delegate_) { |
2440 | + if (!container_) { |
2441 | return; |
2442 | } |
2443 | if (!layer_.get()) { |
2444 | return; |
2445 | } |
2446 | |
2447 | - delegate_->GetCompositor()->SetRootLayer(scoped_refptr<cc::Layer>()); |
2448 | + container_->DetachLayer(layer_); |
2449 | } |
2450 | |
2451 | -RenderWidgetHostView::RenderWidgetHostView(content::RenderWidgetHost* host) : |
2452 | - host_(content::RenderWidgetHostImpl::From(host)), |
2453 | - delegate_(nullptr), |
2454 | - resource_collection_(new cc::DelegatedFrameResourceCollection()), |
2455 | - last_output_surface_id_(0), |
2456 | - frame_is_evicted_(true), |
2457 | - selection_cursor_position_(0), |
2458 | - selection_anchor_position_(0), |
2459 | - current_text_input_type_(ui::TEXT_INPUT_TYPE_NONE), |
2460 | - show_ime_if_needed_(false), |
2461 | - focused_node_is_editable_(false), |
2462 | - is_loading_(false), |
2463 | - is_showing_(false), |
2464 | - top_controls_shrink_blink_size_(false), |
2465 | - gesture_provider_(GestureProvider::Create(this)) { |
2466 | +RenderWidgetHostView::RenderWidgetHostView( |
2467 | + content::RenderWidgetHost* host, |
2468 | + RenderWidgetHostViewContainer* container) |
2469 | + : host_(content::RenderWidgetHostImpl::From(host)), |
2470 | + container_(container), |
2471 | + resource_collection_(new cc::DelegatedFrameResourceCollection()), |
2472 | + last_output_surface_id_(0), |
2473 | + frame_is_evicted_(true), |
2474 | + ime_bridge_(this), |
2475 | + is_loading_(false), |
2476 | + is_showing_(false), |
2477 | + top_controls_shrink_blink_size_(false), |
2478 | + gesture_provider_(GestureProvider::Create(this)) { |
2479 | CHECK(host_) << "Implementation didn't supply a RenderWidgetHost"; |
2480 | |
2481 | resource_collection_->SetClient(this); |
2482 | host_->SetView(this); |
2483 | |
2484 | gesture_provider_->SetDoubleTapSupportForPageEnabled(false); |
2485 | + |
2486 | + if (container) { |
2487 | + CompositorObserver::Observe(container->GetCompositor()); |
2488 | + } |
2489 | } |
2490 | |
2491 | RenderWidgetHostView::~RenderWidgetHostView() { |
2492 | resource_collection_->SetClient(nullptr); |
2493 | - SetDelegate(nullptr); |
2494 | -} |
2495 | - |
2496 | -void RenderWidgetHostView::CompositorDidCommit() { |
2497 | - RunAckCallbacks(); |
2498 | -} |
2499 | - |
2500 | -void RenderWidgetHostView::SetDelegate( |
2501 | - RenderWidgetHostViewDelegate* delegate) { |
2502 | - if (delegate == delegate_) { |
2503 | + SetContainer(nullptr); |
2504 | +} |
2505 | + |
2506 | +void RenderWidgetHostView::SetContainer( |
2507 | + RenderWidgetHostViewContainer* container) { |
2508 | + if (container == container_) { |
2509 | return; |
2510 | } |
2511 | |
2512 | DetachLayer(); |
2513 | - delegate_ = delegate; |
2514 | + container_ = container; |
2515 | AttachLayer(); |
2516 | |
2517 | - if (delegate_) { |
2518 | - DCHECK(host_) << |
2519 | - "Shouldn't be attaching to a delegate when we're already destroyed"; |
2520 | - host_->SendScreenRects(); |
2521 | - host_->WasResized(); |
2522 | - |
2523 | - if (delegate_->IsVisible()) { |
2524 | - Show(); |
2525 | - } else { |
2526 | - Hide(); |
2527 | - } |
2528 | - |
2529 | - UpdateCursorOnWebView(); |
2530 | - delegate_->TextInputStateChanged(current_text_input_type_, |
2531 | - show_ime_if_needed_); |
2532 | - delegate_->FocusedNodeChanged(focused_node_is_editable_); |
2533 | - delegate_->SelectionBoundsChanged(caret_rect_, |
2534 | - selection_cursor_position_, |
2535 | - selection_anchor_position_); |
2536 | - delegate_->SelectionChanged(); |
2537 | - } else if (host_) { |
2538 | - Hide(); |
2539 | + CompositorObserver::Observe( |
2540 | + container_ ? container_->GetCompositor() : nullptr); |
2541 | + |
2542 | + if (!host_) { |
2543 | + return; |
2544 | } |
2545 | + |
2546 | + host_->SendScreenRects(); |
2547 | + host_->WasResized(); |
2548 | } |
2549 | |
2550 | void RenderWidgetHostView::Blur() { |
2551 | |
2552 | === modified file 'shared/browser/oxide_render_widget_host_view.h' |
2553 | --- shared/browser/oxide_render_widget_host_view.h 2015-09-29 08:25:11 +0000 |
2554 | +++ shared/browser/oxide_render_widget_host_view.h 2015-10-21 17:31:00 +0000 |
2555 | @@ -30,10 +30,10 @@ |
2556 | #include "cc/layers/delegated_frame_resource_collection.h" |
2557 | #include "cc/output/compositor_frame_metadata.h" |
2558 | #include "content/common/cursors/webcursor.h" |
2559 | -#include "ui/base/ime/text_input_type.h" |
2560 | -#include "ui/gfx/geometry/rect.h" |
2561 | #include "ui/gfx/geometry/size.h" |
2562 | |
2563 | +#include "shared/browser/compositor/oxide_compositor_observer.h" |
2564 | +#include "shared/browser/input/oxide_ime_bridge_impl.h" |
2565 | #include "shared/browser/oxide_gesture_provider.h" |
2566 | #include "shared/browser/oxide_renderer_frame_evictor_client.h" |
2567 | #include "shared/port/content/browser/render_widget_host_view_oxide.h" |
2568 | @@ -53,23 +53,25 @@ |
2569 | |
2570 | namespace oxide { |
2571 | |
2572 | -class RenderWidgetHostViewDelegate; |
2573 | -class WebView; |
2574 | +class RenderWidgetHostViewContainer; |
2575 | |
2576 | class RenderWidgetHostView final : |
2577 | public content::RenderWidgetHostViewOxide, |
2578 | + public CompositorObserver, |
2579 | public GestureProviderClient, |
2580 | public RendererFrameEvictorClient, |
2581 | public cc::DelegatedFrameResourceCollectionClient, |
2582 | public base::SupportsWeakPtr<RenderWidgetHostView> { |
2583 | public: |
2584 | - RenderWidgetHostView(content::RenderWidgetHost* render_widget_host); |
2585 | + RenderWidgetHostView(content::RenderWidgetHost* render_widget_host, |
2586 | + RenderWidgetHostViewContainer* container); |
2587 | ~RenderWidgetHostView(); |
2588 | |
2589 | content::RenderWidgetHostImpl* host() const { return host_; } |
2590 | |
2591 | - void CompositorDidCommit(); |
2592 | - void SetDelegate(RenderWidgetHostViewDelegate* delegate); |
2593 | + void SetContainer(RenderWidgetHostViewContainer* container); |
2594 | + |
2595 | + ImeBridgeImpl* ime_bridge() { return &ime_bridge_; } |
2596 | |
2597 | const base::string16& selection_text() const { |
2598 | return selection_text_; |
2599 | @@ -79,6 +81,8 @@ |
2600 | return compositor_frame_metadata_; |
2601 | } |
2602 | |
2603 | + const content::WebCursor& current_cursor() const { return current_cursor_; } |
2604 | + |
2605 | void HandleTouchEvent(const ui::MotionEvent& event); |
2606 | void ResetGestureDetection(); |
2607 | |
2608 | @@ -158,6 +162,9 @@ |
2609 | bool LockMouse() final; |
2610 | void UnlockMouse() final; |
2611 | |
2612 | + // CompositorObserver implementation |
2613 | + void CompositorDidCommit() final; |
2614 | + |
2615 | // GestureProviderClient implementation |
2616 | void OnGestureEvent(const blink::WebGestureEvent& event) final; |
2617 | |
2618 | @@ -169,7 +176,7 @@ |
2619 | |
2620 | // =================== |
2621 | |
2622 | - void UpdateCursorOnWebView(); |
2623 | + void UpdateCurrentCursor(); |
2624 | |
2625 | void DestroyDelegatedContent(); |
2626 | void SendDelegatedFrameAck(uint32 surface_id); |
2627 | @@ -180,7 +187,7 @@ |
2628 | |
2629 | content::RenderWidgetHostImpl* host_; |
2630 | |
2631 | - RenderWidgetHostViewDelegate* delegate_; |
2632 | + RenderWidgetHostViewContainer* container_; |
2633 | |
2634 | gfx::GLSurfaceHandle shared_surface_handle_; |
2635 | |
2636 | @@ -197,15 +204,10 @@ |
2637 | |
2638 | bool frame_is_evicted_; |
2639 | |
2640 | - gfx::Rect caret_rect_; |
2641 | - size_t selection_cursor_position_; |
2642 | - size_t selection_anchor_position_; |
2643 | - |
2644 | - ui::TextInputType current_text_input_type_; |
2645 | - bool show_ime_if_needed_; |
2646 | - bool focused_node_is_editable_; |
2647 | + ImeBridgeImpl ime_bridge_; |
2648 | |
2649 | bool is_loading_; |
2650 | + content::WebCursor web_cursor_; |
2651 | content::WebCursor current_cursor_; |
2652 | |
2653 | bool is_showing_; |
2654 | |
2655 | === renamed file 'shared/browser/oxide_render_widget_host_view_delegate.h' => 'shared/browser/oxide_render_widget_host_view_container.h' |
2656 | --- shared/browser/oxide_render_widget_host_view_delegate.h 2015-05-14 15:37:57 +0000 |
2657 | +++ shared/browser/oxide_render_widget_host_view_container.h 2015-10-21 17:31:00 +0000 |
2658 | @@ -1,5 +1,5 @@ |
2659 | // vim:expandtab:shiftwidth=2:tabstop=2: |
2660 | -// Copyright (C) 2014 Canonical Ltd. |
2661 | +// Copyright (C) 2014-2015 Canonical Ltd. |
2662 | |
2663 | // This library is free software; you can redistribute it and/or |
2664 | // modify it under the terms of the GNU Lesser General Public |
2665 | @@ -15,16 +15,24 @@ |
2666 | // License along with this library; if not, write to the Free Software |
2667 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
2668 | |
2669 | -#ifndef _OXIDE_SHARED_BROWSER_RENDER_WIDGET_HOST_VIEW_DELEGATE_H_ |
2670 | -#define _OXIDE_SHARED_BROWSER_RENDER_WIDGET_HOST_VIEW_DELEGATE_H_ |
2671 | - |
2672 | +#ifndef _OXIDE_SHARED_BROWSER_RENDER_WIDGET_HOST_VIEW_CONTAINER_H_ |
2673 | +#define _OXIDE_SHARED_BROWSER_RENDER_WIDGET_HOST_VIEW_CONTAINER_H_ |
2674 | + |
2675 | +#include <vector> |
2676 | + |
2677 | +#include "base/memory/ref_counted.h" |
2678 | +#include "content/public/common/menu_item.h" |
2679 | #include "third_party/WebKit/public/platform/WebScreenInfo.h" |
2680 | -#include "ui/base/ime/text_input_type.h" |
2681 | #include "ui/gfx/geometry/rect.h" |
2682 | #include "ui/gfx/geometry/size.h" |
2683 | |
2684 | +namespace cc { |
2685 | +class Layer; |
2686 | +} |
2687 | + |
2688 | namespace content { |
2689 | -class WebCursor; |
2690 | +struct ContextMenuParams; |
2691 | +class RenderFrameHost; |
2692 | } |
2693 | |
2694 | namespace gfx { |
2695 | @@ -34,44 +42,43 @@ |
2696 | namespace oxide { |
2697 | |
2698 | class Compositor; |
2699 | -class WebView; |
2700 | +class RenderWidgetHostView; |
2701 | |
2702 | -class RenderWidgetHostViewDelegate { |
2703 | +class RenderWidgetHostViewContainer { |
2704 | public: |
2705 | - virtual ~RenderWidgetHostViewDelegate() {} |
2706 | - |
2707 | - virtual void EvictCurrentFrame() = 0; |
2708 | - |
2709 | - virtual void UpdateCursor(const content::WebCursor& cursor) = 0; |
2710 | - |
2711 | - virtual void TextInputStateChanged(ui::TextInputType type, |
2712 | - bool show_ime_if_needed) = 0; |
2713 | - |
2714 | - virtual void FocusedNodeChanged(bool is_editable_node) = 0; |
2715 | - |
2716 | - virtual void ImeCancelComposition() = 0; |
2717 | - |
2718 | - virtual void SelectionBoundsChanged(const gfx::Rect& caret_rect, |
2719 | - size_t selection_cursor_position, |
2720 | - size_t selection_anchor_position) = 0; |
2721 | - |
2722 | - virtual void SelectionChanged() = 0; |
2723 | + virtual ~RenderWidgetHostViewContainer() {} |
2724 | |
2725 | virtual Compositor* GetCompositor() const = 0; |
2726 | |
2727 | + virtual void AttachLayer(scoped_refptr<cc::Layer> layer) = 0; |
2728 | + |
2729 | + virtual void DetachLayer(scoped_refptr<cc::Layer> layer) = 0; |
2730 | + |
2731 | + virtual void CursorChanged() = 0; |
2732 | + |
2733 | virtual gfx::Size GetViewSizePix() const = 0; |
2734 | |
2735 | virtual gfx::Rect GetViewBoundsDip() const = 0; |
2736 | |
2737 | virtual blink::WebScreenInfo GetScreenInfo() const = 0; |
2738 | |
2739 | - virtual bool HasFocus() const = 0; |
2740 | + virtual bool HasFocus(const RenderWidgetHostView* view) const = 0; |
2741 | |
2742 | virtual bool IsVisible() const = 0; |
2743 | |
2744 | virtual float GetLocationBarHeightDip() const = 0; |
2745 | + |
2746 | + virtual void ShowContextMenu(content::RenderFrameHost* render_frame_host, |
2747 | + const content::ContextMenuParams& params) = 0; |
2748 | + |
2749 | + virtual void ShowPopupMenu(content::RenderFrameHost* render_frame_host, |
2750 | + const gfx::Rect& bounds, |
2751 | + int selected_item, |
2752 | + const std::vector<content::MenuItem>& items, |
2753 | + bool allow_multiple_selection) = 0; |
2754 | + virtual void HidePopupMenu() = 0; |
2755 | }; |
2756 | |
2757 | } // namespace oxide |
2758 | |
2759 | -#endif // _OXIDE_SHARED_BROWSER_RENDER_WIDGET_HOST_VIEW_DELEGATE_H_ |
2760 | +#endif // _OXIDE_SHARED_BROWSER_RENDER_WIDGET_HOST_VIEW_CONTAINER_H_ |
2761 | |
2762 | === modified file 'shared/browser/oxide_web_contents_view.cc' |
2763 | --- shared/browser/oxide_web_contents_view.cc 2015-05-28 23:51:39 +0000 |
2764 | +++ shared/browser/oxide_web_contents_view.cc 2015-10-21 17:31:00 +0000 |
2765 | @@ -21,15 +21,27 @@ |
2766 | #include "content/browser/web_contents/web_contents_impl.h" |
2767 | #include "content/public/browser/web_contents.h" |
2768 | |
2769 | +#include "shared/common/oxide_unowned_user_data.h" |
2770 | + |
2771 | #include "oxide_render_widget_host_view.h" |
2772 | -#include "oxide_web_view.h" |
2773 | +#include "oxide_render_widget_host_view_container.h" |
2774 | |
2775 | namespace oxide { |
2776 | |
2777 | -WebContentsView::WebContentsView(content::WebContents* web_contents) : |
2778 | - web_contents_(web_contents) {} |
2779 | - |
2780 | -WebContentsView::~WebContentsView() {} |
2781 | +namespace { |
2782 | +int kUserDataKey; |
2783 | +} |
2784 | + |
2785 | +WebContentsView::WebContentsView(content::WebContents* web_contents) |
2786 | + : web_contents_(web_contents), |
2787 | + container_(nullptr) { |
2788 | + web_contents_->SetUserData(&kUserDataKey, |
2789 | + new UnownedUserData<WebContentsView>(this)); |
2790 | +} |
2791 | + |
2792 | +WebContentsView::~WebContentsView() { |
2793 | + web_contents_->RemoveUserData(&kUserDataKey); |
2794 | +} |
2795 | |
2796 | // static |
2797 | content::WebContentsViewOxide* WebContentsView::Create( |
2798 | @@ -37,8 +49,27 @@ |
2799 | return new WebContentsView(web_contents); |
2800 | } |
2801 | |
2802 | -WebView* WebContentsView::GetWebView() const { |
2803 | - return WebView::FromWebContents(web_contents_); |
2804 | +// static |
2805 | +WebContentsView* WebContentsView::FromWebContents( |
2806 | + content::WebContents* contents) { |
2807 | + UnownedUserData<WebContentsView>* data = |
2808 | + static_cast<UnownedUserData<WebContentsView>*>( |
2809 | + contents->GetUserData(&kUserDataKey)); |
2810 | + if (!data) { |
2811 | + return nullptr; |
2812 | + } |
2813 | + |
2814 | + return data->get(); |
2815 | +} |
2816 | + |
2817 | +void WebContentsView::SetContainer(RenderWidgetHostViewContainer* container) { |
2818 | + container_ = container; |
2819 | + RenderWidgetHostView* rwhv = |
2820 | + static_cast<RenderWidgetHostView*>( |
2821 | + web_contents_->GetRenderWidgetHostView()); |
2822 | + if (rwhv) { |
2823 | + rwhv->SetContainer(container); |
2824 | + } |
2825 | } |
2826 | |
2827 | gfx::NativeView WebContentsView::GetNativeView() const { |
2828 | @@ -54,7 +85,7 @@ |
2829 | } |
2830 | |
2831 | void WebContentsView::GetContainerBounds(gfx::Rect* out) const { |
2832 | - *out = GetWebView()->GetViewBoundsDip(); |
2833 | + *out = container_->GetViewBoundsDip(); |
2834 | } |
2835 | |
2836 | void WebContentsView::SizeContents(const gfx::Size& size) { |
2837 | @@ -107,21 +138,7 @@ |
2838 | content::RenderWidgetHostViewBase* WebContentsView::CreateViewForWidget( |
2839 | content::RenderWidgetHost* render_widget_host, |
2840 | bool is_guest_view_hack) { |
2841 | - RenderWidgetHostView* rwhv = new RenderWidgetHostView(render_widget_host); |
2842 | - |
2843 | - WebView* view = GetWebView(); |
2844 | - if (view) { |
2845 | - // As RWHV contains the plumbing from WebView::VisibilityChanged to |
2846 | - // RenderWidgetHostImpl::Was{Shown,Hidden}, RWHI::is_hidden could be |
2847 | - // out of date. This ensures that we sync RWHI::is_hidden with the |
2848 | - // real visibility of the webview - see https://launchpad.net/bugs/1322622 |
2849 | - view->VisibilityChanged(); |
2850 | - |
2851 | - // Also sync focus state |
2852 | - view->FocusChanged(); |
2853 | - } |
2854 | - |
2855 | - return rwhv; |
2856 | + return new RenderWidgetHostView(render_widget_host, container_); |
2857 | } |
2858 | |
2859 | content::RenderWidgetHostViewBase* WebContentsView::CreateViewForPopupWidget( |
2860 | @@ -140,7 +157,7 @@ |
2861 | void WebContentsView::ShowContextMenu( |
2862 | content::RenderFrameHost* render_frame_host, |
2863 | const content::ContextMenuParams& params) { |
2864 | - GetWebView()->ShowContextMenu(render_frame_host, params); |
2865 | + container_->ShowContextMenu(render_frame_host, params); |
2866 | } |
2867 | |
2868 | void WebContentsView::StartDragging( |
2869 | @@ -163,13 +180,13 @@ |
2870 | const std::vector<content::MenuItem>& items, |
2871 | bool right_aligned, |
2872 | bool allow_multiple_selection) { |
2873 | - GetWebView()->ShowPopupMenu(render_frame_host, |
2874 | - bounds, selected_item, items, |
2875 | - allow_multiple_selection); |
2876 | + container_->ShowPopupMenu(render_frame_host, |
2877 | + bounds, selected_item, items, |
2878 | + allow_multiple_selection); |
2879 | } |
2880 | |
2881 | void WebContentsView::HidePopupMenu() { |
2882 | - GetWebView()->HidePopupMenu(); |
2883 | + container_->HidePopupMenu(); |
2884 | } |
2885 | |
2886 | } // namespace oxide |
2887 | |
2888 | === modified file 'shared/browser/oxide_web_contents_view.h' |
2889 | --- shared/browser/oxide_web_contents_view.h 2015-05-28 23:51:39 +0000 |
2890 | +++ shared/browser/oxide_web_contents_view.h 2015-10-21 17:31:00 +0000 |
2891 | @@ -27,7 +27,7 @@ |
2892 | |
2893 | namespace oxide { |
2894 | |
2895 | -class WebView; |
2896 | +class RenderWidgetHostViewContainer; |
2897 | |
2898 | class WebContentsView final : public content::WebContentsViewOxide { |
2899 | public: |
2900 | @@ -35,7 +35,9 @@ |
2901 | static content::WebContentsViewOxide* Create( |
2902 | content::WebContents* web_contents); |
2903 | |
2904 | - WebView* GetWebView() const; |
2905 | + static WebContentsView* FromWebContents(content::WebContents* contents); |
2906 | + |
2907 | + void SetContainer(RenderWidgetHostViewContainer* container); |
2908 | |
2909 | // content::WebContentsView |
2910 | gfx::NativeView GetNativeView() const final; |
2911 | @@ -93,6 +95,8 @@ |
2912 | |
2913 | content::WebContents* web_contents_; |
2914 | |
2915 | + RenderWidgetHostViewContainer* container_; |
2916 | + |
2917 | DISALLOW_IMPLICIT_CONSTRUCTORS(WebContentsView); |
2918 | }; |
2919 | |
2920 | |
2921 | === modified file 'shared/browser/oxide_web_view.cc' |
2922 | --- shared/browser/oxide_web_view.cc 2015-10-08 15:56:22 +0000 |
2923 | +++ shared/browser/oxide_web_view.cc 2015-10-21 17:31:00 +0000 |
2924 | @@ -25,17 +25,18 @@ |
2925 | #include "base/strings/string_util.h" |
2926 | #include "base/strings/utf_string_conversions.h" |
2927 | #include "base/supports_user_data.h" |
2928 | +#include "cc/layers/layer.h" |
2929 | +#include "cc/layers/solid_color_layer.h" |
2930 | +#include "cc/trees/layer_tree_settings.h" |
2931 | #include "components/sessions/content/content_serialized_navigation_builder.h" |
2932 | #include "content/browser/frame_host/render_frame_host_impl.h" |
2933 | #include "content/browser/renderer_host/event_with_latency_info.h" |
2934 | #include "content/browser/renderer_host/render_view_host_impl.h" |
2935 | #include "content/browser/renderer_host/render_widget_host_impl.h" |
2936 | -#include "content/browser/renderer_host/ui_events_helper.h" |
2937 | #include "content/browser/web_contents/web_contents_impl.h" |
2938 | #include "content/browser/web_contents/web_contents_view.h" |
2939 | #include "content/public/browser/invalidate_type.h" |
2940 | #include "content/public/browser/browser_context.h" |
2941 | -#include "content/public/browser/native_web_keyboard_event.h" |
2942 | #include "content/public/browser/navigation_controller.h" |
2943 | #include "content/public/browser/navigation_details.h" |
2944 | #include "content/public/browser/navigation_entry.h" |
2945 | @@ -60,7 +61,6 @@ |
2946 | #include "third_party/WebKit/public/web/WebInputEvent.h" |
2947 | #include "ui/base/window_open_disposition.h" |
2948 | #include "ui/events/event.h" |
2949 | -#include "ui/gfx/range/range.h" |
2950 | #include "ui/gl/gl_implementation.h" |
2951 | #include "ui/shell_dialogs/selected_file_info.h" |
2952 | #include "url/gurl.h" |
2953 | @@ -69,12 +69,15 @@ |
2954 | #include "shared/browser/compositor/oxide_compositor.h" |
2955 | #include "shared/browser/compositor/oxide_compositor_frame_data.h" |
2956 | #include "shared/browser/compositor/oxide_compositor_frame_handle.h" |
2957 | +#include "shared/browser/input/oxide_ime_bridge.h" |
2958 | +#include "shared/browser/input/oxide_input_method_context.h" |
2959 | #include "shared/browser/media/oxide_media_capture_devices_dispatcher.h" |
2960 | #include "shared/browser/permissions/oxide_permission_request_dispatcher.h" |
2961 | #include "shared/browser/permissions/oxide_temporary_saved_permission_context.h" |
2962 | #include "shared/common/oxide_content_client.h" |
2963 | #include "shared/common/oxide_enum_flags.h" |
2964 | #include "shared/common/oxide_messages.h" |
2965 | +#include "shared/common/oxide_unowned_user_data.h" |
2966 | |
2967 | #include "oxide_browser_context.h" |
2968 | #include "oxide_browser_process_main.h" |
2969 | @@ -106,20 +109,7 @@ |
2970 | |
2971 | namespace { |
2972 | |
2973 | -const char kWebViewKey[] = "oxide_web_view_data"; |
2974 | - |
2975 | -// SupportsUserData implementations own their data. This class exists |
2976 | -// because we don't want WebContents to own WebView (it's the other way |
2977 | -// around) |
2978 | -class WebViewUserData : public base::SupportsUserData::Data { |
2979 | - public: |
2980 | - WebViewUserData(WebView* view) : view_(view) {} |
2981 | - |
2982 | - WebView* get() const { return view_; } |
2983 | - |
2984 | - private: |
2985 | - WebView* view_; |
2986 | -}; |
2987 | +int kUserDataKey; |
2988 | |
2989 | void FillLoadURLParamsFromOpenURLParams( |
2990 | content::NavigationController::LoadURLParams* load_params, |
2991 | @@ -143,22 +133,6 @@ |
2992 | } |
2993 | } |
2994 | |
2995 | -// Qt input methods don’t generate key events, but a lot of web pages out there |
2996 | -// rely on keydown and keyup events to e.g. perform search-as-you-type or |
2997 | -// enable/disable a submit button based on the contents of a text input field, |
2998 | -// so we send a fake pair of keydown/keyup events. |
2999 | -// This mimicks what is done in GtkIMContextWrapper::HandlePreeditChanged(…) |
3000 | -// and GtkIMContextWrapper::HandleCommit(…) |
3001 | -// (see content/browser/renderer_host/gtk_im_context_wrapper.cc). |
3002 | -void SendFakeCompositionKeyEvent(content::RenderWidgetHostImpl* host, |
3003 | - blink::WebInputEvent::Type type) { |
3004 | - content::NativeWebKeyboardEvent fake_event; |
3005 | - fake_event.windowsKeyCode = ui::VKEY_PROCESSKEY; |
3006 | - fake_event.skip_in_browser = true; |
3007 | - fake_event.type = type; |
3008 | - host->ForwardKeyboardEvent(fake_event); |
3009 | -} |
3010 | - |
3011 | void CreateHelpers(content::WebContents* contents, |
3012 | content::WebContents* opener = nullptr) { |
3013 | new WebViewContentsHelper(contents, opener); |
3014 | @@ -225,13 +199,9 @@ |
3015 | |
3016 | WebView::WebView(WebViewClient* client) |
3017 | : client_(client), |
3018 | - text_input_type_(ui::TEXT_INPUT_TYPE_NONE), |
3019 | - show_ime_if_needed_(false), |
3020 | - focused_node_is_editable_(false), |
3021 | - selection_cursor_position_(0), |
3022 | - selection_anchor_position_(0), |
3023 | web_contents_helper_(nullptr), |
3024 | compositor_(Compositor::Create(this)), |
3025 | + root_layer_(cc::SolidColorLayer::Create(cc::LayerSettings())), |
3026 | is_fullscreen_(false), |
3027 | blocked_content_(CONTENT_TYPE_NONE), |
3028 | location_bar_height_pix_(0), |
3029 | @@ -239,6 +209,14 @@ |
3030 | location_bar_animated_(true), |
3031 | weak_factory_(this) { |
3032 | CHECK(client) << "Didn't specify a client"; |
3033 | + |
3034 | + root_layer_->SetIsDrawable(true); |
3035 | + root_layer_->SetBackgroundColor(SK_ColorWHITE); |
3036 | + |
3037 | + compositor_->SetRootLayer(root_layer_); |
3038 | + |
3039 | + CompositorObserver::Observe(compositor_.get()); |
3040 | + InputMethodContextObserver::Observe(client_->GetInputMethodContext()); |
3041 | } |
3042 | |
3043 | void WebView::CommonInit(scoped_ptr<content::WebContents> contents) { |
3044 | @@ -246,7 +224,8 @@ |
3045 | |
3046 | // Attach ourself to the WebContents |
3047 | web_contents_->SetDelegate(this); |
3048 | - web_contents_->SetUserData(kWebViewKey, new WebViewUserData(this)); |
3049 | + web_contents_->SetUserData(&kUserDataKey, |
3050 | + new UnownedUserData<WebView>(this)); |
3051 | |
3052 | content::WebContentsObserver::Observe(web_contents_.get()); |
3053 | |
3054 | @@ -262,6 +241,8 @@ |
3055 | registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_CHANGED, |
3056 | content::NotificationService::AllBrowserContextsAndSources()); |
3057 | |
3058 | + WebContentsView::FromWebContents(web_contents_.get())->SetContainer(this); |
3059 | + |
3060 | DCHECK(std::find(g_all_web_views.Get().begin(), |
3061 | g_all_web_views.Get().end(), |
3062 | this) == |
3063 | @@ -329,11 +310,13 @@ |
3064 | return false; |
3065 | } |
3066 | |
3067 | - if (!IsInputPanelVisible()) { |
3068 | + if (!client_->GetInputMethodContext() || |
3069 | + !client_->GetInputMethodContext()->IsInputPanelVisible()) { |
3070 | return false; |
3071 | } |
3072 | |
3073 | - if (!focused_node_is_editable_) { |
3074 | + if (!GetRenderWidgetHostView() || |
3075 | + !GetRenderWidgetHostView()->ime_bridge()->focused_node_is_editable()) { |
3076 | return false; |
3077 | } |
3078 | |
3079 | @@ -388,6 +371,10 @@ |
3080 | return client_->GetScriptMessageHandlerAt(index); |
3081 | } |
3082 | |
3083 | +void WebView::InputPanelVisibilityChanged() { |
3084 | + MaybeScrollFocusedEditableNodeIntoView(); |
3085 | +} |
3086 | + |
3087 | void WebView::CompositorDidCommit() { |
3088 | RenderWidgetHostView* rwhv = GetRenderWidgetHostView(); |
3089 | if (!rwhv) { |
3090 | @@ -395,8 +382,6 @@ |
3091 | } |
3092 | |
3093 | pending_compositor_frame_metadata_ = rwhv->compositor_frame_metadata(); |
3094 | - |
3095 | - rwhv->CompositorDidCommit(); |
3096 | } |
3097 | |
3098 | void WebView::CompositorSwapFrame(CompositorFrameHandle* handle) { |
3099 | @@ -438,63 +423,79 @@ |
3100 | } |
3101 | } |
3102 | |
3103 | -void WebView::EvictCurrentFrame() { |
3104 | - current_compositor_frame_ = nullptr; |
3105 | - client_->EvictCurrentFrame(); |
3106 | -} |
3107 | - |
3108 | -void WebView::UpdateCursor(const content::WebCursor& cursor) { |
3109 | - client_->UpdateCursor(cursor); |
3110 | -} |
3111 | - |
3112 | -void WebView::TextInputStateChanged(ui::TextInputType type, |
3113 | - bool show_ime_if_needed) { |
3114 | - if (type == text_input_type_ && |
3115 | - show_ime_if_needed == show_ime_if_needed_) { |
3116 | - return; |
3117 | - } |
3118 | - |
3119 | - text_input_type_ = type; |
3120 | - show_ime_if_needed_ = show_ime_if_needed; |
3121 | - |
3122 | - client_->TextInputStateChanged(); |
3123 | -} |
3124 | - |
3125 | -void WebView::FocusedNodeChanged(bool is_editable_node) { |
3126 | - focused_node_is_editable_ = is_editable_node; |
3127 | - client_->FocusedNodeChanged(); |
3128 | - |
3129 | - MaybeScrollFocusedEditableNodeIntoView(); |
3130 | -} |
3131 | - |
3132 | -void WebView::ImeCancelComposition() { |
3133 | - client_->ImeCancelComposition(); |
3134 | -} |
3135 | - |
3136 | -void WebView::SelectionBoundsChanged(const gfx::Rect& caret_rect, |
3137 | - size_t selection_cursor_position, |
3138 | - size_t selection_anchor_position) { |
3139 | - if (caret_rect == caret_rect_ && |
3140 | - selection_cursor_position == selection_cursor_position_ && |
3141 | - selection_anchor_position == selection_anchor_position_) { |
3142 | - return; |
3143 | - } |
3144 | - |
3145 | - caret_rect_ = caret_rect; |
3146 | - selection_cursor_position_ = selection_cursor_position; |
3147 | - selection_anchor_position_ = selection_anchor_position; |
3148 | - |
3149 | - client_->SelectionBoundsChanged(); |
3150 | -} |
3151 | - |
3152 | -void WebView::SelectionChanged() { |
3153 | - client_->SelectionChanged(); |
3154 | -} |
3155 | - |
3156 | Compositor* WebView::GetCompositor() const { |
3157 | return compositor_.get(); |
3158 | } |
3159 | |
3160 | +void WebView::AttachLayer(scoped_refptr<cc::Layer> layer) { |
3161 | + DCHECK(layer.get()); |
3162 | + root_layer_->InsertChild(layer, 0); |
3163 | + root_layer_->SetIsDrawable(false); |
3164 | +} |
3165 | + |
3166 | +void WebView::DetachLayer(scoped_refptr<cc::Layer> layer) { |
3167 | + DCHECK(layer.get()); |
3168 | + DCHECK_EQ(layer->parent(), root_layer_.get()); |
3169 | + layer->RemoveFromParent(); |
3170 | + if (root_layer_->children().size() == 0) { |
3171 | + root_layer_->SetIsDrawable(true); |
3172 | + } |
3173 | +} |
3174 | + |
3175 | +void WebView::CursorChanged() { |
3176 | + RenderWidgetHostView* rwhv = GetRenderWidgetHostView(); |
3177 | + if (!rwhv) { |
3178 | + return; |
3179 | + } |
3180 | + |
3181 | + client_->UpdateCursor(rwhv->current_cursor()); |
3182 | +} |
3183 | + |
3184 | +bool WebView::HasFocus(const RenderWidgetHostView* view) const { |
3185 | + if (!HasFocus()) { |
3186 | + return false; |
3187 | + } |
3188 | + |
3189 | + return view == GetRenderWidgetHostView(); |
3190 | +} |
3191 | + |
3192 | +void WebView::ShowContextMenu(content::RenderFrameHost* render_frame_host, |
3193 | + const content::ContextMenuParams& params) { |
3194 | + WebContextMenu* menu = client_->CreateContextMenu(render_frame_host, params); |
3195 | + if (!menu) { |
3196 | + return; |
3197 | + } |
3198 | + |
3199 | + menu->Show(); |
3200 | +} |
3201 | + |
3202 | +void WebView::ShowPopupMenu(content::RenderFrameHost* render_frame_host, |
3203 | + const gfx::Rect& bounds, |
3204 | + int selected_item, |
3205 | + const std::vector<content::MenuItem>& items, |
3206 | + bool allow_multiple_selection) { |
3207 | + DCHECK(!active_popup_menu_); |
3208 | + |
3209 | + WebPopupMenu* menu = client_->CreatePopupMenu(render_frame_host); |
3210 | + if (!menu) { |
3211 | + static_cast<content::RenderFrameHostImpl *>( |
3212 | + render_frame_host)->DidCancelPopupMenu(); |
3213 | + return; |
3214 | + } |
3215 | + |
3216 | + active_popup_menu_ = menu->GetWeakPtr(); |
3217 | + |
3218 | + menu->Show(bounds, items, selected_item, allow_multiple_selection); |
3219 | +} |
3220 | + |
3221 | +void WebView::HidePopupMenu() { |
3222 | + if (!active_popup_menu_) { |
3223 | + return; |
3224 | + } |
3225 | + |
3226 | + active_popup_menu_->Close(); |
3227 | +} |
3228 | + |
3229 | content::WebContents* WebView::OpenURLFromTab( |
3230 | content::WebContents* source, |
3231 | const content::OpenURLParams& params) { |
3232 | @@ -874,15 +875,31 @@ |
3233 | void WebView::RenderViewHostChanged(content::RenderViewHost* old_host, |
3234 | content::RenderViewHost* new_host) { |
3235 | if (old_host && old_host->GetView()) { |
3236 | - static_cast<RenderWidgetHostView *>(old_host->GetView())->SetDelegate(nullptr); |
3237 | + RenderWidgetHostView* rwhv = |
3238 | + static_cast<RenderWidgetHostView*>(old_host->GetView()); |
3239 | + rwhv->SetContainer(nullptr); |
3240 | + rwhv->ime_bridge()->SetContext(nullptr); |
3241 | } |
3242 | + |
3243 | if (new_host) { |
3244 | if (new_host->GetView()) { |
3245 | - static_cast<RenderWidgetHostView *>(new_host->GetView())->SetDelegate(this); |
3246 | + RenderWidgetHostView* rwhv = |
3247 | + static_cast<RenderWidgetHostView*>(new_host->GetView()); |
3248 | + rwhv->SetContainer(this); |
3249 | + rwhv->ime_bridge()->SetContext(client_->GetInputMethodContext()); |
3250 | } |
3251 | |
3252 | InitializeTopControlsForHost(new_host, !old_host); |
3253 | } |
3254 | + |
3255 | + if (old_host) { |
3256 | + return; |
3257 | + } |
3258 | + |
3259 | + // For the initial view, we need to sync its visibility and focus state |
3260 | + // with us. For subsequent views, RFHM does this for us |
3261 | + VisibilityChanged(); |
3262 | + FocusChanged(); |
3263 | } |
3264 | |
3265 | void WebView::DidStartProvisionalLoadForFrame( |
3266 | @@ -1067,6 +1084,7 @@ |
3267 | compositor_->SetViewportSize(GetViewSizePix()); |
3268 | compositor_->SetVisibility(IsVisible()); |
3269 | compositor_->SetDeviceScaleFactor(GetScreenInfo().deviceScaleFactor); |
3270 | + root_layer_->SetBounds(GetViewSizeDip()); |
3271 | |
3272 | if (params.restore_entries.size() > 0) { |
3273 | ScopedVector<content::NavigationEntry> entries = |
3274 | @@ -1093,22 +1111,21 @@ |
3275 | |
3276 | CommonInit(contents.Pass()); |
3277 | |
3278 | - RenderWidgetHostView* rwhv = GetRenderWidgetHostView(); |
3279 | - if (rwhv) { |
3280 | - rwhv->SetDelegate(this); |
3281 | - } |
3282 | - |
3283 | content::RenderViewHost* rvh = GetRenderViewHost(); |
3284 | if (rvh) { |
3285 | InitializeTopControlsForHost(rvh, true); |
3286 | } |
3287 | |
3288 | + RenderWidgetHostView* rwhv = GetRenderWidgetHostView(); |
3289 | + if (rwhv) { |
3290 | + rwhv->ime_bridge()->SetContext(client_->GetInputMethodContext()); |
3291 | + } |
3292 | + |
3293 | // Sync WebContents with the state of the WebView |
3294 | WasResized(); |
3295 | ScreenUpdated(); |
3296 | VisibilityChanged(); |
3297 | FocusChanged(); |
3298 | - InputPanelVisibilityChanged(); |
3299 | |
3300 | // Update SSL Status |
3301 | content::NavigationEntry* entry = |
3302 | @@ -1125,21 +1142,24 @@ |
3303 | this), |
3304 | g_all_web_views.Get().end()); |
3305 | |
3306 | + WebContentsView::FromWebContents(web_contents_.get())->SetContainer(nullptr); |
3307 | + |
3308 | RenderWidgetHostView* rwhv = GetRenderWidgetHostView(); |
3309 | if (rwhv) { |
3310 | - rwhv->SetDelegate(nullptr); |
3311 | + rwhv->ime_bridge()->SetContext(nullptr); |
3312 | } |
3313 | |
3314 | // Stop WebContents from calling back in to us |
3315 | content::WebContentsObserver::Observe(nullptr); |
3316 | |
3317 | - web_contents_->RemoveUserData(kWebViewKey); |
3318 | + web_contents_->RemoveUserData(&kUserDataKey); |
3319 | } |
3320 | |
3321 | // static |
3322 | WebView* WebView::FromWebContents(const content::WebContents* web_contents) { |
3323 | - WebViewUserData* data = static_cast<WebViewUserData *>( |
3324 | - web_contents->GetUserData(kWebViewKey)); |
3325 | + UnownedUserData<WebView>* data = |
3326 | + static_cast<UnownedUserData<WebView>*>( |
3327 | + web_contents->GetUserData(&kUserDataKey)); |
3328 | if (!data) { |
3329 | return nullptr; |
3330 | } |
3331 | @@ -1275,11 +1295,9 @@ |
3332 | } |
3333 | |
3334 | void WebView::WasResized() { |
3335 | - { |
3336 | - CompositorLock lock(compositor_.get()); |
3337 | - compositor_->SetDeviceScaleFactor(GetScreenInfo().deviceScaleFactor); |
3338 | - compositor_->SetViewportSize(GetViewSizePix()); |
3339 | - } |
3340 | + compositor_->SetDeviceScaleFactor(GetScreenInfo().deviceScaleFactor); |
3341 | + compositor_->SetViewportSize(GetViewSizePix()); |
3342 | + root_layer_->SetBounds(GetViewSizeDip()); |
3343 | |
3344 | RenderWidgetHostView* rwhv = GetRenderWidgetHostView(); |
3345 | if (rwhv) { |
3346 | @@ -1309,6 +1327,14 @@ |
3347 | web_contents_->WasShown(); |
3348 | } else { |
3349 | web_contents_->WasHidden(); |
3350 | + // TODO: Have an eviction algorithm for LayerTreeHosts in Compositor, and |
3351 | + // trigger eviction of the frontbuffer from a CompositorClient callback. |
3352 | + // XXX: Also this isn't really necessary for eviction - after all, the LTH |
3353 | + // owned by Compositor owns the frontbuffer (via its cc::OutputSurface). |
3354 | + // This callback is really to notify the toolkit layer that the |
3355 | + // frontbuffer is being dropped |
3356 | + current_compositor_frame_ = nullptr; |
3357 | + client_->EvictCurrentFrame(); |
3358 | } |
3359 | |
3360 | MaybeScrollFocusedEditableNodeIntoView(); |
3361 | @@ -1329,10 +1355,6 @@ |
3362 | MaybeScrollFocusedEditableNodeIntoView(); |
3363 | } |
3364 | |
3365 | -void WebView::InputPanelVisibilityChanged() { |
3366 | - MaybeScrollFocusedEditableNodeIntoView(); |
3367 | -} |
3368 | - |
3369 | void WebView::UpdateWebPreferences() { |
3370 | content::RenderViewHost* rvh = web_contents_->GetRenderViewHost(); |
3371 | if (!rvh) { |
3372 | @@ -1605,43 +1627,6 @@ |
3373 | web_contents_->DispatchBeforeUnload(false); |
3374 | } |
3375 | |
3376 | -void WebView::ShowContextMenu(content::RenderFrameHost* render_frame_host, |
3377 | - const content::ContextMenuParams& params) { |
3378 | - WebContextMenu* menu = client_->CreateContextMenu(render_frame_host, params); |
3379 | - if (!menu) { |
3380 | - return; |
3381 | - } |
3382 | - |
3383 | - menu->Show(); |
3384 | -} |
3385 | - |
3386 | -void WebView::ShowPopupMenu(content::RenderFrameHost* render_frame_host, |
3387 | - const gfx::Rect& bounds, |
3388 | - int selected_item, |
3389 | - const std::vector<content::MenuItem>& items, |
3390 | - bool allow_multiple_selection) { |
3391 | - DCHECK(!active_popup_menu_); |
3392 | - |
3393 | - WebPopupMenu* menu = client_->CreatePopupMenu(render_frame_host); |
3394 | - if (!menu) { |
3395 | - static_cast<content::RenderFrameHostImpl *>( |
3396 | - render_frame_host)->DidCancelPopupMenu(); |
3397 | - return; |
3398 | - } |
3399 | - |
3400 | - active_popup_menu_ = menu->GetWeakPtr(); |
3401 | - |
3402 | - menu->Show(bounds, items, selected_item, allow_multiple_selection); |
3403 | -} |
3404 | - |
3405 | -void WebView::HidePopupMenu() { |
3406 | - if (!active_popup_menu_) { |
3407 | - return; |
3408 | - } |
3409 | - |
3410 | - active_popup_menu_->Close(); |
3411 | -} |
3412 | - |
3413 | void WebView::AllowCertificateError( |
3414 | content::RenderFrameHost* rfh, |
3415 | int cert_error, |
3416 | @@ -1727,34 +1712,6 @@ |
3417 | rvh->ForwardWheelEvent(event); |
3418 | } |
3419 | |
3420 | -void WebView::ImeCommitText(const base::string16& text, |
3421 | - const gfx::Range& replacement_range) { |
3422 | - content::RenderWidgetHostImpl* host = GetRenderWidgetHostImpl(); |
3423 | - if (!host) { |
3424 | - return; |
3425 | - } |
3426 | - |
3427 | - SendFakeCompositionKeyEvent(host, blink::WebInputEvent::RawKeyDown); |
3428 | - host->ImeConfirmComposition(text, replacement_range, false); |
3429 | - SendFakeCompositionKeyEvent(host, blink::WebInputEvent::KeyUp); |
3430 | -} |
3431 | - |
3432 | -void WebView::ImeSetComposingText( |
3433 | - const base::string16& text, |
3434 | - const std::vector<blink::WebCompositionUnderline>& underlines, |
3435 | - const gfx::Range& selection_range) { |
3436 | - content::RenderWidgetHostImpl* host = GetRenderWidgetHostImpl(); |
3437 | - if (!host) { |
3438 | - return; |
3439 | - } |
3440 | - |
3441 | - SendFakeCompositionKeyEvent(host, blink::WebInputEvent::RawKeyDown); |
3442 | - host->ImeSetComposition(text, underlines, |
3443 | - selection_range.start(), |
3444 | - selection_range.end()); |
3445 | - SendFakeCompositionKeyEvent(host, blink::WebInputEvent::KeyUp); |
3446 | -} |
3447 | - |
3448 | void WebView::DownloadRequested( |
3449 | const GURL& url, |
3450 | const std::string& mime_type, |
3451 | @@ -1810,10 +1767,6 @@ |
3452 | return client_->HasFocus(); |
3453 | } |
3454 | |
3455 | -bool WebView::IsInputPanelVisible() const { |
3456 | - return client_->IsInputPanelVisible(); |
3457 | -} |
3458 | - |
3459 | JavaScriptDialog* WebView::CreateJavaScriptDialog( |
3460 | content::JavaScriptMessageType javascript_message_type) { |
3461 | return client_->CreateJavaScriptDialog(javascript_message_type); |
3462 | @@ -1837,23 +1790,5 @@ |
3463 | return client_->CanCreateWindows(); |
3464 | } |
3465 | |
3466 | -base::string16 WebView::GetSelectedText() const { |
3467 | - RenderWidgetHostView* rwhv = GetRenderWidgetHostView(); |
3468 | - if (!rwhv) { |
3469 | - return base::string16(); |
3470 | - } |
3471 | - |
3472 | - return rwhv->GetSelectedText(); |
3473 | -} |
3474 | - |
3475 | -const base::string16& WebView::GetSelectionText() const { |
3476 | - RenderWidgetHostView* rwhv = GetRenderWidgetHostView(); |
3477 | - if (!rwhv) { |
3478 | - return base::EmptyString16(); |
3479 | - } |
3480 | - |
3481 | - return rwhv->selection_text(); |
3482 | -} |
3483 | - |
3484 | } // namespace oxide |
3485 | |
3486 | |
3487 | === modified file 'shared/browser/oxide_web_view.h' |
3488 | --- shared/browser/oxide_web_view.h 2015-10-08 15:56:22 +0000 |
3489 | +++ shared/browser/oxide_web_view.h 2015-10-21 17:31:00 +0000 |
3490 | @@ -39,16 +39,16 @@ |
3491 | #include "content/public/common/resource_type.h" |
3492 | #include "third_party/WebKit/public/platform/WebScreenInfo.h" |
3493 | #include "third_party/WebKit/public/platform/WebTopControlsState.h" |
3494 | -#include "third_party/WebKit/public/web/WebCompositionUnderline.h" |
3495 | -#include "ui/base/ime/text_input_type.h" |
3496 | #include "ui/gfx/geometry/point.h" |
3497 | #include "ui/gfx/geometry/rect.h" |
3498 | #include "ui/gfx/geometry/size.h" |
3499 | |
3500 | #include "shared/browser/compositor/oxide_compositor_client.h" |
3501 | +#include "shared/browser/compositor/oxide_compositor_observer.h" |
3502 | +#include "shared/browser/input/oxide_input_method_context_observer.h" |
3503 | #include "shared/browser/oxide_certificate_error.h" |
3504 | #include "shared/browser/oxide_content_types.h" |
3505 | -#include "shared/browser/oxide_render_widget_host_view_delegate.h" |
3506 | +#include "shared/browser/oxide_render_widget_host_view_container.h" |
3507 | #include "shared/browser/oxide_script_message_target.h" |
3508 | #include "shared/browser/oxide_security_status.h" |
3509 | #include "shared/browser/oxide_security_types.h" |
3510 | @@ -63,10 +63,12 @@ |
3511 | class WebMouseWheelEvent; |
3512 | } // namespace blink |
3513 | |
3514 | +namespace cc { |
3515 | +class SolidColorLayer; |
3516 | +} |
3517 | + |
3518 | namespace content { |
3519 | |
3520 | -struct ContextMenuParams; |
3521 | -struct MenuItem; |
3522 | class NativeWebKeyboardEvent; |
3523 | class NotificationRegistrar; |
3524 | struct OpenURLParams; |
3525 | @@ -75,7 +77,6 @@ |
3526 | class RenderWidgetHostImpl; |
3527 | class WebContents; |
3528 | class WebContentsImpl; |
3529 | -class WebCursor; |
3530 | |
3531 | } // namespace content |
3532 | |
3533 | @@ -129,10 +130,12 @@ |
3534 | // This is the main webview class. Implementations should customize this by |
3535 | // providing an implementation of WebViewClient |
3536 | class WebView : public ScriptMessageTarget, |
3537 | + private InputMethodContextObserver, |
3538 | + private CompositorObserver, |
3539 | private CompositorClient, |
3540 | private WebPreferencesObserver, |
3541 | private content::NotificationObserver, |
3542 | - private RenderWidgetHostViewDelegate, |
3543 | + private RenderWidgetHostViewContainer, |
3544 | private content::WebContentsDelegate, |
3545 | private content::WebContentsObserver { |
3546 | public: |
3547 | @@ -199,7 +202,6 @@ |
3548 | void ScreenUpdated(); |
3549 | void VisibilityChanged(); |
3550 | void FocusChanged(); |
3551 | - void InputPanelVisibilityChanged(); |
3552 | void UpdateWebPreferences(); |
3553 | |
3554 | BrowserContext* GetBrowserContext() const; |
3555 | @@ -259,15 +261,6 @@ |
3556 | |
3557 | void PrepareToClose(); |
3558 | |
3559 | - void ShowContextMenu(content::RenderFrameHost* render_frame_host, |
3560 | - const content::ContextMenuParams& params); |
3561 | - void ShowPopupMenu(content::RenderFrameHost* render_frame_host, |
3562 | - const gfx::Rect& bounds, |
3563 | - int selected_item, |
3564 | - const std::vector<content::MenuItem>& items, |
3565 | - bool allow_multiple_selection); |
3566 | - void HidePopupMenu(); |
3567 | - |
3568 | void AllowCertificateError(content::RenderFrameHost* rfh, |
3569 | int cert_error, |
3570 | const net::SSLInfo& ssl_info, |
3571 | @@ -283,13 +276,6 @@ |
3572 | void HandleTouchEvent(const ui::TouchEvent& event); |
3573 | void HandleWheelEvent(const blink::WebMouseWheelEvent& event); |
3574 | |
3575 | - void ImeCommitText(const base::string16& text, |
3576 | - const gfx::Range& replacement_range); |
3577 | - void ImeSetComposingText( |
3578 | - const base::string16& text, |
3579 | - const std::vector<blink::WebCompositionUnderline>& underlines, |
3580 | - const gfx::Range& selection_range); |
3581 | - |
3582 | void DownloadRequested( |
3583 | const GURL& url, |
3584 | const std::string& mime_type, |
3585 | @@ -309,7 +295,6 @@ |
3586 | gfx::Rect GetViewBoundsPix() const; |
3587 | bool IsVisible() const; |
3588 | bool HasFocus() const; |
3589 | - bool IsInputPanelVisible() const; |
3590 | |
3591 | JavaScriptDialog* CreateJavaScriptDialog( |
3592 | content::JavaScriptMessageType javascript_message_type); |
3593 | @@ -319,17 +304,6 @@ |
3594 | |
3595 | bool CanCreateWindows() const; |
3596 | |
3597 | - ui::TextInputType text_input_type() const { return text_input_type_; } |
3598 | - bool show_ime_if_needed() const { return show_ime_if_needed_; } |
3599 | - bool focused_node_is_editable() const { return focused_node_is_editable_; } |
3600 | - |
3601 | - gfx::Rect caret_rect() const { return caret_rect_; } |
3602 | - size_t selection_cursor_position() const { return selection_cursor_position_; } |
3603 | - size_t selection_anchor_position() const { return selection_anchor_position_; } |
3604 | - |
3605 | - base::string16 GetSelectedText() const; |
3606 | - const base::string16& GetSelectionText() const; |
3607 | - |
3608 | private: |
3609 | WebView(WebViewClient* client); |
3610 | |
3611 | @@ -364,8 +338,13 @@ |
3612 | virtual const ScriptMessageHandler* GetScriptMessageHandlerAt( |
3613 | size_t index) const override; |
3614 | |
3615 | + // InputMethodContextObserver implementation |
3616 | + void InputPanelVisibilityChanged() override; |
3617 | + |
3618 | + // CompositorObserver implementation |
3619 | + void CompositorDidCommit() final; |
3620 | + |
3621 | // CompositorClient implementation |
3622 | - void CompositorDidCommit() final; |
3623 | void CompositorSwapFrame(CompositorFrameHandle* handle) final; |
3624 | |
3625 | // WebPreferencesObserver implementation |
3626 | @@ -376,18 +355,20 @@ |
3627 | const content::NotificationSource& source, |
3628 | const content::NotificationDetails& details) final; |
3629 | |
3630 | - // RenderWidgetHostViewDelegate implementation |
3631 | - void EvictCurrentFrame() final; |
3632 | - void UpdateCursor(const content::WebCursor& cursor) final; |
3633 | - void TextInputStateChanged(ui::TextInputType type, |
3634 | - bool show_ime_if_needed) final; |
3635 | - void FocusedNodeChanged(bool is_editable_node) final; |
3636 | - void ImeCancelComposition() final; |
3637 | - void SelectionBoundsChanged(const gfx::Rect& caret_rect, |
3638 | - size_t selection_cursor_position, |
3639 | - size_t selection_anchor_position) final; |
3640 | - void SelectionChanged() final; |
3641 | + // RenderWidgetHostViewContainer implementation |
3642 | Compositor* GetCompositor() const final; |
3643 | + void AttachLayer(scoped_refptr<cc::Layer> layer) final; |
3644 | + void DetachLayer(scoped_refptr<cc::Layer> layer) final; |
3645 | + void CursorChanged() final; |
3646 | + bool HasFocus(const RenderWidgetHostView* view) const final; |
3647 | + void ShowContextMenu(content::RenderFrameHost* render_frame_host, |
3648 | + const content::ContextMenuParams& params) final; |
3649 | + void ShowPopupMenu(content::RenderFrameHost* render_frame_host, |
3650 | + const gfx::Rect& bounds, |
3651 | + int selected_item, |
3652 | + const std::vector<content::MenuItem>& items, |
3653 | + bool allow_multiple_selection) final; |
3654 | + void HidePopupMenu() final; |
3655 | |
3656 | // content::WebContentsDelegate implementation |
3657 | content::WebContents* OpenURLFromTab(content::WebContents* source, |
3658 | @@ -502,14 +483,6 @@ |
3659 | |
3660 | WebViewClient* client_; |
3661 | |
3662 | - ui::TextInputType text_input_type_; |
3663 | - bool show_ime_if_needed_; |
3664 | - bool focused_node_is_editable_; |
3665 | - |
3666 | - gfx::Rect caret_rect_; |
3667 | - size_t selection_cursor_position_; |
3668 | - size_t selection_anchor_position_; |
3669 | - |
3670 | struct WebContentsDeleter { |
3671 | void operator()(content::WebContents* contents); |
3672 | }; |
3673 | @@ -520,6 +493,7 @@ |
3674 | WebViewContentsHelper* web_contents_helper_; |
3675 | |
3676 | scoped_ptr<Compositor> compositor_; |
3677 | + scoped_refptr<cc::SolidColorLayer> root_layer_; |
3678 | |
3679 | scoped_refptr<CompositorFrameHandle> current_compositor_frame_; |
3680 | std::vector<scoped_refptr<CompositorFrameHandle> > previous_compositor_frames_; |
3681 | |
3682 | === modified file 'shared/browser/oxide_web_view_client.cc' |
3683 | --- shared/browser/oxide_web_view_client.cc 2015-10-08 15:56:22 +0000 |
3684 | +++ shared/browser/oxide_web_view_client.cc 2015-10-21 17:31:00 +0000 |
3685 | @@ -23,10 +23,6 @@ |
3686 | |
3687 | WebViewClient::~WebViewClient() {} |
3688 | |
3689 | -bool WebViewClient::IsInputPanelVisible() const { |
3690 | - return false; |
3691 | -} |
3692 | - |
3693 | JavaScriptDialog* WebViewClient::CreateJavaScriptDialog( |
3694 | content::JavaScriptMessageType javascript_message_type) { |
3695 | return nullptr; |
3696 | @@ -137,15 +133,9 @@ |
3697 | |
3698 | void WebViewClient::EvictCurrentFrame() {} |
3699 | |
3700 | -void WebViewClient::TextInputStateChanged() {} |
3701 | - |
3702 | -void WebViewClient::FocusedNodeChanged() {} |
3703 | - |
3704 | -void WebViewClient::SelectionBoundsChanged() {} |
3705 | - |
3706 | -void WebViewClient::ImeCancelComposition() {} |
3707 | - |
3708 | -void WebViewClient::SelectionChanged() {} |
3709 | +InputMethodContext* WebViewClient::GetInputMethodContext() const { |
3710 | + return nullptr; |
3711 | +} |
3712 | |
3713 | void WebViewClient::UpdateCursor(const content::WebCursor& cursor) {} |
3714 | |
3715 | |
3716 | === modified file 'shared/browser/oxide_web_view_client.h' |
3717 | --- shared/browser/oxide_web_view_client.h 2015-10-08 15:56:22 +0000 |
3718 | +++ shared/browser/oxide_web_view_client.h 2015-10-21 17:31:00 +0000 |
3719 | @@ -48,6 +48,7 @@ |
3720 | |
3721 | class CertificateError; |
3722 | class FilePicker; |
3723 | +class InputMethodContext; |
3724 | class JavaScriptDialog; |
3725 | class ResourceDispatcherHostLoginDelegate; |
3726 | class SecurityStatus; |
3727 | @@ -69,9 +70,6 @@ |
3728 | |
3729 | virtual bool HasFocus() const = 0; |
3730 | |
3731 | - // XXX(chrisccoulson): This is global state, so it doesn't belong here |
3732 | - virtual bool IsInputPanelVisible() const; |
3733 | - |
3734 | // TODO(chrisccoulson): Make a delegate for JavaScriptDialogManager and move there |
3735 | virtual JavaScriptDialog* CreateJavaScriptDialog( |
3736 | content::JavaScriptMessageType javascript_message_type); |
3737 | @@ -168,20 +166,7 @@ |
3738 | |
3739 | virtual void EvictCurrentFrame(); |
3740 | |
3741 | - // XXX(chrisccoulson): Rethink all of these IME related bits: |
3742 | - // - Move some logic down from qt/ to shared/ |
3743 | - // - The implementations of some of these only touch process-global |
3744 | - // stuff - should we have an InputMethod singleton in shared/ |
3745 | - // rather than dumping it all in WebView? |
3746 | - virtual void TextInputStateChanged(); |
3747 | - |
3748 | - virtual void FocusedNodeChanged(); |
3749 | - |
3750 | - virtual void SelectionBoundsChanged(); |
3751 | - |
3752 | - virtual void ImeCancelComposition(); |
3753 | - |
3754 | - virtual void SelectionChanged(); |
3755 | + virtual InputMethodContext* GetInputMethodContext() const; |
3756 | |
3757 | virtual void UpdateCursor(const content::WebCursor& cursor); |
3758 | |
3759 | |
3760 | === added file 'shared/common/oxide_unowned_user_data.h' |
3761 | --- shared/common/oxide_unowned_user_data.h 1970-01-01 00:00:00 +0000 |
3762 | +++ shared/common/oxide_unowned_user_data.h 2015-10-21 17:31:00 +0000 |
3763 | @@ -0,0 +1,41 @@ |
3764 | +// vim:expandtab:shiftwidth=2:tabstop=2: |
3765 | +// Copyright (C) 2013-2015 Canonical Ltd. |
3766 | + |
3767 | +// This library is free software; you can redistribute it and/or |
3768 | +// modify it under the terms of the GNU Lesser General Public |
3769 | +// License as published by the Free Software Foundation; either |
3770 | +// version 2.1 of the License, or (at your option) any later version. |
3771 | + |
3772 | +// This library is distributed in the hope that it will be useful, |
3773 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
3774 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
3775 | +// Lesser General Public License for more details. |
3776 | + |
3777 | +// You should have received a copy of the GNU Lesser General Public |
3778 | +// License along with this library; if not, write to the Free Software |
3779 | +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
3780 | + |
3781 | +#ifndef _OXIDE_SHARED_COMMON_UNOWNED_USER_DATA_H_ |
3782 | +#define _OXIDE_SHARED_COMMON_UNOWNED_USER_DATA_H_ |
3783 | + |
3784 | +#include "base/macros.h" |
3785 | +#include "base/supports_user_data.h" |
3786 | + |
3787 | +namespace { |
3788 | + |
3789 | +template <class T> |
3790 | +class UnownedUserData : public base::SupportsUserData::Data { |
3791 | + public: |
3792 | + UnownedUserData(T* ptr) : ptr_(ptr) {} |
3793 | + |
3794 | + T* get() const { return ptr_; } |
3795 | + |
3796 | + private: |
3797 | + T* ptr_; |
3798 | + |
3799 | + DISALLOW_COPY_AND_ASSIGN(UnownedUserData); |
3800 | +}; |
3801 | + |
3802 | +} // namespace oxide |
3803 | + |
3804 | +#endif // _OXIDE_SHARED_COMMON_UNOWNED_USER_DATA_H_ |
3805 | |
3806 | === modified file 'shared/shared.gyp' |
3807 | --- shared/shared.gyp 2015-10-08 15:56:22 +0000 |
3808 | +++ shared/shared.gyp 2015-10-21 17:31:00 +0000 |
3809 | @@ -293,6 +293,8 @@ |
3810 | 'browser/compositor/oxide_compositor_frame_handle.h', |
3811 | 'browser/compositor/oxide_compositor_gpu_shims.cc', |
3812 | 'browser/compositor/oxide_compositor_gpu_shims.h', |
3813 | + 'browser/compositor/oxide_compositor_observer.cc', |
3814 | + 'browser/compositor/oxide_compositor_observer.h', |
3815 | 'browser/compositor/oxide_compositor_output_surface.cc', |
3816 | 'browser/compositor/oxide_compositor_output_surface.h', |
3817 | 'browser/compositor/oxide_compositor_output_surface_gl.cc', |
3818 | @@ -307,6 +309,14 @@ |
3819 | 'browser/compositor/oxide_compositor_utils.h', |
3820 | 'browser/compositor/oxide_mailbox_buffer_map.cc', |
3821 | 'browser/compositor/oxide_mailbox_buffer_map.h', |
3822 | + 'browser/input/oxide_ime_bridge.cc', |
3823 | + 'browser/input/oxide_ime_bridge.h', |
3824 | + 'browser/input/oxide_ime_bridge_impl.cc', |
3825 | + 'browser/input/oxide_ime_bridge_impl.h', |
3826 | + 'browser/input/oxide_input_method_context.cc', |
3827 | + 'browser/input/oxide_input_method_context.h', |
3828 | + 'browser/input/oxide_input_method_context_observer.cc', |
3829 | + 'browser/input/oxide_input_method_context_observer.h', |
3830 | 'browser/media/oxide_media_capture_devices_context.cc', |
3831 | 'browser/media/oxide_media_capture_devices_context.h', |
3832 | 'browser/media/oxide_media_capture_devices_context_client.h', |
3833 | @@ -401,7 +411,7 @@ |
3834 | 'browser/oxide_render_process_initializer.h', |
3835 | 'browser/oxide_render_widget_host_view.cc', |
3836 | 'browser/oxide_render_widget_host_view.h', |
3837 | - 'browser/oxide_render_widget_host_view_delegate.h', |
3838 | + 'browser/oxide_render_widget_host_view_container.h', |
3839 | 'browser/oxide_resource_dispatcher_host_delegate.cc', |
3840 | 'browser/oxide_resource_dispatcher_host_delegate.h', |
3841 | 'browser/oxide_resource_dispatcher_host_login_delegate.cc', |
3842 | @@ -498,6 +508,7 @@ |
3843 | 'common/oxide_script_message_params.h', |
3844 | 'common/oxide_script_message_request.cc', |
3845 | 'common/oxide_script_message_request.h', |
3846 | + 'common/oxide_unowned_user_data.h', |
3847 | 'common/oxide_user_agent.cc', |
3848 | 'common/oxide_user_agent.h', |
3849 | 'common/oxide_user_agent_override_set.cc', |