» tagged pages
» logout

sorted by: recent | see : popular
Content Tagged with WebKit + trolltech

WebKit on Windows CE

I want to introduce a feature that we’ve been asked for over and over: QtWebKit on Windows CE. Its still in the works but already in a quite usable state. Eventually its possible to create your own applications with web browsing capabilities on your favourite Windows CE device!

To give QtWebKit for Windows CE a whirl, you can fetch the current source from the QtWebKit git repository. So make sure that you have the following software installed:

  • Qt for Windows CE
  • Git for getting the source
  • Perl for calling the build script

First of all, download the source code:

git clone git://code.staikos.net/webkit
git checkout -b wince origin/joerg/wince-master

You now should have a local branch called wince, which is based on the remote Windows CE branch. Then you must set up your environment to build Qt for Windows CE applications.
This could look like this:

call vsvars32
set QTDIR=c:\Qt\4.4.1
set PATH=%QTDIR%\bin;%PATH%
setcepaths wince-mymakespec

Go into your WebKit directory and call the build script:

perl WebKitTools\Scripts\build-webkit

If everything goes well, you will find in WebKitBuild\Release\bin a QtWebKit4.dll and QtLauncher.exe. Deploy these files to your device (with the Qt binaries including network and image plugins), run it and browse the web!

For Windows CE 5 I strongly recommend to build a smaller Qt version, tailored to your needs. Remember that you only have 32 MB memory per process which is pretty soon filled if you’re displaying web sites with many images or animations.

Try it, have fun and use the mailing list qt-wince-interest@trolltech.com if you have questions or comments.

Trolltech: Trolltech Labs Blogs

WebKit-based SVG rasterizer

Usually you will use QSvgRenderer or QSvgWidget to show the content of SVG (Scalable Vector Graphics) files. So far, QtSvg supports SVG 1.2 Tiny static, without any DOM nor scripting supports. For a much more advanced SVG dancing, one way to do it is by using QtWebKit [1] that is available since Qt 4.4. More detailed information can be obtained by tracking the SVG status support in WebKit.

For the dojo example, here I present less-than-150-lines of code that rasterizes an SVG [2] into an image. The principle is surprisingly simple: we just use QWebView to load the SVG. To rasterize it, we create a QPainter that operates on an image then ask the main web frame to render to the image by using this painter. A little bit complication is on the scaling. To keep the code cleaner and easier to understand, this little SVG rasterizer is made to work only on SVG that has a valid size, i.e. the SVG explicitly specifies both width and height attributes. Since DOM API is not available yet in Qt 4.4, a trick which is employed here to get both attributes is by using QWebFrame::evaluateJavaScript() function [3].

Without further ado, get the code:

svn checkout svn://labs.trolltech.com/svn/graphics/dojo/svg2png

As with many other vector graphics-related goodies, here is the obligatory “Tiger” screenshot (click to enlarge). On the left side is the SVG file shown inside Inkscape, on the right side is the rasterized version (using svg2png) displayed with Gwenview. Due to the said restriction (specifying width, height), the SVG is not really the same as the commonly used example, I added both the necessary height and width attributes.

Result of WebKit-based SVG rasterizer

As an exercise to the reader, modify the program so that it works with a remote file, e.g. an URL with http or ftp scheme. Hint: check for guessUrlFromString() function in the Qt 4.4 Demo Browser.

[1] However, filter effects are not fully implemented yet.
[2] .svgz is not supported
[3] Use the JavaScript console in the Web Inspector to check and play with the DOM elements and their attributes.

Trolltech: Trolltech Labs Blogs

Network Cache!

The past few weeks I have been hacking on another feature in Qt. Going with the theme of making Qt 4.5 faster I added a cache system to QNetworkAccessManager and provided a simple QNetworkDiskCache that can be used by most applications. Under the hood the new http backend has been enhanced to support all the http rfc cache features you would expect (even behave better than FireFox in one case). Adding a cache system is very important to a lot of our customers.

- Anyone who wants to use rss/atom feeds absolutely must have a cache system in place.
- Anyone who uses QtWebKit has been looking forward to a cache system.
- Any other application that pulls down files off the network such as in XMLPatterns can use the cache to improve performance and reduce network overhead.

To store the cache QDesktopServices::storageLocation has a new enum CacheLocation that can be used to determine a proper cross platform location for where cache files can be stored. The included QNetworkDiskCache is simple and should be good enough for a lot of customers, but for those that want to write a highly optimized one for small devices or to hook into another cache system (such as MSIE’s) the interface QAbstractNetworkCache is provided so you can implement custom cache systems.

For many applications enabling the cache will be as simple as:
QNetworkDiskCache *diskCache = new QNetworkDiskCache(this);
QString location = QDesktopServices::storageLocation(QDesktopServices::CacheLocation);
diskCache->setCacheDirectory(location);
networkAccessManager->setCache(diskCache);

To see it in action you can checkout the demo browser the 4.5 snapshots where I have enabled it.

Trolltech: Trolltech Labs Blogs

Putting QtWebKit to use with Google Maps

Hi there. This is my first blog post, so I guess introductions are in order; My name is Henrik Hartz, and work as a Specialist with Product Management in Troll^W Qt Software. In Product Management I do all kinds of stuff, ranging from working with requirements, specifications, product releases, meeting customers, thinking about the future of Qt, the list goes on.. Recently I’ve had the pleasure of focusing on WebKit.

WebKit is a fantastic technology. Being able to stick web content into your application is simply amazing, there’s just about anything out there you can show! And, a lot of people know HTML, so making use of this to add content to your application enables you to (ab)use your Graphic Designer buddies.

But, WebKit is so much more than just a way to show HTML in your app. You can actually do anything a browser can - and much more! Experimenting with WebKit over the last couple of months I’ve made an example that a lot of people seem to be interested in; Using WebKit to host a Google Maps component.

I wanted to show where our offices are located in the world. So, I started with a simple QStandardItemModel that would read in addresses from a txt file. In the constructor, we read in the text file - using the first field of the comma separated line as the display role, and the rest as the address stored in the UserRole;

QStringList addressLines = address.split(",");

QStandardItem *item = new QStandardItem;
this->insertRow(this->rowCount(),item);

item->setData(addressLines.takeFirst(), Qt::DisplayRole);
item->setData(addressLines.join(",").trimmed(),Qt::UserRole);

With this model in place, we simply set it on the list view of our GUI design (yeah, I like using Qt Designer - it’s fast!);

ui.treeView->setModel(new AddressModel(this));

In the GUI we’ve also placed a web view, which is pointed to a web page under our control. This page shows a Google Maps control. So here is the GUI with the address list and QtWebKit component;

GUI design

This doesn’t do much on it’s own - so we promote the QWebView class to a custom component “Map”, defined by map.h in Qt Designer. This component has some additional services that allow us to update the map, specifically;

void geoCode(const QString &address);

What we want is to update the map based on the entries in the list view when they are clicked. We do this in a slot method connected to the clicked signal of my view. Here we can access the data of the item being clicked, extract the address and ask the map component to geo-code it;

