mirror of
https://github.com/tmux/tmux.git
synced 2026-10-14 23:34:22 +00:00
Two phases for redraw.
This commit is contained in:
215
screen-redraw.c
215
screen-redraw.c
@@ -72,6 +72,13 @@ enum redraw_span_type {
|
||||
};
|
||||
#define REDRAW_SPAN_TYPES 7
|
||||
|
||||
/* Draw phases. */
|
||||
enum redraw_phase {
|
||||
REDRAW_TEXT,
|
||||
REDRAW_IMAGES
|
||||
};
|
||||
#define REDRAW_PHASE_COUNT 2
|
||||
|
||||
/* Border connections to adjacent cells. */
|
||||
#define REDRAW_BORDER_L 0x1
|
||||
#define REDRAW_BORDER_R 0x2
|
||||
@@ -1503,31 +1510,35 @@ redraw_draw_menu_span(struct redraw_draw_ctx *dctx,
|
||||
/* Draw a span. */
|
||||
static void
|
||||
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;
|
||||
enum redraw_span_type type = data->type;
|
||||
u_int width = span->width;
|
||||
|
||||
if (type == REDRAW_SPAN_STATUS && ~data->st.wp->flags & PANE_NEWSTATUS)
|
||||
return;
|
||||
if (phase != REDRAW_TEXT && type != REDRAW_SPAN_PANE)
|
||||
return;
|
||||
|
||||
switch (span->data.type) {
|
||||
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;
|
||||
case REDRAW_SPAN_BORDER:
|
||||
case REDRAW_SPAN_EMPTY:
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1541,6 +1552,7 @@ redraw_draw_pane_lines(struct redraw_draw_ctx *dctx, struct window_pane *wp,
|
||||
struct redraw_line *line;
|
||||
struct redraw_spans *spans;
|
||||
struct redraw_span *span;
|
||||
enum redraw_phase phase;
|
||||
u_int cy;
|
||||
int y, top, bottom;
|
||||
|
||||
@@ -1553,29 +1565,65 @@ redraw_draw_pane_lines(struct redraw_draw_ctx *dctx, struct window_pane *wp,
|
||||
if (bottom > (int)scene->sy)
|
||||
bottom = scene->sy;
|
||||
|
||||
for (y = top; y < bottom; y++) {
|
||||
line = &scene->lines[y];
|
||||
if (dctx->flags & REDRAW_STATUS_TOP)
|
||||
cy = dctx->status_lines + y;
|
||||
else
|
||||
cy = y;
|
||||
if (flags & REDRAW_PANE) {
|
||||
spans = &line->spans[REDRAW_SPAN_PANE];
|
||||
TAILQ_FOREACH(span, spans, entry) {
|
||||
if (span->data.p.wp == wp)
|
||||
redraw_draw_span(dctx, span, cy);
|
||||
}
|
||||
}
|
||||
if (flags & REDRAW_PANE_SCROLLBAR) {
|
||||
spans = &line->spans[REDRAW_SPAN_SCROLLBAR];
|
||||
TAILQ_FOREACH(span, spans, entry) {
|
||||
if (span->data.sb.wp == wp)
|
||||
redraw_draw_span(dctx, span, cy);
|
||||
/* Draw each phase. */
|
||||
for (phase = 0; phase < REDRAW_PHASE_COUNT; phase++) {
|
||||
for (y = top; y < bottom; y++) {
|
||||
line = &scene->lines[y];
|
||||
if (dctx->flags & REDRAW_STATUS_TOP)
|
||||
cy = dctx->status_lines + y;
|
||||
else
|
||||
cy = y;
|
||||
if (flags & REDRAW_PANE) {
|
||||
spans = &line->spans[REDRAW_SPAN_PANE];
|
||||
TAILQ_FOREACH(span, spans, entry) {
|
||||
if (span->data.p.wp != wp)
|
||||
continue;
|
||||
redraw_draw_span(dctx, span, cy, phase);
|
||||
}
|
||||
}
|
||||
if (phase == REDRAW_TEXT &&
|
||||
(flags & REDRAW_PANE_SCROLLBAR)) {
|
||||
spans = &line->spans[REDRAW_SPAN_SCROLLBAR];
|
||||
TAILQ_FOREACH(span, spans, entry) {
|
||||
if (span->data.sb.wp != wp)
|
||||
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. */
|
||||
static void
|
||||
redraw_draw_lines(struct redraw_draw_ctx *dctx, int flags)
|
||||
@@ -1584,52 +1632,24 @@ redraw_draw_lines(struct redraw_draw_ctx *dctx, int flags)
|
||||
struct redraw_line *line;
|
||||
struct redraw_spans *spans;
|
||||
struct redraw_span *span;
|
||||
enum redraw_phase phase;
|
||||
u_int y, cy, type;
|
||||
|
||||
for (y = 0; y < scene->sy; y++) {
|
||||
line = &scene->lines[y];
|
||||
if (dctx->flags & REDRAW_STATUS_TOP)
|
||||
cy = dctx->status_lines + y;
|
||||
else
|
||||
cy = y;
|
||||
for (type = 0; type < REDRAW_SPAN_TYPES; type++) {
|
||||
if (!REDRAW_IS_ALL(flags)) {
|
||||
switch (type) {
|
||||
case REDRAW_SPAN_PANE:
|
||||
if (~flags & REDRAW_PANE)
|
||||
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:
|
||||
/* Draw each phase. */
|
||||
for (phase = 0; phase < REDRAW_PHASE_COUNT; phase++) {
|
||||
for (y = 0; y < scene->sy; y++) {
|
||||
line = &scene->lines[y];
|
||||
if (dctx->flags & REDRAW_STATUS_TOP)
|
||||
cy = dctx->status_lines + y;
|
||||
else
|
||||
cy = y;
|
||||
for (type = 0; type < REDRAW_SPAN_TYPES; type++) {
|
||||
if (!redraw_should_draw(type, flags, phase))
|
||||
continue;
|
||||
}
|
||||
spans = &line->spans[type];
|
||||
TAILQ_FOREACH(span, spans, entry)
|
||||
redraw_draw_span(dctx, span, cy, phase);
|
||||
}
|
||||
spans = &line->spans[type];
|
||||
TAILQ_FOREACH(span, spans, entry)
|
||||
redraw_draw_span(dctx, span, cy);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1650,7 +1670,7 @@ redraw_draw_menu_lines(struct redraw_draw_ctx *dctx)
|
||||
else
|
||||
cy = y;
|
||||
TAILQ_FOREACH(span, &line->spans[REDRAW_SPAN_MENU], entry)
|
||||
redraw_draw_span(dctx, span, cy);
|
||||
redraw_draw_span(dctx, span, cy, REDRAW_TEXT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2052,6 +2072,7 @@ redraw_draw_damage_rectangle(struct redraw_draw_ctx *dctx, u_int x, u_int y,
|
||||
struct redraw_line *line;
|
||||
struct redraw_spans *spans;
|
||||
struct redraw_span *span;
|
||||
enum redraw_phase phase;
|
||||
u_int cy, yy, type;
|
||||
|
||||
if (x >= scene->sx || y >= scene->sy)
|
||||
@@ -2063,29 +2084,55 @@ redraw_draw_damage_rectangle(struct redraw_draw_ctx *dctx, u_int x, u_int y,
|
||||
if (sx == 0 || sy == 0)
|
||||
return;
|
||||
|
||||
/* Draw each phase in the damaged spans. */
|
||||
for (phase = 0; phase < REDRAW_PHASE_COUNT; phase++) {
|
||||
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;
|
||||
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];
|
||||
TAILQ_FOREACH(span, spans, entry) {
|
||||
if (span->x >= x + sx)
|
||||
continue;
|
||||
if (span->x + span->width <= x)
|
||||
continue;
|
||||
redraw_draw_span(dctx, span, cy, phase);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
for (type = 0; type < REDRAW_SPAN_TYPES; type++) {
|
||||
spans = &line->spans[type];
|
||||
TAILQ_FOREACH(span, spans, entry) {
|
||||
if (span->x >= x + sx)
|
||||
continue;
|
||||
if (span->x + span->width <= x)
|
||||
continue;
|
||||
if (type == REDRAW_SPAN_STATUS) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user