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

Windows: Unbind Qt::WindowSystemMenuHint with Qt::WindowMinMaxButtonsHint.

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 6.4.2, 6.4.3
    • None
    • OS: WIndows 10 21H1.
      Qt: 6.4.2 shared via MSYS2 - MinGW x64.
      Compiler: g++ 12.2.0 in MSYS2 - MinGW x64.

      My full project is created and compiled in MinGW x64 via CMake.
    • Windows

    Description

      The Issue

      Unbind Qt::WindowSystemMenuHint with Qt::WindowMinMaxButtonsHint, Qt::WindowMinimizeButtonHint and WindowMaximizeButtonHint. Restore Qt 5 behavior (functional regression issue).

      Reproduce Steps

      Download the attachment. main.h includes the core code, and use CMake to compile it, please.

      In Qt 6:

      1. Directly compile it. You will see we got an empty window. We can move it, but we cannot resize it.
      2. Then, remove the annotation symbol (Ctrl + /) of Line 26 in main.h. Compile and run it. We still cannot resize it.
      3. Then, re-annotate Line 26 and remove the annotation symbol from Line 29 to Line 33. Then compile and run it. We got a resizable window.

      In Qt 5:

      1. Just compile and run the attachment, we can get a resizable window. We do not need to write any Win32 function call. This is the expected behavior.

      Affected Qt Version

      More precisely, the Qt 5 I mentioned in the Reproduce Steps chapter is Qt 5.15.2. And Qt 6 is Qt 6.4.2 and 6.4.3.

      However, I do not know which Qt 6 version brings this functional regression bug. But I am definitely sure this bug only happened on Qt 6. This is the reason why I do not mention the version in detail in the reproduce steps.

      The Deep Reasons

      I have some own research about this bug. First, I have found the difference between Qt 6.4.2 and Qt 5.15 (Sorry for the format of code reference. I do not know how to refer to Qt code properly. So I refer to them via GitHub)

      Qt 6.4.2 implementation: https://github.com/qt/qtbase/blob/e3e40c44d3f998a433a6a1080297c5f28e9a768f/src/plugins/platforms/windows/qwindowswindow.cpp#L833
      Qt 5.15 implementation: https://github.com/qt/qtbase/blob/4ee4fc18b4067b90efa46ca9baba74f53b54d9ec/src/plugins/platforms/windows/qwindowswindow.cpp#L732

      Obviously, Qt 6.4.2 assumes that WS_SYSMENU is the prerequisite of WS_MINIMIZEBOX and WS_MAXIMIZEBOX. This actually binds Qt::WindowSystemMenuHint with Qt::WindowMinMaxButtonsHint, Qt::WindowMinimizeButtonHint, and WindowMaximizeButtonHint.

      In my opinion, just removing this forced bind, the behavior will be restored.

      The Truth of WS_SYSMENU

      First, I notice Qt Document info us that minimize button and maximize button are implies Qt::WindowSystemMenuHint for it to work on some platforms (Reference: https://doc.qt.io/qt-6/qt.html Search Qt::WindowMinMaxButtonsHint in it).
      Also, Microsoft Document show that WS_SYSMENU is "The window has a window menu on its title bar. The WS_CAPTION style must also be specified." WS_MAXIMIZEBOX and WS_MINIMIZEBOX also said "The WS_SYSMENU style must also be specified." (Reference: https://learn.microsoft.com/en-us/windows/win32/winmsg/window-styles )

      No matter how you look at it, the code written by Qt is correct. But it cannot explain the behavior of the attachment.
      Considering that Windows is an OS with a huge history, I believe that WS_SYSMENU may control the resizing function of the window. Although Microsoft does not write this in its document.

      But, why not removing Qt::WindowMinMaxButtonsHint? I will tell you that WS_MINIMIZEBOX not only control the display of minimize box in title bar. It also allows that you click the icon on taskbar to zoom in & out the window. This behavior also is not written in Microsoft document. You can remove Qt::WindowMinMaxButtonsHint in my attachment to see this phenomenon.

      So, I want to say, this is not an unreasonable bug. This requirement is common and reasonable. Qt provide it in Qt 5, but it is buggy in Qt 6. In some case, we do need a frameless window, and we need to control its resizing, and allow the user to click the taskbar icon to zoom in & out the window.

      Epilogue

      The implementation of function nativeEvent is a common implementation on the Internet. Most Windows Qt users use similar code to implement a resizable frameless window. I mean, using Win32 functions, not Qt functions to implement resizing. Related URL was written at code, you can take a look.

      Also this is a part of my work. See this URL if you are interested in it. https://github.com/BLumia/pineapple-pictures/pull/81
      The provided attachment also is the minimalist reproduce implementation of this project.
       

      Attachments

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

        Activity

          People

            qt.team.quick.subscriptions Qt Quick and Widgets Team
            yyc12345 Tad William
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes