fix(webview): use GTK's software renderer when the helper composites in software

GTK's GL renderer aborted in libepoxy while snapshotting a page switch, which closed the web view. GSK_RENDERER set by the user still wins.
This commit is contained in:
vii committed 2026-10-02 20:02:32 -05:00
1 parent 51836a980d
commit a469689bbb
5 files changed
+33

No files matched your search

+3
View File
@@ -37,6 +37,9 @@ GitHub are taken from the matching section here.
renderer.
- Clicking while a Roblox text box has focus no longer closes it. Only Roblox
decides when a click ends typing.
- Going to another page in the web view, such as Friends from a profile, no
longer closes the web view. It crashed on every page change on Wayland
systems whose GL setup GTK could not use.
## [0.3.2] - 2026-09-29
+5
View File
@@ -1424,6 +1424,11 @@ void Activate(GtkApplication* application, gpointer user_data) {
state->disable_hardware_acceleration =
mocktail::webview::ShouldDisableWebViewHardwareAcceleration(
wayland_display, std::getenv("WEBKIT_DISABLE_COMPOSITING_MODE"));
// GTK picks its renderer when a window is realized, which is after this.
if (mocktail::webview::ShouldForceSoftwareGtkRenderer(
state->disable_hardware_acceleration, std::getenv("GSK_RENDERER"))) {
setenv("GSK_RENDERER", "cairo", 0);
}
std::cerr << "[webview] display=" << (wayland_display ? "wayland" : "other")
<< " compositing="
<< (state->disable_hardware_acceleration ? "software" : "default")
+5
View File
@@ -133,6 +133,11 @@ bool ShouldDisableWebViewHardwareAcceleration(
return wayland_display;
}
bool ShouldForceSoftwareGtkRenderer(bool software_compositing,
const char* renderer_override) {
return software_compositing && renderer_override == nullptr;
}
const char* AndroidBridgeSource() { return kBridgeSource; }
std::string BuildRobloxAndroidUserAgent() {
+7
View File
@@ -38,6 +38,13 @@ bool ShouldDisableWebKitSandbox(std::string_view kernel_version,
// Match WebKit's WEBKIT_DISABLE_COMPOSITING_MODE override semantics.
bool ShouldDisableWebViewHardwareAcceleration(
bool wayland_display, const char* compositing_override);
// GTK's GL renderer aborts in libepoxy when it snapshots a page switch on
// hosts where its GL context cannot become current. With software compositing
// the helper does not need GL for its UI, so use the Cairo renderer unless the
// user chose one through GSK_RENDERER.
bool ShouldForceSoftwareGtkRenderer(bool software_compositing,
const char* renderer_override);
const char* AndroidBridgeSource();
std::string BuildRobloxAndroidUserAgent();
bool IsBrowserLoginUrl(std::string_view url);
+13
View File
@@ -134,6 +134,19 @@ TEST(WebViewHelperPolicyTest, HonorsExplicitCompositingEnvironment) {
}
}
TEST(WebViewHelperPolicyTest, ForcesCairoRendererWithSoftwareCompositing) {
EXPECT_TRUE(ShouldForceSoftwareGtkRenderer(true, nullptr));
EXPECT_FALSE(ShouldForceSoftwareGtkRenderer(false, nullptr));
}
TEST(WebViewHelperPolicyTest, HonorsExplicitGtkRendererEnvironment) {
for (bool software_compositing : {false, true}) {
for (const char* value : {"gl", "vulkan", "cairo", ""}) {
EXPECT_FALSE(ShouldForceSoftwareGtkRenderer(software_compositing, value));
}
}
}
TEST(WebViewHelperPolicyTest, AllowsOnlyTlsTopLevelNavigation) {
const UriPolicyResult roblox =
EvaluateNavigationUri("https://www.roblox.com/login");