Force close the folder if when opening a remote session indicates it
does not exist.
Also actually handle the folder not opening during a background sync.
For Cyrus and other servers that puts all user folders under the Inbox,
if the Inbox's special type changes, all children are removed and
re-added. This ensures account paths auto expand whenever any child
is added. This is sub-optimal if a new folder is added and the branch
was manually closed, but that's a corner case.
Fixes#92, see also #11.
Use Glib.NetworkMonitor.connectivity to work out if we should report
an error thrown when checking reachability: Only report if we have
full connectivity, otherwise retry.
Also, NetworkMonitor.can_reach may throw a DBus error if there is a
problem talking to the portal under Flatpak. We should at least
attempt to connect in this case.
Workaround for issue #97, see also #82
When working on accounts with a *lot* of folders on slow servers, this
can be very slow. So let's try to only do it when it's actually needed;
when switching accounts.
Only consider keyboard modifiers that are in GTK's default mod mask
when deciding to engage/disengage the SKC hack in MainWindow, so things
like NumLock being on (GDK_MOD2_MASK) don't disengage the hack.
Fixes#77
Command.serialize has now become send() and send_wait(). ClientSession
will signal a command has been sent after calling the first method, but
will not send another until the second returns. This allows IDLE and
AUTHENTICATE to stall the send queue until they are complete, but also
allows listeners to get signalled when the command has actually been
sent.
Use the same timeout for IdleCommand as for others, but have it manage
its response timer itself, so it is reset when its IDLE continuation is
received, but restarted when DONE is sent, so sending both that and the
initial command are covered by a timeout.
Since the idle timer was not being cancelled, when idle_when_quiet was
set to false the connection would still send IDLE. This also removes the
need to send a NOOP to get in/out of IDLE.
Issue #26 underscored Geary's buggy behaviour in sending commands while
an IDLE command was active - when a new command was queued, DONE would be
sent but then the new command would also be sent without waiting for the
status response for the IDLE command from the server, in violation of
RFC 3501 sections 2.2.1 and 5.5.
A quick fix was to ensure that the new command was held while DEIDLING,
but because of the way the synchronization process between
ClientConnection and the Serialiser works, there is a race that allows
any further commands added to be sent while the IDLE DONE had not yet
been flushed: DONE gets queued, additional command gets queued, then
both get flushed.
Fixing this required re-working how ClientConnection and Serializer
interacted, which was a major re-write. Serializer no longer buffers
any data - it simply writes it out to its underlying stream.
ClientConnection now queues commands and writes them out one by one,
requiring Command implementations to manage stalling the queue until
their expected completions have been received. Literals are hence
written by their command's serialisation process, which gets prompted
by an event from ClientConnection. The two commands that require
non-literal continuations, IDLE and AUTHENTICATE, now manage that
themselves.
As a result, only one command can be serialised at a time, and no
additional commands can be serialised while another is still waiting for
a continuation. Also, command-specific details can be implemented by
command itself, without needing workarounds in the serialiser,
connection, or session.
Instead, make the args property a parameter list, and add params to that.
This means Command's serialize method have a different signature compared
to Parameter's, letting us do some more interesting things with it.
The ListParameter.parent property only existed to make the deserialier's
life easier, but is also why sketchy code was needed for appending search
criteria from a ServerSearchEmail replay op to the actual IMAP search
command sent to the server.
This removes the property altogether, and replaces its only use in
Deserialier with a stack, as nature intended. This means lists can be
added to more than one other list, and e.g. when a search is executed,
the search critera can be used for multiple requests.
I.e. Don't modify the list being appended from, so that when the
ServerSearchEmail replay op is re-executed after a network error, the
search criteria have not disappeared.