mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Add option to include status text in the pane borders. If
pane-border-status is set to "top" or "bottom" (rather than "off"), every pane has a permanent top or bottom border containing the text from pane-border-format. Based on a diff sent long ago by Jonathan Slenders, mostly rewritten and simplified by me.
This commit is contained in:
		@@ -201,6 +201,12 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
 | 
				
			|||||||
	if (strcmp(oe->name, "monitor-silence") == 0)
 | 
						if (strcmp(oe->name, "monitor-silence") == 0)
 | 
				
			||||||
		alerts_reset_all();
 | 
							alerts_reset_all();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* When the pane-border-status option has been changed, resize panes. */
 | 
				
			||||||
 | 
						if (strcmp(oe->name, "pane-border-status") == 0) {
 | 
				
			||||||
 | 
							RB_FOREACH(w, windows, &windows)
 | 
				
			||||||
 | 
								layout_fix_panes(w, w->sx, w->sy);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Update sizes and redraw. May not need it but meh. */
 | 
						/* Update sizes and redraw. May not need it but meh. */
 | 
				
			||||||
	recalculate_sizes();
 | 
						recalculate_sizes();
 | 
				
			||||||
	TAILQ_FOREACH(c, &clients, entry) {
 | 
						TAILQ_FOREACH(c, &clients, entry) {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										50
									
								
								layout.c
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								layout.c
									
									
									
									
									
								
							@@ -32,8 +32,11 @@
 | 
				
			|||||||
 * cell a pointer to its parent cell.
 | 
					 * cell a pointer to its parent cell.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int	layout_resize_pane_grow(struct layout_cell *, enum layout_type, int);
 | 
					static int	layout_resize_pane_grow(struct layout_cell *, enum layout_type,
 | 
				
			||||||
int	layout_resize_pane_shrink(struct layout_cell *, enum layout_type, int);
 | 
							    int);
 | 
				
			||||||
 | 
					static int	layout_resize_pane_shrink(struct layout_cell *,
 | 
				
			||||||
 | 
							    enum layout_type, int);
 | 
				
			||||||
 | 
					static int	layout_need_status(struct layout_cell *, int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct layout_cell *
 | 
					struct layout_cell *
 | 
				
			||||||
layout_create_cell(struct layout_cell *lcparent)
 | 
					layout_create_cell(struct layout_cell *lcparent)
 | 
				
			||||||
@@ -163,6 +166,30 @@ layout_fix_offsets(struct layout_cell *lc)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Returns 1 if we need to reserve space for the pane status line. This is the
 | 
				
			||||||
 | 
					 * case for the most upper panes only.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					layout_need_status(struct layout_cell *lc, int at_top)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct layout_cell	*first_lc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (lc->parent) {
 | 
				
			||||||
 | 
							if (lc->parent->type == LAYOUT_LEFTRIGHT)
 | 
				
			||||||
 | 
								return (layout_need_status(lc->parent, at_top));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (at_top)
 | 
				
			||||||
 | 
								first_lc = TAILQ_FIRST(&lc->parent->cells);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								first_lc = TAILQ_LAST(&lc->parent->cells,layout_cells);
 | 
				
			||||||
 | 
							if (lc == first_lc)
 | 
				
			||||||
 | 
								return (layout_need_status(lc->parent, at_top));
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Update pane offsets and sizes based on their cells. */
 | 
					/* Update pane offsets and sizes based on their cells. */
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
layout_fix_panes(struct window *w, u_int wsx, u_int wsy)
 | 
					layout_fix_panes(struct window *w, u_int wsx, u_int wsy)
 | 
				
			||||||
@@ -170,13 +197,25 @@ layout_fix_panes(struct window *w, u_int wsx, u_int wsy)
 | 
				
			|||||||
	struct window_pane	*wp;
 | 
						struct window_pane	*wp;
 | 
				
			||||||
	struct layout_cell	*lc;
 | 
						struct layout_cell	*lc;
 | 
				
			||||||
	u_int			 sx, sy;
 | 
						u_int			 sx, sy;
 | 
				
			||||||
 | 
						int			 shift, status, at_top;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						status = options_get_number(w->options, "pane-border-status");
 | 
				
			||||||
 | 
						at_top = (status == 1);
 | 
				
			||||||
	TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
						TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
		if ((lc = wp->layout_cell) == NULL)
 | 
							if ((lc = wp->layout_cell) == NULL)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (status != 0)
 | 
				
			||||||
 | 
								shift = layout_need_status(lc, at_top);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								shift = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		wp->xoff = lc->xoff;
 | 
							wp->xoff = lc->xoff;
 | 
				
			||||||
		wp->yoff = lc->yoff;
 | 
							wp->yoff = lc->yoff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (shift && at_top)
 | 
				
			||||||
 | 
								wp->yoff += 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * Layout cells are limited by the smallest size of other cells
 | 
							 * Layout cells are limited by the smallest size of other cells
 | 
				
			||||||
		 * within the same row or column; if this isn't the case
 | 
							 * within the same row or column; if this isn't the case
 | 
				
			||||||
@@ -214,6 +253,9 @@ layout_fix_panes(struct window *w, u_int wsx, u_int wsy)
 | 
				
			|||||||
				sy = lc->sy;
 | 
									sy = lc->sy;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (shift)
 | 
				
			||||||
 | 
								sy -= 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		window_pane_resize(wp, sx, sy);
 | 
							window_pane_resize(wp, sx, sy);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -520,7 +562,7 @@ layout_resize_pane(struct window_pane *wp, enum layout_type type, int change)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper function to grow pane. */
 | 
					/* Helper function to grow pane. */
 | 
				
			||||||
int
 | 
					static int
 | 
				
			||||||
layout_resize_pane_grow(struct layout_cell *lc, enum layout_type type,
 | 
					layout_resize_pane_grow(struct layout_cell *lc, enum layout_type type,
 | 
				
			||||||
    int needed)
 | 
					    int needed)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -561,7 +603,7 @@ layout_resize_pane_grow(struct layout_cell *lc, enum layout_type type,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper function to shrink pane. */
 | 
					/* Helper function to shrink pane. */
 | 
				
			||||||
int
 | 
					static int
 | 
				
			||||||
layout_resize_pane_shrink(struct layout_cell *lc, enum layout_type type,
 | 
					layout_resize_pane_shrink(struct layout_cell *lc, enum layout_type type,
 | 
				
			||||||
    int needed)
 | 
					    int needed)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,6 +51,9 @@ const char *options_table_status_position_list[] = {
 | 
				
			|||||||
const char *options_table_bell_action_list[] = {
 | 
					const char *options_table_bell_action_list[] = {
 | 
				
			||||||
	"none", "any", "current", "other", NULL
 | 
						"none", "any", "current", "other", NULL
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					const char *options_table_pane_status_list[] = {
 | 
				
			||||||
 | 
						"off", "top", "bottom", NULL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Server options. */
 | 
					/* Server options. */
 | 
				
			||||||
const struct options_table_entry options_table[] = {
 | 
					const struct options_table_entry options_table[] = {
 | 
				
			||||||
@@ -693,6 +696,19 @@ const struct options_table_entry options_table[] = {
 | 
				
			|||||||
	  .style = "pane-border-style"
 | 
						  .style = "pane-border-style"
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{ .name = "pane-border-format",
 | 
				
			||||||
 | 
						  .type = OPTIONS_TABLE_STRING,
 | 
				
			||||||
 | 
						  .scope = OPTIONS_TABLE_WINDOW,
 | 
				
			||||||
 | 
						  .default_str = "#{?pane_active,#[reverse],}#{pane_index}#[default] \"#{pane_title}\""
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{ .name = "pane-border-status",
 | 
				
			||||||
 | 
						  .type = OPTIONS_TABLE_CHOICE,
 | 
				
			||||||
 | 
						  .scope = OPTIONS_TABLE_WINDOW,
 | 
				
			||||||
 | 
						  .choices = options_table_pane_status_list,
 | 
				
			||||||
 | 
						  .default_num = 0
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ .name = "pane-border-style",
 | 
						{ .name = "pane-border-style",
 | 
				
			||||||
	  .type = OPTIONS_TABLE_STYLE,
 | 
						  .type = OPTIONS_TABLE_STYLE,
 | 
				
			||||||
	  .scope = OPTIONS_TABLE_WINDOW,
 | 
						  .scope = OPTIONS_TABLE_WINDOW,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										175
									
								
								screen-redraw.c
									
									
									
									
									
								
							
							
						
						
									
										175
									
								
								screen-redraw.c
									
									
									
									
									
								
							@@ -24,12 +24,16 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int	screen_redraw_cell_border1(struct window_pane *, u_int, u_int);
 | 
					int	screen_redraw_cell_border1(struct window_pane *, u_int, u_int);
 | 
				
			||||||
int	screen_redraw_cell_border(struct client *, u_int, u_int);
 | 
					int	screen_redraw_cell_border(struct client *, u_int, u_int);
 | 
				
			||||||
int	screen_redraw_check_cell(struct client *, u_int, u_int,
 | 
					int	screen_redraw_check_cell(struct client *, u_int, u_int, int,
 | 
				
			||||||
	    struct window_pane **);
 | 
						    struct window_pane **);
 | 
				
			||||||
int	screen_redraw_check_is(u_int, u_int, int, struct window *,
 | 
					int	screen_redraw_check_is(u_int, u_int, int, int, struct window *,
 | 
				
			||||||
	    struct window_pane *, struct window_pane *);
 | 
						    struct window_pane *, struct window_pane *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void	screen_redraw_draw_borders(struct client *, int, u_int);
 | 
					int 	screen_redraw_make_pane_status(struct client *, struct window *,
 | 
				
			||||||
 | 
						    struct window_pane *);
 | 
				
			||||||
 | 
					void	screen_redraw_draw_pane_status(struct client *, int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	screen_redraw_draw_borders(struct client *, int, int, u_int);
 | 
				
			||||||
void	screen_redraw_draw_panes(struct client *, u_int);
 | 
					void	screen_redraw_draw_panes(struct client *, u_int);
 | 
				
			||||||
void	screen_redraw_draw_status(struct client *, u_int);
 | 
					void	screen_redraw_draw_status(struct client *, u_int);
 | 
				
			||||||
void	screen_redraw_draw_number(struct client *, struct window_pane *, u_int);
 | 
					void	screen_redraw_draw_number(struct client *, struct window_pane *, u_int);
 | 
				
			||||||
@@ -50,6 +54,10 @@ void	screen_redraw_draw_number(struct client *, struct window_pane *, u_int);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define CELL_BORDERS " xqlkmjwvtun~"
 | 
					#define CELL_BORDERS " xqlkmjwvtun~"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CELL_STATUS_OFF 0
 | 
				
			||||||
 | 
					#define CELL_STATUS_TOP 1
 | 
				
			||||||
 | 
					#define CELL_STATUS_BOTTOM 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Check if cell is on the border of a particular pane. */
 | 
					/* Check if cell is on the border of a particular pane. */
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
screen_redraw_cell_border1(struct window_pane *wp, u_int px, u_int py)
 | 
					screen_redraw_cell_border1(struct window_pane *wp, u_int px, u_int py)
 | 
				
			||||||
@@ -64,15 +72,15 @@ screen_redraw_cell_border1(struct window_pane *wp, u_int px, u_int py)
 | 
				
			|||||||
		if (wp->xoff != 0 && px == wp->xoff - 1)
 | 
							if (wp->xoff != 0 && px == wp->xoff - 1)
 | 
				
			||||||
			return (1);
 | 
								return (1);
 | 
				
			||||||
		if (px == wp->xoff + wp->sx)
 | 
							if (px == wp->xoff + wp->sx)
 | 
				
			||||||
			return (1);
 | 
								return (2);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Top/bottom borders. */
 | 
						/* Top/bottom borders. */
 | 
				
			||||||
	if ((wp->xoff == 0 || px >= wp->xoff - 1) && px <= wp->xoff + wp->sx) {
 | 
						if ((wp->xoff == 0 || px >= wp->xoff - 1) && px <= wp->xoff + wp->sx) {
 | 
				
			||||||
		if (wp->yoff != 0 && py == wp->yoff - 1)
 | 
							if (wp->yoff != 0 && py == wp->yoff - 1)
 | 
				
			||||||
			return (1);
 | 
								return (3);
 | 
				
			||||||
		if (py == wp->yoff + wp->sy)
 | 
							if (py == wp->yoff + wp->sy)
 | 
				
			||||||
			return (1);
 | 
								return (4);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Outside pane. */
 | 
						/* Outside pane. */
 | 
				
			||||||
@@ -92,7 +100,7 @@ screen_redraw_cell_border(struct client *c, u_int px, u_int py)
 | 
				
			|||||||
		if (!window_pane_visible(wp))
 | 
							if (!window_pane_visible(wp))
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		if ((retval = screen_redraw_cell_border1(wp, px, py)) != -1)
 | 
							if ((retval = screen_redraw_cell_border1(wp, px, py)) != -1)
 | 
				
			||||||
			return (retval);
 | 
								return (!!retval);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (0);
 | 
						return (0);
 | 
				
			||||||
@@ -100,16 +108,33 @@ screen_redraw_cell_border(struct client *c, u_int px, u_int py)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* Check if cell inside a pane. */
 | 
					/* Check if cell inside a pane. */
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
screen_redraw_check_cell(struct client *c, u_int px, u_int py,
 | 
					screen_redraw_check_cell(struct client *c, u_int px, u_int py, int pane_status,
 | 
				
			||||||
    struct window_pane **wpp)
 | 
					    struct window_pane **wpp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct window		*w = c->session->curw->window;
 | 
						struct window		*w = c->session->curw->window;
 | 
				
			||||||
	struct window_pane	*wp;
 | 
						struct window_pane	*wp;
 | 
				
			||||||
	int			 borders;
 | 
						int			 borders;
 | 
				
			||||||
 | 
						u_int			 right, line;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (px > w->sx || py > w->sy)
 | 
						if (px > w->sx || py > w->sy)
 | 
				
			||||||
		return (CELL_OUTSIDE);
 | 
							return (CELL_OUTSIDE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pane_status != CELL_STATUS_OFF) {
 | 
				
			||||||
 | 
							TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
 | 
								if (!window_pane_visible(wp))
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (pane_status == CELL_STATUS_TOP)
 | 
				
			||||||
 | 
									line = wp->yoff - 1;
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									line = wp->yoff + wp->sy;
 | 
				
			||||||
 | 
								right = wp->xoff + 2 + wp->status_size - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (py == line && px >= wp->xoff + 2 && px <= right)
 | 
				
			||||||
 | 
									return (CELL_INSIDE);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
						TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
		if (!window_pane_visible(wp))
 | 
							if (!window_pane_visible(wp))
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
@@ -135,8 +160,13 @@ screen_redraw_check_cell(struct client *c, u_int px, u_int py,
 | 
				
			|||||||
			borders |= 8;
 | 
								borders |= 8;
 | 
				
			||||||
		if (px <= w->sx && screen_redraw_cell_border(c, px + 1, py))
 | 
							if (px <= w->sx && screen_redraw_cell_border(c, px + 1, py))
 | 
				
			||||||
			borders |= 4;
 | 
								borders |= 4;
 | 
				
			||||||
		if (py == 0 || screen_redraw_cell_border(c, px, py - 1))
 | 
							if (pane_status == CELL_STATUS_TOP) {
 | 
				
			||||||
			borders |= 2;
 | 
								if (py != 0 && screen_redraw_cell_border(c, px, py - 1))
 | 
				
			||||||
 | 
									borders |= 2;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								if (py == 0 || screen_redraw_cell_border(c, px, py - 1))
 | 
				
			||||||
 | 
									borders |= 2;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		if (py <= w->sy && screen_redraw_cell_border(c, px, py + 1))
 | 
							if (py <= w->sy && screen_redraw_cell_border(c, px, py + 1))
 | 
				
			||||||
			borders |= 1;
 | 
								borders |= 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -177,11 +207,18 @@ screen_redraw_check_cell(struct client *c, u_int px, u_int py,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* Check if the border of a particular pane. */
 | 
					/* Check if the border of a particular pane. */
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
screen_redraw_check_is(u_int px, u_int py, int type, struct window *w,
 | 
					screen_redraw_check_is(u_int px, u_int py, int type, int pane_status,
 | 
				
			||||||
    struct window_pane *wantwp, struct window_pane *wp)
 | 
					    struct window *w, struct window_pane *wantwp, struct window_pane *wp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						int	border;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Is this off the active pane border? */
 | 
						/* Is this off the active pane border? */
 | 
				
			||||||
	if (screen_redraw_cell_border1(wantwp, px, py) != 1)
 | 
						border = screen_redraw_cell_border1(wantwp, px, py);
 | 
				
			||||||
 | 
						if (border == 0 || border == -1)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						if (pane_status == CELL_STATUS_TOP && border == 4)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						if (pane_status == CELL_STATUS_BOTTOM && border == 3)
 | 
				
			||||||
		return (0);
 | 
							return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* If there are more than two panes, that's enough. */
 | 
						/* If there are more than two panes, that's enough. */
 | 
				
			||||||
@@ -192,6 +229,10 @@ screen_redraw_check_is(u_int px, u_int py, int type, struct window *w,
 | 
				
			|||||||
	if (wp == NULL || (type == CELL_OUTSIDE || type == CELL_INSIDE))
 | 
						if (wp == NULL || (type == CELL_OUTSIDE || type == CELL_INSIDE))
 | 
				
			||||||
		return (1);
 | 
							return (1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* With status lines mark the entire line. */
 | 
				
			||||||
 | 
						if (pane_status != CELL_STATUS_OFF)
 | 
				
			||||||
 | 
							return (1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Check if the pane covers the whole width. */
 | 
						/* Check if the pane covers the whole width. */
 | 
				
			||||||
	if (wp->xoff == 0 && wp->sx == w->sx) {
 | 
						if (wp->xoff == 0 && wp->sx == w->sx) {
 | 
				
			||||||
		/* This can either be the top pane or the bottom pane. */
 | 
							/* This can either be the top pane or the bottom pane. */
 | 
				
			||||||
@@ -214,7 +255,77 @@ screen_redraw_check_is(u_int px, u_int py, int type, struct window *w,
 | 
				
			|||||||
		return (0);
 | 
							return (0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (type);
 | 
						return (1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Update pane status. */
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					screen_redraw_make_pane_status(struct client *c, struct window *w,
 | 
				
			||||||
 | 
					    struct window_pane *wp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct grid_cell	 gc;
 | 
				
			||||||
 | 
						const char		*fmt;
 | 
				
			||||||
 | 
						struct format_tree	*ft;
 | 
				
			||||||
 | 
						char			*out;
 | 
				
			||||||
 | 
						size_t			 outlen, old_size = wp->status_size;
 | 
				
			||||||
 | 
						struct screen_write_ctx	 ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (wp == w->active)
 | 
				
			||||||
 | 
							style_apply(&gc, w->options, "pane-active-border-style");
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							style_apply(&gc, w->options, "pane-border-style");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fmt = options_get_string(w->options, "pane-border-format");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ft = format_create(NULL, 0);
 | 
				
			||||||
 | 
						format_defaults(ft, c, NULL, NULL, wp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						screen_free(&wp->status_screen);
 | 
				
			||||||
 | 
						screen_init(&wp->status_screen, wp->sx, 1, 0);
 | 
				
			||||||
 | 
						wp->status_screen.mode = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						out = format_expand(ft, fmt);
 | 
				
			||||||
 | 
						outlen = screen_write_cstrlen("%s", out);
 | 
				
			||||||
 | 
						if (outlen > wp->sx - 4)
 | 
				
			||||||
 | 
							outlen = wp->sx - 4;
 | 
				
			||||||
 | 
						screen_resize(&wp->status_screen, outlen, 1, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						screen_write_start(&ctx, NULL, &wp->status_screen);
 | 
				
			||||||
 | 
						screen_write_cursormove(&ctx, 0, 0);
 | 
				
			||||||
 | 
						screen_write_clearline(&ctx);
 | 
				
			||||||
 | 
						screen_write_cnputs(&ctx, outlen, &gc, "%s", out);
 | 
				
			||||||
 | 
						screen_write_stop(&ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						format_free(ft);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wp->status_size = outlen;
 | 
				
			||||||
 | 
						return (wp->status_size != old_size);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Draw pane status. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					screen_redraw_draw_pane_status(struct client *c, int pane_status)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct window		*w = c->session->curw->window;
 | 
				
			||||||
 | 
						struct options		*oo = c->session->options;
 | 
				
			||||||
 | 
						struct tty		*tty = &c->tty;
 | 
				
			||||||
 | 
						struct window_pane	*wp;
 | 
				
			||||||
 | 
						int			 spos;
 | 
				
			||||||
 | 
						u_int			 yoff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spos = options_get_number(oo, "status-position");
 | 
				
			||||||
 | 
						TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
 | 
							if (pane_status == CELL_STATUS_TOP)
 | 
				
			||||||
 | 
								yoff = wp->yoff - 1;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								yoff = wp->yoff + wp->sy;
 | 
				
			||||||
 | 
							if (spos == 0)
 | 
				
			||||||
 | 
								yoff += 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							tty_draw_line(tty, NULL, &wp->status_screen, 0, wp->xoff + 2,
 | 
				
			||||||
 | 
							    yoff);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						tty_cursor(tty, 0, 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Redraw entire screen. */
 | 
					/* Redraw entire screen. */
 | 
				
			||||||
@@ -222,10 +333,12 @@ void
 | 
				
			|||||||
screen_redraw_screen(struct client *c, int draw_panes, int draw_status,
 | 
					screen_redraw_screen(struct client *c, int draw_panes, int draw_status,
 | 
				
			||||||
    int draw_borders)
 | 
					    int draw_borders)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct options	*oo = c->session->options;
 | 
						struct options		*oo = c->session->options;
 | 
				
			||||||
	struct tty	*tty = &c->tty;
 | 
						struct tty		*tty = &c->tty;
 | 
				
			||||||
	u_int		 top;
 | 
						struct window		*w = c->session->curw->window;
 | 
				
			||||||
	int	 	 status, spos;
 | 
						struct window_pane	*wp;
 | 
				
			||||||
 | 
						u_int			 top;
 | 
				
			||||||
 | 
						int	 		 status, pane_status, spos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Suspended clients should not be updated. */
 | 
						/* Suspended clients should not be updated. */
 | 
				
			||||||
	if (c->flags & CLIENT_SUSPENDED)
 | 
						if (c->flags & CLIENT_SUSPENDED)
 | 
				
			||||||
@@ -243,12 +356,24 @@ screen_redraw_screen(struct client *c, int draw_panes, int draw_status,
 | 
				
			|||||||
	if (!status)
 | 
						if (!status)
 | 
				
			||||||
		draw_status = 0;
 | 
							draw_status = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Update pane status lines. */
 | 
				
			||||||
 | 
						pane_status = options_get_number(w->options, "pane-border-status");
 | 
				
			||||||
 | 
						if (pane_status != CELL_STATUS_OFF && (draw_borders || draw_status)) {
 | 
				
			||||||
 | 
							TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
 | 
								if (screen_redraw_make_pane_status(c, w, wp))
 | 
				
			||||||
 | 
									draw_borders = draw_status = 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Draw the elements. */
 | 
				
			||||||
	if (draw_borders)
 | 
						if (draw_borders)
 | 
				
			||||||
		screen_redraw_draw_borders(c, status, top);
 | 
							screen_redraw_draw_borders(c, status, pane_status, top);
 | 
				
			||||||
	if (draw_panes)
 | 
						if (draw_panes)
 | 
				
			||||||
		screen_redraw_draw_panes(c, top);
 | 
							screen_redraw_draw_panes(c, top);
 | 
				
			||||||
	if (draw_status)
 | 
						if (draw_status)
 | 
				
			||||||
		screen_redraw_draw_status(c, top);
 | 
							screen_redraw_draw_status(c, top);
 | 
				
			||||||
 | 
						if (pane_status != CELL_STATUS_OFF && (draw_borders || draw_status))
 | 
				
			||||||
 | 
							screen_redraw_draw_pane_status(c, pane_status);
 | 
				
			||||||
	tty_reset(tty);
 | 
						tty_reset(tty);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -272,7 +397,8 @@ screen_redraw_pane(struct client *c, struct window_pane *wp)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* Draw the borders. */
 | 
					/* Draw the borders. */
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
screen_redraw_draw_borders(struct client *c, int status, u_int top)
 | 
					screen_redraw_draw_borders(struct client *c, int status, int pane_status,
 | 
				
			||||||
 | 
					    u_int top)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct session		*s = c->session;
 | 
						struct session		*s = c->session;
 | 
				
			||||||
	struct window		*w = s->curw->window;
 | 
						struct window		*w = s->curw->window;
 | 
				
			||||||
@@ -323,16 +449,17 @@ screen_redraw_draw_borders(struct client *c, int status, u_int top)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	for (j = 0; j < tty->sy - status; j++) {
 | 
						for (j = 0; j < tty->sy - status; j++) {
 | 
				
			||||||
		for (i = 0; i < tty->sx; i++) {
 | 
							for (i = 0; i < tty->sx; i++) {
 | 
				
			||||||
			type = screen_redraw_check_cell(c, i, j, &wp);
 | 
								type = screen_redraw_check_cell(c, i, j, pane_status,
 | 
				
			||||||
 | 
								    &wp);
 | 
				
			||||||
			if (type == CELL_INSIDE)
 | 
								if (type == CELL_INSIDE)
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
			if (type == CELL_OUTSIDE && small &&
 | 
								if (type == CELL_OUTSIDE && small &&
 | 
				
			||||||
			    i > msgx && j == msgy)
 | 
								    i > msgx && j == msgy)
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
			active = screen_redraw_check_is(i, j, type, w,
 | 
								active = screen_redraw_check_is(i, j, type, pane_status,
 | 
				
			||||||
			    w->active, wp);
 | 
								    w, w->active, wp);
 | 
				
			||||||
			if (server_is_marked(s, s->curw, marked_pane.wp) &&
 | 
								if (server_is_marked(s, s->curw, marked_pane.wp) &&
 | 
				
			||||||
			    screen_redraw_check_is(i, j, type, w,
 | 
								    screen_redraw_check_is(i, j, type, pane_status, w,
 | 
				
			||||||
			    marked_pane.wp, wp)) {
 | 
								    marked_pane.wp, wp)) {
 | 
				
			||||||
				if (active)
 | 
									if (active)
 | 
				
			||||||
					tty_attributes(tty, &m_active_gc, NULL);
 | 
										tty_attributes(tty, &m_active_gc, NULL);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -921,7 +921,7 @@ server_client_check_redraw(struct client *c)
 | 
				
			|||||||
	struct session		*s = c->session;
 | 
						struct session		*s = c->session;
 | 
				
			||||||
	struct tty		*tty = &c->tty;
 | 
						struct tty		*tty = &c->tty;
 | 
				
			||||||
	struct window_pane	*wp;
 | 
						struct window_pane	*wp;
 | 
				
			||||||
	int		 	 flags, redraw;
 | 
						int		 	 flags, masked, redraw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED))
 | 
						if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED))
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
@@ -961,15 +961,15 @@ server_client_check_redraw(struct client *c)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (c->flags & CLIENT_BORDERS) {
 | 
						masked = c->flags & (CLIENT_BORDERS|CLIENT_STATUS);
 | 
				
			||||||
 | 
						if (masked != 0)
 | 
				
			||||||
		tty_update_mode(tty, tty->mode, NULL);
 | 
							tty_update_mode(tty, tty->mode, NULL);
 | 
				
			||||||
 | 
						if (masked == CLIENT_BORDERS)
 | 
				
			||||||
		screen_redraw_screen(c, 0, 0, 1);
 | 
							screen_redraw_screen(c, 0, 0, 1);
 | 
				
			||||||
	}
 | 
						else if (masked == CLIENT_STATUS)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (c->flags & CLIENT_STATUS) {
 | 
					 | 
				
			||||||
		tty_update_mode(tty, tty->mode, NULL);
 | 
					 | 
				
			||||||
		screen_redraw_screen(c, 0, 1, 0);
 | 
							screen_redraw_screen(c, 0, 1, 0);
 | 
				
			||||||
	}
 | 
						else if (masked != 0)
 | 
				
			||||||
 | 
							screen_redraw_screen(c, 0, 1, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tty->flags = (tty->flags & ~(TTY_FREEZE|TTY_NOCURSOR)) | flags;
 | 
						tty->flags = (tty->flags & ~(TTY_FREEZE|TTY_NOCURSOR)) | flags;
 | 
				
			||||||
	tty_update_mode(tty, tty->mode, NULL);
 | 
						tty_update_mode(tty, tty->mode, NULL);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										8
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								tmux.1
									
									
									
									
									
								
							@@ -3065,6 +3065,14 @@ Like
 | 
				
			|||||||
.Ic base-index ,
 | 
					.Ic base-index ,
 | 
				
			||||||
but set the starting index for pane numbers.
 | 
					but set the starting index for pane numbers.
 | 
				
			||||||
.Pp
 | 
					.Pp
 | 
				
			||||||
 | 
					.It Ic pane-border-format Ar format
 | 
				
			||||||
 | 
					Set the text shown in pane border status lines.
 | 
				
			||||||
 | 
					.Pp
 | 
				
			||||||
 | 
					.It Xo Ic pane-border-status
 | 
				
			||||||
 | 
					.Op Ic off | top | bottom
 | 
				
			||||||
 | 
					.Xc
 | 
				
			||||||
 | 
					Turn pane border status lines off or set their position.
 | 
				
			||||||
 | 
					.Pp
 | 
				
			||||||
.It Ic pane-border-style Ar style
 | 
					.It Ic pane-border-style Ar style
 | 
				
			||||||
Set the pane border style for panes aside from the active pane.
 | 
					Set the pane border style for panes aside from the active pane.
 | 
				
			||||||
For how to specify
 | 
					For how to specify
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								tmux.h
									
									
									
									
									
								
							@@ -894,6 +894,9 @@ struct window_pane {
 | 
				
			|||||||
	struct screen	*screen;
 | 
						struct screen	*screen;
 | 
				
			||||||
	struct screen	 base;
 | 
						struct screen	 base;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct screen	 status_screen;
 | 
				
			||||||
 | 
						size_t		 status_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Saved in alternative screen mode. */
 | 
						/* Saved in alternative screen mode. */
 | 
				
			||||||
	u_int		 saved_cx;
 | 
						u_int		 saved_cx;
 | 
				
			||||||
	u_int		 saved_cy;
 | 
						u_int		 saved_cy;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								window.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								window.c
									
									
									
									
									
								
							@@ -764,6 +764,8 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
 | 
				
			|||||||
	screen_init(&wp->base, sx, sy, hlimit);
 | 
						screen_init(&wp->base, sx, sy, hlimit);
 | 
				
			||||||
	wp->screen = &wp->base;
 | 
						wp->screen = &wp->base;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						screen_init(&wp->status_screen, 1, 1, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (gethostname(host, sizeof host) == 0)
 | 
						if (gethostname(host, sizeof host) == 0)
 | 
				
			||||||
		screen_set_title(&wp->base, host);
 | 
							screen_set_title(&wp->base, host);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user