cmd-resize-pane.c revision 1.1.1.7 1 /* $OpenBSD$ */
2
3 /*
4 * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott (at) gmail.com>
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 * Increase or decrease pane size.
27 */
28
29 static enum cmd_retval cmd_resize_pane_exec(struct cmd *, struct cmdq_item *);
30
31 static void cmd_resize_pane_mouse_update(struct client *,
32 struct mouse_event *);
33
34 const struct cmd_entry cmd_resize_pane_entry = {
35 .name = "resize-pane",
36 .alias = "resizep",
37
38 .args = { "DLMRt:Ux:y:Z", 0, 1 },
39 .usage = "[-DLMRUZ] [-x width] [-y height] " CMD_TARGET_PANE_USAGE " "
40 "[adjustment]",
41
42 .tflag = CMD_PANE,
43
44 .flags = CMD_AFTERHOOK,
45 .exec = cmd_resize_pane_exec
46 };
47
48 static enum cmd_retval
49 cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item)
50 {
51 struct args *args = self->args;
52 struct window_pane *wp = item->state.tflag.wp;
53 struct winlink *wl = item->state.tflag.wl;
54 struct window *w = wl->window;
55 struct client *c = item->client;
56 struct session *s = item->state.tflag.s;
57 const char *errstr;
58 char *cause;
59 u_int adjust;
60 int x, y;
61
62 if (args_has(args, 'M')) {
63 if (cmd_mouse_window(&item->mouse, &s) == NULL)
64 return (CMD_RETURN_NORMAL);
65 if (c == NULL || c->session != s)
66 return (CMD_RETURN_NORMAL);
67 c->tty.mouse_drag_update = cmd_resize_pane_mouse_update;
68 cmd_resize_pane_mouse_update(c, &item->mouse);
69 return (CMD_RETURN_NORMAL);
70 }
71
72 if (args_has(args, 'Z')) {
73 if (w->flags & WINDOW_ZOOMED)
74 window_unzoom(w);
75 else
76 window_zoom(wp);
77 server_redraw_window(w);
78 server_status_window(w);
79 return (CMD_RETURN_NORMAL);
80 }
81 server_unzoom_window(w);
82
83 if (args->argc == 0)
84 adjust = 1;
85 else {
86 adjust = strtonum(args->argv[0], 1, INT_MAX, &errstr);
87 if (errstr != NULL) {
88 cmdq_error(item, "adjustment %s", errstr);
89 return (CMD_RETURN_ERROR);
90 }
91 }
92
93 if (args_has(self->args, 'x')) {
94 x = args_strtonum(self->args, 'x', PANE_MINIMUM, INT_MAX,
95 &cause);
96 if (cause != NULL) {
97 cmdq_error(item, "width %s", cause);
98 free(cause);
99 return (CMD_RETURN_ERROR);
100 }
101 layout_resize_pane_to(wp, LAYOUT_LEFTRIGHT, x);
102 }
103 if (args_has(self->args, 'y')) {
104 y = args_strtonum(self->args, 'y', PANE_MINIMUM, INT_MAX,
105 &cause);
106 if (cause != NULL) {
107 cmdq_error(item, "height %s", cause);
108 free(cause);
109 return (CMD_RETURN_ERROR);
110 }
111 layout_resize_pane_to(wp, LAYOUT_TOPBOTTOM, y);
112 }
113
114 if (args_has(self->args, 'L'))
115 layout_resize_pane(wp, LAYOUT_LEFTRIGHT, -adjust, 1);
116 else if (args_has(self->args, 'R'))
117 layout_resize_pane(wp, LAYOUT_LEFTRIGHT, adjust, 1);
118 else if (args_has(self->args, 'U'))
119 layout_resize_pane(wp, LAYOUT_TOPBOTTOM, -adjust, 1);
120 else if (args_has(self->args, 'D'))
121 layout_resize_pane(wp, LAYOUT_TOPBOTTOM, adjust, 1);
122 server_redraw_window(wl->window);
123
124 return (CMD_RETURN_NORMAL);
125 }
126
127 static void
128 cmd_resize_pane_mouse_update(struct client *c, struct mouse_event *m)
129 {
130 struct winlink *wl;
131 struct window_pane *wp;
132 int found;
133 u_int y, ly;
134
135 wl = cmd_mouse_window(m, NULL);
136 if (wl == NULL) {
137 c->tty.mouse_drag_update = NULL;
138 return;
139 }
140
141 y = m->y;
142 if (m->statusat == 0 && y > 0)
143 y--;
144 else if (m->statusat > 0 && y >= (u_int)m->statusat)
145 y = m->statusat - 1;
146 ly = m->ly;
147 if (m->statusat == 0 && ly > 0)
148 ly--;
149 else if (m->statusat > 0 && ly >= (u_int)m->statusat)
150 ly = m->statusat - 1;
151
152 found = 0;
153 TAILQ_FOREACH(wp, &wl->window->panes, entry) {
154 if (!window_pane_visible(wp))
155 continue;
156
157 if (wp->xoff + wp->sx == m->lx &&
158 wp->yoff <= 1 + ly &&
159 wp->yoff + wp->sy >= ly) {
160 layout_resize_pane(wp, LAYOUT_LEFTRIGHT, m->x - m->lx, 0);
161 found = 1;
162 }
163 if (wp->yoff + wp->sy == ly &&
164 wp->xoff <= 1 + m->lx &&
165 wp->xoff + wp->sx >= m->lx) {
166 layout_resize_pane(wp, LAYOUT_TOPBOTTOM, y - ly, 0);
167 found = 1;
168 }
169 }
170 if (found)
171 server_redraw_window(wl->window);
172 else
173 c->tty.mouse_drag_update = NULL;
174 }
175