QCocoaMenuBar: Update even if no window is attached

Then we need to check if the current active (or focused)
window has any menubar associated. In case there isn't,
and the menubar has no window associated, then we should
update immediately.

The previous condition is still valid.

Change-Id: I4532ccc87354d91c76b53f5433dc3944b9e29584
Task-number: QTBUG-56275
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
This commit is contained in:
Gabriel de Dietrich 2016-09-30 15:39:03 -07:00
parent e2d8c7bf22
commit 9c83d7f871
5 changed files with 101 additions and 1 deletions

View File

@ -70,6 +70,7 @@ private:
static QCocoaWindow *findWindowForMenubar();
static QCocoaMenuBar *findGlobalMenubar();
bool needsImmediateUpdate();
bool shouldDisable(QCocoaWindow *active) const;
NSMenuItem *nativeItemForMenu(QCocoaMenu *menu) const;

View File

@ -89,6 +89,32 @@ QCocoaMenuBar::~QCocoaMenuBar()
}
}
bool QCocoaMenuBar::needsImmediateUpdate()
{
if (m_window && m_window->window()->isActive()) {
return true;
} else if (!m_window) {
// Only update if the focus/active window has no
// menubar, which means it'll be using this menubar.
// This is to avoid a modification in a parentless
// menubar to affect a window-assigned menubar.
QWindow *fw = QGuiApplication::focusWindow();
if (!fw) {
// Same if there's no focus window, BTW.
return true;
} else {
QCocoaWindow *cw = static_cast<QCocoaWindow *>(fw->handle());
if (cw && !cw->menubar())
return true;
}
}
// Either the menubar is attached to a non-active window,
// or the application's focus window has its own menubar
// (which is different from this one)
return false;
}
void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *before)
{
QCocoaMenu *menu = static_cast<QCocoaMenu *>(platformMenu);
@ -129,7 +155,7 @@ void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *befor
syncMenu(menu);
if (m_window && m_window->window()->isActive())
if (needsImmediateUpdate())
updateMenuBarImmediately();
}

View File

@ -2,3 +2,8 @@ CONFIG += testcase
TARGET = tst_qmenubar
QT += widgets testlib
SOURCES += tst_qmenubar.cpp
macos: {
OBJECTIVE_SOURCES += tst_qmenubar_mac.mm
LIBS += -framework AppKit
}

View File

@ -133,6 +133,9 @@ private slots:
void cornerWidgets_data();
void cornerWidgets();
void taskQTBUG53205_crashReparentNested();
#ifdef Q_OS_MACOS
void taskQTBUG56275_reinsertMenuInParentlessQMenuBar();
#endif
protected slots:
void onSimpleActivated( QAction*);
@ -1495,7 +1498,28 @@ void tst_QMenuBar::slotForTaskQTBUG53205()
taskQTBUG53205MenuBar->setParent(parent);
}
#ifdef Q_OS_MACOS
extern bool tst_qmenubar_taskQTBUG56275(QMenuBar *);
void tst_QMenuBar::taskQTBUG56275_reinsertMenuInParentlessQMenuBar()
{
QMenuBar menubar;
QMenu *menu = new QMenu("menu", &menubar);
QMenu* submenu = menu->addMenu("submenu");
submenu->addAction("action1");
submenu->addAction("action2");
menu->addAction("action3");
menubar.addMenu(menu);
QTest::qWait(100);
menubar.clear();
menubar.addMenu(menu);
QTest::qWait(100);
QVERIFY(tst_qmenubar_taskQTBUG56275(&menubar));
}
#endif // Q_OS_MACOS
QTEST_MAIN(tst_QMenuBar)
#include "tst_qmenubar.moc"

View File

@ -0,0 +1,44 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#import <Cocoa/Cocoa.h>
#include <QMenuBar>
#include <QTest>
bool tst_qmenubar_taskQTBUG56275(QMenuBar *menubar)
{
NSMenu *mainMenu = menubar->toNSMenu();
return mainMenu.numberOfItems == 2
&& [[mainMenu itemAtIndex:1].title isEqualToString:@"menu"];
}