2008-12-06 09:08 Gwenole Beauchesne * src/npw-viewer.c: Rework the XEMBED hack. Don't let the browser cause Gtk to kill our window. i.e. don't process WM_DELETE_EVENT sent by the browser GtkSocket. That way, we will kill the window ourselves in NPP_Destroy(). Index: src/npw-viewer.c =================================================================== --- src/npw-viewer.c (révision 786) +++ src/npw-viewer.c (copie de travail) @@ -52,7 +52,7 @@ // [UNIMPLEMENTED] Define to use XPCOM emulation #define USE_XPCOM 0 -// Define to use XEMBED hack (GTK_WINDOW_POPUP toplevel instead of GtkPlug) +// Define to use XEMBED hack (don't let browser kill our window) #define USE_XEMBED_HACK 1 // Define to allow windowless plugins @@ -78,7 +78,6 @@ typedef struct _PluginInstance { NPW_DECL_PLUGIN_INSTANCE; bool use_xembed; - bool use_xembed_hack; bool is_windowless; NPWindow window; uint32_t width, height; @@ -106,7 +105,6 @@ // Gtk wrapper data typedef struct _GtkData { - GdkWindow *browser_window; GtkWidget *container; GtkWidget *socket; } GtkData; @@ -567,20 +565,11 @@ GtkData *toolkit = calloc(1, sizeof(*toolkit)); if (toolkit == NULL) return -1; - if (plugin->use_xembed_hack) - toolkit->container = gtk_window_new(GTK_WINDOW_POPUP); - else - toolkit->container = gtk_plug_new((GdkNativeWindow)window->window); + toolkit->container = gtk_plug_new((GdkNativeWindow)window->window); if (toolkit->container == NULL) return -1; gtk_widget_set_size_request(toolkit->container, window->width, window->height); gtk_widget_show(toolkit->container); - if (plugin->use_xembed_hack) { - toolkit->browser_window = gdk_window_foreign_new((GdkNativeWindow)window->window); - if (toolkit->browser_window == NULL) - return -1; - gdk_window_reparent(toolkit->container->window, toolkit->browser_window, 0, 0); - } toolkit->socket = gtk_socket_new(); if (toolkit->socket == NULL) return -1; @@ -589,6 +578,14 @@ gtk_widget_show_all(toolkit->container); window->window = (void *)gtk_socket_get_id(GTK_SOCKET(toolkit->socket)); plugin->toolkit_data = toolkit; +#if USE_XEMBED_HACK + // don't let the browser kill our window out of NPP_Destroy() scope + g_signal_connect(toolkit->container, "delete-event", + G_CALLBACK(gtk_true), NULL); +#endif + // make sure we don't try to destroy the widget again in destroy_window() + g_signal_connect(toolkit->container, "destroy", + G_CALLBACK(gtk_widget_destroyed), &toolkit->container); // keep the socket as the plugin tries to destroy the widget itself g_signal_connect(toolkit->socket, "plug_removed", G_CALLBACK(gtk_true), NULL); @@ -669,9 +666,6 @@ if (plugin->toolkit_data) { if (plugin->use_xembed) { // window size changes are already caught per the XEMBED protocol - GtkData *toolkit = (GtkData *)plugin->toolkit_data; - if (plugin->use_xembed_hack) - gtk_widget_set_size_request(toolkit->container, plugin->window.width, plugin->window.height); } else { XtData *toolkit = (XtData *)plugin->toolkit_data; @@ -2942,17 +2936,6 @@ plugin->use_xembed = supports_XEmbed && needs_XEmbed; } } - -#if USE_XEMBED_HACK - // check if XEMBED hack is to be used - if (plugin->use_xembed && plugin_funcs.getvalue) { - NPNToolkitType toolkit = 0; - NPError error = g_NPN_GetValue_real(NULL, NPNVToolkit, (void *)&toolkit); - if (error == NPERR_NO_ERROR && toolkit == NPNVGtk2) - plugin->use_xembed_hack = true; - } -#endif - return ret; } @@ -3135,22 +3118,6 @@ // NPP_GetValue static NPError -g_NPP_GetValue_fixes(NPP instance, NPPVariable variable, void *value) -{ - PluginInstance *plugin = PLUGIN_INSTANCE(instance); - switch (variable) { - case NPPVpluginNeedsXEmbed: - // claim we don't support XEMBED though we actually do - if (plugin->use_xembed_hack) - *((PRBool *)value) = PR_FALSE; - break; - default: - break; - } - return NPERR_NO_ERROR; -} - -static NPError g_NPP_GetValue(NPP instance, NPPVariable variable, void *value) { if (instance == NULL) @@ -3161,8 +3128,6 @@ D(bugiI("NPP_GetValue instance=%p, variable=%d [%s]\n", instance, variable, string_of_NPPVariable(variable))); NPError ret = plugin_funcs.getvalue(instance, variable, value); - if (ret == NPERR_NO_ERROR) - ret = g_NPP_GetValue_fixes(instance, variable, value); D(bugiD("NPP_GetValue return: %d [%s]\n", ret, string_of_NPError(ret))); return ret; }