comparison framework/MainWindowBase.cpp @ 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 1d8cb0d92f4b
children 337cdb5e5b06 0876ea394902
comparison
equal deleted inserted replaced
353:5a66f4e5a3dc 354:4969e7921931
97 #include <QProcess> 97 #include <QProcess>
98 #include <QCheckBox> 98 #include <QCheckBox>
99 #include <QRegExp> 99 #include <QRegExp>
100 #include <QScrollArea> 100 #include <QScrollArea>
101 #include <QDesktopWidget> 101 #include <QDesktopWidget>
102 #include <QSignalMapper>
102 103
103 #include <iostream> 104 #include <iostream>
104 #include <cstdio> 105 #include <cstdio>
105 #include <errno.h> 106 #include <errno.h>
106 107
265 delete m_viewManager; 266 delete m_viewManager;
266 delete m_oscQueue; 267 delete m_oscQueue;
267 delete m_oscQueueStarter; 268 delete m_oscQueueStarter;
268 delete m_midiInput; 269 delete m_midiInput;
269 Profiles::getInstance()->dump(); 270 Profiles::getInstance()->dump();
271 }
272
273 void
274 MainWindowBase::finaliseMenus()
275 {
276 QMenuBar *mb = menuBar();
277 QList<QMenu *> menus = mb->findChildren<QMenu *>();
278 foreach (QMenu *menu, menus) {
279 if (menu) finaliseMenu(menu);
280 }
281 }
282
283 void
284 MainWindowBase::finaliseMenu(QMenu *menu)
285 {
286 #ifdef Q_OS_MAC
287 // See https://bugreports.qt-project.org/browse/QTBUG-38256 and
288 // our issue #890 http://code.soundsoftware.ac.uk/issues/890 --
289 // single-key shortcuts that are associated only with a menu
290 // action do not work with Qt 5.x under OS/X.
291 //
292 // Apparently Cocoa never handled them as a matter of course, but
293 // earlier versions of Qt picked them up as widget shortcuts and
294 // handled them anyway. That behaviour was removed to fix a crash
295 // when invoking a menu while its window was overridden by a modal
296 // dialog (https://bugreports.qt-project.org/browse/QTBUG-30657).
297 //
298 // This workaround restores the single-key shortcut behaviour by
299 // searching for single-key shortcuts in menus and replacing them
300 // with global application shortcuts that invoke the relevant
301 // actions, testing whether the actions are enabled on invocation.
302 // As it happens, it also replaces some shortcuts that were
303 // working fine (because they were also associated with toolbar
304 // buttons) but that seems to be OK so long as we remove the
305 // shortcuts from the actions as well as adding the new global
306 // shortcuts, to avoid an ambiguous shortcut error.
307 //
308 // If the Qt developers ever fix this in Qt (I couldn't think of
309 // an obvious fix myself) then presumably we can remove this.
310
311 QSignalMapper *mapper = new QSignalMapper(this);
312
313 connect(mapper, SIGNAL(mapped(QObject *)),
314 this, SLOT(menuActionMapperInvoked(QObject *)));
315
316 foreach (QAction *a, menu->actions()) {
317 QKeySequence sc = a->shortcut();
318 if (sc.count() == 1 && !(sc[0] & Qt::KeyboardModifierMask)) {
319 QShortcut *newSc = new QShortcut(sc, a->parentWidget());
320 QObject::connect(newSc, SIGNAL(activated()), mapper, SLOT(map()));
321 mapper->setMapping(newSc, a);
322 a->setShortcut(QKeySequence()); // avoid ambiguous shortcut error
323 }
324 }
325 #endif
326 }
327
328 void
329 MainWindowBase::menuActionMapperInvoked(QObject *o)
330 {
331 QAction *a = qobject_cast<QAction *>(o);
332 if (a && a->isEnabled()) {
333 a->trigger();
334 }
270 } 335 }
271 336
272 void 337 void
273 MainWindowBase::resizeConstrained(QSize size) 338 MainWindowBase::resizeConstrained(QSize size)
274 { 339 {