diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2017-11-03 17:02:34 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2017-11-03 17:02:34 +0000 |
commit | 19ad58bb79afda4e9307ffbeed520837205d581c (patch) | |
tree | aa76d8c3bd758484bd78c81b53f301afe3c816f1 /usr.bin | |
parent | 6cbc7ffe22deeb6321ed120545cf4c685eb35ef9 (diff) |
Support mouse on preview in tree mode.
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/tmux/grid.c | 4 | ||||
-rw-r--r-- | usr.bin/tmux/mode-tree.c | 62 | ||||
-rw-r--r-- | usr.bin/tmux/screen-write.c | 4 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 6 | ||||
-rw-r--r-- | usr.bin/tmux/window-buffer.c | 4 | ||||
-rw-r--r-- | usr.bin/tmux/window-client.c | 4 | ||||
-rw-r--r-- | usr.bin/tmux/window-tree.c | 105 |
7 files changed, 147 insertions, 42 deletions
diff --git a/usr.bin/tmux/grid.c b/usr.bin/tmux/grid.c index cb9953c72e5..9832e75b150 100644 --- a/usr.bin/tmux/grid.c +++ b/usr.bin/tmux/grid.c @@ -1,4 +1,4 @@ -/* $OpenBSD: grid.c,v 1.77 2017/09/11 06:40:46 nicm Exp $ */ +/* $OpenBSD: grid.c,v 1.78 2017/11/03 17:02:33 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -182,7 +182,7 @@ grid_clear_cell(struct grid *gd, u_int px, u_int py, u_int bg) static int grid_check_y(struct grid *gd, u_int py) { - if ((py) >= (gd)->hsize + (gd)->sy) { + if (py >= gd->hsize + gd->sy) { log_debug("y out of range: %u", py); return (-1); } diff --git a/usr.bin/tmux/mode-tree.c b/usr.bin/tmux/mode-tree.c index 737efa6d4ee..6095bcaa116 100644 --- a/usr.bin/tmux/mode-tree.c +++ b/usr.bin/tmux/mode-tree.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mode-tree.c,v 1.18 2017/11/03 14:23:44 nicm Exp $ */ +/* $OpenBSD: mode-tree.c,v 1.19 2017/11/03 17:02:33 nicm Exp $ */ /* * Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -190,27 +190,6 @@ mode_tree_clear_tagged(struct mode_tree_list *mtl) } } -static void -mode_tree_set_current(struct mode_tree_data *mtd, uint64_t tag) -{ - u_int i; - - for (i = 0; i < mtd->line_size; i++) { - if (mtd->line_list[i].item->tag == tag) - break; - } - if (i != mtd->line_size) { - mtd->current = i; - if (mtd->current > mtd->height - 1) - mtd->offset = mtd->current - mtd->height + 1; - else - mtd->offset = 0; - } else { - mtd->current = 0; - mtd->offset = 0; - } -} - void mode_tree_up(struct mode_tree_data *mtd, int wrap) { @@ -248,6 +227,36 @@ mode_tree_get_current(struct mode_tree_data *mtd) return (mtd->line_list[mtd->current].item->itemdata); } +void +mode_tree_expand_current(struct mode_tree_data *mtd) +{ + if (!mtd->line_list[mtd->current].item->expanded) { + mtd->line_list[mtd->current].item->expanded = 1; + mode_tree_build(mtd); + } +} + +void +mode_tree_set_current(struct mode_tree_data *mtd, uint64_t tag) +{ + u_int i; + + for (i = 0; i < mtd->line_size; i++) { + if (mtd->line_list[i].item->tag == tag) + break; + } + if (i != mtd->line_size) { + mtd->current = i; + if (mtd->current > mtd->height - 1) + mtd->offset = mtd->current - mtd->height + 1; + else + mtd->offset = 0; + } else { + mtd->current = 0; + mtd->offset = 0; + } +} + u_int mode_tree_count_tagged(struct mode_tree_data *mtd) { @@ -718,7 +727,7 @@ mode_tree_filter_free(void *data) int mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key, - struct mouse_event *m) + struct mouse_event *m, u_int *xp, u_int *yp) { struct mode_tree_line *line; struct mode_tree_item *current, *parent; @@ -731,8 +740,13 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key, *key = KEYC_NONE; return (0); } + if (xp != NULL) + *xp = x; + if (yp != NULL) + *yp = y; if (x > mtd->width || y > mtd->height) { - *key = KEYC_NONE; + if (!mtd->preview || y < mtd->height) + *key = KEYC_NONE; return (0); } if (mtd->offset + y < mtd->line_size) { diff --git a/usr.bin/tmux/screen-write.c b/usr.bin/tmux/screen-write.c index 37373f03ccc..028ddcf5dac 100644 --- a/usr.bin/tmux/screen-write.c +++ b/usr.bin/tmux/screen-write.c @@ -1,4 +1,4 @@ -/* $OpenBSD: screen-write.c,v 1.133 2017/11/02 22:00:42 nicm Exp $ */ +/* $OpenBSD: screen-write.c,v 1.134 2017/11/03 17:02:33 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -403,6 +403,8 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src, cy = s->cy; for (yy = py; yy < py + ny; yy++) { + if (yy >= gd->hsize + gd->sy) + break; cx = s->cx; for (xx = px; xx < px + nx; xx++) { if (xx >= gd->linedata[yy].cellsize) diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index ecbd644b1d1..32704f672e2 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.811 2017/11/02 22:00:42 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.812 2017/11/03 17:02:33 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -2232,6 +2232,8 @@ typedef int (*mode_tree_search_cb)(void *, void *, const char *); typedef void (*mode_tree_each_cb)(void *, void *, struct client *, key_code); u_int mode_tree_count_tagged(struct mode_tree_data *); void *mode_tree_get_current(struct mode_tree_data *); +void mode_tree_expand_current(struct mode_tree_data *); +void mode_tree_set_current(struct mode_tree_data *, uint64_t); void mode_tree_each_tagged(struct mode_tree_data *, mode_tree_each_cb, struct client *, key_code, int); void mode_tree_up(struct mode_tree_data *, int); @@ -2248,7 +2250,7 @@ struct mode_tree_item *mode_tree_add(struct mode_tree_data *, void mode_tree_remove(struct mode_tree_data *, struct mode_tree_item *); void mode_tree_draw(struct mode_tree_data *); int mode_tree_key(struct mode_tree_data *, struct client *, key_code *, - struct mouse_event *); + struct mouse_event *, u_int *, u_int *); void mode_tree_run_command(struct client *, struct cmd_find_state *, const char *, const char *); diff --git a/usr.bin/tmux/window-buffer.c b/usr.bin/tmux/window-buffer.c index b9cc3273198..6d62830b4ba 100644 --- a/usr.bin/tmux/window-buffer.c +++ b/usr.bin/tmux/window-buffer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window-buffer.c,v 1.11 2017/11/02 22:00:42 nicm Exp $ */ +/* $OpenBSD: window-buffer.c,v 1.12 2017/11/03 17:02:33 nicm Exp $ */ /* * Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -344,7 +344,7 @@ window_buffer_key(struct window_pane *wp, struct client *c, struct window_buffer_itemdata *item; int finished; - finished = mode_tree_key(mtd, c, &key, m); + finished = mode_tree_key(mtd, c, &key, m, NULL, NULL); switch (key) { case 'd': item = mode_tree_get_current(mtd); diff --git a/usr.bin/tmux/window-client.c b/usr.bin/tmux/window-client.c index bbf2c8300e5..812cf0680fc 100644 --- a/usr.bin/tmux/window-client.c +++ b/usr.bin/tmux/window-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window-client.c,v 1.11 2017/11/02 22:00:42 nicm Exp $ */ +/* $OpenBSD: window-client.c,v 1.12 2017/11/03 17:02:33 nicm Exp $ */ /* * Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -318,7 +318,7 @@ window_client_key(struct window_pane *wp, struct client *c, struct window_client_itemdata *item; int finished; - finished = mode_tree_key(mtd, c, &key, m); + finished = mode_tree_key(mtd, c, &key, m, NULL, NULL); switch (key) { case 'd': case 'x': diff --git a/usr.bin/tmux/window-tree.c b/usr.bin/tmux/window-tree.c index 8ccf9d36c9c..dbe96d674b9 100644 --- a/usr.bin/tmux/window-tree.c +++ b/usr.bin/tmux/window-tree.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window-tree.c,v 1.26 2017/11/02 22:00:42 nicm Exp $ */ +/* $OpenBSD: window-tree.c,v 1.27 2017/11/03 17:02:33 nicm Exp $ */ /* * Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -104,6 +104,12 @@ struct window_tree_modedata { enum window_tree_type type; int offset; + + int left; + int right; + u_int start; + u_int end; + u_int each; }; static void @@ -545,17 +551,25 @@ window_tree_draw_session(struct window_tree_modedata *data, struct session *s, return; if (left) { + data->left = cx + 2; screen_write_cursormove(ctx, cx + 2, cy); screen_write_vline(ctx, sy, 0, 0); screen_write_cursormove(ctx, cx, cy + sy / 2); screen_write_puts(ctx, &grid_default_cell, "<"); - } + } else + data->left = -1; if (right) { + data->right = cx + sx - 3; screen_write_cursormove(ctx, cx + sx - 3, cy); screen_write_vline(ctx, sy, 0, 0); screen_write_cursormove(ctx, cx + sx - 1, cy + sy / 2); screen_write_puts(ctx, &grid_default_cell, ">"); - } + } else + data->right = -1; + + data->start = start; + data->end = end; + data->each = each; i = loop = 0; RB_FOREACH(wl, winlinks, &s->windows) { @@ -670,17 +684,25 @@ window_tree_draw_window(struct window_tree_modedata *data, struct session *s, return; if (left) { + data->left = cx + 2; screen_write_cursormove(ctx, cx + 2, cy); screen_write_vline(ctx, sy, 0, 0); screen_write_cursormove(ctx, cx, cy + sy / 2); screen_write_puts(ctx, &grid_default_cell, "<"); - } + } else + data->left = -1; if (right) { + data->right = cx + sx - 3; screen_write_cursormove(ctx, cx + sx - 3, cy); screen_write_vline(ctx, sy, 0, 0); screen_write_cursormove(ctx, cx + sx - 1, cy + sy / 2); screen_write_puts(ctx, &grid_default_cell, ">"); - } + } else + data->right = -1; + + data->start = start; + data->end = end; + data->each = each; i = loop = 0; TAILQ_FOREACH(wp, &w->panes, entry) { @@ -963,21 +985,86 @@ window_tree_command_free(void *modedata) window_tree_destroy(data); } +static key_code +window_tree_mouse(struct window_tree_modedata *data, key_code key, u_int x, + struct window_tree_itemdata *item) +{ + struct session *s; + struct winlink *wl; + struct window_pane *wp; + u_int loop; + + if (key != KEYC_MOUSEDOWN1_PANE) + return (KEYC_NONE); + + if (data->left != -1 && x <= (u_int)data->left) + return ('<'); + if (data->right != -1 && x >= (u_int)data->right) + return ('>'); + + if (data->left != -1) + x -= data->left; + else if (x != 0) + x--; + if (x == 0 || data->end == 0) + x = 0; + else { + x = x / data->each; + if (data->start + x >= data->end) + x = data->end - 1; + } + + window_tree_pull_item(item, &s, &wl, &wp); + if (item->type == WINDOW_TREE_SESSION) { + if (s == NULL) + return (KEYC_NONE); + mode_tree_expand_current(data->data); + loop = 0; + RB_FOREACH(wl, winlinks, &s->windows) { + if (loop == data->start + x) + break; + loop++; + } + if (wl != NULL) + mode_tree_set_current(data->data, (uint64_t)wl); + return ('\r'); + } + if (item->type == WINDOW_TREE_WINDOW) { + if (wl == NULL) + return (KEYC_NONE); + mode_tree_expand_current(data->data); + loop = 0; + TAILQ_FOREACH(wp, &wl->window->panes, entry) { + if (loop == data->start + x) + break; + loop++; + } + if (wp != NULL) + mode_tree_set_current(data->data, (uint64_t)wp); + return ('\r'); + } + return (KEYC_NONE); +} + static void window_tree_key(struct window_pane *wp, struct client *c, __unused struct session *s, key_code key, struct mouse_event *m) { struct window_tree_modedata *data = wp->modedata; - struct window_tree_itemdata *item; + struct window_tree_itemdata *item, *new_item; char *name, *prompt; struct cmd_find_state fs; int finished; - u_int tagged; + u_int tagged, x, y; item = mode_tree_get_current(data->data); - finished = mode_tree_key(data->data, c, &key, m); - if (item != mode_tree_get_current(data->data)) + finished = mode_tree_key(data->data, c, &key, m, &x, &y); + if (item != (new_item = mode_tree_get_current(data->data))) { + item = new_item; data->offset = 0; + } + if (KEYC_IS_MOUSE(key)) + key = window_tree_mouse(data, key, x, item); switch (key) { case '<': data->offset--; |