mirror of
https://github.com/tmux/tmux.git
synced 2025-12-18 00:02:54 -05:00
Add box border drawing for active pane
Add screen_redraw_draw_active_box() to draw a complete box border around the active pane when box mode is enabled: - Draw styled border (using pane-active-border-style) for active pane - Draw blank spaces for inactive pane border areas - Skip normal pane separator borders when box mode is active - Adjust pane content drawing to account for box mode offset - Call box drawing on border redraws, window redraws, and pane redraws The box border uses the configured pane-border-lines style for the line drawing characters.
This commit is contained in:
parent
3d3cdaedda
commit
27baf46563
165
screen-redraw.c
165
screen-redraw.c
@ -35,6 +35,7 @@ static void screen_redraw_draw_scrollbar(struct screen_redraw_ctx *,
|
|||||||
struct window_pane *, int, int, int, u_int, u_int, u_int);
|
struct window_pane *, int, int, int, u_int, u_int, u_int);
|
||||||
static void screen_redraw_draw_pane_scrollbar(struct screen_redraw_ctx *,
|
static void screen_redraw_draw_pane_scrollbar(struct screen_redraw_ctx *,
|
||||||
struct window_pane *);
|
struct window_pane *);
|
||||||
|
static void screen_redraw_draw_active_box(struct screen_redraw_ctx *);
|
||||||
|
|
||||||
#define START_ISOLATE "\342\201\246"
|
#define START_ISOLATE "\342\201\246"
|
||||||
#define END_ISOLATE "\342\201\251"
|
#define END_ISOLATE "\342\201\251"
|
||||||
@ -662,11 +663,13 @@ screen_redraw_screen(struct client *c)
|
|||||||
screen_redraw_draw_borders(&ctx);
|
screen_redraw_draw_borders(&ctx);
|
||||||
if (ctx.pane_status != PANE_STATUS_OFF)
|
if (ctx.pane_status != PANE_STATUS_OFF)
|
||||||
screen_redraw_draw_pane_status(&ctx);
|
screen_redraw_draw_pane_status(&ctx);
|
||||||
|
screen_redraw_draw_active_box(&ctx);
|
||||||
screen_redraw_draw_pane_scrollbars(&ctx);
|
screen_redraw_draw_pane_scrollbars(&ctx);
|
||||||
}
|
}
|
||||||
if (flags & CLIENT_REDRAWWINDOW) {
|
if (flags & CLIENT_REDRAWWINDOW) {
|
||||||
log_debug("%s: redrawing panes", c->name);
|
log_debug("%s: redrawing panes", c->name);
|
||||||
screen_redraw_draw_panes(&ctx);
|
screen_redraw_draw_panes(&ctx);
|
||||||
|
screen_redraw_draw_active_box(&ctx);
|
||||||
screen_redraw_draw_pane_scrollbars(&ctx);
|
screen_redraw_draw_pane_scrollbars(&ctx);
|
||||||
}
|
}
|
||||||
if (ctx.statuslines != 0 &&
|
if (ctx.statuslines != 0 &&
|
||||||
@ -696,8 +699,10 @@ screen_redraw_pane(struct client *c, struct window_pane *wp,
|
|||||||
tty_sync_start(&c->tty);
|
tty_sync_start(&c->tty);
|
||||||
tty_update_mode(&c->tty, c->tty.mode, NULL);
|
tty_update_mode(&c->tty, c->tty.mode, NULL);
|
||||||
|
|
||||||
if (!redraw_scrollbar_only)
|
if (!redraw_scrollbar_only) {
|
||||||
screen_redraw_draw_pane(&ctx, wp);
|
screen_redraw_draw_pane(&ctx, wp);
|
||||||
|
screen_redraw_draw_active_box(&ctx);
|
||||||
|
}
|
||||||
|
|
||||||
if (window_pane_show_scrollbar(wp, ctx.pane_scrollbars))
|
if (window_pane_show_scrollbar(wp, ctx.pane_scrollbars))
|
||||||
screen_redraw_draw_pane_scrollbar(&ctx, wp);
|
screen_redraw_draw_pane_scrollbar(&ctx, wp);
|
||||||
@ -833,11 +838,20 @@ screen_redraw_draw_borders(struct screen_redraw_ctx *ctx)
|
|||||||
struct client *c = ctx->c;
|
struct client *c = ctx->c;
|
||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
struct window *w = s->curw->window;
|
struct window *w = s->curw->window;
|
||||||
|
struct options *oo = w->options;
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
u_int i, j;
|
u_int i, j;
|
||||||
|
|
||||||
log_debug("%s: %s @%u", __func__, c->name, w->id);
|
log_debug("%s: %s @%u", __func__, c->name, w->id);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Skip drawing pane separator borders when box mode is active,
|
||||||
|
* since each pane has its own complete box border.
|
||||||
|
*/
|
||||||
|
if (options_get_number(oo, "pane-border-indicators") == PANE_BORDER_BOX &&
|
||||||
|
TAILQ_NEXT(TAILQ_FIRST(&w->panes), entry) != NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
TAILQ_FOREACH(wp, &w->panes, entry)
|
TAILQ_FOREACH(wp, &w->panes, entry)
|
||||||
wp->border_gc_set = 0;
|
wp->border_gc_set = 0;
|
||||||
|
|
||||||
@ -847,6 +861,134 @@ screen_redraw_draw_borders(struct screen_redraw_ctx *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Draw box border around the active pane. */
|
||||||
|
static void
|
||||||
|
screen_redraw_draw_active_box(struct screen_redraw_ctx *ctx)
|
||||||
|
{
|
||||||
|
struct client *c = ctx->c;
|
||||||
|
struct session *s = c->session;
|
||||||
|
struct window *w = s->curw->window;
|
||||||
|
struct options *oo = w->options;
|
||||||
|
struct tty *tty = &c->tty;
|
||||||
|
struct window_pane *wp, *active_wp;
|
||||||
|
struct grid_cell gc, blank_gc;
|
||||||
|
struct format_tree *ft;
|
||||||
|
u_int i, top, left, right, bottom, tty_top;
|
||||||
|
int is_active;
|
||||||
|
|
||||||
|
/* Check if box mode is enabled. */
|
||||||
|
if (options_get_number(oo, "pane-border-indicators") != PANE_BORDER_BOX)
|
||||||
|
return;
|
||||||
|
if (TAILQ_NEXT(TAILQ_FIRST(&w->panes), entry) == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Get active pane. */
|
||||||
|
active_wp = server_client_get_pane(c);
|
||||||
|
|
||||||
|
/* Account for status line at top. */
|
||||||
|
if (ctx->statustop)
|
||||||
|
tty_top = ctx->statuslines;
|
||||||
|
else
|
||||||
|
tty_top = 0;
|
||||||
|
|
||||||
|
/* Set up blank cell for inactive pane borders. */
|
||||||
|
memcpy(&blank_gc, &grid_default_cell, sizeof blank_gc);
|
||||||
|
utf8_set(&blank_gc.data, ' ');
|
||||||
|
|
||||||
|
/* Draw border area for all panes. */
|
||||||
|
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||||
|
if (!window_pane_visible(wp))
|
||||||
|
continue;
|
||||||
|
if (wp->sx < 3 || wp->sy < 3)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
is_active = (wp == active_wp);
|
||||||
|
|
||||||
|
log_debug("%s: %s @%u %%%u active=%d", __func__, c->name,
|
||||||
|
w->id, wp->id, is_active);
|
||||||
|
|
||||||
|
/* Calculate box position. */
|
||||||
|
left = wp->xoff;
|
||||||
|
right = wp->xoff + wp->sx - 1;
|
||||||
|
top = wp->yoff;
|
||||||
|
bottom = wp->yoff + wp->sy - 1;
|
||||||
|
|
||||||
|
if (is_active) {
|
||||||
|
/* Set up grid cell with active border style. */
|
||||||
|
memcpy(&gc, &grid_default_cell, sizeof gc);
|
||||||
|
ft = format_create_defaults(NULL, c, s, s->curw, wp);
|
||||||
|
style_apply(&gc, oo, "pane-active-border-style", ft);
|
||||||
|
format_free(ft);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw top border. */
|
||||||
|
for (i = left; i <= right; i++) {
|
||||||
|
if (is_active) {
|
||||||
|
if (i == left)
|
||||||
|
screen_redraw_border_set(w, wp,
|
||||||
|
ctx->pane_lines, CELL_TOPLEFT, &gc);
|
||||||
|
else if (i == right)
|
||||||
|
screen_redraw_border_set(w, wp,
|
||||||
|
ctx->pane_lines, CELL_TOPRIGHT, &gc);
|
||||||
|
else
|
||||||
|
screen_redraw_border_set(w, wp,
|
||||||
|
ctx->pane_lines, CELL_LEFTRIGHT, &gc);
|
||||||
|
tty_cursor(tty, i, tty_top + top);
|
||||||
|
tty_cell(tty, &gc, &grid_default_cell, NULL, NULL);
|
||||||
|
} else {
|
||||||
|
tty_cursor(tty, i, tty_top + top);
|
||||||
|
tty_cell(tty, &blank_gc, &grid_default_cell, NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw bottom border. */
|
||||||
|
for (i = left; i <= right; i++) {
|
||||||
|
if (is_active) {
|
||||||
|
if (i == left)
|
||||||
|
screen_redraw_border_set(w, wp,
|
||||||
|
ctx->pane_lines, CELL_BOTTOMLEFT, &gc);
|
||||||
|
else if (i == right)
|
||||||
|
screen_redraw_border_set(w, wp,
|
||||||
|
ctx->pane_lines, CELL_BOTTOMRIGHT, &gc);
|
||||||
|
else
|
||||||
|
screen_redraw_border_set(w, wp,
|
||||||
|
ctx->pane_lines, CELL_LEFTRIGHT, &gc);
|
||||||
|
tty_cursor(tty, i, tty_top + bottom);
|
||||||
|
tty_cell(tty, &gc, &grid_default_cell, NULL, NULL);
|
||||||
|
} else {
|
||||||
|
tty_cursor(tty, i, tty_top + bottom);
|
||||||
|
tty_cell(tty, &blank_gc, &grid_default_cell, NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw left border (excluding corners). */
|
||||||
|
for (i = top + 1; i < bottom; i++) {
|
||||||
|
if (is_active) {
|
||||||
|
screen_redraw_border_set(w, wp, ctx->pane_lines,
|
||||||
|
CELL_TOPBOTTOM, &gc);
|
||||||
|
tty_cursor(tty, left, tty_top + i);
|
||||||
|
tty_cell(tty, &gc, &grid_default_cell, NULL, NULL);
|
||||||
|
} else {
|
||||||
|
tty_cursor(tty, left, tty_top + i);
|
||||||
|
tty_cell(tty, &blank_gc, &grid_default_cell, NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw right border (excluding corners). */
|
||||||
|
for (i = top + 1; i < bottom; i++) {
|
||||||
|
if (is_active) {
|
||||||
|
screen_redraw_border_set(w, wp, ctx->pane_lines,
|
||||||
|
CELL_TOPBOTTOM, &gc);
|
||||||
|
tty_cursor(tty, right, tty_top + i);
|
||||||
|
tty_cell(tty, &gc, &grid_default_cell, NULL, NULL);
|
||||||
|
} else {
|
||||||
|
tty_cursor(tty, right, tty_top + i);
|
||||||
|
tty_cell(tty, &blank_gc, &grid_default_cell, NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Draw the panes. */
|
/* Draw the panes. */
|
||||||
static void
|
static void
|
||||||
screen_redraw_draw_panes(struct screen_redraw_ctx *ctx)
|
screen_redraw_draw_panes(struct screen_redraw_ctx *ctx)
|
||||||
@ -896,8 +1038,11 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
|
|||||||
struct colour_palette *palette = &wp->palette;
|
struct colour_palette *palette = &wp->palette;
|
||||||
struct grid_cell defaults;
|
struct grid_cell defaults;
|
||||||
u_int i, j, top, x, y, width;
|
u_int i, j, top, x, y, width;
|
||||||
|
int box_mode;
|
||||||
|
|
||||||
log_debug("%s: %s @%u %%%u", __func__, c->name, w->id, wp->id);
|
box_mode = window_pane_box_mode(wp);
|
||||||
|
log_debug("%s: %s @%u %%%u box=%d", __func__, c->name, w->id, wp->id,
|
||||||
|
box_mode);
|
||||||
|
|
||||||
if (wp->xoff + wp->sx <= ctx->ox || wp->xoff >= ctx->ox + ctx->sx)
|
if (wp->xoff + wp->sx <= ctx->ox || wp->xoff >= ctx->ox + ctx->sx)
|
||||||
return;
|
return;
|
||||||
@ -905,34 +1050,44 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
|
|||||||
top = ctx->statuslines;
|
top = ctx->statuslines;
|
||||||
else
|
else
|
||||||
top = 0;
|
top = 0;
|
||||||
for (j = 0; j < wp->sy; j++) {
|
for (j = 0; j < (box_mode ? wp->sy - 2 : wp->sy); j++) {
|
||||||
if (wp->yoff + j < ctx->oy || wp->yoff + j >= ctx->oy + ctx->sy)
|
if (wp->yoff + j < ctx->oy || wp->yoff + j >= ctx->oy + ctx->sy)
|
||||||
continue;
|
continue;
|
||||||
y = top + wp->yoff + j - ctx->oy;
|
|
||||||
|
|
||||||
if (wp->xoff >= ctx->ox &&
|
if (box_mode) {
|
||||||
|
/* Box mode: draw at offset position. */
|
||||||
|
y = top + wp->yoff + 1 + j - ctx->oy;
|
||||||
|
i = 0;
|
||||||
|
x = wp->xoff + 1 - ctx->ox;
|
||||||
|
width = wp->sx - 2;
|
||||||
|
} else if (wp->xoff >= ctx->ox &&
|
||||||
wp->xoff + wp->sx <= ctx->ox + ctx->sx) {
|
wp->xoff + wp->sx <= ctx->ox + ctx->sx) {
|
||||||
/* All visible. */
|
/* All visible. */
|
||||||
|
y = top + wp->yoff + j - ctx->oy;
|
||||||
i = 0;
|
i = 0;
|
||||||
x = wp->xoff - ctx->ox;
|
x = wp->xoff - ctx->ox;
|
||||||
width = wp->sx;
|
width = wp->sx;
|
||||||
} else if (wp->xoff < ctx->ox &&
|
} else if (wp->xoff < ctx->ox &&
|
||||||
wp->xoff + wp->sx > ctx->ox + ctx->sx) {
|
wp->xoff + wp->sx > ctx->ox + ctx->sx) {
|
||||||
/* Both left and right not visible. */
|
/* Both left and right not visible. */
|
||||||
|
y = top + wp->yoff + j - ctx->oy;
|
||||||
i = ctx->ox;
|
i = ctx->ox;
|
||||||
x = 0;
|
x = 0;
|
||||||
width = ctx->sx;
|
width = ctx->sx;
|
||||||
} else if (wp->xoff < ctx->ox) {
|
} else if (wp->xoff < ctx->ox) {
|
||||||
/* Left not visible. */
|
/* Left not visible. */
|
||||||
|
y = top + wp->yoff + j - ctx->oy;
|
||||||
i = ctx->ox - wp->xoff;
|
i = ctx->ox - wp->xoff;
|
||||||
x = 0;
|
x = 0;
|
||||||
width = wp->sx - i;
|
width = wp->sx - i;
|
||||||
} else {
|
} else {
|
||||||
/* Right not visible. */
|
/* Right not visible. */
|
||||||
|
y = top + wp->yoff + j - ctx->oy;
|
||||||
i = 0;
|
i = 0;
|
||||||
x = wp->xoff - ctx->ox;
|
x = wp->xoff - ctx->ox;
|
||||||
width = ctx->sx - x;
|
width = ctx->sx - x;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_debug("%s: %s %%%u line %u,%u at %u,%u, width %u",
|
log_debug("%s: %s %%%u line %u,%u at %u,%u, width %u",
|
||||||
__func__, c->name, wp->id, i, j, x, y, width);
|
__func__, c->name, wp->id, i, j, x, y, width);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user