cmd-move-window.c revision 1.2
1/* $OpenBSD: cmd-move-window.c,v 1.2 2009/07/13 17:47:46 nicm Exp $ */ 2 3/* 4 * Copyright (c) 2008 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> 20 21#include <stdlib.h> 22 23#include "tmux.h" 24 25/* 26 * Move a window. 27 */ 28 29int cmd_move_window_exec(struct cmd *, struct cmd_ctx *); 30 31const struct cmd_entry cmd_move_window_entry = { 32 "move-window", "movew", 33 "[-dk] " CMD_SRCDST_WINDOW_USAGE, 34 CMD_DFLAG|CMD_KFLAG, 35 cmd_srcdst_init, 36 cmd_srcdst_parse, 37 cmd_move_window_exec, 38 cmd_srcdst_send, 39 cmd_srcdst_recv, 40 cmd_srcdst_free, 41 cmd_srcdst_print 42}; 43 44int 45cmd_move_window_exec(struct cmd *self, struct cmd_ctx *ctx) 46{ 47 struct cmd_srcdst_data *data = self->data; 48 struct session *src, *dst; 49 struct winlink *wl_src, *wl_dst; 50 struct client *c; 51 u_int i; 52 int destroyed, idx; 53 char *cause; 54 55 if ((wl_src = cmd_find_window(ctx, data->src, &src)) == NULL) 56 return (-1); 57 if ((idx = cmd_find_index(ctx, data->dst, &dst)) == -2) 58 return (-1); 59 60 wl_dst = NULL; 61 if (idx != -1) 62 wl_dst = winlink_find_by_index(&dst->windows, idx); 63 if (wl_dst != NULL) { 64 if (wl_dst->window == wl_src->window) 65 return (0); 66 67 if (data->flags & CMD_KFLAG) { 68 /* 69 * Can't use session_detach as it will destroy session 70 * if this makes it empty. 71 */ 72 session_alert_cancel(dst, wl_dst); 73 winlink_stack_remove(&dst->lastw, wl_dst); 74 winlink_remove(&dst->windows, wl_dst); 75 76 /* Force select/redraw if current. */ 77 if (wl_dst == dst->curw) { 78 data->flags &= ~CMD_DFLAG; 79 dst->curw = NULL; 80 } 81 } 82 } 83 84 wl_dst = session_attach(dst, wl_src->window, idx, &cause); 85 if (wl_dst == NULL) { 86 ctx->error(ctx, "attach window failed: %s", cause); 87 xfree(cause); 88 return (-1); 89 } 90 91 destroyed = session_detach(src, wl_src); 92 for (i = 0; i < ARRAY_LENGTH(&clients); i++) { 93 c = ARRAY_ITEM(&clients, i); 94 if (c == NULL || c->session != src) 95 continue; 96 if (destroyed) { 97 c->session = NULL; 98 server_write_client(c, MSG_EXIT, NULL, 0); 99 } else 100 server_redraw_client(c); 101 } 102 103 if (data->flags & CMD_DFLAG) 104 server_status_session(dst); 105 else { 106 session_select(dst, wl_dst->idx); 107 server_redraw_session(dst); 108 } 109 recalculate_sizes(); 110 111 return (0); 112} 113