mirror of
https://github.com/tmux/tmux.git
synced 2026-06-20 17:25:57 +00:00
Fix cursor and redraw overlap with auto-hide scrollbars
Auto-hide scrollbars are drawn as overlays inside the pane rather than in reserved columns. Avoid optimized pane scrolling/redraw paths writing through a visible overlay scrollbar, and suppress the terminal cursor when it would be placed in the visible overlay scrollbar column. This prevents transient wrong-colour cells and cursor blocks appearing over the scrollbar, especially when scrolling small floating panes. This fixed the green block issue.
This commit is contained in:
@@ -2174,6 +2174,10 @@ screen_write_collect_flush_scrolled(struct screen_write_ctx *ctx)
|
|||||||
screen_write_redraw_pane(ctx, &ttyctx);
|
screen_write_redraw_pane(ctx, &ttyctx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (wp != NULL && window_pane_scrollbar_overlay_visible(wp)) {
|
||||||
|
wp->flags |= PANE_REDRAW;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
log_debug("%s: scrolled %u (region %u-%u)", __func__, ctx->scrolled,
|
log_debug("%s: scrolled %u (region %u-%u)", __func__, ctx->scrolled,
|
||||||
s->rupper, s->rlower);
|
s->rupper, s->rlower);
|
||||||
@@ -2187,7 +2191,7 @@ screen_write_collect_flush_scrolled(struct screen_write_ctx *ctx)
|
|||||||
tty_write(tty_cmd_scrollup, &ttyctx);
|
tty_write(tty_cmd_scrollup, &ttyctx);
|
||||||
|
|
||||||
if (wp != NULL)
|
if (wp != NULL)
|
||||||
wp->flags |= PANE_REDRAWSCROLLBAR;
|
window_pane_scrollbar_redraw(wp);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1882,7 +1882,7 @@ server_client_reset_state(struct client *c)
|
|||||||
struct screen *s = NULL;
|
struct screen *s = NULL;
|
||||||
struct options *oo = c->session->options;
|
struct options *oo = c->session->options;
|
||||||
int mode = 0, cursor, flags, pane_mode = 0;
|
int mode = 0, cursor, flags, pane_mode = 0;
|
||||||
u_int cx = 0, cy = 0, ox, oy, sx, sy, n;
|
u_int cx = 0, cy = 0, ox, oy, sx, sy, n, sb_w;
|
||||||
struct visible_ranges *r;
|
struct visible_ranges *r;
|
||||||
|
|
||||||
if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED))
|
if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED))
|
||||||
@@ -1942,6 +1942,21 @@ server_client_reset_state(struct client *c)
|
|||||||
if (!window_position_is_visible(r, cx))
|
if (!window_position_is_visible(r, cx))
|
||||||
cursor = 0;
|
cursor = 0;
|
||||||
|
|
||||||
|
if (window_pane_scrollbar_overlay_visible(wp)) {
|
||||||
|
sb_w = wp->scrollbar_style.width;
|
||||||
|
if (sb_w > wp->sx)
|
||||||
|
sb_w = wp->sx;
|
||||||
|
if (sb_w != 0 &&
|
||||||
|
options_get_number(w->options,
|
||||||
|
"pane-scrollbars-position") ==
|
||||||
|
PANE_SCROLLBARS_LEFT) {
|
||||||
|
if (s->cx < sb_w)
|
||||||
|
cursor = 0;
|
||||||
|
} else if (sb_w != 0 &&
|
||||||
|
s->cx >= wp->sx - sb_w)
|
||||||
|
cursor = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (status_at_line(c) == 0)
|
if (status_at_line(c) == 0)
|
||||||
cy += status_line_size(c);
|
cy += status_line_size(c);
|
||||||
}
|
}
|
||||||
|
|||||||
2
tmux.h
2
tmux.h
@@ -3518,9 +3518,11 @@ int window_pane_show_scrollbar(struct window_pane *, int);
|
|||||||
int window_pane_scrollbar_reserve(struct window_pane *, int);
|
int window_pane_scrollbar_reserve(struct window_pane *, int);
|
||||||
int window_pane_scrollbar_visible(struct window_pane *, int);
|
int window_pane_scrollbar_visible(struct window_pane *, int);
|
||||||
int window_pane_scrollbar_overlay(struct window_pane *, int);
|
int window_pane_scrollbar_overlay(struct window_pane *, int);
|
||||||
|
int window_pane_scrollbar_overlay_visible(struct window_pane *);
|
||||||
void window_pane_scrollbar_show(struct window_pane *, int);
|
void window_pane_scrollbar_show(struct window_pane *, int);
|
||||||
void window_pane_scrollbar_hide(struct window_pane *);
|
void window_pane_scrollbar_hide(struct window_pane *);
|
||||||
void window_pane_scrollbar_start_timer(struct window_pane *);
|
void window_pane_scrollbar_start_timer(struct window_pane *);
|
||||||
|
void window_pane_scrollbar_redraw(struct window_pane *);
|
||||||
int window_pane_get_bg(struct window_pane *);
|
int window_pane_get_bg(struct window_pane *);
|
||||||
int window_pane_get_fg(struct window_pane *);
|
int window_pane_get_fg(struct window_pane *);
|
||||||
int window_pane_get_fg_control_client(struct window_pane *);
|
int window_pane_get_fg_control_client(struct window_pane *);
|
||||||
|
|||||||
@@ -5284,7 +5284,10 @@ window_copy_redraw_lines(struct window_mode_entry *wme, u_int py, u_int ny)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
screen_write_start_pane(&ctx, wp, NULL);
|
if (window_pane_scrollbar_overlay_visible(wp))
|
||||||
|
screen_write_start(&ctx, &data->screen);
|
||||||
|
else
|
||||||
|
screen_write_start_pane(&ctx, wp, NULL);
|
||||||
for (i = py; i < py + ny; i++)
|
for (i = py; i < py + ny; i++)
|
||||||
window_copy_write_line(wme, &ctx, i);
|
window_copy_write_line(wme, &ctx, i);
|
||||||
screen_write_cursormove(&ctx,
|
screen_write_cursormove(&ctx,
|
||||||
@@ -5292,7 +5295,7 @@ window_copy_redraw_lines(struct window_mode_entry *wme, u_int py, u_int ny)
|
|||||||
0);
|
0);
|
||||||
screen_write_stop(&ctx);
|
screen_write_stop(&ctx);
|
||||||
|
|
||||||
wp->flags |= PANE_REDRAWSCROLLBAR;
|
window_pane_scrollbar_redraw(wp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -6580,7 +6583,10 @@ window_copy_scroll_up(struct window_mode_entry *wme, u_int ny)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
screen_write_start_pane(&ctx, wp, NULL);
|
if (window_pane_scrollbar_overlay_visible(wp))
|
||||||
|
screen_write_start(&ctx, &data->screen);
|
||||||
|
else
|
||||||
|
screen_write_start_pane(&ctx, wp, NULL);
|
||||||
screen_write_cursormove(&ctx, 0, 0, 0);
|
screen_write_cursormove(&ctx, 0, 0, 0);
|
||||||
screen_write_deleteline(&ctx, ny, 8);
|
screen_write_deleteline(&ctx, ny, 8);
|
||||||
window_copy_write_lines(wme, &ctx, screen_size_y(s) - ny, ny);
|
window_copy_write_lines(wme, &ctx, screen_size_y(s) - ny, ny);
|
||||||
@@ -6595,7 +6601,7 @@ window_copy_scroll_up(struct window_mode_entry *wme, u_int ny)
|
|||||||
window_copy_cursor_offset(wme, data->cx, screen_size_x(s)), data->cy,
|
window_copy_cursor_offset(wme, data->cx, screen_size_x(s)), data->cy,
|
||||||
0);
|
0);
|
||||||
screen_write_stop(&ctx);
|
screen_write_stop(&ctx);
|
||||||
wp->flags |= PANE_REDRAWSCROLLBAR;
|
window_pane_scrollbar_redraw(wp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -6641,7 +6647,10 @@ window_copy_scroll_down(struct window_mode_entry *wme, u_int ny)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
screen_write_start_pane(&ctx, wp, NULL);
|
if (window_pane_scrollbar_overlay_visible(wp))
|
||||||
|
screen_write_start(&ctx, &data->screen);
|
||||||
|
else
|
||||||
|
screen_write_start_pane(&ctx, wp, NULL);
|
||||||
screen_write_cursormove(&ctx, 0, 0, 0);
|
screen_write_cursormove(&ctx, 0, 0, 0);
|
||||||
screen_write_insertline(&ctx, ny, 8);
|
screen_write_insertline(&ctx, ny, 8);
|
||||||
window_copy_write_lines(wme, &ctx, 0, ny);
|
window_copy_write_lines(wme, &ctx, 0, ny);
|
||||||
@@ -6652,7 +6661,7 @@ window_copy_scroll_down(struct window_mode_entry *wme, u_int ny)
|
|||||||
screen_write_cursormove(&ctx, window_copy_cursor_offset(wme, data->cx,
|
screen_write_cursormove(&ctx, window_copy_cursor_offset(wme, data->cx,
|
||||||
screen_size_x(s)), data->cy, 0);
|
screen_size_x(s)), data->cy, 0);
|
||||||
screen_write_stop(&ctx);
|
screen_write_stop(&ctx);
|
||||||
wp->flags |= PANE_REDRAWSCROLLBAR;
|
window_pane_scrollbar_redraw(wp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
26
window.c
26
window.c
@@ -1151,8 +1151,28 @@ window_pane_scrollbar_auto_hide(struct window_pane *wp)
|
|||||||
"pane-scrollbars-auto-hide"));
|
"pane-scrollbars-auto-hide"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
int
|
||||||
|
window_pane_scrollbar_overlay_visible(struct window_pane *wp)
|
||||||
|
{
|
||||||
|
int sb;
|
||||||
|
|
||||||
|
sb = options_get_number(wp->window->options, "pane-scrollbars");
|
||||||
|
return (window_pane_scrollbar_overlay(wp, sb) &&
|
||||||
|
window_pane_scrollbar_visible(wp, sb));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
window_pane_scrollbar_redraw(struct window_pane *wp)
|
window_pane_scrollbar_redraw(struct window_pane *wp)
|
||||||
|
{
|
||||||
|
if (window_pane_scrollbar_overlay_visible(wp)) {
|
||||||
|
wp->flags |= PANE_REDRAW;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wp->flags |= PANE_REDRAWSCROLLBAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
window_pane_scrollbar_redraw_visibility(struct window_pane *wp)
|
||||||
{
|
{
|
||||||
redraw_invalidate_scene(wp->window);
|
redraw_invalidate_scene(wp->window);
|
||||||
wp->flags |= PANE_REDRAW;
|
wp->flags |= PANE_REDRAW;
|
||||||
@@ -2066,7 +2086,7 @@ window_pane_scrollbar_show(struct window_pane *wp, int start_timer)
|
|||||||
if (start_timer)
|
if (start_timer)
|
||||||
window_pane_scrollbar_start_timer(wp);
|
window_pane_scrollbar_start_timer(wp);
|
||||||
if (changed)
|
if (changed)
|
||||||
window_pane_scrollbar_redraw(wp);
|
window_pane_scrollbar_redraw_visibility(wp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -2078,7 +2098,7 @@ window_pane_scrollbar_hide(struct window_pane *wp)
|
|||||||
if (!wp->sb_auto_visible)
|
if (!wp->sb_auto_visible)
|
||||||
return;
|
return;
|
||||||
wp->sb_auto_visible = 0;
|
wp->sb_auto_visible = 0;
|
||||||
window_pane_scrollbar_redraw(wp);
|
window_pane_scrollbar_redraw_visibility(wp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|||||||
Reference in New Issue
Block a user