Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam 2024-11-15 16:01:11 +00:00
commit be594ff8a4
10 changed files with 190 additions and 66 deletions

View File

@ -291,7 +291,7 @@ layout_fix_panes(struct window *w, struct window_pane *skip)
{ {
struct window_pane *wp; struct window_pane *wp;
struct layout_cell *lc; struct layout_cell *lc;
int status, scrollbars, sb_pos; int status, scrollbars, sb_pos, sb_w, sb_pad;
u_int sx, sy; u_int sx, sy;
status = options_get_number(w->options, "pane-border-status"); status = options_get_number(w->options, "pane-border-status");
@ -314,11 +314,26 @@ layout_fix_panes(struct window *w, struct window_pane *skip)
} }
if (window_pane_show_scrollbar(wp, scrollbars)) { if (window_pane_show_scrollbar(wp, scrollbars)) {
sb_w = wp->scrollbar_style.width;
sb_pad = wp->scrollbar_style.pad;
if (sb_w < 1)
sb_w = 1;
if (sb_pad < 0)
sb_pad = 0;
if (sb_pos == PANE_SCROLLBARS_LEFT) { if (sb_pos == PANE_SCROLLBARS_LEFT) {
sx = sx - PANE_SCROLLBARS_WIDTH; if ((int)sx - sb_w < PANE_MINIMUM) {
wp->xoff = wp->xoff + PANE_SCROLLBARS_WIDTH; wp->xoff = wp->xoff +
(int)sx - PANE_MINIMUM;
sx = PANE_MINIMUM;
} else {
sx = sx - sb_w - sb_pad;
wp->xoff = wp->xoff + sb_w + sb_pad;
}
} else /* sb_pos == PANE_SCROLLBARS_RIGHT */ } else /* sb_pos == PANE_SCROLLBARS_RIGHT */
sx = sx - PANE_SCROLLBARS_WIDTH; if ((int)sx - sb_w - sb_pad < PANE_MINIMUM)
sx = PANE_MINIMUM;
else
sx = sx - sb_w - sb_pad;
wp->flags |= PANE_REDRAWSCROLLBAR; wp->flags |= PANE_REDRAWSCROLLBAR;
} }
@ -353,6 +368,7 @@ layout_resize_check(struct window *w, struct layout_cell *lc,
enum layout_type type) enum layout_type type)
{ {
struct layout_cell *lcchild; struct layout_cell *lcchild;
struct style *sb_style = &w->active->scrollbar_style;
u_int available, minimum; u_int available, minimum;
int status, scrollbars; int status, scrollbars;
@ -364,7 +380,8 @@ layout_resize_check(struct window *w, struct layout_cell *lc,
if (type == LAYOUT_LEFTRIGHT) { if (type == LAYOUT_LEFTRIGHT) {
available = lc->sx; available = lc->sx;
if (scrollbars) if (scrollbars)
minimum = PANE_MINIMUM + PANE_SCROLLBARS_WIDTH; minimum = PANE_MINIMUM + sb_style->width +
sb_style->pad;
else else
minimum = PANE_MINIMUM; minimum = PANE_MINIMUM;
} else { } else {
@ -891,11 +908,12 @@ struct layout_cell *
layout_split_pane(struct window_pane *wp, enum layout_type type, int size, layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
int flags) int flags)
{ {
struct layout_cell *lc, *lcparent, *lcnew, *lc1, *lc2; struct layout_cell *lc, *lcparent, *lcnew, *lc1, *lc2;
u_int sx, sy, xoff, yoff, size1, size2, minimum; struct style *sb_style = &wp->scrollbar_style;
u_int new_size, saved_size, resize_first = 0; u_int sx, sy, xoff, yoff, size1, size2, minimum;
int full_size = (flags & SPAWN_FULLSIZE), status; u_int new_size, saved_size, resize_first = 0;
int scrollbars; int full_size = (flags & SPAWN_FULLSIZE), status;
int scrollbars;
/* /*
* If full_size is specified, add a new cell at the top of the window * If full_size is specified, add a new cell at the top of the window
@ -917,9 +935,10 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
/* Check there is enough space for the two new panes. */ /* Check there is enough space for the two new panes. */
switch (type) { switch (type) {
case LAYOUT_LEFTRIGHT: case LAYOUT_LEFTRIGHT:
if (scrollbars) if (scrollbars) {
minimum = PANE_MINIMUM * 2 + PANE_SCROLLBARS_WIDTH; minimum = PANE_MINIMUM * 2 + sb_style->width +
else sb_style->pad;
} else
minimum = PANE_MINIMUM * 2 + 1; minimum = PANE_MINIMUM * 2 + 1;
if (sx < minimum) if (sx < minimum)
return (NULL); return (NULL);
@ -1081,6 +1100,7 @@ int
layout_spread_cell(struct window *w, struct layout_cell *parent) layout_spread_cell(struct window *w, struct layout_cell *parent)
{ {
struct layout_cell *lc; struct layout_cell *lc;
struct style *sb_style = &w->active->scrollbar_style;
u_int number, each, size, this; u_int number, each, size, this;
int change, changed, status, scrollbars; int change, changed, status, scrollbars;
@ -1094,7 +1114,7 @@ layout_spread_cell(struct window *w, struct layout_cell *parent)
if (parent->type == LAYOUT_LEFTRIGHT) { if (parent->type == LAYOUT_LEFTRIGHT) {
if (scrollbars) if (scrollbars)
size = parent->sx - PANE_SCROLLBARS_WIDTH; size = parent->sx - sb_style->width + sb_style->pad;
else else
size = parent->sx; size = parent->sx;
} }

View File

@ -1186,7 +1186,7 @@ const struct options_table_entry options_table[] = {
{ .name = "pane-scrollbars-style", { .name = "pane-scrollbars-style",
.type = OPTIONS_TABLE_STRING, .type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE, .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
.default_str = "bg=black,fg=white", .default_str = "bg=black,fg=white,width=1,pad=0",
.flags = OPTIONS_TABLE_IS_STYLE, .flags = OPTIONS_TABLE_IS_STYLE,
.separator = ",", .separator = ",",
.text = "Style of the pane scrollbar." .text = "Style of the pane scrollbar."

View File

@ -1177,6 +1177,15 @@ options_push_changes(const char *name)
RB_FOREACH(w, windows, &windows) RB_FOREACH(w, windows, &windows)
layout_fix_panes(w, NULL); layout_fix_panes(w, NULL);
} }
if (strcmp(name, "pane-scrollbars-style") == 0) {
RB_FOREACH(wp, window_pane_tree, &all_window_panes) {
style_set_scrollbar_style_from_option(
&wp->scrollbar_style, wp->options);
}
RB_FOREACH(w, windows, &windows)
layout_fix_panes(w, NULL);
}
if (strcmp(name, "input-buffer-size") == 0) if (strcmp(name, "input-buffer-size") == 0)
input_set_buffer_size(options_get_number(global_options, name)); input_set_buffer_size(options_get_number(global_options, name));
RB_FOREACH(s, sessions, &sessions) RB_FOREACH(s, sessions, &sessions)

View File

@ -138,7 +138,7 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
/* Are scrollbars enabled? */ /* Are scrollbars enabled? */
if (window_pane_show_scrollbar(wp, pane_scrollbars)) if (window_pane_show_scrollbar(wp, pane_scrollbars))
sb_w = PANE_SCROLLBARS_WIDTH; sb_w = wp->scrollbar_style.width + wp->scrollbar_style.pad;
/* /*
* Left/right borders. The wp->sy / 2 test is to colour only half the * Left/right borders. The wp->sy / 2 test is to colour only half the
@ -171,7 +171,7 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
} else { } else {
if (sb_pos == PANE_SCROLLBARS_LEFT) { if (sb_pos == PANE_SCROLLBARS_LEFT) {
if ((wp->xoff - sb_w == 0 || px >= wp->xoff - sb_w) && if ((wp->xoff - sb_w == 0 || px >= wp->xoff - sb_w) &&
(px <= ex || (sb_w != 0 && px - 1 == ex))) { (px <= ex || (sb_w != 0 && px < ex + sb_w))) {
if (wp->yoff != 0 && py == wp->yoff - 1) if (wp->yoff != 0 && py == wp->yoff - 1)
return (SCREEN_REDRAW_BORDER_TOP); return (SCREEN_REDRAW_BORDER_TOP);
if (py == ey) if (py == ey)
@ -179,7 +179,7 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
} }
} else { /* sb_pos == PANE_SCROLLBARS_RIGHT */ } else { /* sb_pos == PANE_SCROLLBARS_RIGHT */
if ((wp->xoff == 0 || px >= wp->xoff) && if ((wp->xoff == 0 || px >= wp->xoff) &&
(px <= ex || (sb_w != 0 && px - 1 == ex))) { (px <= ex || (sb_w != 0 && px < ex + sb_w))) {
if (wp->yoff != 0 && py == wp->yoff - 1) if (wp->yoff != 0 && py == wp->yoff - 1)
return (SCREEN_REDRAW_BORDER_TOP); return (SCREEN_REDRAW_BORDER_TOP);
if (py == ey) if (py == ey)
@ -324,7 +324,7 @@ screen_redraw_check_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py,
int border, pane_scrollbars = ctx->pane_scrollbars; int border, pane_scrollbars = ctx->pane_scrollbars;
u_int right, line; u_int right, line;
int sb_pos = ctx->pane_scrollbars_pos; int sb_pos = ctx->pane_scrollbars_pos;
int sb_w = PANE_SCROLLBARS_WIDTH; int sb_w;
*wpp = NULL; *wpp = NULL;
@ -374,6 +374,8 @@ screen_redraw_check_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py,
* pane is at the top then py == 0 to sy; if the pane * pane is at the top then py == 0 to sy; if the pane
* is not at the top, then yoff to yoff + sy. * is not at the top, then yoff to yoff + sy.
*/ */
sb_w = wp->scrollbar_style.width +
wp->scrollbar_style.pad;
if ((pane_status && py != line) || if ((pane_status && py != line) ||
(wp->yoff == 0 && py < wp->sy) || (wp->yoff == 0 && py < wp->sy) ||
(py >= wp->yoff && py < wp->yoff + wp->sy)) { (py >= wp->yoff && py < wp->yoff + wp->sy)) {
@ -948,7 +950,9 @@ screen_redraw_draw_pane_scrollbar(struct screen_redraw_ctx *ctx,
double percent_view; double percent_view;
u_int sb = ctx->pane_scrollbars, total_height, sb_h = wp->sy; u_int sb = ctx->pane_scrollbars, total_height, sb_h = wp->sy;
u_int sb_pos = ctx->pane_scrollbars_pos, slider_h, slider_y; u_int sb_pos = ctx->pane_scrollbars_pos, slider_h, slider_y;
u_int sb_w = PANE_SCROLLBARS_WIDTH, cm_y, cm_size; int sb_w = wp->scrollbar_style.width;
int sb_pad = wp->scrollbar_style.pad;
int cm_y, cm_size, xoff = wp->xoff, ox = ctx->ox;
int sb_x, sb_y = (int)(wp->yoff - ctx->oy); /* sb top */ int sb_x, sb_y = (int)(wp->yoff - ctx->oy); /* sb top */
if (window_pane_mode(wp) == WINDOW_PANE_NO_MODE) { if (window_pane_mode(wp) == WINDOW_PANE_NO_MODE) {
@ -971,9 +975,9 @@ screen_redraw_draw_pane_scrollbar(struct screen_redraw_ctx *ctx,
} }
if (sb_pos == PANE_SCROLLBARS_LEFT) if (sb_pos == PANE_SCROLLBARS_LEFT)
sb_x = (int)wp->xoff - sb_w - ctx->ox; sb_x = xoff - sb_w - sb_pad - ox;
else else
sb_x = (int)wp->xoff + wp->sx - ctx->ox; sb_x = xoff + wp->sx - ox;
if (slider_h < 1) if (slider_h < 1)
slider_h = 1; slider_h = 1;
@ -994,39 +998,42 @@ screen_redraw_draw_scrollbar(struct screen_redraw_ctx *ctx,
u_int slider_h, u_int slider_y) u_int slider_h, u_int slider_y)
{ {
struct client *c = ctx->c; struct client *c = ctx->c;
struct window *w = wp->window;
struct tty *tty = &c->tty; struct tty *tty = &c->tty;
struct grid_cell gc, slgc, *gcp; struct grid_cell gc, slgc, *gcp;
u_int i, j, sb_w = PANE_SCROLLBARS_WIDTH; struct style *sb_style = &wp->scrollbar_style;
u_int pad_col = 0; u_int i, j, imax, jmax;
u_int sb_w = sb_style->width, sb_pad = sb_style->pad;
int px, py, ox = ctx->ox, oy = ctx->oy; int px, py, ox = ctx->ox, oy = ctx->oy;
int sb_pad = PANE_SCROLLBARS_PADDING, sx = ctx->sx; int sx = ctx->sx, sy = ctx->sy, xoff = wp->xoff;
int sy = ctx->sy, xoff = wp->xoff, yoff = wp->yoff; int yoff = wp->yoff;
/* Set up default style. */
style_apply(&gc, w->options, "pane-scrollbars-style", NULL);
utf8_set(&gc.data, ' ');
/* Set up style for slider. */ /* Set up style for slider. */
gc = sb_style->gc;
memcpy(&slgc, &gc, sizeof slgc); memcpy(&slgc, &gc, sizeof slgc);
slgc.fg = gc.bg;
slgc.bg = gc.fg; slgc.bg = gc.fg;
if (sb_pad != 0) { imax = sb_w + sb_pad;
if (sb_pos == PANE_SCROLLBARS_RIGHT) if ((int)imax + sb_x > sx)
pad_col = 0; imax = sx - sb_x;
else jmax = sb_h;
pad_col = sb_w - 1; if ((int)jmax + sb_y > sy)
} jmax = sy - sb_y;
for (i = 0; i < sb_w; i++) { for (j = 0; j < jmax; j++) {
for (j = 0; j < sb_h; j++) { py = sb_y + j;
for (i = 0; i < imax; i++) {
px = sb_x + i; px = sb_x + i;
py = sb_y + j; if (px < xoff - ox - (int)sb_w - (int)sb_pad ||
if (px < xoff - ox - 1 || px >= sx || px < 0 || px >= sx || px < 0 ||
py < yoff - oy - 1 || py >= sy || py < 0) py < yoff - oy - 1 ||
py >= sy || py < 0)
continue; continue;
tty_cursor(tty, px, py); tty_cursor(tty, px, py);
if (sb_pad && i == pad_col) { if ((sb_pos == PANE_SCROLLBARS_LEFT &&
i >= sb_w && i < sb_w + sb_pad) ||
(sb_pos == PANE_SCROLLBARS_RIGHT &&
i < sb_pad)) {
tty_cell(tty, &grid_default_cell, tty_cell(tty, &grid_default_cell,
&grid_default_cell, NULL, NULL); &grid_default_cell, NULL, NULL);
} else { } else {

View File

@ -577,7 +577,7 @@ server_client_check_mouse(struct client *c, struct key_event *event)
struct window_pane *wp, *fwp; struct window_pane *wp, *fwp;
u_int x, y, b, sx, sy, px, py, line = 0, sb_pos; u_int x, y, b, sx, sy, px, py, line = 0, sb_pos;
u_int sl_top, sl_bottom, sl_mpos = 0; u_int sl_top, sl_bottom, sl_mpos = 0;
int ignore = 0, sb, sb_w, pane_status; int ignore = 0, sb, sb_w, sb_pad, pane_status;
key_code key; key_code key;
struct timeval tv; struct timeval tv;
struct style_range *sr; struct style_range *sr;
@ -779,10 +779,15 @@ have_event:
/* Try the scrollbar next to a pane. */ /* Try the scrollbar next to a pane. */
sb = options_get_number(wo, "pane-scrollbars"); sb = options_get_number(wo, "pane-scrollbars");
if (window_pane_show_scrollbar(wp, sb)) sb_pos = options_get_number(wo,
sb_w = PANE_SCROLLBARS_WIDTH; "pane-scrollbars-position");
else if (window_pane_show_scrollbar(wp, sb)) {
sb_w = wp->scrollbar_style.width;
sb_pad = wp->scrollbar_style.pad;
} else {
sb_w = 0; sb_w = 0;
sb_pad = 0;
}
pane_status = options_get_number(wo, pane_status = options_get_number(wo,
"pane-border-status"); "pane-border-status");
if (pane_status == PANE_STATUS_TOP) if (pane_status == PANE_STATUS_TOP)
@ -791,8 +796,9 @@ have_event:
line = wp->yoff + wp->sy; line = wp->yoff + wp->sy;
/* /*
* Check if py could lie within a scrollbar. If the * Check if py could lie within a scrollbar
* pane is at the top, then py is 0; if not then the * (but not within the padding). If the pane is
* at the top, then py is 0; if not then the
* top, then yoff to yoff + sy. * top, then yoff to yoff + sy.
*/ */
if ((pane_status != PANE_STATUS_OFF && py != line) || if ((pane_status != PANE_STATUS_OFF && py != line) ||
@ -801,11 +807,11 @@ have_event:
sb_pos = options_get_number(wo, sb_pos = options_get_number(wo,
"pane-scrollbars-position"); "pane-scrollbars-position");
if ((sb_pos == PANE_SCROLLBARS_RIGHT && if ((sb_pos == PANE_SCROLLBARS_RIGHT &&
(px >= wp->xoff + wp->sx && (px >= wp->xoff + wp->sx + sb_pad &&
px < wp->xoff + wp->sx + sb_w)) || px < wp->xoff + wp->sx + sb_pad + sb_w)) ||
(sb_pos == PANE_SCROLLBARS_LEFT && (sb_pos == PANE_SCROLLBARS_LEFT &&
(px >= wp->xoff - sb_w && (px >= wp->xoff - sb_pad - sb_w &&
px < wp->xoff))) { px < wp->xoff - sb_pad))) {
sl_top = wp->yoff + wp->sb_slider_y; sl_top = wp->yoff + wp->sb_slider_y;
sl_bottom = (wp->yoff + sl_bottom = (wp->yoff +
wp->sb_slider_y + wp->sb_slider_y +
@ -3678,6 +3684,8 @@ server_client_set_flags(struct client *c, const char *flags)
flag = CLIENT_IGNORESIZE; flag = CLIENT_IGNORESIZE;
else if (strcmp(next, "active-pane") == 0) else if (strcmp(next, "active-pane") == 0)
flag = CLIENT_ACTIVEPANE; flag = CLIENT_ACTIVEPANE;
else if (strcmp(next, "no-detach-on-destroy") == 0)
flag = CLIENT_NO_DETACH_ON_DESTROY;
if (flag == 0) if (flag == 0)
continue; continue;
@ -3711,6 +3719,8 @@ server_client_get_flags(struct client *c)
strlcat(s, "control-mode,", sizeof s); strlcat(s, "control-mode,", sizeof s);
if (c->flags & CLIENT_IGNORESIZE) if (c->flags & CLIENT_IGNORESIZE)
strlcat(s, "ignore-size,", sizeof s); strlcat(s, "ignore-size,", sizeof s);
if (c->flags & CLIENT_NO_DETACH_ON_DESTROY)
strlcat(s, "no-detach-on-destroy,", sizeof s);
if (c->flags & CLIENT_CONTROL_NOOUTPUT) if (c->flags & CLIENT_CONTROL_NOOUTPUT)
strlcat(s, "no-output,", sizeof s); strlcat(s, "no-output,", sizeof s);
if (c->flags & CLIENT_CONTROL_WAITEXIT) if (c->flags & CLIENT_CONTROL_WAITEXIT)

View File

@ -426,7 +426,7 @@ void
server_destroy_session(struct session *s) server_destroy_session(struct session *s)
{ {
struct client *c; struct client *c;
struct session *s_new = NULL; struct session *s_new = NULL, *cs_new, *use_s;
int detach_on_destroy; int detach_on_destroy;
detach_on_destroy = options_get_number(s->options, "detach-on-destroy"); detach_on_destroy = options_get_number(s->options, "detach-on-destroy");
@ -438,15 +438,26 @@ server_destroy_session(struct session *s)
s_new = session_previous_session(s); s_new = session_previous_session(s);
else if (detach_on_destroy == 4) else if (detach_on_destroy == 4)
s_new = session_next_session(s); s_new = session_next_session(s);
if (s_new == s)
s_new = NULL; /*
* If no suitable new session was found above, then look for any
* session as an alternative in case a client needs it.
*/
if (s_new == NULL &&
(detach_on_destroy == 1 || detach_on_destroy == 2))
cs_new = server_find_session(s, server_newer_session);
TAILQ_FOREACH(c, &clients, entry) { TAILQ_FOREACH(c, &clients, entry) {
if (c->session != s) if (c->session != s)
continue; continue;
use_s = s_new;
if (use_s == NULL && (c->flags & CLIENT_NO_DETACH_ON_DESTROY))
use_s = cs_new;
c->session = NULL; c->session = NULL;
c->last_session = NULL; c->last_session = NULL;
server_client_set_session(c, s_new); server_client_set_session(c, use_s);
if (s_new == NULL) if (use_s == NULL)
c->flags |= CLIENT_EXIT; c->flags |= CLIENT_EXIT;
} }
recalculate_sizes(); recalculate_sizes();

44
style.c
View File

@ -39,6 +39,8 @@ static struct style style_default = {
STYLE_RANGE_NONE, 0, "", STYLE_RANGE_NONE, 0, "",
STYLE_WIDTH_DEFAULT, STYLE_PAD_DEFAULT,
STYLE_DEFAULT_BASE STYLE_DEFAULT_BASE
}; };
@ -216,6 +218,16 @@ style_parse(struct style *sy, const struct grid_cell *base, const char *in)
if ((value = attributes_fromstring(tmp + 2)) == -1) if ((value = attributes_fromstring(tmp + 2)) == -1)
goto error; goto error;
sy->gc.attr &= ~value; sy->gc.attr &= ~value;
} else if (end > 6 && strncasecmp(tmp, "width=", 6) == 0) {
n = strtonum(tmp + 6, 0, UINT_MAX, &errstr);
if (errstr != NULL)
goto error;
sy->width = (int)n;
} else if (end > 4 && strncasecmp(tmp, "pad=", 4) == 0) {
n = strtonum(tmp + 4, 0, UINT_MAX, &errstr);
if (errstr != NULL)
goto error;
sy->pad = (int)n;
} else { } else {
if ((value = attributes_fromstring(tmp)) == -1) if ((value = attributes_fromstring(tmp)) == -1)
goto error; goto error;
@ -326,7 +338,16 @@ style_tostring(struct style *sy)
attributes_tostring(gc->attr)); attributes_tostring(gc->attr));
comma = ","; comma = ",";
} }
if (sy->width >= 0) {
xsnprintf(s + off, sizeof s - off, "%swidth=%u", comma,
sy->width);
comma = ",";
}
if (sy->pad >= 0) {
xsnprintf(s + off, sizeof s - off, "%spad=%u", comma,
sy->pad);
comma = ",";
}
if (*s == '\0') if (*s == '\0')
return ("default"); return ("default");
return (s); return (s);
@ -381,3 +402,24 @@ style_copy(struct style *dst, struct style *src)
{ {
memcpy(dst, src, sizeof *dst); memcpy(dst, src, sizeof *dst);
} }
void
style_set_scrollbar_style_from_option(struct style *sb_style, struct options *oo)
{
struct style *sy;
sy = options_string_to_style(oo, "pane-scrollbars-style", NULL);
if (sy == NULL) {
style_set(sb_style, &grid_default_cell);
sb_style->width = PANE_SCROLLBARS_DEFAULT_WIDTH;
sb_style->pad = PANE_SCROLLBARS_DEFAULT_PADDING;
utf8_set(&sb_style->gc.data, PANE_SCROLLBARS_CHARACTER);
} else {
style_copy(sb_style, sy);
if (sb_style->width < 1)
sb_style->width = PANE_SCROLLBARS_DEFAULT_WIDTH;
if (sb_style->pad < 0)
sb_style->pad = PANE_SCROLLBARS_DEFAULT_PADDING;
utf8_set(&sb_style->gc.data, PANE_SCROLLBARS_CHARACTER);
}
}

10
tmux.1
View File

@ -1068,6 +1068,9 @@ The flags are:
the client has an independent active pane the client has an independent active pane
.It ignore-size .It ignore-size
the client does not affect the size of other clients the client does not affect the size of other clients
.It no-detach-on-destroy
do not detach the client when the session it is attached to is destroyed if
there are any other sessions
.It no-output .It no-output
the client does not receive pane output in control mode the client does not receive pane output in control mode
.It pause-after=seconds .It pause-after=seconds
@ -5073,7 +5076,12 @@ see the
section. section.
The foreground colour is used for the slider, the background for the rest of the The foreground colour is used for the slider, the background for the rest of the
scrollbar. scrollbar.
Attributes are ignored. The
.Ar width
attribute sets the width of the scrollbar and the
.Ar pad
attribute the padding between the scrollbar and the pane.
Other attributes are ignored.
.Pp .Pp
.It Xo Ic pane-scrollbars-position .It Xo Ic pane-scrollbars-position
.Op Ic left | right .Op Ic left | right

19
tmux.h
View File

@ -872,6 +872,10 @@ struct style_range {
}; };
TAILQ_HEAD(style_ranges, style_range); TAILQ_HEAD(style_ranges, style_range);
/* Default style width and pad. */
#define STYLE_WIDTH_DEFAULT -1
#define STYLE_PAD_DEFAULT -1
/* Style default. */ /* Style default. */
enum style_default_type { enum style_default_type {
STYLE_DEFAULT_BASE, STYLE_DEFAULT_BASE,
@ -892,6 +896,9 @@ struct style {
u_int range_argument; u_int range_argument;
char range_string[16]; char range_string[16];
int width;
int pad;
enum style_default_type default_type; enum style_default_type default_type;
}; };
@ -1195,6 +1202,8 @@ struct window_pane {
int control_bg; int control_bg;
int control_fg; int control_fg;
struct style scrollbar_style;
TAILQ_ENTRY(window_pane) entry; /* link in list of all panes */ TAILQ_ENTRY(window_pane) entry; /* link in list of all panes */
TAILQ_ENTRY(window_pane) sentry; /* link in list of last visited */ TAILQ_ENTRY(window_pane) sentry; /* link in list of last visited */
RB_ENTRY(window_pane) tree_entry; RB_ENTRY(window_pane) tree_entry;
@ -1299,9 +1308,10 @@ TAILQ_HEAD(winlink_stack, winlink);
#define PANE_SCROLLBARS_RIGHT 0 #define PANE_SCROLLBARS_RIGHT 0
#define PANE_SCROLLBARS_LEFT 1 #define PANE_SCROLLBARS_LEFT 1
/* Pane scrollbars width and padding. */ /* Pane scrollbars width, padding and fill character. */
#define PANE_SCROLLBARS_WIDTH 1 #define PANE_SCROLLBARS_DEFAULT_PADDING 0
#define PANE_SCROLLBARS_PADDING 0 #define PANE_SCROLLBARS_DEFAULT_WIDTH 1
#define PANE_SCROLLBARS_CHARACTER ' '
/* True if screen in alternate screen. */ /* True if screen in alternate screen. */
#define SCREEN_IS_ALTERNATE(s) ((s)->saved_grid != NULL) #define SCREEN_IS_ALTERNATE(s) ((s)->saved_grid != NULL)
@ -1948,6 +1958,7 @@ struct client {
#define CLIENT_BRACKETPASTING 0x1000000000ULL #define CLIENT_BRACKETPASTING 0x1000000000ULL
#define CLIENT_ASSUMEPASTING 0x2000000000ULL #define CLIENT_ASSUMEPASTING 0x2000000000ULL
#define CLIENT_REDRAWSCROLLBARS 0x4000000000ULL #define CLIENT_REDRAWSCROLLBARS 0x4000000000ULL
#define CLIENT_NO_DETACH_ON_DESTROY 0x8000000000ULL
#define CLIENT_ALLREDRAWFLAGS \ #define CLIENT_ALLREDRAWFLAGS \
(CLIENT_REDRAWWINDOW| \ (CLIENT_REDRAWWINDOW| \
CLIENT_REDRAWSTATUS| \ CLIENT_REDRAWSTATUS| \
@ -3522,6 +3533,8 @@ void style_apply(struct grid_cell *, struct options *,
const char *, struct format_tree *); const char *, struct format_tree *);
void style_set(struct style *, const struct grid_cell *); void style_set(struct style *, const struct grid_cell *);
void style_copy(struct style *, struct style *); void style_copy(struct style *, struct style *);
void style_set_scrollbar_style_from_option(struct style *,
struct options *);
/* spawn.c */ /* spawn.c */
struct winlink *spawn_window(struct spawn_context *, char **); struct winlink *spawn_window(struct spawn_context *, char **);

View File

@ -603,9 +603,10 @@ window_get_active_at(struct window *w, u_int x, u_int y)
if (pane_scrollbars == PANE_SCROLLBARS_ALWAYS || if (pane_scrollbars == PANE_SCROLLBARS_ALWAYS ||
(pane_scrollbars == PANE_SCROLLBARS_MODAL && (pane_scrollbars == PANE_SCROLLBARS_MODAL &&
window_pane_mode(wp) != WINDOW_PANE_NO_MODE)) window_pane_mode(wp) != WINDOW_PANE_NO_MODE)) {
sb_w = PANE_SCROLLBARS_WIDTH; sb_w = wp->scrollbar_style.width +
else wp->scrollbar_style.pad;
} else
sb_w = 0; sb_w = 0;
if (sb_pos == PANE_SCROLLBARS_LEFT) { if (sb_pos == PANE_SCROLLBARS_LEFT) {
@ -968,6 +969,9 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
wp->control_bg = -1; wp->control_bg = -1;
wp->control_fg = -1; wp->control_fg = -1;
style_set_scrollbar_style_from_option(&wp->scrollbar_style,
wp->options);
colour_palette_init(&wp->palette); colour_palette_init(&wp->palette);
colour_palette_from_option(&wp->palette, wp->options); colour_palette_from_option(&wp->palette, wp->options);