void MainWindow::showItem(const QModelIndex &idx)
{
ui.map->geoCode( idx.data( Qt::UserRole).toString() );
}

The geoCode method will use QtWebKit’s capability of calling JavaScript functions in the web environment. Here we’ll use the Google Maps API to get Google to return a coordinate of the specified address in CSV format, using the asynchronous QNetworkAccessManager::get(const QNetworkRequest &request) API;

void Map::geoCode(const QString &address)
{
QString requestStr( tr("http://maps.google.com/maps/geo?q=%1&output=%2&key=%3")
.arg(address)
.arg("csv")
.arg("GOOGLE_MAPS_KEY") );

manager->get( QNetworkRequest(requestStr) );
}

In another method connected to the QNetworkManager::finished(QNetworkReply*) signal, we parse out the coordinate returned in CSV format from Google, and pass it to a method which updates the map component appropriately;

void Map::loadCoordinates()
{
QStringList scriptStr;
scriptStr
< < "var map = new GMap2(document.getElementById(\"map\"));"
< < "var bounds = new GLatLngBounds;"
< < "var markers = [];"
< < "map.setCenter( new GLatLng(0,0),1 );";

int num=-1;
foreach( QPointF point, coordinates ) {
scriptStr < < QString("markers[%1] = new GMarker(new GLatLng(%2, %3));")
.arg(++num)
.arg(point.x())
.arg(point.y());
}

scriptStr
< < "for( var i=0; i<markers.length; ++i ) {"
< < " bounds.extend(markers[i].getPoint());"
< < " map.addOverlay(markers[i]);"
< < "}"
< < "map.setCenter(bounds.getCenter());";

this->page()->mainFrame()->evaluateJavaScript( scriptStr.join("\n") );
}

In the final call, we tell QtWebKit to evaluate the JavaScript we have synthesized, and the web view updates with the appropriate location;

Qt Software Address book

The snippets shown here are simplified to some extent, but you can find the complete source code here. Please remember to put the HTML for the map component on a server you control - and replace the GOOGLE_MAPS_KEY with your own key (you need to register and bind to a domain for it to work) in both map.cpp and index.html.

Enjoy!

Trolltech: Trolltech Labs Blogs

Putting QtWebKit to use with Google Maps

Hi there. This is my first blog post, so I guess introductions are in order; My name is Henrik Hartz, and work as a Specialist with Product Management in Troll^W Qt Software. In Product Management I do all kinds of stuff, ranging from working with requirements, specifications, product releases, meeting customers, thinking about the future of Qt, the list goes on.. Recently I’ve had the pleasure of focusing on WebKit.

WebKit is a fantastic technology. Being able to stick web content into your application is simply amazing, there’s just about anything out there you can show! And, a lot of people know HTML, so making use of this to add content to your application enables you to (ab)use your Graphic Designer buddies.

But, WebKit is so much more than just a way to show HTML in your app. You can actually do anything a browser can - and much more! Experimenting with WebKit over the last couple of months I’ve made an example that a lot of people seem to be interested in; Using WebKit to host a Google Maps component.

I wanted to show where our offices are located in the world. So, I started with a simple QStandardItemModel that would read in addresses from a txt file. In the constructor, we read in the text file - using the first field of the comma separated line as the display role, and the rest as the address stored in the UserRole;

QStringList addressLines = address.split(",");

QStandardItem *item = new QStandardItem;
this->insertRow(this->rowCount(),item);

item->setData(addressLines.takeFirst(), Qt::DisplayRole);
item->setData(addressLines.join(",").trimmed(),Qt::UserRole);

With this model in place, we simply set it on the list view of our GUI design (yeah, I like using Qt Designer - it’s fast!);

ui.treeView->setModel(new AddressModel(this));

In the GUI we’ve also placed a web view, which is pointed to a web page under our control. This page shows a Google Maps control. So here is the GUI with the address list and QtWebKit component;

GUI design

This doesn’t do much on it’s own - so we promote the QWebView class to a custom component “Map”, defined by map.h in Qt Designer. This component has some additional services that allow us to update the map, specifically;

void geoCode(const QString &address);

What we want is to update the map based on the entries in the list view when they are clicked. We do this in a slot method connected to the clicked signal of my view. Here we can access the data of the item being clicked, extract the address and ask the map component to geo-code it;

void MainWindow::showItem(const QModelIndex &idx)
{
ui.map->geoCode( idx.data( Qt::UserRole).toString() );
}

The geoCode method will use QtWebKit’s capability of calling JavaScript functions in the web environment. Here we’ll use the Google Maps API to get Google to return a coordinate of the specified address in CSV format, using the asynchronous QNetworkAccessManager::get(const QNetworkRequest &amp;request) API;

void Map::geoCode(const QString &address)
{
QString requestStr( tr("http://maps.google.com/maps/geo?q=%1&amp;output=%2&amp;key=%3")
.arg(address)
.arg("csv")
.arg("GOOGLE_MAPS_KEY") );

manager->get( QNetworkRequest(requestStr) );
}

In another method connected to the QNetworkManager::finished(QNetworkReply*) signal, we parse out the coordinate returned in CSV format from Google, and pass it to a method which updates the map component appropriately;

void Map::loadCoordinates()
{
QStringList scriptStr;
scriptStr
< < "var map = new GMap2(document.getElementById(\"map\"));"
< < "var bounds = new GLatLngBounds;"
< < "var markers = [];"
< < "map.setCenter( new GLatLng(0,0),1 );";

int num=-1;
foreach( QPointF point, coordinates ) {
scriptStr < < QString("markers[%1] = new GMarker(new GLatLng(%2, %3));")
.arg(++num)
.arg(point.x())
.arg(point.y());
}

scriptStr
< < "for( var i=0; i<markers.length; ++i ) {"
< < " bounds.extend(markers[i].getPoint());"
< < " map.addOverlay(markers[i]);"
< < "}"
< < "map.setCenter(bounds.getCenter());";

this->page()->mainFrame()->evaluateJavaScript( scriptStr.join("\n") );
}

In the final call, we tell QtWebKit to evaluate the JavaScript we have synthesized, and the web view updates with the appropriate location;

Qt Software Address book

The snippets shown here are simplified to some extent, but you can find the complete source code here. Please remember to put the HTML for the map component on a server you control - and replace the GOOGLE_MAPS_KEY with your own key (you need to register and bind to a domain for it to work) in both map.cpp and index.html.

Enjoy!

Trolltech: Trolltech Labs Blogs

Qt Jambi 4.4.0 Released!

So the time is finally here. Qt 4.4.0 was released a few weeks ago and as promised Qt Jambi is right behind. A lot of effort has gone into this one, in addition to supporting all the new Qt features, like Phonon, Webkit, Widgets in Graphics View, XQuery and Qt Concurrent, we also have a seriously improved deployment system, JDBC support and a compile-time checked signal-slot approach for the paranoid. Its a good time to be a Java developer I tell yah! We already mentioned all the featuers in the Qt Jambi 4.4.0 Preview Blog so we won’t repeat ourselves here… (There is a danger in linking to eskils blog, as it links to others again, which again links to others, which in the end proves to be a fairly complex graph, but then again… we are engineers and like that kind of stuff)

