Commit 37fa0f4a authored by Carlos Garnacho's avatar Carlos Garnacho Committed by Jonas Ådahl
Browse files

text-input: Reword the interpretation of serials to be more specific

Here's a long story. The serial is formerly described as:

  When the client receives a done event with a serial different than the
  number of past commit requests, it must proceed as normal, except it
  should not change the current state of the zwp_text_input_v3 object.

Upon first reading it might be obvious to interpret "proceed as normal"
as "apply the changes made by the done event" and "not change the current
state" as "do not make requests on it until serial matches with
expectations again". This would turn the serial into a flow control
mechanism to avoid pushing state changes that we know might be stale.

GTK however makes another outlandish interpretation, where "proceed as
normal" means "ignore the changes made by the done event" and "not change
state of the zwp_text_input_v3 object" is "not change client state". This
makes the serial a full synchronization mechanism where IM commands that
are deemed out of sync are symply ignored.

This would seem a misinterpretation of the protocol, and I proceeded to
change the behavior in GTK. Then some deja vu feeling struck me and I found
https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/384#note_344864

, this
change was already done and discussed in the past. Not just that, it is
the right interpretation.

However, there's some notable disadvantages, there's 2 easy ways to
completely break the synchronization between compositor and client:
Having the IM push new state too often (i.e. multiple consecutive
.done events), or having the client .commit too often. If any of both
peers gets ahead of the other slightly, the end result is ignored input.
More specifically, IBus has no provision for this kind of transactional
behavior (probably other IMs too), so implementing "emit .done once after
a set of changes" is not quite possible.

Arguably, ignoring IM input is also a bad thing. IMs expect all commands
to be respected and applied in order and might even rely on that in
their own internal state. Since only state changes are flushed on .done
events, partially ignoring IM commands will end up with the client IM state
out of sync.

The usecase described at that GNOME gitlab comment (edited text changes
happening in parallel to IM interaction) trades the handling of an
inherently racy corner case with the worst kind of mishandling (ignoring
user input) if IM/client don't perfectly sync up.

On the other hand, the flow control approach is more lenient with IMs and
clients "getting a step ahead", and more importantly does not punish the
user whenever either IM/client happens to do that. Double down on this
(already intuitively correct) description, and specify further what it
implies.
Signed-off-by: Carlos Garnacho's avatarCarlos Garnacho <carlosg@gnome.org>
parent 39c014cc
......@@ -422,9 +422,14 @@
The serial number reflects the last state of the zwp_text_input_v3
object known to the compositor. The value of the serial argument must
be equal to the number of commit requests already issued on that object.
When the client receives a done event with a serial different than the
number of past commit requests, it must proceed as normal, except it
should not change the current state of the zwp_text_input_v3 object.
number of past commit requests, it must proceed with evaluating and
applying the changes as normal, except it should not change the current
state of the zwp_text_input_v3 object. All pending state requests
(set_surrounding_text, set_content_type and set_cursor_rectangle) on
the zwp_text_input_v3 object should be sent and committed after
receiving a zwp_text_input_v3.done event with a matching serial.
</description>
<arg name="serial" type="uint"/>
</event>
......
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