=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/mode-tree.c,v retrieving revision 1.27 retrieving revision 1.28 diff -c -r1.27 -r1.28 *** src/usr.bin/tmux/mode-tree.c 2019/03/18 20:53:33 1.27 --- src/usr.bin/tmux/mode-tree.c 2019/05/12 08:58:09 1.28 *************** *** 1,4 **** ! /* $OpenBSD: mode-tree.c,v 1.27 2019/03/18 20:53:33 nicm Exp $ */ /* * Copyright (c) 2017 Nicholas Marriott --- 1,4 ---- ! /* $OpenBSD: mode-tree.c,v 1.28 2019/05/12 08:58:09 nicm Exp $ */ /* * Copyright (c) 2017 Nicholas Marriott *************** *** 35,40 **** --- 35,41 ---- struct window_pane *wp; void *modedata; + const char *menu; const char **sort_list; u_int sort_size; *************** *** 43,48 **** --- 44,50 ---- mode_tree_build_cb buildcb; mode_tree_draw_cb drawcb; mode_tree_search_cb searchcb; + mode_tree_menu_cb menucb; struct mode_tree_list children; struct mode_tree_list saved; *************** *** 89,96 **** --- 91,111 ---- int flat; }; + struct mode_tree_menu { + struct mode_tree_data *data; + struct client *c; + u_int line; + void *itemdata; + }; + static void mode_tree_free_items(struct mode_tree_list *); + #define MODE_TREE_MENU \ + "Scroll Left,<,|" \ + "Scroll Right,>,|" \ + "|" \ + "Cancel,q," + static struct mode_tree_item * mode_tree_find_item(struct mode_tree_list *mtl, uint64_t tag) { *************** *** 299,306 **** struct mode_tree_data * mode_tree_start(struct window_pane *wp, struct args *args, mode_tree_build_cb buildcb, mode_tree_draw_cb drawcb, ! mode_tree_search_cb searchcb, void *modedata, const char **sort_list, ! u_int sort_size, struct screen **s) { struct mode_tree_data *mtd; const char *sort; --- 314,322 ---- struct mode_tree_data * mode_tree_start(struct window_pane *wp, struct args *args, mode_tree_build_cb buildcb, mode_tree_draw_cb drawcb, ! mode_tree_search_cb searchcb, mode_tree_menu_cb menucb, void *modedata, ! const char *menu, const char **sort_list, u_int sort_size, ! struct screen **s) { struct mode_tree_data *mtd; const char *sort; *************** *** 311,316 **** --- 327,333 ---- mtd->wp = wp; mtd->modedata = modedata; + mtd->menu = menu; mtd->sort_list = sort_list; mtd->sort_size = sort_size; *************** *** 334,339 **** --- 351,357 ---- mtd->buildcb = buildcb; mtd->drawcb = drawcb; mtd->searchcb = searchcb; + mtd->menucb = menucb; TAILQ_INIT(&mtd->children); *************** *** 762,767 **** --- 780,850 ---- mode_tree_remove_ref(data); } + static void + mode_tree_menu_callback(__unused struct menu *menu, __unused u_int idx, + key_code key, void *data) + { + struct mode_tree_menu *mtm = data; + struct mode_tree_data *mtd = mtm->data; + struct mode_tree_item *mti; + + if (mtd->dead || key == KEYC_NONE) + goto out; + + if (mtm->line >= mtd->line_size) + goto out; + mti = mtd->line_list[mtm->line].item; + if (mti->itemdata != mtm->itemdata) + goto out; + mtd->current = mtm->line; + mtd->menucb (mtd->modedata, mtm->c, key); + + out: + mode_tree_remove_ref(mtd); + free(mtm); + } + + static void + mode_tree_display_menu(struct mode_tree_data *mtd, struct client *c, u_int x, + u_int y, int outside) + { + struct mode_tree_item *mti; + struct menu *menu; + struct mode_tree_menu *mtm; + const char *s; + char *title; + u_int line; + + if (mtd->offset + y > mtd->line_size - 1) + line = mtd->current; + else + line = mtd->offset + y; + mti = mtd->line_list[line].item; + + if (!outside) { + s = mtd->menu; + xasprintf(&title, "#[align=centre]%s", mti->name); + } else { + s = MODE_TREE_MENU; + title = xstrdup(""); + } + menu = menu_create(s, c, NULL, title); + free(title); + if (menu == NULL) + return; + + mtm = xmalloc(sizeof *mtm); + mtm->data = mtd; + mtm->c = c; + mtm->line = line; + mtm->itemdata = mti->itemdata; + mtd->references++; + + if (menu_display(menu, 0, NULL, x, y, c, NULL, mode_tree_menu_callback, + mtm) != 0) + menu_free(menu); + } + int mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key, struct mouse_event *m, u_int *xp, u_int *yp) *************** *** 772,778 **** int choice; key_code tmp; ! if (KEYC_IS_MOUSE(*key)) { if (cmd_mouse_at(mtd->wp, m, &x, &y, 0) != 0) { *key = KEYC_NONE; return (0); --- 855,861 ---- int choice; key_code tmp; ! if (KEYC_IS_MOUSE(*key) && m != NULL) { if (cmd_mouse_at(mtd->wp, m, &x, &y, 0) != 0) { *key = KEYC_NONE; return (0); *************** *** 782,801 **** if (yp != NULL) *yp = y; if (x > mtd->width || y > mtd->height) { if (!mtd->preview) *key = KEYC_NONE; return (0); } if (mtd->offset + y < mtd->line_size) { if (*key == KEYC_MOUSEDOWN1_PANE || *key == KEYC_DOUBLECLICK1_PANE) mtd->current = mtd->offset + y; if (*key == KEYC_DOUBLECLICK1_PANE) *key = '\r'; ! else *key = KEYC_NONE; ! } else *key = KEYC_NONE; return (0); } --- 865,893 ---- if (yp != NULL) *yp = y; if (x > mtd->width || y > mtd->height) { + if (*key == KEYC_MOUSEDOWN3_PANE) + mode_tree_display_menu(mtd, c, x, y, 1); if (!mtd->preview) *key = KEYC_NONE; return (0); } if (mtd->offset + y < mtd->line_size) { if (*key == KEYC_MOUSEDOWN1_PANE || + *key == KEYC_MOUSEDOWN3_PANE || *key == KEYC_DOUBLECLICK1_PANE) mtd->current = mtd->offset + y; if (*key == KEYC_DOUBLECLICK1_PANE) *key = '\r'; ! else { ! if (*key == KEYC_MOUSEDOWN3_PANE) ! mode_tree_display_menu(mtd, c, x, y, 0); *key = KEYC_NONE; ! } ! } else { ! if (*key == KEYC_MOUSEDOWN3_PANE) ! mode_tree_display_menu(mtd, c, x, y, 0); *key = KEYC_NONE; + } return (0); } *************** *** 879,885 **** current->tagged = 1; } else current->tagged = 0; ! mode_tree_down(mtd, 0); break; case 'T': for (i = 0; i < mtd->line_size; i++) --- 971,978 ---- current->tagged = 1; } else current->tagged = 0; ! if (m != NULL) ! mode_tree_down(mtd, 0); break; case 'T': for (i = 0; i < mtd->line_size; i++)