Original changes.

This commit is contained in:
Nicholas Marriott 2024-10-28 08:45:29 +00:00
parent 914815e70f
commit aaeb8cb37d
13 changed files with 1240 additions and 167 deletions

View File

@ -30,8 +30,8 @@ const struct cmd_entry cmd_copy_mode_entry = {
.name = "copy-mode",
.alias = NULL,
.args = { "deHMs:t:uq", 0, 0, NULL },
.usage = "[-deHMuq] [-s src-pane] " CMD_TARGET_PANE_USAGE,
.args = { "deHMs:t:uqS", 0, 0, NULL },
.usage = "[-deHMuqS] [-s src-pane] " CMD_TARGET_PANE_USAGE,
.source = { 's', CMD_FIND_PANE, 0 },
.target = { 't', CMD_FIND_PANE, 0 },
@ -92,7 +92,12 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item)
if (args_has(args, 'u'))
window_copy_pageup(wp, 0);
if (args_has(args, 'd'))
window_copy_pagedown(wp, 0, args_has(args, 'e'));
window_copy_pagedown(wp, 0, args_has(args, 'e'));
if (args_has(args, 'S')) {
window_copy_scroll(wp, c->tty.mouse_slider_mpos,
event->m.y, args_has(args, 'e'));
return (CMD_RETURN_NORMAL);
}
return (CMD_RETURN_NORMAL);
}

View File

@ -219,6 +219,7 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
free(title);
return (CMD_RETURN_NORMAL);
}
wp->flags |= PANE_REDRAWSCROLLBAR;
if (c != NULL && c->session != NULL && (c->flags & CLIENT_ACTIVEPANE))
activewp = server_client_get_pane(c);

View File

@ -640,6 +640,9 @@ key_bindings_init(void)
"bind -Tcopy-mode-vi M-x { send -X jump-to-mark }",
"bind -Tcopy-mode-vi C-Up { send -X scroll-up }",
"bind -Tcopy-mode-vi C-Down { send -X scroll-down }",
"bind -n MouseDown1ScrollbarUp { copy-mode -u }",
"bind -n MouseDown1ScrollbarDown { copy-mode -d }",
"bind -n MouseDrag1ScrollbarSlider { copy-mode -S }"
};
u_int i;
struct cmd_parse_result *pr;

View File

