diff options
Diffstat (limited to 'src/core/render_widget_host_view_qt.cpp')
-rw-r--r-- | src/core/render_widget_host_view_qt.cpp | 225 |
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) |