Skip to content

Instantly share code, notes, and snippets.

@aperezdc
Created June 16, 2025 12:45
Show Gist options
  • Save aperezdc/cc41e8ae10c3028a7c3653eaf76c08d5 to your computer and use it in GitHub Desktop.
Save aperezdc/cc41e8ae10c3028a7c3653eaf76c08d5 to your computer and use it in GitHub Desktop.
Example: changing header bar colors depending on WebKitWebView:theme-color
/*
* Compile with:
* gcc $(pkg-config webkitgtk-6.0 --cflags --libs) webkitgtk-themecolor-example.c
*
* SPDX-License-Identifier: MIT
*/
#include <gio/gio.h>
#include <webkit/webkit.h>
static void
handle_web_view_theme_color_notify(WebKitWebView *web_view, GParamSpec *pspec, GtkWindow *window)
{
GdkRGBA rgba;
g_autofree char *css_class = g_strdup_printf("tinted_%" PRIu64, (uint64_t) window);
if (webkit_web_view_get_theme_color(web_view, &rgba)) {
const unsigned r = MAX(0, MIN(255, (unsigned) nearbyint(rgba.red * 255)));
const unsigned g = MAX(0, MIN(255, (unsigned) nearbyint(rgba.green * 255)));
const unsigned b = MAX(0, MIN(255, (unsigned) nearbyint(rgba.red * 255)));
const gboolean w = ((r * 299 + g * 587 + b * 114) / 1000) <= 128;
gtk_widget_add_css_class(GTK_WIDGET(window), css_class);
g_autofree char *css_snippet = g_strdup_printf(
"window.%s > headerbar { color: %s; background: rgb(%u, %u, %u); }",
css_class, w ? "white" : "black", r, g, b);
gtk_css_provider_load_from_string(
g_object_get_data(G_OBJECT(window), "tint-css-provider"),
css_snippet);
} else {
gtk_widget_remove_css_class(GTK_WIDGET(window), css_class);
}
}
static GtkWidget* handle_web_view_create(WebKitWebView*, WebKitNavigationAction*, GtkApplication*);
static GtkWidget*
add_window(GtkApplication *app, WebKitWebView *related_view, const char *uri)
{
WebKitWebView *web_view = g_object_new(WEBKIT_TYPE_WEB_VIEW,
"related-view", related_view,
NULL);
GtkWidget *header = gtk_header_bar_new();
gtk_header_bar_set_show_title_buttons(GTK_HEADER_BAR(header), TRUE);
GtkWidget *window = gtk_application_window_new(app);
gtk_window_set_titlebar(GTK_WINDOW(window), header);
gtk_window_set_child(GTK_WINDOW(window), GTK_WIDGET(web_view));
gtk_window_set_default_size(GTK_WINDOW(window), 1200, 900);
gtk_window_set_default_widget(GTK_WINDOW(window), GTK_WIDGET(web_view));
GtkCssProvider *tint_css_provider = gtk_css_provider_new();
gtk_style_context_add_provider_for_display(gdk_display_get_default(),
GTK_STYLE_PROVIDER(tint_css_provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
g_object_set_data_full(G_OBJECT(window), "tint-css-provider", tint_css_provider, g_object_unref);
g_object_bind_property(web_view, "title", window, "title", G_BINDING_SYNC_CREATE);
g_signal_connect(web_view, "notify::theme-color", G_CALLBACK(handle_web_view_theme_color_notify), window);
g_signal_connect(web_view, "create", G_CALLBACK(handle_web_view_create), app);
if (uri) webkit_web_view_load_uri(web_view, uri);
gtk_window_present(GTK_WINDOW(window));
return GTK_WIDGET(web_view);
}
static void
handle_app_activate(GtkApplication *app)
{
add_window(app, NULL, "https://duckduckgo.com");
}
static void
handle_app_open(GtkApplication *app, GFile *files[], int n_files, char *hint)
{
for (int i = 0; i < n_files; i++) {
g_autofree char *uri = g_file_get_uri(files[i]);
add_window(app, NULL, uri);
}
}
static GtkWidget*
handle_web_view_create(WebKitWebView *web_view, WebKitNavigationAction *action, GtkApplication *app)
{
return add_window(app, web_view, NULL);
}
int
main(int argc, char *argv[])
{
gtk_init();
g_autoptr(GtkApplication) app = gtk_application_new(NULL, G_APPLICATION_HANDLES_OPEN);
g_signal_connect(app, "activate", G_CALLBACK(handle_app_activate), NULL);
g_signal_connect(app, "open", G_CALLBACK(handle_app_open), NULL);
return g_application_run(G_APPLICATION(app), argc, argv);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment