No problem.

On 5/3/17, Nicholas Marriott <[email protected]> wrote:
> Can you send me everything together please?
>
>
> On Wed, May 03, 2017 at 01:14:09AM -0500, Joshua Brot wrote:
>> I've now implemented the client-session-changed control mode hook per
>> our discussion. Furthermore, I discovered that client-session-changed
>> was not being sent during the switch client command which explains why
>> it was not firing enough earlier. My patch corrects this behavior. I
>> then proceeded to grep the entire source for "session = " and can say
>> with relative confidence that at every other place where the session
>> gets changed, the client-session-changed notification is properly
>> sent.
>>
>> I've attached a separate patch from last time. Let me know if you'd
>> prefer to have one patch with both changes. Also let me know if
>> there's anything else that needs changing in the patch. All together,
>> with these two patches I'm very satisfied with the data provided by
>> control mode and I believe I should be able to complete my project as
>> planned. :)
>>
>> Thanks,
>> Joshua
>>
>> On 5/2/17, Nicholas Marriott <[email protected]> wrote:
>> > I think all sessions windows panes is OK, at the moment only input is
>> > filtered by the control client's session (because it is high volume).
>> >
>> > pane-mode-changed it would be nice if it showed the mode but TBH it is
>> > probably not worth the trouble if doing ls/lsp/whatever is fine (can
>> > add
>> > a format to show the name of the mode if needed).
>> >
>> > For client-session-changed I suggest splitting it into
>> > %%session-changed
>> > (for this client's session like now) and %%client-session-changed (for
>> > another client's session). You'll need to loop over all clients and
>> > choose which one to use, like it does for window-renamed etc.
>> >
>> >
>> >
>> >
>> > On Tue, May 02, 2017 at 08:37:16PM -0500, Joshua Brot wrote:
>> >> Thanks for the pointers. Based off of what you said, I've created a
>> >> patch which implements the features I mentioned. Two things I'm not
>> >> sure about: 1) it seems like the control mode client will receive
>> >> these notifications for all sessions/windows/panes, as opposed to
>> >> notifications for the current session only. Should I revise the patch
>> >> to add in filtes for this? 2) For the pane-mode-changed notification,
>> >> it looks like I only get the pane-id which means the notification
>> >> doesn't report much and I'll probably have to perform a list-panes
>> >> query in response to get more information. Neither of these issues
>> >> seem very problematic, though, so perhaps its best to just leave the
>> >> patch as it is.
>> >>
>> >> With regards to the client_session_changed callback, what I'd like is
>> >> to have a notification for when any client changes sessions (not just
>> >> the one running Control Mode). I thought that client_session_changed
>> >> was called every time a client changed sessions, but in testing this
>> >> appears not to be the case (I'm not even quite sure when it does get
>> >> called). Should this be a new control mode notification like the ones
>> >> I just implemented, or should this be handled in a different way?
>> >>
>> >> Thanks,
>> >> Joshua
>> >>
>> >> On 5/2/17, Nicholas Marriott <[email protected]> wrote:
>> >> > Hi
>> >> >
>> >> > What have you got so far?
>> >> >
>> >> > Control mode should already get updated for client-session-changed,
>> >> > if
>> >> > you look at notify.c:notify_callback there is already a check that
>> >> > passes it into control_notify_client_session_changed.
>> >> >
>> >> > For new ones you will need to add a notify_add call somewhere and
>> >> > then
>> >> > add a control-notify.c function and a check in notify_callback, for
>> >> > active pane it'll probably need a notify_add call in
>> >> > window.c:window_set_active_pane.
>> >> >
>> >> > Mode changes you can do in window_pane_set_mode and
>> >> > window_pane_reset_mode.
>> >> >
>> >> >
>> >> > On Tue, May 02, 2017 at 02:27:57AM -0500, Joshua Brot wrote:
>> >> >> Hi!
>> >> >>
>> >> >> I???m currently in the process of writing a Wayland Compositor with
>> >> >> the
>> >> >> goal of using tmux as a tiling window manager. Basically, the
>> >> >> compositor
>> >> >> provides an interface similar to the TTY with tmux running. When
>> >> >> the
>> >> >> user
>> >> >> launches a visual application, the compositor will then overlay it
>> >> >> on
>> >> >> the
>> >> >> pane from which it was launched. My current strategy for
>> >> >> implementing
>> >> >> this
>> >> >> is to launch an internal tmux client in control mode to every
>> >> >> session
>> >> >> on
>> >> >> the server in order to track what actions the client is taking and
>> >> >> respond
>> >> >> accordingly.
>> >> >>
>> >> >> In its current state, tmux???s control mode looks like it provides
>> >> >> almost
>> >> >> enough capabilities to make this project work. The biggest thing it
>> >> >> is
>> >> >> missing are notifications for when the user switches active panes
>> >> >> within a
>> >> >> window and when the user switches active windows in a session. It
>> >> >> would
>> >> >> also be nice to have a notification for when the user switches into
>> >> >> and
>> >> >> out of copy mode, but this isn???t essential. Finally, it would be
>> >> >> nice
>> >> >> to
>> >> >> get notifications on the ???client-session-changed??? hook, but
>> >> >> since
>> >> >> there is a hook already I can very easily work around this.
>> >> >>
>> >> >> I have begun to look through tmux???s source in order to implement
>> >> >> these
>> >> >> features myself, but I haven???t made much progress yet as the
>> >> >> project
>> >> >> is
>> >> >> quite large and I???m not familiar enough with all of the use cases
>> >> >> needed
>> >> >>  to make these notifications always work. Any advice on how to
>> >> >> implement
>> >> >> these features would be much appreciated (or if someone is willing
>> >> >> to
>> >> >> implement the features themself, that would be great too :).
>> >> >> Finally,
>> >> >> any
>> >> >> feedback on my general strategy would be appreciated as I???m not
>> >> >> entirely
>> >> >> sure if I???m going about this in a reasonable way.
>> >> >>
>> >> >> Thanks!
>> >> >> ???Joshua Brot
>> >> >>
>> >> >> --
>> >> >> You received this message because you are subscribed to the Google
>> >> >> Groups
>> >> >> "tmux-users" group.
>> >> >> To unsubscribe from this group and stop receiving emails from it,
>> >> >> send
>> >> >> an
>> >> >> email to [email protected].
>> >> >> To post to this group, send an email to
>> >> >> [email protected].
>> >> >> For more options, visit https://groups.google.com/d/optout.
>> >> >
>> >
>> >> From c830ea1e227b73888f51961eb7517deac2f93981 Mon Sep 17 00:00:00 2001
>> >> From: Joshua Brot <[email protected]>
>> >> Date: Tue, 2 May 2017 20:12:16 -0500
>> >> Subject: [PATCH] Added several features to command mode.
>> >>
>> >> Signed-off-by: Joshua Brot <[email protected]>
>> >> ---
>> >>  control-notify.c | 41 +++++++++++++++++++++++++++++++++++++++++
>> >>  notify.c         |  6 ++++++
>> >>  session.c        |  1 +
>> >>  tmux.1           | 14 ++++++++++++++
>> >>  tmux.h           |  3 +++
>> >>  window.c         | 13 +++++++++++--
>> >>  6 files changed, 76 insertions(+), 2 deletions(-)
>> >>
>> >> diff --git a/control-notify.c b/control-notify.c
>> >> index 230bce61..056e1992 100644
>> >> --- a/control-notify.c
>> >> +++ b/control-notify.c
>> >> @@ -60,6 +60,19 @@ control_notify_input(struct client *c, struct
>> >> window_pane *wp,
>> >>  }
>> >>
>> >>  void
>> >> +control_notify_pane_mode_changed(int pane)
>> >> +{
>> >> + struct client   *c;
>> >> +
>> >> + TAILQ_FOREACH(c, &clients, entry) {
>> >> +         if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
>> >> +                 continue;
>> >> +
>> >> +         control_write(c, "%%pane-mode-changed %%%u", pane);
>> >> + }
>> >> +}
>> >> +
>> >> +void
>> >>  control_notify_window_layout_changed(struct window *w)
>> >>  {
>> >>   struct client           *c;
>> >> @@ -97,6 +110,20 @@ control_notify_window_layout_changed(struct window
>> >> *w)
>> >>  }
>> >>
>> >>  void
>> >> +control_notify_window_pane_changed(struct window *w)
>> >> +{
>> >> + struct client   *c;
>> >> +
>> >> + TAILQ_FOREACH(c, &clients, entry) {
>> >> +         if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
>> >> +                 continue;
>> >> +
>> >> +         control_write(c, "%%window-pane-changed @%u %%%u",
>> >> +                       w->id, w->active->id);
>> >> + }
>> >> +}
>> >> +
>> >> +void
>> >>  control_notify_window_unlinked(__unused struct session *s, struct
>> >> window
>> >> *w)
>> >>  {
>> >>   struct client   *c;
>> >> @@ -203,3 +230,17 @@ control_notify_session_closed(__unused struct
>> >> session
>> >> *s)
>> >>           control_write(c, "%%sessions-changed");
>> >>   }
>> >>  }
>> >> +
>> >> +void
>> >> +control_notify_session_window_changed(struct session *s)
>> >> +{
>> >> + struct client   *c;
>> >> +
>> >> + TAILQ_FOREACH(c, &clients, entry) {
>> >> +         if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
>> >> +                 continue;
>> >> +
>> >> +         control_write(c, "%%session-window-changed $%u @%u",
>> >> +                       s->id, s->curw->window->id);
>> >> + }
>> >> +}
>> >> diff --git a/notify.c b/notify.c
>> >> index 0241fa60..31284127 100644
>> >> --- a/notify.c
>> >> +++ b/notify.c
>> >> @@ -78,8 +78,12 @@ notify_callback(struct cmdq_item *item, void *data)
>> >>
>> >>   log_debug("%s: %s", __func__, ne->name);
>> >>
>> >> + if (strcmp(ne->name, "pane-mode-changed") == 0)
>> >> +         control_notify_pane_mode_changed(ne->pane);
>> >>   if (strcmp(ne->name, "window-layout-changed") == 0)
>> >>           control_notify_window_layout_changed(ne->window);
>> >> + if (strcmp(ne->name, "window-pane-changed") == 0)
>> >> +         control_notify_window_pane_changed(ne->window);
>> >>   if (strcmp(ne->name, "window-unlinked") == 0)
>> >>           control_notify_window_unlinked(ne->session, ne->window);
>> >>   if (strcmp(ne->name, "window-linked") == 0)
>> >> @@ -94,6 +98,8 @@ notify_callback(struct cmdq_item *item, void *data)
>> >>           control_notify_session_created(ne->session);
>> >>   if (strcmp(ne->name, "session-closed") == 0)
>> >>           control_notify_session_closed(ne->session);
>> >> + if (strcmp(ne->name, "session-window-changed") == 0)
>> >> +         control_notify_session_window_changed(ne->session);
>> >>
>> >>   notify_hook(item, ne);
>> >>
>> >> diff --git a/session.c b/session.c
>> >> index b52b0274..b9f30428 100644
>> >> --- a/session.c
>> >> +++ b/session.c
>> >> @@ -552,6 +552,7 @@ session_set_current(struct session *s, struct
>> >> winlink
>> >> *wl)
>> >>   s->curw = wl;
>> >>   winlink_clear_flags(wl);
>> >>   window_update_activity(wl->window);
>> >> + notify_session("session-window-changed", s);
>> >>   return (0);
>> >>  }
>> >>
>> >> diff --git a/tmux.1 b/tmux.1
>> >> index cb069e5e..12bd3509 100644
>> >> --- a/tmux.1
>> >> +++ b/tmux.1
>> >> @@ -4258,6 +4258,10 @@ and the window flags are
>> >>  A window pane produced output.
>> >>  .Ar value
>> >>  escapes non-printable characters and backslash as octal \\xxx.
>> >> +.It Ic %pane-mode-changed Ar pane-id
>> >> +The pane with ID
>> >> +.Ar pane-id
>> >> +has changed mode.
>> >>  .It Ic %session-changed Ar session-id Ar name
>> >>  The client is now attached to the session with ID
>> >>  .Ar session-id ,
>> >> @@ -4266,6 +4270,11 @@ which is named
>> >>  .It Ic %session-renamed Ar name
>> >>  The current session was renamed to
>> >>  .Ar name .
>> >> +.It Ic %session-window-changed Ar session-id Ar window-id
>> >> +The session with ID
>> >> +.Ar session-id
>> >> +changed its active window to the window with ID
>> >> +.Ar window-id .
>> >>  .It Ic %sessions-changed
>> >>  A session was created or destroyed.
>> >>  .It Ic %unlinked-window-add Ar window-id
>> >> @@ -4280,6 +4289,11 @@ was linked to the current session.
>> >>  The window with ID
>> >>  .Ar window-id
>> >>  closed.
>> >> +.It Ic %window-pane-changed Ar window-id Ar pane-id
>> >> +The active pane in the window with ID
>> >> +.Ar window-id
>> >> +changed to the pane with ID
>> >> +.Ar pane-id .
>> >>  .It Ic %window-renamed Ar window-id Ar name
>> >>  The window with ID
>> >>  .Ar window-id
>> >> diff --git a/tmux.h b/tmux.h
>> >> index 417145f1..1139d6ba 100644
>> >> --- a/tmux.h
>> >> +++ b/tmux.h
>> >> @@ -2211,7 +2211,9 @@ void        control_write_buffer(struct client *,
>> >> struct
>> >> evbuffer *);
>> >>  /* control-notify.c */
>> >>  void     control_notify_input(struct client *, struct window_pane *,
>> >>       struct evbuffer *);
>> >> +void     control_notify_pane_mode_changed(int pane);
>> >>  void     control_notify_window_layout_changed(struct window *);
>> >> +void     control_notify_window_pane_changed(struct window *);
>> >>  void     control_notify_window_unlinked(struct session *, struct window
>> >> *);
>> >>  void     control_notify_window_linked(struct session *, struct window *);
>> >>  void     control_notify_window_renamed(struct window *);
>> >> @@ -2219,6 +2221,7 @@
>> >> void      control_notify_client_session_changed(struct
>> >> client *);
>> >>  void     control_notify_session_renamed(struct session *);
>> >>  void     control_notify_session_created(struct session *);
>> >>  void     control_notify_session_closed(struct session *);
>> >> +void     control_notify_session_window_changed(struct session *s);
>> >>
>> >>  /* session.c */
>> >>  extern struct sessions sessions;
>> >> diff --git a/window.c b/window.c
>> >> index ed73050e..92742685 100644
>> >> --- a/window.c
>> >> +++ b/window.c
>> >> @@ -355,6 +355,8 @@ window_create_spawn(const char *name, int argc,
>> >> char
>> >> **argv, const char *path,
>> >>   } else
>> >>           w->name = default_window_name(w);
>> >>
>> >> + notify_window("window-pane-changed", w);
>> >> +
>> >>   return (w);
>> >>  }
>> >>
>> >> @@ -441,11 +443,14 @@ window_set_active_pane(struct window *w, struct
>> >> window_pane *wp)
>> >>           w->active = TAILQ_PREV(w->active, window_panes, entry);
>> >>           if (w->active == NULL)
>> >>                   w->active = TAILQ_LAST(&w->panes, window_panes);
>> >> -         if (w->active == wp)
>> >> +         if (w->active == wp) {
>> >> +                 notify_window("window-pane-changed", w);
>> >>                   return (1);
>> >> +         }
>> >>   }
>> >>   w->active->active_point = next_active_point++;
>> >>   w->active->flags |= PANE_CHANGED;
>> >> + notify_window("window-pane-changed", w);
>> >>   return (1);
>> >>  }
>> >>
>> >> @@ -621,8 +626,10 @@ window_lost_pane(struct window *w, struct
>> >> window_pane
>> >> *wp)
>> >>                   if (w->active == NULL)
>> >>                           w->active = TAILQ_NEXT(wp, entry);
>> >>           }
>> >> -         if (w->active != NULL)
>> >> +         if (w->active != NULL) {
>> >>                   w->active->flags |= PANE_CHANGED;
>> >> +                 notify_window("window-pane-changed", w);
>> >> +         }
>> >>   } else if (wp == w->last)
>> >>           w->last = NULL;
>> >>  }
>> >> @@ -1196,6 +1203,7 @@ window_pane_set_mode(struct window_pane *wp,
>> >> const
>> >> struct window_mode *mode)
>> >>   wp->flags |= (PANE_REDRAW|PANE_CHANGED);
>> >>
>> >>   server_status_window(wp->window);
>> >> + notify_pane("pane-mode-changed", wp);
>> >>   return (0);
>> >>  }
>> >>
>> >> @@ -1215,6 +1223,7 @@ window_pane_reset_mode(struct window_pane *wp)
>> >>   wp->flags |= (PANE_REDRAW|PANE_CHANGED);
>> >>
>> >>   server_status_window(wp->window);
>> >> + notify_pane("pane-mode-changed", wp);
>> >>  }
>> >>
>> >>  void
>> >> --
>> >> 2.12.2
>> >>
>> >
>> >
>
>> From 4584ea34afd15a75d2480173d2bdceab1bc2df0a Mon Sep 17 00:00:00 2001
>> From: Joshua Brot <[email protected]>
>> Date: Wed, 3 May 2017 01:03:56 -0500
>> Subject: [PATCH] Added missing call to client-session-change and expanded
>>  Control Mode notification.
>>
>> Signed-off-by: Joshua Brot <[email protected]>
>> ---
>>  cmd-switch-client.c |  1 +
>>  control-notify.c    | 19 +++++++++++++++----
>>  tmux.1              |  7 +++++++
>>  3 files changed, 23 insertions(+), 4 deletions(-)
>>
>> diff --git a/cmd-switch-client.c b/cmd-switch-client.c
>> index 2bc1e10c..a24f0276 100644
>> --- a/cmd-switch-client.c
>> +++ b/cmd-switch-client.c
>> @@ -129,6 +129,7 @@ cmd_switch_client_exec(struct cmd *self, struct
>> cmdq_item *item)
>>      if (~item->shared->flags & CMDQ_SHARED_REPEAT)
>>              server_client_set_key_table(c, NULL);
>>      status_timer_start(c);
>> +    notify_client("client-session-changed", c);
>>      session_update_activity(s, NULL);
>>      gettimeofday(&s->last_attached_time, NULL);
>>
>> diff --git a/control-notify.c b/control-notify.c
>> index 056e1992..af431892 100644
>> --- a/control-notify.c
>> +++ b/control-notify.c
>> @@ -181,15 +181,26 @@ control_notify_window_renamed(struct window *w)
>>  }
>>
>>  void
>> -control_notify_client_session_changed(struct client *c)
>> +control_notify_client_session_changed(struct client *cc)
>>  {
>> +    struct client *c;
>>      struct session  *s;
>>
>> -    if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
>> +    if (cc->session == NULL)
>>              return;
>> -    s = c->session;
>> +    s = cc->session;
>>
>> -    control_write(c, "%%session-changed $%u %s", s->id, s->name);
>> +    TAILQ_FOREACH(c, &clients, entry) {
>> +            if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
>> +                    continue;
>> +
>> +            if (cc == c) {
>> +                    control_write(c, "%%session-changed $%u %s", s->id, 
>> s->name);
>> +            } else {
>> +                    control_write(c, "%%client-session-changed %u $%u %s",
>> +                                  cc->pid, s->id, s->name);
>> +            }
>> +    }
>>  }
>>
>>  void
>> diff --git a/tmux.1 b/tmux.1
>> index 12bd3509..9b8215e5 100644
>> --- a/tmux.1
>> +++ b/tmux.1
>> @@ -4236,6 +4236,13 @@ A notification will never occur inside an output
>> block.
>>  .Pp
>>  The following notifications are defined:
>>  .Bl -tag -width Ds
>> +.It Ic %client-session-changed Ar client-pid Ar session-id Ar name
>> +The client with pid
>> +.Ar client-pid
>> +is now attached to the session with ID
>> +.Ar session-id ,
>> +which is named
>> +.Ar name .
>>  .It Ic %exit Op Ar reason
>>  The
>>  .Nm
>> --
>> 2.12.2
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"tmux-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
From 3e8c7bdcadb03e0cf90edfd80a27f6db1fd83cd8 Mon Sep 17 00:00:00 2001
From: Pamelloes <[email protected]>
Date: Wed, 3 May 2017 02:18:14 -0500
Subject: [PATCH] Added several features to control mode. Also added missing
 call to client-session-change.

Signed-off-by: Joshua Brot <[email protected]>
---
 cmd-switch-client.c |  1 +
 control-notify.c    | 60 +++++++++++++++++++++++++++++++++++++++++++++++++----
 notify.c            |  6 ++++++
 session.c           |  1 +
 tmux.1              | 21 +++++++++++++++++++
 tmux.h              |  3 +++
 window.c            | 13 ++++++++++--
 7 files changed, 99 insertions(+), 6 deletions(-)

diff --git a/cmd-switch-client.c b/cmd-switch-client.c
index 2bc1e10c..a24f0276 100644
--- a/cmd-switch-client.c
+++ b/cmd-switch-client.c
@@ -129,6 +129,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
 	if (~item->shared->flags & CMDQ_SHARED_REPEAT)
 		server_client_set_key_table(c, NULL);
 	status_timer_start(c);
+	notify_client("client-session-changed", c);
 	session_update_activity(s, NULL);
 	gettimeofday(&s->last_attached_time, NULL);
 
diff --git a/control-notify.c b/control-notify.c
index 230bce61..af431892 100644
--- a/control-notify.c
+++ b/control-notify.c
@@ -60,6 +60,19 @@ control_notify_input(struct client *c, struct window_pane *wp,
 }
 
 void
+control_notify_pane_mode_changed(int pane)
+{
+	struct client	*c;
+
+	TAILQ_FOREACH(c, &clients, entry) {
+		if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
+			continue;
+
+		control_write(c, "%%pane-mode-changed %%%u", pane);
+	}
+}
+
+void
 control_notify_window_layout_changed(struct window *w)
 {
 	struct client		*c;
@@ -97,6 +110,20 @@ control_notify_window_layout_changed(struct window *w)
 }
 
 void
