mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 01:34:18 +00:00 
			
		
		
		
	Add options and flags for menu styles similar to those existing for
popups, from Alexis Hildebrandt. GitHub issue 3650.
This commit is contained in:
		@@ -39,10 +39,11 @@ const struct cmd_entry cmd_display_menu_entry = {
 | 
			
		||||
	.name = "display-menu",
 | 
			
		||||
	.alias = "menu",
 | 
			
		||||
 | 
			
		||||
	.args = { "c:t:S:OT:x:y:", 1, -1, cmd_display_menu_args_parse },
 | 
			
		||||
	.usage = "[-O] [-c target-client] [-S starting-choice] "
 | 
			
		||||
		 CMD_TARGET_PANE_USAGE " [-T title] [-x position] "
 | 
			
		||||
		 "[-y position] name key command ...",
 | 
			
		||||
	.args = { "b:c:C:t:s:S:OT:x:y:", 1, -1, cmd_display_menu_args_parse },
 | 
			
		||||
	.usage = "[-O] [-b border-lines] [-c target-client] "
 | 
			
		||||
		 "[-C starting-choice] [-s style] [-S border-style] "
 | 
			
		||||
		 CMD_TARGET_PANE_USAGE "[-T title] [-x position] [-y position] "
 | 
			
		||||
		 "name key command ...",
 | 
			
		||||
 | 
			
		||||
	.target = { 't', CMD_FIND_PANE, 0 },
 | 
			
		||||
 | 
			
		||||
@@ -289,19 +290,25 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
 | 
			
		||||
	struct client		*tc = cmdq_get_target_client(item);
 | 
			
		||||
	struct menu		*menu = NULL;
 | 
			
		||||
	struct menu_item	 menu_item;
 | 
			
		||||
	const char		*key, *name;
 | 
			
		||||
	const char		*key, *name, *value;
 | 
			
		||||
	const char		*style = args_get(args, 's');
 | 
			
		||||
	const char		*border_style = args_get(args, 'S');
 | 
			
		||||
	enum box_lines		 lines = BOX_LINES_DEFAULT;
 | 
			
		||||
	char			*title, *cause;
 | 
			
		||||
	int			 flags = 0, starting_choice = 0;
 | 
			
		||||
	u_int			 px, py, i, count = args_count(args);
 | 
			
		||||
	struct options		*o = target->s->curw->window->options;
 | 
			
		||||
	struct options_entry	*oe;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	if (tc->overlay_draw != NULL)
 | 
			
		||||
		return (CMD_RETURN_NORMAL);
 | 
			
		||||
 | 
			
		||||
	if (args_has(args, 'S')) {
 | 
			
		||||
		if (strcmp(args_get(args, 'S'), "-") == 0)
 | 
			
		||||
	if (args_has(args, 'C')) {
 | 
			
		||||
		if (strcmp(args_get(args, 'C'), "-") == 0)
 | 
			
		||||
			starting_choice = -1;
 | 
			
		||||
		else {
 | 
			
		||||
			starting_choice = args_strtonum(args, 'S', 0, UINT_MAX,
 | 
			
		||||
			starting_choice = args_strtonum(args, 'C', 0, UINT_MAX,
 | 
			
		||||
			    &cause);
 | 
			
		||||
			if (cause != NULL) {
 | 
			
		||||
				cmdq_error(item, "starting choice %s", cause);
 | 
			
		||||
@@ -352,12 +359,24 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
 | 
			
		||||
		return (CMD_RETURN_NORMAL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	value = args_get(args, 'b');
 | 
			
		||||
	if (value != NULL) {
 | 
			
		||||
		oe = options_get(o, "menu-border-lines");
 | 
			
		||||
		lines = options_find_choice(options_table_entry(oe), value,
 | 
			
		||||
		    &cause);
 | 
			
		||||
		if (lines == -1) {
 | 
			
		||||
			cmdq_error(item, "menu-border-lines %s", cause);
 | 
			
		||||
			free(cause);
 | 
			
		||||
			return (CMD_RETURN_ERROR);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (args_has(args, 'O'))
 | 
			
		||||
		flags |= MENU_STAYOPEN;
 | 
			
		||||
	if (!event->m.valid)
 | 
			
		||||
		flags |= MENU_NOMOUSE;
 | 
			
		||||
	if (menu_display(menu, flags, starting_choice, item, px, py, tc, target,
 | 
			
		||||
	    NULL, NULL) != 0)
 | 
			
		||||
	if (menu_display(menu, flags, starting_choice, item, px, py, tc, lines,
 | 
			
		||||
	    style, border_style, target, NULL, NULL) != 0)
 | 
			
		||||
		return (CMD_RETURN_NORMAL);
 | 
			
		||||
	return (CMD_RETURN_WAIT);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										51
									
								
								menu.c
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								menu.c
									
									
									
									
									
								
							@@ -27,6 +27,10 @@ struct menu_data {
 | 
			
		||||
	struct cmdq_item	*item;
 | 
			
		||||
	int			 flags;
 | 
			
		||||
 | 
			
		||||
	struct grid_cell	 style;
 | 
			
		||||
	struct grid_cell	 border_style;
 | 
			
		||||
	enum box_lines		 border_lines;
 | 
			
		||||
 | 
			
		||||
	struct cmd_find_state	 fs;
 | 
			
		||||
	struct screen		 s;
 | 
			
		||||
 | 
			
		||||
@@ -199,12 +203,17 @@ menu_draw_cb(struct client *c, void *data,
 | 
			
		||||
	u_int			 i, px = md->px, py = md->py;
 | 
			
		||||
	struct grid_cell	 gc;
 | 
			
		||||
 | 
			
		||||
	style_apply(&gc, c->session->curw->window->options, "mode-style", NULL);
 | 
			
		||||
 | 
			
		||||
	screen_write_start(&ctx, s);
 | 
			
		||||
	screen_write_clearscreen(&ctx, 8);
 | 
			
		||||
	screen_write_menu(&ctx, menu, md->choice, BOX_LINES_DEFAULT,
 | 
			
		||||
	    &grid_default_cell, &grid_default_cell, &gc);
 | 
			
		||||
 | 
			
		||||
	if (md->border_lines != BOX_LINES_NONE) {
 | 
			
		||||
		screen_write_box(&ctx, menu->width + 4, menu->count + 2,
 | 
			
		||||
		    md->border_lines, &md->border_style, menu->title);
 | 
			
		||||
	}
 | 
			
		||||
	style_apply(&gc, c->session->curw->window->options, "mode-style", NULL);
 | 
			
		||||
 | 
			
		||||
	screen_write_menu(&ctx, menu, md->choice, md->border_lines,
 | 
			
		||||
	    &md->style, &md->border_style, &gc);
 | 
			
		||||
	screen_write_stop(&ctx);
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < screen_size_y(&md->s); i++) {
 | 
			
		||||
@@ -432,11 +441,14 @@ chosen:
 | 
			
		||||
struct menu_data *
 | 
			
		||||
menu_prepare(struct menu *menu, int flags, int starting_choice,
 | 
			
		||||
    struct cmdq_item *item, u_int px, u_int py, struct client *c,
 | 
			
		||||
    enum box_lines lines, const char *style, const char *border_style,
 | 
			
		||||
    struct cmd_find_state *fs, menu_choice_cb cb, void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct menu_data	*md;
 | 
			
		||||
	int			 choice;
 | 
			
		||||
	const char		*name;
 | 
			
		||||
	struct style		 sytmp;
 | 
			
		||||
	struct options		*o = c->session->curw->window->options;
 | 
			
		||||
 | 
			
		||||
	if (c->tty.sx < menu->width + 4 || c->tty.sy < menu->count + 2)
 | 
			
		||||
		return (NULL);
 | 
			
		||||
@@ -445,9 +457,35 @@ menu_prepare(struct menu *menu, int flags, int starting_choice,
 | 
			
		||||
	if (py + menu->count + 2 > c->tty.sy)
 | 
			
		||||
		py = c->tty.sy - menu->count - 2;
 | 
			
		||||
 | 
			
		||||
	if (lines == BOX_LINES_DEFAULT)
 | 
			
		||||
		lines = options_get_number(o, "menu-border-lines");
 | 
			
		||||
 | 
			
		||||
	md = xcalloc(1, sizeof *md);
 | 
			
		||||
	md->item = item;
 | 
			
		||||
	md->flags = flags;
 | 
			
		||||
	md->border_lines = lines;
 | 
			
		||||
 | 
			
		||||
	memcpy(&md->style, &grid_default_cell, sizeof md->style);
 | 
			
		||||
	style_apply(&md->style, o, "menu-style", NULL);
 | 
			
		||||
	if (style != NULL) {
 | 
			
		||||
		style_set(&sytmp, &grid_default_cell);
 | 
			
		||||
		if (style_parse(&sytmp, &md->style, style) == 0) {
 | 
			
		||||
			md->style.fg = sytmp.gc.fg;
 | 
			
		||||
			md->style.bg = sytmp.gc.bg;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	md->style.attr = 0;
 | 
			
		||||
 | 
			
		||||
	memcpy(&md->border_style, &grid_default_cell, sizeof md->border_style);
 | 
			
		||||
	style_apply(&md->border_style, o, "menu-border-style", NULL);
 | 
			
		||||
	if (border_style != NULL) {
 | 
			
		||||
		style_set(&sytmp, &grid_default_cell);
 | 
			
		||||
		if (style_parse(&sytmp, &md->border_style, border_style) == 0) {
 | 
			
		||||
			md->border_style.fg = sytmp.gc.fg;
 | 
			
		||||
			md->border_style.bg = sytmp.gc.bg;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	md->border_style.attr = 0;
 | 
			
		||||
 | 
			
		||||
	if (fs != NULL)
 | 
			
		||||
		cmd_find_copy_state(&md->fs, fs);
 | 
			
		||||
@@ -501,12 +539,13 @@ menu_prepare(struct menu *menu, int flags, int starting_choice,
 | 
			
		||||
int
 | 
			
		||||
menu_display(struct menu *menu, int flags, int starting_choice,
 | 
			
		||||
    struct cmdq_item *item, u_int px, u_int py, struct client *c,
 | 
			
		||||
    enum box_lines lines, const char *style, const char *border_style,
 | 
			
		||||
    struct cmd_find_state *fs, menu_choice_cb cb, void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct menu_data	*md;
 | 
			
		||||
 | 
			
		||||
	md = menu_prepare(menu, flags, starting_choice, item, px, py, c, fs, cb,
 | 
			
		||||
	    data);
 | 
			
		||||
	md = menu_prepare(menu, flags, starting_choice, item, px, py, c, lines,
 | 
			
		||||
	    style, border_style, fs, cb, data);
 | 
			
		||||
	if (md == NULL)
 | 
			
		||||
		return (-1);
 | 
			
		||||
	server_client_set_overlay(c, 0, NULL, menu_mode_cb, menu_draw_cb,
 | 
			
		||||
 
 | 
			
		||||
@@ -962,8 +962,8 @@ mode_tree_display_menu(struct mode_tree_data *mtd, struct client *c, u_int x,
 | 
			
		||||
		x -= (menu->width + 4) / 2;
 | 
			
		||||
	else
 | 
			
		||||
		x = 0;
 | 
			
		||||
	if (menu_display(menu, 0, 0, NULL, x, y, c, NULL,
 | 
			
		||||
	    mode_tree_menu_callback, mtm) != 0)
 | 
			
		||||
	if (menu_display(menu, 0, 0, NULL, x, y, c, BOX_LINES_DEFAULT, NULL,
 | 
			
		||||
	    NULL, NULL, mode_tree_menu_callback, mtm) != 0)
 | 
			
		||||
		menu_free(menu);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -327,6 +327,33 @@ const struct options_table_entry options_table[] = {
 | 
			
		||||
		  "Empty does not write a history file."
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	{ .name = "menu-style",
 | 
			
		||||
	  .type = OPTIONS_TABLE_STRING,
 | 
			
		||||
	  .scope = OPTIONS_TABLE_WINDOW,
 | 
			
		||||
	  .flags = OPTIONS_TABLE_IS_STYLE,
 | 
			
		||||
	  .default_str = "default",
 | 
			
		||||
	  .separator = ",",
 | 
			
		||||
	  .text = "Default style of menu."
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	{ .name = "menu-border-style",
 | 
			
		||||
	  .type = OPTIONS_TABLE_STRING,
 | 
			
		||||
	  .scope = OPTIONS_TABLE_WINDOW,
 | 
			
		||||
	  .default_str = "default",
 | 
			
		||||
	  .flags = OPTIONS_TABLE_IS_STYLE,
 | 
			
		||||
	  .separator = ",",
 | 
			
		||||
	  .text = "Default style of menu borders."
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	{ .name = "menu-border-lines",
 | 
			
		||||
	  .type = OPTIONS_TABLE_CHOICE,
 | 
			
		||||
	  .scope = OPTIONS_TABLE_WINDOW,
 | 
			
		||||
	  .choices = options_table_popup_border_lines_list,
 | 
			
		||||
	  .default_num = BOX_LINES_SINGLE,
 | 
			
		||||
	  .text = "Type of characters used to draw menu border lines. Some of "
 | 
			
		||||
	          "these are only supported on terminals with UTF-8 support."
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	{ .name = "message-limit",
 | 
			
		||||
	  .type = OPTIONS_TABLE_NUMBER,
 | 
			
		||||
	  .scope = OPTIONS_TABLE_SERVER,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								popup.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								popup.c
									
									
									
									
									
								
							@@ -575,8 +575,8 @@ menu:
 | 
			
		||||
		x = m->x - (pd->menu->width + 4) / 2;
 | 
			
		||||
	else
 | 
			
		||||
		x = 0;
 | 
			
		||||
	pd->md = menu_prepare(pd->menu, 0, 0, NULL, x, m->y, c, NULL,
 | 
			
		||||
	    popup_menu_done, pd);
 | 
			
		||||
	pd->md = menu_prepare(pd->menu, 0, 0, NULL, x, m->y, c,
 | 
			
		||||
	    BOX_LINES_DEFAULT, NULL, NULL, NULL, popup_menu_done, pd);
 | 
			
		||||
	c->flags |= CLIENT_REDRAWOVERLAY;
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
 
 | 
			
		||||
@@ -713,15 +713,16 @@ screen_write_menu(struct screen_write_ctx *ctx, struct menu *menu, int choice,
 | 
			
		||||
		name = menu->items[i].name;
 | 
			
		||||
		if (name == NULL) {
 | 
			
		||||
			screen_write_cursormove(ctx, cx, cy + 1 + i, 0);
 | 
			
		||||
			screen_write_hline(ctx, width + 4, 1, 1, lines, gc);
 | 
			
		||||
			screen_write_hline(ctx, width + 4, 1, 1, lines,
 | 
			
		||||
			    border_gc);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (choice >= 0 && i == (u_int)choice && *name != '-')
 | 
			
		||||
			gc = choice_gc;
 | 
			
		||||
 | 
			
		||||
		screen_write_cursormove(ctx, cx + 2, cy + 1 + i, 0);
 | 
			
		||||
		for (j = 0; j < width; j++)
 | 
			
		||||
		screen_write_cursormove(ctx, cx + 1, cy + 1 + i, 0);
 | 
			
		||||
		for (j = 0; j < width + 2; j++)
 | 
			
		||||
			screen_write_putc(ctx, gc, ' ');
 | 
			
		||||
 | 
			
		||||
		screen_write_cursormove(ctx, cx + 2, cy + 1 + i, 0);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								status.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								status.c
									
									
									
									
									
								
							@@ -1764,8 +1764,9 @@ status_prompt_complete_list_menu(struct client *c, char **list, u_int size,
 | 
			
		||||
	else
 | 
			
		||||
		offset = 0;
 | 
			
		||||
 | 
			
		||||
	if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, 0, NULL, offset,
 | 
			
		||||
	    py, c, NULL, status_prompt_menu_callback, spm) != 0) {
 | 
			
		||||
	if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, 0, NULL, offset, py, c,
 | 
			
		||||
	    BOX_LINES_DEFAULT, NULL, NULL, NULL, status_prompt_menu_callback,
 | 
			
		||||
	    spm) != 0) {
 | 
			
		||||
		menu_free(menu);
 | 
			
		||||
		free(spm);
 | 
			
		||||
		return (0);
 | 
			
		||||
@@ -1857,8 +1858,9 @@ status_prompt_complete_window_menu(struct client *c, struct session *s,
 | 
			
		||||
	else
 | 
			
		||||
		offset = 0;
 | 
			
		||||
 | 
			
		||||
	if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, 0, NULL, offset,
 | 
			
		||||
	    py, c, NULL, status_prompt_menu_callback, spm) != 0) {
 | 
			
		||||
	if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, 0, NULL, offset, py, c,
 | 
			
		||||
	    BOX_LINES_DEFAULT, NULL, NULL, NULL, status_prompt_menu_callback,
 | 
			
		||||
	    spm) != 0) {
 | 
			
		||||
		menu_free(menu);
 | 
			
		||||
		free(spm);
 | 
			
		||||
		return (NULL);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user