@ -119,7 +119,7 @@ layout_print_cell(struct layout_cell *lc, const char *hdr, u_int n)
case LAYOUT_LEFTRIGHT:
case LAYOUT_TOPBOTTOM:
TAILQ_FOREACH(lcchild, &lc->cells, entry)
layout_print_cell(lcchild, hdr, n + 1);
layout_print_cell(lcchild, hdr, n + 1);
break;
case LAYOUT_WINDOWPANE:
break;
@ -230,7 +230,7 @@ layout_fix_offsets1(struct layout_cell *lc)
void
layout_fix_offsets(struct window *w)
{
struct layout_cell *lc = w->layout_root;
struct layout_cell *lc = w->layout_root;
lc->xoff = 0;
lc->yoff = 0;
@ -275,7 +275,8 @@ layout_cell_is_bottom(struct window *w, struct layout_cell *lc)
* the case for the most upper or lower panes only.
*/
static int
layout_add_border(struct window *w, struct layout_cell *lc, int status)
layout_add_horizontal_border(struct window *w, struct layout_cell *lc,
int status)
{
if (status == PANE_STATUS_TOP)
return (layout_cell_is_top(w, lc));
@ -290,22 +291,46 @@ layout_fix_panes(struct window *w, struct window_pane *skip)
{
struct window_pane *wp;
struct layout_cell *lc;
int status;
int status, scrollbars, sb_pos, sb_w;
u_int sx, sy;
u_int mode;
status = options_get_number(w->options, "pane-border-status");
scrollbars = options_get_number(w->options, "pane-scrollbars");
sb_pos = options_get_number(w->options, "pane-scrollbars-position");
sb_w = PANE_SCROLLBARS_WIDTH;
TAILQ_FOREACH(wp, &w->panes, entry) {
if ((lc = wp->layout_cell) == NULL || wp == skip)
continue;
wp->xoff = lc->xoff;
wp->yoff = lc->yoff;
sx = lc->sx;
sy = lc->sy;
if (layout_add_border(w, lc, status)) {
if (layout_add_horizontal_border(w, lc, status)) {
if (status == PANE_STATUS_TOP)
wp->yoff++;
window_pane_resize(wp, lc->sx, lc->sy - 1);
} else
window_pane_resize(wp, lc->sx, lc->sy);
sy = sy - 1;
}
mode = window_pane_mode(wp);
if ((scrollbars == PANE_SCROLLBARS_ALWAYS) ||
(scrollbars == PANE_SCROLLBARS_MODAL &&
mode != WINDOW_PANE_NO_MODE)) {
if (sb_pos == PANE_SCROLLBARS_LEFT) {
sx = sx - sb_w;
wp->xoff = wp->xoff + sb_w;
} else {
/* sb_pos == PANE_SCROLLBARS_RIGHT */
sx = sx - sb_w;
}
wp->flags |= PANE_REDRAWSCROLLBAR;
}
window_pane_resize(wp, sx, sy);
}
}
@ -337,17 +362,23 @@ layout_resize_check(struct window *w, struct layout_cell *lc,
{
struct layout_cell *lcchild;
u_int available, minimum;
int status;
int status, scrollbars, sb_w;
status = options_get_number(w->options, "pane-border-status");
scrollbars = options_get_number(w->options, "pane-scrollbars");
sb_w = PANE_SCROLLBARS_WIDTH;
if (lc->type == LAYOUT_WINDOWPANE) {
/* Space available in this cell only. */
if (type == LAYOUT_LEFTRIGHT) {
available = lc->sx;
minimum = PANE_MINIMUM;
if (scrollbars)
minimum = PANE_MINIMUM + sb_w;
else
minimum = PANE_MINIMUM;
} else {
available = lc->sy;
if (layout_add_border(w, lc, status))
if (layout_add_horizontal_border(w, lc, status))
minimum = PANE_MINIMUM + 1;
else
minimum = PANE_MINIMUM;
@ -872,7 +903,8 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
struct layout_cell *lc, *lcparent, *lcnew, *lc1, *lc2;
u_int sx, sy, xoff, yoff, size1, size2, minimum;
u_int new_size, saved_size, resize_first = 0;
int full_size = (flags & SPAWN_FULLSIZE), status;
int full_size = (flags & SPAWN_FULLSIZE);
int status, scrollbars, sb_w;
/*
* If full_size is specified, add a new cell at the top of the window
@ -883,6 +915,8 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
else
lc = wp->layout_cell;
status = options_get_number(wp->window->options, "pane-border-status");
scrollbars = options_get_number(wp->window->options, "pane-scrollbars");
sb_w = PANE_SCROLLBARS_WIDTH;
/* Copy the old cell size. */
sx = lc->sx;
@ -893,11 +927,15 @@ 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 (sx < PANE_MINIMUM * 2 + 1)
if (scrollbars)
minimum = PANE_MINIMUM * 2 + sb_w;
else
minimum = PANE_MINIMUM * 2 + 1;
if (sx < minimum)
return (NULL);
break;
case LAYOUT_TOPBOTTOM:
if (layout_add_border(wp->window, lc, status))
if (layout_add_horizontal_border(wp->window, lc, status))
minimum = PANE_MINIMUM * 2 + 2;
else
minimum = PANE_MINIMUM * 2 + 1;
@ -1054,7 +1092,7 @@ layout_spread_cell(struct window *w, struct layout_cell *parent)
{
struct layout_cell *lc;
u_int number, each, size, this;
int change, changed, status;
int change, changed, status, scrollbars, sb_w;
number = 0;
TAILQ_FOREACH (lc, &parent->cells, entry)
@ -1062,11 +1100,17 @@ layout_spread_cell(struct window *w, struct layout_cell *parent)
if (number <= 1)
return (0);
status = options_get_number(w->options, "pane-border-status");
scrollbars = options_get_number(w->options, "pane-scrollbars");
sb_w = PANE_SCROLLBARS_WIDTH;
if (parent->type == LAYOUT_LEFTRIGHT)
size = parent->sx;
if (parent->type == LAYOUT_LEFTRIGHT) {
if (scrollbars)
size = parent->sx - sb_w;
else
size = parent->sx;
}
else if (parent->type == LAYOUT_TOPBOTTOM) {
if (layout_add_border(w, parent, status))
if (layout_add_horizontal_border(w, parent, status))
size = parent->sy - 1;
else
size = parent->sy;
@ -1087,7 +1131,7 @@ layout_spread_cell(struct window *w, struct layout_cell *parent)
change = each - (int)lc->sx;
layout_resize_adjust(w, lc, LAYOUT_LEFTRIGHT, change);
} else if (parent->type == LAYOUT_TOPBOTTOM) {
if (layout_add_border(w, lc, status))
if (layout_add_horizontal_border(w, lc, status))
this = each + 1;
else
this = each;

View File

@ -63,6 +63,12 @@ static const char *options_table_cursor_style_list[] = {
"default", "blinking-block", "block", "blinking-underline", "underline",
"blinking-bar", "bar", NULL
};
static const char *options_table_pane_scrollbars_list[] = {
"off", "modal", "on", NULL
};
static const char *options_table_pane_scrollbars_position_list[] = {
"right", "left", NULL
};
static const char *options_table_pane_status_list[] = {
"off", "top", "bottom", NULL
};
@ -1160,7 +1166,32 @@ const struct options_table_entry options_table[] = {
.text = "The default colour palette for colours zero to 255."
},
{ .name = "popup-style",
{ .name = "pane-scrollbars",
.type = OPTIONS_TABLE_CHOICE,
.scope = OPTIONS_TABLE_WINDOW,
.choices = options_table_pane_scrollbars_list,
.default_num = PANE_SCROLLBARS_OFF,
.text = "Pane scrollbar state."
},
{ .name = "pane-scrollbars-style",
.type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
.default_str = "bg=black,fg=white",
.flags = OPTIONS_TABLE_IS_STYLE,
.separator = ",",
.text = "Style of the pane scrollbar."
},
{ .name = "pane-scrollbars-position",
.type = OPTIONS_TABLE_CHOICE,
.scope = OPTIONS_TABLE_WINDOW,
.choices = options_table_pane_scrollbars_position_list,
.default_num = PANE_SCROLLBARS_RIGHT,
.text = "Pane scrollbar position."
},
{ .name = "popup-style",
.type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW,
.default_str = "default",

View File

@ -425,7 +425,7 @@ options_array_set(struct options_entry *o, u_int idx, const char *value,
struct options_array_item *a;
char *new;
struct cmd_parse_result *pr;
long long number;
long long number;
if (!OPTIONS_IS_ARRAY(o)) {
if (cause != NULL)
@ -1175,6 +1175,11 @@ options_push_changes(const char *name)
RB_FOREACH(w, windows, &windows)
layout_fix_panes(w, NULL);
}
if (strcmp(name, "pane-scrollbars") == 0 ||
strcmp(name, "pane-scrollbars-position") == 0) {
RB_FOREACH(w, windows, &windows)
layout_fix_panes(w, NULL);
}
RB_FOREACH(s, sessions, &sessions)
status_update_cache(s);

View File

@ -30,6 +30,13 @@ static void screen_redraw_draw_pane(struct screen_redraw_ctx *,
struct window_pane *);
static void screen_redraw_set_context(struct client *,
struct screen_redraw_ctx *);
static void screen_redraw_draw_pane_scrollbars(struct screen_redraw_ctx *);
static void screen_redraw_draw_scrollbar(struct client *,
struct window_pane *, int, u_int, u_int, u_int, u_int,
u_int);
static void screen_redraw_draw_pane_scrollbar(struct screen_redraw_ctx *,
struct window_pane *);
#define START_ISOLATE "\342\201\246"
#define END_ISOLATE "\342\201\251"
@ -107,15 +114,81 @@ screen_redraw_two_panes(struct window *w, int direction)
return (1);
}
/*
* This is how panes are referenced in screen_redraw_pane_border:
*
* sb_pos == PANE_SCROLLBARS_RIGHT:
*
* .0................o..............X.
* :a zSSSBa zSSS: <- dotted border is outside of tmux,
* |___wp->sx___|_| |___wp->sx___|_| this is the terminal window
* | sb_w^ | sb_w^
* ^wp->xoff ^wp->xoff
*
* sb_pos == PANE_SCROLLBARS_LEFT:
*
* .0...................o...........X.
* :SSSa zBSSSa z: <- Notes, see below
* |_||___wp->sx___||_||___wp->sx___|
* sb_w^ | sb_w^ |
* ^wp->xoff ^wp->xoff
*
* Terminal window tmux runs inide is X+1 characters wide
* 0 is the first column of the terminal
* X is the last column of the terminal, so 0-79 is 80 chars wide (px is [0..X])
* o is the offset of righthand pane in diagram (not a variable)
* a is the first column of each pane
* z is the last column of each pane
* wp->xoff (rel to terminal) is character offset of the pane,
* it will be 0 for left pane and o for right pane above.
* wp->sx is size of pane (usable width of pane in characters)
* sb_w is the width of the scrollbar in characters
* S is the scrollbar, (in this example sb_w would be 3)
* B is the pane border, if there is a right and left and they are superimposed
*
* The vertical situation looks like this:
* .....
* :Border (if pane-border-status==top)
* 0: | <- wp->yoff
* : |
* : |
* : wp->sy
* : |
* : |
* :Border
* o: | <- wp->yoff
* : |
* : |
* : wp->sy
* : |
* : |
* :Border (if pane-border-status==bottom)
* Y:Status line(s)
* .....
*
* 0 is first line of terminal
* Y is last line of terminal (py is [0..Y])
* o is the offset of the lower window in diagram (not a variable)
* wp->yoff (rel to terminal) is first line of pane
* wp->sy is usable size of pane in lines (6 in above example)
* There can be zero to 5 status lines
* Panes can have an optional border status
*
*/
/* Check if cell is on the border of a pane. */
static enum screen_redraw_border_type
screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
u_int px, u_int py)
{
struct options *oo = wp->window->options;
int split = 0;
int hsplit = 0;
int vsplit = 0;
u_int ex = wp->xoff + wp->sx, ey = wp->yoff + wp->sy;
int pane_status = ctx->pane_status;
int pane_scrollbars = ctx->pane_scrollbars;
int sb_pos = ctx->pane_scrollbars_pos;
int sb_w = PANE_SCROLLBARS_WIDTH;
/* Inside pane. */
if (px >= wp->xoff && px < ex && py >= wp->yoff && py < ey)
@ -125,62 +198,85 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
switch (options_get_number(oo, "pane-border-indicators")) {
case PANE_BORDER_COLOUR:
case PANE_BORDER_BOTH:
split = 1;
hsplit = screen_redraw_two_panes(wp->window, 0);
vsplit = screen_redraw_two_panes(wp->window, 1);
break;
}
/* Left/right borders. */
if (pane_status == PANE_STATUS_OFF) {
if (screen_redraw_two_panes(wp->window, 0) && split) {
if (wp->xoff == 0 && px == wp->sx && py <= wp->sy / 2)
return (SCREEN_REDRAW_BORDER_RIGHT);
if (wp->xoff != 0 &&
px == wp->xoff - 1 &&
py > wp->sy / 2)
return (SCREEN_REDRAW_BORDER_LEFT);
} else {
if ((wp->yoff == 0 || py >= wp->yoff - 1) && py <= ey) {
if (wp->xoff != 0 && px == wp->xoff - 1)
return (SCREEN_REDRAW_BORDER_LEFT);
if (px == ex)
return (SCREEN_REDRAW_BORDER_RIGHT);
}
}
if (pane_scrollbars == PANE_SCROLLBARS_ALWAYS ||
(pane_scrollbars == PANE_SCROLLBARS_MODAL &&
window_pane_mode(wp) != WINDOW_PANE_NO_MODE)) {
pane_scrollbars = 1;
} else {
if ((wp->yoff == 0 || py >= wp->yoff - 1) && py <= ey) {
if (wp->xoff != 0 && px == wp->xoff - 1)
return (SCREEN_REDRAW_BORDER_LEFT);
if (px == ex)
return (SCREEN_REDRAW_BORDER_RIGHT);
sb_w = 0;
}
/* Left/right borders.
*
* The wp->sy / 2 test is used to show half the active
* window's border and the other half the other
* window. It's easy to do this when 1 window
* vertically, so this feature only works when there's
* exactly 2 side-by-side panes. This could be
* genralised in the future.
*/
if ((wp->yoff == 0 || py >= wp->yoff - 1) && py <= ey) {
if (sb_pos == PANE_SCROLLBARS_LEFT) {
if (wp->xoff - sb_w == 0 &&
px == wp->sx + sb_w)
if (!hsplit || (hsplit && py <= wp->sy / 2))
return (SCREEN_REDRAW_BORDER_RIGHT);
if (wp->xoff - sb_w != 0 &&
px == wp->xoff - sb_w - 1)
if (!hsplit || (hsplit && py > wp->sy / 2))
return (SCREEN_REDRAW_BORDER_LEFT);
} else {
/* sb_pos == PANE_SCROLLBARS_RIGHT */
if (wp->xoff == 0 &&
px == wp->sx + sb_w)
if (!hsplit || (hsplit && py <= wp->sy / 2))
return (SCREEN_REDRAW_BORDER_RIGHT);
if (wp->xoff != 0 &&
px == wp->xoff - 1)
if (!hsplit || (hsplit && py > wp->sy / 2))
return (SCREEN_REDRAW_BORDER_LEFT);
}
}
/* Top/bottom borders. */
if (pane_status == PANE_STATUS_OFF) {
if (screen_redraw_two_panes(wp->window, 1) && split) {
if (wp->yoff == 0 && py == wp->sy && px <= wp->sx / 2)
return (SCREEN_REDRAW_BORDER_BOTTOM);
if (wp->yoff != 0 &&
py == wp->yoff - 1 &&
px > wp->sx / 2)
return (SCREEN_REDRAW_BORDER_TOP);
} else {
if ((wp->xoff == 0 || px >= wp->xoff - 1) && px <= ex) {
if (wp->yoff != 0 && py == wp->yoff - 1)
if (vsplit &&
pane_status == PANE_STATUS_OFF &&
pane_scrollbars == PANE_SCROLLBARS_OFF) {
if (wp->yoff == 0 &&
py == wp->sy &&
px <= wp->sx / 2)
return (SCREEN_REDRAW_BORDER_BOTTOM);
if (wp->yoff != 0 &&
py == wp->yoff - 1 &&
px > wp->sx / 2)
return (SCREEN_REDRAW_BORDER_TOP);
} else {
if (sb_pos == PANE_SCROLLBARS_LEFT) {
if ((wp->xoff - sb_w == 0 || px >= wp->xoff - sb_w) &&
(px <= ex ||
(pane_scrollbars && px - 1 == ex))) {
if (wp->yoff != 0 &&
py == wp->yoff - 1)
return (SCREEN_REDRAW_BORDER_TOP);
if (py == ey)
return (SCREEN_REDRAW_BORDER_BOTTOM);
}
} else {
/* sb_pos == PANE_SCROLLBARS_RIGHT */
if ((wp->xoff == 0 || px >= wp->xoff) &&
(px <= ex ||
(pane_scrollbars && px - 1 == ex))) {
if (wp->yoff != 0 &&
py == wp->yoff - 1)
return (SCREEN_REDRAW_BORDER_TOP);
if (py == ey)
return (SCREEN_REDRAW_BORDER_BOTTOM);
}
}
} else if (pane_status == PANE_STATUS_TOP) {
if ((wp->xoff == 0 || px >= wp->xoff - 1) && px <= ex) {
if (wp->yoff != 0 && py == wp->yoff - 1)
return (SCREEN_REDRAW_BORDER_TOP);
}
} else {
if ((wp->xoff == 0 || px >= wp->xoff - 1) && px <= ex) {
if (py == ey)
return (SCREEN_REDRAW_BORDER_BOTTOM);
}
}
@ -243,8 +339,12 @@ screen_redraw_type_of_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py)
return (CELL_OUTSIDE);
/*
* Construct a bitmask of whether the cells to the left (bit 4), right,
* Construct a bitmask of whether the cells to the left (bit 8), right,
* top, and bottom (bit 1) of this cell are borders.
*
* bits 8 4 2 1: 2
* 8 + 4
* 1
*/
if (px == 0 || screen_redraw_cell_border(ctx, px - 1, py))
borders |= 8;
@ -315,6 +415,9 @@ screen_redraw_check_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py,
u_int sx = w->sx, sy = w->sy;
int border;
u_int right, line;
int pane_scrollbars = ctx->pane_scrollbars;
int sb_pos = ctx->pane_scrollbars_pos;
int sb_w = PANE_SCROLLBARS_WIDTH;
*wpp = NULL;
@ -351,6 +454,37 @@ screen_redraw_check_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py,
goto next2;
*wpp = wp;
/* Check if CELL_SCROLLBAR */
if (pane_scrollbars == PANE_SCROLLBARS_ALWAYS ||
(pane_scrollbars == PANE_SCROLLBARS_MODAL &&
window_pane_mode(wp) != WINDOW_PANE_NO_MODE)) {
if (pane_status == PANE_STATUS_TOP)
line = wp->yoff - 1;
else
line = wp->yoff + wp->sy;
/* check if py could lie within a scroller
* if pane at the top then py==0 included
* if pane not at the top, then yoff to yoff+sy
*/
if ((pane_status && py != line) ||
(wp->yoff == 0 && py < wp->sy) ||
(py >= wp->yoff && py < wp->yoff + wp->sy)) {
/* check if px lies within a scroller
*/
if ((sb_pos == PANE_SCROLLBARS_RIGHT &&
(px >= wp->xoff + wp->sx &&
px < wp->xoff + wp->sx + sb_w)) ||
(sb_pos == PANE_SCROLLBARS_LEFT &&
(px >= wp->xoff - sb_w &&
px < wp->xoff))) {
return (CELL_SCROLLBAR);
}
}
}
/*
* If definitely inside, return. If not on border, skip.
* Otherwise work out the cell.
@ -510,14 +644,13 @@ screen_redraw_draw_pane_status(struct screen_redraw_ctx *ctx)
/* Update status line and change flags if unchanged. */
static uint64_t
screen_redraw_update(struct client *c, uint64_t flags)
screen_redraw_update(struct screen_redraw_ctx *ctx, uint64_t flags)
{
struct client *c = ctx->c;
struct window *w = c->session->curw->window;
struct window_pane *wp;
struct options *wo = w->options;
int redraw;
enum pane_lines lines;
struct screen_redraw_ctx ctx;
if (c->message_string != NULL)
redraw = status_message_redraw(c);
@ -531,17 +664,17 @@ screen_redraw_update(struct client *c, uint64_t flags)
if (c->overlay_draw != NULL)
flags |= CLIENT_REDRAWOVERLAY;
if (options_get_number(wo, "pane-border-status") != PANE_STATUS_OFF) {
screen_redraw_set_context(c, &ctx);
lines = options_get_number(wo, "pane-border-lines");
if (ctx->pane_status != PANE_STATUS_OFF) {
lines = ctx->pane_lines;
redraw = 0;
TAILQ_FOREACH(wp, &w->panes, entry) {
if (screen_redraw_make_pane_status(c, wp, &ctx, lines))
if (screen_redraw_make_pane_status(c, wp, ctx, lines))
redraw = 1;
}
if (redraw)
flags |= CLIENT_REDRAWBORDERS;
}
return (flags);
}
@ -568,6 +701,10 @@ screen_redraw_set_context(struct client *c, struct screen_redraw_ctx *ctx)
ctx->pane_status = options_get_number(wo, "pane-border-status");
ctx->pane_lines = options_get_number(wo, "pane-border-lines");
ctx->pane_scrollbars = options_get_number(wo, "pane-scrollbars");
ctx->pane_scrollbars_pos =
options_get_number(wo, "pane-scrollbars-position");
tty_window_offset(&c->tty, &ctx->ox, &ctx->oy, &ctx->sx, &ctx->sy);
log_debug("%s: %s @%u ox=%u oy=%u sx=%u sy=%u %u/%d", __func__, c->name,
@ -585,11 +722,12 @@ screen_redraw_screen(struct client *c)
if (c->flags & CLIENT_SUSPENDED)
return;
flags = screen_redraw_update(c, c->flags);
screen_redraw_set_context(c, &ctx);
flags = screen_redraw_update(&ctx, c->flags);
if ((flags & CLIENT_ALLREDRAWFLAGS) == 0)
return;
screen_redraw_set_context(c, &ctx);
tty_sync_start(&c->tty);
tty_update_mode(&c->tty, c->tty.mode, NULL);
@ -598,10 +736,12 @@ screen_redraw_screen(struct client *c)
screen_redraw_draw_borders(&ctx);
if (ctx.pane_status != PANE_STATUS_OFF)
screen_redraw_draw_pane_status(&ctx);
screen_redraw_draw_pane_scrollbars(&ctx);
}
if (flags & CLIENT_REDRAWWINDOW) {
log_debug("%s: redrawing panes", c->name);
screen_redraw_draw_panes(&ctx);
screen_redraw_draw_pane_scrollbars(&ctx);
}
if (ctx.statuslines != 0 &&
(flags & (CLIENT_REDRAWSTATUS|CLIENT_REDRAWSTATUSALWAYS))) {
@ -616,11 +756,13 @@ screen_redraw_screen(struct client *c)
tty_reset(&c->tty);
}
/* Redraw a single pane. */
/* Redraw a single pane and its scrollbar. */
void
screen_redraw_pane(struct client *c, struct window_pane *wp)
{
struct screen_redraw_ctx ctx;
int pane_scrollbars;
int pane_mode;
if (!window_pane_visible(wp))
return;
@ -631,6 +773,26 @@ screen_redraw_pane(struct client *c, struct window_pane *wp)
screen_redraw_draw_pane(&ctx, wp);
/* Redraw scrollbar if needed. Always redraw scrollbar
* in a mode because if redrawing a pane, it's because
* pane has scrolled.
*/
pane_mode = window_pane_mode(wp);
if (wp->flags & PANE_REDRAWSCROLLBAR ||
pane_mode != WINDOW_PANE_NO_MODE) {
pane_scrollbars = ctx.pane_scrollbars;
if (pane_scrollbars == PANE_SCROLLBARS_MODAL &&
pane_mode == WINDOW_PANE_NO_MODE) {
pane_scrollbars = 0;
}
if (pane_scrollbars != 0) {
screen_redraw_draw_pane_scrollbar(&ctx, wp);
}
}
tty_reset(&c->tty);
}
@ -651,10 +813,13 @@ screen_redraw_draw_borders_style(struct screen_redraw_ctx *ctx, u_int x,
wp->border_gc_set = 1;
ft = format_create_defaults(NULL, c, s, s->curw, wp);
if (screen_redraw_check_is(ctx, x, y, active))
style_apply(&wp->border_gc, oo, "pane-active-border-style", ft);
else
if (screen_redraw_check_is(ctx, x, y, active)) {
log_debug("%s: %s y:%u active", __func__, c->name, y);
style_apply(&wp->border_gc, oo, "pane-active-border-style", ft);
} else {
log_debug("%s: %s y:%u", __func__, c->name, y);
style_apply(&wp->border_gc, oo, "pane-border-style", ft);
}
format_free(ft);
return (&wp->border_gc);
@ -685,7 +850,7 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j)
}
cell_type = screen_redraw_check_cell(ctx, x, y, &wp);
if (cell_type == CELL_INSIDE)
if (cell_type == CELL_INSIDE || cell_type == CELL_SCROLLBAR)
return;
if (wp == NULL) {
@ -874,3 +1039,151 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
tty_draw_images(c, wp, s);
#endif
}
/* Draw the panes scrollbars */
static void
screen_redraw_draw_pane_scrollbars(struct screen_redraw_ctx *ctx)
{
struct client *c = ctx->c;
struct window *w = c->session->curw->window;
struct window_pane *wp;
log_debug("%s: %s @%u", __func__, c->name, w->id);
TAILQ_FOREACH(wp, &w->panes, entry) {
switch(ctx->pane_scrollbars) {
case PANE_SCROLLBARS_OFF:
return;
case PANE_SCROLLBARS_MODAL:
if (window_pane_mode(wp) == WINDOW_PANE_NO_MODE)
return;
break;
case PANE_SCROLLBARS_ALWAYS:
break;
}
if (window_pane_visible(wp))
screen_redraw_draw_pane_scrollbar(ctx, wp);
}
}
/* Draw scrollbar
*
* sb_x and sb_y are the upper left character of the scrollbar
* sb_h is scrollbar height, the number of lines in the scrollbar
* slider_h is the height of the slider in lines
* slider_y is the line within sb_h of the current vertical position
* The height and position of the slider are proportional to the number of
* lines in the scroll back buffer + number of lines on the screen
* (total_height) and the percentage of the number of visible lines to the
* total height (percent_view).
*/
void
screen_redraw_draw_pane_scrollbar(struct screen_redraw_ctx *ctx,
struct window_pane *wp)
{
struct client *c = ctx->c;
struct screen *s = wp->screen;
double percent_view;
u_int sb = ctx->pane_scrollbars;
u_int sb_pos = ctx->pane_scrollbars_pos;
u_int sb_w = PANE_SCROLLBARS_WIDTH;
u_int sb_x;
u_int sb_y = wp->yoff;
u_int sb_h = wp->sy;
u_int slider_h;
u_int slider_y;
u_int total_height;
if (window_pane_mode(wp) == WINDOW_PANE_NO_MODE) {
/* not in a mode */
if (sb == PANE_SCROLLBARS_MODAL) {
return;
}
/* show slider at the bottom of the scrollbar */
total_height = screen_size_y(s) + screen_hsize(s);
percent_view = (double)sb_h / total_height;
slider_h = (u_int)((double)sb_h * percent_view);
slider_y = sb_h - slider_h;
} else {
/* copy-mode or view-mode */
u_int cm_y_pos, cm_size;
if (TAILQ_FIRST(&wp->modes) == NULL ||
window_copy_get_current_offset(wp, &cm_y_pos, &cm_size) == 0)
return;
total_height = cm_size + sb_h;
percent_view = (double)sb_h / (cm_size + sb_h);
slider_h = (u_int)((double)sb_h * percent_view);
slider_y = (u_int)(sb_h + 1) * ((double)cm_y_pos / total_height);
}
if (sb_pos == PANE_SCROLLBARS_LEFT)
sb_x = wp->xoff - sb_w;
else
sb_x = wp->xoff + wp->sx;
if (slider_h < 1)
slider_h = 1;
if (slider_y >= sb_h)
slider_y = sb_h - 1;
screen_redraw_draw_scrollbar(c, wp, sb_pos, sb_x, sb_y, sb_h,
slider_h, slider_y);
/* Store current position and height of the slider */
wp->sb_slider_y = slider_y; /* top of slider y pos in scrollbar */
wp->sb_slider_h = slider_h; /* height of slider */
}
static void
screen_redraw_draw_scrollbar(struct client *c, struct window_pane *wp,
int sb_pos, u_int px, u_int py, u_int sb_h, u_int slider_h, u_int slider_y)
{
struct window *w = wp->window;
struct tty *tty = &c->tty;
struct grid_cell gc;
u_int i, j;
int fg, bg;
u_int pad_col = 0;
u_int sb_w = PANE_SCROLLBARS_WIDTH;
u_int sb_pad = PANE_SCROLLBARS_PADDING;
log_debug("%s: scrollbar pos:%d w:%u @%u,%u h:%u eh:%u ep:%u",
__func__, sb_pos, sb_w, px, py, sb_h, slider_h, slider_y);
/* Set up default colour. */
style_apply(&gc, w->options, "pane-scrollbars-style", NULL);
fg = gc.fg;
bg = gc.bg;
utf8_set(&gc.data, ' ');
if (sb_pad) {
if (sb_pos == PANE_SCROLLBARS_RIGHT)
pad_col = 0;
else
pad_col = sb_w - 1;
}
gc.bg = bg;
for (i = 0; i < sb_w; i++) {
for (j = 0; j < sb_h; j++) {
tty_cursor(tty, px+i, py+j);
if (sb_pad && i==pad_col) {
tty_cell(tty, &grid_default_cell,
&grid_default_cell, NULL, NULL);
} else {
if (j >= slider_y && j < slider_y + slider_h) {
gc.bg = fg;
gc.fg = bg;
} else {
gc.bg = bg;
gc.fg = fg;
}
tty_cell(tty, &gc, &grid_default_cell, NULL,
NULL);
}
}
}
}

View File

@ -151,7 +151,7 @@ screen_write_set_client_cb(struct tty_ctx *ttyctx, struct client *c)
*/
log_debug("%s: adding %%%u to deferred redraw", __func__,
wp->id);
wp->flags |= PANE_REDRAW;
wp->flags |= (PANE_REDRAW|PANE_REDRAWSCROLLBAR);
return (-1);
}
@ -1792,6 +1792,9 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
ttyctx.num = ctx->scrolled;
ttyctx.bg = ctx->bg;
tty_write(tty_cmd_scrollup, &ttyctx);
if (ctx->wp != NULL)
ctx->wp->flags |= PANE_REDRAWSCROLLBAR;
}
ctx->scrolled = 0;
ctx->bg = 8;

View File

@ -66,7 +66,7 @@ RB_GENERATE(client_windows, client_window, entry, server_client_window_cmp);
u_int
server_client_how_many(void)
{
struct client *c;
struct client *c;
u_int n;
n = 0;
@ -572,6 +572,7 @@ server_client_check_mouse(struct client *c, struct key_event *event)
{
struct mouse_event *m = &event->m;
struct session *s = c->session, *fs;
struct options *wo = s->curw->window->options;
struct winlink *fwl;
struct window_pane *wp, *fwp;
u_int x, y, b, sx, sy, px, py;
@ -579,6 +580,9 @@ server_client_check_mouse(struct client *c, struct key_event *event)
key_code key;
struct timeval tv;
struct style_range *sr;
int pane_scrollbars, sb_w, pane_status;
u_int line = 0, sb_pos;
u_int slider_top, slider_bottom, where_in_slider = 0;
enum { NOTYPE,
MOVE,
DOWN,
@ -594,7 +598,11 @@ server_client_check_mouse(struct client *c, struct key_event *event)
STATUS_LEFT,
STATUS_RIGHT,
STATUS_DEFAULT,
BORDER } where = NOWHERE;
BORDER,
SCROLLBAR_UP,
SCROLLBAR_SLIDER,
SCROLLBAR_DOWN,
} where = NOWHERE;
log_debug("%s mouse %02x at %u,%u (last %u,%u) (%d)", c->name, m->b,
m->x, m->y, m->lx, m->ly, c->tty.mouse_drag_flag);
@ -743,54 +751,117 @@ have_event:
}
}
/* Not on status line. Adjust position and check for border or pane. */
/*
* Not on status line. Adjust position and check for
* border, pane, or scrollbar.
*/
if (where == NOWHERE) {
px = x;
if (m->statusat == 0 && y >= m->statuslines)
py = y - m->statuslines;
else if (m->statusat > 0 && y >= (u_int)m->statusat)
py = m->statusat - 1;
else
py = y;
tty_window_offset(&c->tty, &m->ox, &m->oy, &sx, &sy);
log_debug("mouse window @%u at %u,%u (%ux%u)",
s->curw->window->id, m->ox, m->oy, sx, sy);
if (px > sx || py > sy)
return (KEYC_UNKNOWN);
px = px + m->ox;
py = py + m->oy;
/* Try the pane borders if not zoomed. */
if (~s->curw->window->flags & WINDOW_ZOOMED) {
TAILQ_FOREACH(wp, &s->curw->window->panes, entry) {
if ((wp->xoff + wp->sx == px &&
wp->yoff <= 1 + py &&
wp->yoff + wp->sy >= py) ||
(wp->yoff + wp->sy == py &&
wp->xoff <= 1 + px &&
wp->xoff + wp->sx >= px))
break;
}
if (wp != NULL)
where = BORDER;
}
/* Otherwise try inside the pane. */
if (where == NOWHERE) {
wp = window_get_active_at(s->curw->window, px, py);
if (wp != NULL)
where = PANE;
if (c->tty.mouse_scrolling_flag) {
where = SCROLLBAR_SLIDER;
} else {
px = x;
if (m->statusat == 0 && y >= m->statuslines)
py = y - m->statuslines;
else if (m->statusat > 0 && y >= (u_int)m->statusat)
py = m->statusat - 1;
else
py = y;
tty_window_offset(&c->tty, &m->ox, &m->oy, &sx, &sy);
log_debug("mouse window @%u at %u,%u (%ux%u)",
s->curw->window->id, m->ox, m->oy, sx, sy);
if (px > sx || py > sy)
return (KEYC_UNKNOWN);
px = px + m->ox;
py = py + m->oy;
/* try inside the pane. */
wp = window_get_active_at(s->curw->window, px, py);
if (wp == NULL)
return (KEYC_UNKNOWN);
/* Try the scrollbar which is actually next to a pane */
pane_scrollbars = options_get_number(wo, "pane-scrollbars");
sb_pos = options_get_number(wo, "pane-scrollbars-position");
if (pane_scrollbars == PANE_SCROLLBARS_ALWAYS ||
(pane_scrollbars == PANE_SCROLLBARS_MODAL &&
window_pane_mode(wp) != WINDOW_PANE_NO_MODE))
sb_w = PANE_SCROLLBARS_WIDTH;
else
sb_w = 0;
pane_status = options_get_number(wo, "pane-border-status");
if (pane_status == PANE_STATUS_TOP)
line = wp->yoff - 1;
else if (pane_status == PANE_STATUS_BOTTOM)
line = wp->yoff + wp->sy;
/* check if py could lie within a scroller
* if pane at the top then py==0 included
* if pane not at the top, then yoff to yoff+sy
*/
if ((pane_status && py != line) ||
(wp->yoff == 0 && py < wp->sy) ||
(py >= wp->yoff && py < wp->yoff + wp->sy)) {
/* check if px lies within a scroller
log_debug("wps @%u at %u,%u (%ux%u)", wp->id,
m->ox, m->oy, px, py);
*/
if ((sb_pos == PANE_SCROLLBARS_RIGHT &&
(px >= wp->xoff + wp->sx &&
px < wp->xoff + wp->sx + sb_w)) ||
(sb_pos == PANE_SCROLLBARS_LEFT &&
(px >= wp->xoff - sb_w &&
px < wp->xoff))) {
/* definitely in the scrollbar */
slider_top = wp->yoff + wp->sb_slider_y;
slider_bottom = wp->yoff + wp->sb_slider_y + wp->sb_slider_h - 1;
if (py < slider_top)
where = SCROLLBAR_UP;
else if (py >= slider_top &&
py <= slider_bottom) {
where = SCROLLBAR_SLIDER;
where_in_slider = py - wp->sb_slider_y - wp->yoff;
} else
/* py > slider_bottom */
where = SCROLLBAR_DOWN;
} else {
where = PANE;
}
} else {
/* Try the pane borders if not zoomed. */
if (~s->curw->window->flags & WINDOW_ZOOMED) {
TAILQ_FOREACH(wp, &s->curw->window->panes, entry) {
if ((wp->xoff + wp->sx == px &&
wp->yoff <= 1 + py &&
wp->yoff + wp->sy >= py) ||
(wp->yoff + wp->sy == py &&
wp->xoff <= 1 + px &&
wp->xoff + wp->sx >= px))
break;
}
if (wp != NULL)
where = BORDER;
}
}
if (where == PANE)
log_debug("mouse %u,%u on pane %%%u", x, y, wp->id);
else if (where == BORDER)
log_debug("mouse on pane %%%u border", wp->id);
else if (where == SCROLLBAR_UP ||
where == SCROLLBAR_SLIDER ||
where == SCROLLBAR_DOWN)
log_debug("mouse on pane %%%u scrollbar", wp->id);
m->wp = wp->id;
m->w = wp->window->id;
}
if (where == PANE)
log_debug("mouse %u,%u on pane %%%u", x, y, wp->id);
else if (where == BORDER)
log_debug("mouse on pane %%%u border", wp->id);
m->wp = wp->id;
m->w = wp->window->id;
}
} else
m->wp = -1;
/* Stop dragging if needed. */
if (type != DRAG && type != WHEEL && c->tty.mouse_drag_flag != 0) {
@ -799,6 +870,7 @@ have_event:
c->tty.mouse_drag_update = NULL;
c->tty.mouse_drag_release = NULL;
c->tty.mouse_scrolling_flag = 0;
/*
* End a mouse drag by passing a MouseDragEnd key corresponding
@ -816,6 +888,8 @@ have_event:
key = KEYC_MOUSEDRAGEND1_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDRAGEND1_STATUS_DEFAULT;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDRAGEND1_SCROLLBAR_SLIDER;
if (where == BORDER)
key = KEYC_MOUSEDRAGEND1_BORDER;
break;
@ -830,6 +904,8 @@ have_event:
key = KEYC_MOUSEDRAGEND2_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDRAGEND2_STATUS_DEFAULT;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDRAGEND2_SCROLLBAR_SLIDER;
if (where == BORDER)
key = KEYC_MOUSEDRAGEND2_BORDER;
break;
@ -844,6 +920,8 @@ have_event:
key = KEYC_MOUSEDRAGEND3_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDRAGEND3_STATUS_DEFAULT;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDRAGEND3_SCROLLBAR_SLIDER;
if (where == BORDER)
key = KEYC_MOUSEDRAGEND3_BORDER;
break;
@ -858,6 +936,8 @@ have_event:
key = KEYC_MOUSEDRAGEND6_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDRAGEND6_STATUS_DEFAULT;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDRAGEND6_SCROLLBAR_SLIDER;
if (where == BORDER)
key = KEYC_MOUSEDRAGEND6_BORDER;
break;
@ -872,6 +952,8 @@ have_event:
key = KEYC_MOUSEDRAGEND7_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDRAGEND7_STATUS_DEFAULT;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDRAGEND7_SCROLLBAR_SLIDER;
if (where == BORDER)
key = KEYC_MOUSEDRAGEND7_BORDER;
break;
@ -886,6 +968,8 @@ have_event:
key = KEYC_MOUSEDRAGEND8_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDRAGEND8_STATUS_DEFAULT;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDRAGEND8_SCROLLBAR_SLIDER;
if (where == BORDER)
key = KEYC_MOUSEDRAGEND8_BORDER;
break;
@ -900,6 +984,8 @@ have_event:
key = KEYC_MOUSEDRAGEND9_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDRAGEND9_STATUS_DEFAULT;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDRAGEND9_SCROLLBAR_SLIDER;
if (where == BORDER)
key = KEYC_MOUSEDRAGEND9_BORDER;
break;
@ -914,6 +1000,8 @@ have_event:
key = KEYC_MOUSEDRAGEND10_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDRAGEND10_STATUS_DEFAULT;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDRAGEND10_SCROLLBAR_SLIDER;
if (where == BORDER)
key = KEYC_MOUSEDRAGEND10_BORDER;
break;
@ -928,6 +1016,8 @@ have_event:
key = KEYC_MOUSEDRAGEND11_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDRAGEND11_STATUS_DEFAULT;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDRAGEND11_SCROLLBAR_SLIDER;
if (where == BORDER)
key = KEYC_MOUSEDRAGEND11_BORDER;
break;
@ -936,6 +1026,7 @@ have_event:
break;
}
c->tty.mouse_drag_flag = 0;
c->tty.mouse_slider_mpos = -1;
goto out;
}
@ -974,6 +1065,12 @@ have_event:
key = KEYC_MOUSEDRAG1_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDRAG1_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEDRAG1_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDRAG1_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEDRAG1_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEDRAG1_BORDER;
break;
@ -988,6 +1085,12 @@ have_event:
key = KEYC_MOUSEDRAG2_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDRAG2_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEDRAG2_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDRAG2_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEDRAG2_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEDRAG2_BORDER;
break;
@ -1002,6 +1105,12 @@ have_event:
key = KEYC_MOUSEDRAG3_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDRAG3_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEDRAG3_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDRAG3_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEDRAG3_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEDRAG3_BORDER;
break;
@ -1016,6 +1125,12 @@ have_event:
key = KEYC_MOUSEDRAG6_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDRAG6_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEDRAG6_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDRAG6_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEDRAG6_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEDRAG6_BORDER;
break;
@ -1030,6 +1145,12 @@ have_event:
key = KEYC_MOUSEDRAG7_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDRAG7_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEDRAG7_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDRAG7_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEDRAG7_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEDRAG7_BORDER;
break;
@ -1044,6 +1165,12 @@ have_event:
key = KEYC_MOUSEDRAG8_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDRAG8_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEDRAG8_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDRAG8_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEDRAG8_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEDRAG8_BORDER;
break;
@ -1058,6 +1185,12 @@ have_event:
key = KEYC_MOUSEDRAG9_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDRAG9_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEDRAG9_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDRAG9_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEDRAG9_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEDRAG9_BORDER;
break;
@ -1072,6 +1205,12 @@ have_event:
key = KEYC_MOUSEDRAG10_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDRAG10_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEDRAG10_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDRAG10_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEDRAG10_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEDRAG10_BORDER;
break;
@ -1086,6 +1225,12 @@ have_event:
key = KEYC_MOUSEDRAG11_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDRAG11_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEDRAG11_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDRAG11_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEDRAG11_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEDRAG11_BORDER;
break;
@ -1094,9 +1239,16 @@ have_event:
/*
* Begin a drag by setting the flag to a non-zero value that
* corresponds to the mouse button in use.
* corresponds to the mouse button in use. If starting to
* drag the scrollbar, store the relative position in the
* slider where the user grabed.
*/
c->tty.mouse_drag_flag = MOUSE_BUTTONS(b) + 1;
if (c->tty.mouse_scrolling_flag == 0 &&
where == SCROLLBAR_SLIDER) {
c->tty.mouse_scrolling_flag = 1;
c->tty.mouse_slider_mpos = where_in_slider;
}
break;
case WHEEL:
if (MOUSE_BUTTONS(b) == MOUSE_WHEEL_UP) {
@ -1140,6 +1292,12 @@ have_event:
key = KEYC_MOUSEUP1_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEUP1_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEUP1_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEUP1_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEUP1_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEUP1_BORDER;
break;
@ -1154,6 +1312,12 @@ have_event:
key = KEYC_MOUSEUP2_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEUP2_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEUP2_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEUP2_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEUP2_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEUP2_BORDER;
break;
@ -1168,6 +1332,12 @@ have_event:
key = KEYC_MOUSEUP3_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEUP3_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEUP3_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEUP3_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEUP3_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEUP3_BORDER;
break;
@ -1182,6 +1352,12 @@ have_event:
key = KEYC_MOUSEUP6_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEUP6_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEUP6_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEUP6_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEUP6_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEUP6_BORDER;
break;
@ -1196,6 +1372,12 @@ have_event:
key = KEYC_MOUSEUP7_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEUP7_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEUP7_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEUP7_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEUP7_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEUP7_BORDER;
break;
@ -1210,6 +1392,12 @@ have_event:
key = KEYC_MOUSEUP8_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEUP8_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEUP8_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEUP8_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEUP8_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEUP8_BORDER;
break;
@ -1224,6 +1412,12 @@ have_event:
key = KEYC_MOUSEUP9_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEUP9_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEUP9_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEUP9_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEUP9_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEUP9_BORDER;
break;
@ -1237,7 +1431,13 @@ have_event:
if (where == STATUS_RIGHT)
key = KEYC_MOUSEUP1_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEUP1_STATUS_DEFAULT;
key = KEYC_MOUSEUP10_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEUP10_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEUP10_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEUP1_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEUP1_BORDER;
break;
@ -1252,6 +1452,12 @@ have_event:
key = KEYC_MOUSEUP11_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEUP11_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEUP11_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEUP11_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEUP11_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEUP11_BORDER;
break;
@ -1270,6 +1476,12 @@ have_event:
key = KEYC_MOUSEDOWN1_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDOWN1_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEDOWN1_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDOWN1_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEDOWN1_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEDOWN1_BORDER;
break;
@ -1284,6 +1496,12 @@ have_event:
key = KEYC_MOUSEDOWN2_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDOWN2_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEDOWN2_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDOWN2_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEDOWN2_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEDOWN2_BORDER;
break;
@ -1298,6 +1516,12 @@ have_event:
key = KEYC_MOUSEDOWN3_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDOWN3_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEDOWN3_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDOWN3_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEDOWN3_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEDOWN3_BORDER;
break;
@ -1312,6 +1536,12 @@ have_event:
key = KEYC_MOUSEDOWN6_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDOWN6_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEDOWN6_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDOWN6_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEDOWN6_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEDOWN6_BORDER;
break;
@ -1326,6 +1556,12 @@ have_event:
key = KEYC_MOUSEDOWN7_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDOWN7_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEDOWN7_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDOWN7_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEDOWN7_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEDOWN7_BORDER;
break;
@ -1340,6 +1576,12 @@ have_event:
key = KEYC_MOUSEDOWN8_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDOWN8_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEDOWN8_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDOWN8_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEDOWN8_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEDOWN8_BORDER;
break;
@ -1354,6 +1596,12 @@ have_event:
key = KEYC_MOUSEDOWN9_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDOWN9_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEDOWN9_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDOWN9_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEDOWN9_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEDOWN9_BORDER;
break;
@ -1368,6 +1616,12 @@ have_event:
key = KEYC_MOUSEDOWN10_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDOWN10_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEDOWN10_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDOWN10_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEDOWN10_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEDOWN10_BORDER;
break;
@ -1382,6 +1636,12 @@ have_event:
key = KEYC_MOUSEDOWN11_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_MOUSEDOWN11_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_MOUSEDOWN11_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_MOUSEDOWN11_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_MOUSEDOWN11_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_MOUSEDOWN11_BORDER;
break;
@ -1400,6 +1660,12 @@ have_event:
key = KEYC_SECONDCLICK1_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_SECONDCLICK1_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_SECONDCLICK1_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_SECONDCLICK1_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_SECONDCLICK1_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_SECONDCLICK1_BORDER;
break;
@ -1414,6 +1680,12 @@ have_event:
key = KEYC_SECONDCLICK2_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_SECONDCLICK2_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_SECONDCLICK2_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_SECONDCLICK2_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_SECONDCLICK2_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_SECONDCLICK2_BORDER;
break;
@ -1428,6 +1700,12 @@ have_event:
key = KEYC_SECONDCLICK3_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_SECONDCLICK3_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_SECONDCLICK3_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_SECONDCLICK3_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_SECONDCLICK3_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_SECONDCLICK3_BORDER;
break;
@ -1442,6 +1720,12 @@ have_event:
key = KEYC_SECONDCLICK6_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_SECONDCLICK6_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_SECONDCLICK6_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_SECONDCLICK6_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_SECONDCLICK6_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_SECONDCLICK6_BORDER;
break;
@ -1456,6 +1740,12 @@ have_event:
key = KEYC_SECONDCLICK7_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_SECONDCLICK7_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_SECONDCLICK7_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_SECONDCLICK7_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_SECONDCLICK7_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_SECONDCLICK7_BORDER;
break;
@ -1470,6 +1760,12 @@ have_event:
key = KEYC_SECONDCLICK8_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_SECONDCLICK8_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_SECONDCLICK8_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_SECONDCLICK8_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_SECONDCLICK8_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_SECONDCLICK8_BORDER;
break;
@ -1484,6 +1780,12 @@ have_event:
key = KEYC_SECONDCLICK9_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_SECONDCLICK9_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_SECONDCLICK9_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_SECONDCLICK9_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_SECONDCLICK9_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_SECONDCLICK9_BORDER;
break;
@ -1498,6 +1800,12 @@ have_event:
key = KEYC_SECONDCLICK10_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_SECONDCLICK10_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_SECONDCLICK10_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_SECONDCLICK10_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_SECONDCLICK10_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_SECONDCLICK10_BORDER;
break;
@ -1512,6 +1820,12 @@ have_event:
key = KEYC_SECONDCLICK11_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_SECONDCLICK11_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_SECONDCLICK11_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_SECONDCLICK11_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_SECONDCLICK11_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_SECONDCLICK11_BORDER;
break;
@ -1530,6 +1844,12 @@ have_event:
key = KEYC_DOUBLECLICK1_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_DOUBLECLICK1_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_DOUBLECLICK1_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_DOUBLECLICK1_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_DOUBLECLICK1_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_DOUBLECLICK1_BORDER;
break;
@ -1544,6 +1864,12 @@ have_event:
key = KEYC_DOUBLECLICK2_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_DOUBLECLICK2_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_DOUBLECLICK2_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_DOUBLECLICK2_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_DOUBLECLICK2_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_DOUBLECLICK2_BORDER;
break;
@ -1558,6 +1884,12 @@ have_event:
key = KEYC_DOUBLECLICK3_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_DOUBLECLICK3_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_DOUBLECLICK3_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_DOUBLECLICK3_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_DOUBLECLICK3_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_DOUBLECLICK3_BORDER;
break;
@ -1572,6 +1904,12 @@ have_event:
key = KEYC_DOUBLECLICK6_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_DOUBLECLICK6_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_DOUBLECLICK6_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_DOUBLECLICK6_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_DOUBLECLICK6_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_DOUBLECLICK6_BORDER;
break;
@ -1586,6 +1924,12 @@ have_event:
key = KEYC_DOUBLECLICK7_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_DOUBLECLICK7_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_DOUBLECLICK7_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_DOUBLECLICK7_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_DOUBLECLICK7_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_DOUBLECLICK7_BORDER;
break;
@ -1600,6 +1944,12 @@ have_event:
key = KEYC_DOUBLECLICK8_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_DOUBLECLICK8_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_DOUBLECLICK8_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_DOUBLECLICK8_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_DOUBLECLICK8_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_DOUBLECLICK8_BORDER;
break;
@ -1614,6 +1964,12 @@ have_event:
key = KEYC_DOUBLECLICK9_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_DOUBLECLICK9_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_DOUBLECLICK9_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_DOUBLECLICK9_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_DOUBLECLICK9_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_DOUBLECLICK9_BORDER;
break;
@ -1628,6 +1984,12 @@ have_event:
key = KEYC_DOUBLECLICK10_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_DOUBLECLICK10_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_DOUBLECLICK10_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_DOUBLECLICK10_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_DOUBLECLICK10_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_DOUBLECLICK10_BORDER;
break;
@ -1642,6 +2004,12 @@ have_event:
key = KEYC_DOUBLECLICK11_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_DOUBLECLICK11_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_DOUBLECLICK11_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_DOUBLECLICK11_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_DOUBLECLICK11_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_DOUBLECLICK11_BORDER;
break;
@ -1660,6 +2028,12 @@ have_event:
key = KEYC_TRIPLECLICK1_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_TRIPLECLICK1_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_TRIPLECLICK1_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_TRIPLECLICK1_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_TRIPLECLICK1_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_TRIPLECLICK1_BORDER;
break;
@ -1674,6 +2048,12 @@ have_event:
key = KEYC_TRIPLECLICK2_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_TRIPLECLICK2_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_TRIPLECLICK2_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_TRIPLECLICK2_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_TRIPLECLICK2_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_TRIPLECLICK2_BORDER;
break;
@ -1688,6 +2068,12 @@ have_event:
key = KEYC_TRIPLECLICK3_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_TRIPLECLICK3_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_TRIPLECLICK3_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_TRIPLECLICK3_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_TRIPLECLICK3_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_TRIPLECLICK3_BORDER;
break;
@ -1702,6 +2088,12 @@ have_event:
key = KEYC_TRIPLECLICK6_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_TRIPLECLICK6_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_TRIPLECLICK6_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_TRIPLECLICK6_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_TRIPLECLICK6_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_TRIPLECLICK6_BORDER;
break;
@ -1716,6 +2108,12 @@ have_event:
key = KEYC_TRIPLECLICK7_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_TRIPLECLICK7_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_TRIPLECLICK7_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_TRIPLECLICK7_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_TRIPLECLICK7_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_TRIPLECLICK7_BORDER;
break;
@ -1730,6 +2128,12 @@ have_event:
key = KEYC_TRIPLECLICK8_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_TRIPLECLICK8_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_TRIPLECLICK8_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_TRIPLECLICK8_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_TRIPLECLICK8_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_TRIPLECLICK8_BORDER;
break;
@ -1744,6 +2148,12 @@ have_event:
key = KEYC_TRIPLECLICK9_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_TRIPLECLICK9_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_TRIPLECLICK9_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_TRIPLECLICK9_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_TRIPLECLICK9_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_TRIPLECLICK9_BORDER;
break;
@ -1758,6 +2168,12 @@ have_event:
key = KEYC_TRIPLECLICK10_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_TRIPLECLICK10_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_TRIPLECLICK10_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_TRIPLECLICK10_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_TRIPLECLICK10_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_TRIPLECLICK10_BORDER;
break;
@ -1772,6 +2188,12 @@ have_event:
key = KEYC_TRIPLECLICK11_STATUS_RIGHT;
if (where == STATUS_DEFAULT)
key = KEYC_TRIPLECLICK11_STATUS_DEFAULT;
if (where == SCROLLBAR_UP)
key = KEYC_TRIPLECLICK11_SCROLLBAR_UP;
if (where == SCROLLBAR_SLIDER)
key = KEYC_TRIPLECLICK11_SCROLLBAR_SLIDER;
if (where == SCROLLBAR_DOWN)
key = KEYC_TRIPLECLICK11_SCROLLBAR_DOWN;
if (where == BORDER)
key = KEYC_TRIPLECLICK11_BORDER;
break;
@ -1806,7 +2228,7 @@ server_client_is_bracket_paste(struct client *c, key_code key)
}
if (key == KEYC_PASTE_END) {
c->flags &= ~CLIENT_BRACKETPASTING;
c->flags &= ~CLIENT_BRACKETPASTING;
log_debug("%s: bracket paste off", c->name);
return (0);
}
@ -2226,7 +2648,7 @@ server_client_loop(void)
server_client_check_pane_resize(wp);
server_client_check_pane_buffer(wp);
}
wp->flags &= ~PANE_REDRAW;
wp->flags &= ~(PANE_REDRAW|PANE_REDRAWSCROLLBAR);
}
check_window_name(w);
}
@ -2685,7 +3107,7 @@ server_client_check_redraw(struct client *c)
needed = 1;
else {
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp->flags & PANE_REDRAW) {
if (wp->flags & (PANE_REDRAW|PANE_REDRAWSCROLLBAR)) {
needed = 1;
break;
}
@ -2704,7 +3126,7 @@ server_client_check_redraw(struct client *c)
if (~c->flags & CLIENT_REDRAWWINDOW) {
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp->flags & PANE_REDRAW) {
if (wp->flags & (PANE_REDRAW|PANE_REDRAWSCROLLBAR)) {
log_debug("%s: pane %%%u needs redraw",
c->name, wp->id);
c->redraw_panes |= (1 << bit);
@ -2737,7 +3159,7 @@ server_client_check_redraw(struct client *c)
*/
TAILQ_FOREACH(wp, &w->panes, entry) {
redraw = 0;
if (wp->flags & PANE_REDRAW)
if (wp->flags & (PANE_REDRAW))
redraw = 1;
else if (c->flags & CLIENT_REDRAWPANES)
redraw = !!(c->redraw_panes & (1 << bit));
@ -3261,7 +3683,7 @@ const char *
server_client_get_flags(struct client *c)
{
static char s[256];
char tmp[32];
char tmp[32];
*s = '\0';
if (c->flags & CLIENT_ATTACHED)

73
tmux.1
View File

@ -2402,22 +2402,31 @@ The synopsis for the
command is:
.Bl -tag -width Ds
.It Xo Ic copy-mode
.Op Fl deHMqu
.Op Fl deHMquS
.Op Fl s Ar src-pane
.Op Fl t Ar target-pane
.Xc
Enter copy mode.
.Pp
.Fl u
also scrolls one page up after entering and
enters copy mode and scrolls one page up and
.Fl d
one page down if already in copy mode.
.Fl M
begins a mouse drag (only valid if bound to a mouse key binding, see
.Sx MOUSE SUPPORT ) .
one page down.
.Fl H
hides the position indicator in the top right.
.Fl q
cancels copy mode and any other modes.
.Pp
.Fl M
begins a mouse drag (only valid if bound to a mouse key binding, see
.Sx MOUSE SUPPORT ) .
.Fl S
scrolls when bound to a mouse drag event; for example,
.Ic copy-mode -Se
is bound to
.Ar MouseDrag1ScrollbarSlider
by default.
.Pp
.Fl s
copies from
.Ar src-pane
@ -5028,6 +5037,55 @@ and
.Ql heavy
will fall back to standard ACS line drawing when UTF-8 is not supported.
.Pp
.It Xo Ic pane-scrollbars
.Op Ic off | modal | on
.Xc
When enabled, a character based scrollbar appears on the left or right
of each pane.
A filled section of the scrollbar, known as the
.Ql slider ,
represents the position and size of the visible part of the pane content.
By default dragging the scrollbar slider up will enter copy mode; in copy
mode dragging the slider will scroll the pane.
.Pp
If set to
.Ic on
the scrollbar is visible all the time.
If set to
.Ic modal
the scrollbar only appears when the pane is in copy mode or view mode.
When the scrollbar is visible, the pane is narrowed by the width of the
scrollbar and the text in the pane is reflowed.
If set to
.Ic modal ,
the pane is narrowed only when the scrollbar is visible.
.Pp
When the
.Ic mouse
option is on, clicking above and below the slider pages up and down and dragging
the slider scrolls the pane.
.Pp
See also
.Xr pane-scrollbar-style
and the scrollbar mouse events in the
.Sx MOUSE SUPPORT
section.
.Pp
.It Ic pane-scrollbar-style Ar style
Set the pane scrollbar style for the currently active pane.
For how to specify
.Ar style ,
see the
.Sx STYLES
section.
Attributes are ignored.
.Pp
.It Xo Ic pane-scrollbars-position
.Op Ic left | right
.Xc
Sets which side of the pane to display the pane scrollbars on. The
default is right.
.Pp
.It Ic window-status-activity-style Ar style
Set status line style for windows with an activity alert.
For how to specify
@ -5400,6 +5458,9 @@ and a location suffix, one of the following:
.It Li "StatusLeft" Ta "the left part of the status line"
.It Li "StatusRight" Ta "the right part of the status line"
.It Li "StatusDefault" Ta "any other part of the status line"
.It Li "ScrollbarSlider" Ta "the scrollbar slider"
.It Li "ScrollbarUp" Ta "above the scrollbar slider"
.It Li "ScrollbarDown" Ta "below the scrollbar slider"
.El
.Pp
The following mouse events are available:

41
tmux.h
View File

@ -184,13 +184,19 @@ struct winlink;
KEYC_ ## name ## _STATUS_LEFT, \
KEYC_ ## name ## _STATUS_RIGHT, \
KEYC_ ## name ## _STATUS_DEFAULT, \
KEYC_ ## name ## _SCROLLBAR_UP, \
KEYC_ ## name ## _SCROLLBAR_SLIDER, \
KEYC_ ## name ## _SCROLLBAR_DOWN, \
KEYC_ ## name ## _BORDER
#define KEYC_MOUSE_STRING(name, s) \
{ #s "Pane", KEYC_ ## name ## _PANE }, \
{ #s "Status", KEYC_ ## name ## _STATUS }, \
{ #s "StatusLeft", KEYC_ ## name ## _STATUS_LEFT }, \
{ #s "StatusRight", KEYC_ ## name ## _STATUS_RIGHT }, \
{ #s "StatusDefault", KEYC_ ## name ## _STATUS_DEFAULT }, \
#define KEYC_MOUSE_STRING(name, s) \
{ #s "Pane", KEYC_ ## name ## _PANE }, \
{ #s "Status", KEYC_ ## name ## _STATUS }, \
{ #s "StatusLeft", KEYC_ ## name ## _STATUS_LEFT }, \
{ #s "StatusRight", KEYC_ ## name ## _STATUS_RIGHT }, \
{ #s "StatusDefault", KEYC_ ## name ## _STATUS_DEFAULT }, \
{ #s "ScrollbarUp", KEYC_ ## name ## _SCROLLBAR_UP }, \
{ #s "ScrollbarSlider", KEYC_ ## name ## _SCROLLBAR_SLIDER }, \
{ #s "ScrollbarDown", KEYC_ ## name ## _SCROLLBAR_DOWN }, \
{ #s "Border", KEYC_ ## name ## _BORDER }
/*
@ -747,6 +753,7 @@ struct colour_palette {
#define CELL_RIGHTJOIN 10
#define CELL_JOIN 11
#define CELL_OUTSIDE 12
#define CELL_SCROLLBAR 13
/* Cell borders. */
#define CELL_BORDERS " xqlkmjwvtun~"
@ -1015,6 +1022,9 @@ struct screen_redraw_ctx {
int pane_status;
enum pane_lines pane_lines;
int pane_scrollbars;
int pane_scrollbars_pos;
struct grid_cell no_pane_gc;
int no_pane_gc_set;
@ -1133,6 +1143,10 @@ struct window_pane {
#define PANE_EMPTY 0x800
#define PANE_STYLECHANGED 0x1000
#define PANE_UNSEENCHANGES 0x2000
#define PANE_REDRAWSCROLLBAR 0x4000
u_int sb_slider_y;
u_int sb_slider_h;
int argc;
char **argv;
@ -1275,6 +1289,17 @@ TAILQ_HEAD(winlink_stack, winlink);
#define PANE_STATUS_TOP 1
#define PANE_STATUS_BOTTOM 2
/* Pane scrollbars options. */
#define PANE_SCROLLBARS_OFF 0
#define PANE_SCROLLBARS_MODAL 1
#define PANE_SCROLLBARS_ALWAYS 2
#define PANE_SCROLLBARS_RIGHT 0
#define PANE_SCROLLBARS_LEFT 1
/* Pane scrollbars width and padding. */
#define PANE_SCROLLBARS_WIDTH 1
#define PANE_SCROLLBARS_PADDING 0
/* Layout direction. */
enum layout_type {
LAYOUT_LEFTRIGHT,
@ -1524,6 +1549,9 @@ struct tty {
u_int mouse_last_y;
u_int mouse_last_b;
int mouse_drag_flag;
int mouse_scrolling_flag;
int mouse_slider_mpos;
void (*mouse_drag_update)(struct client *,
struct mouse_event *);
void (*mouse_drag_release)(struct client *,
@ -3288,6 +3316,7 @@ void printflike(3, 4) window_copy_add(struct window_pane *, int, const char *,
...);
void printflike(3, 0) window_copy_vadd(struct window_pane *, int, const char *,
va_list);
void window_copy_scroll(struct window_pane *, int, u_int, int);
void window_copy_pageup(struct window_pane *, int);
void window_copy_pagedown(struct window_pane *, int, int);
void window_copy_start_drag(struct client *, struct mouse_event *);

View File

@ -40,6 +40,8 @@ static void window_copy_free(struct window_mode_entry *);
static void window_copy_resize(struct window_mode_entry *, u_int, u_int);
static void window_copy_formats(struct window_mode_entry *,
struct format_tree *);
static void window_copy_scroll1(struct window_mode_entry *,
struct window_pane *wp, int, u_int, int);
static void window_copy_pageup1(struct window_mode_entry *, int);
static int window_copy_pagedown1(struct window_mode_entry *, int, int);
static void window_copy_next_paragraph(struct window_mode_entry *);
@ -274,7 +276,7 @@ struct window_copy_mode_data {
u_int cx;
u_int cy;
u_int lastcx; /* position in last line w/ content */
u_int lastcx; /* position in last line w/ content */
u_int lastsx; /* size of last line w/ content */
u_int mx; /* mark position */
@ -546,7 +548,7 @@ window_copy_vadd(struct window_pane *wp, int parse, const char *fmt, va_list ap)
struct window_copy_mode_data *data = wme->data;
struct screen *backing = data->backing;
struct screen *writing = data->writing;
struct screen_write_ctx writing_ctx, backing_ctx, ctx;
struct screen_write_ctx writing_ctx, backing_ctx, ctx;
struct grid_cell gc;
u_int old_hsize, old_cy;
u_int sx = screen_size_x(backing);
@ -598,6 +600,122 @@ window_copy_vadd(struct window_pane *wp, int parse, const char *fmt, va_list ap)
screen_write_stop(&ctx);
}
void
window_copy_scroll(struct window_pane *wp, int sl_mpos, u_int my,
int scroll_exit)
{
struct window_mode_entry *wme = TAILQ_FIRST(&wp->modes);
window_set_active_pane(wp->window, wp, 0);
if (wme != NULL) {
window_copy_scroll1(wme, wp, sl_mpos, my, scroll_exit);
}
}
static void
window_copy_scroll1(struct window_mode_entry *wme, struct window_pane *wp,
int sl_mpos, u_int my, int scroll_exit)
{
struct window_copy_mode_data *data = wme->data;
u_int ox, oy, px, py, n, offset, size;
u_int new_offset, slider_y = wp->sb_slider_y;
u_int slider_height = wp->sb_slider_h;
u_int sb_height = wp->sy, sb_top = wp->yoff;
u_int sy = screen_size_y(data->backing);
int new_slider_y, delta;
log_debug("%s: slider %u mouse %u", __func__, slider_y, my);
/*
* sl_mpos is where in the slider the user is dragging, mouse
* is dragging this y point relative to top of slider.
*/
if (my <= sb_top + sl_mpos) {
/* Slider banged into top. */
new_slider_y = sb_top - wp->yoff;
} else if (my - sl_mpos > sb_top + sb_height - slider_height) {
/* Slider banged into bottom. */
new_slider_y = sb_top - wp->yoff + (sb_height - slider_height);
} else {
/* Slider is somewhere in the middle. */
new_slider_y = my - wp->yoff - sl_mpos + 1;
}
log_debug("%s: new slider %u mouse %u", __func__, new_slider_y, my);
if (TAILQ_FIRST(&wp->modes) == NULL ||
window_copy_get_current_offset(wp, &offset, &size) == 0)
return;
/*
* See screen_redraw_draw_pane_scrollbar(), this is the inverse of the
* formula used there.
*/
new_offset = new_slider_y * ((float)(size + sb_height) / sb_height);
delta = (int)offset - new_offset;
log_debug("%s: delta %d mouse %u", __func__, delta, my);
/*
* Move pane view around based on delta relative to the cursor,
* maintaining the selection.
*/
oy = screen_hsize(data->backing) + data->cy - data->oy;
ox = window_copy_find_length(wme, oy);
if (data->cx != ox) {
data->lastcx = data->cx;
data->lastsx = ox;
}
data->cx = data->lastcx;
if (delta >= 0) {
n = (u_int)delta;
if (data->oy + n > screen_hsize(data->backing)) {
data->oy = screen_hsize(data->backing);
if (data->cy < n)
data->cy = 0;
else
data->cy -= n;
} else
data->oy += n;
} else {
n = (u_int)-delta;
if (data->oy < n) {
data->oy = 0;
if (data->cy + (n - data->oy) >= sy)
data->cy = sy - 1;
else
data->cy += n - data->oy;
} else
data->oy -= n;
}
/* Don't also drag tail when dragging a scrollbar, it looks weird. */
data->cursordrag = CURSORDRAG_NONE;
if (data->screen.sel == NULL || !data->rectflag) {
py = screen_hsize(data->backing) + data->cy - data->oy;
px = window_copy_find_length(wme, py);
if ((data->cx >= data->lastsx && data->cx != px) ||
data->cx > px)
window_copy_cursor_end_of_line(wme);
}
if (scroll_exit && data->oy == 0) {
window_pane_reset_mode(wp);
return;
}
if (data->searchmark != NULL && !data->timeout)
window_copy_search_marks(wme, NULL, data->searchregex, 1);
window_copy_update_selection(wme, 1, 0);
window_copy_redraw_screen(wme);
return;
}
void
window_copy_pageup(struct window_pane *wp, int half_page)
{
@ -3803,12 +3921,12 @@ window_copy_search(struct window_mode_entry *wme, int direction, int regex)
* beginning of the mark.
*/
if (window_copy_search_mark_at(data, fx, fy,
&start) == 0) {
&start) == 0) {
while (window_copy_search_mark_at(data, fx, fy,
&at) == 0 &&
&at) == 0 &&
data->searchmark != NULL &&
data->searchmark[at] ==
data->searchmark[start]) {
data->searchmark[start]) {
data->cx = fx;
data->cy = fy -
screen_hsize(data->backing) +
@ -4077,7 +4195,7 @@ window_copy_match_at_cursor(struct window_copy_mode_data *data)
/*
* Cells will not be set in the marked array unless they are valid text
* and wrapping will be taken care of, so we can just copy.
*/
*/
for (at = start; at <= end; at++) {
py = at / sx;
px = at - (py * sx);
@ -4175,7 +4293,7 @@ window_copy_write_one(struct window_mode_entry *wme,
struct window_copy_mode_data *data = wme->data;
struct grid *gd = data->backing->grid;
struct grid_cell gc;
u_int fx;
u_int fx;
screen_write_cursormove(ctx, 0, py, 0);
for (fx = 0; fx < nx; fx++) {
@ -4256,10 +4374,13 @@ static void
window_copy_write_lines(struct window_mode_entry *wme,
struct screen_write_ctx *ctx, u_int py, u_int ny)
{
u_int yy;
u_int yy;
struct window_pane *wp = wme->wp;
for (yy = py; yy < py + ny; yy++)
window_copy_write_line(wme, ctx, py);
wp->flags |= PANE_REDRAWSCROLLBAR;
}
static void
@ -4295,7 +4416,7 @@ window_copy_redraw_lines(struct window_mode_entry *wme, u_int py, u_int ny)
{
struct window_pane *wp = wme->wp;
struct window_copy_mode_data *data = wme->data;
struct screen_write_ctx ctx;
struct screen_write_ctx ctx;
u_int i;
screen_write_start_pane(&ctx, wp, NULL);
@ -4303,6 +4424,8 @@ window_copy_redraw_lines(struct window_mode_entry *wme, u_int py, u_int ny)
window_copy_write_line(wme, &ctx, i);
screen_write_cursormove(&ctx, data->cx, data->cy, 0);
screen_write_stop(&ctx);
wp->flags |= PANE_REDRAWSCROLLBAR;
}
static void
@ -4445,7 +4568,7 @@ window_copy_adjust_selection(struct window_mode_entry *wme, u_int *selx,
{
struct window_copy_mode_data *data = wme->data;
struct screen *s = &data->screen;
u_int sx, sy, ty;
u_int sx, sy, ty;
int relpos;
sx = *selx;
@ -5348,8 +5471,7 @@ window_copy_cursor_previous_word_pos(struct window_mode_entry *wme,
py = hsize + data->cy - data->oy;
grid_reader_start(&gr, back_s->grid, px, py);
grid_reader_cursor_previous_word(&gr, separators, /* already= */ 0,
/* stop_at_eol= */ 1);
grid_reader_cursor_previous_word(&gr, separators, 0, 1);
grid_reader_get_cursor(&gr, &px, &py);
*ppx = px;
*ppy = py;
@ -5462,6 +5584,7 @@ window_copy_scroll_up(struct window_mode_entry *wme, u_int ny)
window_copy_write_line(wme, &ctx, screen_size_y(s) - ny - 1);
screen_write_cursormove(&ctx, data->cx, data->cy, 0);
screen_write_stop(&ctx);
wp->flags |= PANE_REDRAWSCROLLBAR;
}
static void
@ -5495,6 +5618,7 @@ window_copy_scroll_down(struct window_mode_entry *wme, u_int ny)
window_copy_write_line(wme, &ctx, 1);
screen_write_cursormove(&ctx, data->cx, data->cy, 0);
screen_write_stop(&ctx);
wp->flags |= PANE_REDRAWSCROLLBAR;
}
static void

View File

@ -591,11 +591,31 @@ struct window_pane *
window_get_active_at(struct window *w, u_int x, u_int y)
{
struct window_pane *wp;
int pane_scrollbars;
u_int sb_pos, sb_w, xoff, sx;
pane_scrollbars = options_get_number(w->options, "pane-scrollbars");
sb_pos = options_get_number(w->options, "pane-scrollbars-position");
TAILQ_FOREACH(wp, &w->panes, entry) {
if (!window_pane_visible(wp))
continue;
if (x < wp->xoff || x > wp->xoff + wp->sx)
if (pane_scrollbars == PANE_SCROLLBARS_ALWAYS ||
(pane_scrollbars == PANE_SCROLLBARS_MODAL &&
window_pane_mode(wp) != WINDOW_PANE_NO_MODE))
sb_w = PANE_SCROLLBARS_WIDTH;
else
sb_w = 0;
if (sb_pos == PANE_SCROLLBARS_LEFT) {
xoff = wp->xoff - sb_w;
sx = wp->sx + sb_w;
} else { /* sb_pos == PANE_SCROLLBARS_RIGHT */
xoff = wp->xoff;
sx = wp->sx + sb_w;
}
if (x < xoff || x > xoff + sx)
continue;
if (y < wp->yoff || y > wp->yoff + wp->sy)
continue;
@ -1096,6 +1116,8 @@ window_pane_set_mode(struct window_pane *wp, struct window_pane *swp,
struct args *args)
{
struct window_mode_entry *wme;
struct window *w = wp->window;
u_int pane_scrollbars;
if (!TAILQ_EMPTY(&wp->modes) && TAILQ_FIRST(&wp->modes)->mode == mode)
return (1);
@ -1120,6 +1142,10 @@ window_pane_set_mode(struct window_pane *wp, struct window_pane *swp,
wp->screen = wme->screen;
wp->flags |= (PANE_REDRAW|PANE_CHANGED);
pane_scrollbars = options_get_number(w->options, "pane-scrollbars");
if (pane_scrollbars == PANE_SCROLLBARS_MODAL)
layout_fix_panes(w, NULL);
server_redraw_window_borders(wp->window);
server_status_window(wp->window);
notify_pane("pane-mode-changed", wp);
@ -1131,6 +1157,8 @@ void
window_pane_reset_mode(struct window_pane *wp)
{
struct window_mode_entry *wme, *next;
struct window *w = wp->window;
u_int pane_scrollbars;
if (TAILQ_EMPTY(&wp->modes))
return;
@ -1151,7 +1179,11 @@ window_pane_reset_mode(struct window_pane *wp)
if (next->mode->resize != NULL)
next->mode->resize(next, wp->sx, wp->sy);
}
wp->flags |= (PANE_REDRAW|PANE_CHANGED);
wp->flags |= (PANE_REDRAW|PANE_REDRAWSCROLLBAR|PANE_CHANGED);
pane_scrollbars = options_get_number(w->options, "pane-scrollbars");
if (pane_scrollbars != PANE_SCROLLBARS_OFF)
layout_fix_panes(w, NULL);
server_redraw_window_borders(wp->window);
server_status_window(wp->window);
@ -1168,7 +1200,7 @@ window_pane_reset_mode_all(struct window_pane *wp)
static void
window_pane_copy_paste(struct window_pane *wp, char *buf, size_t len)
{
struct window_pane *loop;
struct window_pane *loop;
TAILQ_FOREACH(loop, &wp->window->panes, entry) {
if (loop != wp &&
@ -1186,7 +1218,7 @@ window_pane_copy_paste(struct window_pane *wp, char *buf, size_t len)
static void
window_pane_copy_key(struct window_pane *wp, key_code key)
{
struct window_pane *loop;
struct window_pane *loop;
TAILQ_FOREACH(loop, &wp->window->panes, entry) {
if (loop != wp &&