summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--options-table.c2
-rw-r--r--server-fn.c55
-rw-r--r--session.c6
-rw-r--r--tmux.115
4 files changed, 44 insertions, 34 deletions
diff --git a/options-table.c b/options-table.c
index eacf0947..a42d41c1 100644
--- a/options-table.c
+++ b/options-table.c
@@ -86,7 +86,7 @@ static const char *options_table_remain_on_exit_list[] = {
"off", "on", "failed", NULL
};
static const char *options_table_detach_on_destroy_list[] = {
- "off", "on", "no-detached", NULL
+ "off", "on", "no-detached", "previous", "next", NULL
};
static const char *options_table_extended_keys_list[] = {
"off", "on", "always", NULL
diff --git a/server-fn.c b/server-fn.c
index 2e9665f5..3c14c733 100644
--- a/server-fn.c
+++ b/server-fn.c
@@ -29,8 +29,7 @@
#include "tmux.h"
-static struct session *server_next_session(struct session *);
-static void server_destroy_session_group(struct session *);
+static void server_destroy_session_group(struct session *);
void
server_redraw_client(struct client *c)
@@ -209,8 +208,8 @@ server_kill_window(struct window *w, int renumber)
if (session_detach(s, wl)) {
server_destroy_session_group(s);
break;
- } else
- server_redraw_session_group(s);
+ }
+ server_redraw_session_group(s);
}
if (renumber)
@@ -384,9 +383,10 @@ server_destroy_session_group(struct session *s)
struct session_group *sg;
struct session *s1;
- if ((sg = session_group_contains(s)) == NULL)
+ if ((sg = session_group_contains(s)) == NULL) {
server_destroy_session(s);
- else {
+ session_destroy(s, 1, __func__);
+ } else {
TAILQ_FOREACH_SAFE(s, &sg->sessions, gentry, s1) {
server_destroy_session(s);
session_destroy(s, 1, __func__);
@@ -395,52 +395,55 @@ server_destroy_session_group(struct session *s)
}
static struct session *
-server_next_session(struct session *s)
+server_find_session(struct session *s,
+ int (*f)(struct session *, struct session *))
{
struct session *s_loop, *s_out = NULL;
RB_FOREACH(s_loop, sessions, &sessions) {
- if (s_loop == s)
- continue;
- if (s_out == NULL ||
- timercmp(&s_loop->activity_time, &s_out->activity_time, <))
+ if (s_loop != s && (s_out == NULL || f(s_loop, s_out)))
s_out = s_loop;
}
return (s_out);
}
-static struct session *
-server_next_detached_session(struct session *s)
+static int
+server_newer_session(struct session *s_loop, struct session *s_out)
{
- struct session *s_loop, *s_out = NULL;
+ return (timercmp(&s_loop->activity_time, &s_out->activity_time, <));
+}
- RB_FOREACH(s_loop, sessions, &sessions) {
- if (s_loop == s || s_loop->attached)
- continue;
- if (s_out == NULL ||
- timercmp(&s_loop->activity_time, &s_out->activity_time, <))
- s_out = s_loop;
- }
- return (s_out);
+static int
+server_newer_detached_session(struct session *s_loop, struct session *s_out)
+{
+ if (s_loop->attached)
+ return (0);
+ return (server_newer_session(s_loop, s_out));
}
void
server_destroy_session(struct session *s)
{
struct client *c;
- struct session *s_new;
+ struct session *s_new = NULL;
int detach_on_destroy;
detach_on_destroy = options_get_number(s->options, "detach-on-destroy");
if (detach_on_destroy == 0)
- s_new = server_next_session(s);
+ s_new = server_find_session(s, server_newer_session);
else if (detach_on_destroy == 2)
- s_new = server_next_detached_session(s);
- else
+ s_new = server_find_session(s, server_newer_detached_session);
+ else if (detach_on_destroy == 3)
+ s_new = session_previous_session(s);
+ else if (detach_on_destroy == 4)
+ s_new = session_next_session(s);
+ if (s_new == s)
s_new = NULL;
TAILQ_FOREACH(c, &clients, entry) {
if (c->session != s)
continue;
+ c->session = NULL;
+ c->last_session = NULL;
server_client_set_session(c, s_new);
if (s_new == NULL)
c->flags |= CLIENT_EXIT;
diff --git a/session.c b/session.c
index de3f336f..688b23f4 100644
--- a/session.c
+++ b/session.c
@@ -367,11 +367,9 @@ session_detach(struct session *s, struct winlink *wl)
session_group_synchronize_from(s);
- if (RB_EMPTY(&s->windows)) {
- session_destroy(s, 1, __func__);
+ if (RB_EMPTY(&s->windows))
return (1);
- }
- return (0);
+ return (0);
}
/* Return if session has window. */
diff --git a/tmux.1 b/tmux.1
index 3228556c..6306e12a 100644
--- a/tmux.1
+++ b/tmux.1
@@ -4039,16 +4039,25 @@ The default is 80x24.
If enabled and the session is no longer attached to any clients, it is
destroyed.
.It Xo Ic detach-on-destroy
-.Op Ic off | on | no-detached
+.Op Ic off | on | no-detached | previous | next
.Xc
-If on (the default), the client is detached when the session it is attached to
+If
+.Ic on
+(the default), the client is detached when the session it is attached to
is destroyed.
-If off, the client is switched to the most recently active of the remaining
+If
+.Ic off ,
+the client is switched to the most recently active of the remaining
sessions.
If
.Ic no-detached ,
the client is detached only if there are no detached sessions; if detached
sessions exist, the client is switched to the most recently active.
+If
+.Ic previous
+or
+.Ic next ,
+the client is switched to the previous or next session in alphabetical order.
.It Ic display-panes-active-colour Ar colour
Set the colour used by the
.Ic display-panes