Martin Stransky 93db231
diff --git a/dom/plugins/base/nsPluginNativeWindowGtk.cpp b/dom/plugins/base/nsPluginNativeWindowGtk.cpp
Martin Stransky 93db231
--- a/dom/plugins/base/nsPluginNativeWindowGtk.cpp
Martin Stransky 93db231
+++ b/dom/plugins/base/nsPluginNativeWindowGtk.cpp
Martin Stransky 93db231
@@ -19,16 +19,17 @@
Martin Stransky 93db231
 
Martin Stransky 93db231
 #if (GTK_MAJOR_VERSION == 3)
Martin Stransky 93db231
 #include <gtk/gtkx.h>
Martin Stransky 93db231
 #else
Martin Stransky 93db231
 #include "gtk2xtbin.h"
Martin Stransky 93db231
 #endif
Martin Stransky 93db231
 #include "mozilla/X11Util.h"
Martin Stransky 93db231
 
Martin Stransky 93db231
+static void plug_added_cb(GtkWidget *widget, gpointer data);
Martin Stransky 93db231
 static gboolean plug_removed_cb   (GtkWidget *widget, gpointer data);
Martin Stransky 93db231
 static void socket_unrealize_cb   (GtkWidget *widget, gpointer data);
Martin Stransky 93db231
 
Martin Stransky 93db231
 nsPluginNativeWindowGtk::nsPluginNativeWindowGtk() : nsPluginNativeWindow()
Martin Stransky 93db231
 {
Martin Stransky 93db231
   // initialize the struct fields
Martin Stransky 93db231
   window = nullptr; 
Martin Stransky 93db231
   x = 0; 
Martin Stransky 93db231
@@ -158,16 +159,19 @@ nsresult nsPluginNativeWindowGtk::Create
Martin Stransky 93db231
 
Martin Stransky 93db231
   //attach the socket to the container widget
Martin Stransky 93db231
   gtk_widget_set_parent_window(mSocketWidget, parent_win);
Martin Stransky 93db231
 
Martin Stransky 93db231
   // enable/disable focus event handlers,
Martin Stransky 93db231
   // see plugin_window_filter_func() for details
Martin Stransky 93db231
   g_object_set_data(G_OBJECT(mSocketWidget), "enable-xt-focus", (void *)aEnableXtFocus);
Martin Stransky 93db231
 
Martin Stransky 93db231
+  g_signal_connect(mSocketWidget, "plug_added",
Martin Stransky 93db231
+                   G_CALLBACK(plug_added_cb), nullptr);
Martin Stransky 93db231
+
Martin Stransky 93db231
   // Make sure to handle the plug_removed signal.  If we don't the
Martin Stransky 93db231
   // socket will automatically be destroyed when the plug is
Martin Stransky 93db231
   // removed, which means we're destroying it more than once.
Martin Stransky 93db231
   // SYNTAX ERROR.
Martin Stransky 93db231
   g_signal_connect(mSocketWidget, "plug_removed",
Martin Stransky 93db231
                    G_CALLBACK(plug_removed_cb), nullptr);
Martin Stransky 93db231
 
Martin Stransky 93db231
   g_signal_connect(mSocketWidget, "unrealize",
Martin Stransky 93db231
@@ -273,16 +277,42 @@ nsresult nsPluginNativeWindowGtk::Create
Martin Stransky 93db231
   // Leave mWsInfo.type = 0 - Who knows what this is meant to be?
Martin Stransky 93db231
 
Martin Stransky 93db231
   XFlush(mWsInfo.display);
Martin Stransky 93db231
 
Martin Stransky 93db231
   return NS_OK;
Martin Stransky 93db231
 }
Martin Stransky 93db231
 #endif
Martin Stransky 93db231
 
Martin Stransky 93db231
+static void
Martin Stransky 93db231
+plug_window_finalize_cb(gpointer socket, GObject* plug_window)
Martin Stransky 93db231
+{
Martin Stransky 93db231
+  g_object_unref(socket);
Martin Stransky 93db231
+}
Martin Stransky 93db231
+
Martin Stransky 93db231
+static void
Martin Stransky 93db231
+plug_added_cb(GtkWidget *socket, gpointer data)
Martin Stransky 93db231
+{
Martin Stransky 93db231
+  // The plug window has been embedded, and gtk_socket_add_window() has added
Martin Stransky 93db231
+  // a filter to the socket's plug_window, passing the socket as data for the
Martin Stransky 93db231
+  // filter, so the socket must live as long as events may be received on the
Martin Stransky 93db231
+  // plug window.
Martin Stransky 93db231
+  //
Martin Stransky 93db231
+  // https://git.gnome.org/browse/gtk+/tree/gtk/gtksocket.c?h=3.18.7#n1124
Martin Stransky 93db231
+  g_object_ref(socket);
Martin Stransky 93db231
+  // When the socket is unrealized, perhaps during gtk_widget_destroy() from
Martin Stransky 93db231
+  // ~nsPluginNativeWindowGtk, the plug is removed.  The plug in the child
Martin Stransky 93db231
+  // process then destroys its widget and window.  When the browser process
Martin Stransky 93db231
+  // receives the DestroyNotify event for the plug window, GDK releases its
Martin Stransky 93db231
+  // reference to plugWindow.  This is typically the last reference and so the
Martin Stransky 93db231
+  // weak ref callback triggers release of the socket.
Martin Stransky 93db231
+  GdkWindow* plugWindow = gtk_socket_get_plug_window(GTK_SOCKET(socket));
Martin Stransky 93db231
+  g_object_weak_ref(G_OBJECT(plugWindow), plug_window_finalize_cb, socket);
Martin Stransky 93db231
+}
Martin Stransky 93db231
+
Martin Stransky 93db231
 /* static */
Martin Stransky 93db231
 gboolean
Martin Stransky 93db231
 plug_removed_cb (GtkWidget *widget, gpointer data)
Martin Stransky 93db231
 {
Martin Stransky 93db231
   // Gee, thanks for the info!
Martin Stransky 93db231
   return TRUE;
Martin Stransky 93db231
 }
Martin Stransky 93db231
 
Martin Stransky 93db231
diff --git a/widget/gtk/mozgtk/mozgtk.c b/widget/gtk/mozgtk/mozgtk.c
Martin Stransky 93db231
--- a/widget/gtk/mozgtk/mozgtk.c
Martin Stransky 93db231
+++ b/widget/gtk/mozgtk/mozgtk.c
Martin Stransky 93db231
@@ -384,16 +384,17 @@ STUB(gtk_selection_data_targets_include_
Martin Stransky 93db231
 STUB(gtk_separator_get_type)
Martin Stransky 93db231
 STUB(gtk_separator_menu_item_new)
Martin Stransky 93db231
 STUB(gtk_separator_tool_item_new)
Martin Stransky 93db231
 STUB(gtk_settings_get_default)
Martin Stransky 93db231
 STUB(gtk_settings_get_for_screen)
Martin Stransky 93db231
 STUB(gtk_socket_add_id)
Martin Stransky 93db231
 STUB(gtk_socket_get_id)
Martin Stransky 93db231
 STUB(gtk_socket_get_type)
Martin Stransky 93db231
+STUB(gtk_socket_get_plug_window)
Martin Stransky 93db231
 STUB(gtk_socket_new)
Martin Stransky 93db231
 STUB(gtk_spin_button_new)
Martin Stransky 93db231
 STUB(gtk_statusbar_new)
Martin Stransky 93db231
 STUB(gtk_style_lookup_icon_set)
Martin Stransky 93db231
 STUB(gtk_table_attach)
Martin Stransky 93db231
 STUB(gtk_table_get_type)
Martin Stransky 93db231
 STUB(gtk_table_new)
Martin Stransky 93db231
 STUB(gtk_target_list_add)
Martin Stransky 93db231