5#include <QtCore/private/qnapi_p.h>
6#include <QtCore/private/qohoslogger_p.h>
7#include <QtCore/qnamespace.h>
8#include <QtGui/private/qhighdpiscaling_p.h>
12#include <QtCore/qrect.h>
13#include <QtGui/qinputdevice.h>
14#include <QtGui/qguiapplication.h>
15#include <QtGui/qtextformat.h>
17#include <qohosjsutils.h>
18#include <inputmethod/inputmethod_controller_capi.h>
29 using TextInputType = ::InputMethod_TextInputType;
30 if (hints & Qt::ImhMultiLine) {
31 return TextInputType::IME_TEXT_INPUT_TYPE_MULTILINE;
32 }
else if (hints & Qt::ImhDigitsOnly) {
33 return (hints & Qt::ImhHiddenText)
34 ? TextInputType::IME_TEXT_INPUT_TYPE_NUMBER_PASSWORD
35 : TextInputType::IME_TEXT_INPUT_TYPE_NUMBER;
36 }
else if (hints & Qt::ImhDialableCharactersOnly) {
37 return TextInputType::IME_TEXT_INPUT_TYPE_PHONE;
38 }
else if (hints & (Qt::ImhDate | Qt::ImhTime)) {
39 return TextInputType::IME_TEXT_INPUT_TYPE_DATETIME;
40 }
else if (hints & Qt::ImhEmailCharactersOnly) {
41 return TextInputType::IME_TEXT_INPUT_TYPE_EMAIL_ADDRESS;
42 }
else if (hints & Qt::ImhUrlCharactersOnly) {
43 return TextInputType::IME_TEXT_INPUT_TYPE_URL;
44 }
else if (hints & Qt::ImhHiddenText) {
45 return TextInputType::IME_TEXT_INPUT_TYPE_VISIBLE_PASSWORD;
47 return TextInputType::IME_TEXT_INPUT_TYPE_TEXT;
54 case ::InputMethod_Direction::IME_DIRECTION_NONE:
56 case ::InputMethod_Direction::IME_DIRECTION_UP:
58 case ::InputMethod_Direction::IME_DIRECTION_DOWN:
60 case ::InputMethod_Direction::IME_DIRECTION_LEFT:
62 case ::InputMethod_Direction::IME_DIRECTION_RIGHT:
70 switch (qtEnterKeyType) {
71 case Qt::EnterKeyType::EnterKeyReturn:
72 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_NEWLINE;
73 case Qt::EnterKeyType::EnterKeyDone:
74 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_DONE;
75 case Qt::EnterKeyType::EnterKeyGo:
76 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_GO;
77 case Qt::EnterKeyType::EnterKeySend:
78 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_SEND;
79 case Qt::EnterKeyType::EnterKeySearch:
80 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_SEARCH;
81 case Qt::EnterKeyType::EnterKeyNext:
82 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_NEXT;
83 case Qt::EnterKeyType::EnterKeyPrevious:
84 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_PREVIOUS;
85 case Qt::EnterKeyType::EnterKeyDefault:
86 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_NONE;
89 "%s: Cannot map Qt::EnterKeyType to OHOS value. Returning ::InputMethod_EnterKeyType::IME_ENTER_KEY_UNSPECIFIED",
91 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_UNSPECIFIED;
95 QOhosInputContext::RequestKeyboardReason qtRequestKeyboardReason)
97 switch (qtRequestKeyboardReason) {
98 case QOhosInputContext::RequestKeyboardReason::NONE:
99 return ::InputMethod_RequestKeyboardReason::IME_REQUEST_REASON_NONE;
100 case QOhosInputContext::RequestKeyboardReason::MOUSE:
101 return ::InputMethod_RequestKeyboardReason::IME_REQUEST_REASON_MOUSE;
102 case QOhosInputContext::RequestKeyboardReason::TOUCH:
103 return ::InputMethod_RequestKeyboardReason::IME_REQUEST_REASON_TOUCH;
104 case QOhosInputContext::RequestKeyboardReason::OTHER:
105 return ::InputMethod_RequestKeyboardReason::IME_REQUEST_REASON_OTHER;
108 "%s: Cannot map QOhosInputContext::RequestKeyboardReason to OHOS value. Returning ::InputMethod_RequestKeyboardReason::IME_REQUEST_REASON_NONE",
110 return ::InputMethod_RequestKeyboardReason::IME_REQUEST_REASON_NONE;
116 const auto value = query->value(property).toInt(&converted);
117 return converted ?
std::optional(value) :
std::nullopt;
122 int x = qBound(rect.left(), p.x(), rect.right());
123 int y = qBound(rect.top(), p.y(), rect.bottom());
129 auto *focusObject = QGuiApplication::focusObject();
133 QInputMethodQueryEvent directEvent(Qt::ImTextBeforeCursor | Qt::ImTextAfterCursor);
134 QCoreApplication::sendEvent(focusObject, &directEvent);
136 const auto textBeforeCursorResult = directEvent.value(Qt::ImTextBeforeCursor);
137 const auto textAfterCursorResult = directEvent.value(Qt::ImTextAfterCursor);
138 if (textBeforeCursorResult.canConvert<QString>() && textAfterCursorResult.canConvert<QString>())
139 return {textBeforeCursorResult.toString(), textAfterCursorResult.toString()};
141 QInputMethodQueryEvent fallbackEvent(Qt::ImSurroundingText | Qt::ImCursorPosition);
142 QCoreApplication::sendEvent(focusObject, &fallbackEvent);
144 const auto surroundingTextResult = fallbackEvent.value(Qt::ImSurroundingText);
145 const auto cursorPositionResult = fallbackEvent.value(Qt::ImCursorPosition);
147 if (!surroundingTextResult.canConvert<QString>() || !cursorPositionResult.canConvert<
int>())
150 const auto cursorPos = cursorPositionResult.toInt();
154 const QString text = surroundingTextResult.toString();
155 return {text.left(cursorPos), text.mid(cursorPos)};
163 , m_qtImEnabled(
false)
167 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::QOhosInputContext");
170 QGuiApplication::inputMethod(), &QInputMethod::cursorRectangleChanged,
171 this, &QOhosInputContext::onCursorRectangleChanged);
173 QGuiApplication::instance()->installEventFilter(
this);
180 if (m_imConnectionState == ImConnectionState::Attached) {
181 setImConnectionState(ImConnectionState::Detached);
182 setImConnectionState(ImConnectionState::Attached);
188 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::commit");
190 const QString phrase = std::exchange(m_pendingPreeditText, {});
191 const auto replaceRange = std::exchange(m_previewReplaceRange, {});
193 if (phrase.isEmpty())
196 QInputMethodEvent event;
197 event.setCommitString(phrase, replaceRange.from, replaceRange.length);
198 sendFocusObjectInputMethodEvent(&event);
203 if (!focusObjectOrNull()) {
208 m_qtImEnabled = queryImEnabled();
209 const auto qtInputMethodHintsValue = queryInputMethodHints();
210 const auto qtEnterKeyTypeValue = queryEnterKeyType();
212 const bool imStateChanged =
213 m_qtInputMethodHints != qtInputMethodHintsValue
214 || m_qtEnterKeyType != qtEnterKeyTypeValue;
216 auto imAlreadyAttached = m_imConnectionState == ImConnectionState::Attached;
217 if (imAlreadyAttached && imStateChanged)
218 updateInputMethodControllerAttributes(qtInputMethodHintsValue, qtEnterKeyTypeValue);
220 m_qtInputMethodHints = qtInputMethodHintsValue;
221 m_qtEnterKeyType = qtEnterKeyTypeValue;
223 if (inputMethodAccepted() && m_qtImEnabled) {
224 if (imAlreadyAttached) {
225 pushTextAroundCursorToProxy();
229 auto updateCausedByWidgetTransform = queries == Qt::ImInputItemClipRectangle;
230 auto updateCausedByQueryAllImParameters = queries == Qt::ImQueryAll;
232 if (updateCausedByQueryAllImParameters)
235 if (!updateCausedByWidgetTransform || !imAlreadyAttached) {
245 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::invokeAction");
250 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::keyboardRect");
256 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::isAnimating");
262 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::showInputPanel");
263 setImConnectionState(ImConnectionState::Attached);
268 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::hideInputPanel");
269 setImConnectionState(ImConnectionState::Detached);
274 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::isInputPanelVisible");
275 return m_imConnectionRequestedState == ImConnectionState::Attached;
280 if (object == m_focusObject)
283 const bool wasAttached = m_imConnectionState == ImConnectionState::Attached;
285 if (!m_pendingPreeditText.isEmpty())
288 m_focusObject = object;
290 if (wasAttached && object !=
nullptr) {
291 m_qtImEnabled = queryImEnabled();
299 return m_focusObject;
304 if (requestedState != m_imConnectionRequestedState) {
305 setImConnectionStateImpl(requestedState);
307 if (m_imConnectionState == ImConnectionState::Attached && !m_softwareKeyboardVisible)
312void QOhosInputContext::setImConnectionStateImpl(ImConnectionState requestedState)
314 m_imConnectionRequestedState = m_qtImEnabled ? requestedState : ImConnectionState::Detached;
316 if (!m_imConnectionRequestActive) {
317 m_imConnectionRequestActive =
true;
319 dispatchRequestedImStateChange(requestedState);
323void QOhosInputContext::dispatchRequestedImStateChange(ImConnectionState requestedState)
326 if (requestedState == ImConnectionState::Attached)
327 result = attachToInputMethodController();
329 result = detachFromInputMethodController();
330 handleRequestedImConnectionState(requestedState, result);
339 : m_inputContext(inputContext)
344 void onInsertText(
std::string text)
override
346 m_inputContext.sendInsertedTextToQt(
std::move(text));
349 void onInsertPreviewText(
std::string previewText,
int start,
int end)
override
351 m_inputContext.sendInsertedPreviewTextToQt(
std::move(previewText), start, end);
354 void onFinishPreviewText()
override
359 void onDeleteForward(
int length)
override
361 m_inputContext.sendFocusObjectFunctionalKeyEvent(Qt::Key_Delete, QStringLiteral(
"\u007F"), length);
364 void onDeleteBackward(
int length)
override
366 m_inputContext.sendFocusObjectFunctionalKeyEvent(Qt::Key_Backspace, QStringLiteral(
"\u0008"), length);
369 void onSendKeyboardStatus(::InputMethod_KeyboardStatus keyboardStatus)
override
371 bool ohosKeyboardShown = keyboardStatus == ::InputMethod_KeyboardStatus::IME_KEYBOARD_STATUS_SHOW;
375 void onSendEnterKey(::InputMethod_EnterKeyType)
override
377 m_inputContext.sendFocusObjectFunctionalKeyEvent(Qt::Key_Enter, QStringLiteral(
"\u000D"));
380 void onMoveCursor(::InputMethod_Direction direction)
override
382 auto qtDirection = tryMapInputMethodDirectionToQt(direction);
383 if (!qtDirection.has_value()) {
385 "got unsupported InputMethod_Direction value (%d), cursor won't be moved!",
386 static_cast<
int>(direction));
390 m_inputContext.sendCursorMoveToQt(qtDirection.value());
397 qOhosPrintfWarning(
"%s: proxy already exists!", Q_FUNC_INFO);
399 m_imProxy = std::make_shared<QOhosInputMethodProxy>(
400 std::make_shared<ImCallbacks>(*
this),
401 mapQtToOhosImeRequestReason(
402 m_lastInputTypeToTriggerSoftKeyboard.value_or(RequestKeyboardReason::OTHER)));
404 if (m_imProxy->hasAttachedSuccessfully()) {
405 pushTextAroundCursorToProxy();
406 m_imProxy->notifyConfigurationChange(
407 mapQtToOhosImeEnterKeyType(m_qtEnterKeyType),
408 mapQtInputMethodHintsToOhosImeTextInputType(m_qtInputMethodHints));
417 qOhosPrintfWarning(
"%s: proxy doesn't exist!", Q_FUNC_INFO);
423void QOhosInputContext::handleRequestedImConnectionState(ImConnectionState requestedState,
bool success)
425 m_imConnectionRequestActive =
false;
428 qOhosWarning(QtForOhos)
430 << (requestedState == ImConnectionState::Attached ?
"attach to" :
"detach from")
435 m_imConnectionState = requestedState;
437 if (m_imConnectionRequestedState != m_imConnectionState)
438 setImConnectionStateImpl(m_imConnectionRequestedState);
440 onCursorRectangleChanged();
445 if (m_imProxy ==
nullptr) {
446 qOhosPrintfError(
"%s: proxy doesn't exist!", Q_FUNC_INFO);
450 m_imProxy->showTextInput(mapQtToOhosImeRequestReason(
451 m_lastInputTypeToTriggerSoftKeyboard.value_or(RequestKeyboardReason::OTHER)));
456 m_softwareKeyboardVisible = visible;
461 m_lastInputTypeToTriggerSoftKeyboard = inputType;
466 if (m_imConnectionState == ImConnectionState::Detached) {
467 qOhosDebug(QtForOhos) <<
"Cursor rectangle changed while detached; deferring update until attach";
468 m_updateCursorRectangleAfterAttaching =
true;
472 auto *focusedWindow = QGuiApplication::focusWindow();
473 if (focusedWindow ==
nullptr) {
474 qOhosCritical(QtForOhos)
475 <<
"Could not retrieve focused window. Updating cursor position isn't possible";
479 auto focusedWindowPosition = focusedWindow->mapToGlobal(QPoint(0, 0));
480 QRect cursorRectangle = QGuiApplication::inputMethod()->cursorRectangle().toRect();
481 if (!m_updateCursorRectangleAfterAttaching
482 && cursorRectangle == m_lastCursorRectangle
483 && m_lastFocusedWindowPosition == focusedWindowPosition) {
487 m_lastCursorRectangle = cursorRectangle;
488 m_lastFocusedWindowPosition = focusedWindowPosition;
489 auto globalInputItemRectangle =
490 QGuiApplication::inputMethod()->inputItemClipRectangle()
491 .translated(m_lastFocusedWindowPosition)
493 auto globalCursorRectangle = m_lastCursorRectangle.translated(m_lastFocusedWindowPosition);
494 auto inputItemClampedCursorPos = clampToRect(
495 {globalCursorRectangle.x(), globalCursorRectangle.y()},
496 globalInputItemRectangle.isValid()
497 ? globalInputItemRectangle
498 : QRect(focusedWindowPosition, focusedWindow->size()));
499 auto nativeCursorPos = QHighDpiScaling::mapPositionToNative(
500 inputItemClampedCursorPos, focusedWindow->screen()->handle());
501 auto screenBasedCursorPos = nativeCursorPos - focusedWindow->screen()->handle()->geometry().topLeft();
503 screenBasedCursorPos.x(), screenBasedCursorPos.y(),
504 globalCursorRectangle.width(), globalCursorRectangle.height()
506 m_updateCursorRectangleAfterAttaching =
false;
510 Qt::InputMethodHints qtInputMethodHints, Qt::EnterKeyType qtEnterKeyType)
512 if (m_imProxy ==
nullptr) {
513 qOhosPrintfError(
"%s: proxy doesn't exist!", Q_FUNC_INFO);
517 m_imProxy->notifyConfigurationChange(
518 mapQtToOhosImeEnterKeyType(qtEnterKeyType),
519 mapQtInputMethodHintsToOhosImeTextInputType(qtInputMethodHints));
524 if (m_imProxy ==
nullptr) {
525 qOhosPrintfError(
"%s: proxy doesn't exist!", Q_FUNC_INFO);
529 m_imProxy->notifyCursorUpdate(globalCursorRect);
534 if (m_imProxy ==
nullptr) {
535 qOhosPrintfError(
"%s: proxy doesn't exist!", Q_FUNC_INFO);
539 const auto textAroundCursor = queryQtImTextAroundCursorOrEmpty();
540 m_imProxy->setTextAroundCursor(
541 textAroundCursor.first.toStdU16String(),
542 textAroundCursor.second.toStdU16String(),
543 tryQueryCursorPosition().value_or(0));
548 if (m_imProxy ==
nullptr) {
549 qOhosPrintfError(
"%s: proxy doesn't exist!", Q_FUNC_INFO);
553 auto query = tryQueryFocusObjectInputMethod(
554 Qt::ImSurroundingText | Qt::ImCursorPosition | Qt::ImAnchorPosition);
558 const auto surroundingText = query->value(Qt::ImSurroundingText);
559 const auto cursorPosition = query->value(Qt::ImCursorPosition);
560 const auto anchorPosition = query->value(Qt::ImAnchorPosition);
562 if (!surroundingText.canConvert<QString>() || !cursorPosition.canConvert<
int>()
563 || !anchorPosition.canConvert<
int>())
566 const int cursor = cursorPosition.toInt();
567 const int anchor = anchorPosition.toInt();
569 m_imProxy->notifySelectionChange(
570 surroundingText.toString().toStdU16String(), std::min(anchor, cursor), std::max(anchor, cursor));
575 if (obj->isWidgetType() && queryImEnabled()) {
576 auto focusReason = event->reason();
577 if (focusReason == Qt::OtherFocusReason || focusReason == Qt::ActiveWindowFocusReason)
578 setLastInputTypeToTriggerSoftKeyboard(RequestKeyboardReason::NONE);
584 if (event->type() == QEvent::FocusIn)
585 handleFocusInEvent(obj,
static_cast<QFocusEvent *>(event));
591 auto query = tryQueryFocusObjectInputMethod(Qt::ImEnabled);
595 if (!query->value(Qt::ImEnabled).toBool()) {
596 qOhosDebug(QtForOhos) <<
"onInsertText(): focus object is not able to handle InputMethod";
600 m_pendingPreeditText.clear();
601 m_previewReplaceRange = {};
603 QInputMethodEvent event;
604 event.setCommitString(QString::fromStdString(textToInsert));
605 sendFocusObjectInputMethodEvent(&event);
610 auto query = tryQueryFocusObjectInputMethod(Qt::ImEnabled);
614 if (!query->value(Qt::ImEnabled).toBool()) {
615 qOhosPrintfDebug(
"%s: focus object is not able to handle InputMethod", Q_FUNC_INFO);
619 m_previewReplaceRange = {};
620 const auto cursor = tryQueryCursorPosition();
621 if (cursor && !(start < 0 && end < 0)) {
622 const int from = qMin(start, end);
623 const int to = qMax(start, end);
624 m_previewReplaceRange = { from - *cursor, to - from };
627 const QString previewString = QString::fromStdString(previewText);
628 QList<QInputMethodEvent::Attribute> imEventAttributes;
629 if (!previewString.isEmpty()) {
630 QTextCharFormat format;
631 format.setFontUnderline(
true);
632 imEventAttributes.append(
633 QInputMethodEvent::Attribute(
634 QInputMethodEvent::TextFormat, 0, previewString.length(), format));
637 m_pendingPreeditText = previewString;
639 QInputMethodEvent preeditStringEvent(previewString, imEventAttributes);
640 sendFocusObjectInputMethodEvent(&preeditStringEvent);
645 auto *focusObject = focusObjectOrNull();
646 if (focusObject ==
nullptr) {
647 qOhosWarning(QtForOhos) <<
"sendFocusObjectInputMethodEvent(): no focus object to send event to!";
651 QCoreApplication::sendEvent(focusObject, event);
657 case QOhosInputContext::Direction::CURSOR_UP:
658 sendFocusObjectFunctionalKeyEvent(Qt::Key_Up);
660 case QOhosInputContext::Direction::CURSOR_DOWN:
661 sendFocusObjectFunctionalKeyEvent(Qt::Key_Down);
663 case QOhosInputContext::Direction::CURSOR_LEFT:
664 sendFocusObjectFunctionalKeyEvent(Qt::Key_Left);
666 case QOhosInputContext::Direction::CURSOR_RIGHT:
667 sendFocusObjectFunctionalKeyEvent(Qt::Key_Right);
672void QOhosInputContext::sendFocusObjectFunctionalKeyEvent(Qt::Key key,
const QString &keyText,
int repeatCount)
674 auto *focusObject = focusObjectOrNull();
675 if (focusObject ==
nullptr) {
676 qOhosWarning(QtForOhos) <<
"sendFocusObjectFunctionalKeyEvent(): no focus object to send event to!";
680 for (
int i = 0; i < repeatCount; ++i) {
681 QGuiApplication::postEvent(focusObject,
new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier, keyText));
682 QGuiApplication::postEvent(focusObject,
new QKeyEvent(QEvent::KeyRelease, key, Qt::NoModifier, keyText));
688 auto query = tryQueryFocusObjectInputMethod(Qt::ImEnabled);
689 return !query.isNull() && query->value(Qt::ImEnabled).toBool();
694 std::optional<Qt::InputMethodHints> hints;
695 auto query = tryQueryFocusObjectInputMethod(Qt::ImHints);
696 if (!query.isNull()) {
697 auto imHintsInt = tryGetIntPropertyFromQuery(Qt::ImHints, query);
698 if (imHintsInt.has_value())
699 hints =
static_cast<Qt::InputMethodHints>(imHintsInt.value());
702 return hints.value_or(defaultInputMethodHints);
707 std::optional<Qt::EnterKeyType> enterKeyType;
708 auto query = tryQueryFocusObjectInputMethod(Qt::ImEnterKeyType);
709 if (!query.isNull()) {
710 auto imEnterKeyTypeInt = tryGetIntPropertyFromQuery(Qt::ImEnterKeyType, query);
711 if (imEnterKeyTypeInt.has_value())
712 enterKeyType =
static_cast<Qt::EnterKeyType>(imEnterKeyTypeInt.value());
715 return enterKeyType.value_or(defaultEnterKeyType);
720 auto query = tryQueryFocusObjectInputMethod(Qt::ImCursorPosition);
721 return !query.isNull()
722 ? tryGetIntPropertyFromQuery(Qt::ImCursorPosition, query)
726QSharedPointer<QInputMethodQueryEvent>
QOhosInputContext::tryQueryFocusObjectInputMethod(Qt::InputMethodQueries queries)
const
728 auto *focusObject = focusObjectOrNull();
729 if (focusObject ==
nullptr) {
730 qOhosWarning(QtForOhos) <<
"tryQueryFocusObjectInputMethod(): no focus object to query information from!";
734 auto imqEvent = QSharedPointer<QInputMethodQueryEvent>::create(queries);
735 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)
QtOhosQpa::enums::ohos::inputMethod::Direction Direction
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.
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)
const Qt::InputMethodHints defaultInputMethodHints
QPoint clampToRect(const QPoint &p, const QRect &rect)
::InputMethod_RequestKeyboardReason mapQtToOhosImeRequestReason(QOhosInputContext::RequestKeyboardReason qtRequestKeyboardReason)
std::pair< QString, QString > queryQtImTextAroundCursorOrEmpty()