Under the cover we’ve also done quite some work. We also did an overhaul of the garbage collection and memory management subsystem and hopefully ironed out all the bumps and dents. We’ve also done some work on the build system, so that our users that build from source have a bit more substantial buildsystem to work with. Previously it was a complex install document, which has been replaced by a simple ant command which just does it all… I was very happy to see that the deployment system & ANT build scripts works well enough for the webstart to look like a plain, normal webstart app:

<resources>
<j2se version="1.5+"/>
<jar href="qtjambi-examples-4.4.0_01.jar"/>
<jar href="qtjambi-4.4.0_01.jar"/>
</resources>

<resources os="Windows" arch="x86">
<j2se version="1.5+"/>
<jar href="qtjambi-win32-msvc2005-4.4.0_01.jar"/>
</resources>

No magic nativejar or anything like that, just the qtjambi-win32-msvc2005-4.4.0_01.jar in the classpath and that is enough to load it, jpeg and svg plugins and all. The good thing is that the files included in the webstart are produced directly by the ant script with all dependencies etc set up properly… (well… almost properly, it took us an evening last week to get it really working, but now it works properly). Because of the fixes to memory management and deployment Eskil and I got these offical diplomas:

Absolutely last load issue fixed and Last memory managment bug

So, what more is there to say… Try the webstart with its new demos, download the packages and start hacking!

-
The Qt Jambi Team

Trolltech: Trolltech Labs Blogs

Bringing Web Inspector to Linux

For web developers, when it comes to debugging the web applications, tools like Firebug for Firefox, Safari Web Inspector and the recently introduced Opera Dragonfly can be handy and very useful. These kinds of tools offers the possibility to trace the DOM, verify the corresponding (computed) CSS, check network usage and resource loading performance, debug JavaScript, etc.

As for the Web Inspector (which is technically a WebKit feature), it is written in HTML/CSS/JavaScript except for the rather small platform-specific InspectorClient code. As Holger has mentioned before, with QtWebKit it is very easy to bring WebInspector into any QtWebKit-based browser, such as the Demo Browser (shipped with Qt 4.4) or its successor Arora. Since these browsers are available on several platforms, it also means now you can use Web Inspector on Linux (*). Using either the Demo Browser or Arora, just open the menu Tools, Enable Web Inspector and you are ready. After loading any web site, right click on the web page to find the menu item Inspect that will launch the Web Inspector.

The screenshot below gives the unsurprising proof of Web Inspector on Linux (click to enlarge):

Web Inspector on Linux

In the example, I was trying to find out the potential slow-down in SpeedCrunch website. It was easy to spot that the Slideshow JavaScript (slideshow.js) takes around 200 ms. If this particular JavaScript code can be deferred, the web page would have been 200 ms faster.

What about other WebKit-based application? If your application is using QtWebKit, it is almost trivial to enable the Web Inspector. You can use the action available from QWebView::pageAction or trigger it directly using QWebView::triggerPageAction, in both cases passing QWebPage::InspectElement as the action. Easy enough, isn’t it?

Happy inspecting!

(*) Before, it is only possible if you run Safari under Wine

Trolltech: Trolltech Labs Blogs

Top Secret, Hush Hush!

So, after Simon snitched on me and leaked highly sensitive information about my top-secret project, I guess it’s finally time to spill the beans.

Yes, it is true. For the past few months I have been semi-secretly working on taking over the world implementing support for the HTML5 video and audio elements in the Qt port of WebKit, using Phonon as the media backend. This adds QtWebKit to the list of cool browsers that support this feature.

The introduction of a special purpose media element in the HTML5 draft allows embedding of audio and video content into web pages without resorting to using the generic object tag with some random plugin-based player. It’s as easy as this:

<video src="foobar.ogg">Fallback content here.</video>

The media element also comes with a scripting API, making it easy to roll your own player interface if you want to (or use the default one provided by the user agent by adding the controls attribute).

Employing Phonon to implement the playback started out as my “hey-welcome-to-Trolltech-here-is-a-fun-task-for-you”-project, but turned out to also be a good test-case for the implementation of the various Phonon backends we are doing here at Trolltech. The project was momentarily put on ice while we were busy stabilizing the 4.4 release, but now that 4.4 is out the door it’s time to get back in the saddle.

Some of the tasks currently in the pipeline are Win and Mac support (which is still largely untested), full screen support using overlays (for speed), routing the data through an IODevice rather than just passing a URL (which will help buffering and let us ensure that per-site credentials will work), plus implementing more of the default UI controls.

Initial support is already in WebKit trunk for those of you who want to try it out, and the finished result will be in Qt 4.5. Here’s a screenshot, for you pixel peepers out there:

Trolltech: Trolltech Labs Blogs

QtWebKit Development Update

As part of Qt 4.4 we have now made our very first release! -D

Shortly before the release we finished merging all our changes back to the Subversion trunk branch, where we are working directly now. We will continue to maintain and bugfix the code in the Qt 4.4.x release series, but we try to make the changes in trunk first and then backport changes as they fit.

Our current goal is to catch up with the architectural changes that happened in trunk and maintain the layout tests. Holger for example fixed the HTML Canvas after some internal API changes. Ariya started working on Netscape plugins for Windows and Tor Arne I heard is polishing a secret feature he’s been semi-secretly working on for a while now in not-so-secret trunk. I heard rumors that he’s going to secretly blog about the secret feature soon, so stay tuned.

Big props also to Marc and the guys at Collabora for landing the initial support for Netscape plugins for the X11 Qt and Gtk ports in WebKit trunk! Great job!

On the application side Urs Wolfer’s Google Summer of Code project for integrating QtWebKit into KDE has been accepted. Congrats Urs! Feel free to stop by in #webkit and bug us if you have questions )

Trolltech: Trolltech Labs Blogs

Arora & QtWebKit Trunk

Arora

The demo browser in Qt 4.4 has obtained a lot of attention and interest. Now that 4.4 is almost out I have forked it and started a new project called Arora where development can continue, features can be added, and anyone who wants can contribute. The source code is in a Git repository and is currently hosted on github. Along with some improvements and features there are autotest and manual tests. Git (and GitHub) makes it pretty easy for new developers to a project to fork off a branch to develop features that can be later merged back into the project. Feel free to grab the source and add the feature that you miss the most or take one of the fun items off the TODO list. To any artists out there we need an icon to match the new name. Given that this is a fork of the demo future news on Arora will be on the project’s home page or on the Arora blog.

QtWebKit & WebKit trunk

In an effort to stabilize QtWebKit before the 4.4 release QtWebKit was forked from WebKit about six months ago. This is why the acid3 test score in Qt4.4 didn’t match the latest Safari. Now that 4.4 is almost out the door work has begun on integrating the changes into WebKit trunk for 4.5. Not everything is in yet, but already a lot works and it is very exciting. I’ll let this screen shot speak for itself:

acid3.png

The remaining failing tests mostly relate to SVG Fonts. If you are interested in helping out feel free to join #webkit or #qtwebkit on freenode. Instructions on how to build Arora with QtWebKit trunk can be found in the Arora source wiki page.

Trolltech: Trolltech Labs Blogs

WebKit DemoBrowser

In 4.4 Qt is getting a new module, qtwebkit. I have been watching it develop over the past year and have been eager to play around with it in Qt. Shortly after the module was merged into the main Qt branch I began working on a small browser in my spare time. Something I could use for at least some of my daily browsing. By eating my own dogfood I could catch errors in WebKit, the new networking code, and especially spot trouble areas in the API before the release.

*Disclaimer: This is just a little demo project of mine, not a FireFox replacement.*

Startup speed
One nice feature of Qt4 over Qt3 is the startup speed. I have seen reviews of KDE4 that even mention the nice bump that KDE applications received, even application have have just been porting and no extra refactoring was done. When Zack was first working on the webkit Qt integration I noticed that his test application would launch near instantaneous when Qt was in memory already. So if WebKit can launch fast, and Qt can launch fast I was definitely going to make sure that some silly demo code didn’t make it launch slow. So even with an icon database, history, cookies, tabs, etc the demo can still launches quickly. So I think it is fast enough.

Networking
In 4.4 there are some new networking class built up around the new QNetworkAccessManager class. Check out Thiago’s recent blog entry One more piece falling into place: Network Access for some more information about all the new goodies included with it. On top of networking classes I created some gui components including a minimal download manager with the usual suspects such as a progress bar, download speed, etc. A nice little demo for the download manager in its own right. Something new that QNetworkAccessManager uses that not mentioned before is the QCookieJar that is included with Qt4. Wrapping it I added saving/loading, and the usual web browser features.

User Agent
Once the browser was in good enough shape to be use every day I setup Gnome and KDE to choose the demo browser as my preferred browser. So anytime I clicked on links from e-mail or from #qt on irc the demo browser would be used and in the server logs a new user agent would show up for the mysterious demobrowser/0.1. The default qtwebkit user-agent is constructed from QCoreApplication::applicationName and the new QCoreApplication::applicationVersion properties. So if you integrate QtWebKit in your application it will automatically include the application name and version in the user-agent. This is of course configurable. Because it is just a demo and for simplicity sake the demo behaves like a single application, when launched it will contact the already running browser and tell it to open the url from the command line arguments if there is one (configurable to open in new window or tab of course).

Session Managment
Developing the demo I knew that I typically leave my browser open for days at a time and loosing your open tabs (or anything really) in a crash is never good. Also while developing the demo I would want to quickly restart it as changes were made. With that in mind the demo contains is a little watch dog class that makes sure that at most you will only loose the up to the last three seconds in the event of a crash. Not just tabs, but history, cookies, and everything else is protected. Restarting the browser selecting History/Restore Last session will quickly re-open all the top level windows and their tabs from last time.

x-qt-plugin
QtWebKit include a plugin framework and QWebPage has extra built in support for one specific plugin type, x-qt-plugin which the demobrowser implements (see QWebPage::createPlugin) The demo browser lets you add any Qt widget into the webpage. Just like with QScript, signals, slots, properties are all fully accessible from JavaScript. You could even embed QWebView and make a browser in the browser if you wanted to. With the demo browser if you load up a webpage with the following code you will find a loading QProgressbar.
<object type="application/x-qt-plugin" classid="QProgressBar" name="progressbar" height=30></object>
<script>
function display(){
if (++document.progressbar.value != 100)
setTimeout("display()", 50)
}
display();
</script>

More than for a browser
Already there have been Qt developers blogging about their interesting QtWebKit projects such as Amarok and KDE Plasmoids. I am looking forward to see what everyone does with QtWebKit.

FAQ:
The demo can be found in the demos/browser directory of the Qt package. The browser in the 4.4 snapshots has more then the beta including proxy configuration, in page search, improved keyboard shortcuts and some of the features mentioned here.

  • This is only a demo, I tried to not do anything that couldn’t be done with Qt easily, so adding bunzip, tar, and bittorrent support to the download manager wasn’t on my todo. There are plenty of neat things to do first such as bookmarks.
  • Although plugin support was added to QtWebKit for 4.4, the official Adobe flash plugin support will have to wait for 4.5. Or more to the point the netscape plugin support wont be added until 4.5
  • gmail currently does not work.
  • There are no known crashes so please report any that you find.
  • I plan on continuing to develop this demo, for example I have bookmarks mostly done in a branch and am am working on adding more autotests before merging.
  • Many cookie issues can be worked around by turning on “Accept All Cookies” in the preference, the cookiejar has a few fixes that are not in yet.
  • Feel free to check out the code for the demo. The total size is quiet small and I tried to keep the code clean.

A blog about a browser is only complete with a screenshot so here it is running on Windows (Vista), Linux (Gnome), and OS X (Tiger)
demobrowser.png
Having a cross platform browser who’s code base is small and completely open kicks ass.

A big thanks to Jen, Jens, Holger, Morten, Thiago, Simon, Jesper, Thomas, Paul, and everyone else who gave feedback/patches.

Trolltech: Trolltech Labs Blogs

QtWebKit in Action

Henrik recorded some cool videos showing off a bit of the integration of WebKit into Qt. The Quicktime videos are at the bottom of our QtWebKit announcement page, showing WebKit in designer, integrating Google maps into your Qt application or how to embed native widgets into HTML.

Trolltech: Trolltech Labs Blogs

The other side of the summer

Lots has been happening downunder lately. Namely, summer has come and gone. Wasn’t too hot this year, but rained heaps. Causing my pitiful electric mower to die a horrible death on my back yard that was in some spots, a meter tall. Several lawn mowing services balked at the idea of mowing it, so I bit the big one, and bought a petrol mower. How I hate mowing grass, it goes against nature, is noisy and smelly. My daughter of almost 6 months has started sitting and somewhat getting some sort of locomotion going, although it usually ends up in tears, because she wants to just jump into the whole walking thing like her brother and everyone else does. My 2.5 year old son started painting. Luckily not on the walls, but on an easel.

On the Trolltech front, besides the whole Nokia thing, we released Qtopia 4.3.1 SDK for Neo. What better way to create software for Qtopia for your FIC Neo. It seems that OpenMoko have been slowly coming around to officially using Qtopia, in some sort.

Other than the SDK I have been busy preparing the Qtopia 4.4 webkit demonstration, that was at 3GSM, errr MWC. Cool things are possible with webkit in Qtopia. Although it is rather large, the sizes of flash memory can be quite large, and most phones now have huge amounts of space, classing them not in the embedded space any longer.

