Commit a74c4361 authored by Xuetian Weng's avatar Xuetian Weng Committed by Xuetian Weng
Browse files

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.
parent dc9c431f
Pipeline #188938 passed with stage
in 12 minutes and 35 seconds
......@@ -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;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment