Ok, here's a new patch. A few things to note:

1) It probably could use some more testing. I removed the safeguard that 
prevented the keys to getting through to panes that didn't have focus tracking 
enabled. In my testing I did see the keys get sent to a pane they shouldn't 
have though. I'm not sure how it happened. Also, as a result of removing this 
safeguard I'm not sure if the KEYC_FOCUS_IN/OUT definitions are still needed in 
tty-keys.c, I don't know what that's for.

2) Sometimes it takes a few seconds for the focus out key to be sent when 
creating a new pane via split window. I'm not sure if this is an artifact of 
the buffer write or what. It's beyond me to figure out how to make that happen 
more immediately, but maybe you guys would know.

3) I removed the option completely, it's not needed I don't think.

4) akracun had added some logic to let panes track their focus status so they 
couldn't ever get double notified. It's not a bad idea, but I was worried that 
the same way panes would get double notified would lead them to get their is 
focused flag out of sync with reality so I removed it. I think double notify is 
better than not notifying, but what do you guys think?

5) I haven't updated CHANGES or man pages, I'm not sure if I should or if you 
guys will.

Thanks,

Aaron



>From 861356b8d074a7b4f3cc55f130270439cad3d756 Mon Sep 17 00:00:00 2001
From: Aaron Jensen <aaronjen...@gmail.com>
Date: Tue, 19 Feb 2013 23:44:53 -0800
Subject: [PATCH] Squashed commit of the following:

commit 8ef8f2e6784a338af937e6fc43018c607524ca7e
Author: Aaron Jensen <aaronjen...@gmail.com>
Date:   Tue Feb 19 23:36:36 2013 -0800

    fix tabs

commit b7fbfeaa058181b894f57232c1ac9f29a6b07bb4
Author: Aaron Jensen <aaronjen...@gmail.com>
Date:   Tue Feb 19 22:57:47 2013 -0800

    use existing flags

    Also remove has_focus check, we shouldn't need it.

commit cd8d698a4066641aac72b94f8be676bb50ad65d0
Author: Aaron Jensen <aaronjen...@gmail.com>
Date:   Tue Feb 19 22:57:17 2013 -0800

    Handle all break-pane cases

commit 7dc35ac62a024816e5443af367152c026beb9cd4
Author: Aaron Jensen <aaronjen...@gmail.com>
Date:   Tue Feb 19 22:55:21 2013 -0800

    Remove safeguard

    We won't send this if it's not enabled on the pane, no need to double check.
    If someone else sends it, so be it.

commit c3854bc78d0b433a5b71f8f65bff351d682947ce
Author: Aaron Jensen <aaronjen...@gmail.com>
Date:   Tue Feb 19 22:54:25 2013 -0800

    Remove focus-filter option

commit a5e96ea4d1fab44f66904444ce9b2ff3c239c57b
Author: a <g...@kracun.com>
Date:   Tue Feb 19 13:23:22 2013 -0800

    removed helper functions for notification, cleaned up formating

commit d54d7aa02160578612e6443a60d3ec1feb35805e
Author: a <g...@kracun.com>
Date:   Tue Feb 19 13:11:34 2013 -0800

    track focus for each pane, prevent double focus notification on break-pane

commit d7495549259b1bcca934591d7045bc733e301805
Author: Aaron Jensen <aaronjen...@gmail.com>
Date:   Tue Feb 19 07:26:55 2013 -0800

    Clean up formatting

commit aabbcfb21e8a1442f2f3ae2ad34408652c7bd31f
Author: Aaron Jensen <aaronjen...@gmail.com>
Date:   Mon Feb 18 17:22:17 2013 -0800

    Use new method in cmd-break-pane

commit f23fd8694a7bad50f862a787bee48333c9c0a59c
Author: Aaron Jensen <aaronjen...@gmail.com>
Date:   Mon Feb 18 16:28:24 2013 -0800

    Refactor to shared focus_notify

commit 4664d34909803029ab89a297d69053101901d784
Author: Aaron Jensen <aaronjen...@gmail.com>
Date:   Mon Feb 18 15:51:51 2013 -0800

    Fix so closing windows works

commit af7f3e33f1353c9bd76605dba57e721cec021b23
Author: Aaron Jensen <aaronjen...@gmail.com>
Date:   Mon Feb 18 15:36:12 2013 -0800

    Add support for focus notify on window switch

commit b31c18b67469fd2b467b8f3f5d7c7bc26bd5cd0d
Author: Aaron Jensen <aaronjen...@gmail.com>
Date:   Mon Feb 18 14:18:03 2013 -0800

    Refactor to use session_set_current_winlink

commit fbc70a1f98c5dd3155adc548182ba156cb70a4e2
Author: a <g...@kracun.com>
Date:   Fri Feb 1 19:02:37 2013 -0800

    missed conditional check for sending event

