Implement isIdle() properly

Previously we were always returning False for isIdle(), which meant that
if you left the message window in the foreground, it would continue to
mark all messages in the current conversation as read as long as you
left your computer running.

The ideal way to solve this would be to define "idle" as "5 minutes
since any user input on the whole machine," but there's no portable way
to listen to all user input, so we settle for listening to a combination
of three events:
- chat window activated
- chat tab switched (via the "open_threads" setting)
- user starts typing (via the "/typing" mqtt topic)

So if a user stays in a single chat tab for more than 5 minutes, without
sending a (long enough to trigger typing) message or changing focus,
then we will stop marking messages read for him. Maybe not ideal, but
much better than the "mark everything read forever" bug we're fixing.