diff options
author | Timo Sirainen <cras@irssi.org> | 2001-10-28 18:40:12 +0000 |
---|---|---|
committer | cras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564> | 2001-10-28 18:40:12 +0000 |
commit | fb439b5c2ae93e0d42a59cf8900a17cbb72214f6 (patch) | |
tree | 604d6da2c3a9dcbbf33c72245043d7b8b6863fa0 /src/fe-text/statusbar.c | |
parent | 44b12481d66c68e00f5dade2a0fc815497b1535c (diff) | |
download | irssi-fb439b5c2ae93e0d42a59cf8900a17cbb72214f6.zip |
Redrawing fixes - irssi should now rarely redraw stuff uselessly in screen.
Most of the code now just marks the window/statusbar/etc. as dirty, and lets
the dirty-checker handle it later.
git-svn-id: http://svn.irssi.org/repos/irssi/trunk@1926 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'src/fe-text/statusbar.c')
-rw-r--r-- | src/fe-text/statusbar.c | 142 |
1 files changed, 107 insertions, 35 deletions
diff --git a/src/fe-text/statusbar.c b/src/fe-text/statusbar.c index 0ed75fed..5ca83f70 100644 --- a/src/fe-text/statusbar.c +++ b/src/fe-text/statusbar.c @@ -225,7 +225,12 @@ static void statusbar_resize_items(STATUSBAR_REC *bar, int max_width) g_slist_free(prior_sorted); } -static void statusbar_redraw_items(STATUSBAR_REC *bar) +#define SBAR_ITEM_REDRAW_NEEDED(_bar, _item, _xpos) \ + (((_bar)->dirty_xpos != -1 && \ + (_xpos) >= (_bar)->dirty_xpos) || \ + (_item)->xpos != (_xpos) || (_item)->current_size != (_item)->size) + +static void statusbar_calc_item_positions(STATUSBAR_REC *bar) { WINDOW_REC *old_active_win; GSList *tmp; @@ -237,25 +242,46 @@ static void statusbar_redraw_items(STATUSBAR_REC *bar) statusbar_resize_items(bar, term_width); + /* left-aligned items */ xpos = 0; for (tmp = bar->items; tmp != NULL; tmp = tmp->next) { SBAR_ITEM_REC *rec = tmp->data; if (!rec->config->right_alignment && rec->size > 0) { - rec->xpos = xpos; - xpos += rec->size; - rec->func(rec, FALSE); + if (SBAR_ITEM_REDRAW_NEEDED(bar, rec, xpos)) { + /* redraw the item */ + rec->dirty = TRUE; + if (bar->dirty_xpos == -1 || + xpos < bar->dirty_xpos) { + irssi_set_dirty(); + bar->dirty = TRUE; + bar->dirty_xpos = xpos; + } + + rec->xpos = xpos; + } + xpos += rec->size; } } + /* right-aligned items */ rxpos = term_width; for (tmp = bar->items; tmp != NULL; tmp = tmp->next) { SBAR_ITEM_REC *rec = tmp->data; if (rec->config->right_alignment && rec->size > 0) { - rxpos -= rec->size; - rec->xpos = rxpos; - rec->func(rec, FALSE); + if (SBAR_ITEM_REDRAW_NEEDED(bar, rec, xpos)) { + rec->dirty = TRUE; + if (bar->dirty_xpos == -1 || + xpos < bar->dirty_xpos) { + irssi_set_dirty(); + bar->dirty = TRUE; + bar->dirty_xpos = xpos; + } + rec->xpos = rxpos; + } + + rxpos -= rec->size; } } @@ -276,26 +302,20 @@ static void statusbar_redraw_items(STATUSBAR_REC *bar) return NULL; }*/ -void statusbar_redraw(STATUSBAR_REC *bar) +void statusbar_redraw(STATUSBAR_REC *bar, int force) { - char *str; - - if (bar == NULL) { - if (active_statusbar_group != NULL) { - term_refresh_freeze(); - g_slist_foreach(active_statusbar_group->bars, - (GFunc) statusbar_redraw, NULL); - term_refresh_thaw(); + if (bar != NULL) { + if (force) { + irssi_set_dirty(); + bar->dirty = TRUE; + bar->dirty_xpos = 0; } - return; + statusbar_calc_item_positions(bar); + } else if (active_statusbar_group != NULL) { + g_slist_foreach(active_statusbar_group->bars, + (GFunc) statusbar_redraw, + GINT_TO_POINTER(force)); } - - str = g_strconcat(bar->color, "%>", NULL); - gui_printtext(0, bar->real_ypos, str); - g_free(str); - - statusbar_redraw_items(bar); - term_refresh(NULL); } void statusbar_item_redraw(SBAR_ITEM_REC *item) @@ -309,15 +329,15 @@ void statusbar_item_redraw(SBAR_ITEM_REC *item) active_win = item->bar->parent_window->active; item->func(item, TRUE); + + item->dirty = TRUE; + item->bar->dirty = TRUE; + irssi_set_dirty(); + if (item->max_size != item->size) { /* item wants a new size - we'll need to redraw the statusbar to see if this is allowed */ - /*FIXME:fprintf(stderr, "%s resizes & redraws whole statusbar", item->config->name);*/ - statusbar_redraw(item->bar); - } else { - /*FIXME:fprintf(stderr, "%s redrawing", item->config->name);*/ - item->func(item, FALSE); - term_refresh(NULL); + statusbar_redraw(item->bar, FALSE); } active_win = old_active_win; @@ -374,7 +394,7 @@ static void statusbars_recalc_ypos(STATUSBAR_REC *bar) if (bar->real_ypos != ypos) { bar->real_ypos = ypos; - statusbar_redraw(bar); + statusbar_redraw(bar, TRUE); } ypos++; @@ -439,6 +459,10 @@ STATUSBAR_REC *statusbar_create(STATUSBAR_GROUP_REC *group, bar->config = config; bar->parent_window = parent_window; + irssi_set_dirty(); + bar->dirty = TRUE; + bar->dirty_xpos = 0; + signal_remove("terminal resized", (SIGNAL_FUNC) sig_terminal_resized); signal_remove("mainwindow resized", (SIGNAL_FUNC) sig_mainwindow_resized); signal_remove("mainwindow moved", (SIGNAL_FUNC) sig_mainwindow_resized); @@ -554,7 +578,7 @@ void statusbar_recreate_items(STATUSBAR_REC *bar) statusbar_item_create(bar, rec); } - statusbar_redraw(bar); + statusbar_redraw(bar, TRUE); } void statusbars_recreate_items(void) @@ -835,6 +859,10 @@ SBAR_ITEM_REC *statusbar_item_create(STATUSBAR_REC *bar, items = g_slist_append(items, rec); g_hash_table_insert(named_sbar_items, config->name, items); + irssi_set_dirty(); + rec->dirty = TRUE; + bar->dirty = TRUE; + signal_emit("statusbar item created", 1, rec); return rec; } @@ -893,6 +921,52 @@ void statusbar_item_destroy(SBAR_ITEM_REC *item) g_free(item); } +static void statusbar_redraw_needed_items(STATUSBAR_REC *bar) +{ + WINDOW_REC *old_active_win; + GSList *tmp; + char *str; + + old_active_win = active_win; + if (bar->parent_window != NULL) + active_win = bar->parent_window->active; + + if (bar->dirty_xpos >= 0) { + str = g_strconcat(bar->color, "%>", NULL); + gui_printtext(bar->dirty_xpos, bar->real_ypos, str); + g_free(str); + } + + for (tmp = bar->items; tmp != NULL; tmp = tmp->next) { + SBAR_ITEM_REC *rec = tmp->data; + + if (rec->dirty || + (bar->dirty_xpos != -1 && + rec->xpos >= bar->dirty_xpos)) { + rec->current_size = rec->size; + rec->func(rec, FALSE); + rec->dirty = FALSE; + } + } + + active_win = old_active_win; +} + +void statusbar_redraw_dirty(void) +{ + GSList *tmp; + + for (tmp = active_statusbar_group->bars; tmp != NULL; tmp = tmp->next) { + STATUSBAR_REC *rec = tmp->data; + + if (rec->dirty) { + statusbar_redraw_needed_items(rec); + rec->dirty = FALSE; + rec->dirty_xpos = -1; + } + } +} + #define STATUSBAR_IS_VISIBLE(bar, window) \ ((bar)->visible == STATUSBAR_VISIBLE_ALWAYS || \ (active_mainwin == (window) && \ @@ -927,7 +1001,7 @@ static void statusbars_add_visible(MAIN_WINDOW_REC *window) STATUSBAR_IS_VISIBLE(config, window) && statusbar_find(group, config->name, window) == NULL) { bar = statusbar_create(group, config, window); - statusbar_redraw(bar); + statusbar_redraw(bar, TRUE); } } } @@ -951,10 +1025,8 @@ static void sig_window_changed(void) for (tmp = mainwindows; tmp != NULL; tmp = tmp->next) { MAIN_WINDOW_REC *rec = tmp->data; - mainwindow_resize_freeze(rec); statusbars_remove_unvisible(rec); statusbars_add_visible(rec); - mainwindow_resize_thaw(rec); } } |