diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b5984c6b65..510350221e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4181,6 +4181,31 @@ static inline bool isKeyEvent(QEvent::Type type) { return type == QEvent::KeyPress || type == QEvent::KeyRelease; } +bool Application::handleInputMethodEventForFocusedEntity(QEvent* event) { + if (_keyboardFocusedEntity.get() != UNKNOWN_ENTITY_ID) { + switch (event->type()) { + case QEvent::InputMethod: + case QEvent::InputMethodQuery: + { + auto eventHandler = getEntities()->getEventHandler(_keyboardFocusedEntity.get()); + if (eventHandler) { + event->setAccepted(false); + QCoreApplication::sendEvent(eventHandler, event); + if (event->isAccepted()) { + _lastAcceptedKeyPress = usecTimestampNow(); + return true; + } + } + break; + } + default: + break; + } + } + + return false; +} + bool Application::handleKeyEventForFocusedEntity(QEvent* event) { if (_keyboardFocusedEntity.get() != UNKNOWN_ENTITY_ID) { switch (event->type()) { @@ -4241,6 +4266,10 @@ bool Application::event(QEvent* event) { return false; } + if ((event->type() == QEvent::InputMethod || event->type() == QEvent::InputMethodQuery) && handleInputMethodEventForFocusedEntity(event)) { + return true; + } + // Allow focused Entities to handle keyboard input if (isKeyEvent(event->type()) && handleKeyEventForFocusedEntity(event)) { return true; diff --git a/interface/src/Application.h b/interface/src/Application.h index 005ec3cb18..bfd3aa6ac2 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -565,6 +565,7 @@ private: bool initMenu(); void pauseUntilLoginDetermined(); void resumeAfterLoginDialogActionTaken(); + bool handleInputMethodEventForFocusedEntity(QEvent* event); bool handleKeyEventForFocusedEntity(QEvent* event); bool handleFileOpenEvent(QFileOpenEvent* event); void cleanupBeforeQuit(); diff --git a/libraries/gl/src/gl/GLWidget.cpp b/libraries/gl/src/gl/GLWidget.cpp index 45c8e70659..078737443c 100644 --- a/libraries/gl/src/gl/GLWidget.cpp +++ b/libraries/gl/src/gl/GLWidget.cpp @@ -39,6 +39,7 @@ GLWidget::GLWidget() { setAttribute(Qt::WA_NativeWindow); setAttribute(Qt::WA_PaintOnScreen); setAttribute(Qt::WA_NoSystemBackground); + setAttribute(Qt::WA_InputMethodEnabled); setAutoFillBackground(false); grabGesture(Qt::PinchGesture); setAcceptDrops(true); @@ -84,6 +85,17 @@ void GLWidget::doneCurrent() { _context->doneCurrent(); } +QVariant GLWidget::inputMethodQuery(Qt::InputMethodQuery query) const { + // TODO: for now we just use top left corner for an IME popup location, but in the future its position could be calculated + // for a given entry field. + if (query == Qt::ImCursorRectangle) { + int x = 50; + int y = 50; + return QRect(x, y, 10, 10); + } + return QWidget::inputMethodQuery(query); +} + bool GLWidget::event(QEvent* event) { switch (event->type()) { case QEvent::MouseMove: @@ -106,6 +118,16 @@ bool GLWidget::event(QEvent* event) { return true; } break; + case QEvent::InputMethod: + if (QCoreApplication::sendEvent(QCoreApplication::instance(), event)) { + return true; + } + break; + case QEvent::InputMethodQuery: + if (QCoreApplication::sendEvent(QCoreApplication::instance(), event)) { + return true; + } + break; default: break; diff --git a/libraries/gl/src/gl/GLWidget.h b/libraries/gl/src/gl/GLWidget.h index 9d5c8800bb..0d8b23cd0a 100644 --- a/libraries/gl/src/gl/GLWidget.h +++ b/libraries/gl/src/gl/GLWidget.h @@ -35,7 +35,7 @@ public: void swapBuffers(); gl::Context* context() { return _context; } QOpenGLContext* qglContext(); - + virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const override; protected: virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result) override; diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index 07376cf761..143a472722 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -1145,6 +1145,12 @@ bool OffscreenUi::eventFilter(QObject* originalDestination, QEvent* event) { } break; } + case QEvent::InputMethod: + case QEvent::InputMethodQuery: + if (QCoreApplication::sendEvent(getWindow(), event)) { + return result; + } + break; default: break; }