From: a <g...@kracun.com>

added focus filtering

Will send \e[I or \e[O when panes are focused/unfocused. Must be
enabled with the focus-filter window option.
---
 cmd-break-pane.c  |  3 +++
 examples/tmux.vim |  2 +-
 input-keys.c      | 10 ++++++++++
 input.c           |  8 ++++++++
 options-table.c   |  5 +++++
 session.c         | 43 ++++++++++++++++++++-----------------------
 tmux.h            |  9 +++++++++
 tty-keys.c        |  6 +++++-
 window.c          | 31 ++++++++++++++++++++++++++++++-
 9 files changed, 91 insertions(+), 26 deletions(-)

diff --git a/cmd-break-pane.c b/cmd-break-pane.c
index 637105a..d927564 100644
--- a/cmd-break-pane.c
+++ b/cmd-break-pane.c
@@ -76,6 +76,9 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
                w->last = NULL;
        layout_close_pane(wp);
 
+       //aleks: focus on separated pane
+       window_pane_focus_notify(w->active, 1);
+
        w = wp->window = window_create1(s->sx, s->sy);
        TAILQ_INSERT_HEAD(&w->panes, wp, entry);
        w->active = wp;
diff --git a/examples/tmux.vim b/examples/tmux.vim
index f1a98be..6d93edd 100644
--- a/examples/tmux.vim
+++ b/examples/tmux.vim
@@ -69,7 +69,7 @@ syn keyword tmuxOptsSet
 syn keyword tmuxOptsSetw
        \ aggressive-resize alternate-screen automatic-rename
        \ c0-change-interval c0-change-trigger clock-mode-colour
-       \ clock-mode-style force-height force-width layout-history-limit
+       \ clock-mode-style focus-filter force-height force-width 
layout-history-limit
        \ main-pane-height main-pane-width mode-attr mode-bg mode-fg move-keys
        \ mode-mouse monitor-activity monitor-content monitor-silence
        \ other-pane-height other-pane-width pane-base-index remain-on-exit
diff --git a/input-keys.c b/input-keys.c
index 0953ce7..bab8119 100644
--- a/input-keys.c
+++ b/input-keys.c
@@ -130,6 +130,10 @@ const struct input_key_ent input_keys[] = {
        { KEYC_KP_ENTER,        "\n",           0 },
        { KEYC_KP_ZERO,         "0",            0 },
        { KEYC_KP_PERIOD,       ".",            0 },
+
+  //aleks:paired input for focus
+       { KEYC_FOCUS_IN,                "\033[I",               0 },
+       { KEYC_FOCUS_OUT,         "\033[O",             0 },
 };
 
 /* Translate a key code into an output key sequence. */
@@ -191,6 +195,12 @@ input_key(struct window_pane *wp, int key)
        dlen = strlen(ike->data);
        log_debug2("found key 0x%x: \"%s\"", key, ike->data);
 
+  if ( key == KEYC_FOCUS_IN || key == KEYC_FOCUS_OUT ) {
+         if (options_get_number(&wp->window->options, "focus-filter"))
+           if (!(wp->focus_notify & PANE_FOCUS_NOTIFY))
+             return;
+  }
+
        /* Prefix a \033 for escape. */
        if (key & KEYC_ESCAPE)
                bufferevent_write(wp->event, "\033", 1);
diff --git a/input.c b/input.c
index 3b8d76b..c3a9dca 100644
--- a/input.c
+++ b/input.c
@@ -1257,6 +1257,10 @@ input_csi_dispatch(struct input_ctx *ictx)
                case 1003:
                        screen_write_mousemode_off(&ictx->ctx);
                        break;
+               case 1004:
+                 //aleks
+                       window_pane_focus_notification_off(wp);
+                       break;
                case 1005:
                        screen_write_utf8mousemode(&ictx->ctx, 0);
                        break;
@@ -1316,6 +1320,10 @@ input_csi_dispatch(struct input_ctx *ictx)
                case 1003:
                        screen_write_mousemode_on(&ictx->ctx, MODE_MOUSE_ANY);
                        break;
+               case 1004:
+                 //aleks
+                       window_pane_focus_notification_on(wp);
+                       break;
                case 1005:
                        screen_write_utf8mousemode(&ictx->ctx, 1);
                        break;
diff --git a/options-table.c b/options-table.c
index 83ec97f..7069da9 100644
--- a/options-table.c
+++ b/options-table.c
@@ -502,6 +502,11 @@ const struct options_table_entry window_options_table[] = {
          .default_num = 1
        },
 
+       { .name = "focus-filter",
+         .type = OPTIONS_TABLE_FLAG,
+         .default_num = 0
+       },
+
        { .name = "force-height",
          .type = OPTIONS_TABLE_NUMBER,
          .minimum = 0,
diff --git a/session.c b/session.c
index 1f4fb30..c669924 100644
--- a/session.c
+++ b/session.c
@@ -345,13 +345,7 @@ session_next(struct session *s, int alert)
                if (alert && ((wl = session_next_alert(wl)) == NULL))
                        return (-1);
        }
-       if (wl == s->curw)
-               return (1);
-       winlink_stack_remove(&s->lastw, wl);
-       winlink_stack_push(&s->lastw, s->curw);
-       s->curw = wl;
-       winlink_clear_flags(wl);
-       return (0);
+       return session_set_current_winlink(s, wl);
 }
 
 struct winlink *
@@ -382,13 +376,7 @@ session_previous(struct session *s, int alert)
                if (alert && (wl = session_previous_alert(wl)) == NULL)
                        return (-1);
        }
