diff options
-rw-r--r-- | CHANGES | 2 | ||||
-rw-r--r-- | cmd-refresh-client.c | 4 | ||||
-rw-r--r-- | cmd-resize-pane.c | 56 | ||||
-rw-r--r-- | cmd-send-keys.c | 2 | ||||
-rw-r--r-- | cmd-set-option.c | 60 | ||||
-rw-r--r-- | cmd-show-options.c | 17 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | environ.c | 10 | ||||
-rw-r--r-- | key-bindings.c | 17 | ||||
-rw-r--r-- | resize.c | 3 | ||||
-rw-r--r-- | server-client.c | 2 | ||||
-rw-r--r-- | tmux.1 | 7 | ||||
-rw-r--r-- | tmux.h | 7 | ||||
-rw-r--r-- | tty.c | 239 |
14 files changed, 237 insertions, 191 deletions
@@ -8,7 +8,7 @@ CHANGES FROM 2.4 to 2.5 09 May 2017 * Add pane_mode format. * Differentiate M-Up from Escape+Up when possible (that is, in terminals with - xterm(1) style functions keys). GitHub issue 907. + xterm(1) style function keys). GitHub issue 907. * Add session_stack and window_stack_index formats. diff --git a/cmd-refresh-client.c b/cmd-refresh-client.c index 5190df89..6af3362b 100644 --- a/cmd-refresh-client.c +++ b/cmd-refresh-client.c @@ -67,8 +67,10 @@ cmd_refresh_client_exec(struct cmd *self, struct cmdq_item *item) cmdq_error(item, "not a control client"); return (CMD_RETURN_ERROR); } - if (tty_set_size(&c->tty, w, h)) + if (tty_set_size(&c->tty, w, h)) { + c->flags |= CLIENT_SIZECHANGED; recalculate_sizes(); + } } else if (args_has(args, 'S')) { c->flags |= CLIENT_STATUSFORCE; server_status_client(c); diff --git a/cmd-resize-pane.c b/cmd-resize-pane.c index 2ad11c23..bbb78de7 100644 --- a/cmd-resize-pane.c +++ b/cmd-resize-pane.c @@ -129,9 +129,8 @@ static void cmd_resize_pane_mouse_update(struct client *c, struct mouse_event *m) { struct winlink *wl; - struct window_pane *wp; - int found; - u_int y, ly; + struct window_pane *loop, *wp_x, *wp_y; + u_int y, ly, x, lx, sx, sy, ex, ey; wl = cmd_mouse_window(m, NULL); if (wl == NULL) { @@ -139,37 +138,48 @@ cmd_resize_pane_mouse_update(struct client *c, struct mouse_event *m) return; } - y = m->y; + y = m->y; x = m->x; if (m->statusat == 0 && y > 0) y--; else if (m->statusat > 0 && y >= (u_int)m->statusat) y = m->statusat - 1; - ly = m->ly; + ly = m->ly; lx = m->lx; if (m->statusat == 0 && ly > 0) ly--; else if (m->statusat > 0 && ly >= (u_int)m->statusat) ly = m->statusat - 1; - found = 0; - TAILQ_FOREACH(wp, &wl->window->panes, entry) { - if (!window_pane_visible(wp)) + wp_x = wp_y = NULL; + TAILQ_FOREACH(loop, &wl->window->panes, entry) { + if (!window_pane_visible(loop)) continue; - if (wp->xoff + wp->sx == m->lx && - wp->yoff <= 1 + ly && - wp->yoff + wp->sy >= ly) { - layout_resize_pane(wp, LAYOUT_LEFTRIGHT, m->x - m->lx, 0); - found = 1; - } - if (wp->yoff + wp->sy == ly && - wp->xoff <= 1 + m->lx && - wp->xoff + wp->sx >= m->lx) { - layout_resize_pane(wp, LAYOUT_TOPBOTTOM, y - ly, 0); - found = 1; - } + sx = loop->xoff; + if (sx != 0) + sx--; + ex = loop->xoff + loop->sx; + + sy = loop->yoff; + if (sy != 0) + sy--; + ey = loop->yoff + loop->sy; + + if ((lx == sx || lx == ex) && + (ly >= sy && ly <= ey) && + (wp_x == NULL || loop->sy > wp_x->sy)) + wp_x = loop; + if ((ly == sy || ly == ey) && + (lx >= sx && lx <= ex) && + (wp_y == NULL || loop->sx > wp_y->sx)) + wp_y = loop; } - if (found) - server_redraw_window(wl->window); - else + if (wp_x == NULL && wp_y == NULL) { c->tty.mouse_drag_update = NULL; + return; + } + if (wp_x != NULL) + layout_resize_pane(wp_x, LAYOUT_LEFTRIGHT, x - lx, 0); + if (wp_y != NULL) + layout_resize_pane(wp_y, LAYOUT_TOPBOTTOM, y - ly, 0); + server_redraw_window(wl->window); } diff --git a/cmd-send-keys.c b/cmd-send-keys.c index e54574fe..5c6db347 100644 --- a/cmd-send-keys.c +++ b/cmd-send-keys.c @@ -73,7 +73,7 @@ cmd_send_keys_inject(struct client *c, struct cmdq_item *item, key_code key) bd = RB_FIND(key_bindings, &table->key_bindings, &bd_find); if (bd != NULL) { table->references++; - key_bindings_dispatch(bd, c, NULL, &item->target); + key_bindings_dispatch(bd, item, c, NULL, &item->target); key_bindings_unref_table(table); } } diff --git a/cmd-set-option.c b/cmd-set-option.c index b35d60d8..ad058b8e 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -42,8 +42,8 @@ const struct cmd_entry cmd_set_option_entry = { .name = "set-option", .alias = "set", - .args = { "agoqst:uw", 1, 2 }, - .usage = "[-agosquw] [-t target-window] option [value]", + .args = { "aFgoqst:uw", 1, 2 }, + .usage = "[-aFgosquw] [-t target-window] option [value]", .target = { 't', CMD_FIND_WINDOW, CMD_FIND_CANFAIL }, @@ -55,8 +55,8 @@ const struct cmd_entry cmd_set_window_option_entry = { .name = "set-window-option", .alias = "setw", - .args = { "agoqt:u", 1, 2 }, - .usage = "[-agoqu] " CMD_TARGET_WINDOW_USAGE " option [value]", + .args = { "aFgoqt:u", 1, 2 }, + .usage = "[-aFgoqu] " CMD_TARGET_WINDOW_USAGE " option [value]", .target = { 't', CMD_FIND_WINDOW, CMD_FIND_CANFAIL }, @@ -70,33 +70,38 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item) struct args *args = self->args; int append = args_has(args, 'a'); struct cmd_find_state *fs = &item->target; + struct client *c, *loop; struct session *s = fs->s; struct winlink *wl = fs->wl; struct window *w; - struct client *c; enum options_table_scope scope; struct options *oo; struct options_entry *parent, *o; - char *name; - const char *value, *target; + char *name, *argument, *value = NULL, *cause; + const char *target; int window, idx, already, error, ambiguous; - char *cause; + + /* Expand argument. */ + c = cmd_find_client(item, NULL, 1); + argument = format_single(item, args->argv[0], c, s, wl, NULL); /* Parse option name and index. */ - name = options_match(args->argv[0], &idx, &ambiguous); + name = options_match(argument, &idx, &ambiguous); if (name == NULL) { if (args_has(args, 'q')) - return (CMD_RETURN_NORMAL); + goto out; if (ambiguous) - cmdq_error(item, "ambiguous option: %s", args->argv[0]); + cmdq_error(item, "ambiguous option: %s", argument); else - cmdq_error(item, "invalid option: %s", args->argv[0]); - return (CMD_RETURN_ERROR); + cmdq_error(item, "invalid option: %s", argument); + goto fail; } if (args->argc < 2) value = NULL; + else if (args_has(args, 'F')) + value = format_single(item, args->argv[1], c, s, wl, NULL); else - value = args->argv[1]; + value = xstrdup(args->argv[1]); /* * Figure out the scope: for user options it comes from the arguments, @@ -114,12 +119,12 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item) scope = OPTIONS_TABLE_WINDOW; else { scope = OPTIONS_TABLE_NONE; - xasprintf(&cause, "unknown option: %s", args->argv[0]); + xasprintf(&cause, "unknown option: %s", argument); } } if (scope == OPTIONS_TABLE_NONE) { if (args_has(args, 'q')) - return (CMD_RETURN_NORMAL); + goto out; cmdq_error(item, "%s", cause); free(cause); goto fail; @@ -159,7 +164,7 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item) /* Check that array options and indexes match up. */ if (idx != -1) { if (*name == '@' || options_array_size(parent, NULL) == -1) { - cmdq_error(item, "not an array: %s", args->argv[0]); + cmdq_error(item, "not an array: %s", argument); goto fail; } } @@ -176,8 +181,8 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item) } if (already) { if (args_has(args, 'q')) - return (CMD_RETURN_NORMAL); - cmdq_error(item, "already set: %s", args->argv[0]); + goto out; + cmdq_error(item, "already set: %s", argument); goto fail; } } @@ -217,7 +222,7 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item) options_array_clear(o); options_array_assign(o, value); } else if (options_array_set(o, idx, value, append) != 0) { - cmdq_error(item, "invalid index: %s", args->argv[0]); + cmdq_error(item, "invalid index: %s", argument); goto fail; } } @@ -232,8 +237,8 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item) } } if (strcmp(name, "key-table") == 0) { - TAILQ_FOREACH(c, &clients, entry) - server_client_set_key_table(c, NULL); + TAILQ_FOREACH(loop, &clients, entry) + server_client_set_key_table(loop, NULL); } if (strcmp(name, "status") == 0 || strcmp(name, "status-interval") == 0) @@ -257,15 +262,20 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item) * anyway. */ recalculate_sizes(); - TAILQ_FOREACH(c, &clients, entry) { - if (c->session != NULL) - server_redraw_client(c); + TAILQ_FOREACH(loop, &clients, entry) { + if (loop->session != NULL) + server_redraw_client(loop); } +out: + free(argument); + free(value); free(name); return (CMD_RETURN_NORMAL); fail: + free(argument); + free(value); free(name); return (CMD_RETURN_ERROR); } diff --git a/cmd-show-options.c b/cmd-show-options.c index 382dd7fb..2dc3dee3 100644 --- a/cmd-show-options.c +++ b/cmd-show-options.c @@ -127,25 +127,36 @@ cmd_show_options_one(struct cmd *self, struct cmdq_item *item, struct options *oo) { struct args *args = self->args; + struct client *c = cmd_find_client(item, NULL, 1); + struct session *s = item->target.s; + struct winlink *wl = item->target.wl; struct options_entry *o; int idx, ambiguous; - const char *name = args->argv[0]; + char *name; + name = format_single(item, args->argv[0], c, s, wl, NULL); o = options_match_get(oo, name, &idx, 1, &ambiguous); if (o == NULL) { - if (args_has(args, 'q')) + if (args_has(args, 'q')) { + free(name); return (CMD_RETURN_NORMAL); + } if (ambiguous) { cmdq_error(item, "ambiguous option: %s", name); + free(name); return (CMD_RETURN_ERROR); } if (*name != '@' && - options_match_get(oo, name, &idx, 0, &ambiguous) != NULL) + options_match_get(oo, name, &idx, 0, &ambiguous) != NULL) { + free(name); return (CMD_RETURN_NORMAL); + } cmdq_error(item, "unknown option: %s", name); + free(name); return (CMD_RETURN_ERROR); } cmd_show_options_print(self, item, o, idx); + free(name); return (CMD_RETURN_NORMAL); } diff --git a/configure.ac b/configure.ac index f7bb2e9f..14a286b8 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ # configure.ac -AC_INIT(tmux, 2.5-rc) +AC_INIT(tmux, master) AC_PREREQ([2.60]) AC_CONFIG_AUX_DIR(etc) @@ -208,9 +208,15 @@ environ_push(struct environ *env) /* Log the environment. */ void -environ_log(struct environ *env, const char *prefix) +environ_log(struct environ *env, const char *fmt, ...) { struct environ_entry *envent; + va_list ap; + char *prefix; + + va_start(ap, fmt); + vasprintf(&prefix, fmt, ap); + va_end(ap); RB_FOREACH(envent, environ, env) { if (envent->value != NULL && *envent->name != '\0') { @@ -218,6 +224,8 @@ environ_log(struct environ *env, const char *prefix) envent->value); } } + + free(prefix); } /* Create initial environment for new child. */ diff --git a/key-bindings.c b/key-bindings.c index 9e327655..8f56cbee 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -400,11 +400,11 @@ key_bindings_read_only(struct cmdq_item *item, __unused void *data) } void -key_bindings_dispatch(struct key_binding *bd, struct client *c, - struct mouse_event *m, struct cmd_find_state *fs) +key_bindings_dispatch(struct key_binding *bd, struct cmdq_item *item, + struct client *c, struct mouse_event *m, struct cmd_find_state *fs) { struct cmd *cmd; - struct cmdq_item *item; + struct cmdq_item *new_item; int readonly; readonly = 1; @@ -413,11 +413,14 @@ key_bindings_dispatch(struct key_binding *bd, struct client *c, readonly = 0; } if (!readonly && (c->flags & CLIENT_READONLY)) - cmdq_append(c, cmdq_get_callback(key_bindings_read_only, NULL)); + new_item = cmdq_get_callback(key_bindings_read_only, NULL); else { - item = cmdq_get_command(bd->cmdlist, fs, m, 0); + new_item = cmdq_get_command(bd->cmdlist, fs, m, 0); if (bd->flags & KEY_BINDING_REPEAT) - item->shared->flags |= CMDQ_SHARED_REPEAT; - cmdq_append(c, item); + new_item->shared->flags |= CMDQ_SHARED_REPEAT; } + if (item != NULL) + cmdq_insert_after(item, new_item); + else + cmdq_append(c, new_item); } @@ -60,6 +60,9 @@ recalculate_sizes(void) TAILQ_FOREACH(c, &clients, entry) { if (c->flags & CLIENT_SUSPENDED) continue; + if ((c->flags & (CLIENT_CONTROL|CLIENT_SIZECHANGED)) == + CLIENT_CONTROL) + continue; if (c->session == s) { if (c->tty.sx < ssx) ssx = c->tty.sx; diff --git a/server-client.c b/server-client.c index e8a9f757..e5c21dfb 100644 --- a/server-client.c +++ b/server-client.c @@ -945,7 +945,7 @@ retry: server_status_client(c); /* Execute the key binding. */ - key_bindings_dispatch(bd, c, m, &fs); + key_bindings_dispatch(bd, NULL, c, m, &fs); key_bindings_unref_table(table); return; } @@ -2335,7 +2335,7 @@ abc123 Commands which set options are as follows: .Bl -tag -width Ds .It Xo Ic set-option -.Op Fl agoqsuw +.Op Fl aFgoqsuw .Op Fl t Ar target-session | Ar target-window .Ar option Ar value .Xc @@ -2351,6 +2351,8 @@ otherwise a session option. If .Fl g is given, the global session or window option is set. +.Fl F +expands formats in the option value. The .Fl u flag unsets an option, so a session inherits the option from the global @@ -2901,7 +2903,7 @@ The default is .Ql \ -_@ . .El .It Xo Ic set-window-option -.Op Fl agoqu +.Op Fl aFgoqu .Op Fl t Ar target-window .Ar option Ar value .Xc @@ -2909,6 +2911,7 @@ The default is Set a window option. The .Fl a , +.Fl F , .Fl g , .Fl o , .Fl q @@ -1349,6 +1349,7 @@ struct client { #define CLIENT_STATUSFORCE 0x80000 #define CLIENT_DOUBLECLICK 0x100000 #define CLIENT_TRIPLECLICK 0x200000 +#define CLIENT_SIZECHANGED 0x400000 int flags; struct key_table *keytable; @@ -1624,7 +1625,7 @@ void environ_put(struct environ *, const char *); void environ_unset(struct environ *, const char *); void environ_update(struct options *, struct environ *, struct environ *); void environ_push(struct environ *); -void environ_log(struct environ *, const char *); +void printflike(2, 3) environ_log(struct environ *, const char *, ...); struct environ *environ_for_session(struct session *, int); /* tty.c */ @@ -1805,8 +1806,8 @@ void key_bindings_add(const char *, key_code, int, struct cmd_list *); void key_bindings_remove(const char *, key_code); void key_bindings_remove_table(const char *); void key_bindings_init(void); -void key_bindings_dispatch(struct key_binding *, struct client *, - struct mouse_event *, struct cmd_find_state *); +void key_bindings_dispatch(struct key_binding *, struct cmdq_item *, + struct client *, struct mouse_event *, struct cmd_find_state *); /* key-string.c */ key_code key_string_lookup_string(const char *); @@ -754,6 +754,74 @@ tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx) } } +static void +tty_clear_line(struct tty *tty, const struct window_pane *wp, u_int py, + u_int px, u_int nx, u_int bg) +{ + log_debug("%s: %u at %u,%u", __func__, nx, px, py); + + /* Nothing to clear. */ + if (nx == 0) + return; + + /* If genuine BCE is available, can try escape sequences. */ + if (!tty_fake_bce(tty, wp, 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); + tty_putcode(tty, TTYC_EL); + return; + } + + /* At the start of the line. Use EL1. */ + if (px == 0 && tty_term_has(tty->term, TTYC_EL1)) { + tty_cursor(tty, px + nx - 1, py); + tty_putcode(tty, TTYC_EL1); + return; + } + + /* Section of line. Use ECH if possible. */ + if (tty_term_has(tty->term, TTYC_ECH)) { + tty_cursor(tty, px, py); + tty_putcode1(tty, TTYC_ECH, nx); + return; + } + } + + /* Couldn't use an escape sequence, use spaces. */ + tty_cursor(tty, px, py); + tty_repeat_space(tty, nx); +} + +static void +tty_clear_area(struct tty *tty, const struct window_pane *wp, u_int py, + u_int ny, u_int px, u_int nx, u_int bg) +{ + u_int yy; + + log_debug("%s: %u,%u at %u,%u", __func__, nx, ny, px, py); + + /* Nothing to clear. */ + if (nx == 0 || ny == 0) + return; + + /* If genuine BCE is available, can try escape sequences. */ + if (!tty_fake_bce(tty, wp, bg)) { + if (px == 0 && + px + nx >= tty->sx && + py + ny >= tty->sy && + tty_term_has(tty->term, TTYC_ED)) { + tty_cursor(tty, 0, py); + tty_putcode(tty, TTYC_ED); + return; + } + } + + /* Couldn't use an escape sequence, loop over the lines. */ + for (yy = py; yy < py + ny; yy++) + tty_clear_line(tty, wp, yy, px, nx, bg); +} + void tty_draw_pane(struct tty *tty, const struct window_pane *wp, u_int py, u_int ox, u_int oy) @@ -766,7 +834,7 @@ tty_draw_line(struct tty *tty, const struct window_pane *wp, struct screen *s, u_int py, u_int ox, u_int oy) { struct grid_cell gc, last; - u_int i, j, sx, width; + u_int i, j, sx, nx, width; int flags, cleared = 0; char buf[512]; size_t len; @@ -861,16 +929,10 @@ tty_draw_line(struct tty *tty, const struct window_pane *wp, tty_putn(tty, buf, len, width); } - if (!cleared && sx < tty->sx) { + nx = screen_size_x(s) - sx; + if (!cleared && sx < tty->sx && nx != 0) { tty_default_attributes(tty, wp, 8); - tty_cursor(tty, ox + sx, oy + py); - if (sx != screen_size_x(s) && - ox + screen_size_x(s) >= tty->sx && - tty_term_has(tty->term, TTYC_EL) && - !tty_fake_bce(tty, wp, 8)) - tty_putcode(tty, TTYC_EL); - else - tty_repeat_space(tty, screen_size_x(s) - sx); + tty_clear_line(tty, wp, oy + py, ox + sx, nx, 8); } tty->flags = (tty->flags & ~TTY_NOCURSOR) | flags; @@ -1016,56 +1078,36 @@ void tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; - struct screen *s = wp->screen; - u_int sx = screen_size_x(s); + u_int nx, py = ctx->yoff + ctx->ocy; tty_default_attributes(tty, wp, ctx->bg); - tty_cursor_pane(tty, ctx, 0, ctx->ocy); - - if (tty_pane_full_width(tty, ctx) && - !tty_fake_bce(tty, wp, ctx->bg) && - tty_term_has(tty->term, TTYC_EL)) - tty_putcode(tty, TTYC_EL); - else - tty_repeat_space(tty, sx); + nx = screen_size_x(wp->screen); + tty_clear_line(tty, wp, py, ctx->xoff, nx, ctx->bg); } void tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; - struct screen *s = wp->screen; - u_int sx = screen_size_x(s); + u_int nx, py = ctx->yoff + ctx->ocy; tty_default_attributes(tty, wp, ctx->bg); - tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); - - if (tty_pane_full_width(tty, ctx) && - tty_term_has(tty->term, TTYC_EL) && - !tty_fake_bce(tty, wp, ctx->bg)) - tty_putcode(tty, TTYC_EL); - else - tty_repeat_space(tty, sx - ctx->ocx); + nx = screen_size_x(wp->screen) - ctx->ocx; + tty_clear_line(tty, wp, py, ctx->xoff + ctx->ocx, nx, ctx->bg); } void tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; + u_int nx, py = ctx->yoff + ctx->ocy; tty_default_attributes(tty, wp, ctx->bg); - if (ctx->xoff == 0 && - tty_term_has(tty->term, TTYC_EL1) && - !tty_fake_bce(tty, ctx->wp, ctx->bg)) { - tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); - tty_putcode(tty, TTYC_EL1); - } else { - tty_cursor_pane(tty, ctx, 0, ctx->ocy); - tty_repeat_space(tty, ctx->ocx + 1); - } + nx = screen_size_x(wp->screen) - ctx->ocx; + tty_clear_line(tty, wp, py, ctx->xoff, ctx->ocx + 1, ctx->bg); } void @@ -1163,116 +1205,69 @@ void tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; - struct screen *s = wp->screen; - u_int i, j; - u_int sx = screen_size_x(s), sy = screen_size_y(s); + u_int px, py, nx, ny; tty_default_attributes(tty, wp, ctx->bg); - tty_region_pane(tty, ctx, 0, sy - 1); + tty_region_pane(tty, ctx, 0, screen_size_y(wp->screen) - 1); tty_margin_off(tty); - if (tty_pane_full_width(tty, ctx) && - ctx->yoff + wp->sy >= tty->sy - 1 && - status_at_line(tty->client) <= 0 && - tty_term_has(tty->term, TTYC_ED)) { - tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); - tty_putcode(tty, TTYC_ED); - } else if (tty_pane_full_width(tty, ctx) && - tty_term_has(tty->term, TTYC_EL) && - !tty_fake_bce(tty, wp, ctx->bg)) { - tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); - tty_putcode(tty, TTYC_EL); - if (ctx->ocy != sy - 1) { - tty_cursor_pane(tty, ctx, 0, ctx->ocy + 1); - for (i = ctx->ocy + 1; i < sy; i++) { - tty_putcode(tty, TTYC_EL); - if (i == sy - 1) - continue; - tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1); - tty->cy++; - } - } - } else { - tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); - tty_repeat_space(tty, sx - ctx->ocx); - for (j = ctx->ocy + 1; j < sy; j++) { - tty_cursor_pane(tty, ctx, 0, j); - tty_repeat_space(tty, sx); - } - } + px = ctx->xoff; + nx = screen_size_x(wp->screen); + py = ctx->yoff + ctx->ocy + 1; + ny = screen_size_y(wp->screen) - ctx->ocy - 1; + + tty_clear_area(tty, wp, py, ny, px, nx, ctx->bg); + + px = ctx->xoff + ctx->ocx; + nx = screen_size_x(wp->screen) - ctx->ocx; + py = ctx->yoff + ctx->ocy; + + tty_clear_line(tty, wp, py, px, nx, ctx->bg); } void tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; - struct screen *s = wp->screen; - u_int i, j; - u_int sx = screen_size_x(s), sy = screen_size_y(s); + u_int px, py, nx, ny; tty_default_attributes(tty, wp, ctx->bg); - tty_region_pane(tty, ctx, 0, sy - 1); + tty_region_pane(tty, ctx, 0, screen_size_y(wp->screen) - 1); tty_margin_off(tty); - if (tty_pane_full_width(tty, ctx) && - tty_term_has(tty->term, TTYC_EL) && - !tty_fake_bce(tty, wp, ctx->bg)) { - tty_cursor_pane(tty, ctx, 0, 0); - for (i = 0; i < ctx->ocy; i++) { - tty_putcode(tty, TTYC_EL); - tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1); - tty->cy++; - } - } else { - tty_cursor_pane(tty, ctx, 0, 0); - for (j = 0; j < ctx->ocy; j++) { - tty_cursor_pane(tty, ctx, 0, j); - tty_repeat_space(tty, sx); - } - } - tty_cursor_pane(tty, ctx, 0, ctx->ocy); - tty_repeat_space(tty, ctx->ocx + 1); + px = ctx->xoff; + nx = screen_size_x(wp->screen); + py = ctx->yoff; + ny = ctx->ocy - 1; + + tty_clear_area(tty, wp, py, ny, px, nx, ctx->bg); + + px = ctx->xoff; + nx = ctx->ocx + 1; + py = ctx->yoff + ctx->ocy; + + tty_clear_line(tty, wp, py, px, nx, ctx->bg); } void tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; - struct screen *s = wp->screen; - u_int i, j; - u_int sx = screen_size_x(s), sy = screen_size_y(s); + u_int px, py, nx, ny; tty_default_attributes(tty, wp, ctx->bg); - tty_region_pane(tty, ctx, 0, sy - 1); + tty_region_pane(tty, ctx, 0, screen_size_y(wp->screen) - 1); tty_margin_off(tty); - if (tty_pane_full_width(tty, ctx) && - ctx->yoff + wp->sy >= tty->sy - 1 && - status_at_line(tty->client) <= 0 && - tty_term_has(tty->term, TTYC_ED)) { - tty_cursor_pane(tty, ctx, 0, 0); - tty_putcode(tty, TTYC_ED); - } else if (tty_pane_full_width(tty, ctx) && - tty_term_has(tty->term, TTYC_EL) && - !tty_fake_bce(tty, wp, ctx->bg)) { - tty_cursor_pane(tty, ctx, 0, 0); - for (i = 0; i < sy; i++) { - tty_putcode(tty, TTYC_EL); - if (i != sy - 1) { - tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1); - tty->cy++; - } - } - } else { - tty_cursor_pane(tty, ctx, 0, 0); - for (j = 0; j < sy; j++) { - tty_cursor_pane(tty, ctx, 0, j); - tty_repeat_space(tty, sx); - } - } + px = ctx->xoff; + nx = screen_size_x(wp->screen); + py = ctx->yoff; + ny = screen_size_y(wp->screen); + + tty_clear_area(tty, wp, py, ny, px, nx, ctx->bg); } void |