From 801be7edee99278d3fccf53a8a7626c18ddd641c Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Wed, 9 Jul 2014 13:55:38 +0200 Subject: [PATCH] Stop QMenuBar to steal keyboard focus when pressing Alt key in Linux. --- interface/src/Application.cpp | 2 ++ interface/src/GLCanvas.cpp | 36 +++++++++++++++++++++++++++++++++++ interface/src/GLCanvas.h | 1 + 3 files changed, 39 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ace265ad4f..95cfaab4cf 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -803,6 +803,7 @@ bool Application::event(QEvent* event) { } void Application::keyPressEvent(QKeyEvent* event) { + qDebug("Application::keyPressEvent(%x)", event->key()); _keysPressed.insert(event->key()); @@ -1053,6 +1054,7 @@ void Application::keyPressEvent(QKeyEvent* event) { } void Application::keyReleaseEvent(QKeyEvent* event) { + qDebug("Application::keyReleaseEvent(%x)", event->key()); _keysPressed.remove(event->key()); diff --git a/interface/src/GLCanvas.cpp b/interface/src/GLCanvas.cpp index 17026b5d5c..87c1016c5e 100644 --- a/interface/src/GLCanvas.cpp +++ b/interface/src/GLCanvas.cpp @@ -23,6 +23,11 @@ GLCanvas::GLCanvas() : QGLWidget(QGLFormat(QGL::NoDepthBuffer)), _throttleRendering(false), _idleRenderInterval(MSECS_PER_FRAME_WHEN_THROTTLED) { +#ifdef Q_OS_LINUX + // Cause GLCanvas::eventFilter to be called. + // It wouldn't hurt to do this on Mac and PC too; but apparently it's only needed on linux. + qApp->installEventFilter(this); +#endif } bool GLCanvas::isThrottleRendering() const { @@ -162,3 +167,34 @@ void GLCanvas::dragEnterEvent(QDragEnterEvent* event) { void GLCanvas::dropEvent(QDropEvent* event) { Application::getInstance()->dropEvent(event); } + +// Pressing Alt (and Meta) key alone activates the menubar because its style inherits the +// SHMenuBarAltKeyNavigation from QWindowsStyle. This makes it impossible for a scripts to +// receive keyPress events for the Alt (and Meta) key in a reliable manner. +// +// This filter catches events before QMenuBar can steal the keyboard focus. +// The idea was borrowed from +// http://www.archivum.info/qt-interest@trolltech.com/2006-09/00053/Re-(Qt4)-Alt-key-focus-QMenuBar-(solved).html + +bool GLCanvas::eventFilter(QObject*, QEvent* event) { + switch (event->type()) { + case QEvent::KeyPress: + case QEvent::KeyRelease: + case QEvent::ShortcutOverride: + { + QKeyEvent* keyEvent = static_cast(event); + if (keyEvent->key() == Qt::Key_Alt || keyEvent->key() == Qt::Key_Meta) { + if (event->type() == QEvent::KeyPress) + keyPressEvent(keyEvent); + else if (event->type() == QEvent::KeyRelease) + keyReleaseEvent(keyEvent); + else + QGLWidget::event(event); + return true; + } + } + default: + break; + } + return false; +} diff --git a/interface/src/GLCanvas.h b/interface/src/GLCanvas.h index 024cd615ae..773fcb5c27 100644 --- a/interface/src/GLCanvas.h +++ b/interface/src/GLCanvas.h @@ -50,6 +50,7 @@ protected: private slots: void activeChanged(Qt::ApplicationState state); void throttleRender(); + bool eventFilter(QObject*, QEvent* event); }; #endif // hifi_GLCanvas_h