commit f7c120f2b460fb850c8f6dea269c884a6a5771ad
Author: a <g...@kracun.com>
Date:   Sat Jan 26 19:28:00 2013 -0800

    added focus filtering

commit ba88d768666223af9ae2b9d501890e13e2403ed9
Author: a <g...@kracun.com>
Date:   Sat Jan 19 11:29:16 2013 -0800

    Added support for Focus Event notification
---
 cmd-break-pane.c | 15 +++++++++++++++
 input-keys.c     |  2 ++
 input.c          |  6 ++++++
 session.c        | 43 ++++++++++++++++++++-----------------------
 tmux.h           |  6 ++++++
 tty-keys.c       |  2 ++
 window.c         | 13 ++++++++++++-
 7 files changed, 63 insertions(+), 24 deletions(-)

diff --git a/cmd-break-pane.c b/cmd-break-pane.c
index 637105a..547e228 100644
--- a/cmd-break-pane.c
+++ b/cmd-break-pane.c
@@ -45,6 +45,8 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
  struct winlink *wl;
  struct session *s;
  struct window_pane *wp;
+ struct window_pane *focus_out_wp;
+ struct window_pane *focus_in_wp;
  struct window *w;
  char *name;
  char *cause;
@@ -64,6 +66,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
 
  w = wl->window;
  TAILQ_REMOVE(&w->panes, wp, entry);
+ focus_out_wp = w->active;
  if (wp == w->active) {
  w->active = w->last;
  w->last = NULL;
@@ -74,6 +77,13 @@ 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'))
+ focus_in_wp = w->active;
+ else
+ focus_in_wp = wp;
+
+
  layout_close_pane(wp);
 
  w = wp->window = window_create1(s->sx, s->sy);
@@ -89,6 +99,11 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
  if (!args_has(self->args, 'd'))
  session_select(s, wl->idx);
 
+ if (focus_out_wp != focus_in_wp) {
+ window_pane_focus_notify(focus_out_wp, 0);
+ window_pane_focus_notify(focus_in_wp, 1);
+ }
+
  server_redraw_session(s);
  server_status_session_group(s);
 
diff --git a/input-keys.c b/input-keys.c
index d57926a..0b73301 100644
--- a/input-keys.c
+++ b/input-keys.c
@@ -130,6 +130,8 @@ const struct input_key_ent input_keys[] = {
  { KEYC_KP_ENTER, "\n", 0 },
  { KEYC_KP_ZERO, "0", 0 },
  { KEYC_KP_PERIOD, ".", 0 },
+ { KEYC_FOCUS_IN, "\033[I", 0 },
+ { KEYC_FOCUS_OUT, "\033[O", 0 },
 };
 
 /* Translate a key code into an output key sequence. */
diff --git a/input.c b/input.c
index 4cf90ec..c2c3f0a 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:
+ wp->flags &= ~PANE_TRACK_FOCUS;
+ break;
  case 1005:
  screen_write_mode_clear(&ictx->ctx, MODE_MOUSE_UTF8);
  break;
@@ -1326,6 +1329,9 @@ 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:
+ wp->flags |= PANE_TRACK_FOCUS;
+ break;
  case 1005:
  screen_write_mode_set(&ictx->ctx, MODE_MOUSE_UTF8);
  break;
diff --git a/session.c b/session.c
index 1f4fb30..2647453 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 f5691e9..9150e57 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. */
@@ -926,6 +929,7 @@ struct window_pane {
  int flags;
 #define PANE_REDRAW 0x1
 #define PANE_DROP 0x2
+#define PANE_TRACK_FOCUS 0x4
 
  char *cmd;
  char *shell;
@@ -2131,6 +2135,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_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 *);
@@ -2275,6 +2280,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 00327bb..87109c6 100644
--- a/tty-keys.c
+++ b/tty-keys.c
@@ -174,6 +174,8 @@ const struct tty_default_key_raw tty_default_raw_keys[] = {
  { "\033[8@", KEYC_END|KEYC_CTRL|KEYC_SHIFT },
  { "\033[6@", KEYC_NPAGE|KEYC_CTRL|KEYC_SHIFT },
  { "\033[5@", KEYC_PPAGE|KEYC_CTRL|KEYC_SHIFT },
+ { "\033[I", KEYC_FOCUS_IN },
+ { "\033[O", KEYC_FOCUS_OUT },
 };
 
 /* Default terminfo(5) keys. */
diff --git a/window.c b/window.c
index 77f06f8..74040c2 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_notify(w->last, 0);
+ window_pane_focus_notify(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_notify(w->active, 1);
 }
 
 struct window_pane *
@@ -950,6 +954,13 @@ window_pane_alternate_off(struct window_pane *wp, struct 
grid_cell *gc,
  wp->flags |= PANE_REDRAW;
 }
 
+void
+window_pane_focus_notify(struct window_pane *wp, int focused)
+{
+ if (wp != NULL && wp->event != NULL && wp->flags & PANE_TRACK_FOCUS)
+ 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

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_feb
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to