Skip to content

Commit

Permalink
Change copy mode to make copy of the pane history so it does not need to
Browse files Browse the repository at this point in the history
freeze updates (which does not play nicely with some applications, a
longstanding problem) and will allow some other changes later. From
Anindya Mukherjee.
  • Loading branch information
nicm committed Apr 6, 2020
1 parent fccce69 commit 77b827f
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 49 deletions.
2 changes: 2 additions & 0 deletions key-bindings.c
Expand Up @@ -387,6 +387,7 @@ key_bindings_init(void)
"bind -Tcopy-mode g command-prompt -p'(goto line)' 'send -X goto-line \"%%%\"'",
"bind -Tcopy-mode n send -X search-again",
"bind -Tcopy-mode q send -X cancel",
"bind -Tcopy-mode r send -X refresh-from-pane",
"bind -Tcopy-mode t command-prompt -1p'(jump to forward)' 'send -X jump-to-forward \"%%%\"'",
"bind -Tcopy-mode Home send -X start-of-line",
"bind -Tcopy-mode End send -X end-of-line",
Expand Down Expand Up @@ -489,6 +490,7 @@ key_bindings_init(void)
"bind -Tcopy-mode-vi n send -X search-again",
"bind -Tcopy-mode-vi o send -X other-end",
"bind -Tcopy-mode-vi q send -X cancel",
"bind -Tcopy-mode-vi r send -X refresh-from-pane",
"bind -Tcopy-mode-vi t command-prompt -1p'(jump to forward)' 'send -X jump-to-forward \"%%%\"'",
"bind -Tcopy-mode-vi v send -X rectangle-toggle",
"bind -Tcopy-mode-vi w send -X next-word",
Expand Down
1 change: 1 addition & 0 deletions tmux.1
Expand Up @@ -1513,6 +1513,7 @@ The following commands are supported in copy mode:
.It Li "previous-space" Ta "B" Ta ""
.It Li "previous-word" Ta "b" Ta "M-b"
.It Li "rectangle-toggle" Ta "v" Ta "R"
.It Li "refresh-from-pane" Ta "r" Ta "r"
.It Li "scroll-down" Ta "C-e" Ta "C-Down"
.It Li "scroll-down-and-cancel" Ta "" Ta ""
.It Li "scroll-up" Ta "C-y" Ta "C-Up"
Expand Down
3 changes: 0 additions & 3 deletions tmux.h
Expand Up @@ -904,7 +904,6 @@ struct window_pane {

int fd;
struct bufferevent *event;
u_int disabled;

struct event resize_timer;

Expand All @@ -925,8 +924,6 @@ struct window_pane {
size_t status_size;

TAILQ_HEAD (, window_mode_entry) modes;
struct event modetimer;
time_t modelast;

char *searchstr;
int searchregex;
Expand Down
69 changes: 50 additions & 19 deletions window-copy.c
Expand Up @@ -130,6 +130,7 @@ static void window_copy_rectangle_toggle(struct window_mode_entry *);
static void window_copy_move_mouse(struct mouse_event *);
static void window_copy_drag_update(struct client *, struct mouse_event *);
static void window_copy_drag_release(struct client *, struct mouse_event *);
static struct screen* window_copy_clone_screen(struct screen *src);

const struct window_mode window_copy_mode = {
.name = "copy-mode",
Expand Down Expand Up @@ -205,6 +206,8 @@ struct window_copy_mode_data {
struct screen *backing;
int backing_written; /* backing display started */

int viewmode; /* view mode entered */

u_int oy; /* number of lines scrolled up */

u_int selx; /* beginning of selection */
Expand Down Expand Up @@ -295,6 +298,27 @@ window_copy_scroll_timer(__unused int fd, __unused short events, void *arg)
}
}

static struct screen *
window_copy_clone_screen(struct screen *src)
{
struct screen *dst;
struct screen_write_ctx ctx;

dst = xcalloc(1, sizeof *dst);
screen_init(dst, screen_size_x(src),
screen_hsize(src) + screen_size_y(src), src->grid->hlimit);
grid_duplicate_lines(dst->grid, 0, src->grid, 0,
screen_hsize(src) + screen_size_y(src));
dst->grid->sy = screen_size_y(src);
dst->grid->hsize = screen_hsize(src);

screen_write_start(&ctx, NULL, dst);
screen_write_cursormove(&ctx, src->cx, src->cy, 0);
screen_write_stop(&ctx);

return (dst);
}

static struct window_copy_mode_data *
window_copy_common_init(struct window_mode_entry *wme)
{
Expand All @@ -320,6 +344,7 @@ window_copy_common_init(struct window_mode_entry *wme)
data->searchmark = NULL;
data->searchx = data->searchy = data->searcho = -1;
data->timeout = 0;
data->viewmode = 0;

data->jumptype = WINDOW_COPY_OFF;
data->jumpchar = '\0';
Expand All @@ -343,10 +368,7 @@ window_copy_init(struct window_mode_entry *wme,

data = window_copy_common_init(wme);

if (wp->fd != -1 && wp->disabled++ == 0)
bufferevent_disable(wp->event, EV_READ|EV_WRITE);

data->backing = &wp->base;
data->backing = window_copy_clone_screen(&wp->base);
data->cx = data->backing->cx;
data->cy = data->backing->cy;

Expand Down Expand Up @@ -375,6 +397,7 @@ window_copy_view_init(struct window_mode_entry *wme,
struct screen *s;

data = window_copy_common_init(wme);
data->viewmode = 1;

data->backing = s = xmalloc(sizeof *data->backing);
screen_init(s, screen_size_x(base), screen_size_y(base), UINT_MAX);
Expand All @@ -385,23 +408,17 @@ window_copy_view_init(struct window_mode_entry *wme,
static void
window_copy_free(struct window_mode_entry *wme)
{
struct window_pane *wp = wme->wp;
struct window_copy_mode_data *data = wme->data;

evtimer_del(&data->dragtimer);

if (wp->fd != -1 && --wp->disabled == 0)
bufferevent_enable(wp->event, EV_READ|EV_WRITE);

free(data->searchmark);
free(data->searchstr);

if (data->backing != &wp->base) {
screen_free(data->backing);
free(data->backing);
}
screen_free(&data->screen);
screen_free(data->backing);
free(data->backing);

screen_free(&data->screen);
free(data);
}

Expand All @@ -425,9 +442,6 @@ window_copy_vadd(struct window_pane *wp, const char *fmt, va_list ap)
struct grid_cell gc;
u_int old_hsize, old_cy;

if (backing == &wp->base)
return;

memcpy(&gc, &grid_default_cell, sizeof gc);

old_hsize = screen_hsize(data->backing);
Expand Down Expand Up @@ -663,15 +677,13 @@ window_copy_formats(struct window_mode_entry *wme, struct format_tree *ft)
static void
window_copy_resize(struct window_mode_entry *wme, u_int sx, u_int sy)
{
struct window_pane *wp = wme->wp;
struct window_copy_mode_data *data = wme->data;
struct screen *s = &data->screen;
struct screen_write_ctx ctx;
int search;

screen_resize(s, sx, sy, 1);
if (data->backing != &wp->base)
screen_resize(data->backing, sx, sy, 1);
screen_resize(data->backing, sx, sy, 1);

if (data->cy > sy - 1)
data->cy = sy - 1;
Expand Down Expand Up @@ -1984,6 +1996,23 @@ window_copy_cmd_search_forward_incremental(struct window_copy_cmd_state *cs)
return (action);
}

static enum window_copy_cmd_action
window_copy_cmd_refresh_from_pane(struct window_copy_cmd_state *cs)
{
struct window_mode_entry *wme = cs->wme;
struct window_pane *wp = wme->wp;
struct window_copy_mode_data *data = wme->data;

if (data->viewmode)
return (WINDOW_COPY_CMD_NOTHING);

screen_free(data->backing);
free(data->backing);
data->backing = window_copy_clone_screen(&wp->base);

return (WINDOW_COPY_CMD_REDRAW);
}

static const struct {
const char *command;
int minargs;
Expand Down Expand Up @@ -2089,6 +2118,8 @@ static const struct {
window_copy_cmd_previous_word },
{ "rectangle-toggle", 0, 0, 0,
window_copy_cmd_rectangle_toggle },
{ "refresh-from-pane", 0, 0, 0,
window_copy_cmd_refresh_from_pane },
{ "scroll-down", 0, 0, 1,
window_copy_cmd_scroll_down },
{ "scroll-down-and-cancel", 0, 0, 0,
Expand Down
27 changes: 0 additions & 27 deletions window.c
Expand Up @@ -1066,40 +1066,15 @@ window_pane_get_palette(struct window_pane *wp, int c)
return (new);
}

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_all(wp);
}
}

int
window_pane_set_mode(struct window_pane *wp, const struct window_mode *mode,
struct cmd_find_state *fs, struct args *args)
{
struct timeval tv = { .tv_sec = 10 };
struct window_mode_entry *wme;

if (!TAILQ_EMPTY(&wp->modes) && TAILQ_FIRST(&wp->modes)->mode == mode)
return (1);

wp->modelast = time(NULL);
if (TAILQ_EMPTY(&wp->modes)) {
evtimer_set(&wp->modetimer, window_pane_mode_timer, wp);
evtimer_add(&wp->modetimer, &tv);
}

TAILQ_FOREACH(wme, &wp->modes, entry) {
if (wme->mode == mode)
break;
Expand Down Expand Up @@ -1141,7 +1116,6 @@ window_pane_reset_mode(struct window_pane *wp)
next = TAILQ_FIRST(&wp->modes);
if (next == NULL) {
log_debug("%s: no next mode", __func__);
evtimer_del(&wp->modetimer);
wp->screen = &wp->base;
} else {
log_debug("%s: next mode is %s", __func__, next->mode->name);
Expand Down Expand Up @@ -1174,7 +1148,6 @@ window_pane_key(struct window_pane *wp, struct client *c, struct session *s,

wme = TAILQ_FIRST(&wp->modes);
if (wme != NULL) {
wp->modelast = time(NULL);
if (wme->mode->key != NULL)
wme->mode->key(wme, c, s, wl, (key & ~KEYC_XTERM), m);
return (0);
Expand Down

0 comments on commit 77b827f

Please sign in to comment.