16483eba0Schristos /* $OpenBSD$ */ 26483eba0Schristos 36483eba0Schristos /* 46483eba0Schristos * Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com> 56483eba0Schristos * 66483eba0Schristos * Permission to use, copy, modify, and distribute this software for any 76483eba0Schristos * purpose with or without fee is hereby granted, provided that the above 86483eba0Schristos * copyright notice and this permission notice appear in all copies. 96483eba0Schristos * 106483eba0Schristos * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 116483eba0Schristos * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 126483eba0Schristos * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 136483eba0Schristos * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 146483eba0Schristos * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 156483eba0Schristos * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 166483eba0Schristos * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 176483eba0Schristos */ 186483eba0Schristos 196483eba0Schristos #include <sys/types.h> 206483eba0Schristos 216483eba0Schristos #include <stdlib.h> 226483eba0Schristos #include <string.h> 236483eba0Schristos 246483eba0Schristos #include "tmux.h" 256483eba0Schristos 266483eba0Schristos /* 276483eba0Schristos * Display a menu on a client. 286483eba0Schristos */ 296483eba0Schristos 3046548964Swiz static enum args_parse_type cmd_display_menu_args_parse(struct args *, 3146548964Swiz u_int, char **); 326483eba0Schristos static enum cmd_retval cmd_display_menu_exec(struct cmd *, 336483eba0Schristos struct cmdq_item *); 349fb66d81Schristos static enum cmd_retval cmd_display_popup_exec(struct cmd *, 359fb66d81Schristos struct cmdq_item *); 366483eba0Schristos 376483eba0Schristos const struct cmd_entry cmd_display_menu_entry = { 386483eba0Schristos .name = "display-menu", 396483eba0Schristos .alias = "menu", 406483eba0Schristos 41*890b6d91Swiz .args = { "b:c:C:H:s:S:MOt:T:x:y:", 1, -1, cmd_display_menu_args_parse }, 42*890b6d91Swiz .usage = "[-MO] [-b border-lines] [-c target-client] " 43f844e94eSwiz "[-C starting-choice] [-H selected-style] [-s style] " 44f844e94eSwiz "[-S border-style] " CMD_TARGET_PANE_USAGE "[-T title] " 456483eba0Schristos "[-x position] [-y position] name key command ...", 466483eba0Schristos 476483eba0Schristos .target = { 't', CMD_FIND_PANE, 0 }, 486483eba0Schristos 499fb66d81Schristos .flags = CMD_AFTERHOOK|CMD_CLIENT_CFLAG, 506483eba0Schristos .exec = cmd_display_menu_exec 516483eba0Schristos }; 526483eba0Schristos 539fb66d81Schristos const struct cmd_entry cmd_display_popup_entry = { 549fb66d81Schristos .name = "display-popup", 559fb66d81Schristos .alias = "popup", 569fb66d81Schristos 5746548964Swiz .args = { "Bb:Cc:d:e:Eh:s:S:t:T:w:x:y:", 0, -1, NULL }, 5846548964Swiz .usage = "[-BCE] [-b border-lines] [-c target-client] " 5946548964Swiz "[-d start-directory] [-e environment] [-h height] " 6046548964Swiz "[-s style] [-S border-style] " CMD_TARGET_PANE_USAGE 6146548964Swiz "[-T title] [-w width] [-x position] [-y position] " 6246548964Swiz "[shell-command]", 639fb66d81Schristos 649fb66d81Schristos .target = { 't', CMD_FIND_PANE, 0 }, 659fb66d81Schristos 669fb66d81Schristos .flags = CMD_AFTERHOOK|CMD_CLIENT_CFLAG, 679fb66d81Schristos .exec = cmd_display_popup_exec 689fb66d81Schristos }; 699fb66d81Schristos 7046548964Swiz static enum args_parse_type 7146548964Swiz cmd_display_menu_args_parse(struct args *args, u_int idx, __unused char **cause) 7246548964Swiz { 7346548964Swiz u_int i = 0; 7446548964Swiz enum args_parse_type type = ARGS_PARSE_STRING; 7546548964Swiz 7646548964Swiz for (;;) { 7746548964Swiz type = ARGS_PARSE_STRING; 7846548964Swiz if (i == idx) 7946548964Swiz break; 8046548964Swiz if (*args_string(args, i++) == '\0') 8146548964Swiz continue; 8246548964Swiz 8346548964Swiz type = ARGS_PARSE_STRING; 8446548964Swiz if (i++ == idx) 8546548964Swiz break; 8646548964Swiz 8746548964Swiz type = ARGS_PARSE_COMMANDS_OR_STRING; 8846548964Swiz if (i++ == idx) 8946548964Swiz break; 9046548964Swiz } 9146548964Swiz return (type); 9246548964Swiz } 9346548964Swiz 949fb66d81Schristos static int 959fb66d81Schristos cmd_display_menu_get_position(struct client *tc, struct cmdq_item *item, 969fb66d81Schristos struct args *args, u_int *px, u_int *py, u_int w, u_int h) 979fb66d81Schristos { 989fb66d81Schristos struct tty *tty = &tc->tty; 999fb66d81Schristos struct cmd_find_state *target = cmdq_get_target(item); 1009fb66d81Schristos struct key_event *event = cmdq_get_event(item); 1019fb66d81Schristos struct session *s = tc->session; 1029fb66d81Schristos struct winlink *wl = target->wl; 1039fb66d81Schristos struct window_pane *wp = target->wp; 1049fb66d81Schristos struct style_ranges *ranges = NULL; 1059fb66d81Schristos struct style_range *sr = NULL; 1069fb66d81Schristos const char *xp, *yp; 1079fb66d81Schristos char *p; 1089fb66d81Schristos int top; 1099fb66d81Schristos u_int line, ox, oy, sx, sy, lines, position; 1109fb66d81Schristos long n; 1119fb66d81Schristos struct format_tree *ft; 1129fb66d81Schristos 1139fb66d81Schristos /* 1149fb66d81Schristos * Work out the position from the -x and -y arguments. This is the 1159fb66d81Schristos * bottom-left position. 1169fb66d81Schristos */ 1179fb66d81Schristos 1189fb66d81Schristos /* If the popup is too big, stop now. */ 1199fb66d81Schristos if (w > tty->sx || h > tty->sy) 1209fb66d81Schristos return (0); 1219fb66d81Schristos 1229fb66d81Schristos /* Create format with mouse position if any. */ 1239fb66d81Schristos ft = format_create_from_target(item); 1249fb66d81Schristos if (event->m.valid) { 1259fb66d81Schristos format_add(ft, "popup_mouse_x", "%u", event->m.x); 1269fb66d81Schristos format_add(ft, "popup_mouse_y", "%u", event->m.y); 1279fb66d81Schristos } 1289fb66d81Schristos 1299fb66d81Schristos /* 1309fb66d81Schristos * If there are any status lines, add this window position and the 1319fb66d81Schristos * status line position. 1329fb66d81Schristos */ 1339fb66d81Schristos top = status_at_line(tc); 1349fb66d81Schristos if (top != -1) { 1359fb66d81Schristos lines = status_line_size(tc); 1369fb66d81Schristos if (top == 0) 1379fb66d81Schristos top = lines; 1389fb66d81Schristos else 1399fb66d81Schristos top = 0; 1409fb66d81Schristos position = options_get_number(s->options, "status-position"); 1419fb66d81Schristos 1429fb66d81Schristos for (line = 0; line < lines; line++) { 1439fb66d81Schristos ranges = &tc->status.entries[line].ranges; 1449fb66d81Schristos TAILQ_FOREACH(sr, ranges, entry) { 1459fb66d81Schristos if (sr->type != STYLE_RANGE_WINDOW) 1469fb66d81Schristos continue; 1479fb66d81Schristos if (sr->argument == (u_int)wl->idx) 1489fb66d81Schristos break; 1499fb66d81Schristos } 1509fb66d81Schristos if (sr != NULL) 1519fb66d81Schristos break; 1529fb66d81Schristos } 1539fb66d81Schristos 1549fb66d81Schristos if (sr != NULL) { 1559fb66d81Schristos format_add(ft, "popup_window_status_line_x", "%u", 1569fb66d81Schristos sr->start); 1579fb66d81Schristos if (position == 0) { 1589fb66d81Schristos format_add(ft, "popup_window_status_line_y", 1599fb66d81Schristos "%u", line + 1 + h); 1609fb66d81Schristos } else { 1619fb66d81Schristos format_add(ft, "popup_window_status_line_y", 1629fb66d81Schristos "%u", tty->sy - lines + line); 1639fb66d81Schristos } 1649fb66d81Schristos } 1659fb66d81Schristos 1669fb66d81Schristos if (position == 0) 1679fb66d81Schristos format_add(ft, "popup_status_line_y", "%u", lines + h); 1689fb66d81Schristos else { 1699fb66d81Schristos format_add(ft, "popup_status_line_y", "%u", 1709fb66d81Schristos tty->sy - lines); 1719fb66d81Schristos } 1729fb66d81Schristos } else 1739fb66d81Schristos top = 0; 1749fb66d81Schristos 1759fb66d81Schristos /* Popup width and height. */ 1769fb66d81Schristos format_add(ft, "popup_width", "%u", w); 1779fb66d81Schristos format_add(ft, "popup_height", "%u", h); 1789fb66d81Schristos 1799fb66d81Schristos /* Position so popup is in the centre. */ 1809fb66d81Schristos n = (long)(tty->sx - 1) / 2 - w / 2; 1819fb66d81Schristos if (n < 0) 1829fb66d81Schristos format_add(ft, "popup_centre_x", "%u", 0); 1839fb66d81Schristos else 1849fb66d81Schristos format_add(ft, "popup_centre_x", "%ld", n); 1859fb66d81Schristos n = (tty->sy - 1) / 2 + h / 2; 186c745c111Schristos if ((unsigned long)n >= tty->sy) 1879fb66d81Schristos format_add(ft, "popup_centre_y", "%u", tty->sy - h); 1889fb66d81Schristos else 1899fb66d81Schristos format_add(ft, "popup_centre_y", "%ld", n); 1909fb66d81Schristos 1919fb66d81Schristos /* Position of popup relative to mouse. */ 1929fb66d81Schristos if (event->m.valid) { 1939fb66d81Schristos n = (long)event->m.x - w / 2; 1949fb66d81Schristos if (n < 0) 1959fb66d81Schristos format_add(ft, "popup_mouse_centre_x", "%u", 0); 1969fb66d81Schristos else 1979fb66d81Schristos format_add(ft, "popup_mouse_centre_x", "%ld", n); 1989fb66d81Schristos n = event->m.y - h / 2; 1999fb66d81Schristos if (n + h >= tty->sy) { 2009fb66d81Schristos format_add(ft, "popup_mouse_centre_y", "%u", 2019fb66d81Schristos tty->sy - h); 2029fb66d81Schristos } else 2039fb66d81Schristos format_add(ft, "popup_mouse_centre_y", "%ld", n); 2049fb66d81Schristos n = (long)event->m.y + h; 2053afd71f9Skre if (n >= (long)tty->sy) 20646548964Swiz format_add(ft, "popup_mouse_top", "%u", tty->sy - 1); 2079fb66d81Schristos else 2089fb66d81Schristos format_add(ft, "popup_mouse_top", "%ld", n); 2099fb66d81Schristos n = event->m.y - h; 2109fb66d81Schristos if (n < 0) 2119fb66d81Schristos format_add(ft, "popup_mouse_bottom", "%u", 0); 2129fb66d81Schristos else 2139fb66d81Schristos format_add(ft, "popup_mouse_bottom", "%ld", n); 2149fb66d81Schristos } 2159fb66d81Schristos 2169fb66d81Schristos /* Position in pane. */ 2179fb66d81Schristos tty_window_offset(&tc->tty, &ox, &oy, &sx, &sy); 2189fb66d81Schristos n = top + wp->yoff - oy + h; 219c745c111Schristos if ((unsigned long)n >= tty->sy) 2209fb66d81Schristos format_add(ft, "popup_pane_top", "%u", tty->sy - h); 2219fb66d81Schristos else 2229fb66d81Schristos format_add(ft, "popup_pane_top", "%ld", n); 2239fb66d81Schristos format_add(ft, "popup_pane_bottom", "%u", top + wp->yoff + wp->sy - oy); 2249fb66d81Schristos format_add(ft, "popup_pane_left", "%u", wp->xoff - ox); 2259fb66d81Schristos n = (long)wp->xoff + wp->sx - ox - w; 2269fb66d81Schristos if (n < 0) 2279fb66d81Schristos format_add(ft, "popup_pane_right", "%u", 0); 2289fb66d81Schristos else 2299fb66d81Schristos format_add(ft, "popup_pane_right", "%ld", n); 2309fb66d81Schristos 2319fb66d81Schristos /* Expand horizontal position. */ 2329fb66d81Schristos xp = args_get(args, 'x'); 2339fb66d81Schristos if (xp == NULL || strcmp(xp, "C") == 0) 2349fb66d81Schristos xp = "#{popup_centre_x}"; 2359fb66d81Schristos else if (strcmp(xp, "R") == 0) 23659b94b2cSchristos xp = "#{popup_pane_right}"; 2379fb66d81Schristos else if (strcmp(xp, "P") == 0) 2389fb66d81Schristos xp = "#{popup_pane_left}"; 2399fb66d81Schristos else if (strcmp(xp, "M") == 0) 2409fb66d81Schristos xp = "#{popup_mouse_centre_x}"; 2419fb66d81Schristos else if (strcmp(xp, "W") == 0) 2429fb66d81Schristos xp = "#{popup_window_status_line_x}"; 2439fb66d81Schristos p = format_expand(ft, xp); 2449fb66d81Schristos n = strtol(p, NULL, 10); 2459fb66d81Schristos if (n + w >= tty->sx) 2469fb66d81Schristos n = tty->sx - w; 2479fb66d81Schristos else if (n < 0) 2489fb66d81Schristos n = 0; 2499fb66d81Schristos *px = n; 25046548964Swiz log_debug("%s: -x: %s = %s = %u (-w %u)", __func__, xp, p, *px, w); 2519fb66d81Schristos free(p); 2529fb66d81Schristos 2539fb66d81Schristos /* Expand vertical position */ 2549fb66d81Schristos yp = args_get(args, 'y'); 2559fb66d81Schristos if (yp == NULL || strcmp(yp, "C") == 0) 2569fb66d81Schristos yp = "#{popup_centre_y}"; 2579fb66d81Schristos else if (strcmp(yp, "P") == 0) 2589fb66d81Schristos yp = "#{popup_pane_bottom}"; 2599fb66d81Schristos else if (strcmp(yp, "M") == 0) 2609fb66d81Schristos yp = "#{popup_mouse_top}"; 2619fb66d81Schristos else if (strcmp(yp, "S") == 0) 2629fb66d81Schristos yp = "#{popup_status_line_y}"; 2639fb66d81Schristos else if (strcmp(yp, "W") == 0) 2649fb66d81Schristos yp = "#{popup_window_status_line_y}"; 2659fb66d81Schristos p = format_expand(ft, yp); 2669fb66d81Schristos n = strtol(p, NULL, 10); 267c745c111Schristos if ((unsigned long)n < h) 2689fb66d81Schristos n = 0; 2699fb66d81Schristos else 2709fb66d81Schristos n -= h; 2719fb66d81Schristos if (n + h >= tty->sy) 2729fb66d81Schristos n = tty->sy - h; 2739fb66d81Schristos else if (n < 0) 2749fb66d81Schristos n = 0; 2759fb66d81Schristos *py = n; 27646548964Swiz log_debug("%s: -y: %s = %s = %u (-h %u)", __func__, yp, p, *py, h); 2779fb66d81Schristos free(p); 2789fb66d81Schristos 279f844e94eSwiz format_free(ft); 2809fb66d81Schristos return (1); 2819fb66d81Schristos } 2829fb66d81Schristos 2836483eba0Schristos static enum cmd_retval 2846483eba0Schristos cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item) 2856483eba0Schristos { 2869fb66d81Schristos struct args *args = cmd_get_args(self); 2879fb66d81Schristos struct cmd_find_state *target = cmdq_get_target(item); 2889fb66d81Schristos struct key_event *event = cmdq_get_event(item); 2899fb66d81Schristos struct client *tc = cmdq_get_target_client(item); 2906483eba0Schristos struct menu *menu = NULL; 2916483eba0Schristos struct menu_item menu_item; 292f844e94eSwiz const char *key, *name, *value; 293f844e94eSwiz const char *style = args_get(args, 's'); 294f844e94eSwiz const char *border_style = args_get(args, 'S'); 295f844e94eSwiz const char *selected_style = args_get(args, 'H'); 296f844e94eSwiz enum box_lines lines = BOX_LINES_DEFAULT; 297f844e94eSwiz char *title, *cause; 298f844e94eSwiz int flags = 0, starting_choice = 0; 29946548964Swiz u_int px, py, i, count = args_count(args); 300f844e94eSwiz struct options *o = target->s->curw->window->options; 301f844e94eSwiz struct options_entry *oe; 302f844e94eSwiz 3036483eba0Schristos 3049fb66d81Schristos if (tc->overlay_draw != NULL) 3056483eba0Schristos return (CMD_RETURN_NORMAL); 3066483eba0Schristos 307f844e94eSwiz if (args_has(args, 'C')) { 308f844e94eSwiz if (strcmp(args_get(args, 'C'), "-") == 0) 309f844e94eSwiz starting_choice = -1; 310f844e94eSwiz else { 311f844e94eSwiz starting_choice = args_strtonum(args, 'C', 0, UINT_MAX, 312f844e94eSwiz &cause); 313f844e94eSwiz if (cause != NULL) { 314f844e94eSwiz cmdq_error(item, "starting choice %s", cause); 315f844e94eSwiz free(cause); 316f844e94eSwiz return (CMD_RETURN_ERROR); 317f844e94eSwiz } 318f844e94eSwiz } 319f844e94eSwiz } 320f844e94eSwiz 3216483eba0Schristos if (args_has(args, 'T')) 3229fb66d81Schristos title = format_single_from_target(item, args_get(args, 'T')); 3236483eba0Schristos else 3246483eba0Schristos title = xstrdup(""); 3256483eba0Schristos menu = menu_create(title); 326f844e94eSwiz free(title); 3276483eba0Schristos 32846548964Swiz for (i = 0; i != count; /* nothing */) { 32946548964Swiz name = args_string(args, i++); 3306483eba0Schristos if (*name == '\0') { 3319fb66d81Schristos menu_add_item(menu, NULL, item, tc, target); 3326483eba0Schristos continue; 3336483eba0Schristos } 3346483eba0Schristos 33546548964Swiz if (count - i < 2) { 3366483eba0Schristos cmdq_error(item, "not enough arguments"); 3376483eba0Schristos menu_free(menu); 3386483eba0Schristos return (CMD_RETURN_ERROR); 3396483eba0Schristos } 34046548964Swiz key = args_string(args, i++); 3416483eba0Schristos 3426483eba0Schristos menu_item.name = name; 3436483eba0Schristos menu_item.key = key_string_lookup_string(key); 34446548964Swiz menu_item.command = args_string(args, i++); 3456483eba0Schristos 3469fb66d81Schristos menu_add_item(menu, &menu_item, item, tc, target); 3476483eba0Schristos } 3486483eba0Schristos if (menu == NULL) { 3496483eba0Schristos cmdq_error(item, "invalid menu arguments"); 3506483eba0Schristos return (CMD_RETURN_ERROR); 3516483eba0Schristos } 3526483eba0Schristos if (menu->count == 0) { 3536483eba0Schristos menu_free(menu); 3546483eba0Schristos return (CMD_RETURN_NORMAL); 3556483eba0Schristos } 3569fb66d81Schristos if (!cmd_display_menu_get_position(tc, item, args, &px, &py, 3579fb66d81Schristos menu->width + 4, menu->count + 2)) { 3589fb66d81Schristos menu_free(menu); 3599fb66d81Schristos return (CMD_RETURN_NORMAL); 3606483eba0Schristos } 3616483eba0Schristos 362f844e94eSwiz value = args_get(args, 'b'); 363f844e94eSwiz if (value != NULL) { 364f844e94eSwiz oe = options_get(o, "menu-border-lines"); 365f844e94eSwiz lines = options_find_choice(options_table_entry(oe), value, 366f844e94eSwiz &cause); 367f844e94eSwiz if (lines == -1) { 368f844e94eSwiz cmdq_error(item, "menu-border-lines %s", cause); 369f844e94eSwiz free(cause); 370f844e94eSwiz return (CMD_RETURN_ERROR); 371f844e94eSwiz } 372f844e94eSwiz } 373f844e94eSwiz 3749fb66d81Schristos if (args_has(args, 'O')) 3759fb66d81Schristos flags |= MENU_STAYOPEN; 376*890b6d91Swiz if (!event->m.valid && !args_has(args, 'M')) 3776483eba0Schristos flags |= MENU_NOMOUSE; 378f844e94eSwiz if (menu_display(menu, flags, starting_choice, item, px, py, tc, lines, 379f844e94eSwiz style, selected_style, border_style, target, NULL, NULL) != 0) 3809fb66d81Schristos return (CMD_RETURN_NORMAL); 3819fb66d81Schristos return (CMD_RETURN_WAIT); 3829fb66d81Schristos } 3839fb66d81Schristos 3849fb66d81Schristos static enum cmd_retval 3859fb66d81Schristos cmd_display_popup_exec(struct cmd *self, struct cmdq_item *item) 3869fb66d81Schristos { 3879fb66d81Schristos struct args *args = cmd_get_args(self); 3889fb66d81Schristos struct cmd_find_state *target = cmdq_get_target(item); 3899fb66d81Schristos struct session *s = target->s; 3909fb66d81Schristos struct client *tc = cmdq_get_target_client(item); 3919fb66d81Schristos struct tty *tty = &tc->tty; 39246548964Swiz const char *value, *shell, *shellcmd = NULL; 39346548964Swiz const char *style = args_get(args, 's'); 39446548964Swiz const char *border_style = args_get(args, 'S'); 39546548964Swiz char *cwd, *cause = NULL, **argv = NULL, *title; 39646548964Swiz int flags = 0, argc = 0; 39746548964Swiz enum box_lines lines = BOX_LINES_DEFAULT; 39846548964Swiz u_int px, py, w, h, count = args_count(args); 39946548964Swiz struct args_value *av; 40046548964Swiz struct environ *env = NULL; 40146548964Swiz struct options *o = s->curw->window->options; 40246548964Swiz struct options_entry *oe; 4039fb66d81Schristos 4049fb66d81Schristos if (args_has(args, 'C')) { 4059fb66d81Schristos server_client_clear_overlay(tc); 4069fb66d81Schristos return (CMD_RETURN_NORMAL); 4079fb66d81Schristos } 4089fb66d81Schristos if (tc->overlay_draw != NULL) 4099fb66d81Schristos return (CMD_RETURN_NORMAL); 4109fb66d81Schristos 4119fb66d81Schristos h = tty->sy / 2; 4129fb66d81Schristos if (args_has(args, 'h')) { 4139fb66d81Schristos h = args_percentage(args, 'h', 1, tty->sy, tty->sy, &cause); 4149fb66d81Schristos if (cause != NULL) { 4159fb66d81Schristos cmdq_error(item, "height %s", cause); 4169fb66d81Schristos free(cause); 4179fb66d81Schristos return (CMD_RETURN_ERROR); 4189fb66d81Schristos } 4199fb66d81Schristos } 4209fb66d81Schristos 4219fb66d81Schristos w = tty->sx / 2; 4229fb66d81Schristos if (args_has(args, 'w')) { 4239fb66d81Schristos w = args_percentage(args, 'w', 1, tty->sx, tty->sx, &cause); 4249fb66d81Schristos if (cause != NULL) { 4259fb66d81Schristos cmdq_error(item, "width %s", cause); 4269fb66d81Schristos free(cause); 4279fb66d81Schristos return (CMD_RETURN_ERROR); 4289fb66d81Schristos } 4299fb66d81Schristos } 4309fb66d81Schristos 43146548964Swiz if (w > tty->sx) 43246548964Swiz w = tty->sx; 43346548964Swiz if (h > tty->sy) 43446548964Swiz h = tty->sy; 4359fb66d81Schristos if (!cmd_display_menu_get_position(tc, item, args, &px, &py, w, h)) 4369fb66d81Schristos return (CMD_RETURN_NORMAL); 4379fb66d81Schristos 43846548964Swiz value = args_get(args, 'b'); 43946548964Swiz if (args_has(args, 'B')) 44046548964Swiz lines = BOX_LINES_NONE; 44146548964Swiz else if (value != NULL) { 44246548964Swiz oe = options_get(o, "popup-border-lines"); 44346548964Swiz lines = options_find_choice(options_table_entry(oe), value, 44446548964Swiz &cause); 44546548964Swiz if (cause != NULL) { 44646548964Swiz cmdq_error(item, "popup-border-lines %s", cause); 44746548964Swiz free(cause); 44846548964Swiz return (CMD_RETURN_ERROR); 44946548964Swiz } 45046548964Swiz } 45146548964Swiz 4529fb66d81Schristos value = args_get(args, 'd'); 4539fb66d81Schristos if (value != NULL) 4549fb66d81Schristos cwd = format_single_from_target(item, value); 4559fb66d81Schristos else 4569fb66d81Schristos cwd = xstrdup(server_client_get_cwd(tc, s)); 45746548964Swiz if (count == 0) 4589fb66d81Schristos shellcmd = options_get_string(s->options, "default-command"); 45946548964Swiz else if (count == 1) 46046548964Swiz shellcmd = args_string(args, 0); 46146548964Swiz if (count <= 1 && (shellcmd == NULL || *shellcmd == '\0')) { 4629fb66d81Schristos shellcmd = NULL; 46346548964Swiz shell = options_get_string(s->options, "default-shell"); 46446548964Swiz if (!checkshell(shell)) 46546548964Swiz shell = _PATH_BSHELL; 46646548964Swiz cmd_append_argv(&argc, &argv, shell); 46746548964Swiz } else 46846548964Swiz args_to_vector(args, &argc, &argv); 46946548964Swiz 47046548964Swiz if (args_has(args, 'e') >= 1) { 47146548964Swiz env = environ_create(); 47246548964Swiz av = args_first_value(args, 'e'); 47346548964Swiz while (av != NULL) { 47446548964Swiz environ_put(env, av->string, 0); 47546548964Swiz av = args_next_value(av); 47646548964Swiz } 4779fb66d81Schristos } 4789fb66d81Schristos 47946548964Swiz if (args_has(args, 'T')) 48046548964Swiz title = format_single_from_target(item, args_get(args, 'T')); 48146548964Swiz else 48246548964Swiz title = xstrdup(""); 4839fb66d81Schristos if (args_has(args, 'E') > 1) 4849fb66d81Schristos flags |= POPUP_CLOSEEXITZERO; 4859fb66d81Schristos else if (args_has(args, 'E')) 4869fb66d81Schristos flags |= POPUP_CLOSEEXIT; 48746548964Swiz if (popup_display(flags, lines, item, px, py, w, h, env, shellcmd, argc, 48846548964Swiz argv, cwd, title, tc, s, style, border_style, NULL, NULL) != 0) { 48946548964Swiz cmd_free_argv(argc, argv); 49046548964Swiz if (env != NULL) 49146548964Swiz environ_free(env); 492f844e94eSwiz free(cwd); 49346548964Swiz free(title); 4946483eba0Schristos return (CMD_RETURN_NORMAL); 49546548964Swiz } 49646548964Swiz if (env != NULL) 49746548964Swiz environ_free(env); 498f844e94eSwiz free(cwd); 49946548964Swiz free(title); 50046548964Swiz cmd_free_argv(argc, argv); 5016483eba0Schristos return (CMD_RETURN_WAIT); 5026483eba0Schristos } 503