mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-03 16:46:18 +00:00 
			
		
		
		
	Add support for focus notifications when tmux pane changes, based on work by
Aaron Jensen.
This commit is contained in:
		
							
								
								
									
										9
									
								
								input.c
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								input.c
									
									
									
									
									
								
							@@ -1260,6 +1260,9 @@ input_csi_dispatch(struct input_ctx *ictx)
 | 
			
		||||
		case 1003:
 | 
			
		||||
			screen_write_mode_clear(&ictx->ctx, ALL_MOUSE_MODES);
 | 
			
		||||
			break;
 | 
			
		||||
		case 1004:
 | 
			
		||||
			screen_write_mode_clear(&ictx->ctx, MODE_FOCUSON);
 | 
			
		||||
			break;
 | 
			
		||||
		case 1005:
 | 
			
		||||
			screen_write_mode_clear(&ictx->ctx, MODE_MOUSE_UTF8);
 | 
			
		||||
			break;
 | 
			
		||||
@@ -1326,6 +1329,12 @@ input_csi_dispatch(struct input_ctx *ictx)
 | 
			
		||||
			screen_write_mode_clear(&ictx->ctx, ALL_MOUSE_MODES);
 | 
			
		||||
			screen_write_mode_set(&ictx->ctx, MODE_MOUSE_ANY);
 | 
			
		||||
			break;
 | 
			
		||||
		case 1004:
 | 
			
		||||
			if (s->mode & MODE_FOCUSON)
 | 
			
		||||
				break;
 | 
			
		||||
			screen_write_mode_set(&ictx->ctx, MODE_FOCUSON);
 | 
			
		||||
			wp->flags &= ~PANE_FOCUSED; /* force update if needed */
 | 
			
		||||
			break;
 | 
			
		||||
		case 1005:
 | 
			
		||||
			screen_write_mode_set(&ictx->ctx, MODE_MOUSE_UTF8);
 | 
			
		||||
			break;
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@
 | 
			
		||||
 | 
			
		||||
#include "tmux.h"
 | 
			
		||||
 | 
			
		||||
void	server_client_check_focus(struct window_pane *);
 | 
			
		||||
void	server_client_check_mouse(struct client *, struct window_pane *);
 | 
			
		||||
void	server_client_repeat_timer(int, short, void *);
 | 
			
		||||
void	server_client_check_exit(struct client *);
 | 
			
		||||
@@ -494,7 +495,7 @@ server_client_loop(void)
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Any windows will have been redrawn as part of clients, so clear
 | 
			
		||||
	 * their flags now.
 | 
			
		||||
	 * their flags now. Also check and update pane focus.
 | 
			
		||||
	 */
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
 | 
			
		||||
		w = ARRAY_ITEM(&windows, i);
 | 
			
		||||
@@ -502,11 +503,54 @@ server_client_loop(void)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		w->flags &= ~WINDOW_REDRAW;
 | 
			
		||||
		TAILQ_FOREACH(wp, &w->panes, entry)
 | 
			
		||||
		TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
			
		||||
			server_client_check_focus(wp);
 | 
			
		||||
			wp->flags &= ~PANE_REDRAW;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Check whether pane should be focused. */
 | 
			
		||||
void
 | 
			
		||||
server_client_check_focus(struct window_pane *wp)
 | 
			
		||||
{
 | 
			
		||||
	struct session	*s;
 | 
			
		||||
 | 
			
		||||
	/* If we don't care about focus, forget it. */
 | 
			
		||||
	if (!(wp->base.mode & MODE_FOCUSON))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	/* If we're not the active pane in our window, we're not focused. */
 | 
			
		||||
	if (wp->window->active != wp)
 | 
			
		||||
		goto not_focused;
 | 
			
		||||
 | 
			
		||||
	/* If we're in a mode, we're not focused. */
 | 
			
		||||
	if (wp->screen != &wp->base)
 | 
			
		||||
		goto not_focused;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * If our window is the current window in any attached sessions, we're
 | 
			
		||||
	 * focused.
 | 
			
		||||
	 */
 | 
			
		||||
	RB_FOREACH(s, sessions, &sessions) {
 | 
			
		||||
		if (s->flags & SESSION_UNATTACHED)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (s->curw->window == wp->window)
 | 
			
		||||
			goto focused;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
not_focused:
 | 
			
		||||
	if (wp->flags & PANE_FOCUSED)
 | 
			
		||||
		bufferevent_write(wp->event, "\033[O", 3);
 | 
			
		||||
	wp->flags &= ~PANE_FOCUSED;
 | 
			
		||||
	return;
 | 
			
		||||
 | 
			
		||||
focused:
 | 
			
		||||
	if (!(wp->flags & PANE_FOCUSED))
 | 
			
		||||
		bufferevent_write(wp->event, "\033[I", 3);
 | 
			
		||||
	wp->flags |= PANE_FOCUSED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Update cursor position and mode settings. The scroll region and attributes
 | 
			
		||||
 * are cleared when idle (waiting for an event) as this is the most likely time
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								tmux.h
									
									
									
									
									
								
							@@ -665,6 +665,7 @@ struct mode_key_table {
 | 
			
		||||
#define MODE_MOUSE_UTF8 0x100
 | 
			
		||||
#define MODE_MOUSE_SGR 0x200
 | 
			
		||||
#define MODE_BRACKETPASTE 0x400
 | 
			
		||||
#define MODE_FOCUSON 0x800
 | 
			
		||||
 | 
			
		||||
#define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ANY)
 | 
			
		||||
 | 
			
		||||
@@ -926,6 +927,7 @@ struct window_pane {
 | 
			
		||||
	int		 flags;
 | 
			
		||||
#define PANE_REDRAW 0x1
 | 
			
		||||
#define PANE_DROP 0x2
 | 
			
		||||
#define PANE_FOCUSED 0x4
 | 
			
		||||
 | 
			
		||||
	char		*cmd;
 | 
			
		||||
	char		*shell;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user