+control_notify_window_pane_changed(struct window *w)
+{
+	struct client	*c;
+
+	TAILQ_FOREACH(c, &clients, entry) {
+		if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
+			continue;
+
+		control_write(c, "%%window-pane-changed @%u %%%u", 
+		              w->id, w->active->id);
+	}
+}
+
+void
 control_notify_window_unlinked(__unused struct session *s, struct window *w)
 {
 	struct client	*c;
@@ -154,15 +181,26 @@ control_notify_window_renamed(struct window *w)
 }
 
 void
-control_notify_client_session_changed(struct client *c)
+control_notify_client_session_changed(struct client *cc)
 {
+	struct client *c;
 	struct session	*s;
 
-	if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
+	if (cc->session == NULL)
 		return;
-	s = c->session;
+	s = cc->session;
+
+	TAILQ_FOREACH(c, &clients, entry) {
+		if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
+			continue;
 
-	control_write(c, "%%session-changed $%u %s", s->id, s->name);
+		if (cc == c) {
+			control_write(c, "%%session-changed $%u %s", s->id, s->name);
+		} else {
+			control_write(c, "%%client-session-changed %u $%u %s",
+			              cc->pid, s->id, s->name);
+		}
+	}
 }
 
 void
@@ -203,3 +241,17 @@ control_notify_session_closed(__unused struct session *s)
 		control_write(c, "%%sessions-changed");
 	}
 }
