I see, so why do we want to disable it automatically in this case?


Sent from Mailbox for iPhone


On Thu, Feb 21, 2013 at 10:44 AM, Nicholas Marriott <nicholas.marriott@gmail.com> wrote:

XT is a terminfo flag which says the terminal "has some xterm features",
tmux uses it as a guide to mean that we can try fancy stuff that works
in xterm and may work elsewhere.

We should probably use something else because not may terminfo entries
actually have it (including the xterm terminfo itself).



On Thu, Feb 21, 2013 at 10:12:40AM -0800, Aaron Jensen wrote:
> Inlline...
> On Thu, Feb 21, 2013 at 9:28 AM, Nicholas Marriott
> <[1]nicholas.marriott@gmail.com> wrote:
>
> Ok the session_set_current_winlink idea is good so I have applied that
> bit but renamed to session_set_current.
>
> Here is an updated diff with a few changes:
>
> - Spacing fixes. Looks like your mailer mangles spaces. Can you fix that
> * or send the diffs as an attachment instead?
>
> Will do, sorry about that.
>
> - Renamed window_pane_focus_notify to just window_pane_focus.
> - Some other renaming and style nits.
> - Send \033[I if needed when first enabled.
>
> Interesting, if this is the expected behavior then this seems like a good
> change.
> *
>
> - Send \033[?1004l in tty.c if the terminal has XT flag.
>
> I did some googling but it's still not clear what this flag represents or
> why this is needed, could you explain please? I don't see this flag in my
> infocmp, so I'm guessing iterm2* does not have this so it won't affect me?
> *
>
> Please take a look at the diff below and let me know if you spot any
> errors before I commit it.
>
> I was thinking about the external focus reporting and I think just
> forwarding through the input will be fine. It will mean that the most
> recent state is the current state. So if you have two terminals and you
> enter them both and then exit one, you will lose focus. But most people
> don't use two computers simulatenously so I think this will not be a
> problem.
>
> Are you talking about the focus filtering here? If so, the problem with
> the external focus is not* things getting out of sync, but reporting
> happening to panes that do not want it. It's a hack of sorts to work
> around the fact that the external terminal doesn't understand the
> different panes in your tmux session. In other words, I would enable focus
> reporting in my terminal (iterm) and tmux both in pane 1. Then if I switch
> to pane 2, and leave focus of iterm, iterm would send ^[[O, which I do not
> actually want in pane 2, so the idea is to have tmux, which does have
> knowledge of who wants those events, discard those if they're not
> appropriate.
>
> Some more comments inline...
> *
>
> So when the bits below are in if you could update your other
> changes on top of them it would be great.
>
> diff --git a/cmd-break-pane.c b/cmd-break-pane.c
> index a4350fe..8e2a375 100644
> --- a/cmd-break-pane.c
> +++ b/cmd-break-pane.c
> @@ -44,7 +44,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx
> *ctx)
> * * * * struct args * * * * * * *args = self->args;
> * * * * struct winlink * * * * **wl;
> * * * * struct session * * * * **s;
> - * * * struct window_pane * * **wp;
> + * * * struct window_pane * * **wp, *out_wp, *in_wp;
> * * * * struct window * * * * * *w;
> * * * * char * * * * * * * * * **name;
> * * * * char * * * * * * * * * **cause;
> @@ -63,6 +63,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx
> *ctx)
> * * * * }
>
> * * * * w = wl->window;
> + * * * out_wp = w->active;
> * * * * TAILQ_REMOVE(&w->panes, wp, entry);
> * * * * if (wp == w->active) {
> * * * * * * * * w->active = w->last;
> @@ -74,6 +75,12 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx
> *ctx)
> * * * * * * * * }
> * * * * } else if (wp == w->last)
> * * * * * * * * w->last = NULL;
> +
> + * * * if (args_has(self->args, 'd'))
> + * * * * * * * in_wp = w->active;
> + * * * else
> + * * * * * * * in_wp = wp;
> +
> * * * * layout_close_pane(wp);
>
> * * * * w = wp->window = window_create1(s->sx, s->sy);
> @@ -89,6 +96,11 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx
> *ctx)
> * * * * if (!args_has(self->args, 'd'))
> * * * * * * * * session_select(s, wl->idx);
>
> + * * * if (out_wp != in_wp) {
> + * * * * * * * window_pane_focus(out_wp, 0);
> + * * * * * * * window_pane_focus(in_wp, 1);
> + * * * }
> +
>
> I think there's still a bug here, but I haven't tested these changes yet
> (they look only cosmetic). The problem is that if you break-pane the pane
> you're on will get a focus out.
> *
>
> * * * * server_redraw_session(s);
> * * * * server_status_session_group(s);
>
> diff --git a/input.c b/input.c
> index 4cf90ec..855ee8a 100644
> --- a/input.c
> +++ b/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,11 @@ 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:
> + * * * * * * * * * * * screen_write_mode_set(&ictx->ctx, MODE_FOCUSON);
> + * * * * * * * * * * * if (s->mode & MODE_FOCUSED)
> + * * * * * * * * * * * * * * * bufferevent_write(wp->event, "\033[I",
> 3);
> + * * * * * * * * * * * break;
> * * * * * * * * case 1005:
> * * * * * * * * * * * * screen_write_mode_set(&ictx->ctx,
> MODE_MOUSE_UTF8);
> * * * * * * * * * * * * break;
> diff --git a/session.c b/session.c
> index 72e8fb0..c7a01fd 100644
> --- a/session.c
> +++ b/session.c
> @@ -413,10 +413,16 @@ session_set_current(struct session *s, struct
> winlink *wl)
> * * * * if (wl == s->curw)
> * * * * * * * * return (1);
>
> + * * * if (s->curw != NULL && s->curw->window != NULL)
> + * * * * * * * window_pane_focus(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(s->curw->window->active, 1);
> +
> * * * * return (0);
> *}
>
> diff --git a/tmux.h b/tmux.h
> index 18e692f..2322b5b 100644
> --- a/tmux.h
> +++ b/tmux.h
> @@ -665,6 +665,8 @@ struct mode_key_table {
> *#define MODE_MOUSE_UTF8 0x100
> *#define MODE_MOUSE_SGR 0x200
> *#define MODE_BRACKETPASTE 0x400
> +#define MODE_FOCUSON 0x800
> +#define MODE_FOCUSED 0x1000
>
> *#define ALL_MOUSE_MODES
> (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ANY)
>
> @@ -2132,6 +2134,7 @@ 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(struct window_pane *, int);
> *int * * * * * * window_pane_set_mode(
> * * * * * * * * * * *struct window_pane *, const struct window_mode *);
> *void * * * * * *window_pane_reset_mode(struct window_pane *);
> diff --git a/tty.c b/tty.c
> index 1abaea4..b5dcf6d 100644
> --- a/tty.c
> +++ b/tty.c
> @@ -221,7 +221,7 @@ tty_start_tty(struct tty *tty)
> * * * * * * * * tty_puts(tty, "\033[?1000l\033[?1006l\033[?1005l");
>
> * * * * if (tty_term_has(tty->term, TTYC_XT))
> - * * * * * * * tty_puts(tty, "\033[c\033[>4;1m");
> + * * * * * * * tty_puts(tty, "\033[c\033[>4;1m\033[?1004l");
>
> * * * * tty->cx = UINT_MAX;
> * * * * tty->cy = UINT_MAX;
> diff --git a/window.c b/window.c
> index 77f06f8..457e3e1 100644
> --- a/window.c
> +++ b/window.c
> @@ -390,8 +390,10 @@ 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;
> * * * * }
> + * * * window_pane_focus(w->last, 0);
> + * * * window_pane_focus(wp, 1);
> *}
>
> *struct window_pane *
> @@ -484,6 +486,8 @@ window_remove_pane(struct window *w, struct
> window_pane *wp)
>
> * * * * TAILQ_REMOVE(&w->panes, wp, entry);
> * * * * window_pane_destroy(wp);
> + * * * if (w != NULL)
> + * * * * * * * window_pane_focus(w->active, 1);
> *}
>
> *struct window_pane *
> @@ -950,6 +954,30 @@ window_pane_alternate_off(struct window_pane *wp,
> struct grid_cell *gc,
> * * * * wp->flags |= PANE_REDRAW;
> *}
>
> +void
> +window_pane_focus(struct window_pane *wp, int focused)
> +{
> + * * * int * * already_focused;
> +
> + * * * if (wp == NULL)
> + * * * * * * * return;
>
> If I remember correctly, wp->event is NULL in some cases (closing the last
> pane for example) which is why I added that check. It crashed on exit.
> *
>
> +
> + * * * already_focused = (wp->screen->mode & MODE_FOCUSED);
> + * * * if (focused && !already_focused) {
> + * * * * * * * wp->screen->mode |= MODE_FOCUSED;
> +
> + * * * * * * * if (wp->screen->mode & MODE_FOCUSON)
> + * * * * * * * * * * * bufferevent_write(wp->event, "\033[I", 3);
> + * * * }
> +
> + * * * if (!focused && already_focused) {
> + * * * * * * * wp->screen->mode &= ~MODE_FOCUSED;
> +
> + * * * * * * * if (wp->screen->mode & MODE_FOCUSON)
> + * * * * * * * * * * * bufferevent_write(wp->event, "\033[O", 3);
> + * * * }
> +}
> +
> *int
> *window_pane_set_mode(struct window_pane *wp, const struct window_mode
> *mode)
> *{
>
> References
>
> Visible links
> 1. mailto:nicholas.marriott@gmail.com