The Neuros OSD I have has some competition, as I bought an already-configured-for-Australian-use series 1, Oztivo’ified Tivo (thanks Ian!), (for research purposes, my dear wife!). Neuros really needs some scheduling information, they know it, and have put up a bounty
What I like about the Neuros OSD over the tivo is it’s size. The tivo is just huge, like a regular desktop box, and has cooling fans. The OSD has sexy curves, is sleek, glossy black and silent. Makes me want to lick it. Not to mention Neuros will be using Qt Embedded, errr Qtopia Core soon.

I feel bad about my old Sharp Zaurus 5000d’s. Gathering dust, or played with by my son, until he realizes they need charging. Perhaps I will charge them up…

Almost forgot to mention, I have been putting together a virtual keyboard for X11 using Qt. Based largely on kvkbd for kde, but reads the keys and keycodes from an xml file. It works too!

QVKeyboard snapshot

tsdogs, who is one of the HTC-linux guys (who have ported linux to HTC Universal phones and friends), recently gotten embeddedkonsole 4 to run on Qtopia 4. It’s named qterminal and I have put a qpk package for the Neo at qtopia.net. For those who think they need a terminal on their phone. The HTC-linux guys have done quite a lot to hack Linux onto these phones, although it needs to be run from an sd card. The sources can be found in the unofficial Qtopia git repository : git clone git://git.asheesh.org/qtopia_snapshot.git

Trolltech: Trolltech Labs Blogs

Who needs a browser, Qt Jambi just got one?

There is almost always room for a browser in a desktop application. You might need to show some help pages, documents, formated source code, xml or what not. And then you need a browser.

Up to now these browsers have often been limited to show some simple html. But with Qt 4.4 and Qt Jambi 4.4 we will have a proper WebKit integration and voila.. you have a full fledged web browser at your fingertips.

Let’s have a quick look at what it can do!

browser1.pngbrowser21.png

Oi, that looks promising.. Let’s have a look at the source code to this example that has been written using Qt Jambi.

import com.trolltech.qt.core.*;
import com.trolltech.qt.gui.*;
import com.trolltech.qt.webkit.*;       

class HelloWebKit extends QWidget {       

    private QWebView browser;
    private QLineEdit field;       

    public HelloWebKit() {
        field = new QLineEdit();
        browser = new QWebView();       

        QVBoxLayout layout = new QVBoxLayout(this);
        layout.addWidget(field);
        layout.addWidget(browser);       

        field.returnPressed.connect(this, "open()");
    }       

    public void open() {
        String text = field.text();       

        if (text.indexOf("://") < 0)
            text = "http://" + text;       

        browser.load(new QUrl(text));
    }       

    public static void main(String args[]) {
        QApplication.initialize(args);       

        HelloWebKit widget = new HelloWebKit();
        widget.show();       

        QApplication.exec();
    }
}

That wasn’t difficult was it -) But can this actually render some normal webpages.. yes it can. So here goes another screenshot -)

browser3.png

Trolltech: Trolltech Labs Blogs

Who needs a browser, Qt Jambi just got one?

There is almost always room for a browser in a desktop application. You might need to show some help pages, documents, formated source code, xml or what not. And then you need a browser.

Up to now these browsers have often been limited to show some simple html. But with Qt 4.4 and Qt Jambi 4.4 we will have a proper WebKit integration and voila.. you have a full fledged web browser at your fingertips.

Let’s have a quick look at what it can do!

browser1.pngbrowser21.png

Oi, that looks promising.. Let’s have a look at the source code to this example that has been written using Qt Jambi.

import com.trolltech.qt.core.*;
import com.trolltech.qt.gui.*;
import com.trolltech.qt.webkit.*;       

class HelloWebKit extends QWidget {       

    private QWebView browser;
    private QLineEdit field;       

    public HelloWebKit() {
        field = new QLineEdit();
        browser = new QWebView();       

        QVBoxLayout layout = new QVBoxLayout(this);
        layout.addWidget(field);
        layout.addWidget(browser);       

        field.returnPressed.connect(this, "open()");
    }       

    public void open() {
        String text = field.text();       

        if (text.indexOf("://") < 0)
            text = "http://" + text;       

        browser.load(new QUrl(text));
    }       

    public static void main(String args[]) {
        QApplication.initialize(args);       

        HelloWebKit widget = new HelloWebKit();
        widget.show();       

        QApplication.exec();
    }
}

That wasn’t difficult was it -) But can this actually render some normal webpages.. yes it can. So here goes another screenshot -)

browser3.png

Trolltech: Trolltech Labs Blogs

QtWebKit Development Update

The temperatures in Oslo have been dropping rapidly in the last few days, we’re well below zero now. The same applies to Qt where Thiago opened the fridge of feature freeze. I like how things fall into place :). Actually I have the same feeling with QtWebKit right now. The pieces of the puzzle are falling together, with lots of really good progress:

  • We have integrated a copy of WebKit into the Qt sources and we’re updating it frequently.
  • Shortly after the integration Friedemann, one of the fearless Designer hackers, added a plugin to embed WebKit into Designer, along with support for QUrl properties. See the screenshot below :).
  • Lars and Holger finished the separation of QWebView and QWebPage. The latter is now a standalone QObject that allows embedding WebKit into non-QWidget environments.
  • Michael Goddard of the TT Brisbane hackers started working on improving the QObject bindings inside JavaScriptCore, to make them behave like QtScript’s bindings with regards to signals & slots, properties and child objects. You can follow the progress in the branches of our public git repository.
  • Holger fixed lots of bugs in the event handling. The Web Inspector works much much better now.
  • We have written a little demo browser application to show the use of QtWebKit. It’s in demos/browser in Qt and this blog post was written using it :)!

QWebView embedded in Qt Designer

Trolltech: Trolltech Labs Blogs

Greetings from FOSS.IN/2007

So Holger (zecke), Girish (g-man) and me (tronical) made it to Foss.in in Bangalore in India. We’re having a great time here, a great atmosphere, awesome food and a nice and warm climate. Girish had a presentation about Qt Stylesheets, I gave a presentation about (Qt)WebKit today and Holger had a presentation about OpenEmbedded. And there is probably going to be another lightning talk tomorrow about WebKit :). As a little side-note we found a rather interestingly named candy-bar. Have a look at it yourself:

Safari Candy

Trolltech: Trolltech Labs Blogs

QtWebKit Development Update

It’s been a while since the last update and a few things happened that are worth reporting.

  • George and Adam visited us in Oslo for a week. We’ve spent a fair amount of time discussing all sorts of topics and we have moved our Git repository over to http://code.staikos.net. The new machine setup makes it possible to give contributors push access.
  • Adam did a lot of great cleanup work in the QtWebKit Wiki pages, including instructions on the use of Git with WebKit’s Subversion repository for example
  • We have started reworking the API on the class level. You can follow the work in the shared/api-changes branch. Right now we want to have a toplevel QWebView class that is a QWidget and provides all the convenience to cover most use-cases. Below that we place QWebPage which contains page related functionality like the actions and the history. The page then provides access to the QWebFrame objects, which deal with the per-frame scrollbars and allow rendering into a given QPainter.
  • Thiago integrated the new network access API into Qt and work has started in the shared/network-access branch to port QtWebKit over to use that API. This will completely replace the existing public networking API in QtWebKit when compiled against Qt 4.4. Of course we will keep the old QWebNetworkInterface API around when compiling against Qt 4.3.

