2024-03-22 23:08:52 +00:00
|
|
|
#include "TextInput.hpp"
|
|
|
|
|
#include "InputManager.hpp"
|
|
|
|
|
#include "../../protocols/TextInputV1.hpp"
|
2025-11-26 07:44:26 +09:00
|
|
|
#include "../../desktop/state/FocusState.hpp"
|
2024-04-25 23:27:25 +01:00
|
|
|
#include "../../protocols/TextInputV3.hpp"
|
2024-05-01 16:41:17 +01:00
|
|
|
#include "../../protocols/InputMethodV2.hpp"
|
2024-06-08 10:07:59 +02:00
|
|
|
#include "../../protocols/core/Compositor.hpp"
|
2024-03-22 23:08:52 +00:00
|
|
|
|
2025-05-01 23:57:11 +02:00
|
|
|
CTextInput::CTextInput(WP<CTextInputV1> ti) : m_v1Input(ti) {
|
2024-03-22 23:08:52 +00:00
|
|
|
initCallbacks();
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-01 23:57:11 +02:00
|
|
|
CTextInput::CTextInput(WP<CTextInputV3> ti) : m_v3Input(ti) {
|
2024-03-22 23:08:52 +00:00
|
|
|
initCallbacks();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CTextInput::initCallbacks() {
|
2024-04-25 23:27:25 +01:00
|
|
|
if (isV3()) {
|
2025-05-01 23:57:11 +02:00
|
|
|
const auto INPUT = m_v3Input.lock();
|
|
|
|
|
|
2025-07-08 09:56:40 -07:00
|
|
|
m_listeners.enable = INPUT->m_events.enable.listen([this] { onEnabled(); });
|
|
|
|
|
m_listeners.disable = INPUT->m_events.disable.listen([this] { onDisabled(); });
|
|
|
|
|
m_listeners.commit = INPUT->m_events.onCommit.listen([this] { onCommit(); });
|
|
|
|
|
m_listeners.reset = INPUT->m_events.reset.listen([this] { onReset(); });
|
|
|
|
|
m_listeners.destroy = INPUT->m_events.destroy.listen([this] {
|
2025-05-01 23:57:11 +02:00
|
|
|
m_listeners.surfaceUnmap.reset();
|
|
|
|
|
m_listeners.surfaceDestroy.reset();
|
|
|
|
|
g_pInputManager->m_relay.removeTextInput(this);
|
|
|
|
|
if (!g_pInputManager->m_relay.getFocusedTextInput())
|
|
|
|
|
g_pInputManager->m_relay.deactivateIME(this);
|
2024-04-25 23:27:25 +01:00
|
|
|
});
|
2024-09-06 04:04:23 +09:00
|
|
|
|
2025-11-26 07:44:26 +09:00
|
|
|
if (Desktop::focusState()->surface() && Desktop::focusState()->surface()->client() == INPUT->client())
|
|
|
|
|
enter(Desktop::focusState()->surface());
|
2024-04-25 23:27:25 +01:00
|
|
|
} else {
|
2025-05-01 23:57:11 +02:00
|
|
|
const auto INPUT = m_v1Input.lock();
|
2024-04-25 23:27:25 +01:00
|
|
|
|
2025-07-08 09:56:40 -07:00
|
|
|
m_listeners.enable = INPUT->m_events.enable.listen([this](const auto& surface) { onEnabled(surface); });
|
|
|
|
|
m_listeners.disable = INPUT->m_events.disable.listen([this] { onDisabled(); });
|
|
|
|
|
m_listeners.commit = INPUT->m_events.onCommit.listen([this] { onCommit(); });
|
|
|
|
|
m_listeners.reset = INPUT->m_events.reset.listen([this] { onReset(); });
|
|
|
|
|
m_listeners.destroy = INPUT->m_events.destroy.listen([this] {
|
2025-05-01 23:57:11 +02:00
|
|
|
m_listeners.surfaceUnmap.reset();
|
|
|
|
|
m_listeners.surfaceDestroy.reset();
|
|
|
|
|
g_pInputManager->m_relay.removeTextInput(this);
|
|
|
|
|
if (!g_pInputManager->m_relay.getFocusedTextInput())
|
|
|
|
|
g_pInputManager->m_relay.deactivateIME(this);
|
2024-07-29 11:14:19 -05:00
|
|
|
});
|
2024-04-25 23:27:25 +01:00
|
|
|
}
|
2024-03-22 23:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
2024-06-08 10:07:59 +02:00
|
|
|
void CTextInput::onEnabled(SP<CWLSurfaceResource> surfV1) {
|
2024-03-22 23:08:52 +00:00
|
|
|
Debug::log(LOG, "TI ENABLE");
|
|
|
|
|
|
2025-05-01 23:57:11 +02:00
|
|
|
if (g_pInputManager->m_relay.m_inputMethod.expired()) {
|
2024-03-22 23:08:52 +00:00
|
|
|
// Debug::log(WARN, "Enabling TextInput on no IME!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// v1 only, map surface to PTI
|
|
|
|
|
if (!isV3()) {
|
2025-11-26 07:44:26 +09:00
|
|
|
if (Desktop::focusState()->surface() != surfV1 || !m_v1Input->m_active)
|
2024-04-05 01:34:04 +09:00
|
|
|
return;
|
|
|
|
|
|
2024-12-07 18:51:18 +01:00
|
|
|
enter(surfV1);
|
2024-03-22 23:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
2025-05-01 23:57:11 +02:00
|
|
|
g_pInputManager->m_relay.activateIME(this);
|
2024-03-22 23:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CTextInput::onDisabled() {
|
2025-05-01 23:57:11 +02:00
|
|
|
if (g_pInputManager->m_relay.m_inputMethod.expired()) {
|
2024-03-22 23:08:52 +00:00
|
|
|
// Debug::log(WARN, "Disabling TextInput on no IME!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-27 00:16:09 +09:00
|
|
|
if (!isV3())
|
2024-03-28 02:28:16 +00:00
|
|
|
leave();
|
2024-03-22 23:08:52 +00:00
|
|
|
|
2025-05-01 23:57:11 +02:00
|
|
|
m_listeners.surfaceUnmap.reset();
|
|
|
|
|
m_listeners.surfaceDestroy.reset();
|
2024-03-22 23:08:52 +00:00
|
|
|
|
2024-09-06 04:04:23 +09:00
|
|
|
if (!focusedSurface())
|
|
|
|
|
return;
|
|
|
|
|
|
2025-05-01 23:57:11 +02:00
|
|
|
const auto PFOCUSEDTI = g_pInputManager->m_relay.getFocusedTextInput();
|
2024-09-06 04:04:23 +09:00
|
|
|
if (!PFOCUSEDTI || PFOCUSEDTI != this)
|
|
|
|
|
return;
|
|
|
|
|
|
2025-05-01 23:57:11 +02:00
|
|
|
g_pInputManager->m_relay.deactivateIME(this);
|
2024-03-22 23:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
2024-09-10 22:49:10 +09:00
|
|
|
void CTextInput::onReset() {
|
2025-05-01 23:57:11 +02:00
|
|
|
if (g_pInputManager->m_relay.m_inputMethod.expired())
|
2024-09-10 22:49:10 +09:00
|
|
|
return;
|
|
|
|
|
|
2024-09-16 01:31:38 +09:00
|
|
|
if (!focusedSurface())
|
|
|
|
|
return;
|
|
|
|
|
|
2025-05-01 23:57:11 +02:00
|
|
|
const auto PFOCUSEDTI = g_pInputManager->m_relay.getFocusedTextInput();
|
2024-09-16 01:31:38 +09:00
|
|
|
if (!PFOCUSEDTI || PFOCUSEDTI != this)
|
|
|
|
|
return;
|
|
|
|
|
|
2025-05-01 23:57:11 +02:00
|
|
|
g_pInputManager->m_relay.deactivateIME(this, false);
|
|
|
|
|
g_pInputManager->m_relay.activateIME(this);
|
2024-09-10 22:49:10 +09:00
|
|
|
}
|
|
|
|
|
|
2024-03-22 23:08:52 +00:00
|
|
|
void CTextInput::onCommit() {
|
2025-05-01 23:57:11 +02:00
|
|
|
if (g_pInputManager->m_relay.m_inputMethod.expired()) {
|
2024-03-22 23:08:52 +00:00
|
|
|
// Debug::log(WARN, "Committing TextInput on no IME!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-04 19:21:36 +02:00
|
|
|
if (!(isV3() ? m_v3Input->m_current.enabled.value : m_v1Input->m_active)) {
|
2024-03-22 23:08:52 +00:00
|
|
|
Debug::log(WARN, "Disabled TextInput commit?");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-01 23:57:11 +02:00
|
|
|
g_pInputManager->m_relay.commitIMEState(this);
|
2024-03-22 23:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
2024-06-08 10:07:59 +02:00
|
|
|
void CTextInput::setFocusedSurface(SP<CWLSurfaceResource> pSurface) {
|
2025-05-01 23:57:11 +02:00
|
|
|
if (pSurface == m_focusedSurface)
|
2024-03-22 23:08:52 +00:00
|
|
|
return;
|
|
|
|
|
|
2025-05-01 23:57:11 +02:00
|
|
|
m_focusedSurface = pSurface;
|
2024-03-22 23:08:52 +00:00
|
|
|
|
|
|
|
|
if (!pSurface)
|
|
|
|
|
return;
|
|
|
|
|
|
2025-05-01 23:57:11 +02:00
|
|
|
m_listeners.surfaceUnmap.reset();
|
|
|
|
|
m_listeners.surfaceDestroy.reset();
|
2024-09-06 04:04:23 +09:00
|
|
|
|
2025-07-08 09:56:40 -07:00
|
|
|
m_listeners.surfaceUnmap = pSurface->m_events.unmap.listen([this] {
|
2024-06-08 10:07:59 +02:00
|
|
|
Debug::log(LOG, "Unmap TI owner1");
|
|
|
|
|
|
2025-05-01 23:57:11 +02:00
|
|
|
if (m_enterLocks)
|
|
|
|
|
m_enterLocks--;
|
|
|
|
|
m_focusedSurface.reset();
|
|
|
|
|
m_listeners.surfaceUnmap.reset();
|
|
|
|
|
m_listeners.surfaceDestroy.reset();
|
|
|
|
|
|
2025-05-04 19:21:36 +02:00
|
|
|
if (isV3() && !m_v3Input.expired() && m_v3Input->m_current.enabled.value) {
|
|
|
|
|
m_v3Input->m_pending.enabled.value = false;
|
|
|
|
|
m_v3Input->m_pending.enabled.isDisablePending = false;
|
|
|
|
|
m_v3Input->m_pending.enabled.isEnablePending = false;
|
|
|
|
|
m_v3Input->m_current.enabled.value = false;
|
2024-09-13 01:41:24 +09:00
|
|
|
}
|
2024-09-06 04:04:23 +09:00
|
|
|
|
2025-05-01 23:57:11 +02:00
|
|
|
if (!g_pInputManager->m_relay.getFocusedTextInput())
|
|
|
|
|
g_pInputManager->m_relay.deactivateIME(this);
|
2024-06-08 10:07:59 +02:00
|
|
|
});
|
|
|
|
|
|
2025-07-08 09:56:40 -07:00
|
|
|
m_listeners.surfaceDestroy = pSurface->m_events.destroy.listen([this] {
|
2024-06-08 10:07:59 +02:00
|
|
|
Debug::log(LOG, "Destroy TI owner1");
|
|
|
|
|
|
2025-05-01 23:57:11 +02:00
|
|
|
if (m_enterLocks)
|
|
|
|
|
m_enterLocks--;
|
|
|
|
|
m_focusedSurface.reset();
|
|
|
|
|
m_listeners.surfaceUnmap.reset();
|
|
|
|
|
m_listeners.surfaceDestroy.reset();
|
|
|
|
|
|
2025-05-04 19:21:36 +02:00
|
|
|
if (isV3() && !m_v3Input.expired() && m_v3Input->m_current.enabled.value) {
|
|
|
|
|
m_v3Input->m_pending.enabled.value = false;
|
|
|
|
|
m_v3Input->m_pending.enabled.isDisablePending = false;
|
|
|
|
|
m_v3Input->m_pending.enabled.isEnablePending = false;
|
|
|
|
|
m_v3Input->m_current.enabled.value = false;
|
2024-09-13 01:41:24 +09:00
|
|
|
}
|
2024-09-06 04:04:23 +09:00
|
|
|
|
2025-05-01 23:57:11 +02:00
|
|
|
if (!g_pInputManager->m_relay.getFocusedTextInput())
|
|
|
|
|
g_pInputManager->m_relay.deactivateIME(this);
|
2024-06-08 10:07:59 +02:00
|
|
|
});
|
2024-03-22 23:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CTextInput::isV3() {
|
2025-05-01 23:57:11 +02:00
|
|
|
return m_v3Input && !m_v1Input;
|
2024-03-22 23:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
2024-06-08 10:07:59 +02:00
|
|
|
void CTextInput::enter(SP<CWLSurfaceResource> pSurface) {
|
2025-05-03 16:02:49 +02:00
|
|
|
if (!pSurface || !pSurface->m_mapped)
|
2024-03-22 23:08:52 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (pSurface == focusedSurface())
|
|
|
|
|
return;
|
|
|
|
|
|
2024-09-06 04:04:23 +09:00
|
|
|
if (focusedSurface())
|
2024-03-22 23:08:52 +00:00
|
|
|
leave();
|
|
|
|
|
|
2025-05-01 23:57:11 +02:00
|
|
|
m_enterLocks++;
|
|
|
|
|
if (m_enterLocks != 1) {
|
2024-03-30 17:00:56 +00:00
|
|
|
Debug::log(ERR, "BUG THIS: TextInput has != 1 locks in enter");
|
|
|
|
|
leave();
|
2025-05-01 23:57:11 +02:00
|
|
|
m_enterLocks = 1;
|
2024-03-30 17:00:56 +00:00
|
|
|
}
|
2024-03-22 23:08:52 +00:00
|
|
|
|
2024-04-25 23:27:25 +01:00
|
|
|
if (isV3())
|
2025-05-01 23:57:11 +02:00
|
|
|
m_v3Input->enter(pSurface);
|
2024-03-22 23:08:52 +00:00
|
|
|
else {
|
2025-05-01 23:57:11 +02:00
|
|
|
m_v1Input->enter(pSurface);
|
2024-03-22 23:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setFocusedSurface(pSurface);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CTextInput::leave() {
|
|
|
|
|
if (!focusedSurface())
|
|
|
|
|
return;
|
|
|
|
|
|
2025-05-01 23:57:11 +02:00
|
|
|
m_enterLocks--;
|
|
|
|
|
if (m_enterLocks != 0) {
|
2024-03-30 17:00:56 +00:00
|
|
|
Debug::log(ERR, "BUG THIS: TextInput has != 0 locks in leave");
|
2025-05-01 23:57:11 +02:00
|
|
|
m_enterLocks = 0;
|
2024-03-30 17:00:56 +00:00
|
|
|
}
|
2024-03-22 23:08:52 +00:00
|
|
|
|
2024-09-13 01:41:24 +09:00
|
|
|
if (isV3())
|
2025-05-01 23:57:11 +02:00
|
|
|
m_v3Input->leave(focusedSurface());
|
2024-09-13 01:41:24 +09:00
|
|
|
else
|
2025-05-01 23:57:11 +02:00
|
|
|
m_v1Input->leave();
|
2024-03-22 23:08:52 +00:00
|
|
|
|
|
|
|
|
setFocusedSurface(nullptr);
|
2024-03-31 21:30:30 +01:00
|
|
|
|
2025-05-01 23:57:11 +02:00
|
|
|
g_pInputManager->m_relay.deactivateIME(this);
|
2024-03-22 23:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
2024-06-08 10:07:59 +02:00
|
|
|
SP<CWLSurfaceResource> CTextInput::focusedSurface() {
|
2025-05-01 23:57:11 +02:00
|
|
|
return m_focusedSurface.lock();
|
2024-03-22 23:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wl_client* CTextInput::client() {
|
2025-05-01 23:57:11 +02:00
|
|
|
return isV3() ? m_v3Input->client() : m_v1Input->client();
|
2024-03-22 23:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
2024-05-01 16:41:17 +01:00
|
|
|
void CTextInput::commitStateToIME(SP<CInputMethodV2> ime) {
|
2025-05-01 23:57:11 +02:00
|
|
|
if (isV3() && !m_v3Input.expired()) {
|
|
|
|
|
const auto INPUT = m_v3Input.lock();
|
2024-04-25 23:27:25 +01:00
|
|
|
|
2025-05-04 19:21:36 +02:00
|
|
|
if (INPUT->m_current.surrounding.updated)
|
|
|
|
|
ime->surroundingText(INPUT->m_current.surrounding.text, INPUT->m_current.surrounding.cursor, INPUT->m_current.surrounding.anchor);
|
2024-03-22 23:08:52 +00:00
|
|
|
|
2025-05-04 19:21:36 +02:00
|
|
|
ime->textChangeCause(INPUT->m_current.cause);
|
2024-03-22 23:08:52 +00:00
|
|
|
|
2025-05-04 19:21:36 +02:00
|
|
|
if (INPUT->m_current.contentType.updated)
|
|
|
|
|
ime->textContentType(INPUT->m_current.contentType.hint, INPUT->m_current.contentType.purpose);
|
2025-05-01 23:57:11 +02:00
|
|
|
} else if (!m_v1Input.expired()) {
|
|
|
|
|
const auto INPUT = m_v1Input.lock();
|
2024-07-29 11:14:19 -05:00
|
|
|
|
2025-05-04 19:21:36 +02:00
|
|
|
if (INPUT->m_pendingSurrounding.isPending)
|
|
|
|
|
ime->surroundingText(INPUT->m_pendingSurrounding.text, INPUT->m_pendingSurrounding.cursor, INPUT->m_pendingSurrounding.anchor);
|
2024-03-22 23:08:52 +00:00
|
|
|
|
2024-05-01 16:41:17 +01:00
|
|
|
ime->textChangeCause(ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_INPUT_METHOD);
|
2024-03-22 23:08:52 +00:00
|
|
|
|
2025-05-04 19:21:36 +02:00
|
|
|
if (m_v1Input->m_pendingContentType.isPending)
|
2025-08-14 19:44:56 +05:00
|
|
|
ime->textContentType(sc<zwpTextInputV3ContentHint>(INPUT->m_pendingContentType.hint), sc<zwpTextInputV3ContentPurpose>(INPUT->m_pendingContentType.purpose));
|
2024-03-22 23:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
2025-05-01 23:57:11 +02:00
|
|
|
g_pInputManager->m_relay.updateAllPopups();
|
2024-03-22 23:08:52 +00:00
|
|
|
|
2024-05-01 16:41:17 +01:00
|
|
|
ime->done();
|
2024-03-22 23:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
2024-05-01 16:41:17 +01:00
|
|
|
void CTextInput::updateIMEState(SP<CInputMethodV2> ime) {
|
2024-03-22 23:08:52 +00:00
|
|
|
if (isV3()) {
|
2025-05-01 23:57:11 +02:00
|
|
|
const auto INPUT = m_v3Input.lock();
|
2024-03-22 23:08:52 +00:00
|
|
|
|
2025-05-04 00:13:29 +02:00
|
|
|
if (ime->m_current.preeditString.committed)
|
|
|
|
|
INPUT->preeditString(ime->m_current.preeditString.string, ime->m_current.preeditString.begin, ime->m_current.preeditString.end);
|
2024-03-22 23:08:52 +00:00
|
|
|
|
2025-05-04 00:13:29 +02:00
|
|
|
if (ime->m_current.committedString.committed)
|
|
|
|
|
INPUT->commitString(ime->m_current.committedString.string);
|
2024-04-25 23:27:25 +01:00
|
|
|
|
2025-05-04 00:13:29 +02:00
|
|
|
if (ime->m_current.deleteSurrounding.committed)
|
|
|
|
|
INPUT->deleteSurroundingText(ime->m_current.deleteSurrounding.before, ime->m_current.deleteSurrounding.after);
|
2024-03-22 23:08:52 +00:00
|
|
|
|
2024-04-25 23:27:25 +01:00
|
|
|
INPUT->sendDone();
|
2024-03-22 23:08:52 +00:00
|
|
|
} else {
|
2025-05-01 23:57:11 +02:00
|
|
|
const auto INPUT = m_v1Input.lock();
|
2024-07-29 11:14:19 -05:00
|
|
|
|
2025-05-04 00:13:29 +02:00
|
|
|
if (ime->m_current.preeditString.committed) {
|
|
|
|
|
INPUT->preeditCursor(ime->m_current.preeditString.begin);
|
|
|
|
|
INPUT->preeditStyling(0, std::string(ime->m_current.preeditString.string).length(), ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_HIGHLIGHT);
|
2025-05-04 19:21:36 +02:00
|
|
|
INPUT->preeditString(m_v1Input->m_serial, ime->m_current.preeditString.string.c_str(), "");
|
2024-03-22 23:08:52 +00:00
|
|
|
} else {
|
2024-09-09 17:58:44 +09:00
|
|
|
INPUT->preeditCursor(0);
|
2024-07-29 11:14:19 -05:00
|
|
|
INPUT->preeditStyling(0, 0, ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_HIGHLIGHT);
|
2025-05-04 19:21:36 +02:00
|
|
|
INPUT->preeditString(m_v1Input->m_serial, "", "");
|
2024-03-22 23:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
2025-05-04 00:13:29 +02:00
|
|
|
if (ime->m_current.committedString.committed)
|
2025-05-04 19:21:36 +02:00
|
|
|
INPUT->commitString(m_v1Input->m_serial, ime->m_current.committedString.string.c_str());
|
2024-03-22 23:08:52 +00:00
|
|
|
|
2025-05-04 00:13:29 +02:00
|
|
|
if (ime->m_current.deleteSurrounding.committed) {
|
|
|
|
|
INPUT->deleteSurroundingText(std::string(ime->m_current.preeditString.string).length() - ime->m_current.deleteSurrounding.before,
|
|
|
|
|
ime->m_current.deleteSurrounding.after + ime->m_current.deleteSurrounding.before);
|
2024-03-22 23:08:52 +00:00
|
|
|
|
2025-05-04 00:13:29 +02:00
|
|
|
if (ime->m_current.preeditString.committed)
|
2025-05-04 19:21:36 +02:00
|
|
|
INPUT->commitString(m_v1Input->m_serial, ime->m_current.preeditString.string.c_str());
|
2024-03-22 23:08:52 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CTextInput::hasCursorRectangle() {
|
2025-05-04 19:21:36 +02:00
|
|
|
return !isV3() || m_v3Input->m_current.box.updated;
|
2024-03-22 23:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CBox CTextInput::cursorBox() {
|
2025-05-04 19:21:36 +02:00
|
|
|
return CBox{isV3() ? m_v3Input->m_current.box.cursorBox : m_v1Input->m_cursorRectangle};
|
2024-07-29 11:14:19 -05:00
|
|
|
}
|