From 963b2b6b1fc55de1d0a8abe1fe9e795ab798c992 Mon Sep 17 00:00:00 2001
From: Anish Athalye <me@anishathalye.com>
Date: Wed, 6 Aug 2014 22:29:59 -0700
Subject: [PATCH] Add feature to enable or disable keyboard input

Add new options to the select-pane command to enable or disable keyboard
input for specific panes.
---
 cmd-select-pane.c | 30 +++++++++++++++++++++---------
 server-fn.c       | 12 ++++++++++++
 tmux.1            |  9 ++++++++-
 tmux.h            |  3 +++
 window.c          |  4 ++++
 5 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/cmd-select-pane.c b/cmd-select-pane.c
index c342fef..a4340bb 100644
--- a/cmd-select-pane.c
+++ b/cmd-select-pane.c
@@ -29,8 +29,8 @@ enum cmd_retval	 cmd_select_pane_exec(struct cmd *, struct cmd_q *);
 
 const struct cmd_entry cmd_select_pane_entry = {
 	"select-pane", "selectp",
-	"lDLRt:U", 0, 0,
-	"[-lDLRU] " CMD_TARGET_PANE_USAGE,
+	"edlDLRt:U", 0, 0,
+	"[-ed] [-lDLRU] " CMD_TARGET_PANE_USAGE,
 	0,
 	cmd_select_pane_key_binding,
 	cmd_select_pane_exec
@@ -78,10 +78,16 @@ cmd_select_pane_exec(struct cmd *self, struct cmd_q *cmdq)
 			return (CMD_RETURN_ERROR);
 		}
 
-		server_unzoom_window(wl->window);
-		window_set_active_pane(wl->window, wl->window->last);
-		server_status_window(wl->window);
-		server_redraw_window_borders(wl->window);
+		if (args_has(self->args, 'e'))
+			server_enable_input(wl->window->last);
+		else if (args_has(self->args, 'd'))
+			server_disable_input(wl->window->last);
+		else {
+			server_unzoom_window(wl->window);
+			window_set_active_pane(wl->window, wl->window->last);
+			server_status_window(wl->window);
+			server_redraw_window_borders(wl->window);
+		}
 
 		return (CMD_RETURN_NORMAL);
 	}
@@ -108,9 +114,15 @@ cmd_select_pane_exec(struct cmd *self, struct cmd_q *cmdq)
 		return (CMD_RETURN_ERROR);
 	}
 
-	window_set_active_pane(wl->window, wp);
-	server_status_window(wl->window);
-	server_redraw_window_borders(wl->window);
+	if (args_has(self->args, 'e'))
+		server_enable_input(wp);
+	else if (args_has(self->args, 'd'))
+		server_disable_input(wp);
+	else {
+		window_set_active_pane(wl->window, wp);
+		server_status_window(wl->window);
+		server_redraw_window_borders(wl->window);
+	}
 
 	return (CMD_RETURN_NORMAL);
 }
diff --git a/server-fn.c b/server-fn.c
index e0859f7..475ef7f 100644
--- a/server-fn.c
+++ b/server-fn.c
@@ -257,6 +257,18 @@ server_lock_client(struct client *c)
 }
 
 void
+server_disable_input(struct window_pane *wp)
+{
+	wp->flags |= PANE_INPUT_DISABLED;
+}
+
+void
+server_enable_input(struct window_pane *wp)
+{
+	wp->flags &= ~PANE_INPUT_DISABLED;
+}
+
+void
 server_kill_window(struct window *w)
 {
 	struct session		*s, *next_s, *target_s;
diff --git a/tmux.1 b/tmux.1
index 924157d..4824e31 100644
--- a/tmux.1
+++ b/tmux.1
@@ -1296,7 +1296,7 @@ flag, see the
 section.
 This command works only if at least one client is attached.
 .It Ic display-panes Op Fl t Ar target-client
-.D1 (alias: Ic displayp)
+.D1 (alias: Ic displayp )
 Display a visible indicator of each pane shown by
 .Ar target-client .
 See the
@@ -1705,6 +1705,7 @@ and
 .Ic previous-layout
 commands.
 .It Xo Ic select-pane
+.Op Fl ed
 .Op Fl lDLRU
 .Op Fl t Ar target-pane
 .Xc
@@ -1714,6 +1715,12 @@ Make pane
 the active pane in window
 .Ar target-window .
 If one of
+.Fl e
+or
+.Fl d
+is used, the pane is not made the active pane, and instead, keyboard input to
+the pane is enabled or disabled, respectively.
+If one of
 .Fl D ,
 .Fl L ,
 .Fl R ,
diff --git a/tmux.h b/tmux.h
index c4c5236..3e8b82e 100644
--- a/tmux.h
+++ b/tmux.h
@@ -918,6 +918,7 @@ struct window_pane {
 #define PANE_FOCUSED 0x4
 #define PANE_RESIZE 0x8
 #define PANE_FOCUSPUSH 0x10
+#define PANE_INPUT_DISABLED 0x20
 
 	int		 argc;
 	char	       **argv;
@@ -1940,6 +1941,8 @@ void	 server_lock(void);
 void	 server_lock_session(struct session *);
 void	 server_lock_client(struct client *);
 int	 server_unlock(const char *);
+void	 server_disable_input(struct window_pane *);
+void	 server_enable_input(struct window_pane *);
 void	 server_kill_window(struct window *);
 int	 server_link_window(struct session *,
 	     struct winlink *, struct session *, int, int, int, char **);
diff --git a/window.c b/window.c
index 5b93f93..e78142a 100644
--- a/window.c
+++ b/window.c
@@ -1076,6 +1076,10 @@ window_pane_key(struct window_pane *wp, struct session *sess, int key)
 
 	if (wp->fd == -1)
 		return;
+
+	if (wp->flags & PANE_INPUT_DISABLED)
+		return;
+
 	input_key(wp, key);
 	if (options_get_number(&wp->window->options, "synchronize-panes")) {
 		TAILQ_FOREACH(wp2, &wp->window->panes, entry) {
-- 
2.0.1

