Skip to content

Here’s the revised documentation page for WebKitGTK:

WebKitGTK

WebKitGTK is an open-source web content engine that allows developers to embed web browsing capabilities within GTK-based applications. It supports modern web technologies like HTML5, CSS, and JavaScript, making it a popular choice for creating GTK-based web browsers and tools. This project provides Kotlin/Native bindings for integrating WebKitGTK in Kotlin applications.

Enabling WebKitGTK

WebKitGTK bindings are not enabled by default and need to be manually added. To enable WebKitGTK bindings, move the WebKitGTK entry from ignoredLibraries to libraries in the gtkkn.json file.

Requirements

To generate bindings and run applications using WebKitGTK, install the necessary development package on your system:

sudo apt install libwebkitgtk-6.0-dev

Example Usage

The following example demonstrates how to create a simple web browser using WebKitGTK. This example is adapted from a similar one provided by the Java GI project, which offers JVM bindings. We extend our thanks to the Java GI project for the inspiration and sample code.

samples/webkit/browser/src/nativeMain/kotlin/org/gtkkn/samples/webkit/browser/Main.kt
@Suppress("LongMethod")
fun main() = Application {
    var loading = false
    // set up a HeaderBar since adw windows don't have any by default
    val headerBar = org.gtkkn.bindings.adw.HeaderBar()

    // setup window layout
    val layout = Box(Orientation.VERTICAL, 0)

    // this is where any playground code can run to set up widgets
    val webView = WebView()

    val back = Button.newFromIconName("go-previous-symbolic").apply {
        setTooltipText("Back")
        connectClicked {
            logger.debug { "Back clicked" }
            webView.goBack()
        }
    }

    val forward = Button.newFromIconName("go-next-symbolic").apply {
        setTooltipText("Forward")
        connectClicked {
            logger.debug { "Forward clicked" }
            webView.goForward()
        }
    }

    val stopOrReload = Button.newFromIconName("process-stop-symbolic").apply {
        setTooltipText("Stop")
        connectClicked {
            logger.debug { "Stop clicked" }
            if (loading) webView.stopLoading() else webView.reload()
        }
    }

    val home = Button.newFromIconName("go-home-symbolic").apply {
        setTooltipText("Home")
        connectClicked {
            logger.debug { "Home clicked" }
            webView.loadUri(HOME_PAGE)
        }
    }

    val urlBar = Entry().apply {
        setInputPurpose(InputPurpose.URL)
        hexpand = true
    }

    // Container for the webview
    val webViewContainer = Bin().apply {
        vexpand = true
        hexpand = true
        setChild(webView)
    }

    // When navigating to another page, update the URL bar
    webView.bindProperty("uri", urlBar.getBuffer(), "text", BindingFlags.DEFAULT)

    webView.connectLoadChanged { loadEvent: LoadEvent ->
        when (loadEvent) {
            STARTED -> {
                logger.debug { "loadEvent = Started" }
                loading = true
                stopOrReload.setIconName("process-stop-symbolic")
                stopOrReload.setTooltipText("Stop")
            }

            REDIRECTED -> logger.debug { "loadEvent = Redirected" }
            COMMITTED -> logger.debug { "loadEvent = Committed" }
            FINISHED -> {
                logger.debug { "loadEvent = Finished" }
                loading = false
                stopOrReload.setIconName("view-refresh-symbolic")
                stopOrReload.setTooltipText("Reload")
            }
        }
    }

    urlBar.connectActivate {
        var url = urlBar.getBuffer().getText()
        val scheme = Uri.peekScheme(url)
        if (scheme == null) {
            url = "https://$url"
        }
        logger.debug { "load url $url" }
        webView.loadUri(url)
    }

    webView.connectNotify { pspecs ->
        logger.debug { "pspecs = ${pspecs.getName()}" }
        if (pspecs.getName() == "estimated-load-progress") {
            urlBar.setProgressFraction(webView.getEstimatedLoadProgress())
            if (urlBar.getProgressFraction() == 1.0) {
                logger.debug { "Glib.timeoutAdd" }
                Glib.timeoutAdd(0, 500.toUInt()) {
                    logger.debug { "setProgressFraction(0.0)" }
                    urlBar.setProgressFraction(0.0)
                    false
                }
            }
        }
    }

    webView.loadUri(HOME_PAGE)

    headerBar.apply {
        packStart(back)
        packStart(forward)
        packStart(stopOrReload)
        packStart(home)
        setTitleWidget(urlBar)
    }

    // and add your widget to the layout to display it
    layout.apply {
        append(headerBar)
        append(webViewContainer)
    }
    setContent(layout)
}

private const val HOME_PAGE = "https://www.gnome.org/"

This sample code creates a basic web browser using WebKitGTK, featuring a WebView widget integrated into a GTK application window and basic URL navigation controls. It demonstrates how to use the Kotlin/Native WebKitGTK bindings to create applications that display and interact with web content.