From 2de75eb5557ea2b248a0d1353181c5f9619992e7 Mon Sep 17 00:00:00 2001
From: Anish Athalye <me@anishathalye.com>
Date: Wed, 6 Aug 2014 22:29:59 -0700
Subject: [PATCH] Implement command to enable / disable input

This patch adds two new commands: `disable-input` and `enable-input`.
These commands allow clients to enable or disable keyboard input for
specific panes.
---
 Makefile.am                      |  1 +
 cmd-input.c                      | 65 ++++++++++++++++++++++++++++++++++++++++
 cmd.c                            |  2 ++
 examples/bash_completion_tmux.sh |  2 ++
 examples/tmux.vim                |  4 +++
 server-fn.c                      | 12 ++++++++
 tmux.1                           | 16 ++++++++--
 tmux.h                           |  5 ++++
 window.c                         |  4 +++
 9 files changed, 109 insertions(+), 2 deletions(-)
 create mode 100644 cmd-input.c

diff --git a/Makefile.am b/Makefile.am
index 5f622ac..4f75efc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -103,6 +103,7 @@ dist_tmux_SOURCES = \
 	cmd-move-window.c \
 	cmd-new-session.c \
 	cmd-new-window.c \
+	cmd-input.c \
 	cmd-paste-buffer.c \
 	cmd-pipe-pane.c \
 	cmd-queue.c \
diff --git a/cmd-input.c b/cmd-input.c
new file mode 100644
index 0000000..94d2499
--- /dev/null
+++ b/cmd-input.c
@@ -0,0 +1,65 @@
+/* $Id$ */
+
+/*
+ * Copyright (c) 2014 Anish Athalye <me@anishathalye.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+
+#include "tmux.h"
+
+/*
+ * Enable or disable keyboard input for a pane.
+ */
+
+enum cmd_retval	 cmd_input_exec(struct cmd *, struct cmd_q *);
+
+const struct cmd_entry cmd_disable_input_entry = {
+	"disable-input", "disable",
+	"t:", 0, 0,
+	CMD_TARGET_PANE_USAGE,
+	0,
+	NULL,
+	cmd_input_exec
+};
+
+const struct cmd_entry cmd_enable_input_entry = {
+	"enable-input", "enable",
+	"t:", 0, 0,
+	CMD_TARGET_PANE_USAGE,
+	0,
+	NULL,
+	cmd_input_exec
+};
+
+enum cmd_retval
+cmd_input_exec(struct cmd *self, struct cmd_q *cmdq)
+{
+	struct args		*args = self->args;
+	struct session		*s;
+	struct window_pane	*wp;
+
+	if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL)
+		return (CMD_RETURN_ERROR);
+
+	if (self->entry == &cmd_disable_input_entry)
+		server_disable_input(wp);
+	else
+		server_enable_input(wp);
+
+	return (CMD_RETURN_NORMAL);
+}
diff --git a/cmd.c b/cmd.c
index 3a948c8..c897899 100644
--- a/cmd.c
+++ b/cmd.c
@@ -44,8 +44,10 @@ const struct cmd_entry *cmd_table[] = {
 	&cmd_copy_mode_entry,
 	&cmd_delete_buffer_entry,
 	&cmd_detach_client_entry,
+	&cmd_disable_input_entry,
 	&cmd_display_message_entry,
 	&cmd_display_panes_entry,
+	&cmd_enable_input_entry,
 	&cmd_find_window_entry,
 	&cmd_has_session_entry,
 	&cmd_if_shell_entry,
diff --git a/examples/bash_completion_tmux.sh b/examples/bash_completion_tmux.sh
index 74728b9..78560af 100644
--- a/examples/bash_completion_tmux.sh
+++ b/examples/bash_completion_tmux.sh
@@ -25,10 +25,12 @@ _tmux()
     copy-mode \
     delete-buffer \
     detach-client \
+    disable-input \
     display-message \
     display-panes \
     down-pane \
     find-window \
+    enable-input \
     has-session \
     if-shell \
     join-pane \
diff --git a/examples/tmux.vim b/examples/tmux.vim
index 4d64514..a6f7e2c 100644
--- a/examples/tmux.vim
+++ b/examples/tmux.vim
@@ -52,9 +52,13 @@ syn keyword tmuxCmds
 	\ delete-buffer
 	\ deleteb
 	\ detach[-client]
+	\ disable-input
+	\ disable
 	\ display[-message]
 	\ display-panes
 	\ displayp
+	\ enable-input
+	\ enable
 	\ find-window
 	\ findw
 	\ has[-session]
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..70d1c63 100644
--- a/tmux.1
+++ b/tmux.1
@@ -14,7 +14,7 @@
 .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: March 25 2013 $
+.Dd $Mdocdate: August 6 2014 $
 .Dt TMUX 1
 .Os
 .Sh NAME
@@ -1295,8 +1295,14 @@ flag, see the
 .Sx FORMATS
 section.
 This command works only if at least one client is attached.
+.It Ic disable-input Op Fl t Ar target-pane
+.D1 (alias: Ic disable )
+Disable keyboard input for
+.Ar target-pane .
+This can be reversed by
+.Ic enable-input .
 .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
@@ -1310,6 +1316,12 @@ While the indicator is on screen, a pane may be selected with the
 to
 .Ql 9
 keys.
+.It Ic enable-input Op Fl t Ar target-pane
+.D1 (alias: Ic enable )
+Enable keyboard input for
+.Ar target-pane .
+This can be reversed by
+.Ic disable-input .
 .It Xo Ic find-window
 .Op Fl CNT
 .Op Fl F Ar format
diff --git a/tmux.h b/tmux.h
index c4c5236..583c9ca 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;
@@ -1789,9 +1790,11 @@ extern const struct cmd_entry cmd_confirm_before_entry;
 extern const struct cmd_entry cmd_copy_mode_entry;
 extern const struct cmd_entry cmd_delete_buffer_entry;
 extern const struct cmd_entry cmd_detach_client_entry;
+extern const struct cmd_entry cmd_disable_input_entry;
 extern const struct cmd_entry cmd_display_message_entry;
 extern const struct cmd_entry cmd_display_panes_entry;
 extern const struct cmd_entry cmd_down_pane_entry;
+extern const struct cmd_entry cmd_enable_input_entry;
 extern const struct cmd_entry cmd_find_window_entry;
 extern const struct cmd_entry cmd_has_session_entry;
 extern const struct cmd_entry cmd_if_shell_entry;
@@ -1940,6 +1943,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

