disobedience/control.c: Handle state-change toggles better.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 6 Jun 2020 09:17:25 +0000 (10:17 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Mon, 15 Jun 2020 12:03:09 +0000 (13:03 +0100)
commitfe0a1c48c648f683b3691132fb2b12b01d1ace32
tree766822fe7a7ccce1f290c7c8b2a136bb9c2e619b
parentaaf8fd32e5cd26f0a21efdca73167db37b5757e7
disobedience/control.c: Handle state-change toggles better.

If you click a toggle icon, say the `pause' button, then: Gtk
immediately toggles the state of the icon, but doesn't change the
corresponding menu item.  Instead, a state change is reported through
the log connection which causes us to update the menu (and the icon,
though that's already in the right state so you don't notice).  (Of
course, this just works the other way around if you use the menu item or
keyboard accelerator instead.)

There are a couple of problems with this, with more or less the same
fix.

  * If the connection to the server is very slow, then there's a lag
    between clicking the icon, or pressing the accelerator, and the rest
    of the UI updating.  This is unfortunate.

  * If something goes wrong, then the icon is left in the wrong state,
    and nothing will correct it.

The fix is as follows:

  * When toggling the state of something, we immediately (a) adjust our
    internal idea of what the state /ought/ to be, and (b) force an
    update of the icon (and associated menu item).  This solves the
    problem of the associated UI element lagging.

  * On a server error, we immediately change the state back again and
    force another icon update.

  * That leaves the RTP connection option (which was my original
    motivation for all of this).  There's no server feedback for this
    control.  Instead, we periodically check whether the RTP player
    process is listening for connections.  An event is signalled if this
    state /changes/, and this event is used to set the icon and
    menu-item state.  So, again, if we force our internal idea of the
    RTP process state to match the icon, but the player doesn't start up
    properly, then the next time we check, we find that the player isn't
    responding, signal the event, and then we fix the icon state.
disobedience/control.c