-       if (wl == s->curw)
-               return (1);
-       winlink_stack_remove(&s->lastw, wl);
-       winlink_stack_push(&s->lastw, s->curw);
-       s->curw = wl;
-       winlink_clear_flags(wl);
-       return (0);
+       return session_set_current_winlink(s, wl);
 }
 
 /* Move session to specific window. */
@@ -398,15 +386,7 @@ session_select(struct session *s, int idx)
        struct winlink  *wl;
 
        wl = winlink_find_by_index(&s->windows, idx);
-       if (wl == NULL)
-               return (-1);
-       if (wl == s->curw)
-               return (1);
-       winlink_stack_remove(&s->lastw, wl);
-       winlink_stack_push(&s->lastw, s->curw);
-       s->curw = wl;
-       winlink_clear_flags(wl);
-       return (0);
+       return session_set_current_winlink(s, wl);
 }
 
 /* Move session to last used window. */
@@ -421,10 +401,27 @@ session_last(struct session *s)
        if (wl == s->curw)
                return (1);
 
+       return session_set_current_winlink(s, wl);
+}
+
+int
+session_set_current_winlink(struct session *s, struct winlink *wl)
+{
+       if (wl == NULL)
+               return (-1);
+       if (wl == s->curw)
+               return (1);
+
+       if (s->curw != NULL && s->curw->window != NULL)
+               window_pane_focus_notify(s->curw->window->active, 0);
+
        winlink_stack_remove(&s->lastw, wl);
        winlink_stack_push(&s->lastw, s->curw);
        s->curw = wl;
        winlink_clear_flags(wl);
+
+       window_pane_focus_notify(s->curw->window->active, 1);
+
        return (0);
 }
 
diff --git a/tmux.h b/tmux.h
index 1dd11ad..4940e8c 100644
--- a/tmux.h
+++ b/tmux.h
@@ -237,6 +237,9 @@ enum key_code {
        KEYC_KP_ENTER,
        KEYC_KP_ZERO,
        KEYC_KP_PERIOD,
+
+  KEYC_FOCUS_IN,
+  KEYC_FOCUS_OUT,
 };
 
 /* Termcap codes. */
