Deliver input events that aren't consumed by a renderer back to the webview

Bug #1313727 reported by Chris Coulson
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Oxide
Fix Released
High
Chris Coulson

Bug Description

RenderViewItem currently consumes all input events (with the exception of some special mouse buttons). However, we need to ensure that events which aren't consumed by the renderer propagate up to parent widgets.

I think this can be achieved by still consuming all events in RenderViewItem, implementing content::WebContentsDelegate::HandleKeyboardEvent (and related functions) and then converting these back to QEvent's.

This will be required for application keyboard shortcuts to work

Changed in oxide:
importance: Undecided → High
status: New → Triaged
Revision history for this message
Arthur Mello (artmello) wrote :

Just pushed an implementation for the method HandleKeyboardEvent to the WebContentsDelegate. The method is converting the NativeWebKeyboardEvent back to a QKeyEvent. But there is two issues on the current implementation.

The first problem is how to retrieve back the key() from the original QEvent since the NativeWebKeyboardEvent stores only the nativeVirtualKey().

The other point is how to add the new QEvent to the queue of events to be processed.

Revision history for this message
Olivier Tilloy (osomon) wrote :

To answer the second question: see QCoreApplication::postEvent(…) (http://qt-project.org/doc/qt-5/qcoreapplication.html#postEvent).

Changed in oxide:
assignee: nobody → Arthur Mello (artmello)
Revision history for this message
Olivier Tilloy (osomon) wrote :

For the first issue, have a look at QKeyEventKeyCodeToWebEventKeyCode(…) in qt/core/browser/oxide_qt_render_widget_host_view.cc, this is where the QEvent’s key code is translated into the NativeWebKeyboardEvent’s windowsKeyCode, so you should be able to do the reverse translation.

Note that from a very quick look at your branch, you’re not actually overriding WebContentsDelegate::HandleKeyboardEvent(…) (see https://code.google.com/p/chromium/codesearch#chromium/src/content/public/browser/web_contents_delegate.h&q=HandleKeyboardEvent&sq=package:chromium&l=252).

Changed in oxide:
status: Triaged → In Progress
Revision history for this message
Arthur Mello (artmello) wrote :

I just updated the branch following your instructions. I am having some problems testing webbrowser-app with my own oxide build (even with out any change). Could someone take a review of this branch?

Revision history for this message
Olivier Tilloy (osomon) wrote :

I tested the branch, I had to modify the target of QCoreApplication::sendEvent to be QGuiApplication::focusObject() for anything to go through.

However, with this change, any key press event enters an infinite loop where oxide::qt::WebView::HandleKeyboardEvent(…) generates a new QKeyEvent that is being handled by oxide::qt::RenderWidgetHostView::HandleKeyEvent(…), which forwards it to the renderer, which in turn will end up calling HandleKeyboardEvent…

Unless I missed something obvious from the proposed solution, this is not going to work.

Revision history for this message
Olivier Tilloy (osomon) wrote :

A side note: once we figure out a working solution, it will be a good candidate for a unit test, QtQuick’s TestCase allows simulating keyboard events (see qt-project.org/doc/qt-5/qml-qttest-testcase.html#simulating-keyboard-and-mouse-events).

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

I'm just building this branch to investigate, but I'd expect the infinite loop when using QGuiApplication::focusObject() (assuming that the focus hasn't changed from the RenderViewItem). The event needs to be delivered to the WebView instead, and it's odd why this doesn't work. I'll take a look to try and figure out why.

As for unit tests - we could actually do with unit tests covering input event handing in general (for mouse, touch and keys). It's something where we're currently lacking quite a bit

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

Ok, I think I understand now:

First of all - we probably want to dispatch the returned event synchronously rather than posting an event to the event loop. So, sendEvent() would be more appropriate than postEvent(). Although, that's not the issue at play here.

When doing either QCoreApplication::postEvent() or QCoreApplication::sendEvent(), this is delegated to a virtual function - QCoreApplication::notify(), which is implemented by QGuiApplication. In the case here, we literally just dispatch the event to the webview, and leave it at that.

The mechanism for propagating events to parent widgets is actually implemented in QApplication::notify(), and we don't have one of those. To dispatch an event in QtQuick that propagates through to parent items, you need to use QQuickWindow::sendEvent():

http://qt-project.org/doc/qt-5/qquickwindow.html#sendEvent.

So, I think we need to delegate the dispatching of the QKeyEvent to WebViewAdapter, and do this call in OxideQQuickWebViewPrivate

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

One other thing - I'm not sure whether it would be worthwhile reimplementing content::NativeWebKeyboardEvent by omitting native_web_keyboard_event_aura.cc from the build and providing our own. It's not a lot of code, and it has a pointer (os_event) on which to store the original event. That might save some effort recreating it here.

You don't have to do that though :)

Olivier Tilloy (osomon)
Changed in oxide:
assignee: Arthur Mello (artmello) → Chris Coulson (chrisccoulson)
Changed in oxide:
status: In Progress → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.