diff --git a/server-client.c b/server-client.c index 25d61376..1114396d 100644 --- a/server-client.c +++ b/server-client.c @@ -46,6 +46,7 @@ static void server_client_check_modes(struct client *); static void server_client_set_title(struct client *); static void server_client_reset_state(struct client *); static int server_client_assume_paste(struct session *); +static void server_client_update_latest(struct client *); static void server_client_dispatch(struct imsg *, void *); static void server_client_dispatch_command(struct client *, struct imsg *); @@ -274,6 +275,40 @@ server_client_open(struct client *c, char **cause) return (0); } +/* Lost an attached client. */ +static void +server_client_attached_lost(struct client *c) +{ + struct session *s = c->session; + struct window *w; + struct client *loop; + struct client *found; + + log_debug("lost attached client %p", c); + + /* + * By this point the session in the client has been cleared so walk all + * windows to find any with this client as the latest. + */ + RB_FOREACH(w, windows, &windows) { + if (w->latest != c) + continue; + + found = NULL; + TAILQ_FOREACH(loop, &clients, entry) { + s = loop->session; + if (loop == c || s == NULL || s->curw->window != w) + continue; + if (found == NULL || + timercmp(&loop->activity_time, &found->activity_time, + >)) + found = loop; + } + if (found != NULL) + server_client_update_latest(found); + } +} + /* Lost a client. */ void server_client_lost(struct client *c) @@ -299,8 +334,10 @@ server_client_lost(struct client *c) TAILQ_REMOVE(&clients, c, entry); log_debug("lost client %p", c); - if (c->flags & CLIENT_ATTACHED) + if (c->flags & CLIENT_ATTACHED) { + server_client_attached_lost(c); notify_client("client-detached", c); + } if (c->flags & CLIENT_CONTROL) control_stop(c);