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>
30 using TextInputType = ::InputMethod_TextInputType;
31 if (hints & Qt::ImhMultiLine) {
32 return TextInputType::IME_TEXT_INPUT_TYPE_MULTILINE;
33 }
else if (hints & Qt::ImhDigitsOnly) {
34 return (hints & Qt::ImhHiddenText)
35 ? TextInputType::IME_TEXT_INPUT_TYPE_NUMBER_PASSWORD
36 : TextInputType::IME_TEXT_INPUT_TYPE_NUMBER;
37 }
else if (hints & Qt::ImhDialableCharactersOnly) {
38 return TextInputType::IME_TEXT_INPUT_TYPE_PHONE;
39 }
else if (hints & (Qt::ImhDate | Qt::ImhTime)) {
40 return TextInputType::IME_TEXT_INPUT_TYPE_DATETIME;
41 }
else if (hints & Qt::ImhEmailCharactersOnly) {
42 return TextInputType::IME_TEXT_INPUT_TYPE_EMAIL_ADDRESS;
43 }
else if (hints & Qt::ImhUrlCharactersOnly) {
44 return TextInputType::IME_TEXT_INPUT_TYPE_URL;
45 }
else if (hints & Qt::ImhHiddenText) {
46 return TextInputType::IME_TEXT_INPUT_TYPE_VISIBLE_PASSWORD;
48 return TextInputType::IME_TEXT_INPUT_TYPE_TEXT;
55 case ::InputMethod_Direction::IME_DIRECTION_NONE:
57 case ::InputMethod_Direction::IME_DIRECTION_UP:
58 return QOhosInputContext::Direction::CURSOR_UP;
59 case ::InputMethod_Direction::IME_DIRECTION_DOWN:
60 return QOhosInputContext::Direction::CURSOR_DOWN;
61 case ::InputMethod_Direction::IME_DIRECTION_LEFT:
62 return QOhosInputContext::Direction::CURSOR_LEFT;
63 case ::InputMethod_Direction::IME_DIRECTION_RIGHT:
64 return QOhosInputContext::Direction::CURSOR_RIGHT;
71 switch (qtEnterKeyType) {
72 case Qt::EnterKeyType::EnterKeyReturn:
73 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_NEWLINE;
74 case Qt::EnterKeyType::EnterKeyDone:
75 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_DONE;
76 case Qt::EnterKeyType::EnterKeyGo:
77 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_GO;
78 case Qt::EnterKeyType::EnterKeySend:
79 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_SEND;
80 case Qt::EnterKeyType::EnterKeySearch:
81 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_SEARCH;
82 case Qt::EnterKeyType::EnterKeyNext:
83 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_NEXT;
84 case Qt::EnterKeyType::EnterKeyPrevious:
85 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_PREVIOUS;
86 case Qt::EnterKeyType::EnterKeyDefault:
87 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_NONE;
90 "%s: Cannot map Qt::EnterKeyType to OHOS value. Returning ::InputMethod_EnterKeyType::IME_ENTER_KEY_UNSPECIFIED",
92 return ::InputMethod_EnterKeyType::IME_ENTER_KEY_UNSPECIFIED;
96 QOhosInputContext::RequestKeyboardReason qtRequestKeyboardReason)
98 switch (qtRequestKeyboardReason) {
99 case QOhosInputContext::RequestKeyboardReason::NONE:
100 return ::InputMethod_RequestKeyboardReason::IME_REQUEST_REASON_NONE;
101 case QOhosInputContext::RequestKeyboardReason::MOUSE:
102 return ::InputMethod_RequestKeyboardReason::IME_REQUEST_REASON_MOUSE;
103 case QOhosInputContext::RequestKeyboardReason::TOUCH:
104 return ::InputMethod_RequestKeyboardReason::IME_REQUEST_REASON_TOUCH;
105 case QOhosInputContext::RequestKeyboardReason::OTHER:
106 return ::InputMethod_RequestKeyboardReason::IME_REQUEST_REASON_OTHER;
109 "%s: Cannot map QOhosInputContext::RequestKeyboardReason to OHOS value. Returning ::InputMethod_RequestKeyboardReason::IME_REQUEST_REASON_NONE",
111 return ::InputMethod_RequestKeyboardReason::IME_REQUEST_REASON_NONE;
117 const auto value = query->value(property).toInt(&converted);
118 return converted ?
std::optional(value) :
std::nullopt;
123 int x = qBound(rect.left(), p.x(), rect.right());
124 int y = qBound(rect.top(), p.y(), rect.bottom());
130 auto *focusObject = QGuiApplication::focusObject();
134 QInputMethodQueryEvent directEvent(Qt::ImTextBeforeCursor | Qt::ImTextAfterCursor);
135 QCoreApplication::sendEvent(focusObject, &directEvent);
137 const auto textBeforeCursorResult = directEvent.value(Qt::ImTextBeforeCursor);
138 const auto textAfterCursorResult = directEvent.value(Qt::ImTextAfterCursor);
139 if (textBeforeCursorResult.canConvert<QString>() && textAfterCursorResult.canConvert<QString>())
140 return {textBeforeCursorResult.toString(), textAfterCursorResult.toString()};
142 QInputMethodQueryEvent fallbackEvent(Qt::ImSurroundingText | Qt::ImCursorPosition);
143 QCoreApplication::sendEvent(focusObject, &fallbackEvent);
145 const auto surroundingTextResult = fallbackEvent.value(Qt::ImSurroundingText);
146 const auto cursorPositionResult = fallbackEvent.value(Qt::ImCursorPosition);
148 if (!surroundingTextResult.canConvert<QString>() || !cursorPositionResult.canConvert<
int>())
151 const auto cursorPos = cursorPositionResult.toInt();
155 const QString text = surroundingTextResult.toString();
156 return {text.left(cursorPos), text.mid(cursorPos)};
164 , m_qtImEnabled(
false)
171 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::QOhosInputContext");
174 QGuiApplication::inputMethod(), &QInputMethod::cursorRectangleChanged,
175 this, &QOhosInputContext::onCursorRectangleChanged);
177 QGuiApplication::instance()->installEventFilter(
this);
184 if (m_imConnectionState == ImConnectionState::Attached) {
185 setImConnectionState(ImConnectionState::Detached);
186 setImConnectionState(ImConnectionState::Attached);
192 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::commit");
194 auto preeditText = std::exchange(m_pendingPreeditText, {});
196 QInputMethodEvent event;
197 event.setCommitString(preeditText);
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);
335 class ImCallbacks :
public QOhosInputMethodProxy::ClientCallbacks
339 : m_inputContext(inputContext)
344 void onInsertText(
std::string text)
override
346 m_inputContext.sendInsertedTextToQt(
std::move(text));
349 void onInsertPreviewText(
std::string previewText)
override
351 m_inputContext.sendInsertedPreviewTextToQt(
std::move(previewText));
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();
602 QInputMethodEvent event;
603 event.setCommitString(QString::fromStdString(textToInsert));
604 sendFocusObjectInputMethodEvent(&event);
609 auto query = tryQueryFocusObjectInputMethod(Qt::ImEnabled);
613 if (!query->value(Qt::ImEnabled).toBool()) {
614 qOhosPrintfDebug(
"%s: focus object is not able to handle InputMethod", Q_FUNC_INFO);
618 const QString previewString = QString::fromStdString(previewText);
619 QList<QInputMethodEvent::Attribute> imEventAttributes;
620 if (!previewString.isEmpty()) {
621 QTextCharFormat format;
622 format.setFontUnderline(
true);
623 imEventAttributes.append(
624 QInputMethodEvent::Attribute(
625 QInputMethodEvent::TextFormat, 0, previewString.length(), format));
628 m_pendingPreeditText = previewString;
630 QInputMethodEvent preeditStringEvent(previewString, imEventAttributes);
631 sendFocusObjectInputMethodEvent(&preeditStringEvent);
636 auto *focusObject = focusObjectOrNull();
637 if (focusObject ==
nullptr) {
638 qOhosWarning(QtForOhos) <<
"sendFocusObjectInputMethodEvent(): no focus object to send event to!";
642 QCoreApplication::sendEvent(focusObject, event);
645void QOhosInputContext::sendCursorMoveToQt(QOhosInputContext::Direction direction)
648 case QOhosInputContext::Direction::CURSOR_UP:
649 sendFocusObjectFunctionalKeyEvent(Qt::Key_Up);
651 case QOhosInputContext::Direction::CURSOR_DOWN:
652 sendFocusObjectFunctionalKeyEvent(Qt::Key_Down);
654 case QOhosInputContext::Direction::CURSOR_LEFT:
655 sendFocusObjectFunctionalKeyEvent(Qt::Key_Left);
657 case QOhosInputContext::Direction::CURSOR_RIGHT:
658 sendFocusObjectFunctionalKeyEvent(Qt::Key_Right);
663void QOhosInputContext::sendFocusObjectFunctionalKeyEvent(Qt::Key key,
const QString &keyText,
int repeatCount)
665 auto *focusObject = focusObjectOrNull();
666 if (focusObject ==
nullptr) {
667 qOhosWarning(QtForOhos) <<
"sendFocusObjectFunctionalKeyEvent(): no focus object to send event to!";
671 for (
int i = 0; i < repeatCount; ++i) {
672 QGuiApplication::postEvent(focusObject,
new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier, keyText));
673 QGuiApplication::postEvent(focusObject,
new QKeyEvent(QEvent::KeyRelease, key, Qt::NoModifier, keyText));
679 auto query = tryQueryFocusObjectInputMethod(Qt::ImEnabled);
680 return !query.isNull() && query->value(Qt::ImEnabled).toBool();
685 std::optional<Qt::InputMethodHints> hints;
686 auto query = tryQueryFocusObjectInputMethod(Qt::ImHints);
687 if (!query.isNull()) {
688 auto imHintsInt = tryGetIntPropertyFromQuery(Qt::ImHints, query);
689 if (imHintsInt.has_value())
690 hints =
static_cast<Qt::InputMethodHints>(imHintsInt.value());
693 return hints.value_or(defaultInputMethodHints);
698 std::optional<Qt::EnterKeyType> enterKeyType;
699 auto query = tryQueryFocusObjectInputMethod(Qt::ImEnterKeyType);
700 if (!query.isNull()) {
701 auto imEnterKeyTypeInt = tryGetIntPropertyFromQuery(Qt::ImEnterKeyType, query);
702 if (imEnterKeyTypeInt.has_value())
703 enterKeyType =
static_cast<Qt::EnterKeyType>(imEnterKeyTypeInt.value());
706 return enterKeyType.value_or(defaultEnterKeyType);
711 auto query = tryQueryFocusObjectInputMethod(Qt::ImCursorPosition);
712 return !query.isNull()
713 ? tryGetIntPropertyFromQuery(Qt::ImCursorPosition, query)
717QSharedPointer<QInputMethodQueryEvent>
QOhosInputContext::tryQueryFocusObjectInputMethod(Qt::InputMethodQueries queries)
const
719 auto *focusObject = focusObjectOrNull();
720 if (focusObject ==
nullptr) {
721 qOhosWarning(QtForOhos) <<
"tryQueryFocusObjectInputMethod(): no focus object to query information from!";
725 auto imqEvent = QSharedPointer<QInputMethodQueryEvent>::create(queries);
726 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.
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()