From 381eaaa3a384f87c68673d20746b1c25a3dfdf97 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 16 Jul 2026 13:04:29 +0100 Subject: [PATCH] No more popups and overlays. --- Makefile.am | 1 - cmd-display-menu.c | 476 +++++-------- options-table.c | 31 +- popup.c | 660 ------------------ regress/screen-redraw-popups.sh | 101 --- .../screen-redraw-results/popup-basic.result | 14 - .../screen-redraw-results/popup-double.result | 14 - .../popup-noborder.result | 14 - .../popup-over-split.result | 14 - screen-redraw.c | 75 +- screen-write.c | 17 +- server-client.c | 161 +---- status.c | 2 - tmux.1 | 204 +----- tmux.h | 45 +- tty-draw.c | 3 +- tty.c | 218 +----- window.c | 1 - 18 files changed, 260 insertions(+), 1791 deletions(-) delete mode 100644 popup.c delete mode 100644 regress/screen-redraw-popups.sh delete mode 100644 regress/screen-redraw-results/popup-basic.result delete mode 100644 regress/screen-redraw-results/popup-double.result delete mode 100644 regress/screen-redraw-results/popup-noborder.result delete mode 100644 regress/screen-redraw-results/popup-over-split.result diff --git a/Makefile.am b/Makefile.am index cbdb4e863..1ec72bf6c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -187,7 +187,6 @@ dist_tmux_SOURCES = \ options-table.c \ options.c \ paste.c \ - popup.c \ proc.c \ prompt-history.c \ prompt.c \ diff --git a/cmd-display-menu.c b/cmd-display-menu.c index 2aaf3238c..3eed593c9 100644 --- a/cmd-display-menu.c +++ b/cmd-display-menu.c @@ -91,203 +91,6 @@ cmd_display_menu_args_parse(struct args *args, u_int idx, __unused char **cause) return (type); } -static int -cmd_display_menu_get_popup_pos(struct client *tc, struct cmdq_item *item, - struct args *args, u_int *px, u_int *py, u_int w, u_int h) -{ - struct tty *tty = &tc->tty; - struct cmd_find_state *target = cmdq_get_target(item); - struct key_event *event = cmdq_get_event(item); - struct session *s = tc->session; - struct winlink *wl = target->wl; - struct window_pane *wp = target->wp; - struct style_ranges *ranges = NULL; - struct style_range *sr = NULL; - const char *xp, *yp; - char *p; - int top; - u_int line, ox, oy, sx, sy, lines, position; - long n; - struct format_tree *ft; - - /* - * Work out the position from the -x and -y arguments. This is the - * bottom-left position. - */ - - /* If the popup is too big, stop now. */ - if (w > tty->sx || h > tty->sy) - return (0); - - /* Create format with mouse position if any. */ - ft = format_create_from_target(item); - if (event->m.valid) { - format_add(ft, "popup_mouse_x", "%u", event->m.x); - format_add(ft, "popup_mouse_y", "%u", event->m.y); - } - - /* Position of the previous menu, for -x/-y L. */ - format_add(ft, "popup_last_x", "%u", target->w->menu_last_px); - format_add(ft, "popup_last_y", "%u", target->w->menu_last_py + h); - - /* - * If there are any status lines, add this window position and the - * status line position. - */ - top = status_at_line(tc); - if (top != -1) { - lines = status_line_size(tc); - if (top == 0) - top = lines; - else - top = 0; - position = options_get_number(s->options, "status-position"); - - for (line = 0; line < lines; line++) { - ranges = &tc->status.entries[line].ranges; - TAILQ_FOREACH(sr, ranges, entry) { - if (sr->type != STYLE_RANGE_WINDOW) - continue; - if (sr->argument == (u_int)wl->idx) - break; - } - if (sr != NULL) - break; - } - - if (sr != NULL) { - format_add(ft, "popup_window_status_line_x", "%u", - sr->start); - if (position == 0) { - format_add(ft, "popup_window_status_line_y", - "%u", line + 1 + h); - } else { - format_add(ft, "popup_window_status_line_y", - "%u", tty->sy - lines + line); - } - } - - if (position == 0) - format_add(ft, "popup_status_line_y", "%u", lines + h); - else { - format_add(ft, "popup_status_line_y", "%u", - tty->sy - lines); - } - } else - top = 0; - - /* Popup width and height. */ - format_add(ft, "popup_width", "%u", w); - format_add(ft, "popup_height", "%u", h); - - /* Position so popup is in the centre. */ - n = (long)(tty->sx - 1) / 2 - w / 2; - if (n < 0) - format_add(ft, "popup_centre_x", "%u", 0); - else - format_add(ft, "popup_centre_x", "%ld", n); - n = (tty->sy - 1) / 2 + h / 2; - if (n >= tty->sy) - format_add(ft, "popup_centre_y", "%u", tty->sy - h); - else - format_add(ft, "popup_centre_y", "%ld", n); - - /* Position of popup relative to mouse. */ - if (event->m.valid) { - n = (long)event->m.x - w / 2; - if (n < 0) - format_add(ft, "popup_mouse_centre_x", "%u", 0); - else - format_add(ft, "popup_mouse_centre_x", "%ld", n); - n = event->m.y - h / 2; - if (n + h >= tty->sy) { - format_add(ft, "popup_mouse_centre_y", "%u", - tty->sy - h); - } else - format_add(ft, "popup_mouse_centre_y", "%ld", n); - n = (long)event->m.y + h; - if (n >= tty->sy) - format_add(ft, "popup_mouse_top", "%u", tty->sy - 1); - else - format_add(ft, "popup_mouse_top", "%ld", n); - n = event->m.y - h; - if (n < 0) - format_add(ft, "popup_mouse_bottom", "%u", 0); - else - format_add(ft, "popup_mouse_bottom", "%ld", n); - } - - /* Position in pane. */ - tty_window_offset(&tc->tty, &ox, &oy, &sx, &sy); - n = top + wp->yoff - oy + h; - if (n >= tty->sy) - format_add(ft, "popup_pane_top", "%u", tty->sy - h); - else - format_add(ft, "popup_pane_top", "%ld", n); - format_add(ft, "popup_pane_bottom", "%u", top + wp->yoff + wp->sy - oy); - format_add(ft, "popup_pane_left", "%u", wp->xoff - ox); - n = (long)wp->xoff + wp->sx - ox - w; - if (n < 0) - format_add(ft, "popup_pane_right", "%u", 0); - else - format_add(ft, "popup_pane_right", "%ld", n); - - /* Expand horizontal position. */ - xp = args_get(args, 'x'); - if (xp == NULL || strcmp(xp, "C") == 0) - xp = "#{popup_centre_x}"; - else if (strcmp(xp, "R") == 0) - xp = "#{popup_pane_right}"; - else if (strcmp(xp, "P") == 0) - xp = "#{popup_pane_left}"; - else if (strcmp(xp, "M") == 0) - xp = "#{popup_mouse_centre_x}"; - else if (strcmp(xp, "L") == 0) - xp = "#{popup_last_x}"; - else if (strcmp(xp, "W") == 0) - xp = "#{popup_window_status_line_x}"; - p = format_expand(ft, xp); - n = strtol(p, NULL, 10); - if (n + w >= tty->sx) - n = tty->sx - w; - else if (n < 0) - n = 0; - *px = n; - log_debug("%s: -x: %s = %s = %u (-w %u)", __func__, xp, p, *px, w); - free(p); - - /* Expand vertical position */ - yp = args_get(args, 'y'); - if (yp == NULL || strcmp(yp, "C") == 0) - yp = "#{popup_centre_y}"; - else if (strcmp(yp, "P") == 0) - yp = "#{popup_pane_bottom}"; - else if (strcmp(yp, "M") == 0) - yp = "#{popup_mouse_top}"; - else if (strcmp(yp, "L") == 0) - yp = "#{popup_last_y}"; - else if (strcmp(yp, "S") == 0) - yp = "#{popup_status_line_y}"; - else if (strcmp(yp, "W") == 0) - yp = "#{popup_window_status_line_y}"; - p = format_expand(ft, yp); - n = strtol(p, NULL, 10); - if (n < h) - n = 0; - else - n -= h; - if (n + h >= tty->sy) - n = tty->sy - h; - else if (n < 0) - n = 0; - *py = n; - log_debug("%s: -y: %s = %s = %u (-h %u)", __func__, yp, p, *py, h); - free(p); - - format_free(ft); - return (1); -} - static int cmd_display_menu_get_menu_pos(struct client *tc, struct cmdq_item *item, struct args *args, u_int *px, u_int *py, u_int w, u_int h) @@ -565,6 +368,22 @@ fail: return (CMD_RETURN_ERROR); } +static enum pane_lines +cmd_display_popup_get_lines(const char *value, char **cause) +{ + const struct options_table_entry *oe; + + if (value == NULL) + value = "single"; + else if (strcmp(value, "rounded") == 0) + value = "single"; + else if (strcmp(value, "padded") == 0) + value = "spaces"; + + oe = options_search("pane-border-lines"); + return (options_find_choice(oe, value, cause)); +} + static enum cmd_retval cmd_display_popup_exec(struct cmd *self, struct cmdq_item *item) { @@ -572,146 +391,187 @@ cmd_display_popup_exec(struct cmd *self, struct cmdq_item *item) struct cmd_find_state *target = cmdq_get_target(item); struct session *s = target->s; struct client *tc = cmdq_get_target_client(item); - struct tty *tty = &tc->tty; - const char *value, *shell, *shellcmd = NULL; - const char *style = args_get(args, 's'); + struct winlink *wl = target->wl; + struct window *w = wl->window; + struct window_pane *wp = target->wp, *new_wp = NULL; + struct spawn_context sc = { 0 }; + struct layout_cell *lc = NULL; + struct layout_geometry lg; + struct event_payload *ep; + struct cmd_find_state fs; + const char *value, *style = args_get(args, 's'); const char *border_style = args_get(args, 'S'); - char *cwd = NULL, *cause = NULL, **argv = NULL; - char *title = NULL; - int modify = popup_present(tc); - int flags = -1, argc = 0; - enum box_lines lines = BOX_LINES_DEFAULT; - u_int px, py, w, h, count = args_count(args); + char *cause = NULL, *title = NULL; + int flags = SPAWN_FLOATING|SPAWN_MODAL; + enum pane_lines lines = PANE_LINES_SINGLE; + u_int px, py, sx, sy, count = args_count(args); struct args_value *av; - struct environ *env = NULL; - struct options *o = s->curw->window->options; - struct options_entry *oe; + long long ll; if (args_has(args, 'C')) { - server_client_clear_overlay(tc); + if (w->modal != NULL) + server_kill_pane(w->modal); return (CMD_RETURN_NORMAL); } - if (!modify && tc->overlay_draw != NULL) + + if (w->modal != NULL) return (CMD_RETURN_NORMAL); - if (!modify) { - h = tty->sy / 2; - if (args_has(args, 'h')) { - h = args_percentage(args, 'h', 1, tty->sy, tty->sy, - &cause); - if (cause != NULL) { - cmdq_error(item, "height %s", cause); - goto fail; - } - } - - w = tty->sx / 2; - if (args_has(args, 'w')) { - w = args_percentage(args, 'w', 1, tty->sx, tty->sx, - &cause); - if (cause != NULL) { - cmdq_error(item, "width %s", cause); - goto fail; - } - } - - if (w > tty->sx) - w = tty->sx; - if (h > tty->sy) - h = tty->sy; - if (!cmd_display_menu_get_popup_pos(tc, item, args, &px, &py, - w, h)) - goto out; - - value = args_get(args, 'd'); - if (value != NULL) - cwd = format_single_from_target(item, value); - else - cwd = xstrdup(server_client_get_cwd(tc, s)); - if (count == 0) { - shellcmd = options_get_string(s->options, - "default-command"); - } else if (count == 1) - shellcmd = args_string(args, 0); - if (count <= 1 && (shellcmd == NULL || *shellcmd == '\0')) { - shellcmd = NULL; - shell = options_get_string(s->options, "default-shell"); - if (!checkshell(shell)) - shell = _PATH_BSHELL; - cmd_append_argv(&argc, &argv, shell); - } else - args_to_vector(args, &argc, &argv); - - if (args_has(args, 'e') >= 1) { - env = environ_create(); - av = args_first_value(args, 'e'); - while (av != NULL) { - environ_put(env, av->string, 0); - av = args_next_value(av); - } - } - } - value = args_get(args, 'b'); if (args_has(args, 'B')) - lines = BOX_LINES_NONE; + lines = PANE_LINES_NONE; else if (value != NULL) { - oe = options_get(o, "popup-border-lines"); - lines = options_find_choice(options_table_entry(oe), value, - &cause); + lines = cmd_display_popup_get_lines(value, &cause); if (cause != NULL) { - cmdq_error(item, "popup-border-lines %s", cause); + cmdq_error(item, "pane-border-lines %s", cause); goto fail; } } + sy = w->sy / 2; + if (args_has(args, 'h')) { + ll = args_percentage(args, 'h', 1, w->sy, w->sy, &cause); + if (cause != NULL) { + cmdq_error(item, "height %s", cause); + goto fail; + } + sy = ll; + } + + sx = w->sx / 2; + if (args_has(args, 'w')) { + ll = args_percentage(args, 'w', 1, w->sx, w->sx, &cause); + if (cause != NULL) { + cmdq_error(item, "width %s", cause); + goto fail; + } + sx = ll; + } + + if (sx > w->sx) + sx = w->sx; + if (sy > w->sy) + sy = w->sy; + if (lines != PANE_LINES_NONE && (sx < 3 || sy < 3)) + goto out; + if (!cmd_display_menu_get_menu_pos(tc, item, args, &px, &py, sx, sy)) + goto out; + + lg.sx = sx; + lg.sy = sy; + lg.xoff = px; + lg.yoff = py; + if (lines != PANE_LINES_NONE) { + lg.sx -= 2; + lg.sy -= 2; + lg.xoff++; + lg.yoff++; + } + + window_push_modal_zoom(w); + lc = layout_floating_pane(w, wp, &lg); + if (lc == NULL) { + window_pop_modal_zoom(w); + goto out; + } + + sc.item = item; + sc.s = s; + sc.wl = wl; + sc.tc = tc; + sc.wp0 = wp; + sc.lc = lc; + sc.idx = -1; + sc.cwd = args_get(args, 'd'); + sc.flags = flags; + + if (count != 1 || *args_string(args, 0) != '\0') + args_to_vector(args, &sc.argc, &sc.argv); + sc.environ = environ_create(); + av = args_first_value(args, 'e'); + while (av != NULL) { + environ_put(sc.environ, av->string, 0); + av = args_next_value(av); + } + + new_wp = spawn_pane(&sc, &cause); + if (new_wp == NULL) { + cmdq_error(item, "create pane failed: %s", cause); + free(cause); + cause = NULL; + window_pop_modal_zoom(w); + goto fail; + } + + options_set_number(new_wp->options, "pane-border-lines", lines); + if (args_has(args, 'E') > 1) + options_set_number(new_wp->options, "remain-on-exit", 2); + else if (args_has(args, 'E')) + options_set_number(new_wp->options, "remain-on-exit", 0); + else + options_set_number(new_wp->options, "remain-on-exit", 3); + + if (style != NULL) { + if (options_set_string(new_wp->options, "window-style", 0, + "%s", style) == NULL) { + cmdq_error(item, "bad style: %s", style); + goto fail; + } + options_set_string(new_wp->options, "window-active-style", 0, + "%s", style); + new_wp->flags |= (PANE_REDRAW|PANE_STYLECHANGED| + PANE_THEMECHANGED); + } + if (border_style != NULL) { + if (options_set_string(new_wp->options, "pane-border-style", 0, + "%s", border_style) == NULL) { + cmdq_error(item, "bad border style: %s", border_style); + goto fail; + } + options_set_string(new_wp->options, "pane-active-border-style", + 0, "%s", border_style); + } if (args_has(args, 'T')) title = format_single_from_target(item, args_get(args, 'T')); - else - title = xstrdup(""); - - if (args_has(args, 'N') || !modify) - flags = 0; - if (args_has(args, 'E') > 1) { - if (flags == -1) - flags = 0; - flags |= POPUP_CLOSEEXITZERO; - } else if (args_has(args, 'E')) { - if (flags == -1) - flags = 0; - flags |= POPUP_CLOSEEXIT; - } - if (args_has(args, 'k')) { - if (flags == -1) - flags = 0; - flags |= POPUP_CLOSEANYKEY; + if (title != NULL) { + screen_set_title(&new_wp->base, title, 0); + ep = event_payload_create(); + cmd_find_from_pane(&fs, new_wp, 0); + event_payload_set_target(ep, &fs); + event_payload_set_pane(ep, "pane", new_wp); + event_payload_set_window(ep, "window", new_wp->window); + event_payload_set_string(ep, "new_title", "%s", title); + events_fire("pane-title-changed", ep); } - if (modify) { - popup_modify(tc, title, style, border_style, lines, flags); - goto out; - } - if (popup_display(flags, lines, item, px, py, w, h, env, shellcmd, argc, - argv, cwd, title, tc, s, style, border_style, NULL, NULL) != 0) - goto out; - environ_free(env); - free(cwd); + cmd_find_from_winlink_pane(&fs, wl, new_wp, 0); + cmdq_insert_hook(s, item, &fs, "after-split-window"); + + new_wp->wait_item = item; + server_redraw_session(s); + if (sc.argv != NULL) + cmd_free_argv(sc.argc, sc.argv); + environ_free(sc.environ); free(title); - cmd_free_argv(argc, argv); return (CMD_RETURN_WAIT); out: - cmd_free_argv(argc, argv); - environ_free(env); - free(cwd); + if (sc.argv != NULL) + cmd_free_argv(sc.argc, sc.argv); + environ_free(sc.environ); free(title); return (CMD_RETURN_NORMAL); fail: free(cause); - cmd_free_argv(argc, argv); - environ_free(env); - free(cwd); + if (new_wp != NULL) { + server_client_remove_pane(new_wp); + layout_close_pane(new_wp); + window_remove_pane(new_wp->window, new_wp); + } + if (sc.argv != NULL) + cmd_free_argv(sc.argc, sc.argv); + environ_free(sc.environ); free(title); return (CMD_RETURN_ERROR); } diff --git a/options-table.c b/options-table.c index d0a175b9f..2a8156e72 100644 --- a/options-table.c +++ b/options-table.c @@ -78,7 +78,7 @@ static const char *options_table_pane_border_indicators_list[] = { static const char *options_table_pane_border_lines_list[] = { "single", "double", "heavy", "simple", "number", "spaces", "none", NULL }; -static const char *options_table_popup_border_lines_list[] = { +static const char *options_table_box_lines_list[] = { "single", "double", "heavy", "simple", "rounded", "padded", "none", NULL }; static const char *options_table_set_clipboard_list[] = { @@ -482,7 +482,7 @@ const struct options_table_entry options_table[] = { { .name = "menu-border-lines", .type = OPTIONS_TABLE_CHOICE, .scope = OPTIONS_TABLE_WINDOW, - .choices = options_table_popup_border_lines_list, + .choices = options_table_box_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." @@ -1644,33 +1644,6 @@ const struct options_table_entry options_table[] = { .text = "Pane scrollbar position." }, - { .name = "popup-style", - .type = OPTIONS_TABLE_STRING, - .scope = OPTIONS_TABLE_WINDOW, - .default_str = "bg=themedarkgrey,fg=themewhite", - .flags = OPTIONS_TABLE_IS_STYLE, - .separator = ",", - .text = "Default style of popups." - }, - - { .name = "popup-border-style", - .type = OPTIONS_TABLE_STRING, - .scope = OPTIONS_TABLE_WINDOW, - .default_str = "bg=themedarkgrey,fg=themelightgrey", - .flags = OPTIONS_TABLE_IS_STYLE, - .separator = ",", - .text = "Default style of popup borders." - }, - - { .name = "popup-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 popup border lines. Some of " - "these are only supported on terminals with UTF-8 support." - }, - { .name = "remain-on-exit", .type = OPTIONS_TABLE_CHOICE, .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE, diff --git a/popup.c b/popup.c deleted file mode 100644 index 3bc7eafa6..000000000 --- a/popup.c +++ /dev/null @@ -1,660 +0,0 @@ -/* $OpenBSD: popup.c,v 1.76 2026/07/14 19:07:03 nicm Exp $ */ - -/* - * Copyright (c) 2020 Nicholas Marriott - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include - -#include -#include -#include -#include - -#include "tmux.h" - -struct popup_data { - struct client *c; - struct cmdq_item *item; - int flags; - char *title; - - char *style; - char *border_style; - struct grid_cell border_cell; - enum box_lines border_lines; - - struct screen s; - struct grid_cell defaults; - struct colour_palette palette; - - struct visible_ranges r; - - struct job *job; - struct input_ctx *ictx; - int status; - popup_close_cb cb; - void *arg; - - int close; - - /* Current position and size. */ - u_int px; - u_int py; - u_int sx; - u_int sy; - - /* Preferred position and size. */ - u_int ppx; - u_int ppy; - u_int psx; - u_int psy; - - enum { OFF, MOVE, SIZE } dragging; - u_int dx; - u_int dy; - - u_int lx; - u_int ly; - u_int lb; -}; - -static void -popup_free(struct popup_data *pd) -{ - server_client_unref(pd->c); - - if (pd->job != NULL) - job_free(pd->job); - input_free(pd->ictx); - - free(pd->r.ranges); - screen_free(&pd->s); - colour_palette_free(&pd->palette); - - free(pd->title); - free(pd->style); - free(pd->border_style); - free(pd); -} - -static void -popup_reapply_styles(struct popup_data *pd) -{ - struct client *c = pd->c; - struct session *s = c->session; - struct options *o; - struct format_tree *ft; - struct style sytmp; - - if (s == NULL) - return; - o = s->curw->window->options; - - ft = format_create_defaults(NULL, c, s, s->curw, NULL); - - /* Reapply popup style from options. */ - memcpy(&pd->defaults, &grid_default_cell, sizeof pd->defaults); - style_apply(&pd->defaults, o, "popup-style", ft); - if (pd->style != NULL) { - style_set(&sytmp, &grid_default_cell); - if (style_parse(&sytmp, &pd->defaults, pd->style) == 0) { - pd->defaults.fg = sytmp.gc.fg; - pd->defaults.bg = sytmp.gc.bg; - } - } - pd->defaults.attr = 0; - - /* Reapply border style from options. */ - memcpy(&pd->border_cell, &grid_default_cell, sizeof pd->border_cell); - style_apply(&pd->border_cell, o, "popup-border-style", ft); - if (pd->border_style != NULL) { - style_set(&sytmp, &grid_default_cell); - if (style_parse(&sytmp, &pd->border_cell, - pd->border_style) == 0) { - pd->border_cell.fg = sytmp.gc.fg; - pd->border_cell.bg = sytmp.gc.bg; - } - } - pd->border_cell.attr = 0; - - format_free(ft); -} - -static void -popup_redraw_cb(const struct tty_ctx *ttyctx) -{ - struct popup_data *pd = ttyctx->arg; - - pd->c->flags |= CLIENT_REDRAWOVERLAY; -} - -static int -popup_set_client_cb(struct tty_ctx *ttyctx, struct client *c) -{ - struct popup_data *pd = ttyctx->arg; - - if (c != pd->c) - return (0); - if (pd->c->flags & CLIENT_REDRAWOVERLAY) - return (0); - - ttyctx->wox = 0; - ttyctx->woy = 0; - ttyctx->wsx = c->tty.sx; - ttyctx->wsy = c->tty.sy; - - if (pd->border_lines == BOX_LINES_NONE) { - ttyctx->xoff = ttyctx->rxoff = pd->px; - ttyctx->yoff = ttyctx->ryoff = pd->py; - } else { - ttyctx->xoff = ttyctx->rxoff = pd->px + 1; - ttyctx->yoff = ttyctx->ryoff = pd->py + 1; - } - - return (1); -} - -static void -popup_init_ctx_cb(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx) -{ - struct popup_data *pd = ctx->arg; - - memcpy(&ttyctx->defaults, &pd->defaults, sizeof ttyctx->defaults); - ttyctx->flags &= ~TTY_CTX_WINDOW_BIGGER; - ttyctx->style_ctx.defaults = &ttyctx->defaults; - ttyctx->style_ctx.palette = &pd->palette; - ttyctx->redraw_cb = popup_redraw_cb; - ttyctx->set_client_cb = popup_set_client_cb; - ttyctx->arg = pd; -} - -static struct screen * -popup_mode_cb(__unused struct client *c, void *data, u_int *cx, u_int *cy) -{ - struct popup_data *pd = data; - - if (pd->border_lines == BOX_LINES_NONE) { - *cx = pd->px + pd->s.cx; - *cy = pd->py + pd->s.cy; - } else { - *cx = pd->px + 1 + pd->s.cx; - *cy = pd->py + 1 + pd->s.cy; - } - return (&pd->s); -} - -/* Return parts of the input range which are not obstructed by the popup. */ -static struct visible_ranges * -popup_check_cb(__unused struct client* c, void *data, u_int px, u_int py, - u_int nx) -{ - struct popup_data *pd = data; - struct visible_ranges *r = &pd->r; - - server_client_overlay_range(pd->px, pd->py, pd->sx, pd->sy, px, py, nx, - r); - return (r); -} - -static void -popup_draw_cb(struct client *c, void *data) -{ - struct popup_data *pd = data; - struct tty *tty = &c->tty; - struct screen s; - struct screen_write_ctx ctx; - u_int i, px = pd->px, py = pd->py; - struct grid_cell defaults; - struct tty_style_ctx style_ctx; - - popup_reapply_styles(pd); - - screen_init(&s, pd->sx, pd->sy, 0); - if (pd->s.hyperlinks != NULL) { - hyperlinks_free(s.hyperlinks); - s.hyperlinks = hyperlinks_copy(pd->s.hyperlinks); - } - screen_write_start(&ctx, &s); - screen_write_clearscreen(&ctx, 8); - - if (pd->border_lines == BOX_LINES_NONE) { - screen_write_cursormove(&ctx, 0, 0, 0); - screen_write_fast_copy(&ctx, &pd->s, 0, 0, pd->sx, pd->sy); - } else if (pd->sx > 2 && pd->sy > 2) { - screen_write_box(&ctx, pd->sx, pd->sy, pd->border_lines, - &pd->border_cell, pd->title); - screen_write_cursormove(&ctx, 1, 1, 0); - screen_write_fast_copy(&ctx, &pd->s, 0, 0, pd->sx - 2, - pd->sy - 2); - } - screen_write_stop(&ctx); - - memcpy(&defaults, &pd->defaults, sizeof defaults); - if (defaults.fg == 8) - defaults.fg = pd->palette.fg; - if (defaults.bg == 8) - defaults.bg = pd->palette.bg; - style_ctx.defaults = &defaults; - style_ctx.palette = &pd->palette; - style_ctx.dim = 0; - style_ctx.hyperlinks = s.hyperlinks; - - c->overlay_check = NULL; - c->overlay_data = NULL; - for (i = 0; i < pd->sy; i++) - tty_draw_line(tty, &s, 0, i, pd->sx, px, py + i, &style_ctx); - screen_free(&s); - c->overlay_check = popup_check_cb; - c->overlay_data = pd; -} - -static void -popup_free_cb(__unused struct client *c, void *data) -{ - struct popup_data *pd = data; - struct cmdq_item *item = pd->item; - - if (pd->cb != NULL) - pd->cb(pd->status, pd->arg); - - if (item != NULL) { - if (cmdq_get_client(item) != NULL && - cmdq_get_client(item)->session == NULL) - cmdq_get_client(item)->retval = pd->status; - cmdq_continue(item); - } - - popup_free(pd); -} - -static void -popup_resize_cb(__unused struct client *c, void *data) -{ - struct popup_data *pd = data; - struct tty *tty = &c->tty; - - if (pd == NULL) - return; - - /* Adjust position and size. */ - if (pd->psy > tty->sy) - pd->sy = tty->sy; - else - pd->sy = pd->psy; - if (pd->psx > tty->sx) - pd->sx = tty->sx; - else - pd->sx = pd->psx; - if (pd->ppy + pd->sy > tty->sy) - pd->py = tty->sy - pd->sy; - else - pd->py = pd->ppy; - if (pd->ppx + pd->sx > tty->sx) - pd->px = tty->sx - pd->sx; - else - pd->px = pd->ppx; - - /* Avoid zero size screens. */ - if (pd->border_lines == BOX_LINES_NONE) { - screen_resize(&pd->s, pd->sx, pd->sy, 0); - if (pd->job != NULL) - job_resize(pd->job, pd->sx, pd->sy ); - } else if (pd->sx > 2 && pd->sy > 2) { - screen_resize(&pd->s, pd->sx - 2, pd->sy - 2, 0); - if (pd->job != NULL) - job_resize(pd->job, pd->sx - 2, pd->sy - 2); - } -} - -static void -popup_handle_drag(struct client *c, struct popup_data *pd, - struct mouse_event *m) -{ - u_int px, py; - - if (!MOUSE_DRAG(m->b)) - pd->dragging = OFF; - else if (pd->dragging == MOVE) { - if (m->x < pd->dx) - px = 0; - else if (m->x - pd->dx + pd->sx > c->tty.sx) - px = c->tty.sx - pd->sx; - else - px = m->x - pd->dx; - if (m->y < pd->dy) - py = 0; - else if (m->y - pd->dy + pd->sy > c->tty.sy) - py = c->tty.sy - pd->sy; - else - py = m->y - pd->dy; - pd->px = px; - pd->py = py; - pd->dx = m->x - pd->px; - pd->dy = m->y - pd->py; - pd->ppx = px; - pd->ppy = py; - server_redraw_client(c); - } else if (pd->dragging == SIZE) { - if (pd->border_lines == BOX_LINES_NONE) { - if (m->x < pd->px + 1) - return; - if (m->y < pd->py + 1) - return; - } else { - if (m->x < pd->px + 3) - return; - if (m->y < pd->py + 3) - return; - } - pd->sx = m->x - pd->px; - pd->sy = m->y - pd->py; - pd->psx = pd->sx; - pd->psy = pd->sy; - - if (pd->border_lines == BOX_LINES_NONE) { - screen_resize(&pd->s, pd->sx, pd->sy, 0); - if (pd->job != NULL) - job_resize(pd->job, pd->sx, pd->sy); - } else { - screen_resize(&pd->s, pd->sx - 2, pd->sy - 2, 0); - if (pd->job != NULL) - job_resize(pd->job, pd->sx - 2, pd->sy - 2); - } - server_redraw_client(c); - } -} - -static int -popup_key_cb(struct client *c, void *data, struct key_event *event) -{ - struct popup_data *pd = data; - struct mouse_event *m = &event->m; - const char *buf; - size_t len; - u_int px, py; - enum { NONE, LEFT, RIGHT, TOP, BOTTOM } border = NONE; - - if (KEYC_IS_MOUSE(event->key)) { - if (pd->dragging != OFF) { - popup_handle_drag(c, pd, m); - goto out; - } - if (m->x < pd->px || - m->x > pd->px + pd->sx - 1 || - m->y < pd->py || - m->y > pd->py + pd->sy - 1) { - return (0); - } - if (pd->border_lines != BOX_LINES_NONE) { - if (m->x == pd->px) - border = LEFT; - else if (m->x == pd->px + pd->sx - 1) - border = RIGHT; - else if (m->y == pd->py) - border = TOP; - else if (m->y == pd->py + pd->sy - 1) - border = BOTTOM; - } - if ((m->b & MOUSE_MASK_MODIFIERS) == 0 && - MOUSE_BUTTONS(m->b) == MOUSE_BUTTON_3 && - (border == LEFT || border == TOP)) - goto out; - if (((m->b & MOUSE_MASK_MODIFIERS) == MOUSE_MASK_META) || - (border != NONE && !MOUSE_DRAG(m->lb))) { - if (!MOUSE_DRAG(m->b)) - goto out; - if (MOUSE_BUTTONS(m->lb) == MOUSE_BUTTON_1) - pd->dragging = MOVE; - else if (MOUSE_BUTTONS(m->lb) == MOUSE_BUTTON_3) - pd->dragging = SIZE; - pd->dx = m->lx - pd->px; - pd->dy = m->ly - pd->py; - goto out; - } - } - if ((((pd->flags & (POPUP_CLOSEEXIT|POPUP_CLOSEEXITZERO)) == 0) || - pd->job == NULL) && - (event->key == '\033' || event->key == ('c'|KEYC_CTRL))) - return (1); - if (pd->job == NULL && (pd->flags & POPUP_CLOSEANYKEY) && - !KEYC_IS_MOUSE(event->key) && !KEYC_IS_PASTE(event->key)) - return (1); - if (pd->job != NULL) { - if (KEYC_IS_MOUSE(event->key)) { - /* Must be inside, checked already. */ - if (pd->border_lines == BOX_LINES_NONE) { - px = m->x - pd->px; - py = m->y - pd->py; - } else { - px = m->x - pd->px - 1; - py = m->y - pd->py - 1; - } - if (!input_key_get_mouse(&pd->s, m, px, py, &buf, &len)) - return (0); - bufferevent_write(job_get_event(pd->job), buf, len); - return (0); - } - input_key(&pd->s, job_get_event(pd->job), event->key); - } - return (0); - -out: - pd->lx = m->x; - pd->ly = m->y; - pd->lb = m->b; - return (0); -} - -static void -popup_job_update_cb(struct job *job) -{ - struct popup_data *pd = job_get_data(job); - struct evbuffer *evb = job_get_event(job)->input; - struct client *c = pd->c; - struct screen *s = &pd->s; - void *data = EVBUFFER_DATA(evb); - size_t size = EVBUFFER_LENGTH(evb); - - if (size == 0) - return; - - c->overlay_check = NULL; - c->overlay_data = NULL; - input_parse_screen(pd->ictx, s, popup_init_ctx_cb, pd, data, size); - c->overlay_check = popup_check_cb; - c->overlay_data = pd; - - evbuffer_drain(evb, size); -} - -static void -popup_job_complete_cb(struct job *job) -{ - struct popup_data *pd = job_get_data(job); - int status; - - status = job_get_status(pd->job); - if (WIFEXITED(status)) - pd->status = WEXITSTATUS(status); - else if (WIFSIGNALED(status)) - pd->status = WTERMSIG(status); - else - pd->status = 0; - pd->job = NULL; - - if ((pd->flags & POPUP_CLOSEEXIT) || - ((pd->flags & POPUP_CLOSEEXITZERO) && pd->status == 0)) - server_client_clear_overlay(pd->c); -} - -int -popup_present(struct client *c) -{ - return (c->overlay_draw == popup_draw_cb); -} - -int -popup_modify(struct client *c, const char *title, const char *style, - const char *border_style, enum box_lines lines, int flags) -{ - struct popup_data *pd = c->overlay_data; - struct style sytmp; - - if (title != NULL) { - if (pd->title != NULL) - free(pd->title); - pd->title = xstrdup(title); - } - if (border_style != NULL) { - free(pd->border_style); - pd->border_style = xstrdup(border_style); - style_set(&sytmp, &pd->border_cell); - if (style_parse(&sytmp, &pd->border_cell, border_style) == 0) { - pd->border_cell.fg = sytmp.gc.fg; - pd->border_cell.bg = sytmp.gc.bg; - } - } - if (style != NULL) { - free(pd->style); - pd->style = xstrdup(style); - style_set(&sytmp, &pd->defaults); - if (style_parse(&sytmp, &pd->defaults, style) == 0) { - pd->defaults.fg = sytmp.gc.fg; - pd->defaults.bg = sytmp.gc.bg; - } - } - if (lines != BOX_LINES_DEFAULT) { - if (lines == BOX_LINES_NONE && pd->border_lines != lines) { - screen_resize(&pd->s, pd->sx, pd->sy, 1); - job_resize(pd->job, pd->sx, pd->sy); - } else if (pd->border_lines == BOX_LINES_NONE && - pd->border_lines != lines) { - screen_resize(&pd->s, pd->sx - 2, pd->sy - 2, 1); - job_resize(pd->job, pd->sx - 2, pd->sy - 2); - } - pd->border_lines = lines; - tty_resize(&c->tty); - } - if (flags != -1) - pd->flags = flags; - - server_redraw_client(c); - return (0); -} - -int -popup_display(int flags, enum box_lines lines, struct cmdq_item *item, u_int px, - u_int py, u_int sx, u_int sy, struct environ *env, const char *shellcmd, - int argc, char **argv, const char *cwd, const char *title, struct client *c, - struct session *s, const char *style, const char *border_style, - popup_close_cb cb, void *arg) -{ - struct popup_data *pd; - u_int jx, jy; - struct options *o; - struct style sytmp; - - if (s != NULL) - o = s->curw->window->options; - else - o = c->session->curw->window->options; - - if (lines == BOX_LINES_DEFAULT) - lines = options_get_number(o, "popup-border-lines"); - if (lines == BOX_LINES_NONE) { - if (sx < 1 || sy < 1) - return (-1); - jx = sx; - jy = sy; - } else { - if (sx < 3 || sy < 3) - return (-1); - jx = sx - 2; - jy = sy - 2; - } - if (c->tty.sx < sx || c->tty.sy < sy) - return (-1); - - pd = xcalloc(1, sizeof *pd); - pd->item = item; - pd->flags = flags; - - if (title != NULL) - pd->title = xstrdup(title); - if (style != NULL) - pd->style = xstrdup(style); - if (border_style != NULL) - pd->border_style = xstrdup(border_style); - - pd->c = c; - pd->c->references++; - - pd->cb = cb; - pd->arg = arg; - pd->status = 128 + SIGHUP; - - pd->border_lines = lines; - memcpy(&pd->border_cell, &grid_default_cell, sizeof pd->border_cell); - style_apply(&pd->border_cell, o, "popup-border-style", NULL); - if (border_style != NULL) { - style_set(&sytmp, &grid_default_cell); - if (style_parse(&sytmp, &pd->border_cell, border_style) == 0) { - pd->border_cell.fg = sytmp.gc.fg; - pd->border_cell.bg = sytmp.gc.bg; - } - } - pd->border_cell.attr = 0; - - screen_init(&pd->s, jx, jy, 0); - screen_set_default_cursor(&pd->s, global_w_options); - colour_palette_init(&pd->palette); - colour_palette_from_option(&pd->palette, global_w_options); - - memcpy(&pd->defaults, &grid_default_cell, sizeof pd->defaults); - style_apply(&pd->defaults, o, "popup-style", NULL); - if (style != NULL) { - style_set(&sytmp, &grid_default_cell); - if (style_parse(&sytmp, &pd->defaults, style) == 0) { - pd->defaults.fg = sytmp.gc.fg; - pd->defaults.bg = sytmp.gc.bg; - } - } - pd->defaults.attr = 0; - - pd->px = px; - pd->py = py; - pd->sx = sx; - pd->sy = sy; - - pd->ppx = px; - pd->ppy = py; - pd->psx = sx; - pd->psy = sy; - - pd->job = job_run(shellcmd, argc, argv, env, s, cwd, - popup_job_update_cb, popup_job_complete_cb, NULL, pd, - JOB_NOWAIT|JOB_PTY|JOB_KEEPWRITE|JOB_DEFAULTSHELL, jx, jy); - if (pd->job == NULL) { - popup_free(pd); - return (-1); - } - pd->ictx = input_init(NULL, job_get_event(pd->job), &pd->palette, c); - - server_client_set_overlay(c, 0, popup_check_cb, popup_mode_cb, - popup_draw_cb, popup_key_cb, popup_free_cb, popup_resize_cb, pd); - return (0); -} diff --git a/regress/screen-redraw-popups.sh b/regress/screen-redraw-popups.sh deleted file mode 100644 index 26e0f7175..000000000 --- a/regress/screen-redraw-popups.sh +++ /dev/null @@ -1,101 +0,0 @@ -#!/bin/sh - -# Exercise drawing of popups (display-popup) over the window scene. A popup is an -# overlay drawn on top of the redraw scene (the overlay_draw path in -# screen-redraw.c), so this guards against regressions in how popups appear. -# -# A popup is modal and stays open until its command exits, so each scene fully -# re-creates the servers and re-attaches; the popup is opened in the background -# (display-popup blocks the client that runs it) and the outer pane is captured -# while it is open. -# -# Run with GENERATE=1 to (re)create the golden files. - -PATH=/bin:/usr/bin -TERM=screen -LC_ALL=C.UTF-8 -export TERM LC_ALL - -[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux) -TMUX= -TMUX2= -SETUP=0 -RESULTS=screen-redraw-results - -TMP=$(mktemp) - -cleanup() { - rm -f "$TMP" - [ -n "$TMUX" ] && $TMUX kill-server 2>/dev/null - [ -n "$TMUX2" ] && $TMUX2 kill-server 2>/dev/null -} -trap cleanup 0 1 15 - -fail() { - echo "$*" >&2 - exit 1 -} - -compare() { - sleep 1 - $TMUX capturep -p >$TMP || exit 1 - if [ -n "$GENERATE" ]; then - cp $TMP "$RESULTS/$1.result" || exit 1 - echo "generated $1" - else - cmp -s $TMP "$RESULTS/$1.result" || \ - fail "scene $1 differs from $RESULTS/$1.result" - fi -} - -C="sh -c 'i=0; while [ \$i -lt 13 ]; do printf \"POP%02d abcdefghij\n\" \$i; i=\$((i + 1)); done; exec sleep 100'" - -# setup: fresh inner window attached inside a fresh outer pane, 40x14. -setup() { - [ -n "$TMUX" ] && $TMUX kill-server 2>/dev/null - [ -n "$TMUX2" ] && $TMUX2 kill-server 2>/dev/null - SETUP=$((SETUP + 1)) - TMUX="$TEST_TMUX -LtestA$$-$SETUP -f/dev/null" - TMUX2="$TEST_TMUX -LtestB$$-$SETUP -f/dev/null" - $TMUX2 new -d -x40 -y14 "$C" || exit 1 - $TMUX2 set -g status off || exit 1 - $TMUX2 set -g window-size manual || exit 1 - $TMUX2 resizew -x40 -y14 || exit 1 - $TMUX new -d -x40 -y14 || exit 1 - $TMUX set -g status off || exit 1 - $TMUX set -g window-size manual || exit 1 - $TMUX set -g default-terminal "tmux-256color" || exit 1 - $TMUX send -l "$TMUX2 attach" || exit 1 - $TMUX send Enter || exit 1 - sleep 1 -} - -# popup : open a popup running a fixed command, in the background (it stays -# open because the command sleeps; the servers are killed at the next setup). -popup() { - $TMUX2 display-popup "$@" -E "sh -c 'printf POPUP; exec sleep 100'" & - sleep 1 -} - -# Basic popup over a single pane. -setup -popup -w20 -h6 -x6 -y3 -compare popup-basic - -# Popup over a split: drawn on top of the pane border. -setup -$TMUX2 splitw -h "$C" || exit 1 -popup -w24 -h8 -x8 -y3 -compare popup-over-split - -# Popup with no border lines (-B). -setup -popup -B -w20 -h6 -x6 -y3 -compare popup-noborder - -# Popup with double border lines. -setup -popup -b double -w20 -h6 -x6 -y3 -compare popup-double - -exit 0 diff --git a/regress/screen-redraw-results/popup-basic.result b/regress/screen-redraw-results/popup-basic.result deleted file mode 100644 index 7b05d3a61..000000000 --- a/regress/screen-redraw-results/popup-basic.result +++ /dev/null @@ -1,14 +0,0 @@ -POP00 ┌──────────────────┐ -POP01 │POPUP │ -POP02 │ │ -POP03 │ │ -POP04 │ │ -POP05 └──────────────────┘ -POP06 abcdefghij -POP07 abcdefghij -POP08 abcdefghij -POP09 abcdefghij -POP10 abcdefghij -POP11 abcdefghij -POP12 abcdefghij - diff --git a/regress/screen-redraw-results/popup-double.result b/regress/screen-redraw-results/popup-double.result deleted file mode 100644 index 70b38c8c3..000000000 --- a/regress/screen-redraw-results/popup-double.result +++ /dev/null @@ -1,14 +0,0 @@ -POP00 ╔══════════════════╗ -POP01 ║POPUP ║ -POP02 ║ ║ -POP03 ║ ║ -POP04 ║ ║ -POP05 ╚══════════════════╝ -POP06 abcdefghij -POP07 abcdefghij -POP08 abcdefghij -POP09 abcdefghij -POP10 abcdefghij -POP11 abcdefghij -POP12 abcdefghij - diff --git a/regress/screen-redraw-results/popup-noborder.result b/regress/screen-redraw-results/popup-noborder.result deleted file mode 100644 index fc641e781..000000000 --- a/regress/screen-redraw-results/popup-noborder.result +++ /dev/null @@ -1,14 +0,0 @@ -POP00 POPUP -POP01 -POP02 -POP03 -POP04 -POP05 -POP06 abcdefghij -POP07 abcdefghij -POP08 abcdefghij -POP09 abcdefghij -POP10 abcdefghij -POP11 abcdefghij -POP12 abcdefghij - diff --git a/regress/screen-redraw-results/popup-over-split.result b/regress/screen-redraw-results/popup-over-split.result deleted file mode 100644 index 558efc92e..000000000 --- a/regress/screen-redraw-results/popup-over-split.result +++ /dev/null @@ -1,14 +0,0 @@ -POP00 ab┌──────────────────────┐fghij -POP01 ab│POPUP │fghij -POP02 ab│ │fghij -POP03 ab│ │fghij -POP04 ab│ │fghij -POP05 ab│ │fghij -POP06 ab│ │fghij -POP07 ab└──────────────────────┘fghij -POP08 abcdefghij │POP08 abcdefghij -POP09 abcdefghij │POP09 abcdefghij -POP10 abcdefghij │POP10 abcdefghij -POP11 abcdefghij │POP11 abcdefghij -POP12 abcdefghij │POP12 abcdefghij - │ diff --git a/screen-redraw.c b/screen-redraw.c index 454c5df6c..d025b004d 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -33,7 +33,7 @@ * this is done at various points, such as when a pane is moved or resized. The * scene only includes the part of the client used for the window: panes, pane * status lines, borders, scrollbars, and any area outside the window. The - * client status line and overlay are not included. + * client status line is not included. * * A scene is made from spans. A span is a horizontal run of cells on one * visible line that can be drawn in the same way. Each span has a type, for @@ -93,7 +93,6 @@ enum redraw_span_type { #define REDRAW_PANE_SCROLLBAR 0x20 #define REDRAW_STATUS 0x40 #define REDRAW_MENU 0x80 -#define REDRAW_OVERLAY 0x100 /* Draw everything. */ #define REDRAW_ALL 0x7fffffff @@ -264,8 +263,6 @@ redraw_flags_to_string(int flags) strlcat(s, "scrollbar ", sizeof s); if (flags & REDRAW_MENU) strlcat(s, "menu ", sizeof s); - if (flags & REDRAW_OVERLAY) - strlcat(s, "overlay ", sizeof s); if (REDRAW_IS_ALL(flags)) strlcat(s, "all ", sizeof s); if (*s != '\0') @@ -1373,42 +1370,28 @@ redraw_draw_span(struct redraw_draw_ctx *dctx, struct redraw_span *span, struct redraw_scene *scene = dctx->scene; struct redraw_span_data *data = &span->data; enum redraw_span_type type = data->type; - struct client *c = scene->c; - struct tty *tty = &c->tty; - struct visible_ranges *r; - struct visible_range *rr; - u_int i, x, n; if (type == REDRAW_SPAN_STATUS && ~data->st.wp->flags & PANE_NEWSTATUS) return; - r = tty_check_overlay_range(tty, span->x, y, span->width); - for (i = 0; i < r->used; i++) { - rr = &r->ranges[i]; - if (rr->nx == 0) - continue; - x = rr->px; - n = rr->nx; - - switch (span->data.type) { - case REDRAW_SPAN_PANE: - redraw_draw_pane_span(dctx, span, x, y, n); - break; - case REDRAW_SPAN_BORDER: - case REDRAW_SPAN_EMPTY: - case REDRAW_SPAN_OUTSIDE: - redraw_draw_border_span(dctx, span, x, y, n); - break; - case REDRAW_SPAN_STATUS: - redraw_draw_status_span(dctx, span, x, y, n); - break; - case REDRAW_SPAN_SCROLLBAR: - redraw_draw_scrollbar_span(dctx, span, x, y, n); - break; - case REDRAW_SPAN_MENU: - redraw_draw_menu_span(dctx, span, x, y, n); - break; - } + switch (span->data.type) { + case REDRAW_SPAN_PANE: + redraw_draw_pane_span(dctx, span, span->x, y, span->width); + break; + case REDRAW_SPAN_BORDER: + case REDRAW_SPAN_EMPTY: + case REDRAW_SPAN_OUTSIDE: + redraw_draw_border_span(dctx, span, span->x, y, span->width); + break; + case REDRAW_SPAN_STATUS: + redraw_draw_status_span(dctx, span, span->x, y, span->width); + break; + case REDRAW_SPAN_SCROLLBAR: + redraw_draw_scrollbar_span(dctx, span, span->x, y, span->width); + break; + case REDRAW_SPAN_MENU: + redraw_draw_menu_span(dctx, span, span->x, y, span->width); + break; } } @@ -1677,10 +1660,8 @@ redraw_draw(struct client *c, struct window_pane *wp, int flags) struct screen *sl; struct redraw_scene *scene; struct window_pane *loop; - u_int width, i, y, lines, j; + u_int width, i, y, lines; struct redraw_span *first; - struct visible_ranges *r; - struct visible_range *rr; int redraw; if (c->flags & CLIENT_SUSPENDED) @@ -1789,19 +1770,9 @@ redraw_draw(struct client *c, struct window_pane *wp, int flags) else y = c->tty.sy - lines; sl = c->status.active; - for (i = 0; i < lines; i++) { - r = tty_check_overlay_range(tty, 0, y + i, tty->sx); - for (j = 0; j < r->used; j++) { - rr = &r->ranges[j]; - if (rr->nx == 0) - continue; - tty_draw_line(tty, sl, rr->px, i, rr->nx, - rr->px, y + i, NULL); - } - } + for (i = 0; i < lines; i++) + tty_draw_line(tty, sl, 0, i, tty->sx, 0, y + i, NULL); } - if (c->overlay_draw != NULL && (flags & REDRAW_OVERLAY)) - c->overlay_draw(c, c->overlay_data); tty_reset(tty); tty_sync_end(tty); @@ -1865,8 +1836,6 @@ redraw_screen(struct client *c) flags |= (REDRAW_PANE_BORDER|REDRAW_PANE_STATUS); if (c->flags & CLIENT_REDRAWSTATUS) flags |= (REDRAW_STATUS|REDRAW_PANE_STATUS); - if (c->flags & CLIENT_REDRAWOVERLAY) - flags |= REDRAW_OVERLAY; if (c->flags & CLIENT_REDRAWMENU) flags |= REDRAW_MENU; if (c->session->curw->window->menu != NULL) diff --git a/screen-write.c b/screen-write.c index a311296e7..fd783e38f 100644 --- a/screen-write.c +++ b/screen-write.c @@ -305,19 +305,14 @@ screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx, if (~ctx->flags & SCREEN_WRITE_SYNC) { /* - * For the active pane or for an overlay (no pane), we want to - * only use synchronized updates if requested (commands that - * move the cursor); for other panes, always use it, since the - * cursor will have to move. + * For the active pane, only use synchronized updates if + * requested (commands that move the cursor); for other panes, + * always use it, since the cursor will have to move. */ if (ctx->wp != NULL && ctx->wp != ctx->wp->window->active) ttyctx->flags |= TTY_CTX_SYNC; - else { - if (ctx->wp == NULL) - ttyctx->flags |= TTY_CTX_OVERLAY_SYNC; - if (is_sync) - ttyctx->flags |= TTY_CTX_SYNC; - } + else if (is_sync) + ttyctx->flags |= TTY_CTX_SYNC; tty_write(tty_cmd_syncstart, ttyctx); ctx->flags |= SCREEN_WRITE_SYNC; } @@ -704,7 +699,7 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src, if (!window_position_is_visible(r, xoff + s->cx)) break; ttyctx.cell = &gc; - ttyctx.flags &= (TTY_CTX_OVERLAY_SYNC|TTY_CTX_SYNC); + ttyctx.flags &= TTY_CTX_SYNC; tty_write(tty_cmd_cell, &ttyctx); ttyctx.ocx++; diff --git a/server-client.c b/server-client.c index 5b071215e..31eb46a42 100644 --- a/server-client.c +++ b/server-client.c @@ -78,77 +78,6 @@ server_client_how_many(void) return (n); } -/* Overlay timer callback. */ -static void -server_client_overlay_timer(__unused int fd, __unused short events, void *data) -{ - server_client_clear_overlay(data); -} - -/* Set an overlay on client. */ -void -server_client_set_overlay(struct client *c, u_int delay, - overlay_check_cb checkcb, overlay_mode_cb modecb, - overlay_draw_cb drawcb, overlay_key_cb keycb, overlay_free_cb freecb, - overlay_resize_cb resizecb, void *data) -{ - struct timeval tv; - - if (c->overlay_draw != NULL) - server_client_clear_overlay(c); - - tv.tv_sec = delay / 1000; - tv.tv_usec = (delay % 1000) * 1000L; - - if (event_initialized(&c->overlay_timer)) - evtimer_del(&c->overlay_timer); - evtimer_set(&c->overlay_timer, server_client_overlay_timer, c); - if (delay != 0) - evtimer_add(&c->overlay_timer, &tv); - - c->overlay_check = checkcb; - c->overlay_mode = modecb; - c->overlay_draw = drawcb; - c->overlay_key = keycb; - c->overlay_free = freecb; - c->overlay_resize = resizecb; - c->overlay_data = data; - - if (c->overlay_check == NULL) - c->tty.flags |= TTY_FREEZE; - if (c->overlay_mode == NULL) - c->tty.flags |= TTY_NOCURSOR; - window_update_focus(c->session->curw->window); - server_redraw_client(c); -} - -/* Clear overlay mode on client. */ -void -server_client_clear_overlay(struct client *c) -{ - if (c->overlay_draw == NULL) - return; - - if (event_initialized(&c->overlay_timer)) - evtimer_del(&c->overlay_timer); - - if (c->overlay_free != NULL) - c->overlay_free(c, c->overlay_data); - - c->overlay_check = NULL; - c->overlay_mode = NULL; - c->overlay_draw = NULL; - c->overlay_key = NULL; - c->overlay_free = NULL; - c->overlay_resize = NULL; - c->overlay_data = NULL; - - c->tty.flags &= ~(TTY_FREEZE|TTY_NOCURSOR); - if (c->session != NULL) - window_update_focus(c->session->curw->window); - server_redraw_client(c); -} - /* Are these ranges empty? That is, nothing is visible. */ int server_client_ranges_is_empty(struct visible_ranges *r) @@ -172,52 +101,6 @@ server_client_ensure_ranges(struct visible_ranges *r, u_int n) r->size = n; } -/* - * Given overlay position and dimensions, return parts of the input range which - * are visible. - */ -void -server_client_overlay_range(u_int x, u_int y, u_int sx, u_int sy, u_int px, - u_int py, u_int nx, struct visible_ranges *r) -{ - u_int ox, onx; - - /* Trivial case of no overlap in the y direction. */ - if (py < y || py > y + sy - 1) { - server_client_ensure_ranges(r, 1); - r->ranges[0].px = px; - r->ranges[0].nx = nx; - r->used = 1; - return; - } - server_client_ensure_ranges(r, 2); - - /* Visible bit to the left of the popup. */ - if (px < x) { - r->ranges[0].px = px; - r->ranges[0].nx = x - px; - if (r->ranges[0].nx > nx) - r->ranges[0].nx = nx; - } else { - r->ranges[0].px = 0; - r->ranges[0].nx = 0; - } - - /* Visible bit to the right of the popup. */ - ox = x + sx; - if (px > ox) - ox = px; - onx = px + nx; - if (onx > ox) { - r->ranges[1].px = ox; - r->ranges[1].nx = onx - ox; - } else { - r->ranges[1].px = 0; - r->ranges[1].nx = 0; - } - r->used = 2; -} - /* Check if this client is inside this server. */ int server_client_check_nested(struct client *c) @@ -500,7 +383,6 @@ server_client_lost(struct client *c) c->flags |= CLIENT_DEAD; - server_client_clear_overlay(c); status_prompt_clear(c); status_message_clear(c); @@ -1724,10 +1606,6 @@ server_client_handle_key0(struct client *c, struct key_event *event, if (s == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS)) return (0); - /* - * Handle theme reporting keys before overlays so they work even when a - * popup is open. - */ if (event->key == KEYC_REPORT_LIGHT_THEME) { server_client_report_theme(c, THEME_LIGHT); return (0); @@ -1738,9 +1616,9 @@ server_client_handle_key0(struct client *c, struct key_event *event, } /* - * Key presses in overlay mode and the command prompt are a special - * case. The queue might be blocked so they need to be processed - * immediately rather than queued. + * Key presses in the command prompt are a special case. The queue might + * be blocked so they need to be processed immediately rather than + * queued. */ if (~c->flags & CLIENT_READONLY) { if (c->message_string != NULL) { @@ -1749,17 +1627,6 @@ server_client_handle_key0(struct client *c, struct key_event *event, status_message_clear(c); } - if (c->overlay_key != NULL) { - switch (c->overlay_key(c, c->overlay_data, event)) { - case 0: - return (0); - case 1: - server_client_clear_overlay(c); - return (0); - } - } - - server_client_clear_overlay(c); if (server_client_handle_menu_key(c, event)) return (0); if (c->prompt != NULL) { @@ -2133,11 +2000,8 @@ server_client_reset_state(struct client *c) flags = (tty->flags & TTY_BLOCK); tty->flags &= ~TTY_BLOCK; - /* Get mode from overlay if any, else from screen. */ - if (c->overlay_draw != NULL) { - if (c->overlay_mode != NULL) - s = c->overlay_mode(c, c->overlay_data, &cx, &cy); - } else if (w->menu != NULL) { + /* Get mode from the menu if any, else from the screen. */ + if (w->menu != NULL) { menu_get_cursor(w->menu, &cx, &cy); s = menu_screen(w->menu); } else if (wp != NULL && c->prompt == NULL) @@ -2159,7 +2023,7 @@ server_client_reset_state(struct client *c) if (c->prompt != NULL) { prompt = 1; status_prompt_cursor(c, &cx, &cy); - } else if (wp != NULL && c->overlay_draw == NULL) { + } else if (wp != NULL) { if (w->menu != NULL) { tty_window_offset(tty, &ox, &oy, &sx, &sy); if (cx < ox || cx >= ox + sx || @@ -2214,7 +2078,7 @@ server_client_reset_state(struct client *c) if ((pane_mode & MODE_SYNC) || !cursor) mode &= ~MODE_CURSOR; } - } else if (c->overlay_mode == NULL || s == NULL) + } else if (s == NULL) mode &= ~MODE_CURSOR; if (~pane_mode & MODE_SYNC) { log_debug("%s: cursor to %u,%u", __func__, cx, cy); @@ -2227,7 +2091,7 @@ server_client_reset_state(struct client *c) * movement events. */ if (options_get_number(oo, "mouse")) { - if (c->overlay_draw == NULL && w->menu == NULL) { + if (w->menu == NULL) { mode &= ~ALL_MOUSE_MODES; TAILQ_FOREACH(loop, &w->panes, entry) { if (loop->screen->mode & MODE_MOUSE_ALL) @@ -2243,7 +2107,7 @@ server_client_reset_state(struct client *c) } /* Clear bracketed paste mode if at the prompt. */ - if (c->overlay_draw == NULL && prompt) + if (prompt) mode &= ~MODE_BRACKETPASTE; /* Set the terminal mode and reset attributes. */ @@ -2406,11 +2270,10 @@ server_client_check_redraw(struct client *c) if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED)) return; if (c->flags & CLIENT_ALLREDRAWFLAGS) { - log_debug("%s: redraw%s%s%s%s%s", c->name, + log_debug("%s: redraw%s%s%s%s", c->name, (c->flags & CLIENT_REDRAWWINDOW) ? " window" : "", (c->flags & CLIENT_REDRAWSTATUS) ? " status" : "", (c->flags & CLIENT_REDRAWBORDERS) ? " borders" : "", - (c->flags & CLIENT_REDRAWOVERLAY) ? " overlay" : "", (c->flags & CLIENT_REDRAWMENU) ? " menu" : ""); } @@ -2610,10 +2473,6 @@ server_client_dispatch(struct imsg *imsg, void *arg) tty_resize(&c->tty); tty_repeat_requests(&c->tty, 0); recalculate_sizes(); - if (c->overlay_resize == NULL) - server_client_clear_overlay(c); - else - c->overlay_resize(c, c->overlay_data); server_redraw_client(c); if (c->session != NULL) server_client_fire_resized(c, old_sx, old_sy); diff --git a/status.c b/status.c index 2f3c8f11e..38bb18e7e 100644 --- a/status.c +++ b/status.c @@ -577,8 +577,6 @@ status_prompt_set(struct client *c, struct cmd_find_state *fs, struct prompt_create_data pd; struct status_prompt_data *spd; - server_client_clear_overlay(c); - status_message_clear(c); status_prompt_clear(c); status_push_screen(c); diff --git a/tmux.1 b/tmux.1 index 15f94cbeb..4b8bc8cf3 100644 --- a/tmux.1 +++ b/tmux.1 @@ -5312,10 +5312,16 @@ section on how to specify .Ar style . .It Ic menu\-border\-lines Ar type Set the type of characters used for drawing menu borders. -See -.Ic popup\-border\-lines -for possible values for -.Ar border\-lines . +.Ar type +may be one of +.Ic single , +.Ic rounded , +.Ic double , +.Ic heavy , +.Ic simple , +.Ic padded , +or +.Ic none . .It Ic message\-command\-style Ar style Set status line message command style. This is used for the command prompt with @@ -5955,48 +5961,6 @@ see the section. Attributes are ignored. .Pp -.It Ic popup\-style Ar style -Set the popup style. -See the -.Sx STYLES -section on how to specify -.Ar style . -Attributes are ignored. -.Pp -.It Ic popup\-border\-style Ar style -Set the popup border style. -See the -.Sx STYLES -section on how to specify -.Ar style . -Attributes are ignored. -.Pp -.It Ic popup\-border\-lines Ar type -Set the type of characters used for drawing popup borders. -.Ar type -may be one of: -.Bl -tag -width Ds -.It single -single lines using ACS or UTF\-8 characters (default) -.It rounded -variation of single with rounded corners using UTF\-8 characters -.It double -double lines using UTF\-8 characters -.It heavy -heavy lines using UTF\-8 characters -.It simple -simple ASCII characters -.It padded -simple ASCII space character -.It none -no border -.El -.Pp -.Ql double -and -.Ql heavy -will fall back to standard ACS line drawing when UTF\-8 is not supported. -.Pp .It Xo Ic pane\-scrollbars .Op Ic off | modal | on | auto\-hide .Xc @@ -8078,10 +8042,16 @@ command should be omitted. .Pp .Fl b sets the type of characters used for drawing menu borders. -See -.Ic popup\-border\-lines -for possible values for -.Ar border\-lines . +.Ar border\-lines +may be one of +.Ic single , +.Ic rounded , +.Ic double , +.Ic heavy , +.Ic simple , +.Ic padded , +or +.Ic none . .Pp .Fl H sets the style for the selected menu item (see @@ -8117,29 +8087,7 @@ Both may be a row or column number, or one of the following special values: .It Li "S" Ta Fl y Ta "The line above or below the status line" .El .Pp -Or a format, which is expanded including the following additional variables: -.Bl -column "XXXXXXXXXXXXXXXXXXXXXXXXXX" -offset indent -.It Sy "Variable name" Ta Sy "Replaced with" -.It Li "popup_centre_x" Ta "Centered in the client" -.It Li "popup_centre_y" Ta "Centered in the client" -.It Li "popup_height" Ta "Height of menu or popup" -.It Li "popup_last_x" Ta "Left of the last menu" -.It Li "popup_last_y" Ta "Bottom of the last menu" -.It Li "popup_mouse_bottom" Ta "Bottom of at the mouse" -.It Li "popup_mouse_centre_x" Ta "Horizontal centre at the mouse" -.It Li "popup_mouse_centre_y" Ta "Vertical centre at the mouse" -.It Li "popup_mouse_top" Ta "Top at the mouse" -.It Li "popup_mouse_x" Ta "Mouse X position" -.It Li "popup_mouse_y" Ta "Mouse Y position" -.It Li "popup_pane_bottom" Ta "Bottom of the pane" -.It Li "popup_pane_left" Ta "Left of the pane" -.It Li "popup_pane_right" Ta "Right of the pane" -.It Li "popup_pane_top" Ta "Top of the pane" -.It Li "popup_status_line_y" Ta "Above or below the status line" -.It Li "popup_width" Ta "Width of menu or popup" -.It Li "popup_window_status_line_x" Ta "At the window position in status line" -.It Li "popup_window_status_line_y" Ta "At the status line showing the window" -.El +Or a format. .Pp Each menu consists of items followed by a key shortcut shown in brackets. If the menu is too large to fit on the terminal, it is not displayed. @@ -8216,116 +8164,6 @@ lists the format variables and their values. .Fl I forwards any input read from stdin to the empty pane given by .Ar target\-pane . -.Tg popup -.It Xo Ic display\-popup -.Op Fl BCEkN -.Op Fl b Ar border\-lines -.Op Fl c Ar target\-client -.Op Fl d Ar start\-directory -.Op Fl e Ar environment -.Op Fl h Ar height -.Op Fl s Ar style -.Op Fl S Ar border\-style -.Op Fl t Ar target\-pane -.Op Fl T Ar title -.Op Fl w Ar width -.Op Fl x Ar position -.Op Fl y Ar position -.Op Ar shell\-command Op Ar argument ... -.Xc -.D1 Pq alias: Ic popup -Display a popup running -.Ar shell\-command -(or -.Ar default\-command -when omitted) on -.Ar target\-client . -A popup is a rectangular box drawn over the top of any panes. -If the command is run inside an existing popup, that popup is modified. -Only the -.Fl b , -.Fl B , -.Fl C , -.Fl E , -.Fl EE , -.Fl K , -.Fl N , -.Fl s , -and -.Fl S -options are accepted in this case; -all others are ignored. -.Pp -.Fl E -closes the popup automatically when -.Ar shell\-command -exits. -Two -.Fl E -closes the popup only if -.Ar shell\-command -exited with success. -.Fl k -allows any key to dismiss the popup instead of only -.Ql Escape -or -.Ql C\-c . -.Pp -.Fl x -and -.Fl y -give the position of the popup, they have the same meaning as for the -.Ic display\-menu -command. -.Fl w -and -.Fl h -give the width and height - both may be a percentage (followed by -.Ql % ) . -If omitted, half of the terminal size is used. -.Pp -.Fl B -does not surround the popup by a border. -.Pp -.Fl b -sets the type of characters used for drawing popup borders. -When -.Fl B -is specified, the -.Fl b -option is ignored. -See -.Ic popup\-border\-lines -for possible values for -.Ar border\-lines . -.Pp -.Fl s -sets the style for the popup and -.Fl S -sets the style for the popup border (see -.Sx STYLES ) . -.Pp -.Fl e -takes the form -.Ql VARIABLE=value -and sets an environment variable for the popup; it may be specified multiple -times. -.Pp -.Fl T -is a format for the popup title (see -.Sx FORMATS ) . -.Pp -The -.Fl C -flag closes any popup on the client. -.Pp -.Fl N -disables any previously specified -.Fl E , -.Fl EE , -or -.Fl k -option. .Tg showphist .It Xo Ic show\-prompt\-history .Op Fl T Ar prompt\-type diff --git a/tmux.h b/tmux.h index 88ad4d419..4fddc72df 100644 --- a/tmux.h +++ b/tmux.h @@ -1825,7 +1825,6 @@ struct tty_ctx { #define TTY_CTX_INVISIBLE_PANES 0x2 #define TTY_CTX_WINDOW_BIGGER 0x4 #define TTY_CTX_SYNC 0x8 -#define TTY_CTX_OVERLAY_SYNC 0x10 #define TTY_CTX_CELL_INVALIDATE 0x20 #define TTY_CTX_PANE_OBSCURED 0x40 @@ -2172,16 +2171,6 @@ struct prompt_draw_data { u_int prompt_line; }; -/* Overlay callbacks */ -typedef struct visible_ranges *(*overlay_check_cb)(struct client *, void *, - u_int, u_int, u_int); -typedef struct screen *(*overlay_mode_cb)(struct client *, void *, u_int *, - u_int *); -typedef void (*overlay_draw_cb)(struct client *, void *); -typedef int (*overlay_key_cb)(struct client *, void *, struct key_event *); -typedef void (*overlay_free_cb)(struct client *, void *); -typedef void (*overlay_resize_cb)(struct client *, void *); - /* Client connection. */ struct client { const char *name; @@ -2265,7 +2254,7 @@ struct client { #define CLIENT_SIZECHANGED 0x400000 #define CLIENT_STATUSOFF 0x800000 #define CLIENT_REDRAWSTATUSALWAYS 0x1000000 -#define CLIENT_REDRAWOVERLAY 0x2000000 +/* 0x2000000 unused */ #define CLIENT_CONTROL_NOOUTPUT 0x4000000 #define CLIENT_DEFAULTSOCKET 0x8000000 #define CLIENT_STARTSERVER 0x10000000 @@ -2285,7 +2274,6 @@ struct client { CLIENT_REDRAWSTATUS| \ CLIENT_REDRAWSTATUSALWAYS| \ CLIENT_REDRAWBORDERS| \ - CLIENT_REDRAWOVERLAY| \ CLIENT_REDRAWMENU) #define CLIENT_UNATTACHEDFLAGS \ (CLIENT_DEAD| \ @@ -2331,15 +2319,6 @@ struct client { u_int pan_ox; u_int pan_oy; - overlay_check_cb overlay_check; - overlay_mode_cb overlay_mode; - overlay_draw_cb overlay_draw; - overlay_key_cb overlay_key; - overlay_free_cb overlay_free; - overlay_resize_cb overlay_resize; - void *overlay_data; - struct event overlay_timer; - struct client_files files; u_int source_file_depth; @@ -2933,8 +2912,6 @@ void tty_default_attributes(struct tty *, u_int, void tty_update_mode(struct tty *, int, struct screen *); const struct grid_cell *tty_check_codeset(struct tty *, const struct grid_cell *); -struct visible_ranges *tty_check_overlay_range(struct tty *, u_int, u_int, - u_int); void tty_sync_start(struct tty *); void tty_sync_end(struct tty *); int tty_open(struct tty *, char **); @@ -3284,14 +3261,8 @@ int server_create_socket(uint64_t, char **); /* server-client.c */ RB_PROTOTYPE(client_windows, client_window, entry, server_client_window_cmp); u_int server_client_how_many(void); -void server_client_set_overlay(struct client *, u_int, overlay_check_cb, - overlay_mode_cb, overlay_draw_cb, overlay_key_cb, - overlay_free_cb, overlay_resize_cb, void *); -void server_client_clear_overlay(struct client *); void server_client_ensure_ranges(struct visible_ranges *, u_int); int server_client_ranges_is_empty(struct visible_ranges *); -void server_client_overlay_range(u_int, u_int, u_int, u_int, u_int, u_int, - u_int, struct visible_ranges *); void server_client_set_key_table(struct client *, const char *); const char *server_client_get_key_table(struct client *); int server_client_check_nested(struct client *); @@ -4143,20 +4114,6 @@ void menu_get_cursor(struct menu_data *, u_int *, u_int *); void menu_resize(struct menu_data *, struct window *); int menu_key(struct client *, struct menu_data *, struct key_event *); -/* popup.c */ -#define POPUP_CLOSEEXIT 0x1 -#define POPUP_CLOSEEXITZERO 0x2 -#define POPUP_CLOSEANYKEY 0x4 -typedef void (*popup_close_cb)(int, void *); -int popup_display(int, enum box_lines, struct cmdq_item *, u_int, - u_int, u_int, u_int, struct environ *, const char *, int, - char **, const char *, const char *, struct client *, - struct session *, const char *, const char *, - popup_close_cb, void *); -int popup_present(struct client *); -int popup_modify(struct client *, const char *, const char *, - const char *, enum box_lines, int); - /* style.c */ int style_parse(struct style *,const struct grid_cell *, const char *); diff --git a/tty-draw.c b/tty-draw.c index d47be66bc..3d2fd7ed9 100644 --- a/tty-draw.c +++ b/tty-draw.c @@ -52,8 +52,7 @@ tty_draw_line_clear(struct tty *tty, u_int px, u_int py, u_int nx, return; /* If genuine BCE is available, can try escape sequences. */ - if (tty->client->overlay_check == NULL && - !wrapped && + if (!wrapped && nx >= 10 && !tty_fake_bce(tty, defaults, bg)) { /* Off the end of the line, use EL if available. */ diff --git a/tty.c b/tty.c index a0d212732..d41118614 100644 --- a/tty.c +++ b/tty.c @@ -66,7 +66,6 @@ static void tty_redraw_region(struct tty *, const struct tty_ctx *); static void tty_emulate_repeat(struct tty *, enum tty_code_code, enum tty_code_code, u_int); static void tty_draw_pane(struct tty *, const struct tty_ctx *, u_int); -static int tty_check_overlay(struct tty *, u_int, u_int); #ifdef ENABLE_SIXEL static void tty_write_one(void (*)(struct tty *, const struct tty_ctx *), @@ -1183,9 +1182,6 @@ tty_clear_line(struct tty *tty, const struct grid_cell *defaults, u_int py, u_int px, u_int nx, u_int bg) { struct client *c = tty->client; - struct visible_ranges *r; - struct visible_range *rr; - u_int i; log_debug("%s: %s, %u at %u,%u", __func__, c->name, nx, px, py); @@ -1194,7 +1190,7 @@ tty_clear_line(struct tty *tty, const struct grid_cell *defaults, u_int py, return; /* If genuine BCE is available, can try escape sequences. */ - if (c->overlay_check == NULL && !tty_fake_bce(tty, defaults, bg)) { + if (!tty_fake_bce(tty, defaults, bg)) { /* Off the end of the line, use EL if available. */ if (px + nx >= tty->sx && tty_term_has(tty->term, TTYC_EL)) { tty_cursor(tty, px, py); @@ -1217,18 +1213,9 @@ tty_clear_line(struct tty *tty, const struct grid_cell *defaults, u_int py, } } - /* - * Couldn't use an escape sequence, use spaces. Clear only the visible - * bit if there is an overlay. - */ - r = tty_check_overlay_range(tty, px, py, nx); - for (i = 0; i < r->used; i++) { - rr = &r->ranges[i]; - if (rr->nx != 0) { - tty_cursor(tty, rr->px, py); - tty_repeat_space(tty, rr->nx); - } - } + /* Couldn't use an escape sequence, use spaces. */ + tty_cursor(tty, px, py); + tty_repeat_space(tty, nx); } /* Clear a line, adjusting to visible part of pane. */ @@ -1237,22 +1224,12 @@ tty_clear_pane_line(struct tty *tty, const struct tty_ctx *ctx, u_int py, u_int px, u_int nx, u_int bg) { struct client *c = tty->client; - struct visible_ranges *r; - struct visible_range *ri; - u_int i, l, x, rx, ry; + u_int l, x, rx, ry; log_debug("%s: %s, %u at %u,%u", __func__, c->name, nx, px, py); - if (tty_clamp_line(tty, ctx, px, py, nx, &l, &x, &rx, &ry)) { - r = tty_check_overlay_range(tty, x, ry, rx); - for (i = 0; i < r->used; i++) { - ri = &r->ranges[i]; - if (ri->nx == 0) - continue; - tty_clear_line(tty, &ctx->defaults, ry, ri->px, ri->nx, - bg); - } - } + if (tty_clamp_line(tty, ctx, px, py, nx, &l, &x, &rx, &ry)) + tty_clear_line(tty, &ctx->defaults, ry, x, rx, bg); } /* Clamp area position to visible part of pane. */ @@ -1333,11 +1310,8 @@ tty_clear_area(struct tty *tty, const struct tty_ctx *ctx, u_int py, if (nx == 0 || ny == 0) return; - /* - * If there is an overlay or BCE is not available, cannot clear as a - * region. - */ - if (c->overlay_check == NULL && !tty_fake_bce(tty, defaults, bg)) { + /* If BCE is available, can try to clear as a region. */ + if (!tty_fake_bce(tty, defaults, bg)) { /* Use ED if clearing off the bottom of the terminal. */ if (px == 0 && px + nx >= tty->sx && @@ -1409,53 +1383,28 @@ static void tty_draw_pane(struct tty *tty, const struct tty_ctx *ctx, u_int py) { struct screen *s = ctx->s; - u_int nx = ctx->sx, i, x, rx, ry, j; - struct visible_ranges *r; - struct visible_range *rr; + u_int nx = ctx->sx, i, x, rx, ry; log_debug("%s: %s %u", __func__, tty->client->name, py); if (~ctx->flags & TTY_CTX_WINDOW_BIGGER) { - r = tty_check_overlay_range(tty, ctx->xoff, ctx->yoff + py, nx); - for (j = 0; j < r->used; j++) { - rr = &r->ranges[j]; - if (rr->nx == 0) - continue; - tty_draw_line(tty, s, rr->px - ctx->xoff, py, rr->nx, - rr->px, ctx->yoff + py, &ctx->style_ctx); - } + tty_draw_line(tty, s, 0, py, nx, ctx->xoff, ctx->yoff + py, + &ctx->style_ctx); return; } - if (tty_clamp_line(tty, ctx, 0, py, nx, &i, &x, &rx, &ry)) { - r = tty_check_overlay_range(tty, x, ry, rx); - for (j = 0; j < r->used; j++) { - rr = &r->ranges[j]; - if (rr->nx == 0) - continue; - tty_draw_line(tty, s, i + rr->px - x, py, rr->nx, - rr->px, ry, &ctx->style_ctx); - } - } + if (tty_clamp_line(tty, ctx, 0, py, nx, &i, &x, &rx, &ry)) + tty_draw_line(tty, s, i, py, rx, x, ry, &ctx->style_ctx); } void tty_cmd_redrawline(struct tty *tty, const struct tty_ctx *ctx) { - u_int i, x, rx, ry, j; - struct visible_ranges *r; - struct visible_range *rr; + u_int i, x, rx, ry; if (tty_clamp_line(tty, ctx, ctx->ocx, ctx->ocy, ctx->n, - &i, &x, &rx, &ry)) { - r = tty_check_overlay_range(tty, x, ry, rx); - for (j = 0; j < r->used; j++) { - rr = &r->ranges[j]; - if (rr->nx == 0) - continue; - tty_draw_line(tty, ctx->s, ctx->ocx + i + rr->px - x, - ctx->ocy, rr->nx, rr->px, ry, &ctx->style_ctx); - } - } + &i, &x, &rx, &ry)) + tty_draw_line(tty, ctx->s, ctx->ocx + i, ctx->ocy, rx, x, ry, + &ctx->style_ctx); } /* Check if character needs to be mapped for codeset. */ @@ -1492,36 +1441,6 @@ tty_check_codeset(struct tty *tty, const struct grid_cell *gc) return (&new); } -/* Check if a single character is covered by the overlay. */ -static int -tty_check_overlay(struct tty *tty, u_int px, u_int py) -{ - struct visible_ranges *r; - - /* - * With a single character, if there is anything visible (that is, the - * range is not empty), it must be that character. - */ - r = tty_check_overlay_range(tty, px, py, 1); - return (!server_client_ranges_is_empty(r)); -} - -/* Return parts of the input range which are visible. */ -struct visible_ranges * -tty_check_overlay_range(struct tty *tty, u_int px, u_int py, u_int nx) -{ - struct client *c = tty->client; - - if (c->overlay_check == NULL) { - server_client_ensure_ranges(&tty->r, 1); - tty->r.ranges[0].px = px; - tty->r.ranges[0].nx = nx; - tty->r.used = 1; - return (&tty->r); - } - return (c->overlay_check(c, c->overlay_data, px, py, nx)); -} - #ifdef ENABLE_SIXEL /* Update context for client. */ static int @@ -1665,14 +1584,11 @@ tty_write_one(void (*cmdfn)(struct tty *, const struct tty_ctx *), void tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) { - struct client *c = tty->client; - if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) || !tty_full_width(tty, ctx) || tty_fake_bce(tty, &ctx->defaults, ctx->bg) || (!tty_term_has(tty->term, TTYC_ICH) && - !tty_term_has(tty->term, TTYC_ICH1)) || - c->overlay_check != NULL) { + !tty_term_has(tty->term, TTYC_ICH1))) { tty_draw_pane(tty, ctx, ctx->ocy); return; } @@ -1687,14 +1603,11 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) { - struct client *c = tty->client; - if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) || !tty_full_width(tty, ctx) || tty_fake_bce(tty, &ctx->defaults, ctx->bg) || (!tty_term_has(tty->term, TTYC_DCH) && - !tty_term_has(tty->term, TTYC_DCH1)) || - c->overlay_check != NULL) { + !tty_term_has(tty->term, TTYC_DCH1))) { tty_draw_pane(tty, ctx, ctx->ocy); return; } @@ -1717,16 +1630,13 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) { - struct client *c = tty->client; - if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) || !tty_full_width(tty, ctx) || tty_fake_bce(tty, &ctx->defaults, ctx->bg) || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_IL1) || ctx->sx == 1 || - ctx->sy == 1 || - c->overlay_check != NULL) { + ctx->sy == 1) { tty_redraw_region(tty, ctx); return; } @@ -1744,16 +1654,13 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx) { - struct client *c = tty->client; - if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) || !tty_full_width(tty, ctx) || tty_fake_bce(tty, &ctx->defaults, ctx->bg) || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_DL1) || ctx->sx == 1 || - ctx->sy == 1 || - c->overlay_check != NULL) { + ctx->sy == 1) { tty_redraw_region(tty, ctx); return; } @@ -1797,8 +1704,6 @@ tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx) { - struct client *c = tty->client; - if (ctx->ocy != ctx->orupper) return; @@ -1809,8 +1714,7 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx) (!tty_term_has(tty->term, TTYC_RI) && !tty_term_has(tty->term, TTYC_RIN)) || ctx->sx == 1 || - ctx->sy == 1 || - c->overlay_check != NULL) { + ctx->sy == 1) { tty_redraw_region(tty, ctx); return; } @@ -1830,8 +1734,6 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) { - struct client *c = tty->client; - if (ctx->ocy != ctx->orlower) return; @@ -1840,8 +1742,7 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) tty_fake_bce(tty, &ctx->defaults, 8) || !tty_term_has(tty->term, TTYC_CSR) || ctx->sx == 1 || - ctx->sy == 1 || - c->overlay_check != NULL) { + ctx->sy == 1) { tty_redraw_region(tty, ctx); return; } @@ -1872,7 +1773,6 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_scrollup(struct tty *tty, const struct tty_ctx *ctx) { - struct client *c = tty->client; u_int i; if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) || @@ -1880,8 +1780,7 @@ tty_cmd_scrollup(struct tty *tty, const struct tty_ctx *ctx) tty_fake_bce(tty, &ctx->defaults, 8) || !tty_term_has(tty->term, TTYC_CSR) || ctx->sx == 1 || - ctx->sy == 1 || - c->overlay_check != NULL) { + ctx->sy == 1) { tty_redraw_region(tty, ctx); return; } @@ -1911,7 +1810,6 @@ void tty_cmd_scrolldown(struct tty *tty, const struct tty_ctx *ctx) { u_int i; - struct client *c = tty->client; if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) || (!tty_full_width(tty, ctx) && !tty_use_margin(tty)) || @@ -1920,8 +1818,7 @@ tty_cmd_scrolldown(struct tty *tty, const struct tty_ctx *ctx) (!tty_term_has(tty->term, TTYC_RI) && !tty_term_has(tty->term, TTYC_RIN)) || ctx->sx == 1 || - ctx->sy == 1 || - c->overlay_check != NULL) { + ctx->sy == 1) { tty_redraw_region(tty, ctx); return; } @@ -2009,11 +1906,9 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx) { - struct client *c = tty->client; u_int i, j; - if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) || - c->overlay_check != NULL) { + if (ctx->flags & TTY_CTX_WINDOW_BIGGER) { ctx->redraw_cb(ctx); return; } @@ -2033,29 +1928,9 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) { - const struct grid_cell *gcp = ctx->cell; - struct screen *s = ctx->s; - struct visible_ranges *r; - u_int px, py, i, vis = 0; - - px = ctx->xoff + ctx->ocx - ctx->wox; - py = ctx->yoff + ctx->ocy - ctx->woy; if (!tty_is_visible(tty, ctx, ctx->ocx, ctx->ocy, 1, 1)) return; - if (gcp->data.width == 1 && !tty_check_overlay(tty, px, py)) - return; - if (gcp->data.width > 1) { /* could be partially obscured */ - r = tty_check_overlay_range(tty, px, py, gcp->data.width); - for (i = 0; i < r->used; i++) - vis += r->ranges[i].nx; - if (vis < gcp->data.width) { - tty_draw_line(tty, s, s->cx, s->cy, gcp->data.width, - px, py, &ctx->style_ctx); - return; - } - } - if (ctx->xoff + ctx->ocx - ctx->wox > tty->sx - 1 && ctx->ocy == ctx->orlower && tty_full_width(tty, ctx)) @@ -2075,9 +1950,6 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx) { - struct visible_ranges *r; - struct visible_range *ri; - u_int i, px, py, cx; const char *cp = ctx->data.data; size_t n = ctx->data.size; @@ -2103,20 +1975,7 @@ tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx) tty_margin_off(tty); tty_cursor_pane_unless_wrap(tty, ctx, ctx->ocx, ctx->ocy); tty_attributes(tty, ctx->cell, &ctx->style_ctx); - - /* Get tty position from pane position for overlay check. */ - px = ctx->xoff + ctx->ocx - ctx->wox; - py = ctx->yoff + ctx->ocy - ctx->woy; - - r = tty_check_overlay_range(tty, px, py, n); - for (i = 0; i < r->used; i++) { - ri = &r->ranges[i]; - if (ri->nx != 0) { - cx = ri->px - ctx->xoff + ctx->wox; - tty_cursor_pane_unless_wrap(tty, ctx, cx, ctx->ocy); - tty_putn(tty, cp + ri->px - px, ri->nx, ri->nx); - } - } + tty_putn(tty, cp, n, n); } void @@ -2210,23 +2069,8 @@ tty_cmd_sixelimage(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_syncstart(struct tty *tty, const struct tty_ctx *ctx) { - struct client *c = tty->client; - - if ((ctx->flags & TTY_CTX_OVERLAY_SYNC) && - (ctx->flags & TTY_CTX_SYNC)) { - /* - * This is an overlay and a command that moves the cursor so - * start synchronized updates. - */ + if (ctx->flags & TTY_CTX_SYNC) tty_sync_start(tty); - } else if (~ctx->flags & TTY_CTX_OVERLAY_SYNC) { - /* - * This is a pane. If there is an overlay, always start; - * otherwise, only if requested. - */ - if ((ctx->flags & TTY_CTX_SYNC) || c->overlay_draw != NULL) - tty_sync_start(tty); - } } void @@ -2245,10 +2089,6 @@ tty_cell(struct tty *tty, const struct grid_cell *gc, if (gc->flags & GRID_FLAG_PADDING) return; - /* Check if character is covered by overlay or floating pane. */ - if (!tty_check_overlay(tty, tty->cx, tty->cy)) - return; - /* Check the output codeset and apply attributes. */ gcp = tty_check_codeset(tty, gc); tty_attributes(tty, gcp, style_ctx); diff --git a/window.c b/window.c index ff2ff443c..d22717d8f 100644 --- a/window.c +++ b/window.c @@ -686,7 +686,6 @@ window_pane_update_focus(struct window_pane *wp) c->session->attached != 0 && (c->flags & CLIENT_FOCUSED) && c->session->curw->window == wp->window && - c->overlay_draw == NULL && wp->window->menu == NULL) { focused = 1; break;