+
+void
+control_notify_session_window_changed(struct session *s)
+{
+	struct client	*c;
+
+	TAILQ_FOREACH(c, &clients, entry) {
+		if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
+			continue;
+
+		control_write(c, "%%session-window-changed $%u @%u", 
+		              s->id, s->curw->window->id);
+	}
+}
diff --git a/notify.c b/notify.c
index 0241fa60..31284127 100644
--- a/notify.c
+++ b/notify.c
@@ -78,8 +78,12 @@ notify_callback(struct cmdq_item *item, void *data)
 
 	log_debug("%s: %s", __func__, ne->name);
 
+	if (strcmp(ne->name, "pane-mode-changed") == 0)
+		control_notify_pane_mode_changed(ne->pane);
 	if (strcmp(ne->name, "window-layout-changed") == 0)
 		control_notify_window_layout_changed(ne->window);
+	if (strcmp(ne->name, "window-pane-changed") == 0)
+		control_notify_window_pane_changed(ne->window);
 	if (strcmp(ne->name, "window-unlinked") == 0)
 		control_notify_window_unlinked(ne->session, ne->window);
 	if (strcmp(ne->name, "window-linked") == 0)
@@ -94,6 +98,8 @@ notify_callback(struct cmdq_item *item, void *data)
 		control_notify_session_created(ne->session);
 	if (strcmp(ne->name, "session-closed") == 0)
 		control_notify_session_closed(ne->session);
