mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-03 16:46:18 +00:00 
			
		
		
		
	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:
		
							
								
								
									
										198
									
								
								window-copy.c
									
									
									
									
									
								
							
							
						
						
									
										198
									
								
								window-copy.c
									
									
									
									
									
								
							@@ -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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user