WebKitGTK+ 2.12

We did it again, the Igalia WebKit team is pleased to announce a new stable release of WebKitGTK+, with a bunch of bugs fixed, some new API bits and many other improvements. I’m going to talk here about some of the most important changes, but as usual you have more information in the NEWS file.

FTL

FTL JIT is a JavaScriptCore optimizing compiler that was developed using LLVM to do low-level optimizations. It’s been used by the Mac port since 2014 but we hadn’t been able to use it because it required some patches for LLVM to work on x86-64 that were not included in any official LLVM release, and there were also some crashes that only happened in Linux. At the beginning of this release cycle we already had LLVM 3.7 with all the required patches and the crashes had been fixed as well, so we finally enabled FTL for the GTK+ port. But in the middle of the release cycle Apple surprised us announcing that they had the new FTL B3 backend ready. B3 replaces LLVM and it’s entirely developed inside WebKit, so it doesn’t require any external dependency. JavaScriptCore developers quickly managed to make B3 work on Linux based ports and we decided to switch to B3 as soon as possible to avoid making a new release with LLVM to remove it in the next one. I’m not going to enter into the technical details of FTL and B3, because they are very well documented and it’s probably too boring for most of the people, the key point is that it improves the overall JavaScript performance in terms of speed.

Persistent GLib main loop sources

Another performance improvement introduced in WebKitGTK+ 2.12 has to do with main loop sources. WebKitGTK+ makes an extensive use the GLib main loop, it has its own RunLoop abstraction on top of GLib main loop that is used by all secondary processes and most of the secondary threads as well, scheduling main loop sources to send tasks between threads. JavaScript timers, animations, multimedia, the garbage collector, and many other features are based on scheduling main loop sources. In most of the cases we are actually scheduling the same callback all the time, but creating and destroying the GSource each time. We realized that creating and destroying main loop sources caused an overhead with an important impact in the performance. In WebKitGTK+ 2.12 all main loop sources were replaced by persistent sources, which are normal GSources that are never destroyed (unless they are not going to be scheduled anymore). We simply use the GSource ready time to make them active/inactive when we want to schedule/stop them.

Overlay scrollbars

GNOME designers have requested us to implement overlay scrollbars since they were introduced in GTK+, because WebKitGTK+ based applications didn’t look consistent with all other GTK+ applications. Since WebKit2, the web view is no longer a GtkScrollable, but it’s scrollable by itself using native scrollbars appearance or the one defined in the CSS. This means we have our own scrollbars implementation that we try to render as close as possible to the native ones, and that’s why it took us so long to find the time to implement overlay scrollbars. But WebKitGTK+ 2.12 finally implements them and are, of course, enabled by default. There’s no API to disable them, but we honor the GTK_OVERLAY_SCROLLING environment variable, so they can be disabled at runtime.

But the appearance was not the only thing that made our scrollbars inconsistent with the rest of the GTK+ applications, we also had a different behavior regarding the actions performed for mouse buttons, and some other bugs that are all fixed in 2.12.

The NetworkProcess is now mandatory

The network process was introduced in WebKitGTK+ since version 2.4 to be able to use multiple web processes. We had two different paths for loading resources depending on the process model being used. When using the shared secondary process model, resources were loaded by the web process directly, while when using the multiple web process model, the web processes sent the requests to the network process for being loaded. The maintenance of this two different paths was not easy, with some bugs happening only when using one model or the other, and also the network process gained features like the disk cache that were not available in the web process. In WebKitGTK+ 2.12 the non network process path has been removed, and the shared single process model has become the multiple web process model with a limit of 1. In practice it means that a single web process is still used, but the network happens in the network process.

NPAPI plugins in Wayland

I read it in many bug reports and mailing lists that NPAPI plugins will not be supported in wayland, so things like http://extensions.gnome.org will not work. That’s not entirely true. NPAPI plugins can be windowed or windowless. Windowed plugins are those that use their own native window for rendering and handling events, implemented in X11 based systems using XEmbed protocol. Since Wayland doesn’t support XEmbed and doesn’t provide an alternative either, it’s true that windowed plugins will not be supported in Wayland. Windowless plugins don’t require any native window, they use the browser window for rendering and events are handled by the browser as well, using X11 drawable and X events in X11 based systems. So, it’s also true that windowless plugins having a UI will not be supported by Wayland either. However, not all windowless plugins have a UI, and there’s nothing X11 specific in the rest of the NPAPI plugins API, so there’s no reason why those can’t work in Wayland. And that’s exactly the case of http://extensions.gnome.org, for example. In WebKitGTK+ 2.12 the X11 implementation of NPAPI plugins has been factored out, leaving the rest of the API implementation common and available to any window system used. That made it possible to support windowless NPAPI plugins with no UI in Wayland, and any other non X11 system, of course.

