From ee123c248951450100475717f5bd45f292d9bb4d Mon Sep 17 00:00:00 2001 From: nicm Date: Sun, 19 Apr 2015 21:05:27 +0000 Subject: Support setting the default window and pane background colours (window and active pane via window-style and window-active-style options, an individual pane by a new select-pane -P flag). From J Raynor. --- tty.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 124 insertions(+), 46 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 83ae8282..59ed3bb8 100644 --- a/tty.c +++ b/tty.c @@ -43,11 +43,14 @@ void tty_colours_fg(struct tty *, const struct grid_cell *); void tty_colours_bg(struct tty *, const struct grid_cell *); int tty_large_region(struct tty *, const struct tty_ctx *); +int tty_fake_bce(const struct tty *, const struct window_pane *); void tty_redraw_region(struct tty *, const struct tty_ctx *); void tty_emulate_repeat( struct tty *, enum tty_code_code, enum tty_code_code, u_int); void tty_repeat_space(struct tty *, u_int); -void tty_cell(struct tty *, const struct grid_cell *); +void tty_cell(struct tty *, const struct grid_cell *, + const struct window_pane *); +void tty_default_colours(struct grid_cell *, const struct window_pane *); #define tty_use_acs(tty) \ (tty_term_has((tty)->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8)) @@ -581,6 +584,23 @@ tty_large_region(unused struct tty *tty, const struct tty_ctx *ctx) return (ctx->orlower - ctx->orupper >= screen_size_y(wp->screen) / 2); } +/* + * Return if BCE is needed but the terminal doesn't have it - it'll need to be + * emulated. + */ +int +tty_fake_bce(const struct tty *tty, const struct window_pane *wp) +{ + struct grid_cell gc; + + memcpy(&gc, &grid_default_cell, sizeof gc); + tty_default_colours(&gc, wp); + + if (gc.bg == 8 && !(gc.flags & GRID_FLAG_BG256)) + return (0); + return (!tty_term_flag(tty->term, TTYC_BCE)); +} + /* * Redraw scroll region using data from screen (already updated). Used when * CSR not supported, or window is a pane that doesn't take up the full @@ -604,15 +624,23 @@ tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx) if (ctx->ocy < ctx->orupper || ctx->ocy > ctx->orlower) { for (i = ctx->ocy; i < screen_size_y(s); i++) - tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff); + tty_draw_pane(tty, wp, i, ctx->xoff, ctx->yoff); } else { for (i = ctx->orupper; i <= ctx->orlower; i++) - tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff); + tty_draw_pane(tty, wp, i, ctx->xoff, ctx->yoff); } } void -tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) +tty_draw_pane(struct tty *tty, const struct window_pane *wp, u_int py, u_int ox, + u_int oy) +{ + tty_draw_line(tty, wp, wp->screen, py, ox, oy); +} + +void +tty_draw_line(struct tty *tty, const struct window_pane *wp, + struct screen *s, u_int py, u_int ox, u_int oy) { const struct grid_cell *gc; struct grid_line *gl; @@ -650,20 +678,20 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) ~(GRID_FLAG_FG256|GRID_FLAG_BG256); tmpgc.flags |= s->sel.cell.flags & (GRID_FLAG_FG256|GRID_FLAG_BG256); - tty_cell(tty, &tmpgc); + tty_cell(tty, &tmpgc, wp); } else - tty_cell(tty, gc); + tty_cell(tty, gc, wp); } if (sx >= tty->sx) { tty_update_mode(tty, tty->mode, s); return; } - tty_reset(tty); + tty_attributes(tty, &grid_default_cell, wp); 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_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp)) tty_putcode(tty, TTYC_EL); else tty_repeat_space(tty, screen_size_x(s) - sx); @@ -713,19 +741,19 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) struct window_pane *wp = ctx->wp; if (!tty_pane_full_width(tty, ctx)) { - tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff); + tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff); return; } - tty_reset(tty); + tty_attributes(tty, &grid_default_cell, wp); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); - if (tty_term_has(tty->term, TTYC_ICH) || - tty_term_has(tty->term, TTYC_ICH1)) + if (!tty_fake_bce(tty, wp) && (tty_term_has(tty->term, TTYC_ICH) || + tty_term_has(tty->term, TTYC_ICH1))) tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num); else - tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff); + tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff); } void @@ -733,14 +761,14 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; - if (!tty_pane_full_width(tty, ctx) || + if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, wp) || (!tty_term_has(tty->term, TTYC_DCH) && !tty_term_has(tty->term, TTYC_DCH1))) { - tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff); + tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff); return; } - tty_reset(tty); + tty_attributes(tty, &grid_default_cell, wp); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); @@ -754,11 +782,11 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx) { u_int i; - tty_reset(tty); + tty_attributes(tty, &grid_default_cell, ctx->wp); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); - if (tty_term_has(tty->term, TTYC_ECH)) + if (tty_term_has(tty->term, TTYC_ECH) && !tty_fake_bce(tty, ctx->wp)) tty_putcode1(tty, TTYC_ECH, ctx->num); else { for (i = 0; i < ctx->num; i++) @@ -769,14 +797,14 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) { - if (!tty_pane_full_width(tty, ctx) || + if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, ctx->wp) || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_IL1)) { tty_redraw_region(tty, ctx); return; } - tty_reset(tty); + tty_attributes(tty, &grid_default_cell, ctx->wp); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); @@ -787,14 +815,14 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx) { - if (!tty_pane_full_width(tty, ctx) || + if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, ctx->wp) || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_DL1)) { tty_redraw_region(tty, ctx); return; } - tty_reset(tty); + tty_attributes(tty, &grid_default_cell, ctx->wp); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); @@ -808,11 +836,12 @@ tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx) struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; - tty_reset(tty); + tty_attributes(tty, &grid_default_cell, wp); tty_cursor_pane(tty, ctx, 0, ctx->ocy); - if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) + if (tty_pane_full_width(tty, ctx) && !tty_fake_bce(tty, wp) && + tty_term_has(tty->term, TTYC_EL)) tty_putcode(tty, TTYC_EL); else tty_repeat_space(tty, screen_size_x(s)); @@ -824,11 +853,12 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx) struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; - tty_reset(tty); + tty_attributes(tty, &grid_default_cell, wp); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); - if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) + if (tty_pane_full_width(tty, ctx) && + tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp)) tty_putcode(tty, TTYC_EL); else tty_repeat_space(tty, screen_size_x(s) - ctx->ocx); @@ -837,9 +867,10 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx) { - tty_reset(tty); + tty_attributes(tty, &grid_default_cell, ctx->wp); - if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) { + if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1) && + !tty_fake_bce(tty, ctx->wp)) { tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); tty_putcode(tty, TTYC_EL1); } else { @@ -854,14 +885,14 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx) if (ctx->ocy != ctx->orupper) return; - if (!tty_pane_full_width(tty, ctx) || + if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, ctx->wp) || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_RI)) { tty_redraw_region(tty, ctx); return; } - tty_reset(tty); + tty_attributes(tty, &grid_default_cell, ctx->wp); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper); @@ -877,7 +908,7 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) if (ctx->ocy != ctx->orlower) return; - if (!tty_pane_full_width(tty, ctx) || + if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, wp) || !tty_term_has(tty->term, TTYC_CSR)) { if (tty_large_region(tty, ctx)) wp->flags |= PANE_REDRAW; @@ -894,7 +925,7 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) if (ctx->num && !(tty->term->flags & TERM_EARLYWRAP)) return; - tty_reset(tty); + tty_attributes(tty, &grid_default_cell, wp); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); @@ -909,12 +940,13 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx) struct screen *s = wp->screen; u_int i, j; - tty_reset(tty); + tty_attributes(tty, &grid_default_cell, wp); tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); - if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) { + if (tty_pane_full_width(tty, ctx) && + tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp)) { tty_putcode(tty, TTYC_EL); if (ctx->ocy != screen_size_y(s) - 1) { tty_cursor_pane(tty, ctx, 0, ctx->ocy + 1); @@ -942,12 +974,13 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx) struct screen *s = wp->screen; u_int i, j; - tty_reset(tty); + tty_attributes(tty, &grid_default_cell, wp); tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); tty_cursor_pane(tty, ctx, 0, 0); - if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) { + if (tty_pane_full_width(tty, ctx) && + tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp)) { for (i = 0; i < ctx->ocy; i++) { tty_putcode(tty, TTYC_EL); tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1); @@ -969,12 +1002,13 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx) struct screen *s = wp->screen; u_int i, j; - tty_reset(tty); + tty_attributes(tty, &grid_default_cell, wp); tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); tty_cursor_pane(tty, ctx, 0, 0); - if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) { + if (tty_pane_full_width(tty, ctx) && + tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp)) { for (i = 0; i < screen_size_y(s); i++) { tty_putcode(tty, TTYC_EL); if (i != screen_size_y(s) - 1) { @@ -997,7 +1031,7 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx) struct screen *s = wp->screen; u_int i, j; - tty_reset(tty); + tty_attributes(tty, &grid_default_cell, wp); tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); @@ -1038,12 +1072,12 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) */ cx = screen_size_x(s) - grid_cell_width(&ctx->last_cell); tty_cursor_pane(tty, ctx, cx, ctx->ocy); - tty_cell(tty, &ctx->last_cell); + tty_cell(tty, &ctx->last_cell, wp); } } else tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); - tty_cell(tty, ctx->cell); + tty_cell(tty, ctx->cell, wp); } void @@ -1055,7 +1089,7 @@ tty_cmd_utf8character(struct tty *tty, const struct tty_ctx *ctx) * Cannot rely on not being a partial character, so just redraw the * whole line. */ - tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff); + tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff); } void @@ -1088,12 +1122,13 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx) tty->cx = tty->cy = UINT_MAX; tty->rupper = tty->rlower = UINT_MAX; - tty_reset(tty); + tty_attributes(tty, &grid_default_cell, ctx->wp); tty_cursor(tty, 0, 0); } void -tty_cell(struct tty *tty, const struct grid_cell *gc) +tty_cell(struct tty *tty, const struct grid_cell *gc, + const struct window_pane *wp) { struct utf8_data ud; u_int i; @@ -1108,7 +1143,7 @@ tty_cell(struct tty *tty, const struct grid_cell *gc) return; /* Set the attributes. */ - tty_attributes(tty, gc); + tty_attributes(tty, gc, wp); /* Get the cell and if ASCII write with putc to do ACS translation. */ grid_cell_get(gc, &ud); @@ -1312,12 +1347,14 @@ out: } void -tty_attributes(struct tty *tty, const struct grid_cell *gc) +tty_attributes(struct tty *tty, const struct grid_cell *gc, + const struct window_pane *wp) { struct grid_cell *tc = &tty->cell, gc2; u_char changed; memcpy(&gc2, gc, sizeof gc2); + tty_default_colours(&gc2, wp); /* * If no setab, try to use the reverse attribute as a best-effort for a @@ -1609,6 +1646,47 @@ tty_try_256(struct tty *tty, u_char colour, const char *type) return (-1); } +void +tty_default_colours(struct grid_cell *gc, const struct window_pane *wp) +{ + const struct grid_cell *agc, *pgc, *wgc; + + if (wp == NULL) + return; + + pgc = &wp->colgc; + agc = options_get_style(&wp->window->options, "window-active-style"); + wgc = options_get_style(&wp->window->options, "window-style"); + + if (gc->fg == 8 && !(gc->flags & GRID_FLAG_FG256)) { + if (pgc->fg != 8 || (pgc->flags & GRID_FLAG_FG256)) { + gc->fg = pgc->fg; + gc->flags |= (pgc->flags & GRID_FLAG_FG256); + } else if (wp == wp->window->active && + (agc->fg != 8 || (agc->flags & GRID_FLAG_FG256))) { + gc->fg = agc->fg; + gc->flags |= (agc->flags & GRID_FLAG_FG256); + } else { + gc->fg = wgc->fg; + gc->flags |= (wgc->flags & GRID_FLAG_FG256); + } + } + + if (gc->bg == 8 && !(gc->flags & GRID_FLAG_BG256)) { + if (pgc->bg != 8 || (pgc->flags & GRID_FLAG_BG256)) { + gc->bg = pgc->bg; + gc->flags |= (pgc->flags & GRID_FLAG_BG256); + } else if (wp == wp->window->active && + (agc->bg != 8 || (agc->flags & GRID_FLAG_BG256))) { + gc->bg = agc->bg; + gc->flags |= (agc->flags & GRID_FLAG_BG256); + } else { + gc->bg = wgc->bg; + gc->flags |= (wgc->flags & GRID_FLAG_BG256); + } + } +} + void tty_bell(struct tty *tty) { -- cgit From bf635e7741f7b881f67ec7e4a5caa02f7ff3d786 Mon Sep 17 00:00:00 2001 From: nicm Date: Sun, 19 Apr 2015 21:34:21 +0000 Subject: Rewrite of tmux mouse support which was a mess. Instead of having options for "mouse-this" and "mouse-that", mouse events may be bound as keys and there is one option "mouse" that turns on mouse support entirely (set -g mouse on). See the new MOUSE SUPPORT section of the man page for description of the key names and new flags (-t= to specify the pane or window under mouse as a target, and send-keys -M to pass through a mouse event). The default builtin bindings for the mouse are: bind -n MouseDown1Pane select-pane -t=; send-keys -M bind -n MouseDown1Status select-window -t= bind -n MouseDrag1Pane copy-mode -M bind -n MouseDrag1Border resize-pane -M To get the effect of turning mode-mouse off, do: unbind -n MouseDrag1Pane unbind -temacs-copy MouseDrag1Pane The old mouse options are now gone, set-option -q may be used to suppress warnings if mixing configuration files. --- tty.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 59ed3bb8..a5067b12 100644 --- a/tty.c +++ b/tty.c @@ -241,6 +241,10 @@ tty_start_tty(struct tty *tty) tty->flags |= TTY_STARTED; tty_force_cursor_colour(tty, ""); + + tty->mouse_drag_flag = 0; + tty->mouse_drag_update = NULL; + tty->mouse_drag_release = NULL; } void -- cgit