WebView focus on the WebPage



  • Is it possible to give a WebView focus that enables JavaScript on the website to accept onClick events without having to click on the WebView?

    We do not have a mouse, and need to get focus on the webpage.

    Ex: I'm on a List with KeyNavigation.right = webView. When I navigate to the right the webView gains focus. I want the next keypress to be sent to the WebPage and NOT to the webView.

    Edit: Found someone else that has the same problem and was never answered: http://developer.qt.nokia.com/forums/viewthread/1917

    Edit: A challenge for you! When the following QML loads up, make it focus the google search bar like most browser. So when I start typing with the keyboard, it immediately starts typing in the search bar. You can not use your mouse! ;)

    @import Qt 4.7
    import QtWebKit 1.0

    WebView {
    id: webView
    width: 1280
    height: 600
    url: "http://www.google.com"
    }
    @

    Edit: Trying to derive from QDeclarativeWebView and extend the functionality myself. However, the registerTypes(const char *uri) is not getting called. If I remove QDeclarativeWebView from the equation, and substitute it with QDeclarativeItem, the plugin now works. /boggle

    GtTools.cpp (Plugin Entry)

    @#include "GtTools.h"
    #include "QDebug"
    #include "InteractiveWebKit.h"

    void GtTools::registerTypes(const char *uri)
    {
    qDebug() << endl << "Registering GtTools" << endl;

    Q_UNUSED(uri);
    
    qmlRegisterType<InteractiveWebKit>("GtTools", 1, 0, "InteractiveWebKit");
    

    }

    Q_EXPORT_PLUGIN(GtTools);@

    GtTools.h

    @#include "GtTools.h"
    #include "QDebug"
    #include "InteractiveWebKit.h"

    void GtTools::registerTypes(const char *uri)
    {
    qDebug() << endl << "Registering GtTools" << endl;

    Q_UNUSED(uri);
    
    qmlRegisterType<InteractiveWebKit>("GtTools", 1, 0, "InteractiveWebKit");
    

    }

    Q_EXPORT_PLUGIN(GtTools);@

    InteractiveWebKit (The class I am extending from QDeclarativeWebView)

    @#include <QtCore/QTime>
    #include <QtDeclarative/qdeclarative.h>

    #include "InteractiveWebKit.h"

    InteractiveWebKit::InteractiveWebKit(QDeclarativeItem *parent):
    QDeclarativeWebView(parent)
    {
    }

    InteractiveWebKit::~InteractiveWebKit() {

    }

    QML_DECLARE_TYPE(InteractiveWebKit);
    @

    InteractiveWebKit.h

    @#ifndef EXAMPLEITEM_H
    #define EXAMPLEITEM_H

    #include <QtCore/QObject>
    #include <QtCore/QString>
    #include <QtCore/QTimer>
    #include <QDeclarativeItem>
    #include <qdeclarativewebview_p.h>

    class InteractiveWebKit : public QDeclarativeWebView
    {
    Q_OBJECT

    public:
    InteractiveWebKit(QDeclarativeItem *parent = 0);
    virtual ~InteractiveWebKit();

    Q_INVOKABLE void focusView() { page()->view()->setFocus(); }
    

    private:
    Q_DISABLE_COPY(InteractiveWebKit)
    };

    #endif // EXAMPLEITEM_H
    @



  • Hi,

    This sounds like a bug -- when WebView gains focus it should assign correct "subfocus", regardless of whether focus was obtained via mouse or keyboard. I'd suggest logging a bug at http://webkit.org/new-qtwebkit-bug with a small example to reproduce the issue.

    Regards,
    Michael



  • Thanks for the reply. It does seem like a bug. I do need a work-around for now as I have a demo to prove this functionality by the end of this week. I think the best approach is to extend the QDeclarativeWebView class and add a simple function to put the focus on the GraphicsView.

    The code I am using is posted above.

    I do get this error when executing:

    plugin cannot be loaded for module "GtTools": Cannot load library /home/townsendg/projects/GtTools-build-desktop/libGtTools.so: (/home/townsendg/projects/GtTools-build-desktop/libGtTools.so: undefined symbol: _ZN19QDeclarativeWebView17componentCompleteEv)

    I am using the 4.7.1 release SDK for Linux 32bit. I did not build from source, but used the SDK binary which came with QtCreator.

    Here is my project file:

    @TEMPLATE = lib
    TARGET = GtTools
    QT += declarative webkit
    CONFIG += debug warn_on qt plugin shared

    TARGET = $$qtLibraryTarget($$TARGET)

    INCLUDEPATH = /home/townsendg/sdk/qtsdk-2010.05/qt/src/3rdparty/webkit/WebKit/qt/declarative

    Input

    SOURCES +=
    GtTools.cpp
    InteractiveWebKit.cpp

    OTHER_FILES=qmldir

    HEADERS +=
    GtTools.h
    InteractiveWebKit.h
    @

    and LDD

    @townsendg@firefly:~/projects/WebKit$ ldd imports/GtTools/libGtTools.so
    linux-gate.so.1 => (0xb78e2000)
    libQtDeclarative.so.4 => /home/townsendg/sdk/qtsdk-2010.05/qt/lib/libQtDeclarative.so.4 (0xb7575000)
    libQtScript.so.4 => /home/townsendg/sdk/qtsdk-2010.05/qt/lib/libQtScript.so.4 (0xb72bd000)
    libQtSvg.so.4 => /home/townsendg/sdk/qtsdk-2010.05/qt/lib/libQtSvg.so.4 (0xb7261000)
    libQtSql.so.4 => /home/townsendg/sdk/qtsdk-2010.05/qt/lib/libQtSql.so.4 (0xb721f000)
    libQtXmlPatterns.so.4 => /home/townsendg/sdk/qtsdk-2010.05/qt/lib/libQtXmlPatterns.so.4 (0xb6d6d000)
    libQtOpenGL.so.4 => /home/townsendg/sdk/qtsdk-2010.05/qt/lib/libQtOpenGL.so.4 (0xb6c7e000)
    libQtNetwork.so.4 => /home/townsendg/sdk/qtsdk-2010.05/qt/lib/libQtNetwork.so.4 (0xb6b41000)
    libQtWebKit.so.4 => /home/townsendg/sdk/qtsdk-2010.05/qt/lib/libQtWebKit.so.4 (0xb57e0000)
    libQtGui.so.4 => /home/townsendg/sdk/qtsdk-2010.05/qt/lib/libQtGui.so.4 (0xb4c71000)
    libQtCore.so.4 => /home/townsendg/sdk/qtsdk-2010.05/qt/lib/libQtCore.so.4 (0xb4993000)
    libpthread.so.0 => /lib/libpthread.so.0 (0xb4962000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb4877000)
    libm.so.6 => /lib/libm.so.6 (0xb4850000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb4834000)
    libc.so.6 => /lib/libc.so.6 (0xb46d6000)
    libGL.so.1 => /usr/lib/nvidia-current/libGL.so.1 (0xb460d000)
    libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0xb4596000)
    libdl.so.2 => /lib/libdl.so.2 (0xb4591000)
    libXrender.so.1 => /usr/lib/libXrender.so.1 (0xb4587000)
    libfontconfig.so.1 => /usr/lib/libfontconfig.so.1 (0xb4557000)
    libz.so.1 => /lib/libz.so.1 (0xb4542000)
    libXext.so.6 => /usr/lib/libXext.so.6 (0xb4532000)
    libX11.so.6 => /usr/lib/libX11.so.6 (0xb4415000)
    libphonon.so.4 => /home/townsendg/sdk/qtsdk-2010.05/qt/lib/libphonon.so.4 (0xb43b7000)
    libQtDBus.so.4 => /home/townsendg/sdk/qtsdk-2010.05/qt/lib/libQtDBus.so.4 (0xb432e000)
    libQtXml.so.4 => /home/townsendg/sdk/qtsdk-2010.05/qt/lib/libQtXml.so.4 (0xb42e3000)
    libgthread-2.0.so.0 => /usr/lib/libgthread-2.0.so.0 (0xb42de000)
    librt.so.1 => /lib/librt.so.1 (0xb42d5000)
    libglib-2.0.so.0 => /lib/libglib-2.0.so.0 (0xb4205000)
    libgobject-2.0.so.0 => /usr/lib/libgobject-2.0.so.0 (0xb41c3000)
    libSM.so.6 => /usr/lib/libSM.so.6 (0xb41ba000)
    libICE.so.6 => /usr/lib/libICE.so.6 (0xb41a1000)
    /lib/ld-linux.so.2 (0xb78e3000)
    libnvidia-tls.so.260.19.06 => /usr/lib/nvidia-current/tls/libnvidia-tls.so.260.19.06 (0xb419f000)
    libnvidia-glcore.so.260.19.06 => /usr/lib/nvidia-current/libnvidia-glcore.so.260.19.06 (0xb2b01000)
    libexpat.so.1 => /lib/libexpat.so.1 (0xb2ada000)
    libxcb.so.1 => /usr/lib/libxcb.so.1 (0xb2ac0000)
    libpcre.so.3 => /lib/libpcre.so.3 (0xb2a8b000)
    libuuid.so.1 => /lib/libuuid.so.1 (0xb2a85000)
    libXau.so.6 => /usr/lib/libXau.so.6 (0xb2a81000)
    libXdmcp.so.6 => /usr/lib/libXdmcp.so.6 (0xb2a7b000)
    @

    Execution:

    @townsendg@firefly:~/projects/WebKit$ QML_IMPORT_TRACE=1 /home/townsendg/sdk/qtsdk-2010.05/qt/bin/qmlviewer WebKit.qml -I imports
    QDeclarativeImportDatabase::addImportPath "/home/townsendg/sdk/qtsdk-2010.05/qt/imports"
    QDeclarativeImportDatabase::addImportPath "/home/townsendg/sdk/qtsdk-2010.05/qt/bin"
    QDeclarativeImportDatabase::addImportPath "imports"
    QDeclarativeImportDatabase::addToImport 0x99048c4 "." -1.-1 File as ""
    QDeclarativeImportDatabase::addToImport 0x99048c4 "Qt" 4.7 Library as ""
    QDeclarativeImportDatabase::addToImport 0x99048c4 "QtWebKit" 1.0 Library as ""
    QDeclarativeImportDatabase::add: loaded "/home/townsendg/sdk/qtsdk-2010.05/qt/imports/QtWebKit/qmldir"
    QDeclarativeImportDatabase::importPlugin "QtWebKit" from "/home/townsendg/sdk/qtsdk-2010.05/qt/imports/QtWebKit/libqmlwebkitplugin.so"
    QDeclarativeImportDatabase::addToImport 0x99048c4 "GtTools" 1.0 Library as ""
    QDeclarativeImportDatabase::add: loaded "/home/townsendg/projects/WebKit/imports/GtTools/qmldir"
    QDeclarativeImportDatabase::importPlugin "GtTools" from "/home/townsendg/projects/WebKit/imports/GtTools/libGtTools.so"
    file:///home/townsendg/projects/WebKit/WebKit.qml:3:1: plugin cannot be loaded for module "GtTools": Cannot load library /home/townsendg/projects/GtTools-build-desktop/libGtTools.so: (/home/townsendg/projects/GtTools-build-desktop/libGtTools.so: undefined symbol: _ZN19QDeclarativeWebView17componentCompleteEv)
    import GtTools 1.0
    ^ @



  • It looks like the shared library and the source are not the same. I copied the qdeclarativewebview_p.h and qdeclarativewebview.cpp into my own plugin projected and made the following changes:

    In qdeclarativewebview_p.h I added the following to QDeclarativeWebView class:

    @
    Q_INVOKABLE void viewFocus();
    @

    In qdeclarativewebview.cpp I added the following to QDeclarativeWebView class:

    @
    void QDeclarativeWebView::viewFocus() {
    if (d && d->view) {
    d->view->setFocus();
    }
    }
    @

    I called this component WebView2 in my Plugin registerTypes

    @ qmlRegisterType<QDeclarativeWebView>(uri, 1, 0, "WebView2");@

    In my qml I added:

    @ onActiveFocusChanged: {
    if (activeFocus) {
    web.viewFocus();
    }
    }@

    Now it works as expected. I really had adding a work around, especially in the private headers protecting me from working on different platforms.

    Is there a better way to do this?



  • I found a better way:

    In qdeclarativewebview.cpp I added setFocusProxy(d->view) in the init method:

    @void QDeclarativeWebView::init()
    {
    d = new QDeclarativeWebViewPrivate(this);

    QWebSettings::enablePersistentStorage();
    
    setAcceptedMouseButtons(Qt::LeftButton);
    setFlag(QGraphicsItem::ItemHasNoContents, true);
    setClip(true);
    
    d->view = new GraphicsWebView(this);
    d->view->setResizesToContents(true);
    QWebPage* wp = new QDeclarativeWebPage(this);
    setPage(wp);
    setFocusProxy(d->view);
    connect(d->view, SIGNAL(geometryChanged()), this, SLOT(updateDeclarativeWebViewSize()));
    connect(d->view, SIGNAL(doubleClick(int, int)), this, SIGNAL(doubleClick(int, int)));
    connect(d->view, SIGNAL(scaleChanged()), this, SIGNAL(contentsScaleChanged()));
    

    }@

    Still looking for the best way to have the view be the focus without changing the SDK and being at the mercy of future releases.



  • [quote author="mbrasser" date="1292308495"]Hi,

    This sounds like a bug -- when WebView gains focus it should assign correct "subfocus", regardless of whether focus was obtained via mouse or keyboard. I'd suggest logging a bug at http://webkit.org/new-qtwebkit-bug with a small example to reproduce the issue.

    Regards,
    Michael[/quote]

    Thanks! I added the bug here: https://bugs.webkit.org/show_bug.cgi?id=51094

    Do you have a suggested work around until the feature is added or bug is fixed?



  • [quote author="Gary_" date="1292390734"]Do you have a suggested work around until the feature is added or bug is fixed?[/quote]

    I can't see any easy workarounds (though I'm definitely not a WebView expert) -- from what I can see an approach like yours above (relying on or modifying private classes) is unfortunately needed for now.

    Regards,
    Michael


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.