+	if (strcmp(ne->name, "session-window-changed") == 0)
+		control_notify_session_window_changed(ne->session);
 
 	notify_hook(item, ne);
 
diff --git a/session.c b/session.c
index b52b0274..b9f30428 100644
--- a/session.c
+++ b/session.c
@@ -552,6 +552,7 @@ session_set_current(struct session *s, struct winlink *wl)
 	s->curw = wl;
 	winlink_clear_flags(wl);
 	window_update_activity(wl->window);
+	notify_session("session-window-changed", s);
 	return (0);
 }
 
diff --git a/tmux.1 b/tmux.1
index cb069e5e..9b8215e5 100644
--- a/tmux.1
+++ b/tmux.1
@@ -4236,6 +4236,13 @@ A notification will never occur inside an output block.
 .Pp
 The following notifications are defined:
 .Bl -tag -width Ds
+.It Ic %client-session-changed Ar client-pid Ar session-id Ar name
+The client with pid
+.Ar client-pid
+is now attached to the session with ID
+.Ar session-id ,
+which is named
+.Ar name .
 .It Ic %exit Op Ar reason
 The
 .Nm
@@ -4258,6 +4265,10 @@ and the window flags are
 A window pane produced output.
 .Ar value
 escapes non-printable characters and backslash as octal \\xxx.
