Mercurial > hg > svapp
changeset 354:4969e7921931 tonioni
Fix single-key menu shortcuts on OS/X (for #890)
author | Chris Cannam |
---|---|
date | Mon, 02 Jun 2014 17:32:08 +0100 |
parents | 5a66f4e5a3dc |
children | e7a3fa8f4eec 42a5801da931 |
files | framework/MainWindowBase.cpp framework/MainWindowBase.h |
diffstat | 2 files changed, 72 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/framework/MainWindowBase.cpp Thu May 29 16:27:52 2014 +0100 +++ b/framework/MainWindowBase.cpp Mon Jun 02 17:32:08 2014 +0100 @@ -99,6 +99,7 @@ #include <QRegExp> #include <QScrollArea> #include <QDesktopWidget> +#include <QSignalMapper> #include <iostream> #include <cstdio> @@ -270,6 +271,70 @@ } void +MainWindowBase::finaliseMenus() +{ + QMenuBar *mb = menuBar(); + QList<QMenu *> menus = mb->findChildren<QMenu *>(); + foreach (QMenu *menu, menus) { + if (menu) finaliseMenu(menu); + } +} + +void +MainWindowBase::finaliseMenu(QMenu *menu) +{ +#ifdef Q_OS_MAC + // See https://bugreports.qt-project.org/browse/QTBUG-38256 and + // our issue #890 http://code.soundsoftware.ac.uk/issues/890 -- + // single-key shortcuts that are associated only with a menu + // action do not work with Qt 5.x under OS/X. + // + // Apparently Cocoa never handled them as a matter of course, but + // earlier versions of Qt picked them up as widget shortcuts and + // handled them anyway. That behaviour was removed to fix a crash + // when invoking a menu while its window was overridden by a modal + // dialog (https://bugreports.qt-project.org/browse/QTBUG-30657). + // + // This workaround restores the single-key shortcut behaviour by + // searching for single-key shortcuts in menus and replacing them + // with global application shortcuts that invoke the relevant + // actions, testing whether the actions are enabled on invocation. + // As it happens, it also replaces some shortcuts that were + // working fine (because they were also associated with toolbar + // buttons) but that seems to be OK so long as we remove the + // shortcuts from the actions as well as adding the new global + // shortcuts, to avoid an ambiguous shortcut error. + // + // If the Qt developers ever fix this in Qt (I couldn't think of + // an obvious fix myself) then presumably we can remove this. + + QSignalMapper *mapper = new QSignalMapper(this); + + connect(mapper, SIGNAL(mapped(QObject *)), + this, SLOT(menuActionMapperInvoked(QObject *))); + + foreach (QAction *a, menu->actions()) { + QKeySequence sc = a->shortcut(); + if (sc.count() == 1 && !(sc[0] & Qt::KeyboardModifierMask)) { + QShortcut *newSc = new QShortcut(sc, a->parentWidget()); + QObject::connect(newSc, SIGNAL(activated()), mapper, SLOT(map())); + mapper->setMapping(newSc, a); + a->setShortcut(QKeySequence()); // avoid ambiguous shortcut error + } + } +#endif +} + +void +MainWindowBase::menuActionMapperInvoked(QObject *o) +{ + QAction *a = qobject_cast<QAction *>(o); + if (a && a->isEnabled()) { + a->trigger(); + } +} + +void MainWindowBase::resizeConstrained(QSize size) { QDesktopWidget *desktop = QApplication::desktop();
--- a/framework/MainWindowBase.h Thu May 29 16:27:52 2014 +0100 +++ b/framework/MainWindowBase.h Mon Jun 02 17:32:08 2014 +0100 @@ -284,6 +284,8 @@ virtual void newerVersionAvailable(QString) { } + virtual void menuActionMapperInvoked(QObject *); + protected: QString m_sessionFile; QString m_audioFile; @@ -412,6 +414,11 @@ virtual void updateVisibleRangeDisplay(Pane *p) const = 0; virtual void updatePositionStatusDisplays() const = 0; + // Call this after setting up the menu bar, to fix up single-key + // shortcuts on OS/X + virtual void finaliseMenus(); + virtual void finaliseMenu(QMenu *); + virtual bool shouldCreateNewSessionForRDFAudio(bool *) { return true; } virtual void connectLayerEditDialog(ModelDataTableDialog *dialog);