mirror of https://github.com/tmux/tmux.git
Use a pointer for the active screen in the status line instead of
copying them around all the time.
This commit is contained in:
parent
818fda0363
commit
b588b1729a
|
@ -569,7 +569,7 @@ screen_redraw_draw_status(struct screen_redraw_ctx *ctx)
|
||||||
struct client *c = ctx->c;
|
struct client *c = ctx->c;
|
||||||
struct window *w = c->session->curw->window;
|
struct window *w = c->session->curw->window;
|
||||||
struct tty *tty = &c->tty;
|
struct tty *tty = &c->tty;
|
||||||
struct screen *s = &c->status.screen;
|
struct screen *s = c->status.active;
|
||||||
u_int i, y;
|
u_int i, y;
|
||||||
|
|
||||||
log_debug("%s: %s @%u", __func__, c->name, w->id);
|
log_debug("%s: %s @%u", __func__, c->name, w->id);
|
||||||
|
|
131
status.c
131
status.c
|
@ -296,6 +296,32 @@ status_get_window_at(struct client *c, u_int x)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Save old status line. */
|
||||||
|
static void
|
||||||
|
status_push_screen(struct client *c)
|
||||||
|
{
|
||||||
|
struct status_line *sl = &c->status;
|
||||||
|
|
||||||
|
if (sl->active == &sl->screen) {
|
||||||
|
sl->active = xmalloc(sizeof *sl->active);
|
||||||
|
screen_init(sl->active, c->tty.sx, status_line_size(c), 0);
|
||||||
|
}
|
||||||
|
sl->references++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore old status line. */
|
||||||
|
static void
|
||||||
|
status_pop_screen(struct client *c)
|
||||||
|
{
|
||||||
|
struct status_line *sl = &c->status;
|
||||||
|
|
||||||
|
if (--sl->references == 0) {
|
||||||
|
screen_free(sl->active);
|
||||||
|
free(sl->active);
|
||||||
|
sl->active = &sl->screen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize status line. */
|
/* Initialize status line. */
|
||||||
void
|
void
|
||||||
status_init(struct client *c)
|
status_init(struct client *c)
|
||||||
|
@ -303,6 +329,7 @@ status_init(struct client *c)
|
||||||
struct status_line *sl = &c->status;
|
struct status_line *sl = &c->status;
|
||||||
|
|
||||||
screen_init(&sl->screen, c->tty.sx, 1, 0);
|
screen_init(&sl->screen, c->tty.sx, 1, 0);
|
||||||
|
sl->active = &sl->screen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free status line. */
|
/* Free status line. */
|
||||||
|
@ -314,37 +341,11 @@ status_free(struct client *c)
|
||||||
if (event_initialized(&sl->timer))
|
if (event_initialized(&sl->timer))
|
||||||
evtimer_del(&sl->timer);
|
evtimer_del(&sl->timer);
|
||||||
|
|
||||||
|
if (sl->active != &sl->screen) {
|
||||||
|
screen_free(sl->active);
|
||||||
|
free(sl->active);
|
||||||
|
}
|
||||||
screen_free(&sl->screen);
|
screen_free(&sl->screen);
|
||||||
if (sl->old_screen != NULL) {
|
|
||||||
screen_free(sl->old_screen);
|
|
||||||
free(sl->old_screen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Save as old status line. */
|
|
||||||
static void
|
|
||||||
status_save_old(struct client *c)
|
|
||||||
{
|
|
||||||
struct status_line *sl = &c->status;
|
|
||||||
|
|
||||||
if (sl->old_screen == NULL) {
|
|
||||||
sl->old_screen = xmalloc(sizeof *sl->old_screen);
|
|
||||||
memcpy(sl->old_screen, &sl->screen, sizeof *sl->old_screen);
|
|
||||||
screen_init(&c->status.screen, c->tty.sx, 1, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free old status line. */
|
|
||||||
static void
|
|
||||||
status_free_old(struct client *c)
|
|
||||||
{
|
|
||||||
struct status_line *sl = &c->status;
|
|
||||||
|
|
||||||
if (sl->old_screen != NULL) {
|
|
||||||
screen_free(sl->old_screen);
|
|
||||||
free(sl->old_screen);
|
|
||||||
sl->old_screen = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw status line for client. */
|
/* Draw status line for client. */
|
||||||
|
@ -365,8 +366,9 @@ status_redraw(struct client *c)
|
||||||
size_t llen, rlen, seplen;
|
size_t llen, rlen, seplen;
|
||||||
int larrow, rarrow;
|
int larrow, rarrow;
|
||||||
|
|
||||||
/* Delete the saved status line, if any. */
|
/* Shouldn't get here if not the active screen. */
|
||||||
status_free_old(c);
|
if (sl->active != &sl->screen)
|
||||||
|
fatalx("not the active screen");
|
||||||
|
|
||||||
/* No status line? */
|
/* No status line? */
|
||||||
lines = status_line_size(c);
|
lines = status_line_size(c);
|
||||||
|
@ -379,9 +381,9 @@ status_redraw(struct client *c)
|
||||||
style_apply(&stdgc, s->options, "status-style");
|
style_apply(&stdgc, s->options, "status-style");
|
||||||
|
|
||||||
/* Create the target screen. */
|
/* Create the target screen. */
|
||||||
memcpy(&old_screen, &sl->screen, sizeof old_screen);
|
memcpy(&old_screen, sl->active, sizeof old_screen);
|
||||||
screen_init(&sl->screen, c->tty.sx, lines, 0);
|
screen_init(sl->active, c->tty.sx, lines, 0);
|
||||||
screen_write_start(&ctx, NULL, &sl->screen);
|
screen_write_start(&ctx, NULL, sl->active);
|
||||||
for (offset = 0; offset < lines * c->tty.sx; offset++)
|
for (offset = 0; offset < lines * c->tty.sx; offset++)
|
||||||
screen_write_putc(&ctx, &stdgc, ' ');
|
screen_write_putc(&ctx, &stdgc, ' ');
|
||||||
screen_write_stop(&ctx);
|
screen_write_stop(&ctx);
|
||||||
|
@ -504,7 +506,7 @@ status_redraw(struct client *c)
|
||||||
|
|
||||||
draw:
|
draw:
|
||||||
/* Begin drawing. */
|
/* Begin drawing. */
|
||||||
screen_write_start(&ctx, NULL, &sl->screen);
|
screen_write_start(&ctx, NULL, sl->active);
|
||||||
|
|
||||||
/* Draw the left string and arrow. */
|
/* Draw the left string and arrow. */
|
||||||
screen_write_cursormove(&ctx, 0, 0, 0);
|
screen_write_cursormove(&ctx, 0, 0, 0);
|
||||||
|
@ -563,7 +565,7 @@ out:
|
||||||
free(left);
|
free(left);
|
||||||
free(right);
|
free(right);
|
||||||
|
|
||||||
if (grid_compare(sl->screen.grid, old_screen.grid) == 0) {
|
if (grid_compare(sl->active->grid, old_screen.grid) == 0) {
|
||||||
screen_free(&old_screen);
|
screen_free(&old_screen);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -634,7 +636,7 @@ status_message_set(struct client *c, const char *fmt, ...)
|
||||||
int delay;
|
int delay;
|
||||||
|
|
||||||
status_message_clear(c);
|
status_message_clear(c);
|
||||||
status_save_old(c);
|
status_push_screen(c);
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
xvasprintf(&c->message_string, fmt, ap);
|
xvasprintf(&c->message_string, fmt, ap);
|
||||||
|
@ -671,7 +673,7 @@ status_message_clear(struct client *c)
|
||||||
c->tty.flags &= ~(TTY_NOCURSOR|TTY_FREEZE);
|
c->tty.flags &= ~(TTY_NOCURSOR|TTY_FREEZE);
|
||||||
c->flags |= CLIENT_ALLREDRAWFLAGS; /* was frozen and may have changed */
|
c->flags |= CLIENT_ALLREDRAWFLAGS; /* was frozen and may have changed */
|
||||||
|
|
||||||
screen_reinit(&c->status.screen);
|
status_pop_screen(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear status line message after timer expires. */
|
/* Clear status line message after timer expires. */
|
||||||
|
@ -687,23 +689,22 @@ status_message_callback(__unused int fd, __unused short event, void *data)
|
||||||
int
|
int
|
||||||
status_message_redraw(struct client *c)
|
status_message_redraw(struct client *c)
|
||||||
{
|
{
|
||||||
|
struct status_line *sl = &c->status;
|
||||||
struct screen_write_ctx ctx;
|
struct screen_write_ctx ctx;
|
||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
struct screen old_status;
|
struct screen old_screen;
|
||||||
size_t len;
|
size_t len;
|
||||||
struct grid_cell gc;
|
|
||||||
u_int lines, offset;
|
u_int lines, offset;
|
||||||
|
struct grid_cell gc;
|
||||||
|
|
||||||
if (c->tty.sx == 0 || c->tty.sy == 0)
|
if (c->tty.sx == 0 || c->tty.sy == 0)
|
||||||
return (0);
|
return (0);
|
||||||
memcpy(&old_status, &c->status.screen, sizeof old_status);
|
memcpy(&old_screen, sl->active, sizeof old_screen);
|
||||||
|
|
||||||
lines = status_line_size(c);
|
lines = status_line_size(c);
|
||||||
if (lines <= 1) {
|
if (lines <= 1)
|
||||||
lines = 1;
|
lines = 1;
|
||||||
screen_init(&c->status.screen, c->tty.sx, 1, 0);
|
screen_init(sl->active, c->tty.sx, 1, 0);
|
||||||
} else
|
|
||||||
screen_init(&c->status.screen, c->tty.sx, lines, 0);
|
|
||||||
|
|
||||||
len = screen_write_strlen("%s", c->message_string);
|
len = screen_write_strlen("%s", c->message_string);
|
||||||
if (len > c->tty.sx)
|
if (len > c->tty.sx)
|
||||||
|
@ -711,7 +712,7 @@ status_message_redraw(struct client *c)
|
||||||
|
|
||||||
style_apply(&gc, s->options, "message-style");
|
style_apply(&gc, s->options, "message-style");
|
||||||
|
|
||||||
screen_write_start(&ctx, NULL, &c->status.screen);
|
screen_write_start(&ctx, NULL, sl->active);
|
||||||
screen_write_cursormove(&ctx, 0, 0, 0);
|
screen_write_cursormove(&ctx, 0, 0, 0);
|
||||||
for (offset = 0; offset < lines * c->tty.sx; offset++)
|
for (offset = 0; offset < lines * c->tty.sx; offset++)
|
||||||
screen_write_putc(&ctx, &gc, ' ');
|
screen_write_putc(&ctx, &gc, ' ');
|
||||||
|
@ -719,11 +720,11 @@ status_message_redraw(struct client *c)
|
||||||
screen_write_nputs(&ctx, len, &gc, "%s", c->message_string);
|
screen_write_nputs(&ctx, len, &gc, "%s", c->message_string);
|
||||||
screen_write_stop(&ctx);
|
screen_write_stop(&ctx);
|
||||||
|
|
||||||
if (grid_compare(c->status.screen.grid, old_status.grid) == 0) {
|
if (grid_compare(sl->active->grid, old_screen.grid) == 0) {
|
||||||
screen_free(&old_status);
|
screen_free(&old_screen);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
screen_free(&old_status);
|
screen_free(&old_screen);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,7 +748,7 @@ status_prompt_set(struct client *c, const char *msg, const char *input,
|
||||||
|
|
||||||
status_message_clear(c);
|
status_message_clear(c);
|
||||||
status_prompt_clear(c);
|
status_prompt_clear(c);
|
||||||
status_save_old(c);
|
status_push_screen(c);
|
||||||
|
|
||||||
c->prompt_string = format_expand_time(ft, msg);
|
c->prompt_string = format_expand_time(ft, msg);
|
||||||
|
|
||||||
|
@ -799,7 +800,7 @@ status_prompt_clear(struct client *c)
|
||||||
c->tty.flags &= ~(TTY_NOCURSOR|TTY_FREEZE);
|
c->tty.flags &= ~(TTY_NOCURSOR|TTY_FREEZE);
|
||||||
c->flags |= CLIENT_ALLREDRAWFLAGS; /* was frozen and may have changed */
|
c->flags |= CLIENT_ALLREDRAWFLAGS; /* was frozen and may have changed */
|
||||||
|
|
||||||
screen_reinit(&c->status.screen);
|
status_pop_screen(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update status line prompt with a new prompt string. */
|
/* Update status line prompt with a new prompt string. */
|
||||||
|
@ -833,23 +834,22 @@ status_prompt_update(struct client *c, const char *msg, const char *input)
|
||||||
int
|
int
|
||||||
status_prompt_redraw(struct client *c)
|
status_prompt_redraw(struct client *c)
|
||||||
{
|
{
|
||||||
|
struct status_line *sl = &c->status;
|
||||||
struct screen_write_ctx ctx;
|
struct screen_write_ctx ctx;
|
||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
struct screen old_status;
|
struct screen old_screen;
|
||||||
u_int i, offset, left, start, pcursor, pwidth, width;
|
u_int i, lines, offset, left, start, width;
|
||||||
u_int lines;
|
u_int pcursor, pwidth;
|
||||||
struct grid_cell gc, cursorgc;
|
struct grid_cell gc, cursorgc;
|
||||||
|
|
||||||
if (c->tty.sx == 0 || c->tty.sy == 0)
|
if (c->tty.sx == 0 || c->tty.sy == 0)
|
||||||
return (0);
|
return (0);
|
||||||
memcpy(&old_status, &c->status.screen, sizeof old_status);
|
memcpy(&old_screen, sl->active, sizeof old_screen);
|
||||||
|
|
||||||
lines = status_line_size(c);
|
lines = status_line_size(c);
|
||||||
if (lines <= 1) {
|
if (lines <= 1)
|
||||||
lines = 1;
|
lines = 1;
|
||||||
screen_init(&c->status.screen, c->tty.sx, 1, 0);
|
screen_init(sl->active, c->tty.sx, lines, 0);
|
||||||
} else
|
|
||||||
screen_init(&c->status.screen, c->tty.sx, lines, 0);
|
|
||||||
|
|
||||||
if (c->prompt_mode == PROMPT_COMMAND)
|
if (c->prompt_mode == PROMPT_COMMAND)
|
||||||
style_apply(&gc, s->options, "message-command-style");
|
style_apply(&gc, s->options, "message-command-style");
|
||||||
|
@ -863,7 +863,7 @@ status_prompt_redraw(struct client *c)
|
||||||
if (start > c->tty.sx)
|
if (start > c->tty.sx)
|
||||||
start = c->tty.sx;
|
start = c->tty.sx;
|
||||||
|
|
||||||
screen_write_start(&ctx, NULL, &c->status.screen);
|
screen_write_start(&ctx, NULL, sl->active);
|
||||||
screen_write_cursormove(&ctx, 0, 0, 0);
|
screen_write_cursormove(&ctx, 0, 0, 0);
|
||||||
for (offset = 0; offset < lines * c->tty.sx; offset++)
|
for (offset = 0; offset < lines * c->tty.sx; offset++)
|
||||||
screen_write_putc(&ctx, &gc, ' ');
|
screen_write_putc(&ctx, &gc, ' ');
|
||||||
|
@ -909,18 +909,17 @@ status_prompt_redraw(struct client *c)
|
||||||
screen_write_cell(&ctx, &cursorgc);
|
screen_write_cell(&ctx, &cursorgc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (c->status.screen.cx < screen_size_x(&c->status.screen) &&
|
if (sl->active->cx < screen_size_x(sl->active) && c->prompt_index >= i)
|
||||||
c->prompt_index >= i)
|
|
||||||
screen_write_putc(&ctx, &cursorgc, ' ');
|
screen_write_putc(&ctx, &cursorgc, ' ');
|
||||||
|
|
||||||
finished:
|
finished:
|
||||||
screen_write_stop(&ctx);
|
screen_write_stop(&ctx);
|
||||||
|
|
||||||
if (grid_compare(c->status.screen.grid, old_status.grid) == 0) {
|
if (grid_compare(sl->active->grid, old_screen.grid) == 0) {
|
||||||
screen_free(&old_status);
|
screen_free(&old_screen);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
screen_free(&old_status);
|
screen_free(&old_screen);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
3
tmux.h
3
tmux.h
|
@ -1315,7 +1315,8 @@ struct status_line {
|
||||||
struct event timer;
|
struct event timer;
|
||||||
|
|
||||||
struct screen screen;
|
struct screen screen;
|
||||||
struct screen *old_screen;
|
struct screen *active;
|
||||||
|
int references;
|
||||||
|
|
||||||
int window_list_offset;
|
int window_list_offset;
|
||||||
|
|
||||||
|
|
|
@ -229,9 +229,6 @@ window_client_draw(__unused void *modedata, void *itemdata,
|
||||||
screen_write_hline(ctx, sx, 0, 0);
|
screen_write_hline(ctx, sx, 0, 0);
|
||||||
|
|
||||||
screen_write_cursormove(ctx, cx, cy + sy - 1, 0);
|
screen_write_cursormove(ctx, cx, cy + sy - 1, 0);
|
||||||
if (c->status.old_screen != NULL)
|
|
||||||
screen_write_fast_copy(ctx, c->status.old_screen, 0, 0, sx, 1);
|
|
||||||
else
|
|
||||||
screen_write_fast_copy(ctx, &c->status.screen, 0, 0, sx, 1);
|
screen_write_fast_copy(ctx, &c->status.screen, 0, 0, sx, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue