(Not So Easy) Hybrid Applications with Qt, WebKit and JavaScriptCore

Recently I discovered a set of slides from the Nokia’s Head of Technology Development, Pekka Kosonen, here: http://www.slideshare.net/pkosonen/next-generation-hybrid-applications-with-qt-presentation-for-see-2009 In this presentation, Pekka gives an overview about what Nokia’s Qt team calls “Hybrid Applications”. What this basically means is an application which makes use of web technology within traditional programming environments like C++. I am myself working on an application based on such an architecture, though I didn’t have a name for such an approach yet, so my thanks goes to Nokia for providing me with another buzzword for my professional life as a software consultant 😉

In this article I want to focus on my current approach, the current state of the API implementations at Nokia and their limitations.

The picture shows the basic structure of my application architecture, as it was design at the very beginning. At its core, there is the model object layer. This layer carries all business objects as well as business functionalities and will be implemented as QObjects while making use of some essential features of Qt like its datatypes and some of the hardware abstraction APIs. One particular aspect important to mention is the QtScript API, which shall be used by the final application after deployment to provide functional customizability to the customer of the application.

QtScript is a scripting environment that is as of Qt 4.5 based on the JavaScriptCore framework provided by WebKit, i.e., a highly optimized scripting engine, it even comes with a JIT. Using the QtScript APIs it is possible to integrate the complete model objects layer into the JavaScript engine.

The presentation layer in my application consists of 2 parts: the presentation of structured text, tables, forms etc. and the presentation of 2-dimensional drawings. In the hybrid application, the display of structured text will be accomplished using QWebViews, which delegate internally to a WebKit engine (the same WebKit as found in Apple’s Safari or Google’s Chrome web browsers). The complexity of the WebKit engine is completely encapsulated by QWebView wrapper classes like QWebElement and QWebFrame. For the 2D drawing part of the application Qt’s QGraphicsScene will be used. Alternatively, HTML 5.0 JavaScript Canvas could be used if performance is good enough.

Now back to the presentation I mentioned above: In the API of a QWebFrame there are 2 interesting methods:

void addToJavaScriptWindowObject ( const QString & name, QObject * object )
void addToJavaScriptWindowObject ( const QString & name, QObject * object, QScriptEngine::ValueOwnership own )

which can be used to provide the UI scripting environment with direct access to the model object layer and vice versa. However, these two functions are the only access point towards the browser internal scripting engine, which makes it impossible to add serious scripting support into the UI scripting part. Having access from the WebKit JavaScript to the C++ model object would offer the possibility to implement very lean presentation in JavaScript, for instance to react on a signal in JavaScript like something has been added to some model element could then lead to a new <TR> being added to a <TABLE>, which coulld all be handled via JavaScript!

This however, will not be possible as long as the API to access the WebKit’s JavaScriptCore is solely based on these two methods only and as there is no way to enrich the WebKit engine with the necessary configuration to tell it about the object model features like all its associations or constructors.

All of this is possible, however, in the standalone QtScript engine, which is essentially based on the same JavaScriptCore but which unfortunately is completely separate from the browser’s JavaScriptCore even though they both do the same. Both JavaScriptCore even have different source code copies in the Qt source code. I can only assume that Nokia separated both because they target different execution environments and therefore they must be adapted differently, but even if, I would like to ask why?

My conclusion so far is that I either have to wait for Qt to integrate both engines in a homogenous style (or do it myself) or think elsewhere, perhaps by integrating the WebKit directly and dropping QWebView completely.


5 thoughts on “(Not So Easy) Hybrid Applications with Qt, WebKit and JavaScriptCore

  1. Have you considered using Ajax like calls to get information on updates to the model? Especially if the new webkit supports web sockets?

  2. Yes I did. But it would require an HTTP server inside the Qt application which maps the AJAX calls to object methods, properties etc. i.e., a lot of extra work, very expensive calling (via OS networking) and introduces a new problem dimension of asynchronicity as the event handling is then not synchronous any more and conversational state must be managed in browser then.

  3. I have tried this ~2 years back … if it is same story today then I don’t think you supporting more JavaScript injection is scheduled in near future.
    However WebKit ports other than QT already supports it to full extent.
    checkout http://code.mcrux.com/ this was a small project (working only on windows).

    You should also checkout Titanium Desktop project .. it implements everything related to your need and ported to windows/linux/osx. (all three native ports using cairo / gtk / native webkit port in each platform respectively.)

  4. Pingback: Rationale for HTML in native applications « André Pareis

  5. Pingback: Alternative Hybrid Application Architecture « André Pareis

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s