Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qohosinputmethodproxy.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#include <QtCore/private/qcore_ohos_p.h>
6#include <QtCore/private/qohoslogger_p.h>
7#include <QtCore/private/qstringconverter_p.h>
8#include <algorithm>
9#include <codecvt>
10#include <locale>
11#include <qarkui/qarkuiutils.h>
12#include <qohosutils.h>
13
15
16namespace {
17
18std::string convertUtf16ToUtf8(const std::u16string &utf16String)
19{
20#ifdef __cpp_lib_string_resize_and_overwrite
21 std::string ut8Str;
22 // In the worst case, we need atleast 3 bytes when converting from utf16
23 // to utf8
24 const auto maxBytes = utf16String.size() * 3;
25 utf8Str.resize_and_overwrite(maxBytes, [&] (char *dst, size_t) noexcept {
26 return QUtf8::convertFromUnicode(dst, QStringView{utf16String}) - dst;
27 });
28 return utf8Str;
29#else
30QT_WARNING_PUSH
31QT_WARNING_DISABLE_DEPRECATED
32 return std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.to_bytes(utf16String);
33QT_WARNING_POP
34#endif
35}
36
38{
39 return std::shared_ptr<::InputMethod_TextEditorProxy>(
40 QArkUi::callArkUiOrFailOnNullResult(
41 Q_OHOS_NAMED_FUNC(::OH_TextEditorProxy_Create)),
42 [](::InputMethod_TextEditorProxy *textEditorProxy) {
43 QArkUi::callArkUi(
44 Q_OHOS_NAMED_FUNC(::OH_TextEditorProxy_Destroy),
45 textEditorProxy);
46 });
47}
48
50 bool showKeyboard, ::InputMethod_RequestKeyboardReason requestKeyboardReason)
51{
52 return std::shared_ptr<::InputMethod_AttachOptions>(
53 QArkUi::callArkUiOrFailOnNullResult(
54 Q_OHOS_NAMED_FUNC(::OH_AttachOptions_CreateWithRequestKeyboardReason),
55 showKeyboard, requestKeyboardReason),
56 [](::InputMethod_AttachOptions *attachOptions) {
57 QArkUi::callArkUi(
58 Q_OHOS_NAMED_FUNC(::OH_AttachOptions_Destroy),
59 attachOptions);
60 });
61}
62
64 std::shared_ptr<::InputMethod_TextEditorProxy> textEditorProxy,
65 std::shared_ptr<::InputMethod_AttachOptions> attachOptions)
66{
67 ::InputMethod_InputMethodProxy *inputMethodProxyPtr = nullptr;
68 ::InputMethod_ErrorCode errcode = QArkUi::callArkUi(
69 Q_OHOS_NAMED_FUNC(::OH_InputMethodController_Attach),
70 textEditorProxy.get(), attachOptions.get(), &inputMethodProxyPtr);
71 if (errcode != ::InputMethod_ErrorCode::IME_ERR_OK) {
72 qOhosPrintfError("%s: OH_InputMethodController_Attach failed!", Q_FUNC_INFO);
73 return {};
74 }
75
76 return std::shared_ptr<::InputMethod_InputMethodProxy>(
77 inputMethodProxyPtr, [](::InputMethod_InputMethodProxy *proxy) {
78 QArkUi::callArkUiOrFailOnErrorResult(
79 Q_OHOS_NAMED_FUNC(::OH_InputMethodController_Detach), proxy);
80 });
81}
82
84 double x, double y, double width, double height)
85{
86 return std::shared_ptr<::InputMethod_CursorInfo>(
87 QArkUi::callArkUiOrFailOnNullResult(
88 Q_OHOS_NAMED_FUNC(::OH_CursorInfo_Create),
89 x, y, width, height),
90 [](::InputMethod_CursorInfo *cursorInfo) {
91 QArkUi::callArkUi(
92 Q_OHOS_NAMED_FUNC(::OH_CursorInfo_Destroy), cursorInfo);
93 });
94}
95
96template<typename CallbackResult, typename... CallbackArgs>
98template<
99 typename CallbackResult,
100 typename... CallbackArgs,
101 ::InputMethod_ErrorCode rawSetCallbackFunc(::InputMethod_TextEditorProxy *, TextEditorProxyCallbackFunc<CallbackResult, CallbackArgs...>)>
103 ::InputMethod_TextEditorProxy *textEditorProxy,
104 QOhosNamedFunc<::InputMethod_ErrorCode(*)(::InputMethod_TextEditorProxy *, TextEditorProxyCallbackFunc<CallbackResult, CallbackArgs...>), rawSetCallbackFunc> setCallbackFunc,
105 std::function<CallbackResult(CallbackArgs...)> callback)
106{
107 static std::map<::InputMethod_TextEditorProxy *, std::shared_ptr<std::function<CallbackResult(CallbackArgs...)>>> callbacksMap;
108
109 bool callbackRegistered;
110 std::tie(std::ignore, callbackRegistered) = callbacksMap.emplace(
111 textEditorProxy,
112 std::make_shared<std::function<CallbackResult(CallbackArgs...)>>(std::move(callback)));
113
114 if (!callbackRegistered)
115 qOhosReportFatalErrorAndAbort(Q_FUNC_INFO, "encountered duplicate callback registration for %p", textEditorProxy);
116
117 QArkUi::callArkUiOrFailOnErrorResult(
118 setCallbackFunc, textEditorProxy,
119 [](::InputMethod_TextEditorProxy *textEditorProxy, CallbackArgs ...callbackArgs) {
120 auto callbackIter = callbacksMap.find(textEditorProxy);
121 if (callbackIter != callbacksMap.end()) {
122 auto sharedCallback = callbackIter->second;
123 return (*sharedCallback)(callbackArgs...);
124 } else {
125 return CallbackResult();
126 }
127 });
128
129 return QtOhos::makeDestroyNotifier(
130 [textEditorProxy]() {
131 callbacksMap.erase(textEditorProxy);
132 });
133}
134
135template<
136 typename CallbackResult,
137 typename... CallbackArgs,
138 ::InputMethod_ErrorCode rawSetCallbackFunc(::InputMethod_TextEditorProxy *, TextEditorProxyCallbackFunc<CallbackResult, CallbackArgs...>),
139 typename Callback>
141 ::InputMethod_TextEditorProxy *textEditorProxy,
142 QOhosNamedFunc<::InputMethod_ErrorCode(*)(::InputMethod_TextEditorProxy *, TextEditorProxyCallbackFunc<CallbackResult, CallbackArgs...>), rawSetCallbackFunc> setCallbackFunc,
143 Callback callback)
144{
145 static_assert(std::is_assignable<std::function<CallbackResult(CallbackArgs...)>, Callback>::value, "");
146 return registerTextEditorProxyCallbackImpl<CallbackResult>(
147 textEditorProxy, setCallbackFunc, std::function<CallbackResult(CallbackArgs...)>(std::move(callback)));
148}
149
150template<typename... CallbackArgs>
152 std::weak_ptr<QOhosInputMethodProxy::ClientCallbacks> weakClientCallbacks,
153 void (QOhosInputMethodProxy::ClientCallbacks::*callbackMemPtr)(CallbackArgs...),
154 CallbackArgs ...args)
155{
156 QtOhos::invokeInQtThread(
157 [weakClientCallbacks, callbackMemPtr, args...]() {
158 auto clientCallbacks = weakClientCallbacks.lock();
159 if (clientCallbacks)
160 (clientCallbacks.get()->*callbackMemPtr)(args...);
161 });
162}
163
164}
165
166std::shared_ptr<void> QOhosInputMethodProxy::registerCallbacks(
167 std::shared_ptr<::InputMethod_TextEditorProxy> textEditorProxy,
168 std::shared_ptr<JsScopeData::JsTextEditorProxyData> textEditorProxyData,
169 std::shared_ptr<QOhosMutexProtectedValue<TextAroundCursor>> textAroundCursor,
170 std::weak_ptr<QOhosInputMethodProxy::ClientCallbacks> weakClientCallbacks)
171{
172 std::vector<std::shared_ptr<void>> registrationHandles;
173
174 registrationHandles.push_back(
175 registerTextEditorProxyCallback(
176 textEditorProxy.get(), Q_OHOS_NAMED_FUNC(::OH_TextEditorProxy_SetGetTextConfigFunc),
177 [](::InputMethod_TextConfig *config) {
178 QArkUi::callArkUiOrFailOnErrorResult(
179 Q_OHOS_NAMED_FUNC(::OH_TextConfig_SetPreviewTextSupport),
180 config, true);
181 }));
182
183 registrationHandles.push_back(
184 registerTextEditorProxyCallback(
185 textEditorProxy.get(), Q_OHOS_NAMED_FUNC(::OH_TextEditorProxy_SetInsertTextFunc),
186 [weakClientCallbacks](const char16_t *text, size_t length) {
187 std::u16string utf16Text(text, length);
188 callInQtThread(
190 convertUtf16ToUtf8(utf16Text));
191 }));
192
193 registrationHandles.push_back(
194 registerTextEditorProxyCallback(
195 textEditorProxy.get(), Q_OHOS_NAMED_FUNC(::OH_TextEditorProxy_SetDeleteForwardFunc),
196 [weakClientCallbacks](std::int32_t length) {
197 callInQtThread(
199 length);
200 }));
201
202 registrationHandles.push_back(
203 registerTextEditorProxyCallback(
204 textEditorProxy.get(), Q_OHOS_NAMED_FUNC(::OH_TextEditorProxy_SetDeleteBackwardFunc),
205 [weakClientCallbacks](std::int32_t length) {
206 callInQtThread(
208 length);
209 }));
210
211 registrationHandles.push_back(
212 registerTextEditorProxyCallback(
213 textEditorProxy.get(), Q_OHOS_NAMED_FUNC(::OH_TextEditorProxy_SetSendKeyboardStatusFunc),
214 [weakClientCallbacks, weakTextEditorProxyData = QtOhos::makeWeakPtr(textEditorProxyData)](::InputMethod_KeyboardStatus keyboardStatus) {
215 auto sharedTextEditorProxyData = weakTextEditorProxyData.lock();
216 if (sharedTextEditorProxyData)
217 sharedTextEditorProxyData->textInputShown = keyboardStatus == ::IME_KEYBOARD_STATUS_SHOW;
218
219 callInQtThread(
220 weakClientCallbacks, &QOhosInputMethodProxy::ClientCallbacks::onSendKeyboardStatus,
221 keyboardStatus);
222 }));
223
224 registrationHandles.push_back(
225 registerTextEditorProxyCallback(
226 textEditorProxy.get(), Q_OHOS_NAMED_FUNC(::OH_TextEditorProxy_SetSendEnterKeyFunc),
227 [weakClientCallbacks](::InputMethod_EnterKeyType enterKeyType) {
228 callInQtThread(
229 weakClientCallbacks, &QOhosInputMethodProxy::ClientCallbacks::onSendEnterKey,
230 enterKeyType);
231 }));
232
233 registrationHandles.push_back(
234 registerTextEditorProxyCallback(
235 textEditorProxy.get(), Q_OHOS_NAMED_FUNC(::OH_TextEditorProxy_SetMoveCursorFunc),
236 [weakClientCallbacks](::InputMethod_Direction direction) {
237 callInQtThread(
238 weakClientCallbacks, &QOhosInputMethodProxy::ClientCallbacks::onMoveCursor,
239 direction);
240 }));
241
242 registrationHandles.push_back(
243 registerTextEditorProxyCallback(
244 textEditorProxy.get(), Q_OHOS_NAMED_FUNC(::OH_TextEditorProxy_SetHandleSetSelectionFunc),
245 [](auto...) {
246 }));
247
248 registrationHandles.push_back(
249 registerTextEditorProxyCallback(
250 textEditorProxy.get(), Q_OHOS_NAMED_FUNC(::OH_TextEditorProxy_SetHandleExtendActionFunc),
251 [](auto...) {
252 }));
253
254 auto makeGetTextOfCursorCallback = [weakTextAroundCursor = QtOhos::makeWeakPtr(textAroundCursor)](
255 std::function<std::u16string(const TextAroundCursor &, std::size_t maxLength)> selectFromTextAroundCursorFunc) {
256 return [weakTextAroundCursor, selectFromTextAroundCursorFunc = std::move(selectFromTextAroundCursorFunc)](
257 int32_t maxLength, char16_t *outBuffer, std::size_t *outLength) {
258 auto protectedTextAroundCursor = weakTextAroundCursor.lock();
259 if (!protectedTextAroundCursor) {
260 qOhosPrintfDebug("%s: cannot get text of cursor", Q_FUNC_INFO);
261 *outLength = 0;
262 return;
263 }
264
265 const auto selectedText = protectedTextAroundCursor->evalWithValue(
266 [maxLength, &selectFromTextAroundCursorFunc](const TextAroundCursor &textAroundCursor) {
267 return selectFromTextAroundCursorFunc(textAroundCursor, static_cast<std::size_t>(maxLength));
268 });
269 *outLength = selectedText.copy(outBuffer, selectedText.size());
270 };
271 };
272
273 registrationHandles.push_back(
274 registerTextEditorProxyCallback(
275 textEditorProxy.get(), Q_OHOS_NAMED_FUNC(::OH_TextEditorProxy_SetGetLeftTextOfCursorFunc),
276 makeGetTextOfCursorCallback(
277 [](const TextAroundCursor &textAroundCursor, std::size_t maxLength) {
278 const auto &leftText = textAroundCursor.leftText;
279 return leftText.substr(leftText.size() - std::min(maxLength, leftText.size()));
280 })));
281
282 registrationHandles.push_back(
283 registerTextEditorProxyCallback(
284 textEditorProxy.get(), Q_OHOS_NAMED_FUNC(::OH_TextEditorProxy_SetGetRightTextOfCursorFunc),
285 makeGetTextOfCursorCallback(
286 [](const TextAroundCursor &textAroundCursor, std::size_t maxLength) {
287 const auto &rightText = textAroundCursor.rightText;
288 return rightText.substr(0, std::min(maxLength, rightText.size()));
289 })));
290
291 registrationHandles.push_back(
292 registerTextEditorProxyCallback(
293 textEditorProxy.get(), Q_OHOS_NAMED_FUNC(::OH_TextEditorProxy_SetGetTextIndexAtCursorFunc),
294 [weakTextAroundCursor = QtOhos::makeWeakPtr(textAroundCursor)]() {
295 auto protectedTextAroundCursor = weakTextAroundCursor.lock();
296 if (!protectedTextAroundCursor) {
297 qOhosPrintfWarning("%s: cannot get text index at cursor", Q_FUNC_INFO);
298 return 0;
299 }
300
301 return protectedTextAroundCursor->evalWithValue(
302 [](const TextAroundCursor &textAroundCursor) {
303 return textAroundCursor.cursorIndex;
304 });
305 }));
306
307 QArkUi::callArkUiOrFailOnErrorResult(
308 Q_OHOS_NAMED_FUNC(::OH_TextEditorProxy_SetReceivePrivateCommandFunc),
309 textEditorProxy.get(),
310 [](::InputMethod_TextEditorProxy *, ::InputMethod_PrivateCommand **, unsigned long) {
311 return 0;
312 });
313
314 registrationHandles.push_back(
315 registerTextEditorProxyCallback(
316 textEditorProxy.get(),
317 Q_OHOS_NAMED_FUNC(::OH_TextEditorProxy_SetSetPreviewTextFunc),
318 [weakClientCallbacks](const char16_t *text, std::size_t length, std::int32_t start, std::int32_t end) {
319 std::u16string utf16Text(text, length);
320 callInQtThread(
322 convertUtf16ToUtf8(utf16Text), start, end);
323 return 0;
324 }));
325
326 registrationHandles.push_back(
327 registerTextEditorProxyCallback(
328 textEditorProxy.get(), Q_OHOS_NAMED_FUNC(::OH_TextEditorProxy_SetFinishTextPreviewFunc),
329 [weakClientCallbacks]() {
330 callInQtThread(
332 }));
333
334 return QtOhos::moveToSharedPtr(std::move(registrationHandles));
335}
336
338 std::shared_ptr<ClientCallbacks> clientCallbacks, ::InputMethod_RequestKeyboardReason requestKeyboardReason)
341{
342 auto weakClientCallbacks = QtOhos::makeWeakPtr(clientCallbacks);
343 m_optJsScopeData.emplace();
344 bool attachedSuccessfully = QOhosJsThreadGateway::eval(
345 [&](auto &) {
346 auto textEditorProxyData = std::make_shared<JsScopeData::JsTextEditorProxyData>();
347 auto textEditorProxy = makeTextEditorProxy();
348 auto callbacksRegistrationHandle = registerCallbacks(
349 textEditorProxy, textEditorProxyData, m_textAroundCursor, weakClientCallbacks);
350
351 auto showKeyboard = true;
352 auto attachOptions = makeAttachOptions(showKeyboard, requestKeyboardReason);
353
354 auto inputMethodProxy = tryMakeInputMethodProxy(textEditorProxy, attachOptions);
355 if (!inputMethodProxy) {
356 qOhosPrintfError("%s: inputMethodProxy is nullptr!", Q_FUNC_INFO);
357 return false;
358 }
359
360 **m_optJsScopeData = JsScopeData {
361 .textEditorProxy = textEditorProxy,
362 .textEditorProxyData = textEditorProxyData,
363 .inputMethodProxy = inputMethodProxy,
364 .callbacksRegistrationHandle = callbacksRegistrationHandle,
365 };
366
367 return true;
368 },
369 Q_FUNC_INFO);
370 if (!attachedSuccessfully)
371 m_optJsScopeData.reset();
372}
373
375{
376 return m_optJsScopeData.has_value();
377}
378
379void QOhosInputMethodProxy::showTextInput(::InputMethod_RequestKeyboardReason requestKeyboardReason)
380{
382 qOhosPrintfError("%s: operation aborted, IMC not attached.", Q_FUNC_INFO);
383 return;
384 }
385
386 QOhosJsThreadGateway::runAndWait(
387 [&](QOhosJsState &) {
388 if ((*m_optJsScopeData)->textEditorProxyData->textInputShown) {
389 qOhosPrintfDebug("%s: text input already shown, skip showing it again", Q_FUNC_INFO);
390 return;
391 }
392
393 auto showKeyboard = true;
394 auto attachOptions = makeAttachOptions(showKeyboard, requestKeyboardReason);
395
396 ::InputMethod_ErrorCode errcode = QArkUi::callArkUi(
397 Q_OHOS_NAMED_FUNC(::OH_InputMethodProxy_ShowTextInput),
398 (*m_optJsScopeData)->inputMethodProxy.get(),
399 attachOptions.get());
400 (*m_optJsScopeData)->textEditorProxyData->textInputShown = errcode == ::InputMethod_ErrorCode::IME_ERR_OK;
401 if (errcode != ::InputMethod_ErrorCode::IME_ERR_OK)
402 qOhosPrintfError("%s: OH_InputMethodProxy_ShowTextInput failed!", Q_FUNC_INFO);
403 },
404 Q_FUNC_INFO);
405}
406
408 ::InputMethod_EnterKeyType enterKeyType, ::InputMethod_TextInputType textInputType)
409{
411 qOhosPrintfError("%s: operation aborted, IMC not attached.", Q_FUNC_INFO);
412 return;
413 }
414
415 QOhosJsThreadGateway::runAndWait(
416 [&](QOhosJsState &) {
417 ::InputMethod_ErrorCode errcode = QArkUi::callArkUi(
418 Q_OHOS_NAMED_FUNC(::OH_InputMethodProxy_NotifyConfigurationChange),
419 (*m_optJsScopeData)->inputMethodProxy.get(),
420 enterKeyType, textInputType);
421 if (errcode != ::InputMethod_ErrorCode::IME_ERR_OK)
422 qOhosPrintfError("%s: OH_InputMethodProxy_NotifyConfigurationChange failed!", Q_FUNC_INFO);
423 },
424 Q_FUNC_INFO);
425}
426
427void QOhosInputMethodProxy::notifyCursorUpdate(const QRectF &cursorRect)
428{
430 qOhosPrintfError("%s: operation aborted, IMC not attached.", Q_FUNC_INFO);
431 return;
432 }
433
434 double x = cursorRect.x();
435 double y = cursorRect.y();
436 double width = cursorRect.width();
437 double height = cursorRect.height();
438
439 QOhosJsThreadGateway::runAndWait(
440 [&](QOhosJsState &) {
441 auto ohCursorInfo = makeCursorInfo(x, y, width, height);
442
443 ::InputMethod_ErrorCode errcode = QArkUi::callArkUi(
444 Q_OHOS_NAMED_FUNC(::OH_InputMethodProxy_NotifyCursorUpdate),
445 (*m_optJsScopeData)->inputMethodProxy.get(), ohCursorInfo.get());
446 if (errcode != ::InputMethod_ErrorCode::IME_ERR_OK)
447 qOhosPrintfError("%s: OH_InputMethodProxy_NotifyCursorUpdate failed!", Q_FUNC_INFO);
448 },
449 Q_FUNC_INFO);
450}
451
452void QOhosInputMethodProxy::notifySelectionChange(std::u16string text, int start, int end)
453{
455 qOhosPrintfError("%s: operation aborted, IMC not attached.", Q_FUNC_INFO);
456 return;
457 }
458
459 QOhosJsThreadGateway::runAndWait(
460 [&](QOhosJsState &) {
461 ::InputMethod_ErrorCode errcode = QArkUi::callArkUi(
462 Q_OHOS_NAMED_FUNC(::OH_InputMethodProxy_NotifySelectionChange),
463 (*m_optJsScopeData)->inputMethodProxy.get(), &text[0], text.size(), start, end);
464 if (errcode != ::InputMethod_ErrorCode::IME_ERR_OK)
465 qOhosPrintfError(
466 "%s: OH_InputMethodProxy_NotifySelectionChange failed with error code: %d", Q_FUNC_INFO,
467 errcode);
468 },
469 Q_FUNC_INFO);
470}
471
473 std::u16string leftText, std::u16string rightText, int cursorIndex)
474{
476 qOhosPrintfError("%s: operation aborted, IMC not attached.", Q_FUNC_INFO);
477 return;
478 }
479
480 m_textAroundCursor->processValue(
481 [&](TextAroundCursor &textAroundCursor) {
482 textAroundCursor.leftText = std::move(leftText);
483 textAroundCursor.rightText = std::move(rightText);
484 textAroundCursor.cursorIndex = cursorIndex;
485 });
486}
487
489
491
492QT_END_NAMESPACE
virtual void onDeleteForward(int length)=0
virtual void onInsertText(std::string text)=0
virtual void onInsertPreviewText(std::string text, int start, int end)=0
virtual void onDeleteBackward(int length)=0
void notifyConfigurationChange(::InputMethod_EnterKeyType enterKeyType, ::InputMethod_TextInputType textInputType)
void notifySelectionChange(std::u16string text, int start, int end)
void showTextInput(::InputMethod_RequestKeyboardReason requestKeyboardReason)
QOhosInputMethodProxy(std::shared_ptr< ClientCallbacks > clientCallbacks, ::InputMethod_RequestKeyboardReason requestKeyboardReason)
void notifyCursorUpdate(const QRectF &cursorRect)
void setTextAroundCursor(std::u16string leftText, std::u16string rightText, int cursorIndex)
Combined button and popup list for selecting options.
std::shared_ptr< void > registerTextEditorProxyCallback(::InputMethod_TextEditorProxy *textEditorProxy, QOhosNamedFunc<::InputMethod_ErrorCode(*)(::InputMethod_TextEditorProxy *, TextEditorProxyCallbackFunc< CallbackResult, CallbackArgs... >), rawSetCallbackFunc > setCallbackFunc, Callback callback)
void callInQtThread(std::weak_ptr< QOhosInputMethodProxy::ClientCallbacks > weakClientCallbacks, void(QOhosInputMethodProxy::ClientCallbacks::*callbackMemPtr)(CallbackArgs...), CallbackArgs ...args)
std::shared_ptr<::InputMethod_AttachOptions > makeAttachOptions(bool showKeyboard, ::InputMethod_RequestKeyboardReason requestKeyboardReason)
std::shared_ptr<::InputMethod_CursorInfo > makeCursorInfo(double x, double y, double width, double height)
std::shared_ptr< void > registerTextEditorProxyCallbackImpl(::InputMethod_TextEditorProxy *textEditorProxy, QOhosNamedFunc<::InputMethod_ErrorCode(*)(::InputMethod_TextEditorProxy *, TextEditorProxyCallbackFunc< CallbackResult, CallbackArgs... >), rawSetCallbackFunc > setCallbackFunc, std::function< CallbackResult(CallbackArgs...)> callback)
CallbackResult(::InputMethod_TextEditorProxy *, CallbackArgs...) TextEditorProxyCallbackFunc
std::string convertUtf16ToUtf8(const std::u16string &utf16String)
std::shared_ptr<::InputMethod_TextEditorProxy > makeTextEditorProxy()
std::shared_ptr<::InputMethod_InputMethodProxy > tryMakeInputMethodProxy(std::shared_ptr<::InputMethod_TextEditorProxy > textEditorProxy, std::shared_ptr<::InputMethod_AttachOptions > attachOptions)