Bug 1134077 - X11: Set EWMH property to keep top-level nsWindows composited. r?karlt
Some compositors such as GNOME mutter use heuristics to unredirect fullscreen
windows in an effort to reduce output latency. This works fine for applications
that take the proper steps to ensure all framebuffer updates happen in the
vblank interval. Since this is not currently the case for Firefox, bypassing
the compositor will lead to frame tearing.
Set _NET_WM_BYPASS_COMPOSITOR to 2 to opt out of fullscreen unredirection.
MozReview-Commit-ID: 1xW2VAnbiJw
--- a/widget/gtk/mozgtk/mozgtk.c
+++ b/widget/gtk/mozgtk/mozgtk.c
@@ -47,16 +47,17 @@ STUB(gdk_keymap_get_entries_for_keyval)
STUB(gdk_keymap_get_for_display)
STUB(gdk_keymap_have_bidi_layouts)
STUB(gdk_keymap_translate_keyboard_state)
STUB(gdk_keyval_name)
STUB(gdk_keyval_to_unicode)
STUB(gdk_pango_context_get)
STUB(gdk_pointer_grab)
STUB(gdk_pointer_ungrab)
+STUB(gdk_property_change)
STUB(gdk_property_get)
STUB(gdk_screen_get_default)
STUB(gdk_screen_get_display)
STUB(gdk_screen_get_font_options)
STUB(gdk_screen_get_height)
STUB(gdk_screen_get_height_mm)
STUB(gdk_screen_get_n_monitors)
STUB(gdk_screen_get_monitor_at_window)
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -3798,16 +3798,35 @@ nsWindow::Create(nsIWidget* aParent,
if (aInitData->mMouseTransparent) {
cairo_rectangle_int_t rect = { 0, 0, 0, 0 };
cairo_region_t *region = cairo_region_create_rectangle(&rect);
gdk_window_input_shape_combine_region(mGdkWindow, region, 0, 0);
cairo_region_destroy(region);
}
}
+
+#ifdef MOZ_X11
+ // Set window manager hint to keep fullscreen windows composited.
+ //
+ // If the window were to get unredirected, there could be visible
+ // tearing because Gecko does not align its framebuffer updates with
+ // vblank.
+ if (mIsX11Display) {
+ gulong value = 2; // Opt out of unredirection
+ GdkAtom cardinal_atom = gdk_x11_xatom_to_atom(XA_CARDINAL);
+ gdk_property_change(gtk_widget_get_window(mShell),
+ gdk_atom_intern("_NET_WM_BYPASS_COMPOSITOR", FALSE),
+ cardinal_atom,
+ 32, // format
+ GDK_PROP_MODE_REPLACE,
+ (guchar*)&value,
+ 1);
+ }
+#endif
}
break;
case eWindowType_plugin:
case eWindowType_plugin_ipc_chrome:
case eWindowType_plugin_ipc_content:
MOZ_ASSERT_UNREACHABLE("Unexpected eWindowType_plugin*");
return NS_ERROR_FAILURE;