Trolltech: Trolltech Labs Blogs

One more piece falling into place: Network Access

As you can probably see from recent blogs, lots of new features are being merged into the mainline Qt (what will become Qt 4.4.0). The latest big one is the Network Access API we’ve been developing for the past few months. It’s in today’s snapshot, so you can try it out already. I’d like to thank Marius Monsen, Prasanth, Lars, Andreas, Simon and everyone else who contributed (even if they just contributed opinions).

It’s also one of the big pieces necessary for WebKit: what’s the use of a browser engine if you can’t download anything off the Internet? And another big new feature: an entirely new HTTP stack, written from the scratch to be fully HTTP/1.1 compatible. At this point in time, we’re throwing random junk and real HTTP replies into it to see how it handles broken servers out there (and broken applications too, like trying to download HTTP off the wrong port).

The design is fairly simple. And if it gives you a sensation of déjà vu, it may be because we designed it to be similar to KIO. And now you’re going to ask me: is it supposed to replace KIO? Well, definitely not, at least not in Qt 4.4: KIO does a lot more than file transfers. It also does file management operations (such as copying, moving, deleting, etc.), which is not part of our design here.

But enough of talking, let’s see some code. The following is a full application that downloads the contents of the first argument:

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    QNetworkAccessManager manager;
    QNetworkReply *reply = manager.get(QUrl::fromEncoded(argv[1]));
    app.connect(reply, SIGNAL(finished()), SLOT(quit()));
    app.exec();
    qDebug() readAll();
}

QNetworkAccessManager is the central class in the design. It holds some configuration (proxy, defaults, etc.) and some internal state. It takes one QNetworkRequest object and an operation (based on HTTP operations: get, post, put, head) and returns a QNetworkReply object.

QNetworkRequest is a simple, value-based implicitly-shared class that holds a URL and some meta-data: HTTP headers and extra attributes. It also does parsing of some tricky HTTP headers for you, so you don’t have to worry about getting the HTTP dates right.

Finally, QNetworkReply is an abstract QIODevice-based class. It’s open for reading by the time you get it, which means it will emit readyRead() whenever data is available for reading. Unlike KIO::TransferJob, if you don’t react to the signal, you won’t lose the data.

The next phase now is to make WebKit use this new infrastructure. The API will probably have a simple setManager() function that takes a QNetworkAccessManager object. When it needs more data from the network, it’ll simply call get() there.

We’ve also designed it to be extensible. You’ll be able to write your own QNetworkAccessManager class, that returns your own QNetworkReply objects and/or implements your application’s own network and security policies.

We’re interested in the feedback you can give us. The team and I are available for questions in the qt4-preview-feedback mailing list.

Trolltech: Trolltech Labs Blogs

QtWebKit Development Update

It’s time for another update on “what’s happening” on the (Qt)WebKit side of things )

  • We’ve been working on preparing the API for a first round of review. As a result of that we have finished the action API in QWebPage that I mentioned in my previous blog. QWebSettings has changed to a pointer based class: Every page returns a pointer to a QWebSettings object and there is static QWebSettings *QWebSettings::defaultSettings(). The individual attributes in the settings are inherited to QWebPage. This makes it easy to apply one global setting to all instances of QWebPage for example:
    QWebSettings *settings = QWebSettings::defaultSettings();
    settings->setAttribute(QWebSettings::JavascriptEnabled, false);
    
  • Lars has implemented a cool new class called QTextBoundaryFinder to find the boundaries for graphemes, words, lines (line breaks) and sentences in a QString. The text iterators in QtWebKit use this class now and provide correct navigation when live-editing is enabled on an HTML element.
  • We’re also working on integrating QtWebKit into Qt itself. Our goal is to include a snapshot of all the sources including the ones generated by build scripts into the Qt source tree. This will make it easier to build QtWebKit itself when it is shipped with Qt.
  • On top of that we are going to have a little QtWebKit hacking workshop next week here in our TT headquarters in Oslo. We plan to lock ourselves in an office and clean up some internals with the help of George and Adam.
  • BTW, Maciej has posted a nice summary about the features in WebKit 3 in the Surfin’ Safari WebKit Blog. QtWebKit is based on the same version and has all the features he describes.

Trolltech: Trolltech Labs Blogs

QtWebKit Development Update

Politics aside I’d like to summarize a bit what happened during the development of the Qt port of WebKit in the last weeks. I like technical details, so I’ll concentrate on those )

  • Lars has worked like crazy to implement support for editing in the layout tests. That means we pass now a whole lot of tests that verify that the on-the-fly editing of web pages works. You can use the contenteditable attribute on HTML elements and they are fully editable in QtWebKit now.
  • Holger has reworked the network job handling introducing priorities. Based on that he fixed support for synchronous downloads and ensured that during a synchronous download no async jobs are served. This is used for example for synchronous XMLHttpRequests.
  • We have started going through the public API again and making comments to things we want to change and fix, in the api-changes branch in our public Git repository
  • I’m reworking the context menu implementation and combining it with a nice API to retrieve QAction objects from a QWebPage. The state of these actions is maintained and you can plug them into toolbars, menus, etc. That will make it easier for developers to customize features like the context menu. Also it simplifies the KDE integration to apply KDE settings such as icons because it’s just one webPage->webAction(QWebPage::Reload)->setIcon(…); call and the action will have the right icon in the toolbar or the context menu.
  • We’ve finally set up a buildbot for the Qt/Windows build of WebKit. This will make sure that compilation always works.

Trolltech: Trolltech Labs Blogs

Open QtWebKit Development

As we plan to integrate WebKit into Qt 4.4 we have to choose a stable code base of WebKit. As Maciej announced on the webkit development list the trunk branch of WebKit is going to be merged with the feature branch and likely to more feature development in the future. Apple instead is going to create a safari-3 branch in WebKit’s Subversion repository and use that for stabilization. We decided to base our work on that stable safari-3 branch. At the same time we decided to switch the development of our patches of the QtWebKit port from Subversion over to git. Our development branches will be hosted on a public git repository here in the Trolltech Labs. You can browse it online through the GitWeb interface. The repository itself is also available through the git protocol, so you can clone the repository and follow our development. Every change that we put into the qtwebkit branch - which is based on the safari-3 branch from Subversion - we also plan to submit into WebKit’s trunk branch in Subversion.

