I don't think we need an option or a big section in the man page. Please look at this.
Not wild about returning +/- lines from the func, and we do need to add to manpage somewhere, just a few lines not a whole section. Also was trying to avoid adding more functions to server-fn.c... Looks like gnome eats shift and alt for me so I only tested ctrl. diff --git a/input-keys.c b/input-keys.c index 7582a63..38f464e 100644 --- a/input-keys.c +++ b/input-keys.c @@ -204,6 +204,23 @@ input_mouse(struct window_pane *wp, struct session *s, struct mouse_event *m) char buf[40]; size_t len; struct paste_buffer *pb; + int i, lines; + + /* + * Mouse wheel used while alternate screen is active and not mouse + * aware, or shift is pressed. + */ + if (server_mouse_wheel(m, &lines) && ((wp->saved_grid != NULL && + !(wp->screen->mode & ALL_MOUSE_MODES)) || m->xb & MOUSE_SHIFT)) { + if (lines < 0) { + for (i = 0; i < -lines; i++) + input_key(wp, KEYC_UP); + } else { + for (i = 0; i < lines; i++) + input_key(wp, KEYC_DOWN); + } + return; + } if (wp->screen->mode & ALL_MOUSE_MODES) { /* diff --git a/server-fn.c b/server-fn.c index 3062698..853a1c7 100644 --- a/server-fn.c +++ b/server-fn.c @@ -609,3 +609,31 @@ server_unzoom_window(struct window *w) server_redraw_window(w); server_status_window(w); } + +/* + * Check if mouse wheel used and return number of lines, shift is a single + * line, meta and ctrl multiply exponentially. + */ +int +server_mouse_wheel(struct mouse_event *m, int *lines) +{ + if (m->event != MOUSE_EVENT_WHEEL) + return (0); + if (m->wheel != MOUSE_WHEEL_UP && m->wheel != MOUSE_WHEEL_DOWN) + return (0); + + if (m->xb & MOUSE_SHIFT) + *lines = 1; + else + *lines = 3; + + if (m->xb & MOUSE_META) + *lines *= 3; + if (m->xb & MOUSE_CTRL) + *lines *= 3; + + if (m->wheel == MOUSE_WHEEL_UP) + *lines = -*lines; + + return (1); +} diff --git a/tmux.h b/tmux.h index 0a6ca4e..c38d20e 100644 --- a/tmux.h +++ b/tmux.h @@ -1133,6 +1133,11 @@ LIST_HEAD(tty_terms, tty_term); #define MOUSE_EVENT_CLICK (1 << 3) #define MOUSE_EVENT_WHEEL (1 << 4) +/* Mouse modifier key states. */ +#define MOUSE_SHIFT 4 +#define MOUSE_META 8 +#define MOUSE_CTRL 16 + /* Mouse flags. */ #define MOUSE_RESIZE_PANE (1 << 0) @@ -1935,6 +1940,7 @@ void server_push_stderr(struct client *); int server_set_stdin_callback(struct client *, void (*)(struct client *, int, void *), void *, char **); void server_unzoom_window(struct window *); +int server_mouse_wheel(struct mouse_event *, int *); /* status.c */ int status_out_cmp(struct status_out *, struct status_out *); diff --git a/window-choose.c b/window-choose.c index e7578fe..d0167f7 100644 --- a/window-choose.c +++ b/window-choose.c @@ -721,7 +721,19 @@ window_choose_mouse( struct window_choose_mode_data *data = wp->modedata; struct screen *s = &data->screen; struct window_choose_mode_item *item; - u_int idx; + u_int i, idx; + int lines; + + if (server_mouse_wheel(m, &lines)) { + if (lines < 0) { + for (i = 0; i < -lines; i++) + window_choose_key(wp, sess, KEYC_UP); + } else { + for (i = 0; i < lines; i++) + window_choose_key(wp, sess, KEYC_DOWN); + } + return; + } if (~m->event & MOUSE_EVENT_CLICK) return; diff --git a/window-copy.c b/window-copy.c index 527c95c..cc3413b 100644 --- a/window-copy.c +++ b/window-copy.c @@ -854,7 +854,7 @@ window_copy_mouse( { struct window_copy_mode_data *data = wp->modedata; struct screen *s = &data->screen; - u_int i; + int i, lines; if (m->x >= screen_size_x(s)) return; @@ -862,16 +862,17 @@ window_copy_mouse( return; /* If mouse wheel (buttons 4 and 5), scroll. */ - if (m->event == MOUSE_EVENT_WHEEL) { - if (m->wheel == MOUSE_WHEEL_UP) { - for (i = 0; i < 5; i++) + if (server_mouse_wheel(m, &lines)) { + if (lines < 0) { + for (i = 0; i < -lines; i++) window_copy_cursor_up(wp, 1); - } else if (m->wheel == MOUSE_WHEEL_DOWN) { - for (i = 0; i < 5; i++) + } else { + for (i = 0; i < lines; i++) window_copy_cursor_down(wp, 1); + /* - * We reached the bottom, leave copy mode, - * but only if no selection is in progress. + * We reached the bottom, leave copy mode, but only if + * no selection is in progress. */ if (data->oy == 0 && !s->sel.flag) goto reset_mode; On Wed, Feb 26, 2014 at 12:59:56PM +0100, Marcel Partap wrote: > --- > input-keys.c | 17 +++++++++++++++++ > options-table.c | 7 +++++++ > tmux.1 | 23 +++++++++++++++++++++++ > tmux.h | 5 +++++ > window-choose.c | 19 ++++++++++++++++++- > window-copy.c | 12 +++++++++--- > 6 files changed, 79 insertions(+), 4 deletions(-) > > diff --git a/input-keys.c b/input-keys.c > index 7582a63..7588092 100644 > --- a/input-keys.c > +++ b/input-keys.c > @@ -204,6 +204,23 @@ input_mouse(struct window_pane *wp, struct session *s, > struct mouse_event *m) > char buf[40]; > size_t len; > struct paste_buffer *pb; > + u_int i, speed; > + > + if (m->event == MOUSE_EVENT_WHEEL) { > + /* Alternate screen is active and not mouse aware, or shift is > pressed. */ > + if ((wp->saved_grid && !(wp->screen->mode & ALL_MOUSE_MODES)) || > + m->xb & MOUSE_SHIFT) { > + speed = options_get_number(&global_s_options, > "mouse-wheel-speed"); > + /* wheel + SHIFT: scroll single line. */ > + speed = (m->xb & MOUSE_SHIFT) ? 1 : speed; > + /* wheel + META or CTRL: exponentiate speed. */ > + speed *= (m->xb & MOUSE_META) ? speed : 1; > + speed *= (m->xb & MOUSE_CTRL) ? speed : 1; > + for (i = 0; i < speed; i++) > + input_key(wp, m->wheel == MOUSE_WHEEL_UP ? > KEYC_UP : KEYC_DOWN); > + return; > + } > + } > > if (wp->screen->mode & ALL_MOUSE_MODES) { > /* > diff --git a/options-table.c b/options-table.c > index 64d3edc..1ea45e0 100644 > --- a/options-table.c > +++ b/options-table.c > @@ -266,6 +266,13 @@ const struct options_table_entry session_options_table[] > = { > .default_num = 0 > }, > > + { .name = "mouse-wheel-speed", > + .type = OPTIONS_TABLE_NUMBER, > + .minimum = 0, > + .maximum = INT_MAX, > + .default_num = 3 > + }, > + > { .name = "pane-active-border-bg", > .type = OPTIONS_TABLE_COLOUR, > .default_num = 8, > diff --git a/tmux.1 b/tmux.1 > index 51d927a..c050c58 100644 > --- a/tmux.1 > +++ b/tmux.1 > @@ -345,6 +345,25 @@ Key bindings may be changed with the > and > .Ic unbind-key > commands. > +.Sh MOUSE WHEEL INPUT > +If > +.Nm > +is run within a terminal emulator that generates xterm-compatible control > +sequences, various aspects may be controlled by mouse (see > +.Ic mouse-* > +options for reference). Regardless of these settings, mouse input is always > +passed through as-is to mouse-capable programs. For programs not natively > +supporting mouse input, > +.Nm > +can emulate wheel scrolling by sending fake up/down cursor key sequences. > +This can be enabled by holding the Shift-modifier while wheeling, and is > +automatically active in alternate screen mode when the foreground application > +does not itself request mouse control. The wheel scrolling speed can be set > by > +the > +.Ic mouse-wheel-speed > +option which also effects copy- and choice-modes. > +The Shift-modifier causes scrolling to slow down to one line for each wheel > +scroll, holding Ctrl or Alt/Meta raises speed exponentially. > .Sh COMMANDS > This section contains a list of the commands supported by > .Nm . > @@ -2392,6 +2411,10 @@ window. > .Op Ic on | off > .Xc > If enabled, request mouse input as UTF-8 on UTF-8 terminals. > +.It Ic mouse-wheel-speed Ar number > +The number of lines scrolled per wheel event. Holding Ctrl or Alt/Meta > modifiers > +exponentiates speed by the same factor, i.e. up to ^3. > +The default is 3. > .It Ic pane-active-border-style Ar style > Set the pane border style for the currently active pane. > For how to specify > diff --git a/tmux.h b/tmux.h > index ec5cf55..793a553 100644 > --- a/tmux.h > +++ b/tmux.h > @@ -1129,6 +1129,11 @@ LIST_HEAD(tty_terms, tty_term); > #define MOUSE_EVENT_CLICK (1 << 3) > #define MOUSE_EVENT_WHEEL (1 << 4) > > +/* Mouse modifier key states. */ > +#define MOUSE_SHIFT 4 > +#define MOUSE_META 8 > +#define MOUSE_CTRL 16 > + > /* Mouse flags. */ > #define MOUSE_RESIZE_PANE (1 << 0) > > diff --git a/window-choose.c b/window-choose.c > index 7b2b32b..67239ae 100644 > --- a/window-choose.c > +++ b/window-choose.c > @@ -698,7 +698,24 @@ window_choose_mouse( > struct window_choose_mode_data *data = wp->modedata; > struct screen *s = &data->screen; > struct window_choose_mode_item *item; > - u_int idx; > + u_int i, idx, speed; > + > + if (m->event == MOUSE_EVENT_WHEEL) { > + speed = options_get_number(&global_s_options, > "mouse-wheel-speed"); > + /* wheel + SHIFT: scroll single line. */ > + speed = (m->xb & MOUSE_SHIFT) ? 1 : speed; > + /* wheel + META or CTRL: exponentiate speed. */ > + speed *= (m->xb & MOUSE_META) ? speed : 1; > + speed *= (m->xb & MOUSE_CTRL) ? speed : 1; > + if (m->wheel == MOUSE_WHEEL_UP) { > + for (i = 0; i < speed; i++) > + window_choose_key(wp, sess, KEYC_UP); > + } else if (m->wheel == MOUSE_WHEEL_DOWN) { > + for (i = 0; i < speed; i++) > + window_choose_key(wp, sess, KEYC_DOWN); > + } > + return; > + } > > if (~m->event & MOUSE_EVENT_CLICK) > return; > diff --git a/window-copy.c b/window-copy.c > index 527c95c..141289e 100644 > --- a/window-copy.c > +++ b/window-copy.c > @@ -854,7 +854,7 @@ window_copy_mouse( > { > struct window_copy_mode_data *data = wp->modedata; > struct screen *s = &data->screen; > - u_int i; > + u_int i, speed; > > if (m->x >= screen_size_x(s)) > return; > @@ -863,11 +863,17 @@ window_copy_mouse( > > /* If mouse wheel (buttons 4 and 5), scroll. */ > if (m->event == MOUSE_EVENT_WHEEL) { > + speed = options_get_number(&global_s_options, > "mouse-wheel-speed"); > + /* wheel + SHIFT: scroll single line. */ > + speed = (m->xb & MOUSE_SHIFT) ? 1 : speed; > + /* wheel + META or CTRL: exponentiate speed. */ > + speed *= (m->xb & MOUSE_META) ? speed : 1; > + speed *= (m->xb & MOUSE_CTRL) ? speed : 1; > if (m->wheel == MOUSE_WHEEL_UP) { > - for (i = 0; i < 5; i++) > + for (i = 0; i < speed; i++) > window_copy_cursor_up(wp, 1); > } else if (m->wheel == MOUSE_WHEEL_DOWN) { > - for (i = 0; i < 5; i++) > + for (i = 0; i < speed; i++) > window_copy_cursor_down(wp, 1); > /* > * We reached the bottom, leave copy mode, > -- > 1.9.0.rc3 > > > ------------------------------------------------------------------------------ > Flow-based real-time traffic analytics software. Cisco certified tool. > Monitor traffic, SLAs, QoS, Medianet, WAAS etc. with NetFlow Analyzer > Customize your own dashboards, set traffic alerts and generate reports. > Network behavioral analysis & security monitoring. All-in-one tool. > http://pubads.g.doubleclick.net/gampad/clk?id=126839071&iu=/4140/ostg.clktrk > _______________________________________________ > tmux-users mailing list > tmux-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/tmux-users ------------------------------------------------------------------------------ Flow-based real-time traffic analytics software. Cisco certified tool. Monitor traffic, SLAs, QoS, Medianet, WAAS etc. with NetFlow Analyzer Customize your own dashboards, set traffic alerts and generate reports. Network behavioral analysis & security monitoring. All-in-one tool. http://pubads.g.doubleclick.net/gampad/clk?id=126839071&iu=/4140/ostg.clktrk _______________________________________________ tmux-users mailing list tmux-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tmux-users