+.It Ic %pane-mode-changed Ar pane-id
+The pane with ID
+.Ar pane-id
+has changed mode.
 .It Ic %session-changed Ar session-id Ar name
 The client is now attached to the session with ID
 .Ar session-id ,
@@ -4266,6 +4277,11 @@ which is named
 .It Ic %session-renamed Ar name
 The current session was renamed to
 .Ar name .
+.It Ic %session-window-changed Ar session-id Ar window-id
+The session with ID
+.Ar session-id
+changed its active window to the window with ID
+.Ar window-id .
 .It Ic %sessions-changed
 A session was created or destroyed.
 .It Ic %unlinked-window-add Ar window-id
@@ -4280,6 +4296,11 @@ was linked to the current session.
 The window with ID
 .Ar window-id
 closed.
+.It Ic %window-pane-changed Ar window-id Ar pane-id
+The active pane in the window with ID
+.Ar window-id
+changed to the pane with ID
+.Ar pane-id .
 .It Ic %window-renamed Ar window-id Ar name
 The window with ID
 .Ar window-id
diff --git a/tmux.h b/tmux.h
index 417145f1..1139d6ba 100644
--- a/tmux.h
+++ b/tmux.h
@@ -2211,7 +2211,9 @@ void	control_write_buffer(struct client *, struct evbuffer *);
 /* control-notify.c */
 void	control_notify_input(struct client *, struct window_pane *,
 	    struct evbuffer *);
