blob: d2984bc1a022a1e4230d76eec525b9dd50e92319 [file] [log] [blame] [raw]
Nicholas Marriott4d9af272009-01-23 16:59:14 +00001/* $Id: session.c,v 1.52 2009-01-23 16:59:14 nicm Exp $ */
Nicholas Marriotta41ece52007-07-09 19:04:12 +00002
3/*
4 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/types.h>
Nicholas Marriott33aa9312008-08-28 17:45:30 +000020#include <sys/time.h>
Nicholas Marriotta41ece52007-07-09 19:04:12 +000021
22#include <string.h>
Nicholas Marriott73d7b702007-08-27 09:53:38 +000023#include <stdlib.h>
Nicholas Marriott3fa8f162007-09-27 09:15:58 +000024#include <unistd.h>
Nicholas Marriotta41ece52007-07-09 19:04:12 +000025
26#include "tmux.h"
27
28/* Global session list. */
Nicholas Marriott103748d2007-12-06 09:46:23 +000029struct sessions sessions;
Nicholas Marriottd1a5fde2009-01-18 18:31:45 +000030
31struct winlink *session_next_activity(struct session *, struct winlink *);
32struct winlink *session_previous_activity(struct session *, struct winlink *);
Nicholas Marriotta41ece52007-07-09 19:04:12 +000033
Nicholas Marriottad4a7422007-10-12 11:24:15 +000034void
Nicholas Marriott14b95122008-06-04 16:46:23 +000035session_alert_cancel(struct session *s, struct winlink *wl)
Nicholas Marriottad4a7422007-10-12 11:24:15 +000036{
Nicholas Marriott14b95122008-06-04 16:46:23 +000037 struct session_alert *sa, *sb;
Nicholas Marriottad4a7422007-10-12 11:24:15 +000038
Nicholas Marriott4198a9c2008-11-05 01:19:24 +000039 sa = SLIST_FIRST(&s->alerts);
Nicholas Marriott14b95122008-06-04 16:46:23 +000040 while (sa != NULL) {
41 sb = sa;
Nicholas Marriott4198a9c2008-11-05 01:19:24 +000042 sa = SLIST_NEXT(sa, entry);
Nicholas Marriott14b95122008-06-04 16:46:23 +000043
44 if (wl == NULL || sb->wl == wl) {
Nicholas Marriott4198a9c2008-11-05 01:19:24 +000045 SLIST_REMOVE(&s->alerts, sb, session_alert, entry);
Nicholas Marriott14b95122008-06-04 16:46:23 +000046 xfree(sb);
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +000047 }
48 }
Nicholas Marriottad4a7422007-10-12 11:24:15 +000049}
50
51void
Nicholas Marriott14b95122008-06-04 16:46:23 +000052session_alert_add(struct session *s, struct window *w, int type)
Nicholas Marriottad4a7422007-10-12 11:24:15 +000053{
Nicholas Marriott14b95122008-06-04 16:46:23 +000054 struct session_alert *sa;
55 struct winlink *wl;
Nicholas Marriottad4a7422007-10-12 11:24:15 +000056
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +000057 RB_FOREACH(wl, winlinks, &s->windows) {
58 if (wl == s->curw)
59 continue;
Nicholas Marriott14b95122008-06-04 16:46:23 +000060
Nicholas Marriott3cd4a082008-06-06 17:55:27 +000061 if (wl->window == w &&
62 !session_alert_has(s, wl, type)) {
Nicholas Marriott14b95122008-06-04 16:46:23 +000063 sa = xmalloc(sizeof *sa);
64 sa->wl = wl;
65 sa->type = type;
Nicholas Marriott4198a9c2008-11-05 01:19:24 +000066 SLIST_INSERT_HEAD(&s->alerts, sa, entry);
Nicholas Marriott14b95122008-06-04 16:46:23 +000067 }
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +000068 }
Nicholas Marriottad4a7422007-10-12 11:24:15 +000069}
70
71int
Nicholas Marriott14b95122008-06-04 16:46:23 +000072session_alert_has(struct session *s, struct winlink *wl, int type)
Nicholas Marriottad4a7422007-10-12 11:24:15 +000073{
Nicholas Marriott14b95122008-06-04 16:46:23 +000074 struct session_alert *sa;
Nicholas Marriottad4a7422007-10-12 11:24:15 +000075
Nicholas Marriott4198a9c2008-11-05 01:19:24 +000076 SLIST_FOREACH(sa, &s->alerts, entry) {
Nicholas Marriott14b95122008-06-04 16:46:23 +000077 if (sa->wl == wl && sa->type == type)
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +000078 return (1);
79 }
Nicholas Marriott14b95122008-06-04 16:46:23 +000080
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +000081 return (0);
Nicholas Marriottad4a7422007-10-12 11:24:15 +000082}
83
Nicholas Marriott3cd4a082008-06-06 17:55:27 +000084int
85session_alert_has_window(struct session *s, struct window *w, int type)
86{
87 struct session_alert *sa;
88
Nicholas Marriott4198a9c2008-11-05 01:19:24 +000089 SLIST_FOREACH(sa, &s->alerts, entry) {
Nicholas Marriott3cd4a082008-06-06 17:55:27 +000090 if (sa->wl->window == w && sa->type == type)
91 return (1);
92 }
93
94 return (0);
95}
96
Nicholas Marriotta41ece52007-07-09 19:04:12 +000097/* Find session by name. */
98struct session *
99session_find(const char *name)
100{
101 struct session *s;
102 u_int i;
103
104 for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
105 s = ARRAY_ITEM(&sessions, i);
106 if (s != NULL && strcmp(s->name, name) == 0)
107 return (s);
108 }
Nicholas Marriott103748d2007-12-06 09:46:23 +0000109
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000110 return (NULL);
111}
112
113/* Create a new session. */
114struct session *
Nicholas Marriott4d9af272009-01-23 16:59:14 +0000115session_create(const char *name,
116 const char *cmd, const char *cwd, u_int sx, u_int sy, char **cause)
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000117{
118 struct session *s;
119 u_int i;
120
121 s = xmalloc(sizeof *s);
Nicholas Marriottfd05d072009-01-10 14:43:43 +0000122 s->flags = 0;
Nicholas Marriott33aa9312008-08-28 17:45:30 +0000123 if (gettimeofday(&s->tv, NULL) != 0)
124 fatal("gettimeofday");
Nicholas Marriott46f5e422008-11-16 10:10:26 +0000125 s->curw = NULL;
126 SLIST_INIT(&s->lastw);
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000127 RB_INIT(&s->windows);
Nicholas Marriott4198a9c2008-11-05 01:19:24 +0000128 SLIST_INIT(&s->alerts);
Nicholas Marriott9798dcd2008-06-20 08:36:20 +0000129 paste_init_stack(&s->buffers);
Nicholas Marriott9e6090a2008-06-03 21:42:37 +0000130 options_init(&s->options, &global_options);
Nicholas Marriott99df48d2008-06-18 22:21:51 +0000131
Nicholas Marriott7ba01f62007-10-03 23:32:26 +0000132 s->sx = sx;
133 s->sy = sy;
134
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000135 for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
Nicholas Marriott04f4e422007-08-27 13:45:26 +0000136 if (ARRAY_ITEM(&sessions, i) == NULL) {
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000137 ARRAY_SET(&sessions, i, s);
Nicholas Marriott04f4e422007-08-27 13:45:26 +0000138 break;
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000139 }
140 }
Nicholas Marriott04f4e422007-08-27 13:45:26 +0000141 if (i == ARRAY_LENGTH(&sessions))
142 ARRAY_ADD(&sessions, s);
143
Nicholas Marriottdf716ec2007-10-03 21:31:07 +0000144 if (name != NULL)
145 s->name = xstrdup(name);
Nicholas Marriott04f4e422007-08-27 13:45:26 +0000146 else
Nicholas Marriottdf716ec2007-10-03 21:31:07 +0000147 xasprintf(&s->name, "%u", i);
Nicholas Marriott4d9af272009-01-23 16:59:14 +0000148 if (session_new(s, NULL, cmd, cwd, -1, cause) == NULL) {
Nicholas Marriott3fa8f162007-09-27 09:15:58 +0000149 session_destroy(s);
150 return (NULL);
151 }
Nicholas Marriott51482b52007-10-26 13:35:39 +0000152 session_select(s, 0);
Nicholas Marriott3fa8f162007-09-27 09:15:58 +0000153
Nicholas Marriotta26f58c2008-06-02 21:08:36 +0000154 log_debug("session %s created", s->name);
155
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000156 return (s);
157}
158
159/* Destroy a session. */
160void
161session_destroy(struct session *s)
162{
Nicholas Marriott765a2242007-11-12 16:39:30 +0000163 u_int i;
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000164
Nicholas Marriotta26f58c2008-06-02 21:08:36 +0000165 log_debug("session %s destroyed", s->name);
166
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000167 if (session_index(s, &i) != 0)
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +0000168 fatalx("session not found");
Nicholas Marriott3fa8f162007-09-27 09:15:58 +0000169 ARRAY_SET(&sessions, i, NULL);
170 while (!ARRAY_EMPTY(&sessions) && ARRAY_LAST(&sessions) == NULL)
171 ARRAY_TRUNC(&sessions, 1);
Nicholas Marriott103748d2007-12-06 09:46:23 +0000172
Nicholas Marriott14b95122008-06-04 16:46:23 +0000173 session_alert_cancel(s, NULL);
Nicholas Marriott9e6090a2008-06-03 21:42:37 +0000174 options_free(&s->options);
Nicholas Marriott9798dcd2008-06-20 08:36:20 +0000175 paste_free_stack(&s->buffers);
Nicholas Marriott9e6090a2008-06-03 21:42:37 +0000176
Nicholas Marriott46f5e422008-11-16 10:10:26 +0000177 while (!SLIST_EMPTY(&s->lastw))
178 winlink_stack_remove(&s->lastw, SLIST_FIRST(&s->lastw));
Nicholas Marriott765a2242007-11-12 16:39:30 +0000179 while (!RB_EMPTY(&s->windows))
180 winlink_remove(&s->windows, RB_ROOT(&s->windows));
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000181
Nicholas Marriottdf716ec2007-10-03 21:31:07 +0000182 xfree(s->name);
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000183 xfree(s);
184}
185
186/* Find session index. */
187int
188session_index(struct session *s, u_int *i)
189{
190 for (*i = 0; *i < ARRAY_LENGTH(&sessions); (*i)++) {
191 if (s == ARRAY_ITEM(&sessions, *i))
192 return (0);
193 }
194 return (-1);
195}
196
197/* Create a new window on a session. */
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000198struct winlink *
Nicholas Marriott4d711642009-01-10 19:37:35 +0000199session_new(struct session *s,
Nicholas Marriott4d9af272009-01-23 16:59:14 +0000200 const char *name, const char *cmd, const char *cwd, int idx, char **cause)
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000201{
202 struct window *w;
Nicholas Marriott7cd3cf02009-01-12 18:22:47 +0000203 const char *env[] = CHILD_ENVIRON;
Nicholas Marriott22990a62007-09-27 09:52:03 +0000204 char buf[256];
Nicholas Marriott9e6090a2008-06-03 21:42:37 +0000205 u_int i, hlimit;
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000206
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000207 if (session_index(s, &i) != 0)
Nicholas Marriott3fa8f162007-09-27 09:15:58 +0000208 fatalx("session not found");
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000209 xsnprintf(buf, sizeof buf, "TMUX=%ld,%u", (long) getpid(), i);
Nicholas Marriott08d9f462007-10-31 14:26:26 +0000210 env[0] = buf;
Nicholas Marriott103748d2007-12-06 09:46:23 +0000211
Nicholas Marriott9e6090a2008-06-03 21:42:37 +0000212 hlimit = options_get_number(&s->options, "history-limit");
Nicholas Marriott4d9af272009-01-23 16:59:14 +0000213 w = window_create(name, cmd, cwd, env, s->sx, s->sy, hlimit, cause);
Nicholas Marriott4d711642009-01-10 19:37:35 +0000214 if (w == NULL)
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000215 return (NULL);
Nicholas Marriott62457bc2008-09-26 06:45:28 +0000216
Nicholas Marriott4d9af272009-01-23 16:59:14 +0000217 return (session_attach(s, w, idx, cause));
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000218}
219
220/* Attach a window to a session. */
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000221struct winlink *
Nicholas Marriott4d9af272009-01-23 16:59:14 +0000222session_attach(struct session *s, struct window *w, int idx, char **cause)
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000223{
Nicholas Marriott4d9af272009-01-23 16:59:14 +0000224 struct winlink *wl;
225
226 if ((wl = winlink_add(&s->windows, w, idx)) == NULL)
227 xasprintf(cause, "index in use: %d", idx);
228 return (wl);
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000229}
230
231/* Detach a window from a session. */
Nicholas Marriott12f71972007-08-27 20:36:52 +0000232int
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000233session_detach(struct session *s, struct winlink *wl)
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000234{
Nicholas Marriottd1a5fde2009-01-18 18:31:45 +0000235 if (s->curw == wl &&
236 session_last(s) != 0 && session_previous(s, 0) != 0)
237 session_next(s, 0);
Nicholas Marriott5ea2ac32007-09-21 20:45:06 +0000238
Nicholas Marriott14b95122008-06-04 16:46:23 +0000239 session_alert_cancel(s, wl);
Nicholas Marriott46f5e422008-11-16 10:10:26 +0000240 winlink_stack_remove(&s->lastw, wl);
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000241 winlink_remove(&s->windows, wl);
242 if (RB_EMPTY(&s->windows)) {
Nicholas Marriottf1451082007-09-21 18:35:16 +0000243 session_destroy(s);
244 return (1);
Nicholas Marriottf456e1c2007-09-21 20:00:28 +0000245 }
Nicholas Marriottf1451082007-09-21 18:35:16 +0000246 return (0);
Nicholas Marriott6e210bb2007-08-27 12:05:15 +0000247}
248
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000249/* Return if session has window. */
250int
251session_has(struct session *s, struct window *w)
252{
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000253 struct winlink *wl;
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000254
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000255 RB_FOREACH(wl, winlinks, &s->windows) {
256 if (wl->window == w)
257 return (1);
258 }
259 return (0);
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000260}
261
Nicholas Marriottd1a5fde2009-01-18 18:31:45 +0000262struct winlink *
263session_next_activity(struct session *s, struct winlink *wl)
264{
265 while (wl != NULL) {
266 if (session_alert_has(s, wl, WINDOW_BELL))
267 break;
268 if (session_alert_has(s, wl, WINDOW_ACTIVITY))
269 break;
270 wl = winlink_next(&s->windows, wl);
271 }
272 return (wl);
273}
274
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000275/* Move session to next window. */
276int
Nicholas Marriottd1a5fde2009-01-18 18:31:45 +0000277session_next(struct session *s, int activity)
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000278{
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000279 struct winlink *wl;
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000280
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000281 if (s->curw == NULL)
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000282 return (-1);
283
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000284 wl = winlink_next(&s->windows, s->curw);
Nicholas Marriottd1a5fde2009-01-18 18:31:45 +0000285 if (activity)
286 wl = session_next_activity(s, wl);
287 if (wl == NULL) {
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000288 wl = RB_MIN(winlinks, &s->windows);
Nicholas Marriottd1a5fde2009-01-18 18:31:45 +0000289 if (activity && ((wl = session_next_activity(s, wl)) == NULL))
290 return (-1);
291 }
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000292 if (wl == s->curw)
293 return (1);
Nicholas Marriott46f5e422008-11-16 10:10:26 +0000294 winlink_stack_remove(&s->lastw, wl);
295 winlink_stack_push(&s->lastw, s->curw);
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000296 s->curw = wl;
Nicholas Marriott14b95122008-06-04 16:46:23 +0000297 session_alert_cancel(s, wl);
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000298 return (0);
299}
300
Nicholas Marriottd1a5fde2009-01-18 18:31:45 +0000301struct winlink *
302session_previous_activity(struct session *s, struct winlink *wl)
303{
304 while (wl != NULL) {
305 if (session_alert_has(s, wl, WINDOW_BELL))
306 break;
307 if (session_alert_has(s, wl, WINDOW_ACTIVITY))
308 break;
309 wl = winlink_previous(&s->windows, wl);
310 }
311 return (wl);
312}
313
Nicholas Marriott103748d2007-12-06 09:46:23 +0000314/* Move session to previous window. */
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000315int
Nicholas Marriottd1a5fde2009-01-18 18:31:45 +0000316session_previous(struct session *s, int activity)
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000317{
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000318 struct winlink *wl;
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000319
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000320 if (s->curw == NULL)
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000321 return (-1);
322
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000323 wl = winlink_previous(&s->windows, s->curw);
Nicholas Marriottd1a5fde2009-01-18 18:31:45 +0000324 if (activity)
325 wl = session_previous_activity(s, wl);
326 if (wl == NULL) {
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000327 wl = RB_MAX(winlinks, &s->windows);
Nicholas Marriottd1a5fde2009-01-18 18:31:45 +0000328 if (activity && (wl = session_previous_activity(s, wl)) == NULL)
329 return (-1);
330 }
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000331 if (wl == s->curw)
332 return (1);
Nicholas Marriott46f5e422008-11-16 10:10:26 +0000333 winlink_stack_remove(&s->lastw, wl);
334 winlink_stack_push(&s->lastw, s->curw);
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000335 s->curw = wl;
Nicholas Marriott14b95122008-06-04 16:46:23 +0000336 session_alert_cancel(s, wl);
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000337 return (0);
338}
339
Nicholas Marriott103748d2007-12-06 09:46:23 +0000340/* Move session to specific window. */
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000341int
Nicholas Marriott4a325c82007-10-26 16:57:32 +0000342session_select(struct session *s, int idx)
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000343{
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000344 struct winlink *wl;
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000345
Nicholas Marriott4a325c82007-10-26 16:57:32 +0000346 wl = winlink_find_by_index(&s->windows, idx);
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000347 if (wl == NULL)
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000348 return (-1);
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000349 if (wl == s->curw)
350 return (1);
Nicholas Marriott46f5e422008-11-16 10:10:26 +0000351 winlink_stack_remove(&s->lastw, wl);
352 winlink_stack_push(&s->lastw, s->curw);
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000353 s->curw = wl;
Nicholas Marriott14b95122008-06-04 16:46:23 +0000354 session_alert_cancel(s, wl);
Nicholas Marriott34f87e52007-09-20 18:03:23 +0000355 return (0);
356}
357
Nicholas Marriott103748d2007-12-06 09:46:23 +0000358/* Move session to last used window. */
Nicholas Marriott34f87e52007-09-20 18:03:23 +0000359int
360session_last(struct session *s)
361{
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000362 struct winlink *wl;
Nicholas Marriott34f87e52007-09-20 18:03:23 +0000363
Nicholas Marriott46f5e422008-11-16 10:10:26 +0000364 wl = SLIST_FIRST(&s->lastw);
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000365 if (wl == NULL)
Nicholas Marriott34f87e52007-09-20 18:03:23 +0000366 return (-1);
Nicholas Marriott103748d2007-12-06 09:46:23 +0000367 if (wl == s->curw)
Nicholas Marriott34f87e52007-09-20 18:03:23 +0000368 return (1);
369
Nicholas Marriott46f5e422008-11-16 10:10:26 +0000370 winlink_stack_remove(&s->lastw, wl);
371 winlink_stack_push(&s->lastw, s->curw);
Nicholas Marriott4ba3cf62007-10-26 12:29:07 +0000372 s->curw = wl;
Nicholas Marriott14b95122008-06-04 16:46:23 +0000373 session_alert_cancel(s, wl);
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000374 return (0);
375}