diff --git a/gtk/gtksearchenginetracker3.c b/gtk/gtksearchenginetracker3.c index 4aba6312ff..0e2c86de6b 100644 --- a/gtk/gtksearchenginetracker3.c +++ b/gtk/gtksearchenginetracker3.c @@ -34,6 +34,8 @@ #include "gtksearchenginetracker3.h" +#define N_RESULT_BATCH_ITEMS 50 + #define MINER_FS_BUS_NAME "org.freedesktop.Tracker3.Miner.Files" #define SEARCH_QUERY_BASE(__PATTERN__) \ @@ -65,6 +67,7 @@ struct _GtkSearchEngineTracker3 TrackerSparqlStatement *search_location_query; TrackerSparqlStatement *file_check_query; GCancellable *cancellable; + guint idle_id; GtkQuery *query; gboolean query_pending; }; @@ -74,6 +77,13 @@ struct _GtkSearchEngineTracker3Class GtkSearchEngineClass parent_class; }; +typedef struct +{ + TrackerSparqlCursor *cursor; + GtkSearchEngineTracker3 *engine; + gboolean got_results; +} CursorData; + static void gtk_search_engine_tracker3_initable_iface_init (GInitableIface *iface); G_DEFINE_TYPE_WITH_CODE (GtkSearchEngineTracker3, @@ -97,6 +107,8 @@ finalize (GObject *object) g_object_unref (engine->cancellable); } + g_clear_handle_id (&engine->idle_id, g_source_remove); + g_clear_object (&engine->search_query); g_clear_object (&engine->search_location_query); g_clear_object (&engine->file_check_query); @@ -149,6 +161,59 @@ create_file_info (TrackerSparqlCursor *cursor) return info; } +static gboolean +handle_cursor_idle_cb (gpointer user_data) +{ + CursorData *data = user_data; + GtkSearchEngineTracker3 *engine = data->engine; + TrackerSparqlCursor *cursor = data->cursor; + gboolean has_next; + GList *hits = NULL; + GtkSearchHit *hit; + int i = 0; + + for (i = 0; i < N_RESULT_BATCH_ITEMS; i++) + { + const gchar *url; + + has_next = tracker_sparql_cursor_next (cursor, NULL, NULL); + if (!has_next) + break; + + url = tracker_sparql_cursor_get_string (cursor, 0, NULL); + hit = g_slice_new0 (GtkSearchHit); + hit->file = g_file_new_for_uri (url); + hit->info = create_file_info (cursor); + hits = g_list_prepend (hits, hit); + data->got_results = TRUE; + } + + _gtk_search_engine_hits_added (GTK_SEARCH_ENGINE (engine), hits); + + g_list_free_full (hits, free_hit); + + if (has_next) + return G_SOURCE_CONTINUE; + else + { + engine->idle_id = 0; + return G_SOURCE_REMOVE; + } +} + +static void +cursor_data_free (gpointer user_data) +{ + CursorData *data = user_data; + + tracker_sparql_cursor_close (data->cursor); + _gtk_search_engine_finished (GTK_SEARCH_ENGINE (data->engine), + data->got_results); + g_object_unref (data->cursor); + g_object_unref (data->engine); + g_free (data); +} + static void query_callback (TrackerSparqlStatement *statement, GAsyncResult *res, @@ -156,9 +221,8 @@ query_callback (TrackerSparqlStatement *statement, { GtkSearchEngineTracker3 *engine; TrackerSparqlCursor *cursor; - GList *hits = NULL; GError *error = NULL; - GtkSearchHit *hit; + CursorData *data; engine = GTK_SEARCH_ENGINE_TRACKER3 (user_data); @@ -174,25 +238,14 @@ query_callback (TrackerSparqlStatement *statement, return; } - while (tracker_sparql_cursor_next (cursor, NULL, NULL)) - { - const gchar *url; + data = g_new0 (CursorData, 1); + data->cursor = cursor; + data->engine = engine; - url = tracker_sparql_cursor_get_string (cursor, 0, NULL); - hit = g_slice_new0 (GtkSearchHit); - hit->file = g_file_new_for_uri (url); - hit->info = create_file_info (cursor); - hits = g_list_prepend (hits, hit); - } - - tracker_sparql_cursor_close (cursor); - - _gtk_search_engine_hits_added (GTK_SEARCH_ENGINE (engine), hits); - _gtk_search_engine_finished (GTK_SEARCH_ENGINE (engine), hits != NULL); - - g_list_free_full (hits, free_hit); - g_object_unref (engine); - g_object_unref (cursor); + engine->idle_id = + g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, + handle_cursor_idle_cb, + data, cursor_data_free); } static void @@ -271,6 +324,8 @@ gtk_search_engine_tracker3_stop (GtkSearchEngine *engine) g_cancellable_cancel (tracker->cancellable); tracker->query_pending = FALSE; } + + g_clear_handle_id (&tracker->idle_id, g_source_remove); } static void