Changes between Version 4 and Version 5 of QtWebKitTiling


Ignore:
Timestamp:
Jun 22, 2010 2:28:42 PM (11 years ago)
Author:
kenneth@webkit.org
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • QtWebKitTiling

    v4 v5  
    1 Tiling with QtWebKit
     1== Tiling with QtWebKit ==
    22
    33Add info about
     
    99----
    1010
    11 QtWebView goes Mobile
     11== QtWebKit goes Mobile ==
    1212
    1313There is a lot of effort being put into QtWebKit in order to make it attractive on the mobile front.
    1414
    15 Among a tons of bug fixes and good performance improvements there are also lots of new features being developed, many geared toward mobile deployment.
     15Among a tons of bug fixes and good performance improvements there are also lots of new features being developed, mainly geared toward mobile deployment.
    1616
    1717The goal with this tutorial is to help you understand some of these new features and how to make the best of them. Or said in other words; how to create a good mobile web view that can be used on touch devices.
    1818
    19 First we should make it clear that QGraphicsWebView is the way forward, so if you want to target mobile devices, it is bye bye QWebView. Why is this? Well, the QWebView is based on the QWidget system, thus it cannot easily support rotation, overlays, hardware accelerated compositing and tiling. If you need a QWidget anyway, you can always construct a QGraphicsView (which is a QWidget) with a QGraphicsWebView inside. This is more or less what we will start with.
     19First we should make it clear that QGraphicsWebView is the way forward, so if you want to target mobile devices, it is bye bye QWebView. Why is that? Well, the QWebView is based on the QWidget system, thus it cannot easily support rotation, overlays, hardware accelerated compositing and tiling. If you need a QWidget anyway, you can always construct a QGraphicsView (which is a QWidget) with a QGraphicsWebView inside. This is more or less what we will start with.
    2020
    2121Let's start with the most simple QGraphicsWebView based "browser" ever:
     
    5353}}}
    5454
    55 Here we just bootstrap a QGraphicsView (QGV) application and add a QGraphicsWebView to the scene.
     55Here we just bootstrap a QGraphicsView application and add a QGraphicsWebView to the scene.
    5656
    57 It might seem a bit useless as you can only navigate through one website but it serves well as a simple example. Notice that I'm disabling the scrollbars on the QGV because QtWebKit handles scrolling and scrollbars automatically. This is due to scrolling optimizations and due to the fact that web authors can interact with the scrollbars for instance style them differently.
     57It might seem a bit useless as you can only navigate through one website, but it serves well as a simple example. Notice that I'm disabling the scrollbars on the graphics view because QtWebKit handles scrolling and scrollbars automatically. This is due to scrolling optimizations and due to the fact that web authors can interact with the scrollbars for instance style them differently.
    5858
    59 On touch-based mobile devices a feature known as tiling is often used. It is used due to the interaction model (touch) as well as a scrolling "optimization". With this optimization we will have to deal with scrolling ourselves and we thus will have to say good bye to the scrollbar styling. Not a big things, as mobile browsers usually do not even show scrollbars, but use scroll indicators instead.
     59On touch-based mobile devices a feature known as tiling is often used. It is used due to the interaction model (touch) as well as a scrolling "optimization". With this optimization we will have to deal with scrolling ourselves and we thus will have to say good bye to the scrollbar styling. Not a big thing, as mobile browsers usually do not even show scrollbars, but use scroll indicators instead.
    6060
    6161Tiling basically means that the contents of the viewport is separated into a grid of tiles, so that when you update some area, instead of just updating the area you actually update the whole tile. This gives a few advantages for scrolling as when you scroll you do not need to repaint the new visible area for each scroll step, as you update a row of tiles each time; tiles that are often only partly on the screen. This minimized all the paint calls that we have to do and makes it possible to make nicely kinetic scrolling a possibility.
     
    6767Tiles also helps with zooming. Repainting at each zoom level change during a zoom animation is basically impossible on a mobile device (or desktop for that sake) and thus with tiling, you can stop the tiles from being updates and just scale the already existing tiles, and then at the end of the animation update tiles on top of the scaled ones.
    6868
     69For now we will ignore the blocking issue and concentrate on the tiling and the interaction model.
    6970
    70 When using tiling, we basically want the QGraphicsWebView to act as our contents, as it supports tiling a.o. things. In order for this we need to make it resize itself to the size of its contents.
     71=== Resize to contents ===
    7172
    72 #1 Magical Step - QGraphicsWebView::resizesToContents
     73When using tiling, we basically want the QGraphicsWebView to act as our contents, as it supports tiling a.o. things. In order for this we need to make it resize itself to the size of its contents. For this we will use {{{QGraphicsWebView::resizesToContents}}}
     74
    7375http://doc.qt.nokia.com/4.7-snapshot/qgraphicswebview.html#resizesToContents-prop
    7476
    75 From Qt 4.7 documentation: "If this property is set, the QGraphicsWebView will automatically change its size
    76 to match the size of the main frame contents. As a result the top level frame will never have scrollbars.
    77 It will also make CSS fixed positioning to behave like absolute positioning with elements positioned
    78 relative to the document instead of the viewport."
     77From Qt 4.7 documentation: "If this property is set, the QGraphicsWebView will automatically change its size to match the size of the main frame contents. As a result the top level frame will never have scrollbars. It will also make CSS fixed positioning to behave like absolute positioning with elements positioned relative to the document instead of the viewport."
    7978
    80 This setting, thus, removes the scrollbars for us on the main frame and makes our QGraphicsWebView resize itself to its content's size. Enabling it:
     79This setting, thus, removes the scrollbars for us on the main frame and makes our QGraphicsWebView resize itself to the size of its content.
     80
     81Enabling it, is as easy as:
    8182
    8283{{{
     
    8687If we are going to expand our mobile web view to the size of the contents of its contained page, then that is going to make the view a lot bigger that what can fit on the device's screen!
    8788
    88 #3 Magical Step - Use a "view" and handle mouse events
     89=== Using a view as the window to the contents ===
    8990
    90 The idea is to have a custom widget which has a QGraphicsWebView as a class member. Remember that the QGraphicsWebView
    91 will be as big as its content's size, so this custom widget will serve as a window, as a viewport.
     91The idea is to have a custom widget which has a QGraphicsWebView as a class member. Remember that the QGraphicsWebView will be as big as its content's size, so this custom widget will serve as a window, as a viewport.
    9292
    9393There is not much more to say here, and the following code snippet illustrates it well:
     
    111111}}}
    112112
    113 In order to properly handle mouse events you must install an event filter on web view or stack it behind its
    114 parent object (search for QGraphicsItem::ItemStacksBehindParent). By doing this the mouse events will reach
    115 a MobileWebView instance before they reach the member QGraphicsWebView
     113In order to properly handle mouse events you must install an event filter on web view or stack it behind its parent object (search for QGraphicsItem::ItemStacksBehindParent). By doing this the mouse events will reach a MobileWebView instance before they reach the member QGraphicsWebView
    116114
    117 Keep in mind that you'll need to add some logic in order to distinguish different mouse events and gestures
    118 like a single click, double click, click-and-pan, etc. That is left as an exercise to the reader.
     115Keep in mind that you'll need to add some logic in order to distinguish different mouse events and gestures like a single click, double click, click-and-pan, etc. That is left as an exercise to the reader.
    119116
    120 Also keep in mind that scrolling will have to be implemented manually, just as zoom etc.
     117Also keep in mind that as stated earlier, scrolling will have to be implemented manually, just as zoom etc.
     118
     119=== Adjusting how contents is laid out ===
    121120
    122121When testing the above on a device, you will notice that many pages do not layout very nicely. In particular the width is larger than the width of the device!
     
    124123The way web contents is laid out, is that the first the viewport width is used for fitting the contents. If the contents doesn't fit due to non-flexible element with a width larger than the viewport width, the min width possible will be used. As most pages are written with a desktop browser in mind, that makes only very few sites fit into the width of a mobile device.
    125124
    126 Qt WebKit has a way to force a layout to a given width/height. What really matters here is the width. If you layout a size to a given width, it will get that width and images etc might get cut of. The width/height is also used for laying out fixed elements, but when we resize the QGraphicsWebView to the size of the contents, fixed elements will not be relative to the view, which is the behaviour found on most mobile browsers.
     125QtWebKit has a way to force a layout to a given width/height. What really matters here is the width. If you layout a size to a given width, it will get that width and images etc might get cut of. The width/height is also used for laying out fixed elements, but when we resize the QGraphicsWebView to the size of the contents, fixed elements will not be relative to the view, which is the behaviour found on most mobile browsers.
    127126
    128 Qt 4.7 docs also says: "This property should be used in conjunction with the QWebPage::preferredContentsSize property.
    129 If not explicitly set, the preferredContentsSize is automatically set to a reasonable value."
     127Qt 4.7 docs also says: "This property should be used in conjunction with the QWebPage::preferredContentsSize property. If not explicitly set, the preferredContentsSize is automatically set to a reasonable value."
    130128
    131 #2 Magical Step - QWebPage::preferredContentsSize
    132129http://doc.qt.nokia.com/4.7-snapshot/qwebpage.html#preferredContentsSize-prop
    133130
     
    136133We saw that this property is automatically set to a reasonable value when using QGraphicsWebView::resizesToContents.
    137134
    138 As you can imaging, laying out with a smaller viewport can cause pages to break, and as thus, a default value has been chosen so that it almost breaks no pages which still making the sites fit. This value is 960x800.
     135As you can imaging, laying out with a smaller viewport can cause pages to break, and as thus, a default value has been chosen so that it almost breaks no pages while still making the sites fit. This value is 960x800.
    139136
    140137If the device have a bigger resolution, this value can be changed using:
     
    146143You can play around with this and find your own magic number, but let's stick to this 960px wide for now.
    147144
     145=== The 'viewport' Meta Tag ===
     146
    148147As some sites do not work with 980 or want to have control on how the page is laid out, QtWebKit as well as Android, Firefox Mobile and the iPhone Safari supports a meta tag called viewport.
    149148
    150 #6 Magical Step - Handle viewport meta tag
    151149This one also deserves a whole blog post for itself. For now let's just say that this is a meta tag that Apple came up with to make a web page capable of "telling" the browser how it wants to be shown.
    152150
     
    154152and http://developer.apple.com/safari/library/documentation/appleapplications/reference/safariwebcontent/usingtheviewport/usingtheviewport.html
    155153
    156 In QtWebKit trunk we already have support for this with a nice API. You must connect the signal from
    157 QWebPage::viewportChangeRequested(const ViewportHints& hints) to a slot of your mobile web view and use
    158 what is provided by QWebPage::ViewportHints to updated your viewport size, scale range, and so on.
     154In QtWebKit trunk we already have support for this with a nice API. You must connect the signal from QWebPage::viewportChangeRequested(const ViewportHints& hints) to a slot of your mobile web view and use what is provided by QWebPage::ViewportHints to updated your viewport size, scale range, and so on.
    159155
    160 This can be tricky and that's why I'm not going deeper on it right now. Since I know you are curious
    161 about it I'll leave you with one more exercise! So try to understand how the guys from MicroB and
    162 Firefox Mobile dealt with this: http://hacks.mozilla.org/2010/05/upcoming-changes-to-the-viewport-meta-tag-for-firefox-mobile
     156This can be tricky and that's why I'm not going deeper on it right now. Since I know you are curious about it I'll leave you with one more exercise! So try to understand how the guys from MicroB and Firefox Mobile dealt with this:
    163157
     158http://hacks.mozilla.org/2010/05/upcoming-changes-to-the-viewport-meta-tag-for-firefox-mobile
     159
     160=== Enabling the tiling ===
    164161
    165162We haven't actually enabled tiling yet, so lets go ahead and do that. That is very simple as it is basically a setting:
     
    173170tiles during an animation, for instance.
    174171
     172=== Avoiding scrollable sub elements ===
     173
    175174One big issue with the above is that, iframes and sites using frames can contain scrollable sub elements. That doesn't work well with the touch interaction model, as you want a finger swipe to scroll the whole page and not end up just scrolling a sub frame. Most mobile browser work around this by enabling something called frame flattening.
    176175
    177 #5 Magical Step - Enable Frame Flattening
    178176Going straight to the point:
    179177