mirror of
https://github.com/tmux/tmux.git
synced 2026-10-15 07:44:24 +00:00
Do redraw as two phases for text and images.
This commit is contained in:
157
screen-redraw.c
157
screen-redraw.c
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: screen-redraw.c,v 1.163 2026/10/02 12:48:52 nicm Exp $ */
|
/* $OpenBSD: screen-redraw.c,v 1.164 2026/10/14 10:34:14 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2026 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2026 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -72,6 +72,13 @@ enum redraw_span_type {
|
|||||||
};
|
};
|
||||||
#define REDRAW_SPAN_TYPES 7
|
#define REDRAW_SPAN_TYPES 7
|
||||||
|
|
||||||
|
/* Draw phases. */
|
||||||
|
enum redraw_phase {
|
||||||
|
REDRAW_TEXT,
|
||||||
|
REDRAW_IMAGES
|
||||||
|
};
|
||||||
|
#define REDRAW_PHASE_COUNT 2
|
||||||
|
|
||||||
/* Border connections to adjacent cells. */
|
/* Border connections to adjacent cells. */
|
||||||
#define REDRAW_BORDER_L 0x1
|
#define REDRAW_BORDER_L 0x1
|
||||||
#define REDRAW_BORDER_R 0x2
|
#define REDRAW_BORDER_R 0x2
|
||||||
@@ -1503,31 +1510,35 @@ redraw_draw_menu_span(struct redraw_draw_ctx *dctx,
|
|||||||
/* Draw a span. */
|
/* Draw a span. */
|
||||||
static void
|
static void
|
||||||
redraw_draw_span(struct redraw_draw_ctx *dctx, struct redraw_span *span,
|
redraw_draw_span(struct redraw_draw_ctx *dctx, struct redraw_span *span,
|
||||||
u_int y)
|
u_int y, enum redraw_phase phase)
|
||||||
{
|
{
|
||||||
struct redraw_span_data *data = &span->data;
|
struct redraw_span_data *data = &span->data;
|
||||||
enum redraw_span_type type = data->type;
|
enum redraw_span_type type = data->type;
|
||||||
|
u_int width = span->width;
|
||||||
|
|
||||||
if (type == REDRAW_SPAN_STATUS && ~data->st.wp->flags & PANE_NEWSTATUS)
|
if (type == REDRAW_SPAN_STATUS && ~data->st.wp->flags & PANE_NEWSTATUS)
|
||||||
return;
|
return;
|
||||||
|
if (phase != REDRAW_TEXT && type != REDRAW_SPAN_PANE)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (span->data.type) {
|
switch (span->data.type) {
|
||||||
case REDRAW_SPAN_PANE:
|
case REDRAW_SPAN_PANE:
|
||||||
redraw_draw_pane_span(dctx, span, span->x, y, span->width);
|
if (phase == REDRAW_TEXT)
|
||||||
|
redraw_draw_pane_span(dctx, span, span->x, y, width);
|
||||||
break;
|
break;
|
||||||
case REDRAW_SPAN_BORDER:
|
case REDRAW_SPAN_BORDER:
|
||||||
case REDRAW_SPAN_EMPTY:
|
case REDRAW_SPAN_EMPTY:
|
||||||
case REDRAW_SPAN_OUTSIDE:
|
case REDRAW_SPAN_OUTSIDE:
|
||||||
redraw_draw_border_span(dctx, span, span->x, y, span->width);
|
redraw_draw_border_span(dctx, span, span->x, y, width);
|
||||||
break;
|
break;
|
||||||
case REDRAW_SPAN_STATUS:
|
case REDRAW_SPAN_STATUS:
|
||||||
redraw_draw_status_span(dctx, span, span->x, y, span->width);
|
redraw_draw_status_span(dctx, span, span->x, y, width);
|
||||||
break;
|
break;
|
||||||
case REDRAW_SPAN_SCROLLBAR:
|
case REDRAW_SPAN_SCROLLBAR:
|
||||||
redraw_draw_scrollbar_span(dctx, span, span->x, y, span->width);
|
redraw_draw_scrollbar_span(dctx, span, span->x, y, width);
|
||||||
break;
|
break;
|
||||||
case REDRAW_SPAN_MENU:
|
case REDRAW_SPAN_MENU:
|
||||||
redraw_draw_menu_span(dctx, span, span->x, y, span->width);
|
redraw_draw_menu_span(dctx, span, span->x, y, width);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1541,6 +1552,7 @@ redraw_draw_pane_lines(struct redraw_draw_ctx *dctx, struct window_pane *wp,
|
|||||||
struct redraw_line *line;
|
struct redraw_line *line;
|
||||||
struct redraw_spans *spans;
|
struct redraw_spans *spans;
|
||||||
struct redraw_span *span;
|
struct redraw_span *span;
|
||||||
|
enum redraw_phase phase;
|
||||||
u_int cy;
|
u_int cy;
|
||||||
int y, top, bottom;
|
int y, top, bottom;
|
||||||
|
|
||||||
@@ -1553,6 +1565,8 @@ redraw_draw_pane_lines(struct redraw_draw_ctx *dctx, struct window_pane *wp,
|
|||||||
if (bottom > (int)scene->sy)
|
if (bottom > (int)scene->sy)
|
||||||
bottom = scene->sy;
|
bottom = scene->sy;
|
||||||
|
|
||||||
|
/* Draw each phase. */
|
||||||
|
for (phase = 0; phase < REDRAW_PHASE_COUNT; phase++) {
|
||||||
for (y = top; y < bottom; y++) {
|
for (y = top; y < bottom; y++) {
|
||||||
line = &scene->lines[y];
|
line = &scene->lines[y];
|
||||||
if (dctx->flags & REDRAW_STATUS_TOP)
|
if (dctx->flags & REDRAW_STATUS_TOP)
|
||||||
@@ -1562,18 +1576,52 @@ redraw_draw_pane_lines(struct redraw_draw_ctx *dctx, struct window_pane *wp,
|
|||||||
if (flags & REDRAW_PANE) {
|
if (flags & REDRAW_PANE) {
|
||||||
spans = &line->spans[REDRAW_SPAN_PANE];
|
spans = &line->spans[REDRAW_SPAN_PANE];
|
||||||
TAILQ_FOREACH(span, spans, entry) {
|
TAILQ_FOREACH(span, spans, entry) {
|
||||||
if (span->data.p.wp == wp)
|
if (span->data.p.wp != wp)
|
||||||
redraw_draw_span(dctx, span, cy);
|
continue;
|
||||||
|
redraw_draw_span(dctx, span, cy, phase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (flags & REDRAW_PANE_SCROLLBAR) {
|
if (phase == REDRAW_TEXT &&
|
||||||
|
(flags & REDRAW_PANE_SCROLLBAR)) {
|
||||||
spans = &line->spans[REDRAW_SPAN_SCROLLBAR];
|
spans = &line->spans[REDRAW_SPAN_SCROLLBAR];
|
||||||
TAILQ_FOREACH(span, spans, entry) {
|
TAILQ_FOREACH(span, spans, entry) {
|
||||||
if (span->data.sb.wp == wp)
|
if (span->data.sb.wp != wp)
|
||||||
redraw_draw_span(dctx, span, cy);
|
continue;
|
||||||
|
redraw_draw_span(dctx, span, cy, phase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return whether to draw a span type in this phase for these flags. */
|
||||||
|
static int
|
||||||
|
redraw_should_draw(enum redraw_span_type type, int flags,
|
||||||
|
enum redraw_phase phase)
|
||||||
|
{
|
||||||
|
if (phase != REDRAW_TEXT && type != REDRAW_SPAN_PANE)
|
||||||
|
return (0);
|
||||||
|
if (REDRAW_IS_ALL(flags))
|
||||||
|
return (1);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case REDRAW_SPAN_PANE:
|
||||||
|
return (flags & REDRAW_PANE);
|
||||||
|
case REDRAW_SPAN_OUTSIDE:
|
||||||
|
return (flags & REDRAW_OUTSIDE);
|
||||||
|
case REDRAW_SPAN_EMPTY:
|
||||||
|
return (flags & REDRAW_EMPTY);
|
||||||
|
case REDRAW_SPAN_BORDER:
|
||||||
|
return (flags & REDRAW_PANE_BORDER);
|
||||||
|
case REDRAW_SPAN_STATUS:
|
||||||
|
return (flags & REDRAW_PANE_STATUS);
|
||||||
|
case REDRAW_SPAN_SCROLLBAR:
|
||||||
|
return (flags & REDRAW_PANE_SCROLLBAR);
|
||||||
|
case REDRAW_SPAN_MENU:
|
||||||
|
return (flags & REDRAW_MENU);
|
||||||
|
default:
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw lines. */
|
/* Draw lines. */
|
||||||
@@ -1584,8 +1632,11 @@ redraw_draw_lines(struct redraw_draw_ctx *dctx, int flags)
|
|||||||
struct redraw_line *line;
|
struct redraw_line *line;
|
||||||
struct redraw_spans *spans;
|
struct redraw_spans *spans;
|
||||||
struct redraw_span *span;
|
struct redraw_span *span;
|
||||||
|
enum redraw_phase phase;
|
||||||
u_int y, cy, type;
|
u_int y, cy, type;
|
||||||
|
|
||||||
|
/* Draw each phase. */
|
||||||
|
for (phase = 0; phase < REDRAW_PHASE_COUNT; phase++) {
|
||||||
for (y = 0; y < scene->sy; y++) {
|
for (y = 0; y < scene->sy; y++) {
|
||||||
line = &scene->lines[y];
|
line = &scene->lines[y];
|
||||||
if (dctx->flags & REDRAW_STATUS_TOP)
|
if (dctx->flags & REDRAW_STATUS_TOP)
|
||||||
@@ -1593,43 +1644,12 @@ redraw_draw_lines(struct redraw_draw_ctx *dctx, int flags)
|
|||||||
else
|
else
|
||||||
cy = y;
|
cy = y;
|
||||||
for (type = 0; type < REDRAW_SPAN_TYPES; type++) {
|
for (type = 0; type < REDRAW_SPAN_TYPES; type++) {
|
||||||
if (!REDRAW_IS_ALL(flags)) {
|
if (!redraw_should_draw(type, flags, phase))
|
||||||
switch (type) {
|
|
||||||
case REDRAW_SPAN_PANE:
|
|
||||||
if (~flags & REDRAW_PANE)
|
|
||||||
continue;
|
continue;
|
||||||
break;
|
|
||||||
case REDRAW_SPAN_OUTSIDE:
|
|
||||||
if (~flags & REDRAW_OUTSIDE)
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
case REDRAW_SPAN_EMPTY:
|
|
||||||
if (~flags & REDRAW_EMPTY)
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
case REDRAW_SPAN_BORDER:
|
|
||||||
if (~flags & REDRAW_PANE_BORDER)
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
case REDRAW_SPAN_STATUS:
|
|
||||||
if (~flags & REDRAW_PANE_STATUS)
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
case REDRAW_SPAN_SCROLLBAR:
|
|
||||||
if (~flags & REDRAW_PANE_SCROLLBAR)
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
case REDRAW_SPAN_MENU:
|
|
||||||
if (~flags & REDRAW_MENU)
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spans = &line->spans[type];
|
spans = &line->spans[type];
|
||||||
TAILQ_FOREACH(span, spans, entry)
|
TAILQ_FOREACH(span, spans, entry)
|
||||||
redraw_draw_span(dctx, span, cy);
|
redraw_draw_span(dctx, span, cy, phase);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1650,7 +1670,7 @@ redraw_draw_menu_lines(struct redraw_draw_ctx *dctx)
|
|||||||
else
|
else
|
||||||
cy = y;
|
cy = y;
|
||||||
TAILQ_FOREACH(span, &line->spans[REDRAW_SPAN_MENU], entry)
|
TAILQ_FOREACH(span, &line->spans[REDRAW_SPAN_MENU], entry)
|
||||||
redraw_draw_span(dctx, span, cy);
|
redraw_draw_span(dctx, span, cy, REDRAW_TEXT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2053,6 +2073,7 @@ redraw_draw_damage_rectangle(struct redraw_draw_ctx *dctx, u_int x, u_int y,
|
|||||||
struct redraw_line *line;
|
struct redraw_line *line;
|
||||||
struct redraw_spans *spans;
|
struct redraw_spans *spans;
|
||||||
struct redraw_span *span;
|
struct redraw_span *span;
|
||||||
|
enum redraw_phase phase;
|
||||||
u_int cy, yy, type;
|
u_int cy, yy, type;
|
||||||
|
|
||||||
if (x >= scene->sx || y >= scene->sy)
|
if (x >= scene->sx || y >= scene->sy)
|
||||||
@@ -2064,6 +2085,8 @@ redraw_draw_damage_rectangle(struct redraw_draw_ctx *dctx, u_int x, u_int y,
|
|||||||
if (sx == 0 || sy == 0)
|
if (sx == 0 || sy == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Draw each phase in the damaged spans. */
|
||||||
|
for (phase = 0; phase < REDRAW_PHASE_COUNT; phase++) {
|
||||||
for (yy = y; yy < y + sy; yy++) {
|
for (yy = y; yy < y + sy; yy++) {
|
||||||
line = &scene->lines[yy];
|
line = &scene->lines[yy];
|
||||||
if (dctx->flags & REDRAW_STATUS_TOP)
|
if (dctx->flags & REDRAW_STATUS_TOP)
|
||||||
@@ -2071,24 +2094,48 @@ redraw_draw_damage_rectangle(struct redraw_draw_ctx *dctx, u_int x, u_int y,
|
|||||||
else
|
else
|
||||||
cy = yy;
|
cy = yy;
|
||||||
for (type = 0; type < REDRAW_SPAN_TYPES; type++) {
|
for (type = 0; type < REDRAW_SPAN_TYPES; type++) {
|
||||||
|
if (phase != REDRAW_TEXT &&
|
||||||
|
type != REDRAW_SPAN_PANE)
|
||||||
|
continue;
|
||||||
|
if (type == REDRAW_SPAN_STATUS)
|
||||||
|
continue;
|
||||||
spans = &line->spans[type];
|
spans = &line->spans[type];
|
||||||
TAILQ_FOREACH(span, spans, entry) {
|
TAILQ_FOREACH(span, spans, entry) {
|
||||||
if (span->x >= x + sx)
|
if (span->x >= x + sx)
|
||||||
continue;
|
continue;
|
||||||
if (span->x + span->width <= x)
|
if (span->x + span->width <= x)
|
||||||
continue;
|
continue;
|
||||||
if (type == REDRAW_SPAN_STATUS) {
|
redraw_draw_span(dctx, span, cy, phase);
|
||||||
redraw_damage_refresh_status(dctx,
|
|
||||||
span->data.st.wp);
|
|
||||||
}
|
|
||||||
redraw_draw_span(dctx, span, cy);
|
|
||||||
if (type == REDRAW_SPAN_PANE) {
|
|
||||||
redraw_damage_draw_pane_prompt(dctx,
|
|
||||||
span, cy);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Draw prompts and pane status lines last. */
|
||||||
|
for (yy = y; yy < y + sy; yy++) {
|
||||||
|
line = &scene->lines[yy];
|
||||||
|
if (dctx->flags & REDRAW_STATUS_TOP)
|
||||||
|
cy = dctx->status_lines + yy;
|
||||||
|
else
|
||||||
|
cy = yy;
|
||||||
|
spans = &line->spans[REDRAW_SPAN_PANE];
|
||||||
|
TAILQ_FOREACH(span, spans, entry) {
|
||||||
|
if (span->x >= x + sx)
|
||||||
|
continue;
|
||||||
|
if (span->x + span->width <= x)
|
||||||
|
continue;
|
||||||
|
redraw_damage_draw_pane_prompt(dctx, span, cy);
|
||||||
|
}
|
||||||
|
spans = &line->spans[REDRAW_SPAN_STATUS];
|
||||||
|
TAILQ_FOREACH(span, spans, entry) {
|
||||||
|
if (span->x >= x + sx)
|
||||||
|
continue;
|
||||||
|
if (span->x + span->width <= x)
|
||||||
|
continue;
|
||||||
|
redraw_damage_refresh_status(dctx, span->data.st.wp);
|
||||||
|
redraw_draw_span(dctx, span, cy, REDRAW_TEXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw pending window damage on this client. */
|
/* Draw pending window damage on this client. */
|
||||||
|
|||||||
2
tmux.h
2
tmux.h
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: tmux.h,v 1.1460 2026/10/14 08:33:19 nicm Exp $ */
|
/* $OpenBSD: tmux.h,v 1.1461 2026/10/14 10:34:14 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
|
|||||||
Reference in New Issue
Block a user