@@ -917,6 +920,8 @@ struct window_pane {
        int              flags;
 #define PANE_REDRAW 0x1
 #define PANE_DROP 0x2
+       int              focus_notify;
+#define PANE_FOCUS_NOTIFY 0x1
 
        char            *cmd;
        char            *shell;
@@ -2118,6 +2123,9 @@ void               window_pane_alternate_on(struct 
window_pane *,
                     struct grid_cell *, int);
 void            window_pane_alternate_off(struct window_pane *,
                     struct grid_cell *, int);
+void            window_pane_focus_notification_on(struct window_pane *);
+void            window_pane_focus_notification_off(struct window_pane *);
+void            window_pane_focus_notify(struct window_pane *, int);
 int             window_pane_set_mode(
                     struct window_pane *, const struct window_mode *);
 void            window_pane_reset_mode(struct window_pane *);
@@ -2259,6 +2267,7 @@ int                session_next(struct session *, int);
 int             session_previous(struct session *, int);
 int             session_select(struct session *, int);
 int             session_last(struct session *);
+int             session_set_current_winlink(struct session *, struct winlink 
*);
 struct session_group *session_group_find(struct session *);
 u_int           session_group_index(struct session_group *);
 void            session_group_add(struct session *, struct session *);
diff --git a/tty-keys.c b/tty-keys.c
index 681f31b..4d1d4b6 100644
--- a/tty-keys.c
+++ b/tty-keys.c
@@ -29,7 +29,7 @@
 
 /*
  * Handle keys input from the outside terminal. tty_keys[] is a base table of
- * supported keys which are looked up in terminfo(5) and translated into a
+ * supported keys which are looked up in terminfo(6) and translated into a
  * ternary tree (a binary tree of binary trees).
  */
 
@@ -186,6 +186,10 @@ const struct tty_key_ent tty_keys[] = {
        { 0,    "\033[6@",      KEYC_NPAGE|KEYC_CTRL|KEYC_SHIFT,TTYKEY_RAW },
        { 0,    "\033[5@",      KEYC_PPAGE|KEYC_CTRL|KEYC_SHIFT,TTYKEY_RAW },
 
+       //aleks:define new terminal keys for focus
+       { 0,    "\033[I",       KEYC_FOCUS_IN, TTYKEY_RAW },
+       { 0,    "\033[O",       KEYC_FOCUS_OUT, TTYKEY_RAW },
+
        /* terminfo lookups below this line so they can override raw keys. */
 
        /* Function keys. */
diff --git a/window.c b/window.c
index aed7596..e7f5cb3 100644
--- a/window.c
+++ b/window.c
@@ -390,8 +390,11 @@ window_set_active_pane(struct window *w, struct 
window_pane *wp)
                if (w->active == NULL)
                        w->active = TAILQ_LAST(&w->panes, window_panes);
                if (w->active == wp)
-                       return;
+                       break;
        }
+       // aleks: write key-string to focused pane
+       window_pane_focus_notify(w->last, 0);
+       window_pane_focus_notify(wp, 1);
 }
 
 struct window_pane *
@@ -484,6 +487,9 @@ window_remove_pane(struct window *w, struct window_pane *wp)
 
        TAILQ_REMOVE(&w->panes, wp, entry);
        window_pane_destroy(wp);
+       // aleks: write key-string to focused pane
+       if (w != NULL)
+         window_pane_focus_notify(w->active, 1);
 }
 
 struct window_pane *
@@ -629,6 +635,8 @@ window_pane_create(struct window *w, u_int sx, u_int sy, 
u_int hlimit)
        wp->sx = sx;
        wp->sy = sy;
 
+       wp->focus_notify = 0;
+
        wp->pipe_fd = -1;
        wp->pipe_off = 0;
        wp->pipe_event = NULL;
@@ -952,6 +960,27 @@ window_pane_alternate_off(struct window_pane *wp, struct 
grid_cell *gc,
        wp->flags |= PANE_REDRAW;
 }
 
+//aleks: new term settings for focus
+void
+window_pane_focus_notification_on(struct window_pane *wp)
+{
+       wp->focus_notify |= PANE_FOCUS_NOTIFY;
+}
+
+void
+window_pane_focus_notification_off(struct window_pane *wp)
+{
+       wp->focus_notify &= ~PANE_FOCUS_NOTIFY;
+}
+
+void
+window_pane_focus_notify(struct window_pane *wp, int focused)
+{
+       if (wp != NULL && wp->event != NULL
+           && wp->focus_notify & PANE_FOCUS_NOTIFY)
+               bufferevent_write(wp->event, focused ? "\033[I" : "\033[O", 3);
+}
+
 int
 window_pane_set_mode(struct window_pane *wp, const struct window_mode *mode)
 {
-- 
1.8.1.3


------------------------------------------------------------------------------
The Go Parallel Website, sponsored by Intel - in partnership with Geeknet, 
is your hub for all things parallel software development, from weekly thought 
leadership blogs to news, videos, case studies, tutorials, tech docs, 
whitepapers, evaluation guides, and opinion stories. Check out the most 
recent posts - join the conversation now. http://goparallel.sourceforge.net/
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to