Always send a done after commit for text input v3.
In Gtk's text-input-v3 implementation it expect done to update the client serial after every commit. Though it is unclear whether this is a protocol requirements, do the same thing like mutter for more compatiblity, especially Gtk3 is in EOL not likely to be patched any time soon. To do so, we will need to keep track of the last active preedit, otherwise only send_done() will clear the preedit.
This commit is contained in:
parent
dc9c431fe3
commit
a74c436156
3 changed files with 41 additions and 2 deletions
|
@ -292,6 +292,7 @@ void TestTextInputV3Interface::testEvents()
|
|||
|
||||
QSignalSpy focusedSurfaceChangedSpy(m_seat, &SeatInterface::focusedTextInputSurfaceChanged);
|
||||
QSignalSpy textInputEnabledSpy(m_serverTextInputV3, &TextInputV3Interface::enabledChanged);
|
||||
QSignalSpy doneSpy(m_clientTextInputV3, &TextInputV3::done);
|
||||
|
||||
// Enter the textinput
|
||||
QVERIFY(focusedSurfaceChangedSpy.isValid());
|
||||
|
@ -308,11 +309,12 @@ void TestTextInputV3Interface::testEvents()
|
|||
m_clientTextInputV3->commit();
|
||||
m_totalCommits++;
|
||||
QVERIFY(textInputEnabledSpy.wait());
|
||||
QVERIFY(doneSpy.wait());
|
||||
QCOMPARE(doneSpy.count(), 1);
|
||||
|
||||
QSignalSpy preEditSpy(m_clientTextInputV3, &TextInputV3::preedit_string);
|
||||
QSignalSpy commitStringSpy(m_clientTextInputV3, &TextInputV3::commit_string);
|
||||
QSignalSpy deleteSurroundingSpy(m_clientTextInputV3, &TextInputV3::delete_surrounding_text);
|
||||
QSignalSpy doneSpy(m_clientTextInputV3, &TextInputV3::done);
|
||||
|
||||
m_serverTextInputV3->sendPreEditString("Hello KDE community!", 1, 2);
|
||||
m_serverTextInputV3->deleteSurroundingText(6, 10);
|
||||
|
@ -320,7 +322,7 @@ void TestTextInputV3Interface::testEvents()
|
|||
m_serverTextInputV3->done();
|
||||
|
||||
QVERIFY(doneSpy.wait());
|
||||
QCOMPARE(doneSpy.count(), 1);
|
||||
QCOMPARE(doneSpy.count(), 2);
|
||||
QCOMPARE(preEditSpy.count(), 1);
|
||||
QCOMPARE(commitStringSpy.count(), 1);
|
||||
QCOMPARE(deleteSurroundingSpy.count(), 1);
|
||||
|
|
|
@ -209,6 +209,11 @@ void TextInputV3InterfacePrivate::sendPreEdit(const QString &text, const quint32
|
|||
if (!surface) {
|
||||
return;
|
||||
}
|
||||
|
||||
pending.preeditText = text;
|
||||
pending.preeditCursorBegin = cursorBegin;
|
||||
pending.preeditCursorEnd = cursorEnd;
|
||||
|
||||
const QList<Resource *> textInputs = enabledTextInputsForClient(surface->client());
|
||||
for (auto resource : textInputs) {
|
||||
send_preedit_string(resource->handle, text, cursorBegin, cursorEnd);
|
||||
|
@ -244,6 +249,11 @@ void TextInputV3InterfacePrivate::done()
|
|||
}
|
||||
const QList<Resource *> textInputs = enabledTextInputsForClient(surface->client());
|
||||
|
||||
preeditText = pending.preeditText;
|
||||
preeditCursorBegin = pending.preeditCursorBegin;
|
||||
preeditCursorEnd = pending.preeditCursorEnd;
|
||||
defaultPendingPreedit();
|
||||
|
||||
for (auto resource : textInputs) {
|
||||
// zwp_text_input_v3.done takes the serial argument which is equal to number of commit requests issued
|
||||
send_done(resource->handle, serialHash[resource]);
|
||||
|
@ -291,6 +301,9 @@ void TextInputV3InterfacePrivate::zwp_text_input_v3_disable(Resource *resource)
|
|||
// reset pending state to default
|
||||
Q_UNUSED(resource)
|
||||
defaultPending();
|
||||
preeditText = QString();
|
||||
preeditCursorBegin = 0;
|
||||
preeditCursorEnd = 0;
|
||||
}
|
||||
|
||||
void TextInputV3InterfacePrivate::zwp_text_input_v3_set_surrounding_text(Resource *resource, const QString &text, int32_t cursor, int32_t anchor)
|
||||
|
@ -377,6 +390,14 @@ void TextInputV3InterfacePrivate::zwp_text_input_v3_commit(Resource *resource)
|
|||
}
|
||||
|
||||
Q_EMIT q->stateCommitted(serialHash[resource]);
|
||||
|
||||
// Gtk text input implementation expect done to be sent after every commit to synchronize the serial value between commit() and done().
|
||||
// So we need to send the current preedit text with done().
|
||||
// If current preedit is empty, there is no need to send it.
|
||||
if (!preeditText.isEmpty() || preeditCursorBegin != 0 || preeditCursorEnd != 0) {
|
||||
send_preedit_string(resource->handle, preeditText, preeditCursorBegin, preeditCursorEnd);
|
||||
}
|
||||
send_done(resource->handle, serialHash[resource]);
|
||||
}
|
||||
|
||||
void TextInputV3InterfacePrivate::defaultPending()
|
||||
|
@ -389,6 +410,14 @@ void TextInputV3InterfacePrivate::defaultPending()
|
|||
pending.surroundingText = QString();
|
||||
pending.surroundingTextCursorPosition = 0;
|
||||
pending.surroundingTextSelectionAnchor = 0;
|
||||
defaultPendingPreedit();
|
||||
}
|
||||
|
||||
void TextInputV3InterfacePrivate::defaultPendingPreedit()
|
||||
{
|
||||
pending.preeditText = QString();
|
||||
pending.preeditCursorBegin = 0;
|
||||
pending.preeditCursorEnd = 0;
|
||||
}
|
||||
|
||||
TextInputV3Interface::TextInputV3Interface(SeatInterface *seat)
|
||||
|
|
|
@ -63,6 +63,10 @@ public:
|
|||
qint32 surroundingTextSelectionAnchor = 0;
|
||||
TextInputChangeCause surroundingTextChangeCause = TextInputChangeCause::InputMethod;
|
||||
|
||||
QString preeditText;
|
||||
quint32 preeditCursorBegin = 0;
|
||||
quint32 preeditCursorEnd = 0;
|
||||
|
||||
struct
|
||||
{
|
||||
QRect cursorRectangle;
|
||||
|
@ -73,12 +77,16 @@ public:
|
|||
QString surroundingText;
|
||||
qint32 surroundingTextCursorPosition = 0;
|
||||
qint32 surroundingTextSelectionAnchor = 0;
|
||||
QString preeditText;
|
||||
quint32 preeditCursorBegin = 0;
|
||||
quint32 preeditCursorEnd = 0;
|
||||
} pending;
|
||||
|
||||
QHash<Resource *, quint32> serialHash;
|
||||
QHash<Resource *, bool> enabled;
|
||||
|
||||
void defaultPending();
|
||||
void defaultPendingPreedit();
|
||||
|
||||
TextInputV3Interface *q;
|
||||
|
||||
|
|
Loading…
Reference in a new issue