From ee31bc59bec8b63e681f7fda0e67819458994880 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 24 Sep 2014 13:25:29 +0200 Subject: iOS: don't show popup on call to setVisible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It turns out that setting visibility means whether or not the menu should appear visible in a parent menu, and not to actually show or hide the popup. This means that the only way to show a popup is to call showPopup, which also makes it simpler since we then always get a parent window as argument that we can activate and get a focus object from. Change-Id: Ie3866b5664294f9aa4d694fa422e8116e9c75ced Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosmenu.h | 6 +- src/plugins/platforms/ios/qiosmenu.mm | 116 ++++++++++++++-------------------- 2 files changed, 49 insertions(+), 73 deletions(-) (limited to 'src/plugins/platforms/ios') diff --git a/src/plugins/platforms/ios/qiosmenu.h b/src/plugins/platforms/ios/qiosmenu.h index 37578cdb24..16e1ee5d1f 100644 --- a/src/plugins/platforms/ios/qiosmenu.h +++ b/src/plugins/platforms/ios/qiosmenu.h @@ -126,7 +126,6 @@ private: quintptr m_tag; bool m_enabled; bool m_visible; - bool m_effectiveVisible; QString m_text; MenuType m_menuType; MenuType m_effectiveMenuType; @@ -140,11 +139,10 @@ private: static QIOSMenu *m_currentMenu; void updateVisibility(); - void updateVisibilityUsingUIMenuController(); - void updateVisibilityUsingUIPickerView(); + void toggleShowUsingUIMenuController(bool show); + void toggleShowUsingUIPickerView(bool show); QIOSMenuItemList visibleMenuItems() const; void repositionMenu(); - void hide() { setVisible(false); } }; #endif // QIOSMENU_H diff --git a/src/plugins/platforms/ios/qiosmenu.mm b/src/plugins/platforms/ios/qiosmenu.mm index 431a8879d5..c247c16514 100644 --- a/src/plugins/platforms/ios/qiosmenu.mm +++ b/src/plugins/platforms/ios/qiosmenu.mm @@ -195,12 +195,12 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_"; if (!m_visibleMenuItems.isEmpty()) QIOSMenu::currentMenu()->handleItemSelected(m_visibleMenuItems.at(m_selectedRow)); else - QIOSMenu::currentMenu()->setVisible(false); + QIOSMenu::currentMenu()->dismiss(); } - (void)cancelMenu { - QIOSMenu::currentMenu()->setVisible(false); + QIOSMenu::currentMenu()->dismiss(); } @end @@ -299,8 +299,7 @@ QIOSMenu::QIOSMenu() : QPlatformMenu() , m_tag(0) , m_enabled(true) - , m_visible(false) - , m_effectiveVisible(false) + , m_visible(true) , m_text(QString()) , m_menuType(DefaultMenu) , m_effectiveMenuType(DefaultMenu) @@ -348,29 +347,23 @@ void QIOSMenu::setText(const QString &text) void QIOSMenu::setEnabled(bool enabled) { - if (m_enabled == enabled) - return; - m_enabled = enabled; - updateVisibility(); } -void QIOSMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) +void QIOSMenu::setVisible(bool visible) { - m_parentWindow = const_cast(parentWindow); - m_targetRect = targetRect; - m_targetItem = static_cast(item); - - if (m_parentWindow && !m_parentWindow->isActive()) - m_parentWindow->requestActivate(); + m_visible = visible; +} - setVisible(true); +void QIOSMenu::setMenuType(QPlatformMenu::MenuType type) +{ + m_menuType = type; } void QIOSMenu::handleItemSelected(QIOSMenuItem *menuItem) { emit menuItem->activated(); - setVisible(false); + dismiss(); if (QIOSMenu *menu = menuItem->m_menu) { menu->setMenuType(m_effectiveMenuType); @@ -378,76 +371,61 @@ void QIOSMenu::handleItemSelected(QIOSMenuItem *menuItem) } } -void QIOSMenu::dismiss() -{ - setVisible(false); -} - -void QIOSMenu::setVisible(bool visible) +void QIOSMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) { - if (m_visible == visible) + if (m_currentMenu == this || !m_visible || !m_enabled || !parentWindow) return; - m_visible = visible; - updateVisibility(); -} + emit aboutToShow(); -void QIOSMenu::updateVisibility() -{ - bool visibleAndEnabled = m_visible && m_enabled; - if ((visibleAndEnabled && m_effectiveVisible) || (!visibleAndEnabled && m_currentMenu != this)) - return; + m_parentWindow = const_cast(parentWindow); + m_targetRect = targetRect; + m_targetItem = static_cast(item); - if (visibleAndEnabled && !qApp->focusObject()) { - // Since the menus depend on communicating with a focus object, a focus object is required to show - // the menu. Note that QIOSMenu::showPopup() will activate the parent window (and set a focus object) - // before this function is called, so this should normally be the case. Not having a focus object is only - // expected in a hybrid environment where the first responder can be something else than a QUIView (then - // no QWindow will be active). If the focus object changes while the menu is visible, the menu will hide. - qWarning() << "QIOSMenu: cannot open menu without any active QWindows!"; - return; - } + if (!m_parentWindow->isActive()) + m_parentWindow->requestActivate(); - m_effectiveVisible = visibleAndEnabled; + if (m_currentMenu && m_currentMenu != this) + m_currentMenu->dismiss(); - if (m_effectiveVisible) { - Q_ASSERT(m_currentMenu != this); - if (m_currentMenu) { - // The current implementation allow only one visible - // menu at a time, so close the one currently showing. - m_currentMenu->setVisible(false); - } - - m_currentMenu = this; - m_effectiveMenuType = m_menuType; - connect(qGuiApp, &QGuiApplication::focusObjectChanged, this, &QIOSMenu::hide); - } else { - disconnect(qGuiApp, &QGuiApplication::focusObjectChanged, this, &QIOSMenu::hide); - m_currentMenu = 0; - } + m_currentMenu = this; + m_effectiveMenuType = m_menuType; + connect(qGuiApp, &QGuiApplication::focusObjectChanged, this, &QIOSMenu::dismiss); switch (m_effectiveMenuType) { case EditMenu: - updateVisibilityUsingUIMenuController(); + toggleShowUsingUIMenuController(true); break; default: - updateVisibilityUsingUIPickerView(); + toggleShowUsingUIPickerView(true); break; } - - // Emit the signal after the fact in case a - // receiver opens a new menu when receiving it. - emit (m_effectiveVisible ? aboutToShow() : aboutToHide()); } -void QIOSMenu::setMenuType(QPlatformMenu::MenuType type) +void QIOSMenu::dismiss() { - m_menuType = type; + if (m_currentMenu != this) + return; + + emit aboutToHide(); + + disconnect(qGuiApp, &QGuiApplication::focusObjectChanged, this, &QIOSMenu::dismiss); + + switch (m_effectiveMenuType) { + case EditMenu: + toggleShowUsingUIMenuController(false); + break; + default: + toggleShowUsingUIPickerView(false); + break; + } + + m_currentMenu = 0; } -void QIOSMenu::updateVisibilityUsingUIMenuController() +void QIOSMenu::toggleShowUsingUIMenuController(bool show) { - if (m_effectiveVisible) { + if (show) { Q_ASSERT(!m_menuController); m_menuController = [[QUIMenuController alloc] initWithVisibleMenuItems:visibleMenuItems()]; repositionMenu(); @@ -462,11 +440,11 @@ void QIOSMenu::updateVisibilityUsingUIMenuController() } } -void QIOSMenu::updateVisibilityUsingUIPickerView() +void QIOSMenu::toggleShowUsingUIPickerView(bool show) { static QObject *focusObjectWithPickerView = 0; - if (m_effectiveVisible) { + if (show) { Q_ASSERT(!m_pickerView); m_pickerView = [[QUIPickerView alloc] initWithVisibleMenuItems:visibleMenuItems() selectItem:m_targetItem]; -- cgit v1.2.3