Skip to content
  • Carlos Garnacho's avatar
    text-input: Reword the interpretation of serials to be more specific · 37fa0f4a
    Carlos Garnacho authored and Jonas Ådahl's avatar Jonas Ådahl committed
    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: default avatarCarlos Garnacho <carlosg@gnome.org>
    37fa0f4a
Loading