From b37399304f9fa310d0790dee8a8325d79cc9af39 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 10 Feb 2009 00:18:06 +0000 Subject: [PATCH] Don't redraw status line unless it has actually changed. Stops extraneous updates between clock/#() changes and doesn't require manual status-interval 0 when no updates are occuring. --- CHANGES | 7 ++++++- grid.c | 26 +++++++++++++++++++++++++- server.c | 12 +++++++----- status.c | 57 ++++++++++++++++++++++++++++++++++++-------------------- tmux.h | 9 +++++---- 5 files changed, 80 insertions(+), 31 deletions(-) diff --git a/CHANGES b/CHANGES index b15d5b37..d4a7d770 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +10 February 2009 + +* No longer redraw the status line every status-interval unless it has actually + changed. + 08 February 2009 * Don't treat empty arguments ("") differently when parsing configuration @@ -1085,7 +1090,7 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.249 2009-02-08 16:38:19 nicm Exp $ +$Id: CHANGES,v 1.250 2009-02-10 00:18:06 nicm Exp $ LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms diff --git a/grid.c b/grid.c index 714721da..4bb17cf6 100644 --- a/grid.c +++ b/grid.c @@ -1,4 +1,4 @@ -/* $Id: grid.c,v 1.7 2009-01-17 18:47:36 nicm Exp $ */ +/* $Id: grid.c,v 1.8 2009-02-10 00:18:06 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -119,6 +119,30 @@ grid_destroy(struct grid_data *gd) xfree(gd); } +/* Compare grids. */ +int +grid_compare(struct grid_data *ga, struct grid_data *gb) +{ + struct grid_cell *gca, *gcb; + u_int xx, yy; + + if (ga->sx != gb->sx || ga->sy != ga->sy) + return (1); + + for (yy = 0; yy < ga->sy; yy++) { + if (ga->size[yy] != gb->size[yy]) + return (1); + for (xx = 0; xx < ga->sx; xx++) { + gca = &ga->data[yy][xx]; + gcb = &gb->data[yy][xx]; + if (memcmp(gca, gcb, sizeof (struct grid_cell)) != 0) + return (1); + } + } + + return (0); +} + /* Scroll a line into the history. */ void grid_scroll_line(struct grid_data *gd) diff --git a/server.c b/server.c index 29aed79f..d7ef46f7 100644 --- a/server.c +++ b/server.c @@ -1,4 +1,4 @@ -/* $Id: server.c,v 1.118 2009-02-08 16:26:43 nicm Exp $ */ +/* $Id: server.c,v 1.119 2009-02-10 00:18:06 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -464,7 +464,7 @@ server_check_redraw(struct client *c) { struct session *s; char title[512]; - int flags; + int flags, redraw; if (c == NULL || c->session == NULL) return; @@ -487,11 +487,13 @@ server_check_redraw(struct client *c) if (c->flags & (CLIENT_REDRAW|CLIENT_STATUS)) { if (c->message_string != NULL) - status_message_redraw(c); + redraw = status_message_redraw(c); else if (c->prompt_string != NULL) - status_prompt_redraw(c); + redraw = status_prompt_redraw(c); else - status_redraw(c); + redraw = status_redraw(c); + if (!redraw) + c->flags &= ~CLIENT_STATUS; } if (c->flags & CLIENT_REDRAW) { diff --git a/status.c b/status.c index 47299388..e8d68cd4 100644 --- a/status.c +++ b/status.c @@ -1,4 +1,4 @@ -/* $Id: status.c,v 1.71 2009-02-01 18:14:49 tcunha Exp $ */ +/* $Id: status.c,v 1.72 2009-02-10 00:18:06 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -38,14 +38,14 @@ void status_prompt_add_history(struct client *); char *status_prompt_complete(const char *); /* Draw status for client on the last lines of given context. */ -void +int status_redraw(struct client *c) { struct screen_write_ctx ctx; struct session *s = c->session; struct winlink *wl; struct window_pane *wp; - struct screen *sc = NULL; + struct screen *sc = NULL, old_status; char *left, *right, *text, *ptr; size_t llen, rlen, offset, xx, yy, sy; size_t size, start, width; @@ -54,11 +54,9 @@ status_redraw(struct client *c) left = right = NULL; - /* Resize the target screen. */ - if (screen_size_x(&c->status) != c->sx) { - screen_free(&c->status); - screen_init(&c->status, c->sx, 1, 0); - } + /* Create the target screen. */ + memcpy(&old_status, &c->status, sizeof old_status); + screen_init(&c->status, c->sx, 1, 0); /* No status line? */ if (c->sy == 0 || !options_get_number(&s->options, "status")) @@ -285,6 +283,13 @@ out: xfree(left); if (right != NULL) xfree(right); + + if (grid_compare(c->status.grid, old_status.grid) == 0) { + screen_free(&old_status); + return (0); + } + screen_free(&old_status); + return (1); } char * @@ -484,20 +489,19 @@ status_print(struct session *s, struct winlink *wl, struct grid_cell *gc) } /* Draw client message on status line of present else on last line. */ -void +int status_message_redraw(struct client *c) { struct screen_write_ctx ctx; struct session *s = c->session; + struct screen old_status; size_t len; struct grid_cell gc; if (c->sx == 0 || c->sy == 0) - return; - if (screen_size_x(&c->status) != c->sx) { - screen_free(&c->status); - screen_init(&c->status, c->sx, 1, 0); - } + return (0); + memcpy(&old_status, &c->status, sizeof old_status); + screen_init(&c->status, c->sx, 1, 0); len = strlen(c->message_string); if (len > c->sx) @@ -516,24 +520,30 @@ status_message_redraw(struct client *c) screen_write_putc(&ctx, &gc, ' '); screen_write_stop(&ctx); + + if (grid_compare(c->status.grid, old_status.grid) == 0) { + screen_free(&old_status); + return (0); + } + screen_free(&old_status); + return (1); } /* Draw client prompt on status line of present else on last line. */ -void +int status_prompt_redraw(struct client *c) { struct screen_write_ctx ctx; struct session *s = c->session; + struct screen old_status; size_t i, size, left, len, offset, n; char ch; struct grid_cell gc; if (c->sx == 0 || c->sy == 0) - return; - if (screen_size_x(&c->status) != c->sx) { - screen_free(&c->status); - screen_init(&c->status, c->sx, 1, 0); - } + return (0); + memcpy(&old_status, &c->status, sizeof old_status); + screen_init(&c->status, c->sx, 1, 0); offset = 0; len = strlen(c->prompt_string); @@ -587,6 +597,13 @@ status_prompt_redraw(struct client *c) screen_write_putc(&ctx, &gc, ch); screen_write_stop(&ctx); + + if (grid_compare(c->status.grid, old_status.grid) == 0) { + screen_free(&old_status); + return (0); + } + screen_free(&old_status); + return (1); } /* Handle keys in prompt. */ diff --git a/tmux.h b/tmux.h index 86ac1da6..23bbbac6 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.262 2009-02-09 18:08:01 nicm Exp $ */ +/* $Id: tmux.h,v 1.263 2009-02-10 00:18:06 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -1296,9 +1296,9 @@ void server_lock(void); int server_unlock(const char *); /* status.c */ -void status_redraw(struct client *); -void status_message_redraw(struct client *); -void status_prompt_redraw(struct client *); +int status_redraw(struct client *); +int status_message_redraw(struct client *); +int status_prompt_redraw(struct client *); void status_prompt_key(struct client *, int); /* resize.c */ @@ -1326,6 +1326,7 @@ int attributes_fromstring(const char *); extern const struct grid_cell grid_default_cell; struct grid_data *grid_create(u_int, u_int, u_int); void grid_destroy(struct grid_data *); +int grid_compare(struct grid_data *, struct grid_data *); void grid_reduce_line(struct grid_data *, u_int, u_int); void grid_expand_line(struct grid_data *, u_int, u_int); void grid_scroll_line(struct grid_data *);