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