New API

And as usual we have completed our API with some new additions:

 

WebKitGTK+ 2.8.0

We are excited and proud of announcing WebKitGTK+ 2.8.0, your favorite web rendering engine, now faster, even more stable and with a bunch of new features and improvements.

Gestures

Touch support is one the most important features missing since WebKitGTK+ 2.0.0. Thanks to the GTK+ gestures API, it’s now more pleasant to use a WebKitWebView in a touch screen. For now only the basic gestures are implemented: pan (for scrolling by dragging from any point of the WebView), tap (handling clicks with the finger) and zoom (for zooming in/out with two fingers). We plan to add more touch enhancements like kinetic scrolling, overshot feedback animation, text selections, long press, etc. in future versions.

HTML5 Notifications

notifications

Notifications are transparently supported by WebKitGTK+ now, using libnotify by default. The default implementation can be overridden by applications to use their own notifications system, or simply to disable notifications.

WebView background color

There’s new API now to set the base background color of a WebKitWebView. The given color is used to fill the web view before the actual contents are rendered. This will not have any visible effect if the web page contents set a background color, of course. If the web view parent window has a RGBA visual, we can even have transparent colors.

webkitgtk-2.8-bgcolor

A new WebKitSnapshotOptions flag has also been added to be able to take web view snapshots over a transparent surface, instead of filling the surface with the default background color (opaque white).

User script messages

The communication between the UI process and the Web Extensions is something that we have always left to the users, so that everybody can use their own IPC mechanism. Epiphany and most of the apps use D-Bus for this, and it works perfectly. However, D-Bus is often too much for simple cases where there are only a few  messages sent from the Web Extension to the UI process. User script messages make these cases a lot easier to implement and can be used from JavaScript code or using the GObject DOM bindings.

Let’s see how it works with a very simple example:

In the UI process, we register a script message handler using the WebKitUserContentManager and connect to the “script-message-received-signal” for the given handler:

webkit_user_content_manager_register_script_message_handler (user_content, 
                                                             "foo");
g_signal_connect (user_content, "script-message-received::foo",
                  G_CALLBACK (foo_message_received_cb), NULL);

Script messages are received in the UI process as a WebKitJavascriptResult:

static void
foo_message_received_cb (WebKitUserContentManager *manager,
                         WebKitJavascriptResult *message,
                         gpointer user_data)
{
        char *message_str;

        message_str = get_js_result_as_string (message);
        g_print ("Script message received for handler foo: %s\n", message_str);
        g_free (message_str);
}

Sending a message from the web process to the UI process using JavaScript is very easy:

window.webkit.messageHandlers.foo.postMessage("bar");

That will send the message “bar” to the registered foo script message handler. It’s not limited to strings, we can pass any JavaScript value to postMessage() that can be serialized. There’s also a convenient API to send script messages in the GObject DOM bindings API:

webkit_dom_dom_window_webkit_message_handlers_post_message (dom_window, 
                                                            "foo", "bar");

 

Who is playing audio?

WebKitWebView has now a boolean read-only property is-playing-adio that is set to TRUE when the web view is playing audio (even if it’s a video) and to FALSE when the audio is stopped. Browsers can use this to provide visual feedback about which tab is playing audio, Epiphany already does that 🙂

ephy-is-playing-audio

HTML5 color input

Color input element is now supported by default, so instead of rendering a text field to manually input the color  as hexadecimal color code, WebKit now renders a color button that when clicked shows a GTK color chooser dialog. As usual, the public API allows to override the default implementation, to use your own color chooser. MiniBrowser uses a popover, for example.

mb-color-input-popover

APNG

APNG (Animated PNG) is a PNG extension that allows to create animated PNGs, similar to GIF but much better, supporting 24 bit images and transparencies. Since 2.8 WebKitGTK+ can render APNG files. You can check how it works with the mozilla demos.

webkitgtk-2.8-apng

SSL

The POODLE vulnerability fix introduced compatibility problems with some websites when establishing the SSL connection. Those problems were actually server side issues, that were incorrectly banning SSL 3.0 record packet versions, but that could be worked around in WebKitGTK+.

WebKitGTK+ already provided a WebKitWebView signal to notify about TLS errors when loading, but only for the connection of the main resource in the main frame. However, it’s still possible that subresources fail due to TLS errors, when using a connection different to the main resource one. WebKitGTK+ 2.8 gained WebKitWebResource::failed-with-tls-errors signal to be notified when a subresource load failed because of invalid certificate.

Ciphersuites based on RC4 are now disallowed when performing TLS negotiation, because it is no longer considered secure.

Performance: bmalloc and concurrent JIT

bmalloc is a new memory allocator added to WebKit to replace TCMalloc. Apple had already used it in the Mac and iOS ports for some time with very good results, but it needed some tweaks to work on Linux. WebKitGTK+ 2.8 now also uses bmalloc which drastically improved the overall performance.

Concurrent JIT was not enabled in GTK (and EFL) port for no apparent reason. Enabling it had also an amazing impact in the performance.

Both performance improvements were very noticeable in the performance bot:

webkitgtk-2.8-perf

 

The first jump on 11th Feb corresponds to the bmalloc switch, while the other jump on 25th Feb is when concurrent JIT was enabled.

Plans for 2.10

WebKitGTK+ 2.8 is an awesome release, but the plans for 2.10 are quite promising.

  • More security: mixed content for most of the resources types will be blocked by default. New API will be provided for managing mixed content.
  • Sandboxing: seccomp filters will be used in the different secondary processes.
  • More performance: FTL will be enabled in JavaScriptCore by default.
  • Even more performance: this time in the graphics side, by using the threaded compositor.
  • Blocking plugins API: new API to provide full control over the plugins load process, allowing to block/unblock plugins individually.
  • Implementation of the Database process: to bring back IndexedDB support.
  • Editing API: full editing API to allow using a WebView in editable mode with all editing capabilities.

GNOME 3.4: WebKit2 and kinetic scrolling

The web at your fingertips

The GNOME Project has released GNOME 3.4, the second major release of GNOME 3. A lot of new features, UI improvements and other enhancements are included in this release, as well as important changes in the development platform. You can see all the details in the release notes.

One of the applications that has received a major revamp is Epiphany, the GNOME Web Browser, not only because of the beautiful new interface, but it also has significant improvements in performance and stability. If Epiphany is not your default browser, give it a try when you upgrade to GNOME 3.4. See Xan‘s and Diego‘s blog posts for more details of the new Web Browser.

WebKit2

GNOME 3.4 includes WebKitGTK+ 1.8.0, the first stable release that contains an initial WebKit2 GTK+ API. It’s disabled by default, though, since it’s still a preliminary version, so you need to build with –enable-webkit2 configure option. It’s already possible to try it out with Devhelp 3.4 which can be optionally built with WebKit2 using –with-webkit2 configure option. If the current API is enough to port your application, give it a try and let us know, you can use the webkit2 devhelp branch as a reference. We’ll provide a migration guide soon too.

Kinetic scrolling

GTK+ 3.4 has finally support for kinetic scrolling in GtkScrolledWindow. I’m very happy to know that the work made by Igalia during the GTK+/Meego Handset integration project has helped Carlos Garnacho to properly integrate kinetic scrolling in GTK+.

What’s next?

During the next development cycle, the Igalia WebKit team will continue to focus on making Epiphany even more awesome, with more UI improvements, and of course porting it to WebKit2.

GTK+/MeeGo Handset integration: Week 10

GtkScrolledWindow: kinetic scrolling

The first time I tried to use the press-and-hold patch to allow selections and drag and drop operations in GtkScrolledWindow when kinetic mode is enabled, it didn’t work because press-and-hold patch uses some of the signals (motion event) consumed by GtkScrolledWindow using the captured-event. So, I thought I could make it work by using the captured-event for the press-and-hold implementation too. I reworked the press-and-hold patch to use the capured-event and the scrolled window patch to use the press-and-hold signal, and it indeed worked!

GTK+/MeeGo Handset integration: Week 8

GtkEntry:placeholder-text

Good news here, Matthias reviewed and approved my patches, so I committed them.

In the same bug report, Johannes Schmid proposed to add placeholder text to GtkCellrendererText too, and I think it makes even more sense than for entries since it’s not obvious when a treeview cell is editable. Glade has a custom implementation for the signal editor. I filed a new bug report and attached a patch.

GtkScrolledWindow: kinetic scrolling

While I was on vacation I had the opportunity to play with an Android phone for a while (thanks Roca!), I was very curious about how they solved the problem of selecting text in scrollable widgets and it turned out that they use press-and-hold. After a long press the current word is selected and two handles show up to extend the selection. I don’t like the handles, and I don’t think we need it, but the press-and-hold solution might work for us. We can simply wait after the long press to cancel the scrolling operation and propagate events to child widgets normally so that both selections and drag and drop operations will work as if kinetic scrolling mode were not enabled. I submitted a patch that uses press-and-hold to allow selections and drag and drop operations when kinetic scrolling mode is enabled in GtkScrolledWindow. However, I couldn’t use any of the solutions proposed for press-and-hold in bug #315645. As kris commented (thanks kris for your feedback in this and other bugs, by the way!), this press-and-hold use case changes the game a bit, so we’ll have to think a bit more about it.

GtkLiveEntry

I noticed my patch had a couple of regressions regarding GtkEntry popdown menu handling, corresponding to old bugs #169534 and #71868. Updated the patches (GtkLiveEntry and GtkTreeView) to apply on current git master and fix the regressions.

GTK+/MeeGo Handset integration: Week 6

GtkWidget::press-and-hold signal

It’s unclear to me whether we really need a new signal for this, or we can just synthesize right click events after the long press. So, I’ve reworked the patch to do the latter, showing the same animation and sending a right click event only when the toucscreen mode is enabled (GtkSettings:gtk-touchscreen-mode). Instead of using the touchscreen setting, we could get the source device of the button press event to enable press-and-hold only when it’s originated by a stylus or the finger, but there’s not a GdkInputSource for the finger yet.

GtkEntry:placeholder-text

Company reviewed my patch and pointed out that we could use a single pango layout instead of having one for the main entry text and another one for the hint text. Both texts are never shown at the same time, so it should be possible to use a single pango layout. He also proposed to rename it to placeholder-text, which is the name used in maemo indeed. So, I rewrote the patch addressing both issues.

API also commented on the bug regarding the GailEntry patch. In order to make sure the placeholder text is always available for the a11y system, no matter whether there’s a tooltip text or not, API suggested to use the AtkObject attributes instead of the description, adding a new attribute for the placeholder text. I reworked the GailEntry patch to do exactly that.

Gtk Meeting

During the GTK+ meeting I proposed to include all the bugs of this project into the list of bugs targeted for 3.2. Matthias has already branched so master branch is now open for new stuff.

Next week

I’ll be on vacation for the whole week 🙂

GTK+/MeeGo Handset integration: Week 5

GtkWidget::press-and-hold signal

I haven’t updated the patch this week, even though some interesting points were raised by garnacho, who tried the patch in a real touchscreen device, because the general approach is still under discussion.

GtkEntry:hint-text

I rewrote the patch to explicitely add the hint text instead of using the tooltip text as suggested by Matthias. Also wrote a patch for GailEntry to return the hint text as ATK object description only when there isn’t a description nor a tooltip text, as API proposed. However, Joanmarie thinks the hint text should always be exposed via the description.

GtkLiveSearch

I finished the patch to add the new widget GtkLiveEntry that works like the current search window used in GtkTreeView. I also wrote patches for GtkTreeView, Evince and Nautilus to use GtkLiveEntry instead of their own implementations. Now it’s time to think about the other part of GtkLiveSearch, the search stuff.

GTK+/MeeGo Handset integration: Week 4

GtkWidget::press-and-hold signal

Last week I submitted a work in progress patch just to show my idea of using a new style class to implement the animation instead of changing the cursor. This week I completed the patch creating a new style class GTK_STYLE_CLASS_PRESS_AND_HOLD and implementing the animation in the theming engine using a variation of the current spinner animation. Also fixed the animation to work when there’s no composite manager running. I haven’t plan to continue working on this patch unless it’s reviewed and it needs more work, of course. Matthias already commented about the general approach.

