summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd-resize-pane.c49
-rw-r--r--layout.c87
-rw-r--r--tmux.h3
3 files changed, 83 insertions, 56 deletions
diff --git a/cmd-resize-pane.c b/cmd-resize-pane.c
index bbb78de7..cfde83b3 100644
--- a/cmd-resize-pane.c
+++ b/cmd-resize-pane.c
@@ -129,14 +129,16 @@ static void
cmd_resize_pane_mouse_update(struct client *c, struct mouse_event *m)
{
struct winlink *wl;
- struct window_pane *loop, *wp_x, *wp_y;
- u_int y, ly, x, lx, sx, sy, ex, ey;
+ struct window *w;
+ u_int y, ly, x, lx;
+ struct layout_cell *lc;
wl = cmd_mouse_window(m, NULL);
if (wl == NULL) {
c->tty.mouse_drag_update = NULL;
return;
}
+ w = wl->window;
y = m->y; x = m->x;
if (m->statusat == 0 && y > 0)
@@ -149,37 +151,16 @@ cmd_resize_pane_mouse_update(struct client *c, struct mouse_event *m)
else if (m->statusat > 0 && ly >= (u_int)m->statusat)
ly = m->statusat - 1;
- wp_x = wp_y = NULL;
- TAILQ_FOREACH(loop, &wl->window->panes, entry) {
- if (!window_pane_visible(loop))
- continue;
-
- sx = loop->xoff;
- if (sx != 0)
- sx--;
- ex = loop->xoff + loop->sx;
-
- sy = loop->yoff;
- if (sy != 0)
- sy--;
- ey = loop->yoff + loop->sy;
-
- if ((lx == sx || lx == ex) &&
- (ly >= sy && ly <= ey) &&
- (wp_x == NULL || loop->sy > wp_x->sy))
- wp_x = loop;
- if ((ly == sy || ly == ey) &&
- (lx >= sx && lx <= ex) &&
- (wp_y == NULL || loop->sx > wp_y->sx))
- wp_y = loop;
- }
- if (wp_x == NULL && wp_y == NULL) {
- c->tty.mouse_drag_update = NULL;
+ lc = layout_search_by_border(w->layout_root, lx, ly);
+ if (lc == NULL)
return;
- }
- if (wp_x != NULL)
- layout_resize_pane(wp_x, LAYOUT_LEFTRIGHT, x - lx, 0);
- if (wp_y != NULL)
- layout_resize_pane(wp_y, LAYOUT_TOPBOTTOM, y - ly, 0);
- server_redraw_window(wl->window);
+
+ if (y != ly && lc->parent->type == LAYOUT_TOPBOTTOM)
+ layout_resize_layout(w, lc, LAYOUT_TOPBOTTOM, y - ly, 0);
+ else if (x != lx && lc->parent->type == LAYOUT_LEFTRIGHT)
+ layout_resize_layout(w, lc, LAYOUT_LEFTRIGHT, x - lx, 0);
+ else
+ return;
+
+ server_redraw_window(w);
}
diff --git a/layout.c b/layout.c
index bab95868..e1112ffa 100644
--- a/layout.c
+++ b/layout.c
@@ -127,6 +127,42 @@ layout_print_cell(struct layout_cell *lc, const char *hdr, u_int n)
}
}
+struct layout_cell *
+layout_search_by_border(struct layout_cell *lc, u_int x, u_int y)
+{
+ struct layout_cell *lcchild, *last = NULL;
+
+ TAILQ_FOREACH(lcchild, &lc->cells, entry) {
+ if (x >= lcchild->xoff && x < lcchild->xoff + lcchild->sx &&
+ y >= lcchild->yoff && y < lcchild->yoff + lcchild->sy) {
+ /* Inside the cell - recurse. */
+ return (layout_search_by_border(lcchild, x, y));
+ }
+
+ if (last == NULL) {
+ last = lcchild;
+ continue;
+ }
+
+ switch (lc->type) {
+ case LAYOUT_LEFTRIGHT:
+ if (x < lcchild->xoff && x >= last->xoff + last->sx)
+ return (last);
+ break;
+ case LAYOUT_TOPBOTTOM:
+ if (y < lcchild->yoff && y >= last->yoff + last->sy)
+ return (last);
+ break;
+ case LAYOUT_WINDOWPANE:
+ break;
+ }
+
+ last = lcchild;
+ }
+
+ return (NULL);
+}
+
void
layout_set_size(struct layout_cell *lc, u_int sx, u_int sy, u_int xoff,
u_int yoff)
@@ -550,14 +586,40 @@ layout_resize_pane_to(struct window_pane *wp, enum layout_type type,
layout_resize_pane(wp, type, change, 1);
}
+void
+layout_resize_layout(struct window *w, struct layout_cell *lc,
+ enum layout_type type, int change, int opposite)
+{
+ int needed, size;
+
+ /* Grow or shrink the cell. */
+ needed = change;
+ while (needed != 0) {
+ if (change > 0) {
+ size = layout_resize_pane_grow(w, lc, type, needed,
+ opposite);
+ needed -= size;
+ } else {
+ size = layout_resize_pane_shrink(w, lc, type, needed);
+ needed += size;
+ }
+
+ if (size == 0) /* no more change possible */
+ break;
+ }
+
+ /* Fix cell offsets. */
+ layout_fix_offsets(w->layout_root);
+ layout_fix_panes(w, w->sx, w->sy);
+ notify_window("window-layout-changed", w);
+}
+
/* Resize a single pane within the layout. */
void
layout_resize_pane(struct window_pane *wp, enum layout_type type, int change,
int opposite)
{
- struct window *w = wp->window;
struct layout_cell *lc, *lcparent;
- int needed, size;
lc = wp->layout_cell;
@@ -574,26 +636,7 @@ layout_resize_pane(struct window_pane *wp, enum layout_type type, int change,
if (lc == TAILQ_LAST(&lcparent->cells, layout_cells))
lc = TAILQ_PREV(lc, layout_cells, entry);
- /* Grow or shrink the cell. */
- needed = change;
- while (needed != 0) {
- if (change > 0) {
- size = layout_resize_pane_grow(w, lc, type, needed,
- opposite);
- needed -= size;
- } else {
- size = layout_resize_pane_shrink(w, lc, type, needed);
- needed += size;
- }
-
- if (size == 0) /* no more change possible */
- break;
- }
-
- /* Fix cell offsets. */
- layout_fix_offsets(wp->window->layout_root);
- layout_fix_panes(wp->window, wp->window->sx, wp->window->sy);
- notify_window("window-layout-changed", wp->window);
+ layout_resize_layout(wp->window, lc, type, change, opposite);
}
/* Helper function to grow pane. */
diff --git a/tmux.h b/tmux.h
index d46dca2e..d6e4ae0b 100644
--- a/tmux.h
+++ b/tmux.h
@@ -2203,6 +2203,9 @@ void layout_free_cell(struct layout_cell *);
void layout_print_cell(struct layout_cell *, const char *, u_int);
void layout_destroy_cell(struct window *, struct layout_cell *,
struct layout_cell **);
+void layout_resize_layout(struct window *, struct layout_cell *,
+ enum layout_type, int, int);
+struct layout_cell *layout_search_by_border(struct layout_cell *, u_int, u_int);
void layout_set_size(struct layout_cell *, u_int, u_int, u_int,
u_int);
void layout_make_leaf(struct layout_cell *, struct window_pane *);