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)
170 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::QOhosInputContext");
173 QGuiApplication::inputMethod(), &QInputMethod::cursorRectangleChanged,
174 this, &QOhosInputContext::onCursorRectangleChanged);
176 QGuiApplication::instance()->installEventFilter(
this);
183 if (m_imConnectionState == ImConnectionState::Attached) {
184 setImConnectionState(ImConnectionState::Detached);
185 setImConnectionState(ImConnectionState::Attached);
191 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::commit");
193 const QString phrase = std::exchange(m_pendingPreeditText, {});
194 const auto replaceRange = std::exchange(m_previewReplaceRange, {});
196 if (phrase.isEmpty())
199 QInputMethodEvent event;
200 event.setCommitString(phrase, replaceRange.from, replaceRange.length);
201 sendFocusObjectInputMethodEvent(&event);
206 if (!focusObjectOrNull()) {
211 m_qtImEnabled = queryImEnabled();
212 const auto qtInputMethodHintsValue = queryInputMethodHints();
213 const auto qtEnterKeyTypeValue = queryEnterKeyType();
215 const bool imStateChanged =
216 m_qtInputMethodHints != qtInputMethodHintsValue
217 || m_qtEnterKeyType != qtEnterKeyTypeValue;
219 auto imAlreadyAttached = m_imConnectionState == ImConnectionState::Attached;
220 if (imAlreadyAttached && imStateChanged)
221 updateInputMethodControllerAttributes(qtInputMethodHintsValue, qtEnterKeyTypeValue);
223 m_qtInputMethodHints = qtInputMethodHintsValue;
224 m_qtEnterKeyType = qtEnterKeyTypeValue;
226 if (inputMethodAccepted() && m_qtImEnabled) {
227 if (imAlreadyAttached) {
228 pushTextAroundCursorToProxy();
232 auto updateCausedByWidgetTransform = queries == Qt::ImInputItemClipRectangle;
233 auto updateCausedByQueryAllImParameters = queries == Qt::ImQueryAll;
235 if (updateCausedByQueryAllImParameters)
238 if (!updateCausedByWidgetTransform || !imAlreadyAttached) {
248 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::invokeAction");
253 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::keyboardRect");
259 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::isAnimating");
265 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::showInputPanel");
266 setImConnectionState(ImConnectionState::Attached);
271 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::hideInputPanel");
272 setImConnectionState(ImConnectionState::Detached);
277 auto __dbg = make_QCScopedDebug(
"QOhosInputContext::isInputPanelVisible");
278 return m_imConnectionRequestedState == ImConnectionState::Attached;
283 if (object == m_focusObject)
286 const bool wasAttached = m_imConnectionState == ImConnectionState::Attached;
288 if (!m_pendingPreeditText.isEmpty())
291 m_focusObject = object;
293 if (wasAttached && object !=
nullptr) {
294 m_qtImEnabled = queryImEnabled();
302 return m_focusObject;
307 if (requestedState != m_imConnectionRequestedState) {
308 setImConnectionStateImpl(requestedState);
310 if (m_imConnectionState == ImConnectionState::Attached && !m_softwareKeyboardVisible)
315void QOhosInputContext::setImConnectionStateImpl(ImConnectionState requestedState)
317 m_imConnectionRequestedState = m_qtImEnabled ? requestedState : ImConnectionState::Detached;
319 if (!m_imConnectionRequestActive) {
320 m_imConnectionRequestActive =
true;
322 dispatchRequestedImStateChange(requestedState);
326void QOhosInputContext::dispatchRequestedImStateChange(ImConnectionState requestedState)
329 if (requestedState == ImConnectionState::Attached)
330 result = attachToInputMethodController();
332 result = detachFromInputMethodController();
333 handleRequestedImConnectionState(requestedState, result);
338 class ImCallbacks :
public QOhosInputMethodProxy::ClientCallbacks
342 : m_inputContext(inputContext)
347 void onInsertText(
std::string text)
override
349 m_inputContext.sendInsertedTextToQt(
std::move(text));
352 void onInsertPreviewText(
std::string previewText,
int start,
int end)
override
354 m_inputContext.sendInsertedPreviewTextToQt(
std::move(previewText), start, end);
357 void onFinishPreviewText()
override
362 void onDeleteForward(
int length)
override
364 m_inputContext.sendFocusObjectFunctionalKeyEvent(Qt::Key_Delete, QStringLiteral(
"\u007F"), length);
367 void onDeleteBackward(
int length)
override
369 m_inputContext.sendFocusObjectFunctionalKeyEvent(Qt::Key_Backspace, QStringLiteral(
"\u0008"), length);
372 void onSendKeyboardStatus(::InputMethod_KeyboardStatus keyboardStatus)
override
374 bool ohosKeyboardShown = keyboardStatus == ::InputMethod_KeyboardStatus::IME_KEYBOARD_STATUS_SHOW;
378 void onSendEnterKey(::InputMethod_EnterKeyType)
override
380 m_inputContext.sendFocusObjectFunctionalKeyEvent(Qt::Key_Enter, QStringLiteral(
"\u000D"));
383 void onMoveCursor(::InputMethod_Direction direction)
override
385 auto qtDirection = tryMapInputMethodDirectionToQt(direction);
386 if (!qtDirection.has_value()) {
388 "got unsupported InputMethod_Direction value (%d), cursor won't be moved!",
389 static_cast<
int>(direction));
393 m_inputContext.sendCursorMoveToQt(qtDirection.value());
400 qOhosPrintfWarning(
"%s: proxy already exists!", Q_FUNC_INFO);
402 m_imProxy = std::make_shared<QOhosInputMethodProxy>(
403 std::make_shared<ImCallbacks>(*
this),
404 mapQtToOhosImeRequestReason(
405 m_lastInputTypeToTriggerSoftKeyboard.value_or(RequestKeyboardReason::OTHER)));
407 if (m_imProxy->hasAttachedSuccessfully()) {
408 pushTextAroundCursorToProxy();
409 m_imProxy->notifyConfigurationChange(
410 mapQtToOhosImeEnterKeyType(m_qtEnterKeyType),
411 mapQtInputMethodHintsToOhosImeTextInputType(m_qtInputMethodHints));
420 qOhosPrintfWarning(
"%s: proxy doesn't exist!", Q_FUNC_INFO);
426void QOhosInputContext::handleRequestedImConnectionState(ImConnectionState requestedState,
bool success)
428 m_imConnectionRequestActive =
false;
431 qOhosWarning(QtForOhos)
433 << (requestedState == ImConnectionState::Attached ?
"attach to" :
"detach from")
438 m_imConnectionState = requestedState;
440 if (m_imConnectionRequestedState != m_imConnectionState)
441 setImConnectionStateImpl(m_imConnectionRequestedState);
443 onCursorRectangleChanged();
448 if (m_imProxy ==
nullptr) {
449 qOhosPrintfError(
"%s: proxy doesn't exist!", Q_FUNC_INFO);
453 m_imProxy->showTextInput(mapQtToOhosImeRequestReason(
454 m_lastInputTypeToTriggerSoftKeyboard.value_or(RequestKeyboardReason::OTHER)));
459 m_softwareKeyboardVisible = visible;
464 m_lastInputTypeToTriggerSoftKeyboard = inputType;
469 if (m_imConnectionState == ImConnectionState::Detached) {
470 qOhosDebug(QtForOhos) <<
"Cursor rectangle changed while detached; deferring update until attach";
471 m_updateCursorRectangleAfterAttaching =
true;
475 auto *focusedWindow = QGuiApplication::focusWindow();
476 if (focusedWindow ==
nullptr) {
477 qOhosCritical(QtForOhos)
478 <<
"Could not retrieve focused window. Updating cursor position isn't possible";
482 auto focusedWindowPosition = focusedWindow->mapToGlobal(QPoint(0, 0));
483 QRect cursorRectangle = QGuiApplication::inputMethod()->cursorRectangle().toRect();
484 if (!m_updateCursorRectangleAfterAttaching
485 && cursorRectangle == m_lastCursorRectangle
486 && m_lastFocusedWindowPosition == focusedWindowPosition) {
490 m_lastCursorRectangle = cursorRectangle;
491 m_lastFocusedWindowPosition = focusedWindowPosition;
492 auto globalInputItemRectangle =
493 QGuiApplication::inputMethod()->inputItemClipRectangle()
494 .translated(m_lastFocusedWindowPosition)
496 auto globalCursorRectangle = m_lastCursorRectangle.translated(m_lastFocusedWindowPosition);
497 auto inputItemClampedCursorPos = clampToRect(
498 {globalCursorRectangle.x(), globalCursorRectangle.y()},
499 globalInputItemRectangle.isValid()
500 ? globalInputItemRectangle
501 : QRect(focusedWindowPosition, focusedWindow->size()));
502 auto nativeCursorPos = QHighDpiScaling::mapPositionToNative(
503 inputItemClampedCursorPos, focusedWindow->screen()->handle());
504 auto screenBasedCursorPos = nativeCursorPos - focusedWindow->screen()->handle()->geometry().topLeft();
506 screenBasedCursorPos.x(), screenBasedCursorPos.y(),
507 globalCursorRectangle.width(), globalCursorRectangle.height()
509 m_updateCursorRectangleAfterAttaching =
false;
513 Qt::InputMethodHints qtInputMethodHints, Qt::EnterKeyType qtEnterKeyType)
515 if (m_imProxy ==
nullptr) {
516 qOhosPrintfError(
"%s: proxy doesn't exist!", Q_FUNC_INFO);
520 m_imProxy->notifyConfigurationChange(
521 mapQtToOhosImeEnterKeyType(qtEnterKeyType),
522 mapQtInputMethodHintsToOhosImeTextInputType(qtInputMethodHints));
527 if (m_imProxy ==
nullptr) {
528 qOhosPrintfError(
"%s: proxy doesn't exist!", Q_FUNC_INFO);
532 m_imProxy->notifyCursorUpdate(globalCursorRect);
537 if (m_imProxy ==
nullptr) {
538 qOhosPrintfError(
"%s: proxy doesn't exist!", Q_FUNC_INFO);
542 const auto textAroundCursor = queryQtImTextAroundCursorOrEmpty();
543 m_imProxy->setTextAroundCursor(
544 textAroundCursor.first.toStdU16String(),
545 textAroundCursor.second.toStdU16String(),
546 tryQueryCursorPosition().value_or(0));
551 if (m_imProxy ==
nullptr) {
552 qOhosPrintfError(
"%s: proxy doesn't exist!", Q_FUNC_INFO);
556 auto query = tryQueryFocusObjectInputMethod(
557 Qt::ImSurroundingText | Qt::ImCursorPosition | Qt::ImAnchorPosition);
561 const auto surroundingText = query->value(Qt::ImSurroundingText);
562 const auto cursorPosition = query->value(Qt::ImCursorPosition);
563 const auto anchorPosition = query->value(Qt::ImAnchorPosition);
565 if (!surroundingText.canConvert<QString>() || !cursorPosition.canConvert<
int>()
566 || !anchorPosition.canConvert<
int>())
569 const int cursor = cursorPosition.toInt();
570 const int anchor = anchorPosition.toInt();
572 m_imProxy->notifySelectionChange(
573 surroundingText.toString().toStdU16String(), std::min(anchor, cursor), std::max(anchor, cursor));
578 if (obj->isWidgetType() && queryImEnabled()) {
579 auto focusReason = event->reason();
580 if (focusReason == Qt::OtherFocusReason || focusReason == Qt::ActiveWindowFocusReason)
581 setLastInputTypeToTriggerSoftKeyboard(RequestKeyboardReason::NONE);
587 if (event->type() == QEvent::FocusIn)
588 handleFocusInEvent(obj,
static_cast<QFocusEvent *>(event));
594 auto query = tryQueryFocusObjectInputMethod(Qt::ImEnabled);
598 if (!query->value(Qt::ImEnabled).toBool()) {
599 qOhosDebug(QtForOhos) <<
"onInsertText(): focus object is not able to handle InputMethod";
603 m_pendingPreeditText.clear();
604 m_previewReplaceRange = {};
606 QInputMethodEvent event;
607 event.setCommitString(QString::fromStdString(textToInsert));
608 sendFocusObjectInputMethodEvent(&event);
613 auto query = tryQueryFocusObjectInputMethod(Qt::ImEnabled);
617 if (!query->value(Qt::ImEnabled).toBool()) {
618 qOhosPrintfDebug(
"%s: focus object is not able to handle InputMethod", Q_FUNC_INFO);
622 m_previewReplaceRange = {};
623 const auto cursor = tryQueryCursorPosition();
624 if (cursor && !(start < 0 && end < 0)) {
625 const int from = qMin(start, end);
626 const int to = qMax(start, end);
627 m_previewReplaceRange = { from - *cursor, to - from };
630 const QString previewString = QString::fromStdString(previewText);
631 QList<QInputMethodEvent::Attribute> imEventAttributes;
632 if (!previewString.isEmpty()) {
633 QTextCharFormat format;
634 format.setFontUnderline(
true);
635 imEventAttributes.append(
636 QInputMethodEvent::Attribute(
637 QInputMethodEvent::TextFormat, 0, previewString.length(), format));
640 m_pendingPreeditText = previewString;
642 QInputMethodEvent preeditStringEvent(previewString, imEventAttributes);
643 sendFocusObjectInputMethodEvent(&preeditStringEvent);
648 auto *focusObject = focusObjectOrNull();
649 if (focusObject ==
nullptr) {
650 qOhosWarning(QtForOhos) <<
"sendFocusObjectInputMethodEvent(): no focus object to send event to!";
654 QCoreApplication::sendEvent(focusObject, event);
660 case QOhosInputContext::Direction::CURSOR_UP:
661 sendFocusObjectFunctionalKeyEvent(Qt::Key_Up);
663 case QOhosInputContext::Direction::CURSOR_DOWN:
664 sendFocusObjectFunctionalKeyEvent(Qt::Key_Down);
666 case QOhosInputContext::Direction::CURSOR_LEFT:
667 sendFocusObjectFunctionalKeyEvent(Qt::Key_Left);
669 case QOhosInputContext::Direction::CURSOR_RIGHT:
670 sendFocusObjectFunctionalKeyEvent(Qt::Key_Right);
675void QOhosInputContext::sendFocusObjectFunctionalKeyEvent(Qt::Key key,
const QString &keyText,
int repeatCount)
677 auto *focusObject = focusObjectOrNull();
678 if (focusObject ==
nullptr) {
679 qOhosWarning(QtForOhos) <<
"sendFocusObjectFunctionalKeyEvent(): no focus object to send event to!";
683 for (
int i = 0; i < repeatCount; ++i) {
684 QGuiApplication::postEvent(focusObject,
new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier, keyText));
685 QGuiApplication::postEvent(focusObject,
new QKeyEvent(QEvent::KeyRelease, key, Qt::NoModifier, keyText));
691 auto query = tryQueryFocusObjectInputMethod(Qt::ImEnabled);
692 return !query.isNull() && query->value(Qt::ImEnabled).toBool();
697 std::optional<Qt::InputMethodHints> hints;
698 auto query = tryQueryFocusObjectInputMethod(Qt::ImHints);
699 if (!query.isNull()) {
700 auto imHintsInt = tryGetIntPropertyFromQuery(Qt::ImHints, query);
701 if (imHintsInt.has_value())
702 hints =
static_cast<Qt::InputMethodHints>(imHintsInt.value());
705 return hints.value_or(defaultInputMethodHints);
710 std::optional<Qt::EnterKeyType> enterKeyType;
711 auto query = tryQueryFocusObjectInputMethod(Qt::ImEnterKeyType);
712 if (!query.isNull()) {
713 auto imEnterKeyTypeInt = tryGetIntPropertyFromQuery(Qt::ImEnterKeyType, query);
714 if (imEnterKeyTypeInt.has_value())
715 enterKeyType =
static_cast<Qt::EnterKeyType>(imEnterKeyTypeInt.value());
718 return enterKeyType.value_or(defaultEnterKeyType);
723 auto query = tryQueryFocusObjectInputMethod(Qt::ImCursorPosition);
724 return !query.isNull()
725 ? tryGetIntPropertyFromQuery(Qt::ImCursorPosition, query)
729QSharedPointer<QInputMethodQueryEvent>
QOhosInputContext::tryQueryFocusObjectInputMethod(Qt::InputMethodQueries queries)
const
731 auto *focusObject = focusObjectOrNull();
732 if (focusObject ==
nullptr) {
733 qOhosWarning(QtForOhos) <<
"tryQueryFocusObjectInputMethod(): no focus object to query information from!";
737 auto imqEvent = QSharedPointer<QInputMethodQueryEvent>::create(queries);
738 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()