Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Grunberg2017-10-12 20:31:17 +0000
committerLeo Ufimtsev2017-11-06 15:27:33 +0000
commitefc5563b7cb50fbcec6327f029f63a31292bde26 (patch)
tree12bdcf93cb0243bdcaee690d444e32e0b67730d7
parent5226b884e7ad613b411b5872742aec832d341e01 (diff)
downloadeclipse.platform.swt-efc5563b7cb50fbcec6327f029f63a31292bde26.tar.gz
eclipse.platform.swt-efc5563b7cb50fbcec6327f029f63a31292bde26.tar.xz
eclipse.platform.swt-efc5563b7cb50fbcec6327f029f63a31292bde26.zip
Bug 525946: [Webkit2] Port download functionality to WebKit2.
- On WEBKIT2, the file dialog logic is now done in same thread as the signal handler since it does not freeze the UI, as may have been the case on WEBKIT1 - Use the 'download-requested' signal on WEBKIT2 as an entrypoint for other signals necessary to successfully download a file - Handle 'decide-destination' signal on WEBKIT2, and place file dialog logic there so that file path may be changed while still having the suggested file name - Handle 'finished', and 'failed' to be aware of download termination as well as disposing of the progress dialog - On WEBKIT2, state of a WebKitDownload is only informed through signals so create a webkitDownloadStatus Map so that the download window may be aware of download state - Re-use status codes from WEBKIT1 in the WEBKIT2 code to keep logic as similar as possible Tested on WEBKIT1 and WEBKIT2 with 2 browser instances each downloading the same large file (different destination) while alternating between instances and downloading smaller files. Change-Id: Ib4d1e5552eedcb73a61ae671f14408ff00f9b9a4 Signed-off-by: Roland Grunberg <rgrunber@redhat.com>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c180
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c9
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h9
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java200
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java122
-rw-r--r--tests/org.eclipse.swt.tests.gtk/Bug Snippets/org/eclipse/swt/tests/gtk/snippets/Bug525946_DownloadFunction.java32
6 files changed, 499 insertions, 53 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c
index 403f0f2e89..dc647bd51f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c
@@ -1436,6 +1436,66 @@ JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1download_1get_1network_1re
}
#endif
+#ifndef NO__1webkit_1download_1get_1received_1data_1length
+JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(_1webkit_1download_1get_1received_1data_1length)
+ (JNIEnv *env, jclass that, jintLong arg0)
+{
+ jlong rc = 0;
+ WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1download_1get_1received_1data_1length_FUNC);
+/*
+ rc = (jlong)webkit_download_get_received_data_length(arg0);
+*/
+ {
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_download_get_received_data_length)
+ if (fp) {
+ rc = (jlong)((jlong (CALLING_CONVENTION*)(jintLong))fp)(arg0);
+ }
+ }
+ WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1download_1get_1received_1data_1length_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1download_1get_1request
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1download_1get_1request)
+ (JNIEnv *env, jclass that, jintLong arg0)
+{
+ jintLong rc = 0;
+ WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1download_1get_1request_FUNC);
+/*
+ rc = (jintLong)webkit_download_get_request(arg0);
+*/
+ {
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_download_get_request)
+ if (fp) {
+ rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong))fp)(arg0);
+ }
+ }
+ WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1download_1get_1request_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1download_1get_1response
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1download_1get_1response)
+ (JNIEnv *env, jclass that, jintLong arg0)
+{
+ jintLong rc = 0;
+ WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1download_1get_1response_FUNC);
+/*
+ rc = (jintLong)webkit_download_get_response(arg0);
+*/
+ {
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_download_get_response)
+ if (fp) {
+ rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong))fp)(arg0);
+ }
+ }
+ WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1download_1get_1response_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO__1webkit_1download_1get_1status
JNIEXPORT jint JNICALL WebKitGTK_NATIVE(_1webkit_1download_1get_1status)
(JNIEnv *env, jclass that, jintLong arg0)
@@ -1496,6 +1556,26 @@ JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(_1webkit_1download_1get_1total_1size)
}
#endif
+#ifndef NO__1webkit_1download_1get_1type
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1download_1get_1type)
+ (JNIEnv *env, jclass that)
+{
+ jintLong rc = 0;
+ WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1download_1get_1type_FUNC);
+/*
+ rc = (jintLong)webkit_download_get_type();
+*/
+ {
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_download_get_type)
+ if (fp) {
+ rc = (jintLong)((jintLong (CALLING_CONVENTION*)())fp)();
+ }
+ }
+ WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1download_1get_1type_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO__1webkit_1download_1get_1uri
JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1download_1get_1uri)
(JNIEnv *env, jclass that, jintLong arg0)
@@ -1516,6 +1596,26 @@ JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1download_1get_1uri)
}
#endif
+#ifndef NO__1webkit_1download_1get_1web_1view
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1download_1get_1web_1view)
+ (JNIEnv *env, jclass that, jintLong arg0)
+{
+ jintLong rc = 0;
+ WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1download_1get_1web_1view_FUNC);
+/*
+ rc = (jintLong)webkit_download_get_web_view(arg0);
+*/
+ {
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_download_get_web_view)
+ if (fp) {
+ rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong))fp)(arg0);
+ }
+ }
+ WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1download_1get_1web_1view_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO__1webkit_1download_1new
JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1download_1new)
(JNIEnv *env, jclass that, jintLong arg0)
@@ -1536,6 +1636,46 @@ JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1download_1new)
}
#endif
+#ifndef NO__1webkit_1download_1set_1allow_1overwrite
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1webkit_1download_1set_1allow_1overwrite)
+ (JNIEnv *env, jclass that, jintLong arg0, jboolean arg1)
+{
+ WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1download_1set_1allow_1overwrite_FUNC);
+/*
+ webkit_download_set_allow_overwrite(arg0, arg1);
+*/
+ {
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_download_set_allow_overwrite)
+ if (fp) {
+ ((void (CALLING_CONVENTION*)(jintLong, jboolean))fp)(arg0, arg1);
+ }
+ }
+ WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1download_1set_1allow_1overwrite_FUNC);
+}
+#endif
+
+#ifndef NO__1webkit_1download_1set_1destination
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1webkit_1download_1set_1destination)
+ (JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1)
+{
+ jbyte *lparg1=NULL;
+ WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1download_1set_1destination_FUNC);
+ if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
+/*
+ webkit_download_set_destination(arg0, lparg1);
+*/
+ {
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_download_set_destination)
+ if (fp) {
+ ((void (CALLING_CONVENTION*)(jintLong, jbyte *))fp)(arg0, lparg1);
+ }
+ }
+fail:
+ if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
+ WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1download_1set_1destination_FUNC);
+}
+#endif
+
#ifndef NO__1webkit_1download_1set_1destination_1uri
JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1webkit_1download_1set_1destination_1uri)
(JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1)
@@ -2116,6 +2256,26 @@ fail:
}
#endif
+#ifndef NO__1webkit_1uri_1response_1get_1content_1length
+JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(_1webkit_1uri_1response_1get_1content_1length)
+ (JNIEnv *env, jclass that, jintLong arg0)
+{
+ jlong rc = 0;
+ WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1uri_1response_1get_1content_1length_FUNC);
+/*
+ rc = (jlong)webkit_uri_response_get_content_length(arg0);
+*/
+ {
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_uri_response_get_content_length)
+ if (fp) {
+ rc = (jlong)((jlong (CALLING_CONVENTION*)(jintLong))fp)(arg0);
+ }
+ }
+ WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1uri_1response_1get_1content_1length_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO__1webkit_1uri_1response_1get_1mime_1type
JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1uri_1response_1get_1mime_1type)
(JNIEnv *env, jclass that, jintLong arg0)
@@ -2200,6 +2360,26 @@ JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1context_1get_1default
}
#endif
+#ifndef NO__1webkit_1web_1context_1get_1type
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1context_1get_1type)
+ (JNIEnv *env, jclass that)
+{
+ jintLong rc = 0;
+ WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1context_1get_1type_FUNC);
+/*
+ rc = (jintLong)webkit_web_context_get_type();
+*/
+ {
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_web_context_get_type)
+ if (fp) {
+ rc = (jintLong)((jintLong (CALLING_CONVENTION*)())fp)();
+ }
+ }
+ WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1context_1get_1type_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO__1webkit_1web_1context_1set_1favicon_1database_1directory
JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1context_1set_1favicon_1database_1directory)
(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c
index 95a217975e..bd41410426 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c
@@ -93,11 +93,18 @@ char * WebKitGTK_nativeFunctionNames[] = {
"_1webkit_1download_1cancel",
"_1webkit_1download_1get_1current_1size",
"_1webkit_1download_1get_1network_1request",
+ "_1webkit_1download_1get_1received_1data_1length",
+ "_1webkit_1download_1get_1request",
+ "_1webkit_1download_1get_1response",
"_1webkit_1download_1get_1status",
"_1webkit_1download_1get_1suggested_1filename",
"_1webkit_1download_1get_1total_1size",
+ "_1webkit_1download_1get_1type",
"_1webkit_1download_1get_1uri",
+ "_1webkit_1download_1get_1web_1view",
"_1webkit_1download_1new",
+ "_1webkit_1download_1set_1allow_1overwrite",
+ "_1webkit_1download_1set_1destination",
"_1webkit_1download_1set_1destination_1uri",
"_1webkit_1download_1start",
"_1webkit_1favicon_1database_1set_1path",
@@ -127,10 +134,12 @@ char * WebKitGTK_nativeFunctionNames[] = {
"_1webkit_1uri_1request_1get_1http_1headers",
"_1webkit_1uri_1request_1get_1uri",
"_1webkit_1uri_1request_1new",
+ "_1webkit_1uri_1response_1get_1content_1length",
"_1webkit_1uri_1response_1get_1mime_1type",
"_1webkit_1user_1content_1manager_1new",
"_1webkit_1user_1content_1manager_1register_1script_1message_1handler",
"_1webkit_1web_1context_1get_1default",
+ "_1webkit_1web_1context_1get_1type",
"_1webkit_1web_1context_1set_1favicon_1database_1directory",
"_1webkit_1web_1data_1source_1get_1data",
"_1webkit_1web_1data_1source_1get_1encoding",
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h
index 5488aaf42d..bbbcb1300d 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h
@@ -103,11 +103,18 @@ typedef enum {
_1webkit_1download_1cancel_FUNC,
_1webkit_1download_1get_1current_1size_FUNC,
_1webkit_1download_1get_1network_1request_FUNC,
+ _1webkit_1download_1get_1received_1data_1length_FUNC,
+ _1webkit_1download_1get_1request_FUNC,
+ _1webkit_1download_1get_1response_FUNC,
_1webkit_1download_1get_1status_FUNC,
_1webkit_1download_1get_1suggested_1filename_FUNC,
_1webkit_1download_1get_1total_1size_FUNC,
+ _1webkit_1download_1get_1type_FUNC,
_1webkit_1download_1get_1uri_FUNC,
+ _1webkit_1download_1get_1web_1view_FUNC,
_1webkit_1download_1new_FUNC,
+ _1webkit_1download_1set_1allow_1overwrite_FUNC,
+ _1webkit_1download_1set_1destination_FUNC,
_1webkit_1download_1set_1destination_1uri_FUNC,
_1webkit_1download_1start_FUNC,
_1webkit_1favicon_1database_1set_1path_FUNC,
@@ -137,10 +144,12 @@ typedef enum {
_1webkit_1uri_1request_1get_1http_1headers_FUNC,
_1webkit_1uri_1request_1get_1uri_FUNC,
_1webkit_1uri_1request_1new_FUNC,
+ _1webkit_1uri_1response_1get_1content_1length_FUNC,
_1webkit_1uri_1response_1get_1mime_1type_FUNC,
_1webkit_1user_1content_1manager_1new_FUNC,
_1webkit_1user_1content_1manager_1register_1script_1message_1handler_FUNC,
_1webkit_1web_1context_1get_1default_FUNC,
+ _1webkit_1web_1context_1get_1type_FUNC,
_1webkit_1web_1context_1set_1favicon_1database_1directory_FUNC,
_1webkit_1web_1data_1source_1get_1data_FUNC,
_1webkit_1web_1data_1source_1get_1encoding_FUNC,
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 4dfd67b8b2..0b58b7c1a5 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
@@ -68,6 +68,7 @@ class WebKit extends WebBrowser {
static long /*int*/ PostString, WebViewType;
static boolean IsWebKit14orNewer;
static Map<LONG, LONG> WindowMappings = new HashMap<> ();
+ static Map<LONG, Integer> webKitDownloadStatus = new HashMap<> (); // Webkit2
static final String ABOUT_BLANK = "about:blank"; //$NON-NLS-1$
static final String CLASSNAME_EXTERNAL = "External"; //$NON-NLS-1$
@@ -121,6 +122,9 @@ class WebKit extends WebBrowser {
static final int MOUSE_TARGET_CHANGED = 18;
static final int CONTEXT_MENU = 19;
static final int AUTHENTICATE = 20;
+ static final int DECIDE_DESTINATION = 21; // webkit2 only.
+ static final int FAILED = 22; // webkit2 only.
+ static final int FINISHED = 23; // webkit2 only.
static final String KEY_CHECK_SUBWINDOW = "org.eclipse.swt.internal.control.checksubwindow"; //$NON-NLS-1$
@@ -554,7 +558,13 @@ static long /*int*/ JSDOMEventProc (long /*int*/ arg0, long /*int*/ event, long
}
static long /*int*/ Proc (long /*int*/ handle, long /*int*/ user_data) {
- Browser browser = FindBrowser (handle);
+ long /*int*/ webView = handle;
+
+ if (WEBKIT2 && OS.G_TYPE_CHECK_INSTANCE_TYPE (handle, WebKitGTK.webkit_download_get_type ())) {
+ webView = WebKitGTK.webkit_download_get_web_view(handle);
+ }
+
+ Browser browser = FindBrowser (webView);
if (browser == null) return 0;
WebKit webkit = (WebKit)browser.webBrowser;
return webkit.webViewProc (handle, user_data);
@@ -562,6 +572,7 @@ static long /*int*/ Proc (long /*int*/ handle, long /*int*/ user_data) {
static long /*int*/ Proc (long /*int*/ handle, long /*int*/ arg0, long /*int*/ user_data) {
long /*int*/ webView = 0;
+ boolean indirectWebView = false; // Behave as if handle were a WebKitWebView (Webkit2 only)
if (OS.G_TYPE_CHECK_INSTANCE_TYPE (handle, WebKitGTK.webkit_web_view_get_type ())) {
webView = handle;
} else if (OS.G_TYPE_CHECK_INSTANCE_TYPE (handle, WebKitGTK.webkit_web_frame_get_type ())) {
@@ -570,6 +581,19 @@ static long /*int*/ Proc (long /*int*/ handle, long /*int*/ arg0, long /*int*/ u
} else {
webView = WebKitGTK.webkit_web_frame_get_web_view (handle); // webkit1 only.
}
+ } else if (WEBKIT2 && OS.G_TYPE_CHECK_INSTANCE_TYPE (handle, WebKitGTK.webkit_web_context_get_type ())) {
+ /*
+ * There is no API to determine WebKitWebView from a WebKitWebContext in WEBKIT2.
+ * Therefore, we pass the WebKitWebView in user_data field only when the handle
+ * is a WebKitWebContext. We then restore user_data to DOWNLOAD_REQUESTED to
+ * ensure the corresponding function gets called.
+ */
+ webView = user_data;
+ user_data = DOWNLOAD_REQUESTED;
+ indirectWebView = true;
+ } else if (WEBKIT2 && OS.G_TYPE_CHECK_INSTANCE_TYPE (handle, WebKitGTK.webkit_download_get_type ())) {
+ webView = WebKitGTK.webkit_download_get_web_view(handle);
+ indirectWebView = true;
} else {
return 0;
}
@@ -579,7 +603,7 @@ static long /*int*/ Proc (long /*int*/ handle, long /*int*/ arg0, long /*int*/ u
Browser browser = FindBrowser (webView);
if (browser == null) return 0;
WebKit webkit = (WebKit)browser.webBrowser;
- if (webView == handle) {
+ if (webView == handle || indirectWebView) {
return webkit.webViewProc (handle, arg0, user_data);
} else {
return webkit.webFrameProc (handle, arg0, user_data);
@@ -713,6 +737,7 @@ long /*int*/ webViewProc (long /*int*/ handle, long /*int*/ user_data) {
switch ((int)/*64*/user_data) {
case CLOSE_WEB_VIEW: return webkit_close_web_view (handle);
case WEB_VIEW_READY: return webkit_web_view_ready (handle);
+ case FINISHED: return webkit_download_finished (handle); // Webkit2 only.
default: return 0;
}
}
@@ -721,6 +746,7 @@ long /*int*/ webViewProc (long /*int*/ handle, long /*int*/ arg0, long /*int*/ u
switch ((int)/*64*/user_data) {
case CREATE_WEB_VIEW: return webkit_create_web_view (handle, arg0);
case DOWNLOAD_REQUESTED: return webkit_download_requested (handle, arg0);
+ case DECIDE_DESTINATION: return webkit_download_decide_destination(handle, arg0); //Webkit2 only.
case NOTIFY_LOAD_STATUS: return webkit_notify_load_status (handle, arg0); // Webkit1
case LOAD_CHANGED: return webkit_load_changed (handle, (int) arg0, user_data);
case NOTIFY_PROGRESS: return webkit_notify_progress (handle, arg0);
@@ -728,6 +754,7 @@ long /*int*/ webViewProc (long /*int*/ handle, long /*int*/ arg0, long /*int*/ u
case POPULATE_POPUP: return webkit_populate_popup (handle, arg0);
case STATUS_BAR_TEXT_CHANGED: return webkit_status_bar_text_changed (handle, arg0); // Webkit1 only.
case AUTHENTICATE: return webkit_authenticate (handle, arg0); // Webkit2 only.
+ case FAILED: return webkit_download_failed (handle, arg0); // Webkit2 only.
default: return 0;
}
}
@@ -858,7 +885,7 @@ public void create (Composite parent, int style) {
OS.g_signal_connect (webView, WebKitGTK.load_changed, Proc3.getAddress (), LOAD_CHANGED);
OS.g_signal_connect (webView, WebKitGTK.ready_to_show, Proc2.getAddress (), WEB_VIEW_READY);
OS.g_signal_connect (webView, WebKitGTK.decide_policy, Proc4.getAddress (), DECIDE_POLICY);
- OS.g_signal_connect (WebKitGTK.webkit_web_context_get_default(), WebKitGTK.download_started, Proc3.getAddress (), DOWNLOAD_REQUESTED);
+ OS.g_signal_connect (WebKitGTK.webkit_web_context_get_default(), WebKitGTK.download_started, Proc3.getAddress (), this.webView);
OS.g_signal_connect (webView, WebKitGTK.mouse_target_changed, Proc4.getAddress (), MOUSE_TARGET_CHANGED);
OS.g_signal_connect (webView, WebKitGTK.context_menu, Proc5.getAddress (), CONTEXT_MENU);
OS.g_signal_connect (webView, WebKitGTK.notify_estimated_load_progress, Proc3.getAddress (), NOTIFY_PROGRESS);
@@ -2057,6 +2084,11 @@ void onResize (Event e) {
}
void openDownloadWindow (final long /*int*/ webkitDownload) {
+ assert WEBKIT1 : WebKitGTK.Webkit1AssertMsg;
+ openDownloadWindow(webkitDownload, null);
+}
+
+void openDownloadWindow (final long /*int*/ webkitDownload, final String suggested_filename) {
final Shell shell = new Shell ();
String msg = Compatibility.getMessage ("SWT_FileDownload"); //$NON-NLS-1$
shell.setText (msg);
@@ -2066,14 +2098,26 @@ void openDownloadWindow (final long /*int*/ webkitDownload) {
gridLayout.verticalSpacing = 20;
shell.setLayout (gridLayout);
- long /*int*/ name = WebKitGTK.webkit_download_get_suggested_filename (webkitDownload);
- int length = C.strlen (name);
+ String nameString;
+ if (WEBKIT1) {
+ long /*int*/ name = WebKitGTK.webkit_download_get_suggested_filename (webkitDownload);
+ int length = C.strlen (name);
+ byte[] bytes = new byte[length];
+ C.memmove (bytes, name, length);
+ nameString = new String (Converter.mbcsToWcs (bytes));
+ } else {
+ nameString = suggested_filename;
+ }
+
+ long /*int*/ url;
+ if (WEBKIT1) {
+ url = WebKitGTK.webkit_download_get_uri (webkitDownload);
+ } else {
+ long /*int*/ request = WebKitGTK.webkit_download_get_request(webkitDownload);
+ url = WebKitGTK.webkit_uri_request_get_uri(request);
+ }
+ int length = C.strlen (url);
byte[] bytes = new byte[length];
- C.memmove (bytes, name, length);
- String nameString = new String (Converter.mbcsToWcs (bytes));
- long /*int*/ url = WebKitGTK.webkit_download_get_uri (webkitDownload);
- length = C.strlen (url);
- bytes = new byte[length];
C.memmove (bytes, url, length);
String urlString = new String (Converter.mbcsToWcs (bytes));
msg = Compatibility.getMessage ("SWT_Download_Location", new Object[] {nameString, urlString}); //$NON-NLS-1$
@@ -2098,7 +2142,12 @@ void openDownloadWindow (final long /*int*/ webkitDownload) {
data = new GridData ();
data.horizontalAlignment = GridData.CENTER;
cancel.setLayoutData (data);
- final Listener cancelListener = event -> WebKitGTK.webkit_download_cancel (webkitDownload);
+ final Listener cancelListener = event -> {
+ if (WEBKIT2) {
+ webKitDownloadStatus.put(new LONG(webkitDownload), WebKitGTK.WEBKIT_DOWNLOAD_STATUS_CANCELLED);
+ }
+ WebKitGTK.webkit_download_cancel (webkitDownload);
+ };
cancel.addListener (SWT.Selection, cancelListener);
OS.g_object_ref (webkitDownload);
@@ -2107,11 +2156,19 @@ void openDownloadWindow (final long /*int*/ webkitDownload) {
display.timerExec (INTERVAL, new Runnable () {
@Override
public void run () {
- int status = WebKitGTK.webkit_download_get_status (webkitDownload);
+ int status = 0; // 0 allows download window to continue
+ if (WEBKIT1) {
+ status = WebKitGTK.webkit_download_get_status (webkitDownload);
+ } else {
+ status = webKitDownloadStatus.containsKey(new LONG(webkitDownload)) ? webKitDownloadStatus.get(new LONG(webkitDownload)) : 0;
+ }
if (shell.isDisposed () || status == WebKitGTK.WEBKIT_DOWNLOAD_STATUS_FINISHED || status == WebKitGTK.WEBKIT_DOWNLOAD_STATUS_CANCELLED) {
shell.dispose ();
display.timerExec (-1, this);
OS.g_object_unref (webkitDownload);
+ if (WEBKIT2) {
+ webKitDownloadStatus.remove(new LONG(webkitDownload));
+ }
return;
}
if (status == WebKitGTK.WEBKIT_DOWNLOAD_STATUS_ERROR) {
@@ -2120,11 +2177,22 @@ void openDownloadWindow (final long /*int*/ webkitDownload) {
OS.g_object_unref (webkitDownload);
cancel.removeListener (SWT.Selection, cancelListener);
cancel.addListener (SWT.Selection, event -> shell.dispose ());
+ if (WEBKIT2) {
+ webKitDownloadStatus.remove(new LONG(webkitDownload));
+ }
return;
}
- long current = WebKitGTK.webkit_download_get_current_size (webkitDownload) / 1024L;
- long total = WebKitGTK.webkit_download_get_total_size (webkitDownload) / 1024L;
+ long current = 0;
+ long total = 0;
+ if (WEBKIT1) {
+ current = WebKitGTK.webkit_download_get_current_size (webkitDownload) / 1024L;
+ total = WebKitGTK.webkit_download_get_total_size (webkitDownload) / 1024L;
+ } else {
+ current = WebKitGTK.webkit_download_get_received_data_length(webkitDownload) / 1024L;
+ long /*int*/ response = WebKitGTK.webkit_download_get_response(webkitDownload);
+ total = WebKitGTK.webkit_uri_response_get_content_length(response) / 1024L;
+ }
String message = Compatibility.getMessage ("SWT_Download_Status", new Object[] {new Long(current), new Long(total)}); //$NON-NLS-1$
statusLabel.setText (message);
display.timerExec (INTERVAL, this);
@@ -2345,42 +2413,88 @@ long /*int*/ webkit_create_web_view (long /*int*/ web_view, long /*int*/ frame)
}
long /*int*/ webkit_download_requested (long /*int*/ web_view, long /*int*/ download) {
- long /*int*/ name = WebKitGTK.webkit_download_get_suggested_filename (download);
- int length = C.strlen (name);
- byte[] bytes = new byte[length];
- C.memmove (bytes, name, length);
- final String nameString = new String (Converter.mbcsToWcs (bytes));
+ if (WEBKIT1) {
+ long /*int*/ name = WebKitGTK.webkit_download_get_suggested_filename (download);
+ int length = C.strlen (name);
+ byte[] bytes = new byte[length];
+ C.memmove (bytes, name, length);
+ final String nameString = new String (Converter.mbcsToWcs (bytes));
- final long /*int*/ request = WebKitGTK.webkit_download_get_network_request (download);
- OS.g_object_ref (request);
+ final long /*int*/ 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 (() -> {
- if (!browser.isDisposed ()) {
- FileDialog dialog = new FileDialog (browser.getShell (), SWT.SAVE);
- 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;
- long /*int*/ newDownload = WebKitGTK.webkit_download_new (request);
- byte[] uriBytes = Converter.wcsToMbcs (path, true);
- WebKitGTK.webkit_download_set_destination_uri (newDownload, uriBytes);
- openDownloadWindow (newDownload);
- WebKitGTK.webkit_download_start (newDownload);
- OS.g_object_unref (newDownload);
+ /*
+ * 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 (() -> {
+ if (!browser.isDisposed ()) {
+ FileDialog dialog = new FileDialog (browser.getShell (), SWT.SAVE);
+ 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;
+ long /*int*/ newDownload = WebKitGTK.webkit_download_new (request);
+ byte[] uriBytes = Converter.wcsToMbcs (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);
- });
+ OS.g_object_unref (request);
+ });
+ } else {
+ OS._g_signal_connect(download, WebKitGTK.decide_destination, Proc3.getAddress(), DECIDE_DESTINATION);
+ OS._g_signal_connect(download, WebKitGTK.failed, Proc3.getAddress(), FAILED);
+ OS._g_signal_connect(download, WebKitGTK.finished, Proc2.getAddress(), FINISHED);
+ }
return 1;
}
+long /*int*/ webkit_download_decide_destination(long /*int*/ download, long /*int*/ suggested_filename) {
+ assert WEBKIT2 : WebKitGTK.Webkit2AssertMsg;
+ final String fileName = getString(suggested_filename);
+
+ if (!browser.isDisposed ()) {
+ FileDialog dialog = new FileDialog (browser.getShell (), SWT.SAVE);
+ dialog.setFileName (fileName);
+ 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 (path, true);
+ WebKitGTK.webkit_download_set_allow_overwrite (download, true);
+ WebKitGTK.webkit_download_set_destination (download, uriBytes);
+ openDownloadWindow (download, fileName);
+ }
+ }
+
+ return 0;
+}
+
+long /*int*/ webkit_download_finished(long /*int*/ download) {
+ assert WEBKIT2 : WebKitGTK.Webkit2AssertMsg;
+ // A failed signal may have been recorded prior. The finish signal is now being called.
+ if (!webKitDownloadStatus.containsKey(new LONG(download))) {
+ webKitDownloadStatus.put(new LONG(download), WebKitGTK.WEBKIT_DOWNLOAD_STATUS_FINISHED);
+ }
+ return 0;
+}
+
+long /*int*/ webkit_download_failed(long /*int*/ download, long /*int*/ error) {
+ assert WEBKIT2 : WebKitGTK.Webkit2AssertMsg;
+ // A cancel may have been issued resulting in this signal call. Preserve the original cause.
+ if (!webKitDownloadStatus.containsKey(new LONG(download))) {
+ webKitDownloadStatus.put(new LONG(download), WebKitGTK.WEBKIT_DOWNLOAD_STATUS_ERROR);
+ }
+ return 0;
+}
+
/**
* Webkit2 only. WebkitWebView mouse-target-changed
* - void user_function (WebKitWebView *web_view, WebKitHitTestResult *hit_test_result, guint modifiers, gpointer user_data)
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 701cebc669..d4e8b50fc0 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
@@ -90,8 +90,11 @@ public class WebKitGTK extends C {
public static final byte[] create = ascii ("create"); // $NON-NLS-1$
public static final byte[] create_web_view = ascii ("create-web-view"); // $NON-NLS-1$
public static final byte[] decide_policy = ascii ("decide-policy"); // $NON-NLS-1$
+ public static final byte[] decide_destination = ascii ("decide-destination"); // $NON-NLS-1$ // Webkit2
public static final byte[] download_requested = ascii ("download-requested"); // $NON-NLS-1$
- public static final byte[] download_started = ascii ("download-started"); // $NON-NLS-1$
+ public static final byte[] download_started = ascii ("download-started"); // $NON-NLS-1$ // Webkit2
+ public static final byte[] failed = ascii ("failed"); // $NON-NLS-1$ // Webkit2
+ public static final byte[] finished = ascii ("finished"); // $NON-NLS-1$ // Webkit2
public static final byte[] hovering_over_link = ascii ("hovering-over-link"); // $NON-NLS-1$ // Webkit1 -> StatusTextListener.changed()
public static final byte[] mouse_target_changed = ascii ("mouse-target-changed"); // $NON-NLS-1$ // Webkit2 -> StatusTextListener.changed()
@@ -756,6 +759,18 @@ public static final void webkit_credential_free (long /*int*/ credential) {
}
/** @method flags=dynamic */
+public static final native long /*int*/ _webkit_web_context_get_type ();
+public static final long /*int*/ webkit_web_context_get_type () {
+ assert WEBKIT2 : Webkit2AssertMsg;
+ lock.lock();
+ try {
+ return _webkit_web_context_get_type ();
+ } finally {
+ lock.unlock();
+ }
+}
+
+/** @method flags=dynamic */
public static final native long /*int*/ _webkit_credential_new (byte[] username, byte[] password, int persistence);
public static final long /*int*/ webkit_credential_new (byte[] username, byte[] password, int persistence) {
assert WEBKIT2 : Webkit2AssertMsg;
@@ -905,7 +920,6 @@ public static final void webkit_download_cancel (long /*int*/ download) {
public static final native long _webkit_download_get_current_size (long /*int*/ download);
public static final long webkit_download_get_current_size (long /*int*/ download) {
assert WEBKIT1 : Webkit1AssertMsg;
- //TODO - guard from being called on webkit2.
lock.lock();
try {
return _webkit_download_get_current_size (download);
@@ -915,10 +929,21 @@ public static final long webkit_download_get_current_size (long /*int*/ download
}
/** @method flags=dynamic */
+public static final native long _webkit_download_get_received_data_length (long /*int*/ download);
+public static final long webkit_download_get_received_data_length (long /*int*/ download) {
+ assert WEBKIT2 : Webkit2AssertMsg;
+ lock.lock();
+ try {
+ return _webkit_download_get_received_data_length (download);
+ } finally {
+ lock.unlock();
+ }
+}
+
+/** @method flags=dynamic */
public static final native long /*int*/ _webkit_download_get_network_request (long /*int*/ download);
public static final long /*int*/ webkit_download_get_network_request (long /*int*/ download) {
assert WEBKIT1 : Webkit1AssertMsg;
- //TODO - guard from being called on webkit2.
lock.lock();
try {
return _webkit_download_get_network_request (download);
@@ -931,7 +956,6 @@ public static final long /*int*/ webkit_download_get_network_request (long /*int
public static final native int _webkit_download_get_status (long /*int*/ download);
public static final int webkit_download_get_status (long /*int*/ download) {
assert WEBKIT1 : Webkit1AssertMsg;
- //TODO - guard from being called on webkit2.
lock.lock();
try {
return _webkit_download_get_status (download);
@@ -944,7 +968,6 @@ public static final int webkit_download_get_status (long /*int*/ download) {
public static final native long /*int*/ _webkit_download_get_suggested_filename (long /*int*/ download);
public static final long /*int*/ webkit_download_get_suggested_filename (long /*int*/ download) {
assert WEBKIT1 : Webkit1AssertMsg;
- //TODO - guard from being called on webkit2.
lock.lock();
try {
return _webkit_download_get_suggested_filename (download);
@@ -954,10 +977,33 @@ public static final long /*int*/ webkit_download_get_suggested_filename (long /*
}
/** @method flags=dynamic */
+public static final native long /*int*/ _webkit_download_get_request (long /*int*/ download);
+public static final long /*int*/ webkit_download_get_request (long /*int*/ download) {
+ assert WEBKIT2 : Webkit2AssertMsg;
+ lock.lock();
+ try {
+ return _webkit_download_get_request (download);
+ } finally {
+ lock.unlock();
+ }
+}
+
+/** @method flags=dynamic */
+public static final native long /*int*/ _webkit_download_get_response (long /*int*/ download);
+public static final long /*int*/ webkit_download_get_response (long /*int*/ download) {
+ assert WEBKIT2 : Webkit2AssertMsg;
+ lock.lock();
+ try {
+ return _webkit_download_get_response (download);
+ } finally {
+ lock.unlock();
+ }
+}
+
+/** @method flags=dynamic */
public static final native long _webkit_download_get_total_size (long /*int*/ download);
public static final long webkit_download_get_total_size (long /*int*/ download) {
assert WEBKIT1 : Webkit1AssertMsg;
- //TODO - guard from being called on webkit2.
lock.lock();
try {
return _webkit_download_get_total_size (download);
@@ -967,10 +1013,33 @@ public static final long webkit_download_get_total_size (long /*int*/ download)
}
/** @method flags=dynamic */
+public static final native long /*int*/ _webkit_download_get_type ();
+public static final long /*int*/ webkit_download_get_type () {
+ assert WEBKIT2 : Webkit2AssertMsg;
+ lock.lock();
+ try {
+ return _webkit_download_get_type ();
+ } finally {
+ lock.unlock();
+ }
+}
+
+/** @method flags=dynamic */
+public static final native long _webkit_uri_response_get_content_length (long /*int*/ response);
+public static final long webkit_uri_response_get_content_length (long /*int*/ response) {
+ assert WEBKIT2 : Webkit2AssertMsg;
+ lock.lock();
+ try {
+ return _webkit_uri_response_get_content_length (response);
+ } finally {
+ lock.unlock();
+ }
+}
+
+/** @method flags=dynamic */
public static final native long /*int*/ _webkit_download_get_uri (long /*int*/ download);
public static final long /*int*/ webkit_download_get_uri (long /*int*/ download) {
assert WEBKIT1 : Webkit1AssertMsg;
- //TODO - guard from being called on webkit2.
lock.lock();
try {
return _webkit_download_get_uri (download);
@@ -980,10 +1049,21 @@ public static final long /*int*/ webkit_download_get_uri (long /*int*/ download)
}
/** @method flags=dynamic */
+public static final native long /*int*/ _webkit_download_get_web_view (long /*int*/ download);
+public static final long /*int*/ webkit_download_get_web_view (long /*int*/ download) {
+ assert WEBKIT2 : Webkit2AssertMsg;
+ lock.lock();
+ try {
+ return _webkit_download_get_web_view (download);
+ } finally {
+ lock.unlock();
+ }
+}
+
+/** @method flags=dynamic */
public static final native long /*int*/ _webkit_download_new (long /*int*/ request);
public static final long /*int*/ webkit_download_new (long /*int*/ request) {
assert WEBKIT1 : Webkit1AssertMsg;
- //TODO - guard from being called on webkit2.
lock.lock();
try {
return _webkit_download_new (request);
@@ -993,10 +1073,21 @@ public static final long /*int*/ webkit_download_new (long /*int*/ request) {
}
/** @method flags=dynamic */
+public static final native void _webkit_download_set_allow_overwrite (long /*int*/ download, boolean allowed);
+public static final void webkit_download_set_allow_overwrite (long /*int*/ download, boolean allowed) {
+ assert WEBKIT2 : Webkit2AssertMsg;
+ lock.lock();
+ try {
+ _webkit_download_set_allow_overwrite (download, allowed);
+ } finally {
+ lock.unlock();
+ }
+}
+
+/** @method flags=dynamic */
public static final native void _webkit_download_set_destination_uri (long /*int*/ download, byte[] destination_uri);
public static final void webkit_download_set_destination_uri (long /*int*/ download, byte[] destination_uri) {
assert WEBKIT1 : Webkit1AssertMsg;
- //TODO - guard from being called on webkit2.
lock.lock();
try {
_webkit_download_set_destination_uri (download, destination_uri);
@@ -1006,10 +1097,21 @@ public static final void webkit_download_set_destination_uri (long /*int*/ downl
}
/** @method flags=dynamic */
+public static final native void _webkit_download_set_destination (long /*int*/ download, byte[] destination_uri);
+public static final void webkit_download_set_destination (long /*int*/ download, byte[] destination_uri) {
+ assert WEBKIT2 : Webkit2AssertMsg;
+ lock.lock();
+ try {
+ _webkit_download_set_destination (download, destination_uri);
+ } finally {
+ lock.unlock();
+ }
+}
+
+/** @method flags=dynamic */
public static final native void _webkit_download_start (long /*int*/ download);
public static final void webkit_download_start (long /*int*/ download) {
assert WEBKIT1 : Webkit1AssertMsg;
- //TODO - guard from being called on webkit2.
lock.lock();
try {
_webkit_download_start (download);
diff --git a/tests/org.eclipse.swt.tests.gtk/Bug Snippets/org/eclipse/swt/tests/gtk/snippets/Bug525946_DownloadFunction.java b/tests/org.eclipse.swt.tests.gtk/Bug Snippets/org/eclipse/swt/tests/gtk/snippets/Bug525946_DownloadFunction.java
new file mode 100644
index 0000000000..95c2e1c0af
--- /dev/null
+++ b/tests/org.eclipse.swt.tests.gtk/Bug Snippets/org/eclipse/swt/tests/gtk/snippets/Bug525946_DownloadFunction.java
@@ -0,0 +1,32 @@
+package org.eclipse.swt.tests.gtk.snippets;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/*
+ * Title: Bug 459462 - [WebKit] Implement Download functionality
+ * How to run: launch snippet
+ * Bug description: Download functionality doesn't work on WebKit2.
+ * Expected results: Download functionality now works on WebKit2.
+ * GTK version(s): GTK3.x
+ */
+
+public class Bug525946_DownloadFunction {
+public static void main(String[] args) {
+final Display display = new Display();
+final Shell shell = new Shell(display);
+shell.setBounds(10, 10, 400, 400);
+shell.setLayout(new FillLayout());
+final Browser browser = new Browser(shell, SWT.NONE);
+browser.setUrl("http://download.eclipse.org/tools/orbit/downloads/drops/R20170516192513/orbit-buildrepo-R20170516192513.zip");
+shell.open();
+while (!shell.isDisposed()) {
+if (!display.readAndDispatch()) display.sleep();
+}
+shell.dispose();
+display.dispose();
+}
+} \ No newline at end of file

Back to the top