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

QMenu - Menu closes when clicking on a submenu displayed as a result of a show event [Regression]

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P1: Critical
    • 4.7.0
    • 4.5.0, 4.5.1, 4.5.2, 4.5.3, 4.6.0, 4.6.1
    • None
    • Not reproducible on mac, but reproduced on a Linux machine.

    Description

      This behavior was introduced in Qt-4.5.0.

      When clicking (also on a touchscreen) on a menu item with a submenu the submenu will popup with its first item highlighted. If this first item has its own menu, this too will be displayed. The effect is you have three levels (A, a, and 1) displayed, with A and a being selected.

      < A > < a > 1
      B b
      C

      Clicking on 1 causes the menu to close up to the menu bar.

      The exact cause chain is still unknown, however I know that QMenuPrivate::setFirstAcitonActive() is called on the second menu (the one with actions a and b) before it is shown. As a result when its show event arrives in QMenu::event() the second menu has a current action (the third menu) which it then pops up. This means the third menu is shown before the second menu. When one clicks on the action 1 in the third menu, the click event goes to the second menu, because it was shown last and has focus. The click is outside it's region, so it closes.

      Steps to reproduce with a mouse (somewhat difficult)
      1. Build and run the following simple demonstration program.

      #include <QApplication> 
      #include <QPushButton> 
      #include <QMenu> 
      
      int main(int argc, char** argv) 
      { 
      QApplication app(argc, argv); 
      
      QPushButton button("Menu"); 
      button.show(); 
      
      QMenu* pMenu = new QMenu("Menu", &button); 
      button.setMenu(pMenu); 
      
      for (int i = 0; i < 3; ++i) { 
      QMenu* pSubMenu = pMenu->addMenu("layer 1:"+QString::number(i)); 
      for (int j = 0; j < 3; ++j) { 
      QMenu* pSubSubMenu = pSubMenu->addMenu("layer 2:"+QString::number(j)); 
      for (int k = 0; k < 3; ++k) { 
      pSubSubMenu->addAction("layer 3:"+QString::number(k)); 
      } 
      } 
      } 
      
      return app.exec(); 
      } 
      

      2. Press & hold the mouse on the button to open the menu.
      3. Move your mouse to the first menu item "layer 1:0" without releasing.
      4. Before the submenu displays, release the mouse button. Three menus should appear.
      5. Move the mouse over to click on a "layer 3" action item.
      6. BUG: When the mouse moves over the third menu, it hides.

      Proposed fix:

      diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp 
      index 8ce7cc0..55d8b5f 100644 
      --- a/src/gui/widgets/qmenu.cpp 
      +++ b/src/gui/widgets/qmenu.cpp 
      @@ -2397,7 +2397,7 @@ QMenu::event(QEvent *e) 
      d->mouseDown = 0; 
      d->updateActionRects(); 
      if (d->currentAction) 
      - d->popupAction(d->currentAction, 0, false); 
      + d->popupAction(d->currentAction, 1, false); 
      break; 
      #ifndef QT_NO_WHATSTHIS 
      case QEvent::QueryWhatsThis: 
      

      Attachments

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

        Activity

          People

            vfm Thierry Bastian (closed Nokia identity) (Inactive)
            dettman Dean Dettman (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes