mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Add an activity time for clients, like for sessions, and change session and
client lookup to pick the most recently used rather than the most recently created - this is much more useful when used interactively and (because the activity time is set at creation) should have no effect on source-file. Based on a problem reported by Jan Johansson.
This commit is contained in:
		
							
								
								
									
										55
									
								
								cmd.c
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								cmd.c
									
									
									
									
									
								
							| @@ -110,8 +110,8 @@ const struct cmd_entry *cmd_table[] = { | |||||||
| 	NULL | 	NULL | ||||||
| }; | }; | ||||||
|  |  | ||||||
| struct session	*cmd_newest_session(struct sessions *); | struct session	*cmd_choose_session(struct sessions *); | ||||||
| struct client	*cmd_newest_client(struct clients *); | struct client	*cmd_choose_client(struct clients *); | ||||||
| struct client	*cmd_lookup_client(const char *); | struct client	*cmd_lookup_client(const char *); | ||||||
| struct session	*cmd_lookup_session(const char *, int *); | struct session	*cmd_lookup_session(const char *, int *); | ||||||
| struct winlink	*cmd_lookup_window(struct session *, const char *, int *); | struct winlink	*cmd_lookup_window(struct session *, const char *, int *); | ||||||
| @@ -285,9 +285,10 @@ cmd_print(struct cmd *cmd, char *buf, size_t len) | |||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Figure out the current session. Use: 1) the current session, if the command |  * Figure out the current session. Use: 1) the current session, if the command | ||||||
|  * context has one; 2) the session containing the pty of the calling client, if |  * context has one; 2) the most recently used session containing the pty of the | ||||||
|  * any 3) the session specified in the TMUX variable from the environment (as |  * calling client, if any; 3) the session specified in the TMUX variable from | ||||||
|  * passed from the client); 3) the newest session. |  * the environment (as passed from the client); 4) the most recently used | ||||||
|  |  * session from all sessions. | ||||||
|  */ |  */ | ||||||
| struct session * | struct session * | ||||||
| cmd_current_session(struct cmd_ctx *ctx) | cmd_current_session(struct cmd_ctx *ctx) | ||||||
| @@ -329,7 +330,7 @@ cmd_current_session(struct cmd_ctx *ctx) | |||||||
| 				ARRAY_ADD(&ss, s); | 				ARRAY_ADD(&ss, s); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		s = cmd_newest_session(&ss); | 		s = cmd_choose_session(&ss); | ||||||
| 		ARRAY_FREE(&ss); | 		ARRAY_FREE(&ss); | ||||||
| 		if (s != NULL) | 		if (s != NULL) | ||||||
| 			return (s); | 			return (s); | ||||||
| @@ -346,35 +347,35 @@ cmd_current_session(struct cmd_ctx *ctx) | |||||||
| 		return (s); | 		return (s); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return (cmd_newest_session(&sessions)); | 	return (cmd_choose_session(&sessions)); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Find the newest session. */ | /* Find the most recently used session from a list. */ | ||||||
| struct session * | struct session * | ||||||
| cmd_newest_session(struct sessions *ss) | cmd_choose_session(struct sessions *ss) | ||||||
| { | { | ||||||
| 	struct session	*s, *snewest; | 	struct session	*s, *sbest; | ||||||
| 	struct timeval	*tv = NULL; | 	struct timeval	*tv = NULL; | ||||||
| 	u_int		 i; | 	u_int		 i; | ||||||
|  |  | ||||||
| 	snewest = NULL; | 	sbest = NULL; | ||||||
| 	for (i = 0; i < ARRAY_LENGTH(ss); i++) { | 	for (i = 0; i < ARRAY_LENGTH(ss); i++) { | ||||||
| 		if ((s = ARRAY_ITEM(ss, i)) == NULL) | 		if ((s = ARRAY_ITEM(ss, i)) == NULL) | ||||||
| 			continue; | 			continue; | ||||||
|  |  | ||||||
| 		if (tv == NULL || timercmp(&s->creation_time, tv, >)) { | 		if (tv == NULL || timercmp(&s->activity_time, tv, >)) { | ||||||
| 			snewest = s; | 			sbest = s; | ||||||
| 			tv = &s->creation_time; | 			tv = &s->activity_time; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return (snewest); | 	return (sbest); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Find the current client. First try the current client if set, then pick the |  * Find the current client. First try the current client if set, then pick the | ||||||
|  * newest of the clients attached to the current session if any, then the |  * most recently used of the clients attached to the current session if any, | ||||||
|  * newest client. |  * then of all clients. | ||||||
|  */ |  */ | ||||||
| struct client * | struct client * | ||||||
| cmd_current_client(struct cmd_ctx *ctx) | cmd_current_client(struct cmd_ctx *ctx) | ||||||
| @@ -401,37 +402,37 @@ cmd_current_client(struct cmd_ctx *ctx) | |||||||
| 				ARRAY_ADD(&cc, c); | 				ARRAY_ADD(&cc, c); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		c = cmd_newest_client(&cc); | 		c = cmd_choose_client(&cc); | ||||||
| 		ARRAY_FREE(&cc); | 		ARRAY_FREE(&cc); | ||||||
| 		if (c != NULL) | 		if (c != NULL) | ||||||
| 			return (c); | 			return (c); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return (cmd_newest_client(&clients)); | 	return (cmd_choose_client(&clients)); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Find the newest client. */ | /* Choose the most recently used client from a list. */ | ||||||
| struct client * | struct client * | ||||||
| cmd_newest_client(struct clients *cc) | cmd_choose_client(struct clients *cc) | ||||||
| { | { | ||||||
| 	struct client	*c, *cnewest; | 	struct client	*c, *cbest; | ||||||
| 	struct timeval	*tv = NULL; | 	struct timeval	*tv = NULL; | ||||||
| 	u_int		 i; | 	u_int		 i; | ||||||
|  |  | ||||||
| 	cnewest = NULL; | 	cbest = NULL; | ||||||
| 	for (i = 0; i < ARRAY_LENGTH(cc); i++) { | 	for (i = 0; i < ARRAY_LENGTH(cc); i++) { | ||||||
| 		if ((c = ARRAY_ITEM(cc, i)) == NULL) | 		if ((c = ARRAY_ITEM(cc, i)) == NULL) | ||||||
| 			continue; | 			continue; | ||||||
| 		if (c->session == NULL) | 		if (c->session == NULL) | ||||||
| 			continue; | 			continue; | ||||||
|  |  | ||||||
| 		if (tv == NULL || timercmp(&c->creation_time, tv, >)) { | 		if (tv == NULL || timercmp(&c->activity_time, tv, >)) { | ||||||
| 			cnewest = c; | 			cbest = c; | ||||||
| 			tv = &c->creation_time; | 			tv = &c->activity_time; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return (cnewest); | 	return (cbest); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Find the target client or report an error and return NULL. */ | /* Find the target client or report an error and return NULL. */ | ||||||
|   | |||||||
| @@ -63,6 +63,7 @@ server_client_create(int fd) | |||||||
| 	 | 	 | ||||||
| 	if (gettimeofday(&c->creation_time, NULL) != 0) | 	if (gettimeofday(&c->creation_time, NULL) != 0) | ||||||
| 		fatal("gettimeofday failed"); | 		fatal("gettimeofday failed"); | ||||||
|  | 	memcpy(&c->activity_time, &c->creation_time, sizeof c->activity_time); | ||||||
|  |  | ||||||
| 	ARRAY_INIT(&c->prompt_hdata); | 	ARRAY_INIT(&c->prompt_hdata); | ||||||
|  |  | ||||||
| @@ -287,6 +288,7 @@ server_client_handle_data(struct client *c) | |||||||
| 		oo = &c->session->options; | 		oo = &c->session->options; | ||||||
|  |  | ||||||
| 		/* Update activity timer. */ | 		/* Update activity timer. */ | ||||||
|  | 		memcpy(&c->activity_time, &tv_now, sizeof c->activity_time); | ||||||
| 		memcpy(&c->session->activity_time, | 		memcpy(&c->session->activity_time, | ||||||
| 		    &tv_now, sizeof c->session->activity_time); | 		    &tv_now, sizeof c->session->activity_time); | ||||||
|  |  | ||||||
| @@ -583,9 +585,13 @@ server_client_msg_dispatch(struct client *c) | |||||||
| 				break; | 				break; | ||||||
| 			c->flags &= ~CLIENT_SUSPENDED; | 			c->flags &= ~CLIENT_SUSPENDED; | ||||||
|  |  | ||||||
| 			if (c->session != NULL && | 			if (gettimeofday(&c->activity_time, NULL) != 0) | ||||||
| 			    gettimeofday(&c->session->activity_time, NULL) != 0) | 				fatal("gettimeofday"); | ||||||
| 				fatal("gettimeofday failed"); | 			if (c->session != NULL) { | ||||||
|  | 				memcpy(&c->session->activity_time, | ||||||
|  | 				    &c->activity_time, | ||||||
|  | 				    sizeof c->session->activity_time); | ||||||
|  | 			} | ||||||
|  |  | ||||||
| 			tty_start_tty(&c->tty); | 			tty_start_tty(&c->tty); | ||||||
| 			server_redraw_client(c); | 			server_redraw_client(c); | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								tmux.1
									
									
									
									
									
								
							| @@ -282,7 +282,7 @@ pattern. | |||||||
| If a single match is found, it is used as the target session; multiple matches | If a single match is found, it is used as the target session; multiple matches | ||||||
| produce an error. | produce an error. | ||||||
| If a session is omitted, the current session is used if available; if no | If a session is omitted, the current session is used if available; if no | ||||||
| current session is available, the most recently created is chosen. | current session is available, the most recently used is chosen. | ||||||
| .Pp | .Pp | ||||||
| .Ar target-window | .Ar target-window | ||||||
| specifies a window in the form | specifies a window in the form | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Nicholas Marriott
					Nicholas Marriott