From e2100c5f5f9c71185e2a3c410ebdd37f52d701a7 Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 28 Aug 2015 15:51:48 +0000 Subject: We now only checking for name changes when the active pane has changed, but that can only happen when we have already been woken up by a read event, so there is no need for a timer, we can just check the changed flag on the end of that read event (we already loop over the windows to check for bells etc anyway). --- names.c | 32 +++++++------------------------- 1 file changed, 7 insertions(+), 25 deletions(-) (limited to 'names.c') diff --git a/names.c b/names.c index aa0673ea..00bc88a2 100644 --- a/names.c +++ b/names.c @@ -25,37 +25,16 @@ #include "tmux.h" -void window_name_callback(unused int, unused short, void *); - -void -queue_window_name(struct window *w) -{ - struct timeval tv; - - tv.tv_sec = 0; - tv.tv_usec = NAME_INTERVAL * 1000L; - - if (event_initialized(&w->name_timer)) - evtimer_del(&w->name_timer); - evtimer_set(&w->name_timer, window_name_callback, w); - evtimer_add(&w->name_timer, &tv); -} - void -window_name_callback(unused int fd, unused short events, void *data) +check_window_name(struct window *w) { - struct window *w = data; - char *name; + char *name; if (w->active == NULL) return; - if (!options_get_number(&w->options, "automatic-rename")) { - if (event_initialized(&w->name_timer)) - event_del(&w->name_timer); + if (!options_get_number(&w->options, "automatic-rename")) return; - } - queue_window_name(w); if (~w->active->flags & PANE_CHANGED) return; @@ -63,9 +42,12 @@ window_name_callback(unused int fd, unused short events, void *data) name = format_window_name(w); if (strcmp(name, w->name) != 0) { + log_debug("@%u new name %s (was %s)", w->id, name, w->name); window_set_name(w, name); server_status_window(w); - } + } else + log_debug("@%u name not changed (still %s)", w->id, w->name); + free(name); } -- cgit From 55b8d7456155de4e5d44136a140a599e2a2a755b Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 28 Aug 2015 16:10:46 +0000 Subject: Revert previous; we do need a timer, until I have a better idea. We can't do the name check every loop, because that is too expensive, and we can't make sure it only happens infrequently because we have no idea when the next change will happen. --- names.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'names.c') diff --git a/names.c b/names.c index 00bc88a2..aa0673ea 100644 --- a/names.c +++ b/names.c @@ -25,16 +25,37 @@ #include "tmux.h" +void window_name_callback(unused int, unused short, void *); + +void +queue_window_name(struct window *w) +{ + struct timeval tv; + + tv.tv_sec = 0; + tv.tv_usec = NAME_INTERVAL * 1000L; + + if (event_initialized(&w->name_timer)) + evtimer_del(&w->name_timer); + evtimer_set(&w->name_timer, window_name_callback, w); + evtimer_add(&w->name_timer, &tv); +} + void -check_window_name(struct window *w) +window_name_callback(unused int fd, unused short events, void *data) { - char *name; + struct window *w = data; + char *name; if (w->active == NULL) return; - if (!options_get_number(&w->options, "automatic-rename")) + if (!options_get_number(&w->options, "automatic-rename")) { + if (event_initialized(&w->name_timer)) + event_del(&w->name_timer); return; + } + queue_window_name(w); if (~w->active->flags & PANE_CHANGED) return; @@ -42,12 +63,9 @@ check_window_name(struct window *w) name = format_window_name(w); if (strcmp(name, w->name) != 0) { - log_debug("@%u new name %s (was %s)", w->id, name, w->name); window_set_name(w, name); server_status_window(w); - } else - log_debug("@%u name not changed (still %s)", w->id, w->name); - + } free(name); } -- cgit From b7861f34bae7a9e00446e0a8cf2f38e220c41c79 Mon Sep 17 00:00:00 2001 From: nicm Date: Sat, 29 Aug 2015 00:29:15 +0000 Subject: Better take on reducing the name timer. Again check for name changes in the main loop after events that may have changed the pane, but do so at most once every 500 millis. If the pane changed too soon, use a timer to ensure that a check happens later. --- names.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 18 deletions(-) (limited to 'names.c') diff --git a/names.c b/names.c index aa0673ea..e880c577 100644 --- a/names.c +++ b/names.c @@ -25,47 +25,76 @@ #include "tmux.h" -void window_name_callback(unused int, unused short, void *); +void name_time_callback(int, short, void *); +int name_time_expired(struct window *, struct timeval *); void -queue_window_name(struct window *w) +name_time_callback(unused int fd, unused short events, void *arg) { - struct timeval tv; + struct window *w = arg; - tv.tv_sec = 0; - tv.tv_usec = NAME_INTERVAL * 1000L; + /* The event loop will call check_window_name for us on the way out. */ + log_debug("@%u name timer expired", w->id); +} + +int +name_time_expired(struct window *w, struct timeval *tv) +{ + struct timeval offset; - if (event_initialized(&w->name_timer)) - evtimer_del(&w->name_timer); - evtimer_set(&w->name_timer, window_name_callback, w); - evtimer_add(&w->name_timer, &tv); + timersub(tv, &w->name_time, &offset); + if (offset.tv_sec != 0 || offset.tv_usec > NAME_INTERVAL) + return (0); + return (NAME_INTERVAL - offset.tv_usec); } void -window_name_callback(unused int fd, unused short events, void *data) +check_window_name(struct window *w) { - struct window *w = data; + struct timeval tv, next; char *name; + int left; if (w->active == NULL) return; - if (!options_get_number(&w->options, "automatic-rename")) { - if (event_initialized(&w->name_timer)) - event_del(&w->name_timer); + if (!options_get_number(&w->options, "automatic-rename")) return; - } - queue_window_name(w); - if (~w->active->flags & PANE_CHANGED) + if (~w->active->flags & PANE_CHANGED) { + log_debug("@%u active pane not changed", w->id); + return; + } + log_debug("@%u active pane changed", w->id); + + gettimeofday(&tv, NULL); + left = name_time_expired(w, &tv); + if (left != 0) { + if (!event_initialized(&w->name_event)) + evtimer_set(&w->name_event, name_time_callback, w); + if (!evtimer_pending(&w->name_event, NULL)) { + log_debug("@%u name timer queued (%d left)", w->id, left); + timerclear(&next); + next.tv_usec = left; + event_add(&w->name_event, &next); + } else + log_debug("@%u name timer already queued (%d left)", w->id, left); return; + } + memcpy(&w->name_time, &tv, sizeof w->name_time); + if (event_initialized(&w->name_event)) + evtimer_del(&w->name_event); + w->active->flags &= ~PANE_CHANGED; name = format_window_name(w); if (strcmp(name, w->name) != 0) { + log_debug("@%u new name %s (was %s)", w->id, name, w->name); window_set_name(w, name); server_status_window(w); - } + } else + log_debug("@%u name not changed (still %s)", w->id, w->name); + free(name); } -- cgit