Add scrollbar auto-hide feature.

This commit is contained in:
Michael Grant
2026-06-20 08:29:47 +02:00
parent cab77de83f
commit 738083c4a4
10 changed files with 288 additions and 25 deletions

View File

@@ -250,10 +250,10 @@ cmd_resize_pane_mouse_resize_move_floating(struct client *c,
sb_pos = options_get_number(w->options, "pane-scrollbars-position");
left = wp->xoff - 1;
right = wp->xoff + sx;
if (window_pane_show_scrollbar(wp, scrollbars) &&
if (window_pane_scrollbar_reserve(wp, scrollbars) &&
sb_pos == PANE_SCROLLBARS_LEFT) {
left -= wp->scrollbar_style.width + wp->scrollbar_style.pad;
} else if (window_pane_show_scrollbar(wp, scrollbars) &&
} else if (window_pane_scrollbar_reserve(wp, scrollbars) &&
sb_pos == PANE_SCROLLBARS_RIGHT) {
right += wp->scrollbar_style.width + wp->scrollbar_style.pad;
}

View File

@@ -433,7 +433,7 @@ layout_fix_panes(struct window *w, struct window_pane *skip)
sy--;
}
if (window_pane_show_scrollbar(wp, scrollbars)) {
if (window_pane_scrollbar_reserve(wp, scrollbars)) {
sb_w = wp->scrollbar_style.width;
sb_pad = wp->scrollbar_style.pad;
if (sb_w < 1)
@@ -506,7 +506,8 @@ layout_resize_check(struct window *w, struct layout_cell *lc,
/* Space available in this cell only. */
if (type == LAYOUT_LEFTRIGHT) {
available = lc->sx;
if (scrollbars)
if (scrollbars && !options_get_number(w->options,
"pane-scrollbars-auto-hide"))
minimum = PANE_MINIMUM + sb_style->width +
sb_style->pad;
else
@@ -1210,7 +1211,8 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
/* Check there is enough space for the two new panes. */
switch (type) {
case LAYOUT_LEFTRIGHT:
if (scrollbars) {
if (scrollbars && !options_get_number(wp->window->options,
"pane-scrollbars-auto-hide")) {
minimum = PANE_MINIMUM * 2 + sb_style->width +
sb_style->pad;
} else

View File

@@ -1404,6 +1404,23 @@ const struct options_table_entry options_table[] = {
.text = "Pane scrollbar state."
},
{ .name = "pane-scrollbars-auto-hide",
.type = OPTIONS_TABLE_FLAG,
.scope = OPTIONS_TABLE_WINDOW,
.default_num = 0,
.text = "Whether pane scrollbars are hidden when not in use."
},
{ .name = "pane-scrollbars-auto-hide-timeout",
.type = OPTIONS_TABLE_NUMBER,
.scope = OPTIONS_TABLE_WINDOW,
.minimum = 0,
.maximum = INT_MAX,
.default_num = 1000,
.unit = "milliseconds",
.text = "Time before auto-hidden pane scrollbars disappear."
},
{ .name = "pane-scrollbars-style",
.type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,

View File

@@ -1225,6 +1225,8 @@ options_push_changes(const char *name)
strcmp(name, "pane-border-lines") == 0 ||
strcmp(name, "pane-border-status") == 0 ||
strcmp(name, "pane-scrollbars") == 0 ||
strcmp(name, "pane-scrollbars-auto-hide") == 0 ||
strcmp(name, "pane-scrollbars-auto-hide-timeout") == 0 ||
strcmp(name, "pane-scrollbars-position") == 0 ||
strcmp(name, "pane-scrollbars-style") == 0)
redraw_invalidate_all_scenes();
@@ -1245,10 +1247,15 @@ options_push_changes(const char *name)
}
if (strcmp(name, "pane-border-status") == 0 ||
strcmp(name, "pane-scrollbars") == 0 ||
strcmp(name, "pane-scrollbars-auto-hide") == 0 ||
strcmp(name, "pane-scrollbars-position") == 0) {
RB_FOREACH(w, windows, &windows)
layout_fix_panes(w, NULL);
}
if (strcmp(name, "pane-scrollbars-auto-hide") == 0) {
RB_FOREACH(wp, window_pane_tree, &all_window_panes)
window_pane_scrollbar_hide(wp);
}
if (strcmp(name, "pane-scrollbars-style") == 0) {
RB_FOREACH(wp, window_pane_tree, &all_window_panes) {
style_set_scrollbar_style_from_option(

View File

@@ -81,6 +81,7 @@ enum redraw_span_type {
#define REDRAW_BORDER_IS_ARROW 0x1
#define REDRAW_SCROLLBAR_LEFT 0x2
#define REDRAW_SCROLLBAR_RIGHT 0x4
#define REDRAW_SCROLLBAR_OVERLAY 0x8
/* Draw operations. */
#define REDRAW_PANE 0x1
@@ -447,7 +448,7 @@ redraw_mark_pane_inside(struct redraw_build_ctx *bctx, struct window_pane *wp)
/* Mark scrollbar data. */
static void
redraw_mark_pane_scrollbar(struct redraw_build_ctx *bctx,
struct window_pane *wp, int sb_w, int sb_left)
struct window_pane *wp, int sb_w, int sb_left, int overlay)
{
struct redraw_build_cell *bc;
u_int x, y;
@@ -457,7 +458,13 @@ redraw_mark_pane_scrollbar(struct redraw_build_ctx *bctx,
if (sb_w == 0)
return;
if (sb_left) {
if (overlay && sb_left) {
sx = wp->xoff;
ex = sx + sb_w - 1;
} else if (overlay) {
ex = wp->xoff + (int)wp->sx - 1;
sx = ex - sb_w + 1;
} else if (sb_left) {
sx = wp->xoff - sb_w;
ex = wp->xoff - 1;
} else {
@@ -481,6 +488,8 @@ redraw_mark_pane_scrollbar(struct redraw_build_ctx *bctx,
bc->data.sb.flags |= REDRAW_SCROLLBAR_LEFT;
else
bc->data.sb.flags |= REDRAW_SCROLLBAR_RIGHT;
if (overlay)
bc->data.sb.flags |= REDRAW_SCROLLBAR_OVERLAY;
}
}
}
@@ -755,19 +764,26 @@ redraw_mark_pane_borders(struct redraw_build_ctx *bctx, struct window_pane *wp,
static void
redraw_mark_pane(struct redraw_build_ctx *bctx, struct window_pane *wp)
{
int sb_w = 0, sb_left = 0;
int sb_w = 0, sb_left = 0, overlay = 0;
if (!window_pane_is_visible(wp))
return;
if (window_pane_show_scrollbar(wp, bctx->sb))
if (window_pane_scrollbar_visible(wp, bctx->sb)) {
overlay = window_pane_scrollbar_overlay(wp, bctx->sb);
if (overlay) {
sb_w = wp->scrollbar_style.width;
if (sb_w > (int)wp->sx)
sb_w = wp->sx;
} else
sb_w = wp->scrollbar_style.width + wp->scrollbar_style.pad;
}
if (sb_w != 0 && bctx->sbp == PANE_SCROLLBARS_LEFT)
sb_left = 1;
redraw_mark_pane_inside(bctx, wp);
redraw_mark_pane_borders(bctx, wp, sb_w, sb_left);
redraw_mark_pane_scrollbar(bctx, wp, sb_w, sb_left);
redraw_mark_pane_borders(bctx, wp, overlay ? 0 : sb_w, sb_left);
redraw_mark_pane_scrollbar(bctx, wp, sb_w, sb_left, overlay);
}
/* Choose the pane that will provide the border style for two-pane layouts. */
@@ -1267,7 +1283,9 @@ redraw_draw_scrollbar_span(struct redraw_draw_ctx *dctx,
tty_cursor(tty, x, y);
for (i = 0; i < n; i++) {
if (span->data.sb.flags & REDRAW_SCROLLBAR_LEFT) {
if (span->data.sb.flags & REDRAW_SCROLLBAR_OVERLAY) {
/* Padding is transparent and is not part of overlay spans. */
} else if (span->data.sb.flags & REDRAW_SCROLLBAR_LEFT) {
if (off + i >= sb_w && off + i < sb_w + sb_pad) {
tty_cell(tty, &grid_default_cell, NULL);
continue;

View File

@@ -48,6 +48,8 @@ static void server_client_dispatch(struct imsg *, void *);
static int server_client_dispatch_command(struct client *, struct imsg *);
static int server_client_dispatch_identify(struct client *, struct imsg *);
static int server_client_dispatch_shell(struct client *);
static void server_client_update_scrollbar_hover(struct client *, int, int,
int);
static void server_client_report_theme(struct client *, enum client_theme);
/* Compare client windows. */
@@ -599,6 +601,60 @@ server_client_exec(struct client *c, const char *cmd)
free(msg);
}
/* Is this point inside the auto-hide scrollbar interaction area? */
static int
server_client_in_scrollbar_area(struct window_pane *wp, int px, int py)
{
struct window *w = wp->window;
u_int width, pad, total;
int sb, sb_pos, start, end;
sb = options_get_number(w->options, "pane-scrollbars");
if (!window_pane_scrollbar_overlay(wp, sb))
return (0);
if (py < wp->yoff || py >= wp->yoff + (int)wp->sy)
return (0);
width = wp->scrollbar_style.width;
pad = wp->scrollbar_style.pad;
total = width + pad;
if (total == 0 || total > wp->sx)
total = wp->sx;
sb_pos = options_get_number(w->options, "pane-scrollbars-position");
if (sb_pos == PANE_SCROLLBARS_LEFT) {
start = wp->xoff;
end = wp->xoff + (int)total - 1;
} else {
end = wp->xoff + (int)wp->sx - 1;
start = end - (int)total + 1;
}
return (px >= start && px <= end);
}
/* Update auto-hide scrollbars for a mouse movement. */
static void
server_client_update_scrollbar_hover(struct client *c, int type, int px, int py)
{
struct window *w = c->session->curw->window;
struct window_pane *wp;
if (type != KEYC_TYPE_MOUSEMOVE)
return;
TAILQ_FOREACH(wp, &w->panes, entry) {
if (!window_pane_is_visible(wp))
continue;
if (server_client_in_scrollbar_area(wp, px, py)) {
wp->sb_auto_hover = 1;
window_pane_scrollbar_show(wp, 0);
} else {
wp->sb_auto_hover = 0;
window_pane_scrollbar_start_timer(wp);
}
}
}
/* Is the mouse inside a pane? */
static enum key_code_mouse_location
server_client_check_mouse_in_pane(struct window_pane *wp, int px, int py,
@@ -606,17 +662,21 @@ server_client_check_mouse_in_pane(struct window_pane *wp, int px, int py,
{
struct window *w = wp->window;
struct window_pane *fwp;
int pane_status, sb, sb_pos, sb_w, sb_pad;
int pane_status, sb, sb_pos, sb_w, sb_pad, sb_overlay;
int pane_status_line, sl_top, sl_bottom;
int bdr_bottom, bdr_top, bdr_left, bdr_right;
int sb_start, sb_end;
sb = options_get_number(w->options, "pane-scrollbars");
sb_pos = options_get_number(w->options, "pane-scrollbars-position");
pane_status = window_pane_get_pane_status(wp);
sb_overlay = window_pane_scrollbar_overlay(wp, sb);
if (window_pane_show_scrollbar(wp, sb)) {
if (window_pane_scrollbar_visible(wp, sb)) {
sb_w = wp->scrollbar_style.width;
sb_pad = wp->scrollbar_style.pad;
if (sb_overlay && sb_w > (int)wp->sx)
sb_w = wp->sx;
} else {
sb_w = 0;
sb_pad = 0;
@@ -629,9 +689,34 @@ server_client_check_mouse_in_pane(struct window_pane *wp, int px, int py,
else
pane_status_line = -1; /* not used */
bdr_left = wp->xoff - 1;
if (sb_pos == PANE_SCROLLBARS_LEFT)
if (!sb_overlay && sb_pos == PANE_SCROLLBARS_LEFT)
bdr_left -= sb_pad + sb_w;
if (sb_overlay && sb_w != 0 &&
py >= wp->yoff && py < wp->yoff + (int)wp->sy &&
px >= wp->xoff && px < wp->xoff + (int)wp->sx) {
if (sb_pos == PANE_SCROLLBARS_LEFT) {
sb_start = wp->xoff;
sb_end = sb_start + sb_w - 1;
} else {
sb_end = wp->xoff + (int)wp->sx - 1;
sb_start = sb_end - sb_w + 1;
}
if (px >= sb_start && px <= sb_end) {
sl_top = wp->yoff + wp->sb_slider_y;
sl_bottom = (wp->yoff + wp->sb_slider_y +
wp->sb_slider_h - 1);
if (py < sl_top)
return (KEYC_MOUSE_LOCATION_SCROLLBAR_UP);
else if (py >= sl_top && py <= sl_bottom) {
*sl_mpos = (py - wp->sb_slider_y - wp->yoff);
return (KEYC_MOUSE_LOCATION_SCROLLBAR_SLIDER);
} else
return (KEYC_MOUSE_LOCATION_SCROLLBAR_DOWN);
}
return (KEYC_MOUSE_LOCATION_PANE);
}
/* Check if point is within the pane or scrollbar. */
if (((pane_status != PANE_STATUS_OFF &&
py != pane_status_line && py != wp->yoff + (int)wp->sy) ||
@@ -679,7 +764,7 @@ server_client_check_mouse_in_pane(struct window_pane *wp, int px, int py,
if (window_pane_is_floating(fwp) &&
window_pane_get_pane_lines(fwp) == PANE_LINES_NONE)
continue;
if (window_pane_show_scrollbar(fwp, sb)) {
if (window_pane_scrollbar_reserve(fwp, sb)) {
sb_w = fwp->scrollbar_style.width;
sb_pad = fwp->scrollbar_style.pad;
} else {
@@ -909,10 +994,14 @@ have_event:
tty_window_offset(&c->tty, &m->ox, &m->oy, &sx, &sy);
log_debug("mouse window @%u at %u,%u (%ux%u)",
w->id, m->ox, m->oy, sx, sy);
if (px > sx || py > sy)
if (px > sx || py > sy) {
server_client_update_scrollbar_hover(c, type,
-1, -1);
return (KEYC_UNKNOWN);
}
px = px + m->ox;
py = py + m->oy;
server_client_update_scrollbar_hover(c, type, px, py);
if (type == KEYC_TYPE_MOUSEDRAG && lwp != NULL) {
/* Use pane from last mouse event. */
@@ -945,7 +1034,8 @@ have_event:
m->wp = wp->id;
m->w = wp->window->id;
}
}
} else
server_client_update_scrollbar_hover(c, type, -1, -1);
/* Reset click type or add a click timer if needed. */
if (type == KEYC_TYPE_MOUSEDOWN ||
@@ -1878,7 +1968,8 @@ server_client_reset_state(struct client *c)
mode |= MODE_MOUSE_ALL;
}
}
if (options_get_number(oo, "focus-follows-mouse"))
if (options_get_number(oo, "focus-follows-mouse") ||
options_get_number(w->options, "pane-scrollbars-auto-hide"))
mode |= MODE_MOUSE_ALL;
else if (~mode & MODE_MOUSE_ALL)
mode |= MODE_MOUSE_BUTTON;

9
tmux.h
View File

@@ -1282,6 +1282,9 @@ struct window_pane {
u_int sb_slider_y;
u_int sb_slider_h;
int sb_auto_visible;
int sb_auto_hover;
struct event sb_auto_timer;
int argc;
char **argv;
@@ -3512,6 +3515,12 @@ void window_set_fill_character(struct window *);
void window_pane_default_cursor(struct window_pane *);
int window_pane_mode(struct window_pane *);
int window_pane_show_scrollbar(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_overlay(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_start_timer(struct window_pane *);
int window_pane_get_bg(struct window_pane *);
int window_pane_get_fg(struct window_pane *);
int window_pane_get_fg_control_client(struct window_pane *);

View File

@@ -860,6 +860,7 @@ window_copy_scroll1(struct window_mode_entry *wme, struct window_pane *wp,
if (data->searchmark != NULL && !data->timeout)
window_copy_search_marks(wme, NULL, data->searchregex, 1);
window_copy_update_selection(wme, 1, 0);
window_pane_scrollbar_show(wp, 1);
window_copy_redraw_screen(wme);
}
@@ -913,6 +914,7 @@ window_copy_pageup1(struct window_mode_entry *wme, int half_page)
if (data->searchmark != NULL && !data->timeout)
window_copy_search_marks(wme, NULL, data->searchregex, 1);
window_copy_update_selection(wme, 1, 0);
window_pane_scrollbar_show(wme->wp, 1);
window_copy_redraw_screen(wme);
}
@@ -973,6 +975,7 @@ window_copy_pagedown1(struct window_mode_entry *wme, int half_page,
if (data->searchmark != NULL && !data->timeout)
window_copy_search_marks(wme, NULL, data->searchregex, 1);
window_copy_update_selection(wme, 1, 0);
window_pane_scrollbar_show(wme->wp, 1);
window_copy_redraw_screen(wme);
return (0);
}
@@ -1789,7 +1792,7 @@ window_copy_cmd_history_bottom(struct window_copy_cmd_state *cs)
struct window_mode_entry *wme = cs->wme;
struct window_copy_mode_data *data = wme->data;
struct screen *s = data->backing;
u_int oy;
u_int oy, old_oy = data->oy;
oy = screen_hsize(s) + data->cy - data->oy;
if (data->lineflag == LINE_SEL_RIGHT_LEFT && oy == data->endsely)
@@ -1802,6 +1805,8 @@ window_copy_cmd_history_bottom(struct window_copy_cmd_state *cs)
if (data->searchmark != NULL && !data->timeout)
window_copy_search_marks(wme, NULL, data->searchregex, 1);
window_copy_update_selection(wme, 1, 0);
if (data->oy != old_oy)
window_pane_scrollbar_show(wme->wp, 1);
return (WINDOW_COPY_CMD_REDRAW);
}
@@ -1810,7 +1815,7 @@ window_copy_cmd_history_top(struct window_copy_cmd_state *cs)
{
struct window_mode_entry *wme = cs->wme;
struct window_copy_mode_data *data = wme->data;
u_int oy;
u_int oy, old_oy = data->oy;
oy = screen_hsize(data->backing) + data->cy - data->oy;
if (data->lineflag == LINE_SEL_LEFT_RIGHT && oy == data->sely)
@@ -1823,6 +1828,8 @@ window_copy_cmd_history_top(struct window_copy_cmd_state *cs)
if (data->searchmark != NULL && !data->timeout)
window_copy_search_marks(wme, NULL, data->searchregex, 1);
window_copy_update_selection(wme, 1, 0);
if (data->oy != old_oy)
window_pane_scrollbar_show(wme->wp, 1);
return (WINDOW_COPY_CMD_REDRAW);
}
@@ -3772,7 +3779,7 @@ window_copy_scroll_to(struct window_mode_entry *wme, u_int px, u_int py,
{
struct window_copy_mode_data *data = wme->data;
struct grid *gd = data->backing->grid;
u_int offset, gap;
u_int offset, gap, old_oy = data->oy;
data->cx = px;
@@ -3796,6 +3803,8 @@ window_copy_scroll_to(struct window_mode_entry *wme, u_int px, u_int py,
if (!no_redraw && data->searchmark != NULL && !data->timeout)
window_copy_search_marks(wme, NULL, data->searchregex, 1);
window_copy_update_selection(wme, 1, 0);
if (data->oy != old_oy)
window_pane_scrollbar_show(wme->wp, 1);
if (!no_redraw)
window_copy_redraw_screen(wme);
}
@@ -6539,6 +6548,7 @@ window_copy_scroll_up(struct window_mode_entry *wme, u_int ny)
if (ny == 0)
return;
data->oy -= ny;
window_pane_scrollbar_show(wp, 1);
if (data->searchmark != NULL && !data->timeout)
window_copy_search_marks(wme, NULL, data->searchregex, 1);
@@ -6604,6 +6614,7 @@ window_copy_scroll_down(struct window_mode_entry *wme, u_int ny)
if (ny == 0)
return;
data->oy += ny;
window_pane_scrollbar_show(wp, 1);
if (data->searchmark != NULL && !data->timeout)
window_copy_search_marks(wme, NULL, data->searchregex, 1);

View File

@@ -126,7 +126,7 @@ window_visible_ranges(struct window_pane *base_wp, int px, int py, u_int width,
continue;
sb_w = wp->scrollbar_style.width + wp->scrollbar_style.pad;
if (!window_pane_show_scrollbar(wp, sb))
if (!window_pane_scrollbar_reserve(wp, sb))
sb_w = sb_pos = 0;
for (i = 0; i < r->used; i++) {

110
window.c
View File

@@ -71,6 +71,7 @@ struct window_pane_input_data {
static struct window_pane *window_pane_create(struct window *, u_int, u_int,
u_int);
static void window_pane_destroy(struct window_pane *);
static void window_pane_scrollbar_timer(int, short, void *);
static void window_pane_full_size_offset(struct window_pane *wp,
int *xoff, int *yoff, u_int *sx, u_int *sy);
@@ -1101,6 +1102,7 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
screen_init(&wp->status_screen, 1, 1, 0);
style_ranges_init(&wp->border_status_line.ranges);
evtimer_set(&wp->sb_auto_timer, window_pane_scrollbar_timer, wp);
if (gethostname(host, sizeof host) == 0)
screen_set_title(&wp->base, host, 0);
@@ -1132,6 +1134,31 @@ window_pane_wait_finish(struct window_pane *wp)
cmdq_continue(item);
}
static void
window_pane_scrollbar_timer(__unused int fd, __unused short events, void *arg)
{
struct window_pane *wp = arg;
if (wp->sb_auto_hover)
return;
window_pane_scrollbar_hide(wp);
}
static int
window_pane_scrollbar_auto_hide(struct window_pane *wp)
{
return (options_get_number(wp->window->options,
"pane-scrollbars-auto-hide"));
}
static void
window_pane_scrollbar_redraw(struct window_pane *wp)
{
redraw_invalidate_scene(wp->window);
wp->flags |= PANE_REDRAW;
server_redraw_window(wp->window);
}
static void
window_pane_destroy(struct window_pane *wp)
{
@@ -1164,6 +1191,8 @@ window_pane_destroy(struct window_pane *wp)
event_del(&wp->resize_timer);
if (event_initialized(&wp->sync_timer))
event_del(&wp->sync_timer);
if (event_initialized(&wp->sb_auto_timer))
event_del(&wp->sb_auto_timer);
window_pane_clear_resizes(wp, NULL);
RB_REMOVE(window_pane_tree, &all_window_panes, wp);
@@ -1540,7 +1569,7 @@ window_pane_full_size_offset(struct window_pane *wp, int *xoff, int *yoff,
pane_scrollbars = options_get_number(w->options, "pane-scrollbars");
sb_pos = options_get_number(w->options, "pane-scrollbars-position");
if (window_pane_show_scrollbar(wp, pane_scrollbars))
if (window_pane_scrollbar_reserve(wp, pane_scrollbars))
sb_w = wp->scrollbar_style.width + wp->scrollbar_style.pad;
else
sb_w = 0;
@@ -1973,6 +2002,85 @@ window_pane_show_scrollbar(struct window_pane *wp, int sb_option)
return (0);
}
int
window_pane_scrollbar_reserve(struct window_pane *wp, int sb_option)
{
if (!window_pane_show_scrollbar(wp, sb_option))
return (0);
return (!window_pane_scrollbar_auto_hide(wp));
}
int
window_pane_scrollbar_overlay(struct window_pane *wp, int sb_option)
{
if (!window_pane_show_scrollbar(wp, sb_option))
return (0);
return (window_pane_scrollbar_auto_hide(wp));
}
int
window_pane_scrollbar_visible(struct window_pane *wp, int sb_option)
{
if (!window_pane_show_scrollbar(wp, sb_option))
return (0);
if (!window_pane_scrollbar_auto_hide(wp))
return (1);
return (wp->sb_auto_visible);
}
void
window_pane_scrollbar_start_timer(struct window_pane *wp)
{
struct timeval tv;
u_int delay;
if (!window_pane_scrollbar_auto_hide(wp) || !wp->sb_auto_visible)
return;
if (wp->sb_auto_hover)
return;
delay = options_get_number(wp->window->options,
"pane-scrollbars-auto-hide-timeout");
tv.tv_sec = delay / 1000;
tv.tv_usec = (delay % 1000) * 1000L;
evtimer_del(&wp->sb_auto_timer);
evtimer_add(&wp->sb_auto_timer, &tv);
}
void
window_pane_scrollbar_show(struct window_pane *wp, int start_timer)
{
int changed = 0;
int sb;
if (!window_pane_scrollbar_auto_hide(wp))
return;
sb = options_get_number(wp->window->options, "pane-scrollbars");
if (!window_pane_show_scrollbar(wp, sb))
return;
if (!wp->sb_auto_visible) {
wp->sb_auto_visible = 1;
changed = 1;
}
evtimer_del(&wp->sb_auto_timer);
if (start_timer)
window_pane_scrollbar_start_timer(wp);
if (changed)
window_pane_scrollbar_redraw(wp);
}
void
window_pane_scrollbar_hide(struct window_pane *wp)
{
if (event_initialized(&wp->sb_auto_timer))
evtimer_del(&wp->sb_auto_timer);
wp->sb_auto_hover = 0;
if (!wp->sb_auto_visible)
return;
wp->sb_auto_visible = 0;
window_pane_scrollbar_redraw(wp);
}
int
window_pane_get_bg(struct window_pane *wp)
{