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

activateWindow doesn't work correctly on the Mac OS X in case of a popup window

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P2: Important P2: Important
    • None
    • 5.5.0
    • GUI: Window management
    • None
    • Mac OS X 10.10.x, Qt 5.5.0, clang, c++11
    • macOS

      QWidget::activateWindow() works incorrectly when I try to create my own popup window functionality.
      Under the Windows everything works as expected.

      I have a sample application that helps to reproduce the problem.
      User must clicks on the window:

      • in case of the Windows OS the result is: popup appears as expected.
      • in case of the Mac OS X the result is: popup blinks.

      I traced this behavior into the Qt library and found some weird code:

      void QApplication::setActiveWindow(QWidget* act)
      {
          QWidget* window = act?act->window():0;
      
          if (QApplicationPrivate::active_window == window)
              return;
      
      #ifndef QT_NO_GRAPHICSVIEW
          if (window && window->graphicsProxyWidget()) {
              // Activate the proxy's view->viewport() ?
              return;
          }
      #endif
      
          QWidgetList toBeActivated;
          QWidgetList toBeDeactivated;
      
          if (QApplicationPrivate::active_window) {
              if (style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, QApplicationPrivate::active_window)) {
                  QWidgetList list = topLevelWidgets();
                  for (int i = 0; i < list.size(); ++i) {
                      QWidget *w = list.at(i);
                      if (w->isVisible() && w->isActiveWindow())
                          toBeDeactivated.append(w);
                  }
              } else {
                  toBeDeactivated.append(QApplicationPrivate::active_window);
              }
          }
      
          if (QApplicationPrivate::focus_widget) {
              if (QApplicationPrivate::focus_widget->testAttribute(Qt::WA_InputMethodEnabled))
                  QGuiApplication::inputMethod()->commit();
      
              QFocusEvent focusAboutToChange(QEvent::FocusAboutToChange, Qt::ActiveWindowFocusReason);
              QApplication::sendEvent(QApplicationPrivate::focus_widget, &focusAboutToChange);
          }
      
          QApplicationPrivate::active_window = window;
      
          if (QApplicationPrivate::active_window) {
              if (style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, QApplicationPrivate::active_window)) {
                  QWidgetList list = topLevelWidgets();
                  for (int i = 0; i < list.size(); ++i) {
                      QWidget *w = list.at(i);
                      if (w->isVisible() && w->isActiveWindow())
                          toBeActivated.append(w);
                  }
              } else {
                  toBeActivated.append(QApplicationPrivate::active_window);
              }
      
          }
      
          // first the activation/deactivation events
          QEvent activationChange(QEvent::ActivationChange);
          QEvent windowActivate(QEvent::WindowActivate);
          QEvent windowDeactivate(QEvent::WindowDeactivate);
      
          for (int i = 0; i < toBeActivated.size(); ++i) {
              QWidget *w = toBeActivated.at(i);
              sendSpontaneousEvent(w, &windowActivate);
              sendSpontaneousEvent(w, &activationChange);
          }
      
          for(int i = 0; i < toBeDeactivated.size(); ++i) {
              QWidget *w = toBeDeactivated.at(i);
              sendSpontaneousEvent(w, &windowDeactivate);
              sendSpontaneousEvent(w, &activationChange);
          }
      
          if (QApplicationPrivate::popupWidgets == 0) { // !inPopupMode()
              // then focus events
              if (!QApplicationPrivate::active_window && QApplicationPrivate::focus_widget) {
                  QApplicationPrivate::setFocusWidget(0, Qt::ActiveWindowFocusReason);
              } else if (QApplicationPrivate::active_window) {
                  QWidget *w = QApplicationPrivate::active_window->focusWidget();
                  if (w && w->isVisible() /*&& w->focusPolicy() != QWidget::NoFocus*/)
                      w->setFocus(Qt::ActiveWindowFocusReason);
                  else {
                      w = QApplicationPrivate::focusNextPrevChild_helper(QApplicationPrivate::active_window, true);
                      if (w) {
                          w->setFocus(Qt::ActiveWindowFocusReason);
                      } else {
                          // If the focus widget is not in the activate_window, clear the focus
                          w = QApplicationPrivate::focus_widget;
                          if (!w && QApplicationPrivate::active_window->focusPolicy() != Qt::NoFocus)
                              QApplicationPrivate::setFocusWidget(QApplicationPrivate::active_window, Qt::ActiveWindowFocusReason);
                          else if (!QApplicationPrivate::active_window->isAncestorOf(w))
                              QApplicationPrivate::setFocusWidget(0, Qt::ActiveWindowFocusReason);
                      }
                  }
              }
          }
      }
      

      A popup window is contained in both lists (toBeActivated and toBeDeactivated) in case of the user clicks (see attachment application as example). I think it is a mistake. But I don't have an idea how to avoid this problem.

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

            sorvig Morten Sørvig
            wiz29 Alexander
            Veli-Pekka Heinonen Veli-Pekka Heinonen
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:

                There are no open Gerrit changes