QtWebEngine backend #666

Closed
The-Compiler opened this Issue May 11, 2015 · 19 comments

Comments

Projects
None yet
7 participants
@The-Compiler
Collaborator

The-Compiler commented May 11, 2015

TODO

  • Basic backend/browsing
  • Loading status
  • Scroll position
  • Settings
    • Support to mark settings as QtWebKit/QtWebEngine only
    • Basic QWebEngineSettings
    • Proxy (blocked by #2082)
    • Custom headers (DNT/Accept-Language) (?)
    • User-stylesheet (relevant code in QupZilla: 1, 2)
    • Cookies-related settings
    • Cache-related settings
    • Private browsing
    • User agent
  • Custom cookie handling
  • Custom cache handling
  • Downloads
    • Basic downloads / unsupported content
    • Download tests
    • Downloading via hints
      • via QtNetwork
      • via QtWebEngine
    • Downloading via :download
      • via QtNetwork
      • via QtWebEngine
    • Downloading adblock filterlists
      • via QtNetwork
      • via QtWebEngine
    • MHTML downloads
  • Authentication handling
  • SSL error handling
  • Commands
    • Support to mark commands as QtWebKit/QtWebEngine only
    • Make as many commands as possible work.
      • :navigate
      • :open-editor
      • :insert-text
      • :paste-primary
  • Support for Qt 5.5+ (not going to happen, 5.6+ only)
  • Custom URL handlers (qute://*)
    • qute:settings / JS bridge
  • Host blocking
  • Hinting
    • Adjust for zoom position
    • Only show visible hints
    • frames
    • iframes
  • History
  • Sessions
  • Inspector
  • Custom error pages
  • Feature permissions (geolocation, notifications, etc)
  • Fullscreen support for videos etc.
  • Javascript:
    • log
    • alert
    • confirm
    • open window/tab (createWindow)
    • close window/tab
  • Selecting files
  • View source
  • auto-insert-mode
  • Mouse handling
    • Insert mode on click
    • Ctrl-Click / Middle-click (open links in new tab)
    • Mouse wheel zooming
    • Rocker gestures
    • Back/forward mouse buttons
  • Other customizations in WebView/WebPage subclasses
    • page background color (had some issues)
    • preventing keyboard focus during insert mode (had some issues)
  • printing (available with Qt 5.8 - :print --pdf is implemented but untested, normal printing is not implemented - also see QupZilla/qupzilla#2068)
  • Make tests run for QtWebEngine
    • end2end tests
      • get testsuite to run cleanly
      • Integrate into CI
      • Investigate why xfail(run=False) tests in caret.feature are so slow
      • Add run=False to some slow xfails or reduce wait timeout
      • Investigate unknown-broken/flaky tests
    • unittests
  • Running without QtWebKit
    • Enforcing that via CI
  • pdfjs? (though QTBUG-50556 talks about adding PDFium))
  • Showing audible tabs / muting

Notes about individual features

Hints

The hints (labels to click links via keyboard, see screenshot) are currently implemented in Python, via the QWebElement API (see hints.py and webelem.py).

Since that API doesn't exist anymore with QtWebEngine, a big part of it will have to be reimplemented in Javascript, either using QWebEnginePage::runJavaScript or QWebChannel.

  • Write more tests for :hint features (see hints.feature)
  • Write more HTML hint tests (see simple.html)
  • Split current HintManager class (see hints.py) into separate classes for finding elements/drawing labels/clicking elements
  • Start implementing those parts in javascript
@addisonamiri

This comment has been minimized.

Show comment
Hide comment
@addisonamiri

addisonamiri May 17, 2015

I'd like this feature a lot. There's only one open source blink-based browser I know of (chromium) so you'll be doubling the number :D

I'd like this feature a lot. There's only one open source blink-based browser I know of (chromium) so you'll be doubling the number :D

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Aug 30, 2015

Collaborator

For the lack of a better place to put this - here's a great example by Kovid Goyal on how to use QtWebChannel:

#!/usr/bin/env python3
# vim:fileencoding=utf-8

from PyQt5.Qt import *

qwebchannel_js = QFile(':/qtwebchannel/qwebchannel.js')
if not qwebchannel_js.open(QIODevice.ReadOnly):
    raise SystemExit(
        'Failed to load qwebchannel.js with error: %s' %
        qwebchannel_js.errorString())
qwebchannel_js = bytes(qwebchannel_js.readAll()).decode('utf-8')


def client_script():
    script = QWebEngineScript()
    script.setSourceCode(qwebchannel_js + '''
    new QWebChannel(qt.webChannelTransport, function(channel) {
        channel.objects.bridge.print('Hello world!');
    });
''')
    script.setName('xxx')
    script.setWorldId(QWebEngineScript.MainWorld)
    script.setInjectionPoint(QWebEngineScript.DocumentReady)
    script.setRunsOnSubFrames(True)
    return script


class WebPage(QWebEnginePage):

    def javaScriptConsoleMessage(self, level, msg, linenumber, source_id):
        try:
            print('%s:%s: %s' % (source_id, linenumber, msg))
        except OSError:
            pass

    @pyqtSlot(str)
    def print(self, text):
        print('From JS:', text)


app = QApplication([])
p = WebPage()
v = QWebEngineView()
v.setPage(p)
p.profile().scripts().insert(client_script())
c = QWebChannel(p)
p.setWebChannel(c)
c.registerObject('bridge', p)
v.setHtml('<p>Hello world!')
v.show()
app.exec_()
Collaborator

The-Compiler commented Aug 30, 2015

For the lack of a better place to put this - here's a great example by Kovid Goyal on how to use QtWebChannel:

#!/usr/bin/env python3
# vim:fileencoding=utf-8

from PyQt5.Qt import *

qwebchannel_js = QFile(':/qtwebchannel/qwebchannel.js')
if not qwebchannel_js.open(QIODevice.ReadOnly):
    raise SystemExit(
        'Failed to load qwebchannel.js with error: %s' %
        qwebchannel_js.errorString())
qwebchannel_js = bytes(qwebchannel_js.readAll()).decode('utf-8')


def client_script():
    script = QWebEngineScript()
    script.setSourceCode(qwebchannel_js + '''
    new QWebChannel(qt.webChannelTransport, function(channel) {
        channel.objects.bridge.print('Hello world!');
    });
''')
    script.setName('xxx')
    script.setWorldId(QWebEngineScript.MainWorld)
    script.setInjectionPoint(QWebEngineScript.DocumentReady)
    script.setRunsOnSubFrames(True)
    return script


class WebPage(QWebEnginePage):

    def javaScriptConsoleMessage(self, level, msg, linenumber, source_id):
        try:
            print('%s:%s: %s' % (source_id, linenumber, msg))
        except OSError:
            pass

    @pyqtSlot(str)
    def print(self, text):
        print('From JS:', text)


app = QApplication([])
p = WebPage()
v = QWebEngineView()
v.setPage(p)
p.profile().scripts().insert(client_script())
c = QWebChannel(p)
p.setWebChannel(c)
c.registerObject('bridge', p)
v.setHtml('<p>Hello world!')
v.show()
app.exec_()
@vyp

This comment has been minimized.

Show comment
Hide comment
@vyp

vyp Oct 12, 2015

Contributor

Not sure if this is the right place but I just wanted to point out https://wiki.qt.io/New_Features_in_Qt_5.6#Removed_Modules. Not sure what that means for qutebrowser though.

Contributor

vyp commented Oct 12, 2015

Not sure if this is the right place but I just wanted to point out https://wiki.qt.io/New_Features_in_Qt_5.6#Removed_Modules. Not sure what that means for qutebrowser though.

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Oct 12, 2015

Collaborator

@vyp See my answer to the Archlinux BBS (and the comment on the Phoronix post quoted there).

Collaborator

The-Compiler commented Oct 12, 2015

@vyp See my answer to the Archlinux BBS (and the comment on the Phoronix post quoted there).

@vyp

This comment has been minimized.

Show comment
Hide comment
@vyp

vyp Oct 12, 2015

Contributor

@The-Compiler Oh I didn't know about that, sorry! Also, I'm not blaming you, just trying to point out information which may be helpful.

But I guess all this means is that as long as distributions continue to package qtwebkit, this shouldn't be an issue.

Contributor

vyp commented Oct 12, 2015

@The-Compiler Oh I didn't know about that, sorry! Also, I'm not blaming you, just trying to point out information which may be helpful.

But I guess all this means is that as long as distributions continue to package qtwebkit, this shouldn't be an issue.

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Oct 12, 2015

Collaborator

No worries - I just got into a bit of rage-mode there because of the Phoronix commenter 😉

But I guess all this means is that as long as distributions continue to package qtwebkit, this shouldn't be an issue.

Indeed. And looking at how much still is using QtWebKit, I'm quite sure they'll continue packaging it rather than dropping all that.

Collaborator

The-Compiler commented Oct 12, 2015

No worries - I just got into a bit of rage-mode there because of the Phoronix commenter 😉

But I guess all this means is that as long as distributions continue to package qtwebkit, this shouldn't be an issue.

Indeed. And looking at how much still is using QtWebKit, I'm quite sure they'll continue packaging it rather than dropping all that.

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Jun 13, 2016

Collaborator

Refactoring notes

Currently working on refactoring everything QtWebKit-specific - some random notes here:

  • Can we simplify the WebView.url_text_changed signal, get rid of it, or move it to webkittab.py?
  • How much of webview.py should go to webkittab.py?
  • A lot of FIXME:qtwebengine tags in source files
Collaborator

The-Compiler commented Jun 13, 2016

Refactoring notes

Currently working on refactoring everything QtWebKit-specific - some random notes here:

  • Can we simplify the WebView.url_text_changed signal, get rid of it, or move it to webkittab.py?
  • How much of webview.py should go to webkittab.py?
  • A lot of FIXME:qtwebengine tags in source files
@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Jul 11, 2016

Collaborator

The qtwebengine branch got merged today, so now you can do --backend webengine to use QtWebEngine in master - however a lot of stuff will still be broken 😉

Collaborator

The-Compiler commented Jul 11, 2016

The qtwebengine branch got merged today, so now you can do --backend webengine to use QtWebEngine in master - however a lot of stuff will still be broken 😉

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Jul 13, 2016

Collaborator

@artur-shaik Would you be interested in working on caret browsing for QtWebEngine by any chance?

Since the related web actions aren't available like in QtWebKit, you'd need to do it all in JS - you can add a new file to javascript/ like I did with scroll.js, and then you'd need to implement WebEngineCaret in webenginetab.py.

Then you can call functions from that file similar to what I did in b78b89f.

Collaborator

The-Compiler commented Jul 13, 2016

@artur-shaik Would you be interested in working on caret browsing for QtWebEngine by any chance?

Since the related web actions aren't available like in QtWebKit, you'd need to do it all in JS - you can add a new file to javascript/ like I did with scroll.js, and then you'd need to implement WebEngineCaret in webenginetab.py.

Then you can call functions from that file similar to what I did in b78b89f.

@artur-shaik

This comment has been minimized.

Show comment
Hide comment
@artur-shaik

artur-shaik Jul 13, 2016

Contributor

@The-Compiler, unfortunatly I'm quite busy right now. Not sure how long I will be busy, but if nobody will do it I can try to implement this when I will have some free time.

Contributor

artur-shaik commented Jul 13, 2016

@The-Compiler, unfortunatly I'm quite busy right now. Not sure how long I will be busy, but if nobody will do it I can try to implement this when I will have some free time.

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Jul 13, 2016

Collaborator

Okay, thanks for the update - anyone else with a bit more JS knowledge than me stepping up? 😉

Collaborator

The-Compiler commented Jul 13, 2016

Okay, thanks for the update - anyone else with a bit more JS knowledge than me stepping up? 😉

@lahwaacz

This comment has been minimized.

Show comment
Hide comment
@lahwaacz

lahwaacz Jul 28, 2016

Collaborator

There are couple of things that currently don't work with webengine and are not listed above:

  1. Special mouse buttons for going backward/forward in history. Works out of the box with QtWebkit and in Chromium.
  2. Webengine does not understand the qute:// scheme, so e.g. :help does not work.
Collaborator

lahwaacz commented Jul 28, 2016

There are couple of things that currently don't work with webengine and are not listed above:

  1. Special mouse buttons for going backward/forward in history. Works out of the box with QtWebkit and in Chromium.
  2. Webengine does not understand the qute:// scheme, so e.g. :help does not work.
@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Jul 28, 2016

Collaborator

"Custom URL handlers" is there. I added "Other customizations in WebView/WebPage subclasses" where the mouse buttons are included.

Collaborator

The-Compiler commented Jul 28, 2016

"Custom URL handlers" is there. I added "Other customizations in WebView/WebPage subclasses" where the mouse buttons are included.

@cosminadrianpopescu

This comment has been minimized.

Show comment
Hide comment
@cosminadrianpopescu

cosminadrianpopescu Nov 9, 2016

Contributor

@The-Compiler
I am interested in doing the WebCaret part and also the proxy for QtWebEngine if nobody is working on it. Please let me know.

Contributor

cosminadrianpopescu commented Nov 9, 2016

@The-Compiler
I am interested in doing the WebCaret part and also the proxy for QtWebEngine if nobody is working on it. Please let me know.

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Nov 9, 2016

Collaborator

The caret part would be nice, but I think it involves a lot of javascript as the needed feature doesn't exist for QtWebEngine at all...

As for the proxy we're currently dealing with weird proxy-related crashes (see e.g. libproxy/libproxy#45 and #1891 (comment)) so I'd like to avoid adding new code for that currently.

Collaborator

The-Compiler commented Nov 9, 2016

The caret part would be nice, but I think it involves a lot of javascript as the needed feature doesn't exist for QtWebEngine at all...

As for the proxy we're currently dealing with weird proxy-related crashes (see e.g. libproxy/libproxy#45 and #1891 (comment)) so I'd like to avoid adding new code for that currently.

@cosminadrianpopescu

This comment has been minimized.

Show comment
Hide comment
@cosminadrianpopescu

cosminadrianpopescu Nov 9, 2016

Contributor

I don't mind the javascript part. I am ok with javascript, in general.

Contributor

cosminadrianpopescu commented Nov 9, 2016

I don't mind the javascript part. I am ok with javascript, in general.

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Jan 2, 2017

Collaborator

I started some work on fullscreen videos in the webengine-fullscreen branch, but exiting fullscreen doesn't work like it should yet - I haven't found out how QupZilla handled this yet.

Collaborator

The-Compiler commented Jan 2, 2017

I started some work on fullscreen videos in the webengine-fullscreen branch, but exiting fullscreen doesn't work like it should yet - I haven't found out how QupZilla handled this yet.

@Ninja3047

This comment has been minimized.

Show comment
Hide comment
@Ninja3047

Ninja3047 Jan 2, 2017

They create a key event handler in webview that checks if the escape key is pressed and then it triggers the ExitFullscreen action.

void WebView::_keyReleaseEvent(QKeyEvent *event)
{
    if (mApp->plugins()->processKeyRelease(Qz::ON_WebView, this, event)) {
        event->accept();
    }

    switch (event->key()) {
    case Qt::Key_Escape:
        if (isFullScreen()) {
            triggerPageAction(QWebEnginePage::ExitFullScreen);
            event->accept();
        }
        break;

    default:
        break;
    }
}

https://github.com/QupZilla/qupzilla/blob/master/src/lib/webengine/webview.cpp (Line 1144)

They create a key event handler in webview that checks if the escape key is pressed and then it triggers the ExitFullscreen action.

void WebView::_keyReleaseEvent(QKeyEvent *event)
{
    if (mApp->plugins()->processKeyRelease(Qz::ON_WebView, this, event)) {
        event->accept();
    }

    switch (event->key()) {
    case Qt::Key_Escape:
        if (isFullScreen()) {
            triggerPageAction(QWebEnginePage::ExitFullScreen);
            event->accept();
        }
        break;

    default:
        break;
    }
}

https://github.com/QupZilla/qupzilla/blob/master/src/lib/webengine/webview.cpp (Line 1144)

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Feb 20, 2017

Collaborator

Many of the missing features are implemented with the upcoming v0.10.0 release (see the changelog), and I think it's time to close this! 🎉

For the things which are still missing, I opened separate issues, see this search.

Collaborator

The-Compiler commented Feb 20, 2017

Many of the missing features are implemented with the upcoming v0.10.0 release (see the changelog), and I think it's time to close this! 🎉

For the things which are still missing, I opened separate issues, see this search.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment