1/* $OpenBSD$ */
2
3/*
4 * Copyright (c) 2009 Nicholas Marriott <[email protected]>
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 * Switch window to selected layout.
27 */
28
29static enum cmd_retval cmd_select_layout_exec(struct cmd *,
30 struct cmdq_item *);
31
32const struct cmd_entry cmd_select_layout_entry = {
33 .name = "select-layout",
34 .alias = "selectl",
35
36 .args = { "Enopt:", 0, 1 },
37 .usage = "[-Enop] " CMD_TARGET_PANE_USAGE " [layout-name]",
38
39 .target = { 't', CMD_FIND_PANE, 0 },
40
41 .flags = CMD_AFTERHOOK,
42 .exec = cmd_select_layout_exec
43};
44
45const struct cmd_entry cmd_next_layout_entry = {
46 .name = "next-layout",
47 .alias = "nextl",
48
49 .args = { "t:", 0, 0 },
50 .usage = CMD_TARGET_WINDOW_USAGE,
51
52 .target = { 't', CMD_FIND_WINDOW, 0 },
53
54 .flags = CMD_AFTERHOOK,
55 .exec = cmd_select_layout_exec
56};
57
58const struct cmd_entry cmd_previous_layout_entry = {
59 .name = "previous-layout",
60 .alias = "prevl",
61
62 .args = { "t:", 0, 0 },
63 .usage = CMD_TARGET_WINDOW_USAGE,
64
65 .target = { 't', CMD_FIND_WINDOW, 0 },
66
67 .flags = CMD_AFTERHOOK,
68 .exec = cmd_select_layout_exec
69};
70
71static enum cmd_retval
72cmd_select_layout_exec(struct cmd *self, struct cmdq_item *item)
73{
74 struct args *args = self->args;
75 struct winlink *wl = item->target.wl;
76 struct window *w = wl->window;
77 struct window_pane *wp = item->target.wp;
78 const char *layoutname;
79 char *oldlayout;
80 int next, previous, layout;
81
82 server_unzoom_window(w);
83
84 next = self->entry == &cmd_next_layout_entry;
85 if (args_has(args, 'n'))
86 next = 1;
87 previous = self->entry == &cmd_previous_layout_entry;
88 if (args_has(args, 'p'))
89 previous = 1;
90
91 oldlayout = w->old_layout;
92 w->old_layout = layout_dump(w->layout_root);
93
94 if (next || previous) {
95 if (next)
96 layout_set_next(w);
97 else
98 layout_set_previous(w);
99 goto changed;
100 }
101
102 if (args_has(args, 'E')) {
103 layout_spread_out(wp);
104 goto changed;
105 }
106
107 if (!args_has(args, 'o')) {
108 if (args->argc == 0)
109 layout = w->lastlayout;
110 else
111 layout = layout_set_lookup(args->argv[0]);
112 if (layout != -1) {
113 layout_set_select(w, layout);
114 goto changed;
115 }
116 }
117
118 if (args->argc != 0)
119 layoutname = args->argv[0];
120 else if (args_has(args, 'o'))
121 layoutname = oldlayout;
122 else
123 layoutname = NULL;
124
125 if (layoutname != NULL) {
126 if (layout_parse(w, layoutname) == -1) {
127 cmdq_error(item, "can't set layout: %s", layoutname);
128 goto error;
129 }
130 goto changed;
131 }
132
133 free(oldlayout);
134 return (CMD_RETURN_NORMAL);
135
136changed:
137 free(oldlayout);
138 recalculate_sizes();
139 server_redraw_window(w);
140 notify_window("window-layout-changed", w);
141 return (CMD_RETURN_NORMAL);
142
143error:
144 free(w->old_layout);
145 w->old_layout = oldlayout;
146 return (CMD_RETURN_ERROR);
147}
148