motd: tuple[str, ...] = tuple()
     users: _UpdatingDict[_UpdatingUser]
     channels: _UpdatingDict[_UpdatingChannel]
-    log_scopes = {'connection_state': LogScope.ALL}
+
+    def recursive_set_and_report_change(self, update: _Update) -> None:
+        super().recursive_set_and_report_change(update)
+        if update.key == 'connection_state':
+            if update.value == 'connected':
+                update.results += [(LogScope.ALL, [':CONNECTED'])]
+            elif not update.value:
+                update.results += [(LogScope.ALL, [':DISCONNECTED'])]
 
 
 class _ClientWindowsManager:
 
 
 # on /connect init databases, log in new windows
 > /connect foo.bar.baz foo:bar foobarbazquux:baz
+1,2 $ DISCONNECTED
 1,2 $ isupport cleared
 1,2 $ isupport:CHANTYPES set to: [#&]
 1,2 $ isupport:PREFIX set to: [(ov)@+]
 1,2 $ port set to: [6697]
 1,2 $ connection_state set to: [connecting]
 1,2 $ connection_state set to: [connected]
+1,2 $ CONNECTED
 2 > CAP LS :302
 2 > USER foobarbazquux 0 * :baz
 2 > NICK :foo
 5 $ quits: foo!~foobarbaz@baz.bar.foo: Client Quit
 1,2 $ channels:#testtest:exits:me cleared
 2 < ERROR :Closing link: (~foobarbaz@baz.bar.foo) [Quit: ircplom says bye]
-1,2,3,4,5,6 $ connection_state set to: [Closing link: (~foobarbaz@baz.bar.foo) [Quit: ircplom says bye]]
-1,2,3,4,5,6 $ connection_state set to: []
+1,2 $ connection_state set to: [Closing link: (~foobarbaz@baz.bar.foo) [Quit: ircplom says bye]]
+1,2 $ connection_state set to: []
+1,2,3,4,5,6 $ DISCONNECTED
 1,2 $ isupport cleared
 1,2 $ isupport:CHANTYPES set to: [#&]
 1,2 $ isupport:PREFIX set to: [(ov)@+]
 
 # check that (save TUI tests assuming start on window 0, and no 4 yet) on reconnect, all the same effects can be expected
 > /reconnect
-1,2,3,4,5,6 $ connection_state set to: [connecting]
-1,2,3,4,5,6 $ connection_state set to: [connected]
-repeat 64:147
-repeat 158:338
+repeat 63:65
+1,2,3,4,5,6 $ CONNECTED
+repeat 66:147
+repeat 159:341
 
 > /quit
 0 <