mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	When creating a new session from the command-line where there is an external
terminal, copy the termios(4) special characters and use them for new windows created in the new session. Suggested by Theo.
This commit is contained in:
		@@ -18,6 +18,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <sys/types.h>
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <termios.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TTYDEFCHARS
 | 
				
			||||||
 | 
					#include <sys/ttydefaults.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "tmux.h"
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
@@ -109,6 +115,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			|||||||
	struct cmd_new_session_data	*data = self->data;
 | 
						struct cmd_new_session_data	*data = self->data;
 | 
				
			||||||
	struct session			*s;
 | 
						struct session			*s;
 | 
				
			||||||
	struct environ			 env;
 | 
						struct environ			 env;
 | 
				
			||||||
 | 
						struct termios			 tio;
 | 
				
			||||||
	const char			*update;
 | 
						const char			*update;
 | 
				
			||||||
	char				*overrides, *cmd, *cwd, *cause;
 | 
						char				*overrides, *cmd, *cwd, *cause;
 | 
				
			||||||
	int				 detached;
 | 
						int				 detached;
 | 
				
			||||||
@@ -192,8 +199,24 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			|||||||
	if (ctx->cmdclient != NULL)
 | 
						if (ctx->cmdclient != NULL)
 | 
				
			||||||
		environ_update(update, &ctx->cmdclient->environ, &env);
 | 
							environ_update(update, &ctx->cmdclient->environ, &env);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Fill in the termios settings used for new windows in this session;
 | 
				
			||||||
 | 
						 * if there is a command client, use the control characters from it.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (ctx->cmdclient != NULL && ctx->cmdclient->tty.fd != -1) {
 | 
				
			||||||
 | 
							if (tcgetattr(ctx->cmdclient->tty.fd, &tio) != 0)
 | 
				
			||||||
 | 
								fatal("tcgetattr failed");
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							memcpy(tio.c_cc, ttydefchars, sizeof tio.c_cc);
 | 
				
			||||||
 | 
						tio.c_iflag = TTYDEF_IFLAG;
 | 
				
			||||||
 | 
						tio.c_oflag = TTYDEF_OFLAG;
 | 
				
			||||||
 | 
						tio.c_lflag = TTYDEF_LFLAG;
 | 
				
			||||||
 | 
						tio.c_cflag = TTYDEF_CFLAG;
 | 
				
			||||||
 | 
						tio.c_ispeed = TTYDEF_SPEED;
 | 
				
			||||||
 | 
						tio.c_ospeed = TTYDEF_SPEED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create the new session. */
 | 
						/* Create the new session. */
 | 
				
			||||||
	s = session_create(data->newname, cmd, cwd, &env, sx, sy, &cause);
 | 
						s = session_create(data->newname, cmd, cwd, &env, &tio, sx, sy, &cause);
 | 
				
			||||||
	if (s == NULL) {
 | 
						if (s == NULL) {
 | 
				
			||||||
		ctx->error(ctx, "create session failed: %s", cause);
 | 
							ctx->error(ctx, "create session failed: %s", cause);
 | 
				
			||||||
		xfree(cause);
 | 
							xfree(cause);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -75,7 +75,7 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			|||||||
 	window_destroy_panes(w);
 | 
					 	window_destroy_panes(w);
 | 
				
			||||||
	TAILQ_INSERT_HEAD(&w->panes, wp, entry);
 | 
						TAILQ_INSERT_HEAD(&w->panes, wp, entry);
 | 
				
			||||||
	window_pane_resize(wp, w->sx, w->sy);
 | 
						window_pane_resize(wp, w->sx, w->sy);
 | 
				
			||||||
	if (window_pane_spawn(wp, data->arg, NULL, &env, &cause) != 0) {
 | 
						if (window_pane_spawn(wp, data->arg, NULL, &env, &s->tio, &cause) != 0) {
 | 
				
			||||||
		ctx->error(ctx, "respawn window failed: %s", cause);
 | 
							ctx->error(ctx, "respawn window failed: %s", cause);
 | 
				
			||||||
		xfree(cause);
 | 
							xfree(cause);
 | 
				
			||||||
		environ_free(&env);
 | 
							environ_free(&env);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -184,7 +184,7 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			|||||||
		type = LAYOUT_LEFTRIGHT;
 | 
							type = LAYOUT_LEFTRIGHT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wp = window_add_pane(w, hlimit);
 | 
						wp = window_add_pane(w, hlimit);
 | 
				
			||||||
	if (window_pane_spawn(wp, cmd, cwd, &env, &cause) != 0)
 | 
						if (window_pane_spawn(wp, cmd, cwd, &env, &s->tio, &cause) != 0)
 | 
				
			||||||
		goto error;
 | 
							goto error;
 | 
				
			||||||
	if (layout_split_pane(w->active, type, size, wp) != 0) {
 | 
						if (layout_split_pane(w->active, type, size, wp) != 0) {
 | 
				
			||||||
		cause = xstrdup("pane too small");
 | 
							cause = xstrdup("pane too small");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -113,7 +113,7 @@ session_find(const char *name)
 | 
				
			|||||||
/* Create a new session. */
 | 
					/* Create a new session. */
 | 
				
			||||||
struct session *
 | 
					struct session *
 | 
				
			||||||
session_create(const char *name, const char *cmd, const char *cwd,
 | 
					session_create(const char *name, const char *cmd, const char *cwd,
 | 
				
			||||||
    struct environ *env, u_int sx, u_int sy, char **cause)
 | 
					    struct environ *env, struct termios *tio, u_int sx, u_int sy, char **cause)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct session	*s;
 | 
						struct session	*s;
 | 
				
			||||||
	u_int		 i;
 | 
						u_int		 i;
 | 
				
			||||||
@@ -131,6 +131,7 @@ session_create(const char *name, const char *cmd, const char *cwd,
 | 
				
			|||||||
	environ_init(&s->environ);
 | 
						environ_init(&s->environ);
 | 
				
			||||||
	if (env != NULL)
 | 
						if (env != NULL)
 | 
				
			||||||
		environ_copy(env, &s->environ);
 | 
							environ_copy(env, &s->environ);
 | 
				
			||||||
 | 
						memcpy(&s->tio, tio, sizeof s->tio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	s->sx = sx;
 | 
						s->sx = sx;
 | 
				
			||||||
	s->sy = sy;
 | 
						s->sy = sy;
 | 
				
			||||||
@@ -200,7 +201,7 @@ session_index(struct session *s, u_int *i)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* Create a new window on a session. */
 | 
					/* Create a new window on a session. */
 | 
				
			||||||
struct winlink *
 | 
					struct winlink *
 | 
				
			||||||
session_new(struct session *s,
 | 
					session_new(struct session *s, 
 | 
				
			||||||
    const char *name, const char *cmd, const char *cwd, int idx, char **cause)
 | 
					    const char *name, const char *cmd, const char *cwd, int idx, char **cause)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct window	*w;
 | 
						struct window	*w;
 | 
				
			||||||
@@ -213,7 +214,8 @@ session_new(struct session *s,
 | 
				
			|||||||
	server_fill_environ(s, &env);
 | 
						server_fill_environ(s, &env);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hlimit = options_get_number(&s->options, "history-limit");
 | 
						hlimit = options_get_number(&s->options, "history-limit");
 | 
				
			||||||
	w = window_create(name, cmd, cwd, &env, s->sx, s->sy, hlimit, cause);
 | 
						w = window_create(
 | 
				
			||||||
 | 
						    name, cmd, cwd, &env, &s->tio, s->sx, s->sy, hlimit, cause);
 | 
				
			||||||
	if (w == NULL) {
 | 
						if (w == NULL) {
 | 
				
			||||||
		environ_free(&env);
 | 
							environ_free(&env);
 | 
				
			||||||
		return (NULL);
 | 
							return (NULL);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								tmux.1
									
									
									
									
									
								
							@@ -398,6 +398,10 @@ is given.
 | 
				
			|||||||
and
 | 
					and
 | 
				
			||||||
.Ar command
 | 
					.Ar command
 | 
				
			||||||
are the name of and command to execute in the initial window.
 | 
					are the name of and command to execute in the initial window.
 | 
				
			||||||
 | 
					.Pp
 | 
				
			||||||
 | 
					If run from a terminal, any
 | 
				
			||||||
 | 
					.Xr termios 4
 | 
				
			||||||
 | 
					special characters are saved and used for new windows in the new session.
 | 
				
			||||||
.It Ic refresh-client Op Fl t Ar target-client
 | 
					.It Ic refresh-client Op Fl t Ar target-client
 | 
				
			||||||
.D1 (alias: Ic refresh )
 | 
					.D1 (alias: Ic refresh )
 | 
				
			||||||
Refresh the current client if bound to a key, or a single client if one is given
 | 
					Refresh the current client if bound to a key, or a single client if one is given
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										13
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								tmux.h
									
									
									
									
									
								
							@@ -803,6 +803,8 @@ struct session {
 | 
				
			|||||||
#define SESSION_UNATTACHED 0x1	/* not attached to any clients */
 | 
					#define SESSION_UNATTACHED 0x1	/* not attached to any clients */
 | 
				
			||||||
	int		 flags;
 | 
						int		 flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct termios   tio;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct environ	 environ;
 | 
						struct environ	 environ;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
ARRAY_DECL(sessions, struct session *);
 | 
					ARRAY_DECL(sessions, struct session *);
 | 
				
			||||||
@@ -1574,7 +1576,8 @@ void		 winlink_stack_remove(struct winlink_stack *, struct winlink *);
 | 
				
			|||||||
int	 	 window_index(struct window *, u_int *);
 | 
					int	 	 window_index(struct window *, u_int *);
 | 
				
			||||||
struct window	*window_create1(u_int, u_int);
 | 
					struct window	*window_create1(u_int, u_int);
 | 
				
			||||||
struct window	*window_create(const char *, const char *, const char *,
 | 
					struct window	*window_create(const char *, const char *, const char *,
 | 
				
			||||||
    		     struct environ *, u_int, u_int, u_int, char **);
 | 
					    		     struct environ *, struct termios *, u_int, u_int, u_int,
 | 
				
			||||||
 | 
							     char **);
 | 
				
			||||||
void		 window_destroy(struct window *);
 | 
					void		 window_destroy(struct window *);
 | 
				
			||||||
void		 window_set_active_pane(struct window *, struct window_pane *);
 | 
					void		 window_set_active_pane(struct window *, struct window_pane *);
 | 
				
			||||||
struct window_pane *window_add_pane(struct window *, u_int);
 | 
					struct window_pane *window_add_pane(struct window *, u_int);
 | 
				
			||||||
@@ -1586,8 +1589,8 @@ u_int		 window_count_panes(struct window *);
 | 
				
			|||||||
void		 window_destroy_panes(struct window *);
 | 
					void		 window_destroy_panes(struct window *);
 | 
				
			||||||
struct window_pane *window_pane_create(struct window *, u_int, u_int, u_int);
 | 
					struct window_pane *window_pane_create(struct window *, u_int, u_int, u_int);
 | 
				
			||||||
void		 window_pane_destroy(struct window_pane *);
 | 
					void		 window_pane_destroy(struct window_pane *);
 | 
				
			||||||
int		 window_pane_spawn(struct window_pane *,
 | 
					int		 window_pane_spawn(struct window_pane *, const char *,
 | 
				
			||||||
		     const char *, const char *, struct environ *, char **);
 | 
							     const char *, struct environ *, struct termios *, char **);
 | 
				
			||||||
void		 window_pane_resize(struct window_pane *, u_int, u_int);
 | 
					void		 window_pane_resize(struct window_pane *, u_int, u_int);
 | 
				
			||||||
int		 window_pane_set_mode(
 | 
					int		 window_pane_set_mode(
 | 
				
			||||||
		     struct window_pane *, const struct window_mode *);
 | 
							     struct window_pane *, const struct window_mode *);
 | 
				
			||||||
@@ -1666,8 +1669,8 @@ void	 session_alert_cancel(struct session *, struct winlink *);
 | 
				
			|||||||
int	 session_alert_has(struct session *, struct winlink *, int);
 | 
					int	 session_alert_has(struct session *, struct winlink *, int);
 | 
				
			||||||
int	 session_alert_has_window(struct session *, struct window *, int);
 | 
					int	 session_alert_has_window(struct session *, struct window *, int);
 | 
				
			||||||
struct session	*session_find(const char *);
 | 
					struct session	*session_find(const char *);
 | 
				
			||||||
struct session	*session_create(const char *, const char *,
 | 
					struct session	*session_create(const char *, const char *, const char *,
 | 
				
			||||||
    		     const char *, struct environ *, u_int, u_int, char **);
 | 
					    		     struct environ *, struct termios *, u_int, u_int, char **);
 | 
				
			||||||
void	 	 session_destroy(struct session *);
 | 
					void	 	 session_destroy(struct session *);
 | 
				
			||||||
int	 	 session_index(struct session *, u_int *);
 | 
					int	 	 session_index(struct session *, u_int *);
 | 
				
			||||||
struct winlink	*session_new(struct session *,
 | 
					struct winlink	*session_new(struct session *,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								window.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								window.c
									
									
									
									
									
								
							@@ -269,7 +269,8 @@ window_create1(u_int sx, u_int sy)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
struct window *
 | 
					struct window *
 | 
				
			||||||
window_create(const char *name, const char *cmd, const char *cwd,
 | 
					window_create(const char *name, const char *cmd, const char *cwd,
 | 
				
			||||||
    struct environ *env, u_int sx, u_int sy, u_int hlimit, char **cause)
 | 
					    struct environ *env, struct termios *tio, u_int sx, u_int sy, u_int hlimit,
 | 
				
			||||||
 | 
					    char **cause)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct window		*w;
 | 
						struct window		*w;
 | 
				
			||||||
	struct window_pane	*wp;
 | 
						struct window_pane	*wp;
 | 
				
			||||||
@@ -277,7 +278,7 @@ window_create(const char *name, const char *cmd, const char *cwd,
 | 
				
			|||||||
	w = window_create1(sx, sy);
 | 
						w = window_create1(sx, sy);
 | 
				
			||||||
	wp = window_add_pane(w, hlimit);
 | 
						wp = window_add_pane(w, hlimit);
 | 
				
			||||||
	layout_init(w);
 | 
						layout_init(w);
 | 
				
			||||||
	if (window_pane_spawn(wp, cmd, cwd, env, cause) != 0) {
 | 
						if (window_pane_spawn(wp, cmd, cwd, env, tio, cause) != 0) {
 | 
				
			||||||
		window_destroy(w);
 | 
							window_destroy(w);
 | 
				
			||||||
		return (NULL);
 | 
							return (NULL);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -470,8 +471,8 @@ window_pane_destroy(struct window_pane *wp)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
window_pane_spawn(struct window_pane *wp,
 | 
					window_pane_spawn(struct window_pane *wp, const char *cmd,
 | 
				
			||||||
    const char *cmd, const char *cwd, struct environ *env, char **cause)
 | 
					    const char *cwd, struct environ *env, struct termios *tio, char **cause)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct winsize	 	 ws;
 | 
						struct winsize	 	 ws;
 | 
				
			||||||
	int		 	 mode;
 | 
						int		 	 mode;
 | 
				
			||||||
@@ -505,7 +506,7 @@ window_pane_spawn(struct window_pane *wp,
 | 
				
			|||||||
	tv.tv_usec = NAME_INTERVAL * 1000L;
 | 
						tv.tv_usec = NAME_INTERVAL * 1000L;
 | 
				
			||||||
	timeradd(&wp->window->name_timer, &tv, &wp->window->name_timer);
 | 
						timeradd(&wp->window->name_timer, &tv, &wp->window->name_timer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 	switch (wp->pid = forkpty(&wp->fd, wp->tty, NULL, &ws)) {
 | 
					 	switch (wp->pid = forkpty(&wp->fd, wp->tty, tio, &ws)) {
 | 
				
			||||||
	case -1:
 | 
						case -1:
 | 
				
			||||||
		wp->fd = -1;
 | 
							wp->fd = -1;
 | 
				
			||||||
		xasprintf(cause, "%s: %s", cmd, strerror(errno));
 | 
							xasprintf(cause, "%s: %s", cmd, strerror(errno));
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user