mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:26:05 +00:00 
			
		
		
		
	Implement "all event" (1003) mouse mode but in a way that works. The
main issue is that if we have two panes, A with 1002 and B with 1003, we need to set 1003 outside tmux in order to get all the mouse events, but then we need to suppress the ones that pane A doesn't want. This is easy in SGR mouse mode, because buttons == 3 is only used for movement events (for other events the trailing m/M marks a release instead), but in normal mouse mode we can't tell so easily. So for that, look at the previous event instead - if it is drag+release as well, then the current event is a movement event.
This commit is contained in:
		@@ -335,14 +335,27 @@ server_client_check_mouse(struct client *c)
 | 
			
		||||
	int			 flag;
 | 
			
		||||
	key_code		 key;
 | 
			
		||||
	struct timeval		 tv;
 | 
			
		||||
	enum { NOTYPE, DOWN, UP, DRAG, WHEEL, DOUBLE, TRIPLE } type = NOTYPE;
 | 
			
		||||
	enum { NOWHERE, PANE, STATUS, BORDER } where = NOWHERE;
 | 
			
		||||
	enum { NOTYPE, MOVE, DOWN, UP, DRAG, WHEEL, DOUBLE, TRIPLE } type;
 | 
			
		||||
	enum { NOWHERE, PANE, STATUS, BORDER } where;
 | 
			
		||||
 | 
			
		||||
	type = NOTYPE;
 | 
			
		||||
	where = NOWHERE;
 | 
			
		||||
 | 
			
		||||
	log_debug("mouse %02x at %u,%u (last %u,%u) (%d)", m->b, m->x, m->y,
 | 
			
		||||
	    m->lx, m->ly, c->tty.mouse_drag_flag);
 | 
			
		||||
 | 
			
		||||
	/* What type of event is this? */
 | 
			
		||||
	if (MOUSE_DRAG(m->b)) {
 | 
			
		||||
	if ((m->sgr_type != ' ' &&
 | 
			
		||||
	    MOUSE_DRAG(m->sgr_b) &&
 | 
			
		||||
	    MOUSE_BUTTONS(m->sgr_b) == 3) ||
 | 
			
		||||
	    (m->sgr_type == ' ' &&
 | 
			
		||||
	    MOUSE_DRAG(m->b) &&
 | 
			
		||||
	    MOUSE_BUTTONS(m->b) == 3 &&
 | 
			
		||||
	    MOUSE_BUTTONS(m->lb) == 3)) {
 | 
			
		||||
		type = MOVE;
 | 
			
		||||
		x = m->x, y = m->y, b = 0;
 | 
			
		||||
		log_debug("move at %u,%u", x, y);
 | 
			
		||||
	} else if (MOUSE_DRAG(m->b)) {
 | 
			
		||||
		type = DRAG;
 | 
			
		||||
		if (c->tty.mouse_drag_flag) {
 | 
			
		||||
			x = m->x, y = m->y, b = m->b;
 | 
			
		||||
@@ -500,6 +513,14 @@ have_event:
 | 
			
		||||
	switch (type) {
 | 
			
		||||
	case NOTYPE:
 | 
			
		||||
		break;
 | 
			
		||||
	case MOVE:
 | 
			
		||||
		if (where == PANE)
 | 
			
		||||
			key = KEYC_MOUSEMOVE_PANE;
 | 
			
		||||
		if (where == STATUS)
 | 
			
		||||
			key = KEYC_MOUSEMOVE_STATUS;
 | 
			
		||||
		if (where == BORDER)
 | 
			
		||||
			key = KEYC_MOUSEMOVE_BORDER;
 | 
			
		||||
		break;
 | 
			
		||||
	case DRAG:
 | 
			
		||||
		if (c->tty.mouse_drag_update != NULL)
 | 
			
		||||
			key = KEYC_DRAGGING;
 | 
			
		||||
@@ -1055,7 +1076,7 @@ static void
 | 
			
		||||
server_client_reset_state(struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	struct window		*w = c->session->curw->window;
 | 
			
		||||
	struct window_pane	*wp = w->active;
 | 
			
		||||
	struct window_pane	*wp = w->active, *loop;
 | 
			
		||||
	struct screen		*s = wp->screen;
 | 
			
		||||
	struct options		*oo = c->session->options;
 | 
			
		||||
	int			 status, mode, o;
 | 
			
		||||
@@ -1079,8 +1100,15 @@ server_client_reset_state(struct client *c)
 | 
			
		||||
	 * mode.
 | 
			
		||||
	 */
 | 
			
		||||
	mode = s->mode;
 | 
			
		||||
	if (options_get_number(oo, "mouse"))
 | 
			
		||||
		mode = (mode & ~ALL_MOUSE_MODES) | MODE_MOUSE_BUTTON;
 | 
			
		||||
	if (options_get_number(oo, "mouse")) {
 | 
			
		||||
		mode &= ~ALL_MOUSE_MODES;
 | 
			
		||||
		TAILQ_FOREACH(loop, &w->panes, entry) {
 | 
			
		||||
			if (loop->screen->mode & MODE_MOUSE_ALL)
 | 
			
		||||
				mode |= MODE_MOUSE_ALL;
 | 
			
		||||
		}
 | 
			
		||||
		if (~mode & MODE_MOUSE_ALL)
 | 
			
		||||
			mode |= MODE_MOUSE_BUTTON;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Set the terminal mode and reset attributes. */
 | 
			
		||||
	tty_update_mode(&c->tty, mode, s);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user