+void	control_notify_pane_mode_changed(int pane);
 void	control_notify_window_layout_changed(struct window *);
+void	control_notify_window_pane_changed(struct window *);
 void	control_notify_window_unlinked(struct session *, struct window *);
 void	control_notify_window_linked(struct session *, struct window *);
 void	control_notify_window_renamed(struct window *);
@@ -2219,6 +2221,7 @@ void	control_notify_client_session_changed(struct client *);
 void	control_notify_session_renamed(struct session *);
 void	control_notify_session_created(struct session *);
 void	control_notify_session_closed(struct session *);
+void	control_notify_session_window_changed(struct session *s);
 
 /* session.c */
 extern struct sessions sessions;
diff --git a/window.c b/window.c
index ed73050e..92742685 100644
--- a/window.c
+++ b/window.c
@@ -355,6 +355,8 @@ window_create_spawn(const char *name, int argc, char **argv, const char *path,
 	} else
 		w->name = default_window_name(w);
 
+	notify_window("window-pane-changed", w);
+
 	return (w);
 }
 
@@ -441,11 +443,14 @@ window_set_active_pane(struct window *w, struct window_pane *wp)
 		w->active = TAILQ_PREV(w->active, window_panes, entry);
 		if (w->active == NULL)
 			w->active = TAILQ_LAST(&w->panes, window_panes);
