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