Bug 726483 - keep an extra reference to the window. r=roc, a=lizzard
authorKarl Tomlinson <karlt+@karlt.net>
Tue, 10 Nov 2015 16:37:02 +1300
changeset 296746 bc7eea62ab83
parent 296745 c134a04010a0
child 296747 d35d09b0b24f
push id5316
push userkwierso@gmail.com
push date2015-11-16 20:42 +0000
treeherdermozilla-beta@c66289e84c50 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, lizzard
bugs726483
milestone43.0
Bug 726483 - keep an extra reference to the window. r=roc, a=lizzard
widget/gtk/nsAppShell.cpp
--- a/widget/gtk/nsAppShell.cpp
+++ b/widget/gtk/nsAppShell.cpp
@@ -40,16 +40,36 @@ PollWrapper(GPollFD *ufds, guint nfsd, g
     mozilla::HangMonitor::Suspend();
     profiler_sleep_start();
     gint result = (*sPollFunc)(ufds, nfsd, timeout_);
     profiler_sleep_end();
     mozilla::HangMonitor::NotifyActivity();
     return result;
 }
 
+#if MOZ_WIDGET_GTK == 3
+// For bug 726483.
+static decltype(GtkContainerClass::check_resize) sReal_gtk_window_check_resize;
+
+void
+wrap_gtk_window_check_resize(GtkContainer *container)
+{
+    GdkWindow* gdk_window = gtk_widget_get_window(&container->widget);
+    if (gdk_window) {
+        g_object_ref(gdk_window);
+    }
+
+    sReal_gtk_window_check_resize(container);
+
+    if (gdk_window) {
+        g_object_unref(gdk_window);
+    }
+}
+#endif
+
 /*static*/ gboolean
 nsAppShell::EventProcessorCallback(GIOChannel *source, 
                                    GIOCondition condition,
                                    gpointer data)
 {
     nsAppShell *self = static_cast<nsAppShell *>(data);
 
     unsigned char c;
@@ -99,16 +119,28 @@ nsAppShell::Init()
     }
 #endif
 
     if (!sPollFunc) {
         sPollFunc = g_main_context_get_poll_func(nullptr);
         g_main_context_set_poll_func(nullptr, &PollWrapper);
     }
 
+#if MOZ_WIDGET_GTK == 3
+    if (!sReal_gtk_window_check_resize &&
+        gtk_check_version(3,8,0) != nullptr) { // GTK 3.0 to GTK 3.6.
+        // 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 = &GTK_CONTAINER_CLASS(gtk_plug_class)->check_resize;
+        sReal_gtk_window_check_resize = *check_resize;
+        *check_resize = wrap_gtk_window_check_resize;
+    }
+#endif
+
     if (PR_GetEnv("MOZ_DEBUG_PAINTS"))
         gdk_window_set_debug_updates(TRUE);
 
     // Whitelist of only common, stable formats - see bugs 1197059 and 1203078
     GSList* pixbufFormats = gdk_pixbuf_get_formats();
     for (GSList* iter = pixbufFormats; iter; iter = iter->next) {
         GdkPixbufFormat* format = static_cast<GdkPixbufFormat*>(iter->data);
         gchar* name = gdk_pixbuf_format_get_name(format);