aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornicm <nicm>2016-06-15 09:13:46 +0000
committernicm <nicm>2016-06-15 09:13:46 +0000
commitbee3e3e28d04a237b1013b1dd3d36cddcd326891 (patch)
treee25badeaca2bcb9c246385a2bff99a14fb30f4e1
parent068b8b03ad06abf1082e288ed7496970cccd7678 (diff)
downloadrtmux-bee3e3e28d04a237b1013b1dd3d36cddcd326891.tar.gz
rtmux-bee3e3e28d04a237b1013b1dd3d36cddcd326891.tar.bz2
rtmux-bee3e3e28d04a237b1013b1dd3d36cddcd326891.zip
Copy mode needs to keep the original grid intact so it can copy from it
if needed, so it disables reading from the pane. This can be problem with some programs. So make tmux automatically exit all modes after 180 seconds of inactivity and if there is pending output.
-rw-r--r--tmux.h3
-rw-r--r--window.c27
2 files changed, 30 insertions, 0 deletions
diff --git a/tmux.h b/tmux.h
index b8d1a1f5..b84530f2 100644
--- a/tmux.h
+++ b/tmux.h
@@ -823,6 +823,7 @@ struct window_mode {
void (*key)(struct window_pane *, struct client *, struct session *,
key_code, struct mouse_event *);
};
+#define WINDOW_MODE_TIMEOUT 180
/* Structures for choose mode. */
struct window_choose_data {
@@ -905,6 +906,8 @@ struct window_pane {
const struct window_mode *mode;
void *modedata;
+ struct event modetimer;
+ time_t modelast;
TAILQ_ENTRY(window_pane) entry;
RB_ENTRY(window_pane) tree_entry;
diff --git a/window.c b/window.c
index a252629d..bba8e3b1 100644
--- a/window.c
+++ b/window.c
@@ -17,6 +17,7 @@
*/
#include <sys/types.h>
+#include <sys/ioctl.h>
#include <errno.h>
#include <fcntl.h>
@@ -1046,15 +1047,38 @@ window_pane_alternate_off(struct window_pane *wp, struct grid_cell *gc,
wp->flags |= PANE_REDRAW;
}
+static void
+window_pane_mode_timer(__unused int fd, __unused short events, void *arg)
+{
+ struct window_pane *wp = arg;
+ struct timeval tv = { .tv_sec = 10 };
+ int n = 0;
+
+ evtimer_del(&wp->modetimer);
+ evtimer_add(&wp->modetimer, &tv);
+
+ log_debug("%%%u in mode: last=%ld", wp->id, (long)wp->modelast);
+
+ if (wp->modelast < time(NULL) - WINDOW_MODE_TIMEOUT) {
+ if (ioctl(wp->fd, FIONREAD, &n) == -1 || n > 0)
+ window_pane_reset_mode(wp);
+ }
+}
+
int
window_pane_set_mode(struct window_pane *wp, const struct window_mode *mode)
{
struct screen *s;
+ struct timeval tv = { .tv_sec = 10 };
if (wp->mode != NULL)
return (1);
wp->mode = mode;
+ wp->modelast = time(NULL);
+ evtimer_set(&wp->modetimer, window_pane_mode_timer, wp);
+ evtimer_add(&wp->modetimer, &tv);
+
if ((s = wp->mode->init(wp)) != NULL)
wp->screen = s;
wp->flags |= (PANE_REDRAW|PANE_CHANGED);
@@ -1069,6 +1093,8 @@ window_pane_reset_mode(struct window_pane *wp)
if (wp->mode == NULL)
return;
+ evtimer_del(&wp->modetimer);
+
wp->mode->free(wp);
wp->mode = NULL;
@@ -1088,6 +1114,7 @@ window_pane_key(struct window_pane *wp, struct client *c, struct session *s,
return;
if (wp->mode != NULL) {
+ wp->modelast = time(NULL);
if (wp->mode->key != NULL)
wp->mode->key(wp, c, s, key, m);
return;