4 * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
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.
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.
19 #include <sys/types.h>
27 * Increase or decrease pane size.
30 static enum cmd_retval
cmd_resize_pane_exec(struct cmd
*, struct cmdq_item
*);
32 static void cmd_resize_pane_mouse_update(struct client
*,
33 struct mouse_event
*);
35 const struct cmd_entry cmd_resize_pane_entry
= {
36 .name
= "resize-pane",
39 .args
= { "DLMRTt:Ux:y:Z", 0, 1, NULL
},
40 .usage
= "[-DLMRTUZ] [-x width] [-y height] " CMD_TARGET_PANE_USAGE
" "
43 .target
= { 't', CMD_FIND_PANE
, 0 },
45 .flags
= CMD_AFTERHOOK
,
46 .exec
= cmd_resize_pane_exec
49 static enum cmd_retval
50 cmd_resize_pane_exec(struct cmd
*self
, struct cmdq_item
*item
)
52 struct args
*args
= cmd_get_args(self
);
53 struct cmd_find_state
*target
= cmdq_get_target(item
);
54 struct key_event
*event
= cmdq_get_event(item
);
55 struct window_pane
*wp
= target
->wp
;
56 struct winlink
*wl
= target
->wl
;
57 struct window
*w
= wl
->window
;
58 struct client
*c
= cmdq_get_client(item
);
59 struct session
*s
= target
->s
;
64 struct grid
*gd
= wp
->base
.grid
;
66 if (args_has(args
, 'T')) {
67 if (!TAILQ_EMPTY(&wp
->modes
))
68 return (CMD_RETURN_NORMAL
);
69 adjust
= screen_size_y(&wp
->base
) - 1 - wp
->base
.cy
;
70 if (adjust
> gd
->hsize
)
72 grid_remove_history(gd
, adjust
);
73 wp
->base
.cy
+= adjust
;
74 wp
->flags
|= PANE_REDRAW
;
75 return (CMD_RETURN_NORMAL
);
78 if (args_has(args
, 'M')) {
79 if (!event
->m
.valid
|| cmd_mouse_window(&event
->m
, &s
) == NULL
)
80 return (CMD_RETURN_NORMAL
);
81 if (c
== NULL
|| c
->session
!= s
)
82 return (CMD_RETURN_NORMAL
);
83 c
->tty
.mouse_drag_update
= cmd_resize_pane_mouse_update
;
84 cmd_resize_pane_mouse_update(c
, &event
->m
);
85 return (CMD_RETURN_NORMAL
);
88 if (args_has(args
, 'Z')) {
89 if (w
->flags
& WINDOW_ZOOMED
)
93 server_redraw_window(w
);
94 return (CMD_RETURN_NORMAL
);
96 server_unzoom_window(w
);
98 if (args_count(args
) == 0)
101 adjust
= strtonum(args_string(args
, 0), 1, INT_MAX
, &errstr
);
102 if (errstr
!= NULL
) {
103 cmdq_error(item
, "adjustment %s", errstr
);
104 return (CMD_RETURN_ERROR
);
108 if (args_has(args
, 'x')) {
109 x
= args_percentage(args
, 'x', 0, INT_MAX
, w
->sx
, &cause
);
111 cmdq_error(item
, "width %s", cause
);
113 return (CMD_RETURN_ERROR
);
115 layout_resize_pane_to(wp
, LAYOUT_LEFTRIGHT
, x
);
117 if (args_has(args
, 'y')) {
118 y
= args_percentage(args
, 'y', 0, INT_MAX
, w
->sy
, &cause
);
120 cmdq_error(item
, "height %s", cause
);
122 return (CMD_RETURN_ERROR
);
124 status
= options_get_number(w
->options
, "pane-border-status");
126 case PANE_STATUS_TOP
:
127 if (y
!= INT_MAX
&& wp
->yoff
== 1)
130 case PANE_STATUS_BOTTOM
:
131 if (y
!= INT_MAX
&& wp
->yoff
+ wp
->sy
== w
->sy
- 1)
135 layout_resize_pane_to(wp
, LAYOUT_TOPBOTTOM
, y
);
138 if (args_has(args
, 'L'))
139 layout_resize_pane(wp
, LAYOUT_LEFTRIGHT
, -adjust
, 1);
140 else if (args_has(args
, 'R'))
141 layout_resize_pane(wp
, LAYOUT_LEFTRIGHT
, adjust
, 1);
142 else if (args_has(args
, 'U'))
143 layout_resize_pane(wp
, LAYOUT_TOPBOTTOM
, -adjust
, 1);
144 else if (args_has(args
, 'D'))
145 layout_resize_pane(wp
, LAYOUT_TOPBOTTOM
, adjust
, 1);
146 server_redraw_window(wl
->window
);
148 return (CMD_RETURN_NORMAL
);
152 cmd_resize_pane_mouse_update(struct client
*c
, struct mouse_event
*m
)
157 static const int offsets
[][2] = {
158 { 0, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 },
160 struct layout_cell
*cells
[nitems(offsets
)], *lc
;
161 u_int ncells
= 0, i
, j
, resizes
= 0;
162 enum layout_type type
;
164 wl
= cmd_mouse_window(m
, NULL
);
166 c
->tty
.mouse_drag_update
= NULL
;
171 y
= m
->y
+ m
->oy
; x
= m
->x
+ m
->ox
;
172 if (m
->statusat
== 0 && y
>= m
->statuslines
)
174 else if (m
->statusat
> 0 && y
>= (u_int
)m
->statusat
)
176 ly
= m
->ly
+ m
->oy
; lx
= m
->lx
+ m
->ox
;
177 if (m
->statusat
== 0 && ly
>= m
->statuslines
)
178 ly
-= m
->statuslines
;
179 else if (m
->statusat
> 0 && ly
>= (u_int
)m
->statusat
)
180 ly
= m
->statusat
- 1;
182 for (i
= 0; i
< nitems(cells
); i
++) {
183 lc
= layout_search_by_border(w
->layout_root
, lx
+ offsets
[i
][0],
188 for (j
= 0; j
< ncells
; j
++) {
189 if (cells
[j
] == lc
) {
203 for (i
= 0; i
< ncells
; i
++) {
204 type
= cells
[i
]->parent
->type
;
205 if (y
!= ly
&& type
== LAYOUT_TOPBOTTOM
) {
206 layout_resize_layout(w
, cells
[i
], type
, y
- ly
, 0);
208 } else if (x
!= lx
&& type
== LAYOUT_LEFTRIGHT
) {
209 layout_resize_layout(w
, cells
[i
], type
, x
- lx
, 0);
214 server_redraw_window(w
);