Mouse support on the scrollbars, from Michael Grant.

This commit is contained in:
nicm
2024-11-12 09:32:56 +00:00
parent c26d71d3e9
commit 713cacab1e
7 changed files with 634 additions and 70 deletions

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 *);
@@ -598,6 +600,113 @@ 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);
if (wme != NULL) {
window_set_active_pane(wp->window, wp, 0);
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;
/*
* 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;
}
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;
/*
* 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);
}
void
window_copy_pageup(struct window_pane *wp, int half_page)
{