textinput: handle IME resetting (#7731)

This commit is contained in:
Sungyoon Cho 2024-09-10 22:49:10 +09:00 committed by GitHub
parent 13f90bb87a
commit 155d44016d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 49 additions and 19 deletions

View file

@ -106,20 +106,22 @@ void CInputMethodRelay::updateAllPopups() {
} }
} }
void CInputMethodRelay::activateIME(CTextInput* pInput) { void CInputMethodRelay::activateIME(CTextInput* pInput, bool shouldCommit) {
if (m_pIME.expired()) if (m_pIME.expired())
return; return;
m_pIME->activate(); m_pIME->activate();
commitIMEState(pInput); if (shouldCommit)
commitIMEState(pInput);
} }
void CInputMethodRelay::deactivateIME(CTextInput* pInput) { void CInputMethodRelay::deactivateIME(CTextInput* pInput, bool shouldCommit) {
if (m_pIME.expired()) if (m_pIME.expired())
return; return;
m_pIME->deactivate(); m_pIME->deactivate();
commitIMEState(pInput); if (shouldCommit)
commitIMEState(pInput);
} }
void CInputMethodRelay::commitIMEState(CTextInput* pInput) { void CInputMethodRelay::commitIMEState(CTextInput* pInput) {

View file

@ -21,8 +21,8 @@ class CInputMethodRelay {
void onNewTextInput(WP<CTextInputV3> tiv3); void onNewTextInput(WP<CTextInputV3> tiv3);
void onNewTextInput(WP<CTextInputV1> pTIV1); void onNewTextInput(WP<CTextInputV1> pTIV1);
void activateIME(CTextInput* pInput); void activateIME(CTextInput* pInput, bool shouldCommit = true);
void deactivateIME(CTextInput* pInput); void deactivateIME(CTextInput* pInput, bool shouldCommit = true);
void commitIMEState(CTextInput* pInput); void commitIMEState(CTextInput* pInput);
void removeTextInput(CTextInput* pInput); void removeTextInput(CTextInput* pInput);

View file

@ -22,6 +22,7 @@ void CTextInput::initCallbacks() {
listeners.enable = INPUT->events.enable.registerListener([this](std::any p) { onEnabled(); }); listeners.enable = INPUT->events.enable.registerListener([this](std::any p) { onEnabled(); });
listeners.disable = INPUT->events.disable.registerListener([this](std::any p) { onDisabled(); }); listeners.disable = INPUT->events.disable.registerListener([this](std::any p) { onDisabled(); });
listeners.commit = INPUT->events.onCommit.registerListener([this](std::any p) { onCommit(); }); listeners.commit = INPUT->events.onCommit.registerListener([this](std::any p) { onCommit(); });
listeners.reset = INPUT->events.reset.registerListener([this](std::any p) { onReset(); });
listeners.destroy = INPUT->events.destroy.registerListener([this](std::any p) { listeners.destroy = INPUT->events.destroy.registerListener([this](std::any p) {
listeners.surfaceUnmap.reset(); listeners.surfaceUnmap.reset();
listeners.surfaceDestroy.reset(); listeners.surfaceDestroy.reset();
@ -41,6 +42,7 @@ void CTextInput::initCallbacks() {
}); });
listeners.disable = INPUT->events.disable.registerListener([this](std::any p) { onDisabled(); }); listeners.disable = INPUT->events.disable.registerListener([this](std::any p) { onDisabled(); });
listeners.commit = INPUT->events.onCommit.registerListener([this](std::any p) { onCommit(); }); listeners.commit = INPUT->events.onCommit.registerListener([this](std::any p) { onCommit(); });
listeners.reset = INPUT->events.reset.registerListener([this](std::any p) { onReset(); });
listeners.destroy = INPUT->events.destroy.registerListener([this](std::any p) { listeners.destroy = INPUT->events.destroy.registerListener([this](std::any p) {
listeners.surfaceUnmap.reset(); listeners.surfaceUnmap.reset();
listeners.surfaceDestroy.reset(); listeners.surfaceDestroy.reset();
@ -93,13 +95,21 @@ void CTextInput::onDisabled() {
g_pInputManager->m_sIMERelay.deactivateIME(this); g_pInputManager->m_sIMERelay.deactivateIME(this);
} }
void CTextInput::onReset() {
if (g_pInputManager->m_sIMERelay.m_pIME.expired())
return;
g_pInputManager->m_sIMERelay.deactivateIME(this, false);
g_pInputManager->m_sIMERelay.activateIME(this);
}
void CTextInput::onCommit() { void CTextInput::onCommit() {
if (g_pInputManager->m_sIMERelay.m_pIME.expired()) { if (g_pInputManager->m_sIMERelay.m_pIME.expired()) {
// Debug::log(WARN, "Committing TextInput on no IME!"); // Debug::log(WARN, "Committing TextInput on no IME!");
return; return;
} }
if (!(isV3() ? pV3Input->current.enabled : pV1Input->active)) { if (!(isV3() ? pV3Input->current.enabled.value : pV1Input->active)) {
Debug::log(WARN, "Disabled TextInput commit?"); Debug::log(WARN, "Disabled TextInput commit?");
return; return;
} }
@ -128,8 +138,8 @@ void CTextInput::setFocusedSurface(SP<CWLSurfaceResource> pSurface) {
listeners.surfaceUnmap.reset(); listeners.surfaceUnmap.reset();
listeners.surfaceDestroy.reset(); listeners.surfaceDestroy.reset();
if (isV3() && !pV3Input.expired() && pV3Input->current.enabled) if (isV3() && !pV3Input.expired() && pV3Input->current.enabled.value)
pV3Input->current.enabled = false; pV3Input->current.enabled.value = false;
if (!g_pInputManager->m_sIMERelay.getFocusedTextInput()) if (!g_pInputManager->m_sIMERelay.getFocusedTextInput())
g_pInputManager->m_sIMERelay.deactivateIME(this); g_pInputManager->m_sIMERelay.deactivateIME(this);
@ -144,8 +154,8 @@ void CTextInput::setFocusedSurface(SP<CWLSurfaceResource> pSurface) {
listeners.surfaceUnmap.reset(); listeners.surfaceUnmap.reset();
listeners.surfaceDestroy.reset(); listeners.surfaceDestroy.reset();
if (isV3() && !pV3Input.expired() && pV3Input->current.enabled) if (isV3() && !pV3Input.expired() && pV3Input->current.enabled.value)
pV3Input->current.enabled = false; pV3Input->current.enabled.value = false;
if (!g_pInputManager->m_sIMERelay.getFocusedTextInput()) if (!g_pInputManager->m_sIMERelay.getFocusedTextInput())
g_pInputManager->m_sIMERelay.deactivateIME(this); g_pInputManager->m_sIMERelay.deactivateIME(this);
@ -194,8 +204,8 @@ void CTextInput::leave() {
if (isV3()) { if (isV3()) {
pV3Input->leave(focusedSurface()); pV3Input->leave(focusedSurface());
if (pV3Input->current.enabled) { if (pV3Input->current.enabled.value) {
pV3Input->current.enabled = false; pV3Input->current.enabled.value = false;
onDisabled(); onDisabled();
} }
} else } else

View file

@ -29,6 +29,7 @@ class CTextInput {
void onEnabled(SP<CWLSurfaceResource> surfV1 = nullptr); void onEnabled(SP<CWLSurfaceResource> surfV1 = nullptr);
void onDisabled(); void onDisabled();
void onCommit(); void onCommit();
void onReset();
bool hasCursorRectangle(); bool hasCursorRectangle();
CBox cursorBox(); CBox cursorBox();
@ -47,6 +48,7 @@ class CTextInput {
struct { struct {
CHyprSignalListener enable; CHyprSignalListener enable;
CHyprSignalListener disable; CHyprSignalListener disable;
CHyprSignalListener reset;
CHyprSignalListener commit; CHyprSignalListener commit;
CHyprSignalListener destroy; CHyprSignalListener destroy;
CHyprSignalListener surfaceUnmap; CHyprSignalListener surfaceUnmap;

View file

@ -31,6 +31,7 @@ CTextInputV1::CTextInputV1(SP<CZwpTextInputV1> resource_) : resource(resource_)
resource->setReset([this](CZwpTextInputV1* pMgr) { resource->setReset([this](CZwpTextInputV1* pMgr) {
pendingSurrounding.isPending = false; pendingSurrounding.isPending = false;
pendingContentType.isPending = false; pendingContentType.isPending = false;
events.reset.emit();
}); });
resource->setSetSurroundingText( resource->setSetSurroundingText(

View file

@ -37,6 +37,7 @@ class CTextInputV1 {
CSignal onCommit; CSignal onCommit;
CSignal enable; CSignal enable;
CSignal disable; CSignal disable;
CSignal reset;
CSignal destroy; CSignal destroy;
} events; } events;

View file

@ -19,17 +19,22 @@ CTextInputV3::CTextInputV3(SP<CZwpTextInputV3> resource_) : resource(resource_)
resource->setOnDestroy([this](CZwpTextInputV3* r) { PROTO::textInputV3->destroyTextInput(this); }); resource->setOnDestroy([this](CZwpTextInputV3* r) { PROTO::textInputV3->destroyTextInput(this); });
resource->setCommit([this](CZwpTextInputV3* r) { resource->setCommit([this](CZwpTextInputV3* r) {
bool wasEnabled = current.enabled; bool wasEnabled = current.enabled.value;
current = pending; current = pending;
serial++; serial++;
if (wasEnabled && !current.enabled) if (wasEnabled && !current.enabled.value)
events.disable.emit(); events.disable.emit();
else if (!wasEnabled && current.enabled) else if (!wasEnabled && current.enabled.value)
events.enable.emit(); events.enable.emit();
else if (current.enabled.value && current.enabled.isEnablePending && current.enabled.isDisablePending)
events.reset.emit();
else else
events.onCommit.emit(); events.onCommit.emit();
pending.enabled.isEnablePending = false;
pending.enabled.isDisablePending = false;
}); });
resource->setSetSurroundingText([this](CZwpTextInputV3* r, const char* text, int32_t cursor, int32_t anchor) { resource->setSetSurroundingText([this](CZwpTextInputV3* r, const char* text, int32_t cursor, int32_t anchor) {
@ -54,10 +59,14 @@ CTextInputV3::CTextInputV3(SP<CZwpTextInputV3> resource_) : resource(resource_)
resource->setEnable([this](CZwpTextInputV3* r) { resource->setEnable([this](CZwpTextInputV3* r) {
pending.reset(); pending.reset();
pending.enabled = true; pending.enabled.value = true;
pending.enabled.isEnablePending = true;
}); });
resource->setDisable([this](CZwpTextInputV3* r) { pending.enabled = false; }); resource->setDisable([this](CZwpTextInputV3* r) {
pending.enabled.value = false;
pending.enabled.isDisablePending = true;
});
} }
CTextInputV3::~CTextInputV3() { CTextInputV3::~CTextInputV3() {

View file

@ -31,6 +31,7 @@ class CTextInputV3 {
CSignal onCommit; CSignal onCommit;
CSignal enable; CSignal enable;
CSignal disable; CSignal disable;
CSignal reset;
CSignal destroy; CSignal destroy;
} events; } events;
@ -53,7 +54,11 @@ class CTextInputV3 {
CBox cursorBox; CBox cursorBox;
} box; } box;
bool enabled = false; struct {
bool isEnablePending = false;
bool isDisablePending = false;
bool value = false;
} enabled;
zwpTextInputV3ChangeCause cause = ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_INPUT_METHOD; zwpTextInputV3ChangeCause cause = ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_INPUT_METHOD;