diff --git a/screen-write.c b/screen-write.c index 9a09d190..36f96c71 100644 --- a/screen-write.c +++ b/screen-write.c @@ -3046,14 +3046,9 @@ screen_write_sixelimage(struct screen_write_ctx *ctx, struct sixel_image *si, } screen_write_collect_flush(ctx, 0, __func__); - screen_write_initctx(ctx, &ttyctx, 0, 1); + screen_write_initctx(ctx, &ttyctx, 0, 0); ttyctx.image = image_store(s, si); - if ((ttyctx.flags & TTY_CTX_PANE_OBSCURED) && ctx->wp != NULL) { - ctx->wp->flags |= PANE_REDRAW; - return; - } - tty_write(tty_cmd_sixelimage, &ttyctx); screen_write_cursormove(ctx, 0, cy + y, 0); diff --git a/tmux.1 b/tmux.1 index 0357b45f..91f34a5d 100644 --- a/tmux.1 +++ b/tmux.1 @@ -292,8 +292,6 @@ Rename the current session. Split the current pane into two, left and right. .It & Kill the current window. -.It @ -Toggle the current pane between floating and tiled. .It \[aq] Prompt for a window index to select. .It \&( @@ -3193,23 +3191,6 @@ or (time). .Fl r reverses the sort order. -.Tg hidep -.It Xo Ic hide\-pane -.Op Fl a -.Op Fl t Ar target\-pane -.Xc -.D1 Pq alias: Ic hidep -Hide -.Ar target\-pane -from the tiled layout without closing it. -The pane continues to run but is no longer visible and does not occupy any -screen space. -Hidden panes are shown in the status line and can be restored with -.Ic show\-pane . -With -.Fl a , -all visible panes in the window are hidden. -The pane must not already be hidden. .Tg movep .It Xo Ic move\-pane .Op Fl bdfhv @@ -6610,7 +6591,6 @@ The following variables are available, where appropriate: .It Li "pane_left" Ta "" Ta "Left of pane" .It Li "pane_marked" Ta "" Ta "1 if this is the marked pane" .It Li "pane_marked_set" Ta "" Ta "1 if a marked pane is set" -.It Li "pane_hidden_flag" Ta "" Ta "1 if pane is hidden" .It Li "pane_mode" Ta "" Ta "Name of pane mode, if any" .It Li "pane_path" Ta "" Ta "Path of pane (can be set by application)" .It Li "pane_pid" Ta "" Ta "PID of first process in pane" diff --git a/tty.c b/tty.c index 0b5ae135..cd419e0f 100644 --- a/tty.c +++ b/tty.c @@ -2172,169 +2172,20 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx) } #ifdef ENABLE_SIXEL -/* - * Render one sub-rectangle of a sixel image at tty position (dst_x, dst_y). - * Caller must have set tty->flags |= TTY_NOBLOCK and called tty_region_off - * and tty_margin_off. After the call, tty->cx and tty->cy are UINT_MAX - * because the cursor position after a sixel DCS sequence is terminal-defined. - */ -static void -tty_sixel_subrect(struct tty *tty, struct sixel_image *si, - u_int src_i, u_int src_j, u_int src_rx, u_int src_ry, - u_int dst_x, u_int dst_y) -{ - struct sixel_image *sub; - char *data; - size_t size; - - if (src_rx == 0 || src_ry == 0) - return; - sub = sixel_scale(si, tty->xpixel, tty->ypixel, - src_i, src_j, src_rx, src_ry, 0); - if (sub == NULL) - return; - data = sixel_print(sub, si, &size); - sixel_free(sub); - if (data == NULL) - return; - tty_cursor(tty, dst_x, dst_y); - tty_add(tty, data, size); - tty->cx = tty->cy = UINT_MAX; - free(data); -} - -/* - * Render the clamped region of sixel image si, split into sub-rectangles - * that avoid cells obscured by floating panes above this one. - * - * Row breakpoints are computed from each floating pane's top/bottom border - * row. Between breakpoints the visible column ranges are constant, so each - * strip is rendered with one set of sub-rectangles. When no floating panes - * overlap the sixel the loop produces a single strip and one sub-rect equal - * to the full clamped rectangle. - * - * i, j : source cell offset (top-left of visible portion after viewport clip) - * rx, ry: rendered size in cells - * x, y : tty destination position - */ -static void -tty_sixelimage_draw(struct tty *tty, const struct tty_ctx *ctx, - struct sixel_image *si, u_int i, u_int j, u_int rx, u_int ry, - u_int x, u_int y) -{ - struct window_pane *wp, *fp; - struct window *w; - struct visible_ranges *vr; - struct visible_range *ri; - u_int sixel_wx0, sixel_wx1, sixel_y0; - u_int breaks[64], nb, b, s, tmp; - u_int strip_start, strip_end, strip_h; - u_int seg_wx0, seg_wx1, seg_w; - u_int src_i2, src_j2, dst_x2; - int fp_tb, fp_bb1, r_top, r_bot; - - tty->flags |= TTY_NOBLOCK; - tty_region_off(tty); - tty_margin_off(tty); - - wp = ctx->arg; - if (wp == NULL) { - /* Overlay/popup: no pane context, render the full clamped rect. */ - tty_sixel_subrect(tty, si, i, j, rx, ry, x, y); - tty_invalidate(tty); - return; - } - - /* - * sixel_y0 is the window y-coordinate of the first rendered row. - * Derived from tty_clamp_area: y = ctx->yoff + ocy + j - ctx->woy, - * so y + ctx->woy = ctx->yoff + ocy + j. - */ - w = wp->window; - sixel_wx0 = x + ctx->wox; - sixel_wx1 = sixel_wx0 + rx; - sixel_y0 = y + ctx->woy; - - nb = 0; - breaks[nb++] = 0; - breaks[nb++] = ry; - - TAILQ_FOREACH(fp, &w->z_index, zentry) { - if (~fp->flags & PANE_FLOATING) - continue; - fp_tb = (int)((fp->yoff > 0) ? fp->yoff - 1 : 0); - fp_bb1 = (int)fp->yoff + (int)fp->sy + 1; - r_top = fp_tb - (int)sixel_y0; - r_bot = fp_bb1 - (int)sixel_y0; - if (r_top > 0 && (u_int)r_top < ry && nb < 62) - breaks[nb++] = (u_int)r_top; - if (r_bot > 0 && (u_int)r_bot < ry && nb < 62) - breaks[nb++] = (u_int)r_bot; - } - - /* Sort breakpoints (insertion sort; small array). */ - for (b = 1; b < nb; b++) { - tmp = breaks[b]; - s = b; - while (s > 0 && breaks[s - 1] > tmp) { - breaks[s] = breaks[s - 1]; - s--; - } - breaks[s] = tmp; - } - - if (nb > 2) - log_debug("%s: sixel %%%u clipped around floating panes", - __func__, wp->id); - - for (b = 0; b + 1 < nb; b++) { - strip_start = breaks[b]; - strip_end = breaks[b + 1]; - if (strip_end == strip_start) - continue; - strip_h = strip_end - strip_start; - - vr = screen_redraw_get_visible_ranges(wp, ctx->xoff, - sixel_y0 + strip_start, wp->sx, NULL); - - for (s = 0; s < vr->used; s++) { - ri = &vr->ranges[s]; - if (ri->nx == 0) - continue; - seg_wx0 = ri->px; - seg_wx1 = ri->px + ri->nx; - if (seg_wx0 < sixel_wx0) - seg_wx0 = sixel_wx0; - if (seg_wx1 > sixel_wx1) - seg_wx1 = sixel_wx1; - if (seg_wx1 <= seg_wx0) - continue; - seg_w = seg_wx1 - seg_wx0; - src_i2 = i + (seg_wx0 - sixel_wx0); - src_j2 = j + strip_start; - dst_x2 = seg_wx0 - ctx->wox; - tty_sixel_subrect(tty, si, src_i2, src_j2, - seg_w, strip_h, dst_x2, y + strip_start); - } - } - - tty_invalidate(tty); -} - void tty_cmd_sixelimage(struct tty *tty, const struct tty_ctx *ctx) { struct image *im = ctx->image; struct sixel_image *si = im->data; + struct sixel_image *new; char *data; size_t size; u_int cx = ctx->ocx, cy = ctx->ocy, sx, sy; u_int i, j, x, y, rx, ry; - int fallback; + int fallback = 0; - fallback = 0; if ((~tty->term->flags & TERM_SIXEL) && - !tty_term_has(tty->term, TTYC_SXL)) + !tty_term_has(tty->term, TTYC_SXL)) fallback = 1; if (tty->xpixel == 0 || tty->ypixel == 0) fallback = 1; @@ -2345,20 +2196,30 @@ tty_cmd_sixelimage(struct tty *tty, const struct tty_ctx *ctx) return; log_debug("%s: clamping to %u,%u-%u,%u", __func__, i, j, rx, ry); - if (fallback) { + if (fallback == 1) { data = xstrdup(im->fallback); size = strlen(data); - tty->flags |= TTY_NOBLOCK; + } else { + new = sixel_scale(si, tty->xpixel, tty->ypixel, i, j, rx, ry, 0); + if (new == NULL) + return; + + data = sixel_print(new, si, &size); + } + if (data != NULL) { + log_debug("%s: %zu bytes: %s", __func__, size, data); tty_region_off(tty); tty_margin_off(tty); tty_cursor(tty, x, y); + + tty->flags |= TTY_NOBLOCK; tty_add(tty, data, size); tty_invalidate(tty); free(data); - return; } - tty_sixelimage_draw(tty, ctx, si, i, j, rx, ry, x, y); + if (fallback == 0) + sixel_free(new); } #endif