summaryrefslogtreecommitdiffstats
path: root/src/core/render_widget_host_view_qt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/render_widget_host_view_qt.cpp')
-rw-r--r--src/core/render_widget_host_view_qt.cpp225
1 files changed, 130 insertions, 95 deletions
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index e741962fb..7a5118837 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -48,6 +48,7 @@
#include "touch_selection_controller_client_qt.h"
#include "touch_selection_menu_controller.h"
#include "type_conversion.h"
+#include "web_contents_adapter.h"
#include "web_contents_adapter_client.h"
#include "web_event_factory.h"
@@ -120,8 +121,7 @@ static inline ui::LatencyInfo CreateLatencyInfo(const blink::WebInputEvent& even
if (!event.TimeStamp().is_null()) {
latency_info.AddLatencyNumberWithTimestamp(
ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
- event.TimeStamp(),
- 1);
+ event.TimeStamp());
}
return latency_info;
}
@@ -489,23 +489,20 @@ gfx::Rect RenderWidgetHostViewQt::GetViewBounds()
void RenderWidgetHostViewQt::UpdateBackgroundColor()
{
+ DCHECK(GetBackgroundColor());
+ SkColor color = *GetBackgroundColor();
+
+ m_delegate->setClearColor(toQt(color));
+
if (m_enableViz) {
- DCHECK(GetBackgroundColor());
- SkColor color = *GetBackgroundColor();
bool opaque = SkColorGetA(color) == SK_AlphaOPAQUE;
m_rootLayer->SetFillsBoundsOpaquely(opaque);
m_rootLayer->SetColor(color);
m_uiCompositor->SetBackgroundColor(color);
- m_delegate->setClearColor(toQt(color));
- host()->Send(new RenderViewObserverQt_SetBackgroundColor(host()->GetRoutingID(), color));
- return;
}
- auto color = GetBackgroundColor();
- if (color) {
- m_delegate->setClearColor(toQt(*color));
- host()->Send(new RenderViewObserverQt_SetBackgroundColor(host()->GetRoutingID(), *color));
- }
+ content::RenderViewHost *rvh = content::RenderViewHost::From(host());
+ host()->Send(new RenderViewObserverQt_SetBackgroundColor(rvh->GetRoutingID(), color));
}
// Return value indicates whether the mouse is locked successfully or not.
@@ -537,110 +534,119 @@ void RenderWidgetHostViewQt::DisplayCursor(const content::WebCursor &webCursor)
ui::CursorType auraType = ui::CursorType::kNull;
#endif
switch (cursorInfo.type) {
- case blink::WebCursorInfo::kTypePointer:
+ case ui::CursorType::kNull:
+ case ui::CursorType::kPointer:
shape = Qt::ArrowCursor;
break;
- case blink::WebCursorInfo::kTypeCross:
+ case ui::CursorType::kCross:
shape = Qt::CrossCursor;
break;
- case blink::WebCursorInfo::kTypeHand:
+ case ui::CursorType::kHand:
shape = Qt::PointingHandCursor;
break;
- case blink::WebCursorInfo::kTypeIBeam:
+ case ui::CursorType::kIBeam:
shape = Qt::IBeamCursor;
break;
- case blink::WebCursorInfo::kTypeWait:
+ case ui::CursorType::kWait:
shape = Qt::WaitCursor;
break;
- case blink::WebCursorInfo::kTypeHelp:
+ case ui::CursorType::kHelp:
shape = Qt::WhatsThisCursor;
break;
- case blink::WebCursorInfo::kTypeEastResize:
- case blink::WebCursorInfo::kTypeWestResize:
- case blink::WebCursorInfo::kTypeEastWestResize:
- case blink::WebCursorInfo::kTypeEastPanning:
- case blink::WebCursorInfo::kTypeWestPanning:
+ case ui::CursorType::kEastResize:
+ case ui::CursorType::kWestResize:
+ case ui::CursorType::kEastWestResize:
+ case ui::CursorType::kEastPanning:
+ case ui::CursorType::kWestPanning:
+ case ui::CursorType::kMiddlePanningHorizontal:
shape = Qt::SizeHorCursor;
break;
- case blink::WebCursorInfo::kTypeNorthResize:
- case blink::WebCursorInfo::kTypeSouthResize:
- case blink::WebCursorInfo::kTypeNorthSouthResize:
- case blink::WebCursorInfo::kTypeNorthPanning:
- case blink::WebCursorInfo::kTypeSouthPanning:
+ case ui::CursorType::kNorthResize:
+ case ui::CursorType::kSouthResize:
+ case ui::CursorType::kNorthSouthResize:
+ case ui::CursorType::kNorthPanning:
+ case ui::CursorType::kSouthPanning:
+ case ui::CursorType::kMiddlePanningVertical:
shape = Qt::SizeVerCursor;
break;
- case blink::WebCursorInfo::kTypeNorthEastResize:
- case blink::WebCursorInfo::kTypeSouthWestResize:
- case blink::WebCursorInfo::kTypeNorthEastSouthWestResize:
- case blink::WebCursorInfo::kTypeNorthEastPanning:
- case blink::WebCursorInfo::kTypeSouthWestPanning:
+ case ui::CursorType::kNorthEastResize:
+ case ui::CursorType::kSouthWestResize:
+ case ui::CursorType::kNorthEastSouthWestResize:
+ case ui::CursorType::kNorthEastPanning:
+ case ui::CursorType::kSouthWestPanning:
shape = Qt::SizeBDiagCursor;
break;
- case blink::WebCursorInfo::kTypeNorthWestResize:
- case blink::WebCursorInfo::kTypeSouthEastResize:
- case blink::WebCursorInfo::kTypeNorthWestSouthEastResize:
- case blink::WebCursorInfo::kTypeNorthWestPanning:
- case blink::WebCursorInfo::kTypeSouthEastPanning:
+ case ui::CursorType::kNorthWestResize:
+ case ui::CursorType::kSouthEastResize:
+ case ui::CursorType::kNorthWestSouthEastResize:
+ case ui::CursorType::kNorthWestPanning:
+ case ui::CursorType::kSouthEastPanning:
shape = Qt::SizeFDiagCursor;
break;
- case blink::WebCursorInfo::kTypeColumnResize:
+ case ui::CursorType::kColumnResize:
shape = Qt::SplitHCursor;
break;
- case blink::WebCursorInfo::kTypeRowResize:
+ case ui::CursorType::kRowResize:
shape = Qt::SplitVCursor;
break;
- case blink::WebCursorInfo::kTypeMiddlePanning:
- case blink::WebCursorInfo::kTypeMove:
+ case ui::CursorType::kMiddlePanning:
+ case ui::CursorType::kMove:
shape = Qt::SizeAllCursor;
break;
- case blink::WebCursorInfo::kTypeProgress:
+ case ui::CursorType::kProgress:
shape = Qt::BusyCursor;
break;
- case blink::WebCursorInfo::kTypeCopy:
+ case ui::CursorType::kDndNone:
+ case ui::CursorType::kDndMove:
+ shape = Qt::DragMoveCursor;
+ break;
+ case ui::CursorType::kDndCopy:
+ case ui::CursorType::kCopy:
shape = Qt::DragCopyCursor;
break;
- case blink::WebCursorInfo::kTypeAlias:
+ case ui::CursorType::kDndLink:
+ case ui::CursorType::kAlias:
shape = Qt::DragLinkCursor;
break;
#if defined(USE_AURA)
- case blink::WebCursorInfo::kTypeVerticalText:
+ case ui::CursorType::kVerticalText:
auraType = ui::CursorType::kVerticalText;
break;
- case blink::WebCursorInfo::kTypeCell:
+ case ui::CursorType::kCell:
auraType = ui::CursorType::kCell;
break;
- case blink::WebCursorInfo::kTypeContextMenu:
+ case ui::CursorType::kContextMenu:
auraType = ui::CursorType::kContextMenu;
break;
- case blink::WebCursorInfo::kTypeZoomIn:
+ case ui::CursorType::kZoomIn:
auraType = ui::CursorType::kZoomIn;
break;
- case blink::WebCursorInfo::kTypeZoomOut:
+ case ui::CursorType::kZoomOut:
auraType = ui::CursorType::kZoomOut;
break;
#else
- case blink::WebCursorInfo::kTypeVerticalText:
- case blink::WebCursorInfo::kTypeCell:
- case blink::WebCursorInfo::kTypeContextMenu:
- case blink::WebCursorInfo::kTypeZoomIn:
- case blink::WebCursorInfo::kTypeZoomOut:
+ case ui::CursorType::kVerticalText:
+ case ui::CursorType::kCell:
+ case ui::CursorType::kContextMenu:
+ case ui::CursorType::kZoomIn:
+ case ui::CursorType::kZoomOut:
// FIXME: Support on OS X
break;
#endif
- case blink::WebCursorInfo::kTypeNoDrop:
- case blink::WebCursorInfo::kTypeNotAllowed:
+ case ui::CursorType::kNoDrop:
+ case ui::CursorType::kNotAllowed:
shape = Qt::ForbiddenCursor;
break;
- case blink::WebCursorInfo::kTypeNone:
+ case ui::CursorType::kNone:
shape = Qt::BlankCursor;
break;
- case blink::WebCursorInfo::kTypeGrab:
+ case ui::CursorType::kGrab:
shape = Qt::OpenHandCursor;
break;
- case blink::WebCursorInfo::kTypeGrabbing:
+ case ui::CursorType::kGrabbing:
shape = Qt::ClosedHandCursor;
break;
- case blink::WebCursorInfo::kTypeCustom:
+ case ui::CursorType::kCustom:
if (cursorInfo.custom_image.colorType() == SkColorType::kN32_SkColorType) {
QImage cursor = toQImage(cursorInfo.custom_image, QImage::Format_ARGB32);
m_delegate->updateCursor(QCursor(QPixmap::fromImage(cursor), cursorInfo.hotspot.x(), cursorInfo.hotspot.y()));
@@ -694,15 +700,8 @@ void RenderWidgetHostViewQt::ImeCompositionRangeChanged(const gfx::Range&, const
QT_NOT_YET_IMPLEMENTED
}
-void RenderWidgetHostViewQt::RenderProcessGone(base::TerminationStatus terminationStatus,
- int exitCode)
+void RenderWidgetHostViewQt::RenderProcessGone()
{
- // RenderProcessHost::FastShutdownIfPossible results in TERMINATION_STATUS_STILL_RUNNING
- if (m_adapterClient && terminationStatus != base::TERMINATION_STATUS_STILL_RUNNING) {
- m_adapterClient->renderProcessTerminated(
- m_adapterClient->renderProcessExitStatus(terminationStatus),
- exitCode);
- }
Destroy();
}
@@ -770,8 +769,11 @@ void RenderWidgetHostViewQt::OnUpdateTextInputStateCalled(content::TextInputMana
}
ui::TextInputType type = getTextInputType();
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
m_delegate->setInputMethodHints(toQtInputMethodHints(getTextInputType()) | Qt::ImhNoPredictiveText | Qt::ImhNoTextHandles | Qt::ImhNoEditMenu);
-
+#else
+ m_delegate->setInputMethodHints(toQtInputMethodHints(getTextInputType()) | Qt::ImhNoPredictiveText);
+#endif
m_surroundingText = toQt(state->value);
// Remove IME composition text from the surrounding text
if (state->composition_start != -1 && state->composition_end != -1)
@@ -825,7 +827,7 @@ void RenderWidgetHostViewQt::OnTextSelectionChanged(content::TextInputManager *t
#if defined(USE_OZONE)
if (!selection->selected_text().empty() && selection->user_initiated()) {
// Set the CLIPBOARD_TYPE_SELECTION to the ui::Clipboard.
- ui::ScopedClipboardWriter clipboard_writer(ui::CLIPBOARD_TYPE_SELECTION);
+ ui::ScopedClipboardWriter clipboard_writer(ui::ClipboardType::kSelection);
clipboard_writer.WriteText(selection->selected_text());
}
#endif // defined(USE_OZONE)
@@ -1000,16 +1002,21 @@ QSGNode *RenderWidgetHostViewQt::updatePaintNode(QSGNode *oldNode)
void RenderWidgetHostViewQt::notifyShown()
{
if (m_enableViz) {
+ // Handle possible frame eviction:
+ if (!m_dfhLocalSurfaceIdAllocator.HasValidLocalSurfaceIdAllocation())
+ m_dfhLocalSurfaceIdAllocator.GenerateId();
if (m_visible)
return;
m_visible = true;
+ }
+
+ host()->WasShown(base::nullopt);
+
+ if (m_enableViz) {
m_delegatedFrameHost->AttachToCompositor(m_uiCompositor.get());
m_delegatedFrameHost->WasShown(GetLocalSurfaceIdAllocation().local_surface_id(),
m_viewRectInDips.size(),
- false /* record_presentation_time */);
- host()->WasShown(false);
- } else {
- host()->WasShown(false);
+ base::nullopt);
}
}
@@ -1020,7 +1027,7 @@ void RenderWidgetHostViewQt::notifyHidden()
return;
m_visible = false;
host()->WasHidden();
- m_delegatedFrameHost->WasHidden();
+ m_delegatedFrameHost->WasHidden(content::DelegatedFrameHost::HiddenCause::kOther);
m_delegatedFrameHost->DetachFromCompositor();
} else {
host()->WasHidden();
@@ -1080,7 +1087,7 @@ bool RenderWidgetHostViewQt::forwardEvent(QEvent *event)
#endif
};
- if (!inputMethodQuery(Qt::ImEnabled).toBool() && !acceptKeyOutOfInputField(keyEvent))
+ if (!inputMethodQuery(Qt::ImEnabled).toBool() && !(inputMethodQuery(Qt::ImHints).toInt() & Qt::ImhHiddenText) && !acceptKeyOutOfInputField(keyEvent))
return false;
Q_ASSERT(m_editCommand.empty());
@@ -1200,7 +1207,11 @@ QVariant RenderWidgetHostViewQt::inputMethodQuery(Qt::InputMethodQuery query)
// TODO: Implement this
return QVariant(); // No limit.
case Qt::ImHints:
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
return int(toQtInputMethodHints(getTextInputType()) | Qt::ImhNoPredictiveText | Qt::ImhNoTextHandles | Qt::ImhNoEditMenu);
+#else
+ return int(toQtInputMethodHints(getTextInputType()) | Qt::ImhNoPredictiveText);
+#endif
default:
return QVariant();
}
@@ -1293,6 +1304,14 @@ void RenderWidgetHostViewQt::handleKeyEvent(QKeyEvent *ev)
}
}
+ // Ignore autorepeating KeyRelease events so that the generated web events
+ // conform to the spec, which requires autorepeat to result in a sequence of
+ // keypress events and only one final keyup event:
+ // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Auto-repeat_handling
+ // https://w3c.github.io/uievents/#dom-keyboardevent-repeat
+ if (ev->type() == QEvent::KeyRelease && ev->isAutoRepeat())
+ return;
+
content::NativeWebKeyboardEvent webEvent = WebEventFactory::toWebKeyboardEvent(ev);
if (webEvent.GetType() == blink::WebInputEvent::kRawKeyDown && !m_editCommand.empty()) {
ui::LatencyInfo latency;
@@ -1554,7 +1573,12 @@ void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
eventTimestamp += m_eventsToNowDelta;
QList<QTouchEvent::TouchPoint> touchPoints = mapTouchPointIds(ev->touchPoints());
- {
+ // Make sure that ACTION_POINTER_DOWN is delivered before ACTION_MOVE,
+ // and ACTION_MOVE before ACTION_POINTER_UP.
+ std::sort(touchPoints.begin(), touchPoints.end(), compareTouchPoints);
+
+ // Check first if the touch event should be routed to the selectionController
+ if (!touchPoints.isEmpty()) {
ui::MotionEvent::Action action;
switch (touchPoints[0].state()) {
case Qt::TouchPointPressed:
@@ -1573,6 +1597,23 @@ void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
MotionEventQt motionEvent(touchPoints, eventTimestamp, action, ev->modifiers(), 0);
if (m_touchSelectionController->WillHandleTouchEvent(motionEvent)) {
+ m_previousTouchPoints = touchPoints;
+ ev->accept();
+ return;
+ }
+ } else {
+ // An empty touchPoints always corresponds to a TouchCancel event.
+ // We can't forward touch cancellations without a previously processed touch event,
+ // as Chromium expects the previous touchPoints for Action::CANCEL.
+ // If both are empty that means the TouchCancel was sent without an ongoing touch,
+ // so there's nothing to cancel anyway.
+ touchPoints = m_previousTouchPoints;
+ if (touchPoints.isEmpty())
+ return;
+
+ MotionEventQt cancelEvent(touchPoints, eventTimestamp, ui::MotionEvent::Action::CANCEL, ev->modifiers());
+ if (m_touchSelectionController->WillHandleTouchEvent(cancelEvent)) {
+ m_previousTouchPoints.clear();
ev->accept();
return;
}
@@ -1589,21 +1630,13 @@ void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
break;
case QEvent::TouchCancel:
{
- // Don't process a TouchCancel event if no motion was started beforehand, or if there are
- // no touch points in the current event or in the previously processed event.
- if (!m_touchMotionStarted || (touchPoints.isEmpty() && m_previousTouchPoints.isEmpty())) {
- clearPreviousTouchMotionState();
- return;
+ // Only process TouchCancel events received following a TouchBegin or TouchUpdate event
+ if (m_touchMotionStarted) {
+ MotionEventQt cancelEvent(touchPoints, eventTimestamp, ui::MotionEvent::Action::CANCEL, ev->modifiers());
+ processMotionEvent(cancelEvent);
}
- // Use last saved touch points for the cancel event, to get rid of a QList assert,
- // because Chromium expects a MotionEvent::ACTION_CANCEL instance to contain at least
- // one touch point, whereas a QTouchCancel may not contain any touch points at all.
- if (touchPoints.isEmpty())
- touchPoints = m_previousTouchPoints;
clearPreviousTouchMotionState();
- MotionEventQt cancelEvent(touchPoints, eventTimestamp, ui::MotionEvent::Action::CANCEL, ev->modifiers());
- processMotionEvent(cancelEvent);
return;
}
case QEvent::TouchEnd:
@@ -1627,11 +1660,6 @@ void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
#endif
}
- // Make sure that ACTION_POINTER_DOWN is delivered before ACTION_MOVE,
- // and ACTION_MOVE before ACTION_POINTER_UP.
- std::sort(touchPoints.begin(), touchPoints.end(), compareTouchPoints);
-
- m_previousTouchPoints = touchPoints;
for (int i = 0; i < touchPoints.size(); ++i) {
ui::MotionEvent::Action action;
switch (touchPoints[i].state()) {
@@ -1658,6 +1686,8 @@ void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
MotionEventQt motionEvent(touchPoints, eventTimestamp, action, ev->modifiers(), i);
processMotionEvent(motionEvent);
}
+
+ m_previousTouchPoints = touchPoints;
}
#if QT_CONFIG(tabletevent)
@@ -1880,6 +1910,11 @@ std::unique_ptr<content::SyntheticGestureTarget> RenderWidgetHostViewQt::CreateS
return nullptr;
}
+ui::Compositor *RenderWidgetHostViewQt::GetCompositor()
+{
+ return m_uiCompositor.get();
+}
+
void RenderWidgetHostViewQt::UpdateNeedsBeginFramesInternal()
{
if (m_enableViz)