This development model allows us to stay open in our development and makes it easy to publish experimental work. At the same time it should be easy to merge changes between branches and stay in touch with the official WebKit Subversion repository. The svn/* branches in the Git repository are automatically imported from Subversion.

Trolltech: Trolltech Labs Blogs

Small steps

I was on vacations last week but I'm being all jealous of my luggage. It got a free trip around the world. During my last 8 flights my luggage has been lost 5 times. Is that a record? Confetti anyone? It's a celebration. If you're going to meet me during any of the upcoming conferences I'll be the outgoing and highly sarcastic naked guy with a sign on my chest saying "for my face look this way" and an arrow pointing up.

I neglected to mention that, as Simon said, QtWebKit is working on Windows. Simon did an amazing job of porting all the quirks of the build system but "amazing" is the default state for all of his code so it's not a surprise at all. While he was doing that I've sat down and ported XML tokenizer to QXmlStream from LibXML. If you never wrote a web rendering tokenizer (and unless you're crazy, the chances of that are pretty high, and if you did you're crazy and won't remember doing it anyway) you know that "fragile" is a term that nicely describes it. After it was ported Lars and I sat down to fix the regressions and they didn't even know what hit them (ha! ninja reference).

In other news I've merged in FreeType2 rasterization algorithm patches in Qt. Our raster engine, uses the beauty that is FreeType's rasterizer, with a few patches on top. Because they break BC in FreeType's public interfaces we can't merge them back at the moment. In any case the patches improve rendering speed in general antialiased paths of the raster engine (meaning on Windows, Qtopia Core and in general whenever rendering to a QImage) by about 10% which is gangsta awesome ("gangsta awesome" is a very high level of awesomeness, at least judging from MTV).

I've also optimized the path clipping code. Andreas uses the path clipping code in GraphicsView for collision detection, so when I say "path clipping code" you should read "path clipping and GraphicsView collision detection". A lot of the time in that algorithm has been spent on vertex allocation for tested paths. I've used a few tricks to speed it up by about 15%. The code for that algorithm is the number two reason why baby seals die (the first is still undisputed). It's not even the algorithm itself but the inherent complexity of the problem. I'm a big fan of computational geometry in computer graphics because it makes grown man cry, except me and I like feeling like the lean, mean, killing machine that I am. My favorite part of the path clipping problem is that there are two ways of solving the precision problems and neither of them really works. The trick is that paths operate in double coordinate system, efficient snap-rounding implementations that I've seen operate in fixed-point coordinate system which falls apart in this case because of absolutely random distribution of vertices across the full double spectrum. Tessellation and clipping itself can be done in a screen coordinate system, which makes it possible to consistently represent your coordinates with fixed-point representation. That doesn't work for paths because, e.g. boolean operations on paths need to be done in native path coordinates not screen coordinates. So the algorithm forces an absolutely crazy mix of dynamic fixed-point size, reduced-predicates, magic and good-will to work. Aren't you happy that I'm doing it for you? You better be.

Yours(1) Latino(2) Lover(3)

1) Not really "yours", more "community". I love "you" but "you" need to realize that I need to be seeing other people.
2) Not really "Latino". Unless of course my Spanish or Brazilian friends would like to name me an "honorary Latino" or "Latino by association". I'd be definitely down with that. The only food I can make that is eatable and doesn't force the fire department to evacuate the building before are nachos. I'm a definition of grace in the kitchen. "Whatever you have in the kitchen I will make it burn" is my motto. Plus I'm sporting quite an attitude to boot. "Make Zack a Latino" campaign. We can make it work!
3) Not really "lover". More "no feelings haver". Though technically I've worked on software for so long that hate is, next to sarcasm, my primary export.

Trolltech: Trolltech Labs Blogs

QtWebKit on Windows

Lars, Zack and I spent the last week making QtWebKit work on Windows. You may wonder why this is worth mentioning at all, since Apple released a WebKit based Safari for Windows not too long ago - and since QtWebKit uses Qt it shouldn’t require any changes at all to work on Windows, right? Indeed, we did not have to change anything in the bits and pieces of WebKit that use Qt, but WebKit is bigger than that. It comes with a lot of build requirements, such as bash, perl, bison, flex, libxml/libxslt, sqlite and more. As a result of that the WebKit for Windows that Safari uses requires a full cygwin installation. That is something we want to avoid as we need to be able to build QtWebKit with minimum dependencies and within “native” Windows environments. So we worked on making it easier to compile the sources and integrate better with QMake for a more portable build process. Below is the obligatory screenshot:

Screenshot of QtLauncher on Windows

QtWebKit can be built with Microsoft’s Visual Studio Compiler or with the MingW port of GCC and the Open Source Edition of Qt for Windows. We are collecting build instructions and help on the WebKit Wiki, so if you want to try to build it yourself I suggest to start there.

Trolltech: Trolltech Labs Blogs

Web on canvas and Dashboard widgets

There are days when I do something quite interesting and in my mind I can almost see myself on a stage in tight, tight spandex pants, long hair, perm, cowboy boots yelling angrily "are you ready to roock?!". People cheering, babies laughing, women throwing their bra's on the stage. It's poetic. Then I remember that I'm a computer scientist and I snap right out of it. I go back to the life filled with math equations on napkins, sleepless nights in front of buzzing computers, stacks of books in corners and no spandex pants (although I can deal with the last one just fine). The fact that I hate rock lessens the blow, but it doesn't make it any less disappointing. So in those moments of sadness I blog, yearning attention and approval, so readily available on the internet. Cough, cough...

I was wondering how hard would it be to create a QGraphicsItem that uses QtWebKit to render pages on a canvas. The idea being that combining full blown canvas like QGraphicsView framework with web rendering engine would give us quite a killer combination. So I've sat down today and done it. At first I had to redo some of the rendering code in QtWebKit and once I was finished I had a QWebGraphicsItem that beautifully renders pages. It being a QGraphicsItem all the effects available to graphics items in Qt are available for free to it. So you can animate, scale, rotate, perspective-transform and do a whole bunch of neat effects on it for free. Once I've done that I figured that it's obvious that this is the best way of getting Apple's Dashboard widgets to work. So I've done that too. I quickly hacked up a class that reads-in Apple Dashboard widget bundles and can render them on a QWebGraphicsItem. The compatibility is not 1:1 quite yet, because some of the Dashboard widgets use JavaScript objects that I haven't implemented yet, like AddressBook object. To be honest I'm not 100% sure whether I want to implement them, I think we can get those things done a lot nicer, it's just a question of whether 1:1 compatibility with Apple Dashboard is worth the extra effort needed to make all those JavaScript objects work on KDE.
First a screenshot of one Apple Dashboard widget rendered and on top a scaled to half its size KDE homepage:


Now a Dashboard widget with a perspective-transformed dot.kde.org page. Since this is QGraphicsView I can interact with the item while it's transformed so I've selected some text on it.

Crackalicious. (no drugs were used while hacking on this, but I did touch myself a little after getting it to work). Furthermore (yes, there's more... what can I say, I'm a giver...) in QtWebKit we have this neat interface that allows you to inject QObject's into the framework as JavaScript objects at run-time, so adding new JavaScript objects is trivial and getting Opera widgets to work would be very, very simple. No spandex pants included though.

Trolltech: Trolltech Labs Blogs

Mirroring widgets

"The life of man is divided between waking, dreaming and dreamless sleep." or so it's written in "The Upanishads"... I wouldn't know because the cartoon version still hasn't been released and I refuse to spend even a second of my life pumping a stream of information into my brain that hasn't been properly sprinkled with commercials and product placement. Which reminds me: use Qt...

I can almost see you sitting at your desk with the same expression the great Plato had when he said: "What?" (not one of his greatest quotes, but I'm sure he said it at one point or the other). In my last blog I described how the engineering department at Trolltech spent the last few months fixing bugs in, what could be described as, a constant "waking" state. By natural progression the next Qt release is putting us in the "dreaming" state.

It's been a while since the last time that I've posted an example on how to do something funky so today I'll partially make up for it. I get a lot of questions asking me how to do something windowing system specific. People at the office can approximate the exact time of delivery of each one of the emails relating to that topic as the seismographic vibrations, originating in the vicinity of the area where the table meets with my head (in a repeated and aggressive fashion), cause ripples to appear in coffee mugs around the office. Hopefully today's example will satisfy the most vicious desires for X11 wackiness.

6'2" (height by association - as measured by the height of the author), weighting at about 139 lines of code (while wearing the license header), the undisputed (mainly because the only one) champion (questionably) of... well, nothing: QX11Mirror. QX11Mirror is a class that can monitor and return the contents of any X11 window in real time. So you could start your favorite media player, pass its window id to QX11Mirror and then render the contents half-the-size with perspective transformation. It would look like this:
One thing that you can't see is that the contents of the movie is updated while the movie is playing and the perspective transformation is animating. All of which is done in real-time. It's really cool.

The original reason for writing this, seemingly, silly example was not "making something pretty". Even though the inability to make applications look gorgeous is the number one cause of hair loss (as shown in a study by doctor "me". Note: "me" is not really a doctor. In fact "me" doesn't even fulfill grammatical requirements of the previous sentences.), which is number one reason for you not looking gorgeous and I'm a big proponent of having KDE developers look beautiful. "KDE - we got hair... In all the right places...". (I know... I'm as shocked as you are that I'm not being paid a zillion dollars to do marketing.) No, the original reason for all of this was to make web plugins behave a lot nicer. Currently the problem is that they don't compose correctly within the web rendering tree. So what I wanted to do is correctly fetch the offscreen contents of those windows, render them in correct stacking order and propagate the events back to them. This goes along the "make stuff work" ideology which I consider myself to be a big fan off. Oh, and here's Flash plugin rendering inside of a Qt applications (as always in my example, things are animating inside):
Oh, and the code is available at Graphics Dojo.

Trolltech: Trolltech Labs Blogs

Browser plugins

One of the perks of being a software engineer is that during the day you get to use such phrases as "oh, what the hell", "that's pure crack" and a large number of "expletive-deleted" without it seeming weird in any way. I can only feel sorry for doctors who rarely get the opportunity to scream "oh, what the hell" while looking at new patients. It's quite therapeutic.

I've spent a little time this week implementing support for plugins in WebKit Qt and the general situation of cross-browser plugins is the reason for the above, spot-on, observations. My blog is, of course, famous for hard-hitting political satire but not today. Today I'll talk technology. No politics, hardly any environmentalism, virtually no vegan propaganda - just straight to the point geek talk (well, "write" but "talk" sounds a lot better).

Given how important browsers are in our day-to-day computer usage it would seem that cross-browser plugins should be a well understood and in fact solved problem. Nope, that's definitely not the case here.

So while tapping your fingers on the messy desk, you roll your eyes and ask "so zack, what is wrong with browser plugins?".
The role of zack - young, careless and wild wacko is played by critically acclaimed me. The role of "you" is played by "you" and "you" really need to step up because you're not convincing anyone right now.

Currently cross-browser plugins use a very sexy (assuming of course that you're heavily into s&m) mix of Xt and another toolkit of their choice. The usage of Xt is just an utter disaster. In fact mixing event loops in any application is a cause of many subtle problems. George had the best idea when he implemented netscape plugins in an out of process application for Konqueror. It's really the only thing that makes sense.

In the Konqueror when a page has a plugin, an external application, the plugin viewer, is started. That process in turn loads and initializes the actual plugin and via DCOP informs the browser what is its window id. Once the hosting browser knows the window id of the plugin, it can XEmbed it. The neat side-effect of this approach is that if a plugin misbehaves one can kill it without any damages to the current browser session (besides the fact that the plugin doesn't render anymore).

The new plugin standard tries to use XEmbed all way. Unfortunately it assumes in-process communication between the browser and the plugin which again is a bad idea. It's a bad idea because it removes this neat concept of an "event loop" from the equation and assumes that whatever event-loop the plugin uses is the same as the one hosting browser is running. Which in turn doesn't do wonders for the whole "cross-browser" aspect of plugins (as long as the definition of "browsers" includes at least two entries and at least one of them is not Firefox).

So lets say you'd like go nuts (like young people tend to do) and display a slider in your plugin which, of course, good, god-fearing people never do. But lets push forward with this highly dubious example and say that maybe you wouldn't want to go all out and display, maybe not right away a slider but some kind of an animating widget. Well, you're pretty screwed because you need the event-loop native to the toolkit in which the widget is implemented to receive the timing events.. Just ask SwfDec guys. They wrote this awesome piece of software, then wrote a browser plugin using, what claims to be, a cross-browser standard just to find out that in that particular standard "cross-browser" meant that it works in Firefox and Firefox. So SwfDec guys found out that Konqueror is not part of that set (unfortunately they also found out a few other things).

So how could we fix it, without having a large groups of grownups sharing some quiet time in a corner, while the sound of weeping fills the room. Hosting plugins in an external process has clear advantages. To the list that I mentioned above we can add another point - by running a plugin in an external process plugins could easily specify what kind of an event loop they need. If your plugin needs Glib's event loop, GTK+ container would be started, if your plugin uses Qt, Qt container would be started (which might or might not use Glib's event loop in Qt 4) if your plugin needs Xt then you should be punched in the face and it all would just work. Containers would announce their window id's through DBUS so that hosting applications could XEmbed them and the world would be a better place (because clearly "browser plugin woes" are occupying one of the top spots on the list of "what's wrong with the world", right between "dust" and "rich people").

At the moment I'm trying to see how feasible it is to lay npruntime implementation, which serves as a bridge between the plugin and the hosting browser on top of DBUS. If that works then we can move to running all plugins as external processes. Which means:
  • plugins taking a lot of CPU can be stopped/killed without affecting the browser
  • when a plugin crashes the browser keeps running without any problems
  • external event loops don't pollute the browser
  • a lot of code for plugin viewers could be shared (besides networking interface) between browsers on systems running X11. Which means that for a change plugin working in one browser would run in all of the others using those containers.
This is basically what we're doing in WebKit Qt. I just really want a simply working plugin infrastructure for browsers. I'm not a man who holds grudges, but last year I didn't get what I wanted, even though I've been exceptionally good, so this better work (last year I wanted to win the lottery. Sure, some might point out that I made it exceedingly difficult by not playing (did you see the odds?) but lets not get bogged down by minor details).

Oh, and a mandatory screenshot of the Diamond plugin in QtWebKit.

Trolltech: Trolltech Labs Blogs