Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-107618

QFileDialog freeze when selecting large zip-file using the windows native dialog

    XMLWordPrintable

Details

    • Windows
    • 933eb68a9d (qt/qtbase/dev) 933eb68a9d (qt/tqtc-qtbase/dev) 520a837888 (qt/qtbase/6.4) 520a837888 (qt/tqtc-qtbase/6.4) 520a837888 (qt/tqtc-qtbase/6.4.1) 520a837888 (qt/tqtc-qtbase/tqtc/qtinsight-6.4)

    Description

      Problem

      We have discovered a case where simply the action of selecting a file in the QFileDialog results in a complete freeze of the dialog for over a minute. This happens when using the Windows Native Dialog only, when forcing DontUseNativeDialog there is no freeze. 

      The freeze happens when you select a very large zip container. In our case the file is 50 gigabytes and contains about 200'000 files. 

      Similar issues

      I read the description to a similar bug report:
      https://bugreports.qt.io/browse/QTBUG-72479

      In that report the IFileDialog class was blamed, so I tried one of the official examples from Microsoft using the IFileDialog:
      https://github.com/microsoft/Windows-classic-samples/tree/main/Samples/Win7Samples/winui/shell/appplatform/commonfiledialog

      However, the Microsoft example do not have the same freezing behavior.

      Cause

      This made me dig a bit into the QT source and I have been able to track down the line of code which is causing the freeze. It is located in: qtbase\src\plugins\platforms\windows\qwindowsdialoghelpers.cpp

      In the constructor for QWindowsShellItem:

      QWindowsShellItem::QWindowsShellItem(IShellItem *item)
          : m_item(item)
          , m_attributes(0)
      {
          if (FAILED(item->GetAttributes(SFGAO_CAPABILITYMASK | SFGAO_DISPLAYATTRMASK | SFGAO_CONTENTSMASK | SFGAO_STORAGECAPMASK, &m_attributes)))
              m_attributes = 0;
      }
      

      The problem in this case is the checking of the SFGAO_CONTENTSMASK which forces the IShellItem to check if the file have subfolders, which in turn makes Windows start the indexing of the zip-file. In our case, this indexing takes over 70 second and during this time the file dialog is completely frozen.

      Further information

      I made a small program which profiles the time to acquire the different IShellItem attributes listed here:
      https://learn.microsoft.com/en-us/windows/win32/shell/sfgao

      The attributes which are expensive to check is: SFGAO_HASSUBFOLDER, SFGAO_CONTENTSMASK and SFGAO_PKEYSFGAOMASK. All these attribute forces windows to start indexing the zip-file, which is an expensive operation when the ZIP file is large. All other attributes can be retrieved within 0.2 ms.

      Proposed solution

      My proposal is to remove the SFGAO_CONTENTSMASK check from the attribute list in the constructor. The bitmask for this enum is the same as in SFGAO_HASSUBFOLDER, which Microsoft describes in their documentation as:

      "The SFGAO_HASSUBFOLDER attribute is only advisory and might be returned by Shell folder implementations even if they do not contain subfolders."

      Since the attribute is only advisory it should be safe to skip, or at least defer to a later point if needed.

      At the same time the attribute check for SFGAO_DISPLAYATTRMASK should probably be remove as well, since the Microsoft documentation states: Do not use.

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              vhilshei Volker Hilsheimer
              bjornblissing Björn Blissing
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes