1//go:build linux23package main45/*6#cgo linux pkg-config: gtk+-3.07#cgo !webkit2_41 pkg-config: webkit2gtk-4.08#cgo webkit2_41 pkg-config: webkit2gtk-4.19#include <string.h>10#include <gtk/gtk.h>11#include <webkit2/webkit2.h>1213static WebKitWebView *airwavesView;14static double airwavesZoom = 1;15static gboolean airwavesKeepDamage;1617// WebKitGTK 2.54 tracks what changed in each frame and draws only that onto18// a buffer it reuses. Under gamescope (Xwayland) parts of older frames show19// through: the guide's previous selection under the new one, a highlight20// left half drawn. Without damage tracking every frame is drawn whole,21// which the GPU does easily.22//23// The feature has to be off before the page is created, which is at the24// first load, so it is turned off when Wails puts the web view in its25// window, just before that load. The interface size is set there too.26static gboolean airwavesWebViewParented(GSignalInvocationHint *hint, guint n, const GValue *params, gpointer data) {27 GObject *widget = g_value_get_object(¶ms[0]);28 if (!WEBKIT_IS_WEB_VIEW(widget))29 return TRUE;30 airwavesView = WEBKIT_WEB_VIEW(widget);31 webkit_web_view_set_zoom_level(airwavesView, airwavesZoom);32 if (airwavesKeepDamage)33 return FALSE;34#if WEBKIT_CHECK_VERSION(2, 42, 0)35 WebKitSettings *settings = webkit_web_view_get_settings(airwavesView);36 WebKitFeatureList *features = webkit_settings_get_all_features();37 for (gsize i = 0; i < webkit_feature_list_get_length(features); i++) {38 WebKitFeature *feature = webkit_feature_list_get(features, i);39 if (!strcmp(webkit_feature_get_identifier(feature), "PropagateDamagingInformation")) {40 webkit_settings_set_feature_enabled(settings, feature, FALSE);41 g_message("airwaves: WebKit damage tracking off");42 }43 }44 webkit_feature_list_unref(features);45#endif46 return FALSE;47}4849// Runs before gtk_init, which Wails calls later: loading GtkWidget's class50// (which needs no display) makes its signals known.51static void airwavesWatchWebView(gboolean keepDamage) {52 airwavesKeepDamage = keepDamage;53 g_type_class_ref(GTK_TYPE_WIDGET);54 g_signal_add_emission_hook(g_signal_lookup("parent-set", GTK_TYPE_WIDGET), 0, airwavesWebViewParented, NULL, NULL);55}5657static gboolean airwavesApplyZoom(gpointer data) {58 if (airwavesView)59 webkit_web_view_set_zoom_level(airwavesView, airwavesZoom);60 return G_SOURCE_REMOVE;61}6263// The web view is GTK's, so it is zoomed on GTK's main loop.64static void airwavesSetZoom(double zoom) {65 airwavesZoom = zoom;66 g_idle_add(airwavesApplyZoom, NULL);67}68*/69import "C"7071import "os"7273// nativeZoom: the interface size is WebKitGTK's page zoom, which keeps74// viewport units, fixed elements and video right; CSS zoom on the root75// misplaces them there.76const nativeZoom = true7778// AIRWAVES_WEBKIT_DAMAGE=1 keeps WebKit's damage tracking, for comparison.79func init() {80 keep := C.gboolean(0)81 if os.Getenv("AIRWAVES_WEBKIT_DAMAGE") != "" {82 keep = 183 }84 C.airwavesWatchWebView(keep)85}8687// setPageZoom sizes the page: 1.25 is 125%.88func setPageZoom(zoom float64) { C.airwavesSetZoom(C.double(zoom)) }