From c8b63e55987f0ee6d4067a7309ef2fac8119b0cc Mon Sep 17 00:00:00 2001 From: rootavish Date: Sun, 20 Jul 2014 23:57:08 +0530 Subject: Moving everything related to webkit to main thread jobs Including creation of windows, webviews etc., still get a crash. The one page epub works fine with the thumbnails though. Also fixing some calls which cause gtk-critical errors when I try to close the window. --- libview/ev-jobs.c | 56 ++++++++++++++++++++++++++++++++++--------------------- libview/ev-jobs.h | 2 +- shell/ev-window.c | 26 +++++++++----------------- 3 files changed, 45 insertions(+), 39 deletions(-) diff --git a/libview/ev-jobs.c b/libview/ev-jobs.c index 44881516..8a9f6727 100644 --- a/libview/ev-jobs.c +++ b/libview/ev-jobs.c @@ -817,23 +817,15 @@ ev_job_thumbnail_run (EvJob *job) if (job->document->iswebdocument == TRUE) { gboolean completed = FALSE; - GtkWidget *webview = webkit_web_view_new(); EvJobWebThumbnail *web_thumb_job = - EV_JOB_WEB_THUMBNAIL(ev_job_web_thumbnail_new(job->document, &completed, webview, (gchar*)rc->page->backend_page)); + EV_JOB_WEB_THUMBNAIL(ev_job_web_thumbnail_new(job->document, &completed, (gchar*)rc->page->backend_page)); ev_job_scheduler_push_job (EV_JOB (web_thumb_job), EV_JOB_PRIORITY_HIGH); - WebKitLoadStatus status ; - - while ((status = webkit_web_view_get_load_status (WEBKIT_WEB_VIEW(webview))) != WEBKIT_LOAD_FINISHED && - status != WEBKIT_LOAD_FAILED) { - /*Let the job complete before we proceed. - *This fix SHOULD solve all problems. - */ + while (completed == FALSE) { + /* Let the job complete*/ } - - web_thumb_job->surface = webkit_web_view_get_snapshot (WEBKIT_WEB_VIEW(webview)); /* For the purpose of thumbnails only, we make the page a cairo surface, instead of the uri's we are passing around*/ EvPage *screenshotpage; screenshotpage = ev_page_new(rc->page->index); @@ -903,7 +895,7 @@ ev_job_web_thumbnail_dispose (GObject *object) job = EV_JOB_WEB_THUMBNAIL (object); - ev_debug_message (DEBUG_JOBS, "%d (%p)", job->page, job); + ev_debug_message (DEBUG_JOBS, "%s (%p)", job->page, job); if(job->offscreenwindow) { gtk_widget_destroy(job->offscreenwindow); @@ -923,14 +915,41 @@ ev_job_web_thumbnail_dispose (GObject *object) g_free(job->page); job->page = NULL; } + + if (&job->screenlock) + { + g_rw_lock_clear (&job->screenlock); + } (* G_OBJECT_CLASS (ev_job_web_thumbnail_parent_class)->dispose) (object); } +static void +web_thumbnail_get_screenshot_cb(WebKitWebView *webview, + GParamSpec *spec, + EvJobWebThumbnail *web_thumb_job) +{ + WebKitLoadStatus status = webkit_web_view_get_load_status(webview); + + if (status == WEBKIT_LOAD_FINISHED) { + g_rw_lock_writer_unlock (&web_thumb_job->screenlock); + g_rw_lock_reader_trylock (&web_thumb_job->screenlock); + web_thumb_job->surface = webkit_web_view_get_snapshot (WEBKIT_WEB_VIEW(webview)); + g_rw_lock_reader_unlock (&web_thumb_job->screenlock); + *(web_thumb_job->completed) = TRUE; + } +} + static gboolean ev_job_web_thumbnail_run (EvJob *job) { EvJobWebThumbnail *web_thumb_job = EV_JOB_WEB_THUMBNAIL(job); + web_thumb_job->webview = webkit_web_view_new(); + web_thumb_job->offscreenwindow = gtk_offscreen_window_new(); + gtk_container_add(GTK_CONTAINER(web_thumb_job->offscreenwindow),GTK_WIDGET(web_thumb_job->webview)); + + gtk_window_set_default_size (GTK_WINDOW(web_thumb_job->offscreenwindow),800,1080); + ev_debug_message (DEBUG_JOBS, "%s (%p)", web_thumb_job->page, job); #ifdef EV_ENABLE_DEBUG @@ -939,10 +958,10 @@ ev_job_web_thumbnail_run (EvJob *job) ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job); #endif - gtk_window_set_default_size (GTK_WINDOW(web_thumb_job->offscreenwindow),800,1080); - + + g_rw_lock_writer_trylock (&web_thumb_job->screenlock); webkit_web_view_load_uri(WEBKIT_WEB_VIEW(web_thumb_job->webview),web_thumb_job->page); - + g_signal_connect(WEBKIT_WEB_VIEW(web_thumb_job->webview),"notify::load-status",G_CALLBACK(web_thumbnail_get_screenshot_cb),web_thumb_job); gtk_widget_show_all(web_thumb_job->offscreenwindow); ev_job_succeeded (EV_JOB(job)); @@ -963,7 +982,6 @@ ev_job_web_thumbnail_class_init (EvJobWebThumbnailClass *class) EvJob * ev_job_web_thumbnail_new (EvDocument *document, gboolean *completed, - GtkWidget *webview, gchar *webpage) { EvJobWebThumbnail *job; @@ -974,15 +992,11 @@ ev_job_web_thumbnail_new (EvDocument *document, EV_JOB (job)->document = g_object_ref (document); - job->webview = webview; job->completed = completed; - job->offscreenwindow = gtk_offscreen_window_new(); - - gtk_container_add(GTK_CONTAINER(job->offscreenwindow),GTK_WIDGET(job->webview)); job->surface = NULL; job->page = g_strdup(webpage); - + g_rw_lock_init (&job->screenlock); return EV_JOB (job); } diff --git a/libview/ev-jobs.h b/libview/ev-jobs.h index a45891b6..ded0f05f 100644 --- a/libview/ev-jobs.h +++ b/libview/ev-jobs.h @@ -306,6 +306,7 @@ struct _EvJobWebThumbnail GtkWidget *webview; GtkWidget *offscreenwindow; gboolean *completed; + GRWLock screenlock; cairo_surface_t *surface; gchar* page; }; @@ -476,7 +477,6 @@ EvJob *ev_job_thumbnail_new (EvDocument *document, GType ev_job_web_thumbnail_get_type (void) G_GNUC_CONST; EvJob *ev_job_web_thumbnail_new (EvDocument *document, gboolean *completed, - GtkWidget *webview, gchar *webpage); /* EvJobFonts */ GType ev_job_fonts_get_type (void) G_GNUC_CONST; diff --git a/shell/ev-window.c b/shell/ev-window.c index 3fcf3786..d73cfba6 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -453,8 +453,9 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) ev_window_set_action_sensitive (ev_window, "EditRotateRight", has_pages && !(document->iswebdocument)); /* View menu */ - /*If it has pages it is a document, so our check for a webdocument lead to a crash. We need to switch these off since more than one - *webview is hard to manage */ + /*If it has pages it is a document, so our check for a webdocument won't lead to a crash. We need to switch these off since more than one + *webview is hard to manage, and would lead to unexpected behaviour in case the number of webviews gets too large. + */ ev_window_set_action_sensitive (ev_window, "ViewContinuous", has_pages && !(document->iswebdocument)); ev_window_set_action_sensitive (ev_window, "ViewDual", has_pages && !(document->iswebdocument)); ev_window_set_action_sensitive (ev_window, "ViewBestFit", has_pages && !(document->iswebdocument)); @@ -1469,6 +1470,10 @@ ev_window_set_document (EvWindow *ev_window, EvDocument *document) ev_window->priv->webview); gtk_widget_show(ev_window->priv->webview); } + else { + /*Since the document is not a webdocument might as well get rid of the webview now*/ + g_object_unref(ev_window->priv->webview); + } #endif if (EV_WINDOW_IS_PRESENTATION (ev_window) && document->iswebdocument == FALSE) { gtk_widget_destroy (ev_window->priv->presentation_view); @@ -5380,26 +5385,13 @@ ev_window_dispose (GObject *object) } if (priv->view) { - if ( gtk_widget_get_parent (priv->view) == NULL ) - { - g_object_ref_sink (priv->view); - g_object_unref(priv->view); - } - else - { - g_object_unref (priv->view); - } + g_object_unref (priv->view); priv->view = NULL; } #ifdef ENABLE_EPUB if ( priv->webview ) { - if (gtk_widget_get_parent(priv->webview) == NULL ) { - g_object_ref_sink (priv->webview); - g_object_unref (priv->webview); - }else { - g_object_unref (priv->webview); - } + g_object_unref (priv->webview); priv->webview = NULL ; } #endif -- cgit v1.2.1