summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornicm <nicm>2017-11-03 17:02:33 +0000
committernicm <nicm>2017-11-03 17:02:33 +0000
commit50a5f84cb4accf806dea2235ca8d3749b107aac8 (patch)
tree4b385f0816915a783b911680d6ec141652023ad7
parentba93a647f1b59d85340f9708ee2ae4fb6f201a64 (diff)
Support mouse on preview in tree mode.
-rw-r--r--grid.c2
-rw-r--r--mode-tree.c60
-rw-r--r--screen-write.c2
-rw-r--r--tmux.h4
-rw-r--r--window-buffer.c2
-rw-r--r--window-client.c2
-rw-r--r--window-tree.c103
7 files changed, 140 insertions, 35 deletions
diff --git a/grid.c b/grid.c
index aa9aea4c..74e80f96 100644
--- a/grid.c
+++ b/grid.c
@@ -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/mode-tree.c b/mode-tree.c
index 28f97805..79af6ab5 100644
--- a/mode-tree.c
+++ b/mode-tree.c
@@ -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/screen-write.c b/screen-write.c
index 44c28982..5ab472bd 100644
--- a/screen-write.c
+++ b/screen-write.c
@@ -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/tmux.h b/tmux.h
index dcd4c676..28fe1349 100644
--- a/tmux.h
+++ b/tmux.h
@@ -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/window-buffer.c b/window-buffer.c
index 14b15762..d416e39f 100644
--- a/window-buffer.c
+++ b/window-buffer.c
@@ -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/window-client.c b/window-client.c
index 5f1b58ba..76e536ec 100644
--- a/window-client.c
+++ b/window-client.c
@@ -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/window-tree.c b/window-tree.c
index 8e676c72..4165047b 100644
--- a/window-tree.c
+++ b/window-tree.c
@@ -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--;