2010-12-28 Martin Robinson <mrobinson@igalia.com>
+ Reviewed by Xan Lopez.
+
+ [GTK] Closing a window during an onload event can trigger serious GLib warnings
+ https://bugs.webkit.org/show_bug.cgi?id=51686
+
+ Don't emit the close-web-view signal immediately during execution of closeWindowSoon.
+ The signal handler may choose to destroy the web view while handling that signal,
+ which may remove the last reference to the web view. FrameLoaderClient depends on the
+ view still existing though. Instead, let the caller finish executing and emit the signal
+ after a 0 length timeout. This matches the behavior on the Windows and Mac ports.
+
+ * WebCoreSupport/ChromeClientGtk.cpp:
+ (WebKit::ChromeClient::ChromeClient): Initialize the timer id.
+ (WebKit::emitCloseWebViewSignalLater): Callback for the timer.
+ (WebKit::ChromeClient::closeWindowSoon): Do the actual signal invocation after
+ the caller finishes its tasks.
+ * WebCoreSupport/ChromeClientGtk.h: Add a new member for the timer id. We
+ can use this to prevent emitting the close-web-view signal twice.
+
+2010-12-28 Martin Robinson <mrobinson@igalia.com>
+
Reviewed by Eric Seidel.
[GTK] Clean up usage of NULL in webkitwebframe.cpp
ChromeClient::ChromeClient(WebKitWebView* webView)
: m_webView(webView)
+ , m_closeSoonTimer(0)
{
ASSERT(m_webView);
}
// Ignored for now
}
+static gboolean emitCloseWebViewSignalLater(WebKitWebView* view)
+{
+ gboolean isHandled;
+ g_signal_emit_by_name(view, "close-web-view", &isHandled);
+ return FALSE;
+}
+
void ChromeClient::closeWindowSoon()
{
// We may not have a WebView as create-web-view can return NULL.
if (!m_webView)
return;
+ if (m_closeSoonTimer) // Don't call close-web-view more than once.
+ return;
- webkit_web_view_stop_loading(m_webView);
+ // We need to remove the parent WebView from WebViewSets here, before it actually
+ // closes, to make sure that JavaScript code that executes before it closes
+ // can't find it. Otherwise, window.open will select a closed WebView instead of
+ // opening a new one <rdar://problem/3572585>.
+ m_webView->priv->corePage->setGroupName("");
- gboolean isHandled = false;
- g_signal_emit_by_name(m_webView, "close-web-view", &isHandled);
+ // We also need to stop the load to prevent further parsing or JavaScript execution
+ // after the window has torn down <rdar://problem/4161660>.
+ webkit_web_view_stop_loading(m_webView);
- if (isHandled)
- return;
+ // Clients commonly destroy the web view during the close-web-view signal, but our caller
+ // may need to send more signals to the web view. For instance, if this happened in the
+ // onload handler, it will need to call FrameLoaderClient::dispatchDidHandleOnloadEvents.
+ // Instead of firing the close-web-view signal now, fire it after the caller finishes.
+ // This seems to match the Mac/Windows port behavior.
+ m_closeSoonTimer = g_timeout_add(0, reinterpret_cast<GSourceFunc>(emitCloseWebViewSignalLater), m_webView);
}
bool ChromeClient::canTakeFocus(FocusDirection)