-		if (w->active == wp)
+		if (w->active == wp) {
+			notify_window("window-pane-changed", w);
 			return (1);
+		}
 	}
 	w->active->active_point = next_active_point++;
 	w->active->flags |= PANE_CHANGED;
+	notify_window("window-pane-changed", w);
 	return (1);
 }
 
@@ -621,8 +626,10 @@ window_lost_pane(struct window *w, struct window_pane *wp)
 			if (w->active == NULL)
 				w->active = TAILQ_NEXT(wp, entry);
 		}
-		if (w->active != NULL)
+		if (w->active != NULL) {
 			w->active->flags |= PANE_CHANGED;
+			notify_window("window-pane-changed", w);
+		}
 	} else if (wp == w->last)
 		w->last = NULL;
 }
@@ -1196,6 +1203,7 @@ window_pane_set_mode(struct window_pane *wp, const struct window_mode *mode)
 	wp->flags |= (PANE_REDRAW|PANE_CHANGED);
 
 	server_status_window(wp->window);
+	notify_pane("pane-mode-changed", wp);
 	return (0);
 }
 
@@ -1215,6 +1223,7 @@ window_pane_reset_mode(struct window_pane *wp)
 	wp->flags |= (PANE_REDRAW|PANE_CHANGED);
 
 	server_status_window(wp->window);
+	notify_pane("pane-mode-changed", wp);
 }
 
 void
-- 
2.12.2

Reply via email to