aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2021-08-09 13:34:17 +0200
committerJonas Ã…dahl <jadahl@gmail.com>2022-03-29 07:33:38 +0000
commit37fa0f4a4e0358455645cd1d07d63c4bdd6d1cee (patch)
tree3beadaebe472ffea9d80b8fa66b9519642365c8b
parent39c014cc9de007ab1adf7940862dce9025f183d5 (diff)
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 <carlosg@gnome.org>
-rw-r--r--unstable/text-input/text-input-unstable-v3.xml9
1 files changed, 7 insertions, 2 deletions
diff --git a/unstable/text-input/text-input-unstable-v3.xml b/unstable/text-input/text-input-unstable-v3.xml
index d5f6322..1fae54d 100644
--- a/unstable/text-input/text-input-unstable-v3.xml
+++ b/unstable/text-input/text-input-unstable-v3.xml
@@ -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>