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

[Reg Qt5->Qt6] QMenu cannot arrange menu entries correctly when there are large quantity of them

    XMLWordPrintable

Details

    • Windows
    • 8cd7a3d47 (dev), 60d91acc0 (6.7), 19792c38e (6.6), dc43086e7 (tqtc/lts-6.5), 7aedcdefb (dev), 137706fc3 (6.7), a158a1807 (6.6), 3a4ea1c70 (tqtc/lts-6.5)

    Description

      Reproducer attached. One can adjust the number of entries to be shown in menu by entering numbers to QLineEdit, so that there are many enough to show the problem. Also, one needs 2 displays with different resolutions and sizes. The more different the displays are, the clearer the problem is. I suppose it is different DPI that causes the issue.

      The issue is that if all menu entries on one display can be shown correctly, there can be some missing from another display. For example, I have 1920*1200 16-inch and 1920*1080 27-inch. Please find the screenshots. With Qt6, QMenu is sized correctly (there is another column), but entries are not arranged accordingly (Menu 49 ~ 54 are missing, and entries are not being placed in the 3rd column) on the 27-inch screen.

      However, it does not happen to Qt5. See the screenshots, that entries are placed correctly into the 3rd column so that all of them are visible on the 27-inch screen.

      Suspected cause:
      In qmenu.cpp:

      void QMenuPrivate::updateActionRects() const
      {
          updateActionRects(popupGeometry());
      }
      

      popupGeometry is called without argument.

      Proposed fix:
      Substitute the content of method by

      Q_Q(const QMenu);
      updateActionRects(popupGeometry(QGuiApplication::screenAt(q->pos())));
      

      Maybe this needs fix too:

      void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation location, bool active)
      {
      ......
      QRect screen = popupGeometry();
      ......
      }
      

      Another "stupid" fix for it is to explicitly set a geometry for QMenu. For example, in the sample program, instead of

      menu.exec(event->globalPos());
      

      do this:

      menu.setGeometry(event->globalX(), event->globalY(), 0, 0); 
      menu.exec();
      

      I don't know why it works, even with nonsense size 0-by-0.

      Attachments

        1. ubuntu_result.png
          ubuntu_result.png
          201 kB
        2. Recording 2023-11-14 102439.mp4
          24.59 MB
        3. qtbug118434.zip
          7 kB
        4. qtbug118434_log.txt
          2 kB
        5. qtbug118434_diag.diff
          2 kB
        6. Qt6_1920_1200_16inch.png
          Qt6_1920_1200_16inch.png
          119 kB
        7. Qt6_1920_1080_27inch.png
          Qt6_1920_1080_27inch.png
          84 kB
        8. Qt5_1920_1200_16inch.png
          Qt5_1920_1200_16inch.png
          105 kB
        9. Qt5_1920_1080_27inch.png
          Qt5_1920_1080_27inch.png
          107 kB
        10. menutest-static.zip
          3 kB
        11. menutest-static.mp4
          18.15 MB
        12. menutest-member.zip
          3 kB
        13. menutest.zip
          3 kB
        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            axelspoerl Axel Spoerl
            luqiaochen Luqiao Chen
            Votes:
            1 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes