Migrating from libwpe

This guide is for embedders moving an application from libwpe and WPEBackend-fdo to WPEPlatform. The higher-level WebKitWebView API is unchanged; almost everything you did below it disappears.

Under libwpe an application created a wpe_view_backend — usually through WPEBackend-fdo’s “exportable” backend — and drove rendering, buffer release, and input dispatch itself through its callbacks. WPEPlatform moves all of that into WebKit and the platform implementation, so migrating an application is mostly a matter of deleting code: the view-backend, the exportable client, buffer management, and input plumbing all go away. In the common case you construct the same WebKitWebView as before and never touch a WPEPlatform type.

WPEPlatform surfaces only when you want more than the defaults — to pin the application to a particular platform, add keyboard shortcuts, or drive the window. Those cases follow, each optional; an application that needs none of them is migrated once its web view is constructed (section 1).

For a symbol-by-symbol lookup, see Migration mapping table. If you maintained a custom WPEBackend-fdo backend rather than an application, that code is a platform implementation — see Writing a WPE platform implementation. The snippets are stripped of boilerplate and assume familiarity with GLib/GObject.

1. Creating the web view

The one change every application makes is how the web view is constructed. Under WPEBackend-fdo you built a wpe_view_backend, wrapped it in a WebKitWebViewBackend, and passed that as the web view’s backend property. WPEPlatform has no backend to build: construct the WebKitWebView without one and WebKit selects a platform for it.

Before:

struct wpe_view_backend *wpe_backend = /* ...fdo exportable backend... */;
WebKitWebViewBackend *backend =
    webkit_web_view_backend_new (wpe_backend, NULL, NULL);
WebKitWebView *web_view =
    g_object_new (WEBKIT_TYPE_WEB_VIEW, "backend", backend, NULL);

After:

WebKitWebView *web_view = g_object_new (WEBKIT_TYPE_WEB_VIEW, NULL);

If your code calls webkit_web_view_new (backend), switch to g_object_new() as above. webkit_web_view_new() only exists in builds with the legacy libwpe API, and there is no variant taking a WPEDisplay. Once WPEPlatform is in use, a backend property passed to g_object_new() is ignored with a critical warning. For most applications the migration is simply dropping the backend. WebKit then resolves a platform by iterating the registered implementations — the built-in Wayland, DRM, and headless ones, plus any installed module — and connecting to the first that succeeds. Your existing settings, network-session, navigation, and signal-handler code carries over unchanged. For an application that needs no platform-specific control, this is the whole migration.

2. Pinning to a specific platform

When an application must run on a particular platform — a Wayland-only kiosk, say — construct a WPEDisplay for it and pass it to the web view through its display construct property (since 2.44), instead of letting WebKit choose.

g_autoptr(GError) error = NULL;
g_autoptr(WPEDisplayWayland) display =
    WPE_DISPLAY_WAYLAND (wpe_display_wayland_new ());
if (!wpe_display_wayland_connect (display, NULL, &error))
    g_error ("Failed to connect to Wayland: %s", error->message);

WebKitWebView *web_view =
    g_object_new (WEBKIT_TYPE_WEB_VIEW, "display", display, NULL);

This links the platform library — here wpe-platform-wayland-2.0 — and instantiates it directly, with no module discovery involved. To stay portable but still choose at runtime, use wpe_display_get_default(), which returns the first platform that connects, or set WPE_PLATFORM=<name> in the environment to force one. This is what replaces libwpe’s wpe_loader_init(), which selected a backend by shared-library name.

3. Adding keyboard shortcuts

Under libwpe the application fed input into WebKit itself by calling wpe_view_backend_dispatch_*_event(), which forwarded the event to the input client WebKit had registered, so browser keyboard shortcuts were typically implemented by filtering events before dispatching them. WPEPlatform delivers the same input as the WPEView::event signal on the WPEView WebKit created for the web view. Reach the view with webkit_web_view_get_wpe_view(), connect to the signal, inspect the WPEEvent, and return TRUE to consume the event before the page sees it.

Before (filtering before wpe_view_backend_dispatch_keyboard_event()):

bool handle_keyboard_event (struct wpe_input_keyboard_event *event)
{
    if (event->pressed
        && (event->modifiers & wpe_input_keyboard_modifier_control)
        && event->key_code == WPE_KEY_q) {
        quit ();
        return true;   // handled
    }
    return false;
}

After:

static gboolean
on_view_event (WPEView *view, WPEEvent *event, gpointer user_data)
{
    if (wpe_event_get_event_type (event) != WPE_EVENT_KEYBOARD_KEY_DOWN)
        return FALSE;

    WPEModifiers modifiers = wpe_event_get_modifiers (event);
    guint        keyval    = wpe_event_keyboard_get_keyval (event);

    if ((modifiers & WPE_MODIFIER_KEYBOARD_CONTROL) && keyval == WPE_KEY_q) {
        quit ();
        return TRUE;   // consumed, not forwarded to the page
    }
    return FALSE;
}

WPEView *view = webkit_web_view_get_wpe_view (web_view);
g_signal_connect (view, "event", G_CALLBACK (on_view_event), NULL);

Event details come from typed accessors — wpe_event_get_event_type(), wpe_event_get_modifiers(), wpe_event_keyboard_get_keyval(), and the pointer, scroll, and touch equivalents — rather than fields of a C struct. The WPE_KEY_* keysym constants keep their names.

4. Controlling the window

The view is presented in a WPEToplevel — the window. Reach it with wpe_view_get_toplevel() and drive the window from there: set the title, toggle fullscreen or maximize, request a resize. Observe changes through the WPEView::toplevel-state-changed signal and wpe_toplevel_get_state().

Before (a libwpe fullscreen handler):

wpe_view_backend_set_fullscreen_handler (backend, on_fullscreen, app);
wpe_view_backend_platform_set_fullscreen (backend, true);

After:

WPEToplevel *toplevel = wpe_view_get_toplevel (view);
wpe_toplevel_set_title (toplevel, "Hello WPE");

if (wpe_toplevel_get_state (toplevel) & WPE_TOPLEVEL_STATE_FULLSCREEN)
    wpe_toplevel_unfullscreen (toplevel);
else
    wpe_toplevel_fullscreen (toplevel);

wpe_toplevel_maximize(), wpe_toplevel_minimize(), and wpe_toplevel_resize() round out the window controls. Support depends on the platform: Wayland implements all of them, headless only tracks size and fullscreen state, and on DRM they have no effect.

5. What WebKit now handles for you

The platform code an fdo-based application carried has no WPEPlatform equivalent, because it is no longer the application’s responsibility:

  • Rendering. The exportable EGL/SHM export callbacks, buffer release, and frame-complete notifications are gone; WebKit renders into the view directly.
  • Input dispatch. The application no longer creates or dispatches events, only observes them (section 3).
  • View state. Visibility, focus, and scale factor are driven by WebKit and the platform, not set by the application.
  • Process and renderer setup. wpe_renderer_host_*, wpe_renderer_backend_egl_*, and wpe_process_provider_* are now internal to WebKit.

The Migration mapping table records where each of these symbols went. The machinery a platform implementation does still need is covered in Writing a WPE platform implementation.