bug 1199602 emit resume-events on GdkFrameClock if flush/resume not balanced at dispose r?acomminos
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=742636 in affected GDK versions.
MozReview-Commit-ID: JZ3kVlXFh0R
--- a/widget/gtk/nsAppShell.cpp
+++ b/widget/gtk/nsAppShell.cpp
@@ -58,16 +58,56 @@ wrap_gtk_window_check_resize(GtkContaine
}
sReal_gtk_window_check_resize(container);
if (gdk_window) {
g_object_unref(gdk_window);
}
}
+
+// Emit resume-events on GdkFrameClock if flush-events has not been
+// balanced by resume-events at dispose.
+// For https://bugzilla.gnome.org/show_bug.cgi?id=742636
+static decltype(GObjectClass::constructed) sRealGdkFrameClockConstructed;
+static decltype(GObjectClass::dispose) sRealGdkFrameClockDispose;
+static GQuark sPendingResumeQuark;
+
+static void
+OnFlushEvents(GObject* clock, gpointer)
+{
+ g_object_set_qdata(clock, sPendingResumeQuark, GUINT_TO_POINTER(1));
+}
+
+static void
+OnResumeEvents(GObject* clock, gpointer)
+{
+ g_object_set_qdata(clock, sPendingResumeQuark, nullptr);
+}
+
+static void
+WrapGdkFrameClockConstructed(GObject* object)
+{
+ sRealGdkFrameClockConstructed(object);
+
+ g_signal_connect(object, "flush-events",
+ G_CALLBACK(OnFlushEvents), nullptr);
+ g_signal_connect(object, "resume-events",
+ G_CALLBACK(OnResumeEvents), nullptr);
+}
+
+static void
+WrapGdkFrameClockDispose(GObject* object)
+{
+ if (g_object_get_qdata(object, sPendingResumeQuark)) {
+ g_signal_emit_by_name(object, "resume-events");
+ }
+
+ sRealGdkFrameClockDispose(object);
+}
#endif
/*static*/ gboolean
nsAppShell::EventProcessorCallback(GIOChannel *source,
GIOCondition condition,
gpointer data)
{
nsAppShell *self = static_cast<nsAppShell *>(data);
@@ -130,16 +170,34 @@ nsAppShell::Init()
// GtkWindow is a static class and so will leak anyway but this ref
// makes sure it isn't recreated.
gpointer gtk_plug_class = g_type_class_ref(GTK_TYPE_WINDOW);
auto check_resize = >K_CONTAINER_CLASS(gtk_plug_class)->check_resize;
sReal_gtk_window_check_resize = *check_resize;
*check_resize = wrap_gtk_window_check_resize;
}
+ if (!sPendingResumeQuark &&
+ gtk_check_version(3,14,7) != nullptr) { // GTK 3.0 to GTK 3.14.7.
+ // GTK 3.8 - 3.14 registered this type when creating the frame clock
+ // for the root window of the display when the display was opened.
+ GType gdkFrameClockIdleType = g_type_from_name("GdkFrameClockIdle");
+ if (gdkFrameClockIdleType) { // not in versions prior to 3.8
+ sPendingResumeQuark = g_quark_from_string("moz-resume-is-pending");
+ auto gdk_frame_clock_idle_class =
+ G_OBJECT_CLASS(g_type_class_peek_static(gdkFrameClockIdleType));
+ auto constructed = &gdk_frame_clock_idle_class->constructed;
+ sRealGdkFrameClockConstructed = *constructed;
+ *constructed = WrapGdkFrameClockConstructed;
+ auto dispose = &gdk_frame_clock_idle_class->dispose;
+ sRealGdkFrameClockDispose = *dispose;
+ *dispose = WrapGdkFrameClockDispose;
+ }
+ }
+
// Workaround for bug 1209659 which is fixed by Gtk3.20
if (gtk_check_version(3, 20, 0) != nullptr)
unsetenv("GTK_CSD");
#endif
if (PR_GetEnv("MOZ_DEBUG_PAINTS"))
gdk_window_set_debug_updates(TRUE);