Enable Steam VR text input

This commit is contained in:
Brad Davis 2016-05-18 21:46:30 -07:00
parent ca6e86e767
commit eab611acc0
4 changed files with 84 additions and 2 deletions

View file

@ -396,6 +396,8 @@ void OffscreenQmlSurface::create(QOpenGLContext* shareContext) {
_renderer->_renderControl->_renderWindow = _proxyWindow; _renderer->_renderControl->_renderWindow = _proxyWindow;
connect(_renderer->_quickWindow, &QQuickWindow::focusObjectChanged, this, &OffscreenQmlSurface::onFocusObjectChanged);
// Create a QML engine. // Create a QML engine.
_qmlEngine = new QQmlEngine; _qmlEngine = new QQmlEngine;
if (!_qmlEngine->incubationController()) { if (!_qmlEngine->incubationController()) {
@ -742,3 +744,42 @@ QVariant OffscreenQmlSurface::returnFromUiThread(std::function<QVariant()> funct
return function(); return function();
} }
void OffscreenQmlSurface::onFocusObjectChanged(QObject* object) {
if (!object) {
setFocusText(false);
return;
}
QVariant result;
#if 1
auto invokeResult = QMetaObject::invokeMethod(object, "inputMethodQuery", Q_RETURN_ARG(QVariant, result),
Q_ARG(Qt::InputMethodQuery, Qt::ImEnabled),
Q_ARG(QVariant, QVariant()));
#else
//static const char* INPUT_METHOD_QUERY_METHOD_NAME = "inputMethodQuery(Qt::InputMethodQuery, QVariant)";
static const char* INPUT_METHOD_QUERY_METHOD_NAME = "inputMethodQuery";
auto meta = object->metaObject();
qDebug() << "new focus " << object;
auto index = meta->indexOfMethod(INPUT_METHOD_QUERY_METHOD_NAME);
if (index < 0 || index >= meta->methodCount()) {
setFocusText(false);
return;
}
auto method = meta->method(index);
auto invokeResult = method.invoke(object,
Q_RETURN_ARG(QVariant, result),
Q_ARG(Qt::InputMethodQuery, Qt::ImEnabled),
Q_ARG(QVariant, QVariant()));
#endif
setFocusText(invokeResult && result.toBool());
}
void OffscreenQmlSurface::setFocusText(bool newFocusText) {
if (newFocusText != _focusText) {
_focusText = newFocusText;
emit focusTextChanged(_focusText);
}
}

View file

@ -30,7 +30,7 @@ class OffscreenQmlRenderThread;
class OffscreenQmlSurface : public QObject { class OffscreenQmlSurface : public QObject {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool focusText READ isFocusText NOTIFY focusTextChanged)
public: public:
OffscreenQmlSurface(); OffscreenQmlSurface();
virtual ~OffscreenQmlSurface(); virtual ~OffscreenQmlSurface();
@ -55,6 +55,7 @@ public:
_mouseTranslator = mouseTranslator; _mouseTranslator = mouseTranslator;
} }
bool isFocusText() const { return _focusText; }
void pause(); void pause();
void resume(); void resume();
bool isPaused() const; bool isPaused() const;
@ -70,6 +71,8 @@ public:
signals: signals:
void textureUpdated(unsigned int texture); void textureUpdated(unsigned int texture);
void focusObjectChanged(QObject* newFocus);
void focusTextChanged(bool focusText);
public slots: public slots:
void requestUpdate(); void requestUpdate();
@ -78,6 +81,7 @@ public slots:
protected: protected:
bool filterEnabled(QObject* originalDestination, QEvent* event) const; bool filterEnabled(QObject* originalDestination, QEvent* event) const;
void setFocusText(bool newFocusText);
private: private:
QObject* finishQmlLoad(std::function<void(QQmlContext*, QObject*)> f); QObject* finishQmlLoad(std::function<void(QQmlContext*, QObject*)> f);
@ -85,6 +89,7 @@ private:
private slots: private slots:
void updateQuick(); void updateQuick();
void onFocusObjectChanged(QObject* newFocus);
private: private:
friend class OffscreenQmlRenderThread; friend class OffscreenQmlRenderThread;
@ -97,6 +102,7 @@ private:
bool _render{ false }; bool _render{ false };
bool _polish{ true }; bool _polish{ true };
bool _paused{ true }; bool _paused{ true };
bool _focusText { false };
uint8_t _maxFps{ 60 }; uint8_t _maxFps{ 60 };
MouseTranslator _mouseTranslator{ [](const QPointF& p) { return p.toPoint(); } }; MouseTranslator _mouseTranslator{ [](const QPointF& p) { return p.toPoint(); } };
QWindow* _proxyWindow { nullptr }; QWindow* _proxyWindow { nullptr };

View file

@ -36,12 +36,14 @@ vec3 _trackedDeviceLinearVelocities[vr::k_unMaxTrackedDeviceCount];
vec3 _trackedDeviceAngularVelocities[vr::k_unMaxTrackedDeviceCount]; vec3 _trackedDeviceAngularVelocities[vr::k_unMaxTrackedDeviceCount];
static mat4 _sensorResetMat; static mat4 _sensorResetMat;
static std::array<vr::Hmd_Eye, 2> VR_EYES { { vr::Eye_Left, vr::Eye_Right } }; static std::array<vr::Hmd_Eye, 2> VR_EYES { { vr::Eye_Left, vr::Eye_Right } };
bool _openVrDisplayActive { false };
bool OpenVrDisplayPlugin::isSupported() const { bool OpenVrDisplayPlugin::isSupported() const {
return openVrSupported(); return openVrSupported();
} }
bool OpenVrDisplayPlugin::internalActivate() { bool OpenVrDisplayPlugin::internalActivate() {
_openVrDisplayActive = true;
_container->setIsOptionChecked(StandingHMDSensorMode, true); _container->setIsOptionChecked(StandingHMDSensorMode, true);
if (!_system) { if (!_system) {
@ -94,6 +96,7 @@ bool OpenVrDisplayPlugin::internalActivate() {
void OpenVrDisplayPlugin::internalDeactivate() { void OpenVrDisplayPlugin::internalDeactivate() {
Parent::internalDeactivate(); Parent::internalDeactivate();
_openVrDisplayActive = false;
_container->setIsOptionChecked(StandingHMDSensorMode, false); _container->setIsOptionChecked(StandingHMDSensorMode, false);
if (_system) { if (_system) {
// Invalidate poses. It's fine if someone else sets these shared values, but we're about to stop updating them, and // Invalidate poses. It's fine if someone else sets these shared values, but we're about to stop updating them, and

View file

@ -12,6 +12,7 @@
#include "ViveControllerManager.h" #include "ViveControllerManager.h"
#include <QtCore/QProcessEnvironment> #include <QtCore/QProcessEnvironment>
#include <QtQuick/QQuickWindow>
#include <PerfStat.h> #include <PerfStat.h>
#include <PathUtils.h> #include <PathUtils.h>
@ -22,6 +23,7 @@
#include <NumericalConstants.h> #include <NumericalConstants.h>
#include <plugins/PluginContainer.h> #include <plugins/PluginContainer.h>
#include <UserActivityLogger.h> #include <UserActivityLogger.h>
#include <OffscreenUi.h>
#include <controllers/UserInputMapper.h> #include <controllers/UserInputMapper.h>
@ -55,6 +57,9 @@ bool ViveControllerManager::isSupported() const {
return openVrSupported(); return openVrSupported();
} }
QMetaObject::Connection _focusConnection;
extern bool _openVrDisplayActive;
bool ViveControllerManager::activate() { bool ViveControllerManager::activate() {
InputPlugin::activate(); InputPlugin::activate();
@ -67,7 +72,20 @@ bool ViveControllerManager::activate() {
_system = acquireOpenVrSystem(); _system = acquireOpenVrSystem();
} }
Q_ASSERT(_system); Q_ASSERT(_system);
auto offscreenUi = DependencyManager::get<OffscreenUi>();
_focusConnection = connect(offscreenUi.data(), &OffscreenUi::focusTextChanged, [this](bool focusText) {
if (_openVrDisplayActive) {
auto overlay = vr::VROverlay();
if (overlay) {
if (focusText) {
//virtual EVROverlayError ShowKeyboard( eInputMode, EGamepadTextInputLineMode eLineInputMode, const char *pchDescription, uint32_t unCharMax, const char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue) = 0;
overlay->ShowKeyboard(vr::EGamepadTextInputMode::k_EGamepadTextInputModeNormal, vr::k_EGamepadTextInputLineModeSingleLine, "Test", 1024, "", false, 0);
} else {
overlay->HideKeyboard();
}
}
}
});
// OpenVR provides 3d mesh representations of the controllers // OpenVR provides 3d mesh representations of the controllers
// Disabled controller rendering code // Disabled controller rendering code
/* /*
@ -132,6 +150,8 @@ bool ViveControllerManager::activate() {
void ViveControllerManager::deactivate() { void ViveControllerManager::deactivate() {
InputPlugin::deactivate(); InputPlugin::deactivate();
disconnect(_focusConnection);
_container->removeMenuItem(MENU_NAME, RENDER_CONTROLLERS); _container->removeMenuItem(MENU_NAME, RENDER_CONTROLLERS);
_container->removeMenu(MENU_PATH); _container->removeMenu(MENU_PATH);
@ -220,6 +240,18 @@ void ViveControllerManager::pluginUpdate(float deltaTime, const controller::Inpu
return; return;
} }
vr::VREvent_t vrEvent;
static char textArray[8192];
while (vr::VRSystem()->PollNextEvent(&vrEvent, sizeof(vrEvent))) {
if (vrEvent.eventType == vr::VREvent_KeyboardDone) {
auto chars = vr::VROverlay()->GetKeyboardText(textArray, 8192);
QInputMethodEvent* event = new QInputMethodEvent();
event->setCommitString(QString(QByteArray(textArray, chars)), 0, 0);
auto focusObject = DependencyManager::get<OffscreenUi>()->getWindow()->focusObject();
qApp->postEvent(focusObject, event);
}
}
// because update mutates the internal state we need to lock // because update mutates the internal state we need to lock
userInputMapper->withLock([&, this]() { userInputMapper->withLock([&, this]() {
_inputDevice->update(deltaTime, inputCalibrationData); _inputDevice->update(deltaTime, inputCalibrationData);