Merge lp:~chrisccoulson/oxide/refactor-webview-rwhv-interation into lp:~oxide-developers/oxide/oxide.trunk

Proposed by Chris Coulson
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
Reviewer Review Type Date Requested Status
Chris Coulson Pending
Review via email: mp+274723@code.launchpad.net
To post a comment you must log in.
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

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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',

Subscribers

People subscribed via source and target branches