Rewrite of tmux mouse support which was a mess. Instead of having

options for "mouse-this" and "mouse-that", mouse events may be bound as
keys and there is one option "mouse" that turns on mouse support
entirely (set -g mouse on).

See the new MOUSE SUPPORT section of the man page for description of the
key names and new flags (-t= to specify the pane or window under mouse
as a target, and send-keys -M to pass through a mouse event).

The default builtin bindings for the mouse are:

    bind -n   MouseDown1Pane select-pane -t=; send-keys -M
    bind -n MouseDown1Status select-window -t=
    bind -n   MouseDrag1Pane copy-mode -M
    bind -n MouseDrag1Border resize-pane -M

To get the effect of turning mode-mouse off, do:

    unbind -n MouseDrag1Pane
    unbind -temacs-copy MouseDrag1Pane

The old mouse options are now gone, set-option -q may be used to
suppress warnings if mixing configuration files.
This commit is contained in:
nicm
2015-04-19 21:34:21 +00:00
parent ee123c2489
commit bf635e7741
27 changed files with 879 additions and 584 deletions

View File

@ -27,11 +27,10 @@
struct screen *window_copy_init(struct window_pane *);
void window_copy_free(struct window_pane *);
void window_copy_resize(struct window_pane *, u_int, u_int);
void window_copy_key(struct window_pane *, struct session *, int);
void window_copy_key(struct window_pane *, struct client *, struct session *,
int, struct mouse_event *);
int window_copy_key_input(struct window_pane *, int);
int window_copy_key_numeric_prefix(struct window_pane *, int);
void window_copy_mouse(struct window_pane *, struct session *,
struct mouse_event *);
void window_copy_redraw_selection(struct window_pane *, u_int);
void window_copy_redraw_lines(struct window_pane *, u_int, u_int);
@ -84,13 +83,14 @@ void window_copy_cursor_previous_word(struct window_pane *, const char *);
void window_copy_scroll_up(struct window_pane *, u_int);
void window_copy_scroll_down(struct window_pane *, u_int);
void window_copy_rectangle_toggle(struct window_pane *);
void window_copy_drag_update(struct client *, struct mouse_event *);
void window_copy_drag_release(struct client *, struct mouse_event *);
const struct window_mode window_copy_mode = {
window_copy_init,
window_copy_free,
window_copy_resize,
window_copy_key,
window_copy_mouse,
NULL,
};
@ -124,38 +124,38 @@ enum window_copy_input_type {
* mode ends).
*/
struct window_copy_mode_data {
struct screen screen;
struct screen screen;
struct screen *backing;
int backing_written; /* backing display has started */
struct screen *backing;
int backing_written; /* backing display started */
struct mode_key_data mdata;
struct mode_key_data mdata;
u_int oy;
u_int oy;
u_int selx;
u_int sely;
u_int selx;
u_int sely;
u_int rectflag; /* are we in rectangle copy mode? */
u_int rectflag; /* are we in rectangle copy mode? */
u_int cx;
u_int cy;
u_int cx;
u_int cy;
u_int lastcx; /* position in last line with content */
u_int lastsx; /* size of last line with content */
u_int lastcx; /* position in last line w/ content */
u_int lastsx; /* size of last line w/ content */
enum window_copy_input_type inputtype;
const char *inputprompt;
char *inputstr;
int inputexit;
const char *inputprompt;
char *inputstr;
int inputexit;
int numprefix;
int numprefix;
enum window_copy_input_type searchtype;
char *searchstr;
char *searchstr;
enum window_copy_input_type jumptype;
char jumpchar;
char jumpchar;
};
struct screen *
@ -193,8 +193,6 @@ window_copy_init(struct window_pane *wp)
s = &data->screen;
screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
if (options_get_number(&wp->window->options, "mode-mouse"))
s->mode |= MODE_MOUSE_STANDARD;
keys = options_get_number(&wp->window->options, "mode-keys");
if (keys == MODEKEY_EMACS)
@ -367,19 +365,20 @@ window_copy_resize(struct window_pane *wp, u_int sx, u_int sy)
}
void
window_copy_key(struct window_pane *wp, struct session *sess, int key)
window_copy_key(struct window_pane *wp, struct client *c, struct session *sess,
int key, struct mouse_event *m)
{
const char *word_separators;
struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
u_int n;
int np, keys;
u_int n, np;
int keys;
enum mode_key_cmd cmd;
const char *arg, *ss;
np = data->numprefix;
if (np <= 0)
np = 1;
np = 1;
if (data->numprefix > 0)
np = data->numprefix;
if (data->inputtype == WINDOW_COPY_JUMPFORWARD ||
data->inputtype == WINDOW_COPY_JUMPBACK ||
@ -536,9 +535,14 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
window_copy_redraw_screen(wp);
break;
case MODEKEYCOPY_STARTSELECTION:
s->sel.lineflag = LINE_SEL_NONE;
window_copy_start_selection(wp);
window_copy_redraw_screen(wp);
if (KEYC_IS_MOUSE(key)) {
if (c != NULL)
window_copy_start_drag(c, m);
} else {
s->sel.lineflag = LINE_SEL_NONE;
window_copy_start_selection(wp);
window_copy_redraw_screen(wp);
}
break;
case MODEKEYCOPY_SELECTLINE:
s->sel.lineflag = LINE_SEL_LEFT_RIGHT;
@ -887,75 +891,6 @@ window_copy_key_numeric_prefix(struct window_pane *wp, int key)
return (0);
}
void
window_copy_mouse(struct window_pane *wp, struct session *sess,
struct mouse_event *m)
{
struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
u_int i, old_cy;
if (m->x >= screen_size_x(s))
return;
if (m->y >= screen_size_y(s))
return;
/* If mouse wheel (buttons 4 and 5), scroll. */
if (m->event == MOUSE_EVENT_WHEEL) {
for (i = 0; i < m->scroll; i++) {
if (m->wheel == MOUSE_WHEEL_UP)
window_copy_cursor_up(wp, 1);
else {
window_copy_cursor_down(wp, 1);
/*
* We reached the bottom, leave copy mode, but
* only if no selection is in progress.
*/
if (data->oy == 0 && !s->sel.flag &&
s->sel.lineflag == LINE_SEL_NONE)
goto reset_mode;
}
}
return;
}
/*
* If already reading motion, move the cursor while buttons are still
* pressed, or stop the selection on their release.
*/
if (s->mode & MODE_MOUSE_BUTTON) {
if (~m->event & MOUSE_EVENT_UP) {
old_cy = data->cy;
window_copy_update_cursor(wp, m->x, m->y);
if (window_copy_update_selection(wp, 1))
window_copy_redraw_selection(wp, old_cy);
return;
}
goto reset_mode;
}
/* Otherwise if other buttons pressed, start selection and motion. */
if (~m->event & MOUSE_EVENT_UP) {
s->mode &= ~MODE_MOUSE_STANDARD;
s->mode |= MODE_MOUSE_BUTTON;
window_copy_update_cursor(wp, m->x, m->y);
window_copy_start_selection(wp);
window_copy_redraw_screen(wp);
}
return;
reset_mode:
s->mode &= ~MODE_MOUSE_BUTTON;
s->mode |= MODE_MOUSE_STANDARD;
if (sess != NULL) {
window_copy_copy_selection(wp, NULL);
window_pane_reset_mode(wp);
}
}
void
window_copy_scroll_to(struct window_pane *wp, u_int px, u_int py)
{
@ -2274,3 +2209,62 @@ window_copy_rectangle_toggle(struct window_pane *wp)
window_copy_update_selection(wp, 1);
window_copy_redraw_screen(wp);
}
void
window_copy_start_drag(struct client *c, unused struct mouse_event *m)
{
struct window_pane *wp;
struct window_copy_mode_data *data;
u_int x, y;
wp = cmd_mouse_pane(m, NULL, NULL);
if (wp->mode != &window_copy_mode)
return;
data = wp->modedata;
if (cmd_mouse_at(wp, m, &x, &y, 1) != 0)
return;
c->tty.mouse_drag_update = window_copy_drag_update;
c->tty.mouse_drag_release = window_copy_drag_release;
window_copy_update_cursor(wp, x, y);
window_copy_start_selection(wp);
window_copy_redraw_screen(wp);
}
void
window_copy_drag_update(unused struct client *c, struct mouse_event *m)
{
struct window_pane *wp;
struct window_copy_mode_data *data;
u_int x, y, old_cy;
wp = cmd_mouse_pane(m, NULL, NULL);
if (wp->mode != &window_copy_mode)
return;
data = wp->modedata;
if (cmd_mouse_at(wp, m, &x, &y, 0) != 0)
return;
old_cy = data->cy;
window_copy_update_cursor(wp, x, y);
if (window_copy_update_selection(wp, 1))
window_copy_redraw_selection(wp, old_cy);
}
void
window_copy_drag_release(unused struct client *c, struct mouse_event *m)
{
struct window_pane *wp;
struct window_copy_mode_data *data;
wp = cmd_mouse_pane(m, NULL, NULL);
if (wp->mode != &window_copy_mode)
return;
data = wp->modedata;
window_copy_copy_selection(wp, NULL);
window_pane_reset_mode(wp);
}