summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd-attach-session.c2
-rw-r--r--cmd-new-session.c1
-rw-r--r--cmd-set-option.c5
-rw-r--r--cmd-switch-client.c1
-rw-r--r--format.c19
-rw-r--r--log.c4
-rw-r--r--options-table.c5
-rw-r--r--server-client.c38
-rw-r--r--server-fn.c1
-rw-r--r--server.c40
-rw-r--r--status.c56
-rw-r--r--tmux.117
-rw-r--r--tmux.h6
-rw-r--r--window-choose.c1
-rw-r--r--window-clock.c50
-rw-r--r--window-copy.c1
16 files changed, 118 insertions, 129 deletions
diff --git a/cmd-attach-session.c b/cmd-attach-session.c
index e7cde0f0..9f357d6e 100644
--- a/cmd-attach-session.c
+++ b/cmd-attach-session.c
@@ -133,6 +133,7 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
}
c->session = s;
+ status_timer_start(c);
notify_attached_session_changed(c);
session_update_activity(s);
server_redraw_client(c);
@@ -177,6 +178,7 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
}
c->session = s;
+ status_timer_start(c);
notify_attached_session_changed(c);
session_update_activity(s);
server_redraw_client(c);
diff --git a/cmd-new-session.c b/cmd-new-session.c
index 1533e5f0..2125ee88 100644
--- a/cmd-new-session.c
+++ b/cmd-new-session.c
@@ -275,6 +275,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
else if (c->session != NULL)
c->last_session = c->session;
c->session = s;
+ status_timer_start(c);
notify_attached_session_changed(c);
session_update_activity(s);
server_redraw_client(c);
diff --git a/cmd-set-option.c b/cmd-set-option.c
index 761cee93..260961cb 100644
--- a/cmd-set-option.c
+++ b/cmd-set-option.c
@@ -176,7 +176,7 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_ERROR);
}
- /* Start or stop timers when automatic-rename changed. */
+ /* Start or stop timers when name or status options changed. */
if (strcmp(oe->name, "automatic-rename") == 0) {
RB_FOREACH(w, windows, &windows) {
if (options_get_number(&w->options, "automatic-rename"))
@@ -185,6 +185,9 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
evtimer_del(&w->name_timer);
}
}
+ if (strcmp(oe->name, "status") == 0 ||
+ strcmp(oe->name, "status-interval") == 0)
+ status_timer_start_all();
/* Update sizes and redraw. May not need it but meh. */
recalculate_sizes();
diff --git a/cmd-switch-client.c b/cmd-switch-client.c
index 4bac540d..6a79c7b7 100644
--- a/cmd-switch-client.c
+++ b/cmd-switch-client.c
@@ -127,6 +127,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
if (c->session != NULL)
c->last_session = c->session;
c->session = s;
+ status_timer_start(c);
session_update_activity(s);
recalculate_sizes();
diff --git a/format.c b/format.c
index 56292556..9cacbd98 100644
--- a/format.c
+++ b/format.c
@@ -38,6 +38,7 @@
void format_job_callback(struct job *);
const char *format_job_get(struct format_tree *, const char *);
+void format_job_timer(int, short, void *);
int format_replace(struct format_tree *, const char *, size_t, char **,
size_t *, size_t *);
@@ -64,6 +65,7 @@ struct format_job {
};
/* Format job tree. */
+struct event format_job_event;
int format_job_cmp(struct format_job *, struct format_job *);
RB_HEAD(format_job_tree, format_job) format_jobs = RB_INITIALIZER();
RB_PROTOTYPE(format_job_tree, format_job, entry, format_job_cmp);
@@ -192,6 +194,8 @@ format_job_callback(struct job *job)
server_status_client(c);
fj->status = 0;
}
+
+ log_debug("%s: %s: %s", __func__, fj->cmd, fj->out);
}
/* Find a job. */
@@ -227,10 +231,11 @@ format_job_get(struct format_tree *ft, const char *cmd)
/* Remove old jobs. */
void
-format_clean(void)
+format_job_timer(unused int fd, unused short events, unused void *arg)
{
struct format_job *fj, *fj1;
time_t now;
+ struct timeval tv = { .tv_sec = 60 };
now = time(NULL);
RB_FOREACH_SAFE(fj, format_job_tree, &format_jobs, fj1) {
@@ -238,14 +243,19 @@ format_clean(void)
continue;
RB_REMOVE(format_job_tree, &format_jobs, fj);
+ log_debug("%s: %s", __func__, fj->cmd);
+
if (fj->job != NULL)
job_free(fj->job);
- free((void*)fj->cmd);
+ free((void *)fj->cmd);
free(fj->out);
free(fj);
}
+
+ evtimer_del(&format_job_event);
+ evtimer_add(&format_job_event, &tv);
}
/* Create a new tree. */
@@ -262,6 +272,11 @@ format_create_status(int status)
struct format_tree *ft;
char host[HOST_NAME_MAX + 1], *ptr;
+ if (!event_initialized(&format_job_event)) {
+ evtimer_set(&format_job_event, format_job_timer, NULL);
+ format_job_timer(-1, 0, NULL);
+ }
+
ft = xcalloc(1, sizeof *ft);
RB_INIT(&ft->tree);
ft->status = status;
diff --git a/log.c b/log.c
index 066165e8..9afeb2ae 100644
--- a/log.c
+++ b/log.c
@@ -68,11 +68,13 @@ void
log_vwrite(const char *msg, va_list ap)
{
char *fmt;
+ time_t t;
if (log_file == NULL)
return;
- if (asprintf(&fmt, "%s\n", msg) == -1)
+ t = time(NULL);
+ if (asprintf(&fmt, "%lld %s\n", (long long)t, msg) == -1)
exit(1);
if (vfprintf(log_file, fmt, ap) == -1)
exit(1);
diff --git a/options-table.c b/options-table.c
index 1c9ccd95..c99937d3 100644
--- a/options-table.c
+++ b/options-table.c
@@ -205,11 +205,6 @@ const struct options_table_entry session_options_table[] = {
.default_str = "lock -np"
},
- { .name = "lock-server",
- .type = OPTIONS_TABLE_FLAG,
- .default_num = 1
- },
-
{ .name = "message-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = 0,
diff --git a/server-client.c b/server-client.c
index ad66a3fe..fab1c1a0 100644
--- a/server-client.c
+++ b/server-client.c
@@ -187,6 +187,8 @@ server_client_lost(struct client *c)
if (c->stderr_data != c->stdout_data)
evbuffer_free(c->stderr_data);
+ if (event_initialized(&c->status_timer))
+ evtimer_del(&c->status_timer);
screen_free(&c->status);
free(c->title);
@@ -288,42 +290,6 @@ client_lost:
server_client_lost(c);
}
-/* Handle client status timer. */
-void
-server_client_status_timer(void)
-{
- struct client *c;
- struct session *s;
- struct timeval tv;
- int interval;
- time_t difference;
-
- if (gettimeofday(&tv, NULL) != 0)
- fatal("gettimeofday failed");
-
- TAILQ_FOREACH(c, &clients, entry) {
- if (c->session == NULL)
- continue;
- if (c->message_string != NULL || c->prompt_string != NULL) {
- /*
- * Don't need timed redraw for messages/prompts so bail
- * now. The status timer isn't reset when they are
- * redrawn anyway.
- */
- continue;
- }
- s = c->session;
-
- if (!options_get_number(&s->options, "status"))
- continue;
- interval = options_get_number(&s->options, "status-interval");
-
- difference = tv.tv_sec - c->status_timer.tv_sec;
- if (interval != 0 && difference >= interval)
- c->flags |= CLIENT_STATUS;
- }
-}
-
/* Check for mouse keys. */
int
server_client_check_mouse(struct client *c)
diff --git a/server-fn.c b/server-fn.c
index 668ef5c4..b7ff9443 100644
--- a/server-fn.c
+++ b/server-fn.c
@@ -422,6 +422,7 @@ server_destroy_session(struct session *s)
} else {
c->last_session = NULL;
c->session = s_new;
+ status_timer_start(c);
notify_attached_session_changed(c);
session_update_activity(s_new);
server_redraw_client(c);
diff --git a/server.c b/server.c
index ad69631d..3916cd7a 100644
--- a/server.c
+++ b/server.c
@@ -63,7 +63,6 @@ void server_child_signal(void);
void server_child_exited(pid_t, int);
void server_child_stopped(pid_t, int);
void server_second_callback(int, short, void *);
-void server_lock_server(void);
void server_lock_sessions(void);
/* Set marked pane. */
@@ -505,25 +504,9 @@ server_child_stopped(pid_t pid, int status)
void
server_second_callback(unused int fd, unused short events, unused void *arg)
{
- struct window *w;
- struct window_pane *wp;
struct timeval tv;
- if (options_get_number(&global_s_options, "lock-server"))
- server_lock_server();
- else
- server_lock_sessions();
-
- RB_FOREACH(w, windows, &windows) {
- TAILQ_FOREACH(wp, &w->panes, entry) {
- if (wp->mode != NULL && wp->mode->timer != NULL)
- wp->mode->timer(wp);
- }
- }
-
- server_client_status_timer();
-
- format_clean();
+ server_lock_sessions();
evtimer_del(&server_ev_second);
memset(&tv, 0, sizeof tv);
@@ -531,27 +514,6 @@ server_second_callback(unused int fd, unused short events, unused void *arg)
evtimer_add(&server_ev_second, &tv);
}
-/* Lock the server if ALL sessions have hit the time limit. */
-void
-server_lock_server(void)
-{
- struct session *s;
- int timeout;
- time_t t;
-
- t = time(NULL);
- RB_FOREACH(s, sessions, &sessions) {
- if (s->flags & SESSION_UNATTACHED)
- continue;
- timeout = options_get_number(&s->options, "lock-after-time");
- if (timeout <= 0 || t <= s->activity_time.tv_sec + timeout)
- return; /* not timed out */
- }
-
- server_lock();
- recalculate_sizes();
-}
-
/* Lock any sessions which have timed out. */
void
server_lock_sessions(void)
diff --git a/status.c b/status.c
index d9501f02..93cee2b1 100644
--- a/status.c
+++ b/status.c
@@ -37,6 +37,7 @@ char *status_print(struct client *, struct winlink *, time_t,
struct grid_cell *);
char *status_replace(struct client *, struct winlink *, const char *, time_t);
void status_message_callback(int, short, void *);
+void status_timer_callback(int, short, void *);
const char *status_prompt_up_history(u_int *);
const char *status_prompt_down_history(u_int *);
@@ -142,6 +143,55 @@ status_prompt_save_history(void)
}
+/* Status timer callback. */
+void
+status_timer_callback(unused int fd, unused short events, void *arg)
+{
+ struct client *c = arg;
+ struct session *s = c->session;
+ struct timeval tv;
+
+ evtimer_del(&c->status_timer);
+
+ if (s == NULL)
+ return;
+
+ if (c->message_string == NULL && c->prompt_string == NULL)
+ c->flags |= CLIENT_STATUS;
+
+ timerclear(&tv);
+ tv.tv_sec = options_get_number(&s->options, "status-interval");
+
+ if (tv.tv_sec != 0)
+ evtimer_add(&c->status_timer, &tv);
+ log_debug("client %d, status interval %d", c->ibuf.fd, (int)tv.tv_sec);
+}
+
+/* Start status timer for client. */
+void
+status_timer_start(struct client *c)
+{
+ struct session *s = c->session;
+
+ if (event_initialized(&c->status_timer))
+ evtimer_del(&c->status_timer);
+ else
+ evtimer_set(&c->status_timer, status_timer_callback, c);
+
+ if (s != NULL && options_get_number(&s->options, "status"))
+ status_timer_callback(-1, 0, c);
+}
+
+/* Start status timer for all clients. */
+void
+status_timer_start_all(void)
+{
+ struct client *c;
+
+ TAILQ_FOREACH(c, &clients, entry)
+ status_timer_start(c);
+}
+
/* Get screen line of status line. -1 means off. */
int
status_at_line(struct client *c)
@@ -244,10 +294,8 @@ status_redraw(struct client *c)
left = right = NULL;
larrow = rarrow = 0;
- /* Update status timer. */
- if (gettimeofday(&c->status_timer, NULL) != 0)
- fatal("gettimeofday failed");
- t = c->status_timer.tv_sec;
+ /* Store current time. */
+ t = time(NULL);
/* Set up default colour. */
style_apply(&stdgc, &s->options, "status-style");
diff --git a/tmux.1 b/tmux.1
index 2001a2f1..681c9367 100644
--- a/tmux.1
+++ b/tmux.1
@@ -2565,9 +2565,7 @@ Lock the session (like the
.Ic lock-session
command) after
.Ar number
-seconds of inactivity, or the entire server (all sessions) if the
-.Ic lock-server
-option is set.
+seconds of inactivity.
The default is not to lock (set to 0).
.It Ic lock-command Ar shell-command
Command to run when locking each client.
@@ -2575,19 +2573,6 @@ The default is to run
.Xr lock 1
with
.Fl np .
-.It Xo Ic lock-server
-.Op Ic on | off
-.Xc
-If this option is
-.Ic on
-(the default),
-instead of each session locking individually as each has been
-idle for
-.Ic lock-after-time ,
-the entire server will lock after
-.Em all
-sessions would have locked.
-This has no effect as a session option; it must be set as a global option.
.It Ic message-command-style Ar style
Set status line message command style, where
.Ar style
diff --git a/tmux.h b/tmux.h
index 44997311..3d77d9a0 100644
--- a/tmux.h
+++ b/tmux.h
@@ -781,7 +781,6 @@ struct window_mode {
void (*resize)(struct window_pane *, u_int, u_int);
void (*key)(struct window_pane *, struct client *, struct session *,
int, struct mouse_event *);
- void (*timer)(struct window_pane *);
};
/* Structures for choose mode. */
@@ -1211,7 +1210,7 @@ struct client {
struct event repeat_timer;
- struct timeval status_timer;
+ struct event status_timer;
struct screen status;
#define CLIENT_TERMINAL 0x1
@@ -1453,7 +1452,6 @@ void cfg_show_causes(struct session *);
/* format.c */
struct format_tree;
-void format_clean(void);
struct format_tree *format_create(void);
struct format_tree *format_create_status(int);
void format_free(struct format_tree *);
@@ -1898,6 +1896,8 @@ int server_set_stdin_callback(struct client *, void (*)(struct client *,
void server_unzoom_window(struct window *);
/* status.c */
+void status_timer_start(struct client *);
+void status_timer_start_all(void);
int status_at_line(struct client *);
struct window *status_get_window_at(struct client *, u_int);
int status_redraw(struct client *);
diff --git a/window-choose.c b/window-choose.c
index c71fea3d..37baf0d7 100644
--- a/window-choose.c
+++ b/window-choose.c
@@ -57,7 +57,6 @@ const struct window_mode window_choose_mode = {
window_choose_free,
window_choose_resize,
window_choose_key,
- NULL,
};
struct window_choose_mode_item {
diff --git a/window-clock.c b/window-clock.c
index 3cabd9e9..4a497891 100644
--- a/window-clock.c
+++ b/window-clock.c
@@ -29,8 +29,8 @@ void window_clock_free(struct window_pane *);
void window_clock_resize(struct window_pane *, u_int, u_int);
void window_clock_key(struct window_pane *, struct client *,
struct session *, int, struct mouse_event *);
-void window_clock_timer(struct window_pane *);
+void window_clock_timer_callback(int, short, void *);
void window_clock_draw_screen(struct window_pane *);
const struct window_mode window_clock_mode = {
@@ -38,12 +38,12 @@ const struct window_mode window_clock_mode = {
window_clock_free,
window_clock_resize,
window_clock_key,
- window_clock_timer,
};
struct window_clock_mode_data {
struct screen screen;
time_t tim;
+ struct event timer;
};
const char window_clock_table[14][5][5] = {
@@ -119,15 +119,42 @@ const char window_clock_table[14][5][5] = {
{ 1,0,0,0,1 } },
};
+void
+window_clock_timer_callback(unused int fd, unused short events, void *arg)
+{
+ struct window_pane *wp = arg;
+ struct window_clock_mode_data *data = wp->modedata;
+ struct tm now, then;
+ time_t t;
+ struct timeval tv = { .tv_sec = 1 };
+
+ evtimer_del(&data->timer);
+ evtimer_add(&data->timer, &tv);
+
+ t = time(NULL);
+ gmtime_r(&t, &now);
+ gmtime_r(&data->tim, &then);
+ if (now.tm_min == then.tm_min)
+ return;
+ data->tim = t;
+
+ window_clock_draw_screen(wp);
+ server_redraw_window(wp->window);
+}
+
struct screen *
window_clock_init(struct window_pane *wp)
{
struct window_clock_mode_data *data;
struct screen *s;
+ struct timeval tv = { .tv_sec = 1 };
wp->modedata = data = xmalloc(sizeof *data);
data->tim = time(NULL);
+ evtimer_set(&data->timer, window_clock_timer_callback, wp);
+ evtimer_add(&data->timer, &tv);
+
s = &data->screen;
screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
s->mode &= ~MODE_CURSOR;
@@ -142,6 +169,7 @@ window_clock_free(struct window_pane *wp)
{
struct window_clock_mode_data *data = wp->modedata;
+ evtimer_del(&data->timer);
screen_free(&data->screen);
free(data);
}
@@ -164,24 +192,6 @@ window_clock_key(struct window_pane *wp, unused struct client *c,
}
void
-window_clock_timer(struct window_pane *wp)
-{
- struct window_clock_mode_data *data = wp->modedata;
- struct tm now, then;
- time_t t;
-
- t = time(NULL);
- gmtime_r(&t, &now);
- gmtime_r(&data->tim, &then);
- if (now.tm_min == then.tm_min)
- return;
- data->tim = t;
-
- window_clock_draw_screen(wp);
- server_redraw_window(wp->window);
-}
-
-void
window_clock_draw_screen(struct window_pane *wp)
{
struct window_clock_mode_data *data = wp->modedata;
diff --git a/window-copy.c b/window-copy.c
index 7d5bae4c..850b437a 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -91,7 +91,6 @@ const struct window_mode window_copy_mode = {
window_copy_free,
window_copy_resize,
window_copy_key,
- NULL,
};
enum window_copy_input_type {