Thunar performs IO in UI functions
I faced performance issues while using Thunar with my phone connected by MTP. The Thunar UI froze often and was not very responsive with scrolling, selecting files and other mere file actions.
I tried to find the cause of issues and it turns out some UI functions make calls that drill down to IO, and freeze while waiting for IO to finish.
This is the list of IO calls I found. The tree structure represents the call stack.
-
From list model:
thunar_list_model_get_value `-thunar_file_get_content_type `-g_file_query_info -- [1] -
From icon renderer:
thunar_icon_renderer_render `-thunar_icon_factory_load_file_icon +-thunar_icon_factory_get_show_thumbnail | `-thunar_file_get_preview_type | `-g_file_query_filesystem_info -- [2] +-g_loadable_icon_load -- [3] `-thunar_file_get_icon_name `-thunar_file_get_content_type `-g_file_query_info -- [4] -
From misc UI:
thunar_standard_view_get_property `-thunar_list_model_get_statusbar_text `-thunar_g_file_get_free_space `-g_file_query_filesystem_info -- [5]thunar_standard_view_request_thumbnails_real (via g_idle_add) `-thunar_thumbnailer_begin_job `-thunar_thumbnailer_file_is_supported `-thunar_file_get_content_typethunar_folder_content_type_loader_idle (via g_idle_add) `-thunar_file_load_content_type `-thunar_file_get_content_typethunar_path_entry_set_current_file `-gtk_entry_set_text ...signal "changed" `-thunar_path_entry_changed `-thunar_folder_get_for_file `-thunar_file_watch `-g_file_monitor `-g_file_query_file_type
I believe there are other IO calls too, but I haven't found them yet. (Should I split the issue per case?)
I'd like to solve the issue, but before doing so I wanted to discuss the solution. I see two approaches to it:
-
Ad-hoc solution
-
Prefetch
GFileInfowith content-type beforehand. This solves [1] and [4], but slows down folder opening. -
Prefetch file system info in
ThunarFolderto prevent [2]. -
How to deal with [3]? I have no good clues for now.
-
-
Async model solution
-
Create a layer that connects GtkTreeView to async values. This could be a special column renderer, a custom data function for a list column, a custom GValue transformation function. When the value is pending the
get_valuecall returns a placeholder (blank or "..."); when the value is ready returns it. -
Use asynchronous
thunar_file_async_get_content_typein the list model. This solves [1]. -
Move the code from
thunar_icon_renderer_renderto a newthunar_file_async_get_iconthat returns the icon asynchronously. This solves [2] [3] and [4].
This solution increases code complexity because it introduces a new layer and a notion of async values that can be pending or ready.
-
For the status bar ([5]) it seems just enough to listen to the
notify::statusbar-text signal.
Could any of these solutions be accepted to the Thunar code? Maybe someone could think up something better? Because I'm not absolutely happy with the approaches above.