Merge pull request #7627 from jherico/qml_key_interaction

Suppress key release events for presses that were absorbed by QML
This commit is contained in:
Brad Hefta-Gaub 2016-04-11 09:31:46 -07:00
commit a204b9d923
4 changed files with 47 additions and 2 deletions

View file

@ -569,7 +569,7 @@ QPointF OffscreenQmlSurface::mapToVirtualScreen(const QPointF& originalPoint, QO
// Event handling customization
//
bool OffscreenQmlSurface::eventFilter(QObject* originalDestination, QEvent* event) {
bool OffscreenQmlSurface::filterEnabled(QObject* originalDestination, QEvent* event) const {
if (_renderer->_quickWindow == originalDestination) {
return false;
}
@ -577,7 +577,13 @@ bool OffscreenQmlSurface::eventFilter(QObject* originalDestination, QEvent* even
if (_paused) {
return false;
}
return true;
}
bool OffscreenQmlSurface::eventFilter(QObject* originalDestination, QEvent* event) {
if (!filterEnabled(originalDestination, event)) {
return false;
}
#ifdef DEBUG
// Don't intercept our own events, or we enter an infinite recursion
QObject* recurseTest = originalDestination;

View file

@ -66,7 +66,7 @@ public:
QQmlContext* getRootContext();
QPointF mapToVirtualScreen(const QPointF& originalPoint, QObject* originalWidget);
virtual bool eventFilter(QObject* originalDestination, QEvent* event);
bool eventFilter(QObject* originalDestination, QEvent* event) override;
signals:
void textureUpdated(unsigned int texture);
@ -76,6 +76,9 @@ public slots:
void requestRender();
void onAboutToQuit();
protected:
bool filterEnabled(QObject* originalDestination, QEvent* event) const;
private:
QObject* finishQmlLoad(std::function<void(QQmlContext*, QObject*)> f);
QPointF mapWindowToUi(const QPointF& sourcePosition, QObject* sourceObject);

View file

@ -563,5 +563,38 @@ QString OffscreenUi::getSaveFileName(void* ignored, const QString &caption, cons
return DependencyManager::get<OffscreenUi>()->fileSaveDialog(caption, dir, filter, selectedFilter, options);
}
bool OffscreenUi::eventFilter(QObject* originalDestination, QEvent* event) {
if (!filterEnabled(originalDestination, event)) {
return false;
}
// let the parent class do it's work
bool result = OffscreenQmlSurface::eventFilter(originalDestination, event);
// Check if this is a key press/release event that might need special attention
auto type = event->type();
if (type != QEvent::KeyPress && type != QEvent::KeyRelease) {
return result;
}
QKeyEvent* keyEvent = dynamic_cast<QKeyEvent*>(event);
bool& pressed = _pressedKeys[keyEvent->key()];
// Keep track of which key press events the QML has accepted
if (result && QEvent::KeyPress == type) {
pressed = true;
}
// QML input elements absorb key press, but apparently not key release.
// therefore we want to ensure that key release events for key presses that were
// accepted by the QML layer are suppressed
if (!result && type == QEvent::KeyRelease && pressed) {
pressed = false;
return true;
}
return result;
}
#include "OffscreenUi.moc"

View file

@ -12,6 +12,7 @@
#ifndef hifi_OffscreenUi_h
#define hifi_OffscreenUi_h
#include <unordered_map>
#include <QtCore/QVariant>
#include <QtWidgets/QFileDialog>
#include <QtWidgets/QMessageBox>
@ -37,6 +38,7 @@ public:
void setNavigationFocused(bool focused);
void unfocusWindows();
void toggleMenu(const QPoint& screenCoordinates);
bool eventFilter(QObject* originalDestination, QEvent* event) override;
QQuickItem* getDesktop();
QQuickItem* getToolWindow();
@ -131,6 +133,7 @@ private:
QQuickItem* _desktop { nullptr };
QQuickItem* _toolWindow { nullptr };
std::unordered_map<int, bool> _pressedKeys;
};
#endif