5#include <QtCore/private/qnapi_p.h>
6#include <qohosjsenv_p.h>
7#include <QtCore/private/qohoslogger_p.h>
8#include <QtCore/qnamespace.h>
9#include <QtGui/private/qhighdpiscaling_p.h>
13#include <QtCore/qrect.h>
14#include <QtGui/qinputdevice.h>
15#include <QtGui/qguiapplication.h>
16#include <QtGui/qtextformat.h>
18#include <qohosjsutils.h>
19#include <inputmethod/inputmethod_controller_capi.h>
28using InsertedTextId = QtOhos::TypedId<std::uint64_t,
struct InsertedTextIdTag>;
35 InsertedTextId
id()
const;
57 JsInputMethodInsertedTextComposer() =
default;
58 void initOrIncrementId();
60 std::optional<InsertedTextId> m_id;
91 if (!m_id.has_value()) {
92 m_id = InsertedTextId(0);
94 auto oldValue = m_id.value().value();
95 m_id = InsertedTextId(++oldValue);
102 return QOhosInsertedText(text, m_id.value());
107 using TextInputType = ::InputMethod_TextInputType;
108 if (hints & Qt::ImhMultiLine) {
109 return TextInputType::IME_TEXT_INPUT_TYPE_MULTILINE;
110 }
else if (hints & Qt::ImhDigitsOnly) {
111 return (hints & Qt::ImhHiddenText)
112 ? TextInputType::IME_TEXT_INPUT_TYPE_NUMBER_PASSWORD
113 : TextInputType::IME_TEXT_INPUT_TYPE_NUMBER;
114 }
else if (hints & Qt::ImhDialableCharactersOnly) {
115 return TextInputType::IME_TEXT_INPUT_TYPE_PHONE;
116 }
else if (hints & (Qt::ImhDate | Qt::ImhTime)) {
117 return TextInputType::IME_TEXT_INPUT_TYPE_DATETIME;
118 }
else if (hints & Qt::ImhEmailCharactersOnly) {
119 return TextInputType::IME_TEXT_INPUT_TYPE_EMAIL_ADDRESS;
120 }
else if (hints & Qt::ImhUrlCharactersOnly) {
121 return TextInputType::IME_TEXT_INPUT_TYPE_URL;
122 }
else if (hints & Qt::ImhHiddenText) {
123 return TextInputType::IME_TEXT_INPUT_TYPE_VISIBLE_PASSWORD;
125 return TextInputType::IME_TEXT_INPUT_TYPE_TEXT;
132 case ::InputMethod_Direction::IME_DIRECTION_NONE:
134 case ::InputMethod_Direction::IME_DIRECTION_UP:
136 case ::InputMethod_Direction::IME_DIRECTION_DOWN:
138 case ::InputMethod_Direction::IME_DIRECTION_LEFT:
140 case ::InputMethod_Direction::IME_DIRECTION_RIGHT:
148 switch (qtEnterKeyType) {
149 case Qt::EnterKeyType::EnterKeyReturn:
150 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_NEWLINE;
151 case Qt::EnterKeyType::EnterKeyDone:
152 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_DONE;
153 case Qt::EnterKeyType::EnterKeyGo:
154 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_GO;
155 case Qt::EnterKeyType::EnterKeySend:
156 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_SEND;
157 case Qt::EnterKeyType::EnterKeySearch:
158 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_SEARCH;
159 case Qt::EnterKeyType::EnterKeyNext:
160 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_NEXT;
161 case Qt::EnterKeyType::EnterKeyPrevious:
162 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_PREVIOUS;
163 case Qt::EnterKeyType::EnterKeyDefault:
164 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_NONE;
167 "%s: Cannot map Qt::EnterKeyType to OHOS value. Returning ::InputMethod_EnterKeyType::IME_ENTER_KEY_UNSPECIFIED",
169 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_UNSPECIFIED;
173 QOhosInputContext::RequestKeyboardReason qtRequestKeyboardReason)
175 switch (qtRequestKeyboardReason) {
176 case QOhosInputContext::RequestKeyboardReason::NONE:
177 return ::InputMethod_RequestKeyboardReason::IME_REQUEST_REASON_NONE;
178 case QOhosInputContext::RequestKeyboardReason::MOUSE:
179 return ::InputMethod_RequestKeyboardReason::IME_REQUEST_REASON_MOUSE;
180 case QOhosInputContext::RequestKeyboardReason::TOUCH:
181 return ::InputMethod_RequestKeyboardReason::IME_REQUEST_REASON_TOUCH;
182 case QOhosInputContext::RequestKeyboardReason::OTHER:
183 return ::InputMethod_RequestKeyboardReason::IME_REQUEST_REASON_OTHER;
186 "%s: Cannot map QOhosInputContext::RequestKeyboardReason to OHOS value. Returning ::InputMethod_RequestKeyboardReason::IME_REQUEST_REASON_NONE",
188 return ::InputMethod_RequestKeyboardReason::IME_REQUEST_REASON_NONE;
194 const auto value = query->value(property).toInt(&converted);
195 return converted ?
std::optional(value) :
std::nullopt;
201 if (!lastInsertedTextId.has_value()) {
202 qOhosPrintfError(
"%s: JsInputMethodInsertedTextComposer has no last inserted text ID", Q_FUNC_INFO);
206 auto currentInsertedTextId = insertedText.id();
207 if (currentInsertedTextId != lastInsertedTextId.value()) {
209 "%s: inserted text and one currently processed differ from each other, system won't be notified with changeSelection()", Q_FUNC_INFO);
214 [&](
QtOhos::
JsState &jsState, QOhosTaskPromise<> taskPromise) {
215 auto startPosition = cursorPosition;
216 auto endPosition = cursorPosition + insertedText
.text().length();
217 jsState.evalToPromiseOrRejectOnThrow(
218 "@ohos.inputMethod.getController().changeSelection(*)", {insertedText
.text(), startPosition, endPosition})
219 .onCatch(QtOhos::makeErrorLoggingJsCallback(
"changeSelection()"))
220 .onFinally(
std::move(taskPromise).makeChained(Q_FUNC_INFO));
227 int x = qBound(rect.left(), p.x(), rect.right());
228 int y = qBound(rect.top(), p.y(), rect.bottom());
234 auto *focusObject = QGuiApplication::focusObject();
238 QInputMethodQueryEvent directEvent(Qt::ImTextBeforeCursor | Qt::ImTextAfterCursor);
239 QCoreApplication::sendEvent(focusObject, &directEvent);
241 const auto textBeforeCursorResult = directEvent.value(Qt::ImTextBeforeCursor);
242 const auto textAfterCursorResult = directEvent.value(Qt::ImTextAfterCursor);
243 if (textBeforeCursorResult.canConvert<QString>() && textAfterCursorResult.canConvert<QString>())
244 return {textBeforeCursorResult.toString(), textAfterCursorResult.toString()};
246 QInputMethodQueryEvent fallbackEvent(Qt::ImSurroundingText | Qt::ImCursorPosition);
247 QCoreApplication::sendEvent(focusObject, &fallbackEvent);
249 const auto surroundingTextResult = fallbackEvent.value(Qt::ImSurroundingText);
250 const auto cursorPositionResult = fallbackEvent.value(Qt::ImCursorPosition);
252 if (!surroundingTextResult.canConvert<QString>() || !cursorPositionResult.canConvert<
int>())
255 const auto cursorPos = cursorPositionResult.toInt();
259 const QString text = surroundingTextResult.toString();
260 return {text.left(cursorPos), text.mid(cursorPos)};
268 , m_qtImEnabled(
false)
275 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::QOhosInputContext");
278 QGuiApplication::inputMethod(), &QInputMethod::cursorRectangleChanged,
279 this, &QOhosInputContext::onCursorRectangleChanged);
281 QGuiApplication::instance()->installEventFilter(
this);
288 if (m_imConnectionState == ImConnectionState::Attached) {
289 setImConnectionState(ImConnectionState::Detached);
290 setImConnectionState(ImConnectionState::Attached);
296 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::commit");
298 auto preeditText = std::exchange(m_pendingPreeditText, {});
300 QInputMethodEvent event;
301 event.setCommitString(preeditText);
302 sendFocusObjectInputMethodEvent(&event);
307 if (!focusObjectOrNull()) {
312 m_qtImEnabled = queryImEnabled();
313 const auto qtInputMethodHintsValue = queryInputMethodHints();
314 const auto qtEnterKeyTypeValue = queryEnterKeyType();
316 const bool imStateChanged =
317 m_qtInputMethodHints != qtInputMethodHintsValue
318 || m_qtEnterKeyType != qtEnterKeyTypeValue;
320 auto imAlreadyAttached = m_imConnectionState == ImConnectionState::Attached;
321 if (imAlreadyAttached && imStateChanged)
322 updateInputMethodControllerAttributes(qtInputMethodHintsValue, qtEnterKeyTypeValue);
324 m_qtInputMethodHints = qtInputMethodHintsValue;
325 m_qtEnterKeyType = qtEnterKeyTypeValue;
327 if (inputMethodAccepted() && m_qtImEnabled) {
328 if (imAlreadyAttached)
329 pushTextAroundCursorToProxy();
331 auto updateCausedByWidgetTransform = queries == Qt::ImInputItemClipRectangle;
332 auto updateCausedByQueryAllImParameters = queries == Qt::ImQueryAll;
334 if (updateCausedByQueryAllImParameters)
337 if (!updateCausedByWidgetTransform || !imAlreadyAttached) {
347 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::invokeAction");
352 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::keyboardRect");
358 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::isAnimating");
364 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::showInputPanel");
365 setImConnectionState(ImConnectionState::Attached);
370 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::hideInputPanel");
371 setImConnectionState(ImConnectionState::Detached);
376 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::isInputPanelVisible");
377 return m_imConnectionRequestedState == ImConnectionState::Attached;
382 m_focusObject = object;
387 return m_focusObject;
392 if (requestedState != m_imConnectionRequestedState) {
393 setImConnectionStateImpl(requestedState);
395 if (m_imConnectionState == ImConnectionState::Attached && !m_softwareKeyboardVisible)
400void QOhosInputContext::setImConnectionStateImpl(ImConnectionState requestedState)
402 m_imConnectionRequestedState = m_qtImEnabled ? requestedState : ImConnectionState::Detached;
404 if (!m_imConnectionRequestActive) {
405 m_imConnectionRequestActive =
true;
407 dispatchRequestedImStateChange(requestedState);
411void QOhosInputContext::dispatchRequestedImStateChange(ImConnectionState requestedState)
414 if (requestedState == ImConnectionState::Attached)
415 result = attachToInputMethodController();
417 result = detachFromInputMethodController();
418 handleRequestedImConnectionState(requestedState, result);
423 class ImCallbacks :
public QOhosInputMethodProxy::ClientCallbacks
427 : m_inputContext(inputContext)
432 void onInsertText(
std::string text)
override
434 m_inputContext.sendInsertedTextToQt(
std::move(text));
437 void onInsertPreviewText(
std::string previewText)
override
439 m_inputContext.sendInsertedPreviewTextToQt(
std::move(previewText));
442 void onFinishPreviewText()
override
447 void onDeleteForward(
int length)
override
449 m_inputContext.sendFocusObjectFunctionalKeyEvent(Qt::Key_Delete, QStringLiteral(
"\u007F"), length);
452 void onDeleteBackward(
int length)
override
454 m_inputContext.sendFocusObjectFunctionalKeyEvent(Qt::Key_Backspace, QStringLiteral(
"\u0008"), length);
457 void onSendKeyboardStatus(::InputMethod_KeyboardStatus keyboardStatus)
override
459 bool ohosKeyboardShown = keyboardStatus == ::InputMethod_KeyboardStatus::IME_KEYBOARD_STATUS_SHOW;
463 void onSendEnterKey(::InputMethod_EnterKeyType)
override
465 m_inputContext.sendFocusObjectFunctionalKeyEvent(Qt::Key_Enter, QStringLiteral(
"\u000D"));
468 void onMoveCursor(::InputMethod_Direction direction)
override
470 auto qtDirection = tryMapInputMethodDirectionToQt(direction);
471 if (!qtDirection.has_value()) {
473 "got unsupported InputMethod_Direction value (%d), cursor won't be moved!",
474 static_cast<
int>(direction));
478 m_inputContext.sendCursorMoveToQt(qtDirection.value());
485 qOhosPrintfWarning(
"%s: proxy already exists!", Q_FUNC_INFO);
487 m_imProxy = std::make_shared<QOhosInputMethodProxy>(
488 std::make_shared<ImCallbacks>(*
this),
489 mapQtToOhosImeRequestReason(
490 m_lastInputTypeToTriggerSoftKeyboard.value_or(RequestKeyboardReason::OTHER)));
492 if (m_imProxy->hasAttachedSuccessfully()) {
493 pushTextAroundCursorToProxy();
494 m_imProxy->notifyConfigurationChange(
495 mapQtToOhosImeEnterKeyType(m_qtEnterKeyType),
496 mapQtInputMethodHintsToOhosImeTextInputType(m_qtInputMethodHints));
505 qOhosPrintfWarning(
"%s: proxy doesn't exist!", Q_FUNC_INFO);
511void QOhosInputContext::handleRequestedImConnectionState(ImConnectionState requestedState,
bool success)
513 m_imConnectionRequestActive =
false;
516 qOhosWarning(QtForOhos)
518 << (requestedState == ImConnectionState::Attached ?
"attach to" :
"detach from")
523 m_imConnectionState = requestedState;
525 if (m_imConnectionRequestedState != m_imConnectionState)
526 setImConnectionStateImpl(m_imConnectionRequestedState);
528 onCursorRectangleChanged();
533 if (m_imProxy ==
nullptr) {
534 qOhosPrintfError(
"%s: proxy doesn't exist!", Q_FUNC_INFO);
538 m_imProxy->showTextInput(mapQtToOhosImeRequestReason(
539 m_lastInputTypeToTriggerSoftKeyboard.value_or(RequestKeyboardReason::OTHER)));
544 m_softwareKeyboardVisible = visible;
549 m_lastInputTypeToTriggerSoftKeyboard = inputType;
554 if (m_imConnectionState == ImConnectionState::Detached) {
555 qOhosDebug(QtForOhos) <<
"Cursor rectangle changed while detached; deferring update until attach";
556 m_updateCursorRectangleAfterAttaching =
true;
560 auto *focusedWindow = QGuiApplication::focusWindow();
561 if (focusedWindow ==
nullptr) {
562 qOhosCritical(QtForOhos)
563 <<
"Could not retrieve focused window. Updating cursor position isn't possible";
567 auto focusedWindowPosition = focusedWindow->mapToGlobal(QPoint(0, 0));
568 QRect cursorRectangle = QGuiApplication::inputMethod()->cursorRectangle().toRect();
569 if (!m_updateCursorRectangleAfterAttaching
570 && cursorRectangle == m_lastCursorRectangle
571 && m_lastFocusedWindowPosition == focusedWindowPosition) {
575 m_lastCursorRectangle = cursorRectangle;
576 m_lastFocusedWindowPosition = focusedWindowPosition;
577 auto globalInputItemRectangle =
578 QGuiApplication::inputMethod()->inputItemClipRectangle()
579 .translated(m_lastFocusedWindowPosition)
581 auto globalCursorRectangle = m_lastCursorRectangle.translated(m_lastFocusedWindowPosition);
582 auto inputItemClampedCursorPos = clampToRect(
583 {globalCursorRectangle.x(), globalCursorRectangle.y()},
584 globalInputItemRectangle.isValid()
585 ? globalInputItemRectangle
586 : QRect(focusedWindowPosition, focusedWindow->size()));
587 auto nativeCursorPos = QHighDpiScaling::mapPositionToNative(
588 inputItemClampedCursorPos, focusedWindow->screen()->handle());
589 auto screenBasedCursorPos = nativeCursorPos - focusedWindow->screen()->handle()->geometry().topLeft();
591 screenBasedCursorPos.x(), screenBasedCursorPos.y(),
592 globalCursorRectangle.width(), globalCursorRectangle.height()
594 m_updateCursorRectangleAfterAttaching =
false;
598 Qt::InputMethodHints qtInputMethodHints, Qt::EnterKeyType qtEnterKeyType)
600 if (m_imProxy ==
nullptr) {
601 qOhosPrintfError(
"%s: proxy doesn't exist!", Q_FUNC_INFO);
605 m_imProxy->notifyConfigurationChange(
606 mapQtToOhosImeEnterKeyType(qtEnterKeyType),
607 mapQtInputMethodHintsToOhosImeTextInputType(qtInputMethodHints));
612 if (m_imProxy ==
nullptr) {
613 qOhosPrintfError(
"%s: proxy doesn't exist!", Q_FUNC_INFO);
617 m_imProxy->notifyCursorUpdate(globalCursorRect);
622 if (m_imProxy ==
nullptr) {
623 qOhosPrintfError(
"%s: proxy doesn't exist!", Q_FUNC_INFO);
627 const auto textAroundCursor = queryQtImTextAroundCursorOrEmpty();
628 m_imProxy->setTextAroundCursor(
629 textAroundCursor.first.toStdU16String(),
630 textAroundCursor.second.toStdU16String());
635 if (obj->isWidgetType() && queryImEnabled()) {
636 auto focusReason = event->reason();
637 if (focusReason == Qt::OtherFocusReason || focusReason == Qt::ActiveWindowFocusReason)
638 setLastInputTypeToTriggerSoftKeyboard(RequestKeyboardReason::NONE);
644 if (event->type() == QEvent::FocusIn)
645 handleFocusInEvent(obj,
static_cast<QFocusEvent *>(event));
653 auto query = tryQueryFocusObjectInputMethod(Qt::ImEnabled);
657 if (!query->value(Qt::ImEnabled).toBool()) {
658 qOhosDebug(QtForOhos) <<
"onInsertText(): focus object is not able to handle InputMethod";
662 m_pendingPreeditText.clear();
664 QInputMethodEvent event;
665 event.setCommitString(QString::fromStdString(insertedText.text()));
666 sendFocusObjectInputMethodEvent(&event);
668 auto cursorPosition = tryQueryCursorPosition();
669 if (cursorPosition.has_value())
670 notifyOhosInputMethodAboutPossibleAutocorrection(insertedText, cursorPosition.value());
672 qOhosWarning(QtForOhos) <<
"Couldn't obtain IM cursorPosition";
677 auto query = tryQueryFocusObjectInputMethod(Qt::ImEnabled);
681 if (!query->value(Qt::ImEnabled).toBool()) {
682 qOhosPrintfDebug(
"%s: focus object is not able to handle InputMethod", Q_FUNC_INFO);
686 const QString previewString = QString::fromStdString(previewText);
687 QList<QInputMethodEvent::Attribute> imEventAttributes;
688 if (!previewString.isEmpty()) {
689 QTextCharFormat format;
690 format.setFontUnderline(
true);
691 imEventAttributes.append(
692 QInputMethodEvent::Attribute(
693 QInputMethodEvent::TextFormat, 0, previewString.length(), format));
696 m_pendingPreeditText = previewString;
698 QInputMethodEvent preeditStringEvent(previewString, imEventAttributes);
699 sendFocusObjectInputMethodEvent(&preeditStringEvent);
704 auto *focusObject = focusObjectOrNull();
705 if (focusObject ==
nullptr) {
706 qOhosWarning(QtForOhos) <<
"sendFocusObjectInputMethodEvent(): no focus object to send event to!";
710 QCoreApplication::sendEvent(focusObject, event);
716 case QOhosInputContext::Direction::CURSOR_UP:
717 sendFocusObjectFunctionalKeyEvent(Qt::Key_Up);
719 case QOhosInputContext::Direction::CURSOR_DOWN:
720 sendFocusObjectFunctionalKeyEvent(Qt::Key_Down);
722 case QOhosInputContext::Direction::CURSOR_LEFT:
723 sendFocusObjectFunctionalKeyEvent(Qt::Key_Left);
725 case QOhosInputContext::Direction::CURSOR_RIGHT:
726 sendFocusObjectFunctionalKeyEvent(Qt::Key_Right);
731void QOhosInputContext::sendFocusObjectFunctionalKeyEvent(Qt::Key key,
const QString &keyText,
int repeatCount)
733 auto *focusObject = focusObjectOrNull();
734 if (focusObject ==
nullptr) {
735 qOhosWarning(QtForOhos) <<
"sendFocusObjectFunctionalKeyEvent(): no focus object to send event to!";
739 for (
int i = 0; i < repeatCount; ++i) {
740 QGuiApplication::postEvent(focusObject,
new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier, keyText));
741 QGuiApplication::postEvent(focusObject,
new QKeyEvent(QEvent::KeyRelease, key, Qt::NoModifier, keyText));
747 auto query = tryQueryFocusObjectInputMethod(Qt::ImEnabled);
748 return !query.isNull() && query->value(Qt::ImEnabled).toBool();
753 std::optional<Qt::InputMethodHints> hints;
754 auto query = tryQueryFocusObjectInputMethod(Qt::ImHints);
755 if (!query.isNull()) {
756 auto imHintsInt = tryGetIntPropertyFromQuery(Qt::ImHints, query);
757 if (imHintsInt.has_value())
758 hints =
static_cast<Qt::InputMethodHints>(imHintsInt.value());
761 return hints.value_or(defaultInputMethodHints);
766 std::optional<Qt::EnterKeyType> enterKeyType;
767 auto query = tryQueryFocusObjectInputMethod(Qt::ImEnterKeyType);
768 if (!query.isNull()) {
769 auto imEnterKeyTypeInt = tryGetIntPropertyFromQuery(Qt::ImEnterKeyType, query);
770 if (imEnterKeyTypeInt.has_value())
771 enterKeyType =
static_cast<Qt::EnterKeyType>(imEnterKeyTypeInt.value());
774 return enterKeyType.value_or(defaultEnterKeyType);
779 auto query = tryQueryFocusObjectInputMethod(Qt::ImCursorPosition);
780 return !query.isNull()
781 ? tryGetIntPropertyFromQuery(Qt::ImCursorPosition, query)
785QSharedPointer<QInputMethodQueryEvent>
QOhosInputContext::tryQueryFocusObjectInputMethod(Qt::InputMethodQueries queries)
const
787 auto *focusObject = focusObjectOrNull();
788 if (focusObject ==
nullptr) {
789 qOhosWarning(QtForOhos) <<
"tryQueryFocusObjectInputMethod(): no focus object to query information from!";
793 auto imqEvent = QSharedPointer<QInputMethodQueryEvent>::create(queries);
794 QCoreApplication::sendEvent(focusObject, imqEvent.data());
void update(Qt::InputMethodQueries queries) override
Notification on editor updates.
QRectF keyboardRect() const override
This function can be reimplemented to return virtual keyboard rectangle in currently active window co...
void setSoftwareKeyboardVisibilityStatus(bool visible)
void showInputPanel() override
Request to show input panel.
void invokeAction(QInputMethod::Action action, int cursorPosition) override
Called when the word currently being composed in the input item is tapped by the user.
void setLastInputTypeToTriggerSoftKeyboard(RequestKeyboardReason inputType)
void reset() override
Method to be called when input method needs to be reset.
void hideInputPanel() override
Request to hide input panel.
bool eventFilter(QObject *obj, QEvent *event) override
Filters events if this object has been installed as an event filter for the watched object.
bool isInputPanelVisible() const override
Returns input panel visibility status.
QObject * focusObjectOrNull() const
void setFocusObject(QObject *object) override
This virtual method gets called to notify updated focus to object.
bool isAnimating() const override
This function can be reimplemented to return true whenever input method is animating shown or hidden.
QtOhos::enums::ohos::inputMethod::Direction Direction
JsInputMethodInsertedTextComposer & operator=(const JsInputMethodInsertedTextComposer &)=delete
JsInputMethodInsertedTextComposer(JsInputMethodInsertedTextComposer &&)=delete
static JsInputMethodInsertedTextComposer & instance()
JsInputMethodInsertedTextComposer & operator=(JsInputMethodInsertedTextComposer &&)=delete
std::optional< InsertedTextId > lastId() const
JsInputMethodInsertedTextComposer(const JsInputMethodInsertedTextComposer &)=delete
QOhosInsertedText makeInsertedText(const std::string &text)
InsertedTextId id() const
QOhosInsertedText(const std::string &text, const InsertedTextId &id)
Combined button and popup list for selecting options.
::InputMethod_TextInputType mapQtInputMethodHintsToOhosImeTextInputType(Qt::InputMethodHints hints)
::InputMethod_EnterKeyType mapQtToOhosImeEnterKeyType(Qt::EnterKeyType qtEnterKeyType)
std::optional< int > tryGetIntPropertyFromQuery(Qt::InputMethodQuery property, QSharedPointer< QInputMethodQueryEvent > query)
const Qt::EnterKeyType defaultEnterKeyType
std::optional< QOhosInputContext::Direction > tryMapInputMethodDirectionToQt(::InputMethod_Direction direction)
void notifyOhosInputMethodAboutPossibleAutocorrection(const QOhosInsertedText &insertedText, int cursorPosition)
const Qt::InputMethodHints defaultInputMethodHints
QPoint clampToRect(const QPoint &p, const QRect &rect)
::InputMethod_RequestKeyboardReason mapQtToOhosImeRequestReason(QOhosInputContext::RequestKeyboardReason qtRequestKeyboardReason)
std::pair< QString, QString > queryQtImTextAroundCursorOrEmpty()
void invokeInJsThreadAndWaitForContinue(std::function< void(JsState &, QOhosTaskPromise<>)> &&task, std::string callerContextName={})