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

[macOS]: Command+H with Qt::Popup window open leads to inconsistent internal state

    XMLWordPrintable

Details

    • macOS
    • 965bcca6d4e22788721a9af906adfbd97af9af29

    Description

      Steps to reproduce:

      • Use this trivial example:

        #include <QComboBox>
        #include <QApplication>

        int main(int argc, char **argv)
        {
        QApplication app(argc, argv);

        QComboBox box1;
        box1.addItems( QStringList() << "a item" << "a second item" );
        box1.show();

        app.exec();

        return 0;
        }

      • Open the popup
      • Press Command+H or right click on the dock and choose "Hide"
      • Show the application again (either command+tab or via the dock)

      Observe: The combobox popup won't react to keyboard nor mouse input anymore. The application thus appears to hang. In reality the window below reacts to keyboard and mouse input. E.g. space/esc and clicking on the combobox arrow work.

      I've done some analysis on the cause of the problem:

      While a popup is open, which is indicated via QCocoaIntegration::instance()->activePopupWindow(), the code in qnsview.mm ensures that keyboard and mouse event are sent to the popup window.

      After the above steps, QCocoaIntegration::instance()->activePopupWindow() returns a null pointer and thus keyboard events and mouse events are sent to the window behind. (E.g. Space and Esc actually interact with the combobox)

      QCocoaIntegration::instance()->activePopupWindow() is null, because as far as qt is concerned the widget is hidden. Yet the corresponding NSPanel is not hidden.

      This is due to a bug in QCocoaWindow::hide()

      On pressing Command+H, qcocoapplicationdelegate.mm applicationDidResignActive is invoked, which posts a event.

      That event is (eventually) handled in QApplication::notify (qapplication.cpp), which calls closeAllPopups(), which calls QWidget::hide() on the combobox popup.

      This then calls QCocoaWindow::hide()

      QCocoaWindow::hide() checks if the m_nsWindow is visible, and if it is already hidden it immediately returns.

      Due to the asynchronous nature of the event handling, the nsWindow is already hidden.

      Removing the check for isVisible and always running [m_nsWindow orderOut:nil] does fix this bug.

      Attachments

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

        Activity

          People

            sorvig Morten Sørvig
            dt Daniel Teske
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes