-
Bug
-
Resolution: Unresolved
-
P2: Important
-
None
-
5.5.0
-
None
-
Mac OS X 10.10.x, Qt 5.5.0, clang, c++11
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.