From 8d895e4bdf05b8234ec4199b4f2b83cc1cbe3aaa Mon Sep 17 00:00:00 2001 From: Grant Gayed Date: Tue, 15 May 2012 14:35:00 -0400 Subject: Bug 379446 - FileDialog hangs when choosing download destination with WebKitGTK 1.8.x --- .../gtk/org/eclipse/swt/browser/WebKit.java | 46 +++++++++++++++------- .../org/eclipse/swt/internal/webkit/WebKitGTK.java | 33 ++++++++++++++++ 2 files changed, 64 insertions(+), 15 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java index 5312eadd49..32dc27140d 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java +++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java @@ -1603,21 +1603,37 @@ int /*long*/ webkit_download_requested (int /*long*/ web_view, int /*long*/ down int length = OS.strlen (name); byte[] bytes = new byte[length]; OS.memmove (bytes, name, length); - String nameString = new String (Converter.mbcsToWcs (null, bytes)); - FileDialog dialog = new FileDialog (browser.getShell (), SWT.OPEN); - dialog.setFileName (nameString); - String title = Compatibility.getMessage ("SWT_FileDownload"); //$NON-NLS-1$ - dialog.setText (title); - String path = dialog.open (); - - if (path != null) { - path = URI_FILEROOT + path; - byte[] uriBytes = Converter.wcsToMbcs (null, path, true); - WebKitGTK.webkit_download_set_destination_uri (download, uriBytes); - openDownloadWindow (download); - } else { - WebKitGTK.webkit_download_cancel (download); - } + final String nameString = new String (Converter.mbcsToWcs (null, bytes)); + + final int /*long*/ request = WebKitGTK.webkit_download_get_network_request (download); + OS.g_object_ref (request); + + /* + * As of WebKitGTK 1.8.x attempting to show a FileDialog in this callback causes + * a hang. The workaround is to open it asynchronously with a new download. + */ + browser.getDisplay ().asyncExec (new Runnable () { + public void run () { + if (!browser.isDisposed ()) { + FileDialog dialog = new FileDialog (browser.getShell (), SWT.OPEN); + dialog.setFileName (nameString); + String title = Compatibility.getMessage ("SWT_FileDownload"); //$NON-NLS-1$ + dialog.setText (title); + String path = dialog.open (); + if (path != null) { + path = URI_FILEROOT + path; + int /*long*/ newDownload = WebKitGTK.webkit_download_new (request); + byte[] uriBytes = Converter.wcsToMbcs (null, path, true); + WebKitGTK.webkit_download_set_destination_uri (newDownload, uriBytes); + openDownloadWindow (newDownload); + WebKitGTK.webkit_download_start (newDownload); + OS.g_object_unref (newDownload); + } + } + OS.g_object_unref (request); + } + }); + return 1; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java index 52ba6975f6..c648f6d859 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java +++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java @@ -742,6 +742,17 @@ public static final long webkit_download_get_current_size (int /*long*/ download } } +/** @method flags=dynamic */ +public static final native int /*long*/ _webkit_download_get_network_request (int /*long*/ download); +public static final int /*long*/ webkit_download_get_network_request (int /*long*/ download) { + lock.lock(); + try { + return _webkit_download_get_network_request (download); + } finally { + lock.unlock(); + } +} + /** @method flags=dynamic */ public static final native int _webkit_download_get_status (int /*long*/ download); public static final int webkit_download_get_status (int /*long*/ download) { @@ -786,6 +797,17 @@ public static final int /*long*/ webkit_download_get_uri (int /*long*/ download) } } +/** @method flags=dynamic */ +public static final native int /*long*/ _webkit_download_new (int /*long*/ request); +public static final int /*long*/ webkit_download_new (int /*long*/ request) { + lock.lock(); + try { + return _webkit_download_new (request); + } finally { + lock.unlock(); + } +} + /** @method flags=dynamic */ public static final native void _webkit_download_set_destination_uri (int /*long*/ download, byte[] destination_uri); public static final void webkit_download_set_destination_uri (int /*long*/ download, byte[] destination_uri) { @@ -797,6 +819,17 @@ public static final void webkit_download_set_destination_uri (int /*long*/ downl } } +/** @method flags=dynamic */ +public static final native void _webkit_download_start (int /*long*/ download); +public static final void webkit_download_start (int /*long*/ download) { + lock.lock(); + try { + _webkit_download_start (download); + } finally { + lock.unlock(); + } +} + /** @method flags=dynamic */ public static final native int /*long*/ _webkit_get_default_session (); public static final int /*long*/ webkit_get_default_session () { -- cgit