GtkEntry:hint-text

I started to work on this bug this week. Like with press-and-hold, this bug had a working patch attached, so I simply ported it to GTK+3 and updated to apply to current git master. It requires some more work though.

GtkScrolledWindow

Submitted a new patch to add a new auto-hide-scrollbars style property, to hide the scrollbars after a timeout when kinetic scrolling mode is enabled.

GtkLiveSearch

With the idea of splitting it into a general purpose entry widget and an object for the search, I have started to write a new widget, based on EmpathyLiveSearch, GtkTreeView and Evince code, that shows a popup window with an entry when typing on a hook widget. I have nothing to show yet, but I plan to finish it during the following week with patches for GtkTreeView and Evince too. Regarding the search part, Benjamin has the idea to add a GtkSearchable interface.

GTK+/MeeGo Handset integration: Week 3

The initial plan for this week was continue working on kinetic scrolling support for GtkScrolledWindow, however I decided to take a look at the other bugs to give some more time to get review/feedback of the kinetic scrolling work in progress patch.

GtkWidget::press-and-hold signal

This looked easier, since it already had a working patch attached to to the bug. I started porting the patch to GTK+ 3 to make it work with current git master. The signal is quite simple, it’s emitted when the mouse button is pressed for a given amount of time. If the mouse pointer is moved (beyond the drag threshold) during the long-press, the operation is cancelled. The tricky part is the animation that should be shown during the long-press to provide visual feedback to the user that something is going to happen when the mouse button is released. The patch, based on hildon code, implemented the animation by changing the current mouse cursor to an animated one. I didn’t like this approach. Talking with Carlos, he suggested to use a transparent popup window with a custom animation similar to the one implemented in the locate pointer plugin of gnome-settings-daemon. I thought we could even leave the animation to the theme engine and implement a popup window that simply calls gtk_render_activity(). So I wrote a new patch that uses the spinner style class to render the animation just to show how it would work. If we agree on this approach we’ll add a new style class and implement a custom animation in the theme engine so that it could be override by themes.

GtkLiveSearch

This is a widget already used by empathy, based on hildon code too, to show a search entry when typing on a given widget. It provides both, the UI to show the search entry, and a match function that implements the search algorithm. I think they are actually two different things. The widget that connects to key-press signal on a hook-widget to show an entry is implemented in other places like GtkTreeView, and even for other purposes than searching like the goto window used by evince to jump to a random page in presentation mode. The search algorithm might be used by other applications that use another UI like a find bar or a dialog.

GtkScrolledWindow

When kinetic scrolling mode is enabled, the scrollbars don’t make sense anymore as a control since the whole view is a scrolling control, however they still make sense as an indicator. HildonPannableArea has its own scrollbars, smaller and without stepper buttons, that are shown when scrolling starts and dissapear (with a fade animation) after a while when the scrolling operation has finished. Playing with the GTK+ theme I realized that we don’t need to implement our own scrollbars, we can just use a custom css to get something similar to the HildonPannableArea scrollbars. The only thing we would need is a way to show/hide the scrollbars that might be just a GtkScrolledWindow style property so that everything depends on the theme.

GTK+/MeeGo Handset integration: Week 2

First of all, thank you very much to all the people who gave me so useful feedback after my previous post.

The idea for this week was to start integrating the HildonPanneableArea code into GtkScrolledWindow, however both Chris and Karl emailed me suggesting to use a time based approach rather than the one used by hildon. Chris pointed me to MxKineticScrollView, which is the evolution of HildonPanneableArea. The code is much easier and cleaner than the hildon one, so I decided to use it instead.

One of the things that caught my attention was that MxKineticScrollView doesn’t need to synthesize events. This is because clutter implements capture and bubble event handling. GTK+ does always bubble so that events are propagated from child to parent. Having support for capture event handling makes the kinetic scrolling implementation easier and simpler, so following the same approach than clutter, I wrote an initial patch to add GtkWidget::captured-event signal.

Using the new captured-event signal, integrate the MxKineticScrollView code into GtkScrolledWindow was a bit easier. I still had to use an input-only event window, and grab the device on button press to make sure that motion and button release events were received on the scrolled window. It’s still far from finished but I have already published a work in progress patch and a new test to try it out.

During the next week I plan to continue working on kinetic scrolling, fixing issues and completing the implementation with the missing features.