Skip to content

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_type
      thunar_folder_content_type_loader_idle (via g_idle_add)
      `-thunar_file_load_content_type
        `-thunar_file_get_content_type
      thunar_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:

  1. Ad-hoc solution

    • Prefetch GFileInfo with content-type beforehand. This solves [1] and [4], but slows down folder opening.

    • Prefetch file system info in ThunarFolder to prevent [2].

    • How to deal with [3]? I have no good clues for now.

  2. 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_value call returns a placeholder (blank or "..."); when the value is ready returns it.

    • Use asynchronous thunar_file_async_get_content_type in the list model. This solves [1].

    • Move the code from thunar_icon_renderer_render to a new thunar_file_async_get_icon that 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.

Edited by Viktor Semykin