mirror of
https://github.com/tmux/tmux.git
synced 2026-03-07 00:05:33 +00:00
1. Rework floating panes to have a stub layout_cell, 2. Add new <..> format to list-windows & select-layout for floating anes, 3. Fix zooming to work with floating panes, 4. Fix several display issues.
This commit is contained in:
@@ -59,6 +59,7 @@ cmd_new_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
struct winlink *wl = target->wl;
|
struct winlink *wl = target->wl;
|
||||||
struct window *w = wl->window;
|
struct window *w = wl->window;
|
||||||
struct window_pane *wp = target->wp, *new_wp;
|
struct window_pane *wp = target->wp, *new_wp;
|
||||||
|
struct layout_cell *lc;
|
||||||
struct cmd_find_state fs;
|
struct cmd_find_state fs;
|
||||||
int flags, input;
|
int flags, input;
|
||||||
const char *template;
|
const char *template;
|
||||||
@@ -147,13 +148,6 @@ cmd_new_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sc.xoff = x;
|
|
||||||
sc.yoff = y;
|
|
||||||
last_x = x;
|
|
||||||
last_y = y;
|
|
||||||
sc.sx = sx;
|
|
||||||
sc.sy = sy;
|
|
||||||
|
|
||||||
input = (args_has(args, 'I') && count == 0);
|
input = (args_has(args, 'I') && count == 0);
|
||||||
|
|
||||||
flags = SPAWN_FLOATING;
|
flags = SPAWN_FLOATING;
|
||||||
@@ -169,7 +163,19 @@ cmd_new_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
sc.wl = wl;
|
sc.wl = wl;
|
||||||
|
|
||||||
sc.wp0 = wp;
|
sc.wp0 = wp;
|
||||||
sc.lc = NULL;
|
|
||||||
|
/* Floating panes sit in layout cells which are not in the layout_root
|
||||||
|
* tree so we call it with parent == NULL.
|
||||||
|
*/
|
||||||
|
lc = layout_create_cell(NULL);
|
||||||
|
lc->xoff = x;
|
||||||
|
lc->yoff = y;
|
||||||
|
lc->sx = sx;
|
||||||
|
lc->sy = sy;
|
||||||
|
sc.lc = lc;
|
||||||
|
|
||||||
|
last_x = x; /* Statically save last xoff & yoff so that new */
|
||||||
|
last_y = y; /* floating panes offset so they don't overlap. */
|
||||||
|
|
||||||
args_to_vector(args, &sc.argc, &sc.argv);
|
args_to_vector(args, &sc.argc, &sc.argv);
|
||||||
sc.environ = environ_create();
|
sc.environ = environ_create();
|
||||||
|
|||||||
@@ -82,14 +82,14 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
if (c == NULL || c->session != s)
|
if (c == NULL || c->session != s)
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
if (c->tty.mouse_wp->layout_cell != NULL) {
|
if (c->tty.mouse_wp->flags & PANE_FLOATING) {
|
||||||
c->tty.mouse_drag_update = cmd_resize_pane_mouse_update_tiled;
|
|
||||||
cmd_resize_pane_mouse_update_tiled(c, &event->m);
|
|
||||||
} else {
|
|
||||||
window_redraw_active_switch(w, c->tty.mouse_wp);
|
window_redraw_active_switch(w, c->tty.mouse_wp);
|
||||||
window_set_active_pane(w, c->tty.mouse_wp, 1);
|
window_set_active_pane(w, c->tty.mouse_wp, 1);
|
||||||
c->tty.mouse_drag_update = cmd_resize_pane_mouse_update_floating;
|
c->tty.mouse_drag_update = cmd_resize_pane_mouse_update_floating;
|
||||||
cmd_resize_pane_mouse_update_floating(c, &event->m);
|
cmd_resize_pane_mouse_update_floating(c, &event->m);
|
||||||
|
} else {
|
||||||
|
c->tty.mouse_drag_update = cmd_resize_pane_mouse_update_tiled;
|
||||||
|
cmd_resize_pane_mouse_update_tiled(c, &event->m);
|
||||||
}
|
}
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
}
|
}
|
||||||
@@ -163,7 +163,9 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m)
|
|||||||
struct winlink *wl;
|
struct winlink *wl;
|
||||||
struct window *w;
|
struct window *w;
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
u_int y, ly, x, lx, new_sx, new_sy, resizes = 0;
|
struct layout_cell *lc;
|
||||||
|
u_int y, ly, x, lx, new_sx, new_sy;
|
||||||
|
int new_xoff, new_yoff, resizes = 0;
|
||||||
|
|
||||||
wl = cmd_mouse_window(m, NULL);
|
wl = cmd_mouse_window(m, NULL);
|
||||||
if (wl == NULL) {
|
if (wl == NULL) {
|
||||||
@@ -184,89 +186,93 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m)
|
|||||||
ly = m->statusat - 1;
|
ly = m->statusat - 1;
|
||||||
|
|
||||||
wp = c->tty.mouse_wp;
|
wp = c->tty.mouse_wp;
|
||||||
|
lc = wp->layout_cell;
|
||||||
|
|
||||||
log_debug("%s: %%%u resize_pane xoff=%u sx=%u xy=%ux%u lxy=%ux%u",
|
log_debug("%s: %%%u resize_pane xoff=%u sx=%u xy=%ux%u lxy=%ux%u",
|
||||||
__func__, wp->id, wp->xoff, wp->sx, x, y, lx, ly);
|
__func__, wp->id, wp->xoff, wp->sx, x, y, lx, ly);
|
||||||
if ((((int)lx == wp->xoff - 1) || ((int)lx == wp->xoff)) &&
|
if ((((int)lx == wp->xoff - 1) || ((int)lx == wp->xoff)) &&
|
||||||
((int)ly == wp->yoff - 1)) {
|
((int)ly == wp->yoff - 1)) {
|
||||||
/* Top left border */
|
/* Top left corner */
|
||||||
new_sx = wp->sx + (lx - x);
|
new_sx = lc->sx + (lx - x);
|
||||||
if (new_sx < PANE_MINIMUM)
|
if (new_sx < PANE_MINIMUM)
|
||||||
new_sx = PANE_MINIMUM;
|
new_sx = PANE_MINIMUM;
|
||||||
new_sy = wp->sy + (ly - y);
|
new_sy = lc->sy + (ly - y);
|
||||||
if (new_sy < PANE_MINIMUM)
|
if (new_sy < PANE_MINIMUM)
|
||||||
new_sy = PANE_MINIMUM;
|
new_sy = PANE_MINIMUM;
|
||||||
window_pane_move(wp, x + 1, y + 1);
|
new_xoff = x + 1; /* Because mouse is on border at xoff - 1 */
|
||||||
window_pane_resize(wp, new_sx, new_sy);
|
new_yoff = y + 1;
|
||||||
|
layout_set_size(lc, new_sx, new_sy, new_xoff, new_yoff);
|
||||||
resizes++;
|
resizes++;
|
||||||
} else if ((((int)lx == wp->xoff + (int)wp->sx + 1) ||
|
} else if ((((int)lx == wp->xoff + (int)wp->sx + 1) ||
|
||||||
((int)lx == wp->xoff + (int)wp->sx)) &&
|
((int)lx == wp->xoff + (int)wp->sx)) &&
|
||||||
((int)ly == wp->yoff - 1)) {
|
((int)ly == wp->yoff - 1)) {
|
||||||
/* Top right border */
|
/* Top right corner */
|
||||||
new_sx = x - wp->xoff - 1;
|
new_sx = x - lc->xoff;
|
||||||
if (new_sx < PANE_MINIMUM)
|
if (new_sx < PANE_MINIMUM)
|
||||||
new_sx = PANE_MINIMUM;
|
new_sx = PANE_MINIMUM;
|
||||||
new_sy = wp->sy + (ly - y);
|
new_sy = lc->sy + (ly - y);
|
||||||
if (new_sy < PANE_MINIMUM)
|
if (new_sy < PANE_MINIMUM)
|
||||||
new_sy = PANE_MINIMUM;
|
new_sy = PANE_MINIMUM;
|
||||||
window_pane_move(wp, wp->xoff, y + 1);
|
new_yoff = y + 1;
|
||||||
window_pane_resize(wp, new_sx, new_sy);
|
layout_set_size(lc, new_sx, new_sy, lc->xoff, new_yoff);
|
||||||
resizes++;
|
resizes++;
|
||||||
} else if ((((int)lx == wp->xoff - 1) || ((int)lx == wp->xoff)) &&
|
} else if ((((int)lx == wp->xoff - 1) || ((int)lx == wp->xoff)) &&
|
||||||
((int)ly == wp->yoff + (int)wp->sy)) {
|
((int)ly == wp->yoff + (int)wp->sy)) {
|
||||||
/* Bottom left border */
|
/* Bottom left corner */
|
||||||
new_sx = wp->sx + (lx - x);
|
new_sx = lc->sx + (lx - x);
|
||||||
if (new_sx < PANE_MINIMUM)
|
if (new_sx < PANE_MINIMUM)
|
||||||
new_sx = PANE_MINIMUM;
|
new_sx = PANE_MINIMUM;
|
||||||
new_sy = y - wp->yoff;
|
new_sy = y - lc->yoff;
|
||||||
if (new_sy < PANE_MINIMUM)
|
if (new_sy < PANE_MINIMUM)
|
||||||
return;
|
return;
|
||||||
window_pane_move(wp, x + 1, wp->yoff);
|
new_xoff = x + 1;
|
||||||
window_pane_resize(wp, new_sx, new_sy);
|
layout_set_size(lc, new_sx, new_sy, new_xoff, lc->yoff);
|
||||||
resizes++;
|
resizes++;
|
||||||
} else if ((((int)lx == wp->xoff + (int)wp->sx + 1) ||
|
} else if ((((int)lx == wp->xoff + (int)wp->sx + 1) ||
|
||||||
((int)lx == wp->xoff + (int)wp->sx)) &&
|
((int)lx == wp->xoff + (int)wp->sx)) &&
|
||||||
((int)ly == wp->yoff + (int)wp->sy)) {
|
((int)ly == wp->yoff + (int)wp->sy)) {
|
||||||
/* Bottom right corner */
|
/* Bottom right corner */
|
||||||
new_sx = x - wp->xoff - 1;
|
new_sx = x - lc->xoff;
|
||||||
if (new_sx < PANE_MINIMUM)
|
if (new_sx < PANE_MINIMUM)
|
||||||
new_sx = PANE_MINIMUM;
|
new_sx = PANE_MINIMUM;
|
||||||
new_sy = y - wp->yoff;
|
new_sy = y - lc->yoff;
|
||||||
if (new_sy < PANE_MINIMUM)
|
if (new_sy < PANE_MINIMUM)
|
||||||
new_sy = PANE_MINIMUM;
|
new_sy = PANE_MINIMUM;
|
||||||
window_pane_resize(wp, new_sx, new_sy);
|
layout_set_size(lc, new_sx, new_sy, lc->xoff, lc->yoff);
|
||||||
resizes++;
|
resizes++;
|
||||||
} else if ((int)lx == wp->xoff + (int)wp->sx + 1) {
|
} else if ((int)lx == wp->xoff + (int)wp->sx + 1) {
|
||||||
/* Right border */
|
/* Right border */
|
||||||
new_sx = x - wp->xoff - 1;
|
new_sx = x - lc->xoff;
|
||||||
if (new_sx < PANE_MINIMUM)
|
if (new_sx < PANE_MINIMUM)
|
||||||
return;
|
return;
|
||||||
window_pane_resize(wp, new_sx, wp->sy);
|
layout_set_size(lc, new_sx, lc->sy, lc->xoff, lc->yoff);
|
||||||
resizes++;
|
resizes++;
|
||||||
} else if ((int)lx == wp->xoff - 1) {
|
} else if ((int)lx == wp->xoff - 1) {
|
||||||
/* Left border */
|
/* Left border */
|
||||||
new_sx = wp->sx + (lx - x);
|
new_sx = lc->sx + (lx - x);
|
||||||
if (new_sx < PANE_MINIMUM)
|
if (new_sx < PANE_MINIMUM)
|
||||||
return;
|
return;
|
||||||
window_pane_move(wp, x + 1, wp->yoff);
|
new_xoff = x + 1;
|
||||||
window_pane_resize(wp, new_sx, wp->sy);
|
layout_set_size(lc, new_sx, lc->sy, new_xoff, lc->yoff);
|
||||||
resizes++;
|
resizes++;
|
||||||
} else if ((int)ly == wp->yoff + (int)wp->sy) {
|
} else if ((int)ly == wp->yoff + (int)wp->sy) {
|
||||||
/* Bottom border */
|
/* Bottom border */
|
||||||
new_sy = y - wp->yoff;
|
new_sy = y - lc->yoff;
|
||||||
if (new_sy < PANE_MINIMUM)
|
if (new_sy < PANE_MINIMUM)
|
||||||
return;
|
return;
|
||||||
window_pane_resize(wp, wp->sx, new_sy);
|
layout_set_size(lc, lc->sx, new_sy, lc->xoff, lc->yoff);
|
||||||
resizes++;
|
resizes++;
|
||||||
} else if ((int)ly == wp->yoff - 1) {
|
} else if ((int)ly == wp->yoff - 1) {
|
||||||
/* Top border */
|
/* Top border (move instead of resize) */
|
||||||
window_pane_move(wp, wp->xoff + (x - lx), y + 1);
|
new_xoff = lc->xoff + (x - lx);
|
||||||
/*
|
new_yoff = y + 1;
|
||||||
|
layout_set_size(lc, lc->sx, lc->sy, new_xoff, new_yoff);
|
||||||
|
/* To resize instead of move:
|
||||||
new_sy = wp->sy + (ly - y);
|
new_sy = wp->sy + (ly - y);
|
||||||
if (new_sy < PANE_MINIMUM)
|
if (new_sy < PANE_MINIMUM)
|
||||||
return;
|
return;
|
||||||
window_pane_move(wp, wp->xoff, y + 1);
|
new_yoff = y + 1;
|
||||||
window_pane_resize(wp, wp->sx, new_sy);
|
layout_set_size(lc, lc->sx, new_sy, lc->xoff, new_yoff);
|
||||||
*/
|
*/
|
||||||
resizes++;
|
resizes++;
|
||||||
} else {
|
} else {
|
||||||
@@ -274,6 +280,7 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m)
|
|||||||
__func__, wp->id, wp->xoff, wp->sx, x, y, lx, ly);
|
__func__, wp->id, wp->xoff, wp->sx, x, y, lx, ly);
|
||||||
}
|
}
|
||||||
if (resizes != 0) {
|
if (resizes != 0) {
|
||||||
|
layout_fix_panes(w, NULL);
|
||||||
server_redraw_window(w);
|
server_redraw_window(w);
|
||||||
server_redraw_window_borders(w);
|
server_redraw_window_borders(w);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ cmd_select_layout_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
previous = 1;
|
previous = 1;
|
||||||
|
|
||||||
oldlayout = w->old_layout;
|
oldlayout = w->old_layout;
|
||||||
w->old_layout = layout_dump(w->layout_root);
|
w->old_layout = layout_dump(w, w->layout_root);
|
||||||
|
|
||||||
if (next || previous) {
|
if (next || previous) {
|
||||||
if (next)
|
if (next)
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
server_redraw_window_borders(markedwp->window);
|
server_redraw_window_borders(markedwp->window);
|
||||||
server_status_window(markedwp->window);
|
server_status_window(markedwp->window);
|
||||||
}
|
}
|
||||||
if (wp->layout_cell == NULL) {
|
if (wp->flags & PANE_FLOATING) {
|
||||||
window_redraw_active_switch(w, wp);
|
window_redraw_active_switch(w, wp);
|
||||||
window_set_active_pane(w, wp, 1);
|
window_set_active_pane(w, wp, 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
struct args_value *av;
|
struct args_value *av;
|
||||||
u_int count = args_count(args), curval = 0;
|
u_int count = args_count(args), curval = 0;
|
||||||
|
|
||||||
if (wp->layout_cell == NULL) {
|
if (wp->flags & PANE_FLOATING) {
|
||||||
cmdq_error(item, "can't split a floating pane");
|
cmdq_error(item, "can't split a floating pane");
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
|
|||||||
6
format.c
6
format.c
@@ -821,8 +821,8 @@ format_cb_window_layout(struct format_tree *ft)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
if (w->saved_layout_root != NULL)
|
if (w->saved_layout_root != NULL)
|
||||||
return (layout_dump(w->saved_layout_root));
|
return (layout_dump(w, w->saved_layout_root));
|
||||||
return (layout_dump(w->layout_root));
|
return (layout_dump(w, w->layout_root));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Callback for window_visible_layout. */
|
/* Callback for window_visible_layout. */
|
||||||
@@ -834,7 +834,7 @@ format_cb_window_visible_layout(struct format_tree *ft)
|
|||||||
if (w == NULL)
|
if (w == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
return (layout_dump(w->layout_root));
|
return (layout_dump(w, w->layout_root));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Callback for pane_start_command. */
|
/* Callback for pane_start_command. */
|
||||||
|
|||||||
178
layout-custom.c
178
layout-custom.c
@@ -27,10 +27,11 @@ static struct layout_cell *layout_find_bottomright(struct layout_cell *);
|
|||||||
static u_short layout_checksum(const char *);
|
static u_short layout_checksum(const char *);
|
||||||
static int layout_append(struct layout_cell *, char *,
|
static int layout_append(struct layout_cell *, char *,
|
||||||
size_t);
|
size_t);
|
||||||
static struct layout_cell *layout_construct(struct layout_cell *,
|
static int layout_construct(struct layout_cell *,
|
||||||
const char **);
|
const char **, struct layout_cell **,
|
||||||
|
struct layout_cell **);
|
||||||
static void layout_assign(struct window_pane **,
|
static void layout_assign(struct window_pane **,
|
||||||
struct layout_cell *);
|
struct layout_cell *, int);
|
||||||
|
|
||||||
/* Find the bottom-right cell. */
|
/* Find the bottom-right cell. */
|
||||||
static struct layout_cell *
|
static struct layout_cell *
|
||||||
@@ -58,14 +59,33 @@ layout_checksum(const char *layout)
|
|||||||
|
|
||||||
/* Dump layout as a string. */
|
/* Dump layout as a string. */
|
||||||
char *
|
char *
|
||||||
layout_dump(struct layout_cell *root)
|
layout_dump(struct window *w, struct layout_cell *root)
|
||||||
{
|
{
|
||||||
char layout[8192], *out;
|
char layout[8192], *out;
|
||||||
|
int braket;
|
||||||
|
struct window_pane *wp;
|
||||||
|
|
||||||
*layout = '\0';
|
*layout = '\0';
|
||||||
if (layout_append(root, layout, sizeof layout) != 0)
|
if (layout_append(root, layout, sizeof layout) != 0)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
|
braket = 0;
|
||||||
|
TAILQ_FOREACH(wp, &w->z_index, zentry) {
|
||||||
|
if (~wp->flags & PANE_FLOATING)
|
||||||
|
break;
|
||||||
|
if (!braket) {
|
||||||
|
strcat(layout, "<");
|
||||||
|
braket = 1;
|
||||||
|
}
|
||||||
|
if (layout_append(wp->layout_cell, layout, sizeof layout) != 0)
|
||||||
|
return (NULL);
|
||||||
|
strcat(layout, ",");
|
||||||
|
}
|
||||||
|
if (braket) {
|
||||||
|
/* Overwrite the trailing ','. */
|
||||||
|
layout[strlen(layout) - 1] = '>';
|
||||||
|
}
|
||||||
|
|
||||||
xasprintf(&out, "%04hx,%s", layout_checksum(layout), layout);
|
xasprintf(&out, "%04hx,%s", layout_checksum(layout), layout);
|
||||||
return (out);
|
return (out);
|
||||||
}
|
}
|
||||||
@@ -81,7 +101,8 @@ layout_append(struct layout_cell *lc, char *buf, size_t len)
|
|||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
if (lc == NULL)
|
||||||
|
return (0);
|
||||||
if (lc->wp != NULL) {
|
if (lc->wp != NULL) {
|
||||||
tmplen = xsnprintf(tmp, sizeof tmp, "%ux%u,%u,%u,%u",
|
tmplen = xsnprintf(tmp, sizeof tmp, "%ux%u,%u,%u,%u",
|
||||||
lc->sx, lc->sy, lc->xoff, lc->yoff, lc->wp->id);
|
lc->sx, lc->sy, lc->xoff, lc->yoff, lc->wp->id);
|
||||||
@@ -109,6 +130,7 @@ layout_append(struct layout_cell *lc, char *buf, size_t len)
|
|||||||
}
|
}
|
||||||
buf[strlen(buf) - 1] = brackets[0];
|
buf[strlen(buf) - 1] = brackets[0];
|
||||||
break;
|
break;
|
||||||
|
case LAYOUT_FLOATING:
|
||||||
case LAYOUT_WINDOWPANE:
|
case LAYOUT_WINDOWPANE:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -125,6 +147,7 @@ layout_check(struct layout_cell *lc)
|
|||||||
|
|
||||||
switch (lc->type) {
|
switch (lc->type) {
|
||||||
case LAYOUT_WINDOWPANE:
|
case LAYOUT_WINDOWPANE:
|
||||||
|
case LAYOUT_FLOATING:
|
||||||
break;
|
break;
|
||||||
case LAYOUT_LEFTRIGHT:
|
case LAYOUT_LEFTRIGHT:
|
||||||
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
||||||
@@ -156,7 +179,7 @@ layout_check(struct layout_cell *lc)
|
|||||||
int
|
int
|
||||||
layout_parse(struct window *w, const char *layout, char **cause)
|
layout_parse(struct window *w, const char *layout, char **cause)
|
||||||
{
|
{
|
||||||
struct layout_cell *lc, *lcchild;
|
struct layout_cell *lcchild, *tiled_lc = NULL, *floating_lc = NULL;
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
u_int npanes, ncells, sx = 0, sy = 0;
|
u_int npanes, ncells, sx = 0, sy = 0;
|
||||||
u_short csum;
|
u_short csum;
|
||||||
@@ -173,11 +196,16 @@ layout_parse(struct window *w, const char *layout, char **cause)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Build the layout. */
|
/* Build the layout. */
|
||||||
lc = layout_construct(NULL, &layout);
|
if (layout_construct(NULL, &layout, &tiled_lc, &floating_lc) != 0) {
|
||||||
if (lc == NULL) {
|
|
||||||
*cause = xstrdup("invalid layout");
|
*cause = xstrdup("invalid layout");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
if (tiled_lc == NULL) {
|
||||||
|
/* A stub layout cell for an empty window. */
|
||||||
|
tiled_lc = layout_create_cell(NULL);
|
||||||
|
tiled_lc->type = LAYOUT_LEFTRIGHT;
|
||||||
|
layout_set_size(tiled_lc, w->sx, w->sy, 0, 0);
|
||||||
|
}
|
||||||
if (*layout != '\0') {
|
if (*layout != '\0') {
|
||||||
*cause = xstrdup("invalid layout");
|
*cause = xstrdup("invalid layout");
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -186,8 +214,10 @@ layout_parse(struct window *w, const char *layout, char **cause)
|
|||||||
/* Check this window will fit into the layout. */
|
/* Check this window will fit into the layout. */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
npanes = window_count_panes(w);
|
npanes = window_count_panes(w);
|
||||||
ncells = layout_count_cells(lc);
|
ncells = layout_count_cells(tiled_lc);
|
||||||
|
ncells += layout_count_cells(floating_lc);
|
||||||
if (npanes > ncells) {
|
if (npanes > ncells) {
|
||||||
|
/* Modify this to open a new pane */
|
||||||
xasprintf(cause, "have %u panes but need %u", npanes,
|
xasprintf(cause, "have %u panes but need %u", npanes,
|
||||||
ncells);
|
ncells);
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -195,9 +225,17 @@ layout_parse(struct window *w, const char *layout, char **cause)
|
|||||||
if (npanes == ncells)
|
if (npanes == ncells)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Fewer panes than cells - close the bottom right. */
|
/*
|
||||||
lcchild = layout_find_bottomright(lc);
|
* Fewer panes than cells - close floating panes first
|
||||||
layout_destroy_cell(w, lcchild, &lc);
|
* then close the bottom right until.
|
||||||
|
*/
|
||||||
|
if (floating_lc && ! TAILQ_EMPTY(&floating_lc->cells)) {
|
||||||
|
lcchild = TAILQ_FIRST(&floating_lc->cells);
|
||||||
|
layout_destroy_cell(w, lcchild, &floating_lc);
|
||||||
|
} else {
|
||||||
|
lcchild = layout_find_bottomright(tiled_lc);
|
||||||
|
layout_destroy_cell(w, lcchild, &tiled_lc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -205,85 +243,112 @@ layout_parse(struct window *w, const char *layout, char **cause)
|
|||||||
* an incorrect top cell size - if it is larger than the top child then
|
* an incorrect top cell size - if it is larger than the top child then
|
||||||
* correct that (if this is still wrong the check code will catch it).
|
* correct that (if this is still wrong the check code will catch it).
|
||||||
*/
|
*/
|
||||||
switch (lc->type) {
|
|
||||||
|
switch (tiled_lc->type) {
|
||||||
case LAYOUT_WINDOWPANE:
|
case LAYOUT_WINDOWPANE:
|
||||||
break;
|
break;
|
||||||
case LAYOUT_LEFTRIGHT:
|
case LAYOUT_LEFTRIGHT:
|
||||||
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
TAILQ_FOREACH(lcchild, &tiled_lc->cells, entry) {
|
||||||
sy = lcchild->sy + 1;
|
sy = lcchild->sy + 1;
|
||||||
sx += lcchild->sx + 1;
|
sx += lcchild->sx + 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LAYOUT_TOPBOTTOM:
|
case LAYOUT_TOPBOTTOM:
|
||||||
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
TAILQ_FOREACH(lcchild, &tiled_lc->cells, entry) {
|
||||||
sx = lcchild->sx + 1;
|
sx = lcchild->sx + 1;
|
||||||
sy += lcchild->sy + 1;
|
sy += lcchild->sy + 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case LAYOUT_FLOATING:
|
||||||
|
*cause = xstrdup("invalid layout");
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
if (lc->type != LAYOUT_WINDOWPANE && (lc->sx != sx || lc->sy != sy)) {
|
if (tiled_lc->type != LAYOUT_WINDOWPANE &&
|
||||||
log_debug("fix layout %u,%u to %u,%u", lc->sx, lc->sy, sx,sy);
|
(tiled_lc->sx != sx || tiled_lc->sy != sy)) {
|
||||||
layout_print_cell(lc, __func__, 0);
|
log_debug("fix layout %u,%u to %u,%u", tiled_lc->sx,
|
||||||
lc->sx = sx - 1; lc->sy = sy - 1;
|
tiled_lc->sy, sx,sy);
|
||||||
|
layout_print_cell(tiled_lc, __func__, 0);
|
||||||
|
tiled_lc->sx = sx - 1; tiled_lc->sy = sy - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the new layout. */
|
/* Check the new layout. */
|
||||||
if (!layout_check(lc)) {
|
if (!layout_check(tiled_lc)) {
|
||||||
*cause = xstrdup("size mismatch after applying layout");
|
*cause = xstrdup("size mismatch after applying layout");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resize to the layout size. */
|
/* Resize window to the layout size. */
|
||||||
window_resize(w, lc->sx, lc->sy, -1, -1);
|
if (sx != 0 && sy != 0)
|
||||||
|
window_resize(w, tiled_lc->sx, tiled_lc->sy, -1, -1);
|
||||||
|
|
||||||
/* Destroy the old layout and swap to the new. */
|
/* Destroy the old layout and swap to the new. */
|
||||||
layout_free_cell(w->layout_root);
|
layout_free_cell(w->layout_root);
|
||||||
w->layout_root = lc;
|
w->layout_root = tiled_lc;
|
||||||
|
|
||||||
/* Assign the panes into the cells. */
|
/* Assign the panes into the cells. */
|
||||||
wp = TAILQ_FIRST(&w->panes);
|
wp = TAILQ_FIRST(&w->panes);
|
||||||
layout_assign(&wp, lc);
|
layout_assign(&wp, tiled_lc, 0);
|
||||||
|
layout_assign(&wp, floating_lc, 1);
|
||||||
|
|
||||||
|
/* Fix z_indexes. */
|
||||||
|
while (!TAILQ_EMPTY(&w->z_index)) {
|
||||||
|
wp = TAILQ_FIRST(&w->z_index);
|
||||||
|
TAILQ_REMOVE(&w->z_index, wp, zentry);
|
||||||
|
}
|
||||||
|
layout_fix_zindexes(w, floating_lc);
|
||||||
|
layout_fix_zindexes(w, tiled_lc);
|
||||||
|
|
||||||
/* Update pane offsets and sizes. */
|
/* Update pane offsets and sizes. */
|
||||||
layout_fix_offsets(w);
|
layout_fix_offsets(w);
|
||||||
layout_fix_panes(w, NULL);
|
layout_fix_panes(w, NULL);
|
||||||
recalculate_sizes();
|
recalculate_sizes();
|
||||||
|
|
||||||
layout_print_cell(lc, __func__, 0);
|
layout_print_cell(tiled_lc, __func__, 0);
|
||||||
|
layout_print_cell(floating_lc, __func__, 0);
|
||||||
|
|
||||||
|
/* Free the floating layout cell, no longer needed. */
|
||||||
|
layout_free_cell(floating_lc);
|
||||||
|
|
||||||
notify_window("window-layout-changed", w);
|
notify_window("window-layout-changed", w);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
layout_free_cell(lc);
|
layout_free_cell(tiled_lc);
|
||||||
|
layout_free_cell(floating_lc);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assign panes into cells. */
|
/* Assign panes into cells. */
|
||||||
static void
|
static void
|
||||||
layout_assign(struct window_pane **wp, struct layout_cell *lc)
|
layout_assign(struct window_pane **wp, struct layout_cell *lc, int floating)
|
||||||
{
|
{
|
||||||
struct layout_cell *lcchild;
|
struct layout_cell *lcchild;
|
||||||
|
|
||||||
|
if (lc == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (lc->type) {
|
switch (lc->type) {
|
||||||
case LAYOUT_WINDOWPANE:
|
case LAYOUT_WINDOWPANE:
|
||||||
layout_make_leaf(lc, *wp);
|
layout_make_leaf(lc, *wp);
|
||||||
|
if (floating) {
|
||||||
|
(*wp)->flags |= PANE_FLOATING;
|
||||||
|
}
|
||||||
*wp = TAILQ_NEXT(*wp, entry);
|
*wp = TAILQ_NEXT(*wp, entry);
|
||||||
return;
|
return;
|
||||||
case LAYOUT_LEFTRIGHT:
|
case LAYOUT_LEFTRIGHT:
|
||||||
case LAYOUT_TOPBOTTOM:
|
case LAYOUT_TOPBOTTOM:
|
||||||
|
case LAYOUT_FLOATING:
|
||||||
TAILQ_FOREACH(lcchild, &lc->cells, entry)
|
TAILQ_FOREACH(lcchild, &lc->cells, entry)
|
||||||
layout_assign(wp, lcchild);
|
layout_assign(wp, lcchild, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Construct a cell from all or part of a layout tree. */
|
|
||||||
static struct layout_cell *
|
static struct layout_cell *
|
||||||
layout_construct(struct layout_cell *lcparent, const char **layout)
|
layout_construct_cell(struct layout_cell *lcparent, const char **layout)
|
||||||
{
|
{
|
||||||
struct layout_cell *lc, *lcchild;
|
struct layout_cell *lc;
|
||||||
u_int sx, sy, xoff, yoff;
|
u_int sx, sy, xoff, yoff;
|
||||||
const char *saved;
|
const char *saved;
|
||||||
|
|
||||||
@@ -324,17 +389,42 @@ layout_construct(struct layout_cell *lcparent, const char **layout)
|
|||||||
lc->xoff = xoff;
|
lc->xoff = xoff;
|
||||||
lc->yoff = yoff;
|
lc->yoff = yoff;
|
||||||
|
|
||||||
|
return (lc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Given a character string layout, recursively construct cells.
|
||||||
|
* Possible return values:
|
||||||
|
* lc LAYOUT_WINDOWPANE, no children
|
||||||
|
* lc LAYOUT_LEFTRIGHT or LAYOUT_TOPBOTTOM, with children
|
||||||
|
* floating_lc LAYOUT_FLOATING, with children
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
layout_construct(struct layout_cell *lcparent, const char **layout,
|
||||||
|
struct layout_cell **lc, struct layout_cell **floating_lc)
|
||||||
|
{
|
||||||
|
struct layout_cell *lcchild, *saved_lc;
|
||||||
|
|
||||||
|
*lc = layout_construct_cell(lcparent, layout);
|
||||||
|
|
||||||
switch (**layout) {
|
switch (**layout) {
|
||||||
case ',':
|
case ',':
|
||||||
case '}':
|
case '}':
|
||||||
case ']':
|
case ']':
|
||||||
|
case '>':
|
||||||
case '\0':
|
case '\0':
|
||||||
return (lc);
|
return (0);
|
||||||
case '{':
|
case '{':
|
||||||
lc->type = LAYOUT_LEFTRIGHT;
|
(*lc)->type = LAYOUT_LEFTRIGHT;
|
||||||
break;
|
break;
|
||||||
case '[':
|
case '[':
|
||||||
lc->type = LAYOUT_TOPBOTTOM;
|
(*lc)->type = LAYOUT_TOPBOTTOM;
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
saved_lc = *lc;
|
||||||
|
*lc = layout_create_cell(lcparent);
|
||||||
|
(*lc)->type = LAYOUT_FLOATING;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -342,13 +432,12 @@ layout_construct(struct layout_cell *lcparent, const char **layout)
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
(*layout)++;
|
(*layout)++;
|
||||||
lcchild = layout_construct(lc, layout);
|
if (layout_construct(*lc, layout, &lcchild, floating_lc) != 0)
|
||||||
if (lcchild == NULL)
|
|
||||||
goto fail;
|
goto fail;
|
||||||
TAILQ_INSERT_TAIL(&lc->cells, lcchild, entry);
|
TAILQ_INSERT_TAIL(&(*lc)->cells, lcchild, entry);
|
||||||
} while (**layout == ',');
|
} while (**layout == ',');
|
||||||
|
|
||||||
switch (lc->type) {
|
switch ((*lc)->type) {
|
||||||
case LAYOUT_LEFTRIGHT:
|
case LAYOUT_LEFTRIGHT:
|
||||||
if (**layout != '}')
|
if (**layout != '}')
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -357,14 +446,21 @@ layout_construct(struct layout_cell *lcparent, const char **layout)
|
|||||||
if (**layout != ']')
|
if (**layout != ']')
|
||||||
goto fail;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
|
case LAYOUT_FLOATING:
|
||||||
|
if (**layout != '>')
|
||||||
|
goto fail;
|
||||||
|
*floating_lc = *lc;
|
||||||
|
*lc = saved_lc;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
(*layout)++;
|
(*layout)++;
|
||||||
|
|
||||||
return (lc);
|
return (0);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
layout_free_cell(lc);
|
layout_free_cell(*lc);
|
||||||
return (NULL);
|
layout_free_cell(*floating_lc);
|
||||||
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|||||||
78
layout.c
78
layout.c
@@ -83,9 +83,24 @@ layout_free_cell(struct layout_cell *lc)
|
|||||||
layout_free_cell(lcchild);
|
layout_free_cell(lcchild);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case LAYOUT_FLOATING:
|
||||||
|
/* A Floating layout cell is only used temporarily
|
||||||
|
* while select-layout constructs a layout.
|
||||||
|
* Cleave the children from the temp layout, then
|
||||||
|
* free temp floating layout cell. Each floating
|
||||||
|
* pane has stub layout.
|
||||||
|
*/
|
||||||
|
while (!TAILQ_EMPTY(&lc->cells)) {
|
||||||
|
lcchild = TAILQ_FIRST(&lc->cells);
|
||||||
|
TAILQ_REMOVE(&lc->cells, lcchild, entry);
|
||||||
|
lcchild->parent = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case LAYOUT_WINDOWPANE:
|
case LAYOUT_WINDOWPANE:
|
||||||
if (lc->wp != NULL)
|
if (lc->wp != NULL) {
|
||||||
|
lc->wp->layout_cell->parent = NULL;
|
||||||
lc->wp->layout_cell = NULL;
|
lc->wp->layout_cell = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,6 +113,9 @@ layout_print_cell(struct layout_cell *lc, const char *hdr, u_int n)
|
|||||||
struct layout_cell *lcchild;
|
struct layout_cell *lcchild;
|
||||||
const char *type;
|
const char *type;
|
||||||
|
|
||||||
|
if (lc == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (lc->type) {
|
switch (lc->type) {
|
||||||
case LAYOUT_LEFTRIGHT:
|
case LAYOUT_LEFTRIGHT:
|
||||||
type = "LEFTRIGHT";
|
type = "LEFTRIGHT";
|
||||||
@@ -105,6 +123,9 @@ layout_print_cell(struct layout_cell *lc, const char *hdr, u_int n)
|
|||||||
case LAYOUT_TOPBOTTOM:
|
case LAYOUT_TOPBOTTOM:
|
||||||
type = "TOPBOTTOM";
|
type = "TOPBOTTOM";
|
||||||
break;
|
break;
|
||||||
|
case LAYOUT_FLOATING:
|
||||||
|
type = "FLOATING";
|
||||||
|
break;
|
||||||
case LAYOUT_WINDOWPANE:
|
case LAYOUT_WINDOWPANE:
|
||||||
type = "WINDOWPANE";
|
type = "WINDOWPANE";
|
||||||
break;
|
break;
|
||||||
@@ -118,6 +139,7 @@ layout_print_cell(struct layout_cell *lc, const char *hdr, u_int n)
|
|||||||
switch (lc->type) {
|
switch (lc->type) {
|
||||||
case LAYOUT_LEFTRIGHT:
|
case LAYOUT_LEFTRIGHT:
|
||||||
case LAYOUT_TOPBOTTOM:
|
case LAYOUT_TOPBOTTOM:
|
||||||
|
case LAYOUT_FLOATING:
|
||||||
TAILQ_FOREACH(lcchild, &lc->cells, entry)
|
TAILQ_FOREACH(lcchild, &lc->cells, entry)
|
||||||
layout_print_cell(lcchild, hdr, n + 1);
|
layout_print_cell(lcchild, hdr, n + 1);
|
||||||
break;
|
break;
|
||||||
@@ -153,6 +175,7 @@ layout_search_by_border(struct layout_cell *lc, u_int x, u_int y)
|
|||||||
return (last);
|
return (last);
|
||||||
break;
|
break;
|
||||||
case LAYOUT_WINDOWPANE:
|
case LAYOUT_WINDOWPANE:
|
||||||
|
case LAYOUT_FLOATING:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,6 +221,29 @@ layout_make_node(struct layout_cell *lc, enum layout_type type)
|
|||||||
lc->wp = NULL;
|
lc->wp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
layout_fix_zindexes(struct window *w, struct layout_cell *lc)
|
||||||
|
{
|
||||||
|
struct layout_cell *lcchild;
|
||||||
|
|
||||||
|
if (lc == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (lc->type) {
|
||||||
|
case LAYOUT_WINDOWPANE:
|
||||||
|
TAILQ_INSERT_TAIL(&w->z_index, lc->wp, zentry);
|
||||||
|
break;
|
||||||
|
case LAYOUT_LEFTRIGHT:
|
||||||
|
case LAYOUT_TOPBOTTOM:
|
||||||
|
case LAYOUT_FLOATING:
|
||||||
|
TAILQ_FOREACH(lcchild, &lc->cells, entry)
|
||||||
|
layout_fix_zindexes(w, lcchild);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
fatalx("bad layout type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Fix cell offsets for a child cell. */
|
/* Fix cell offsets for a child cell. */
|
||||||
static void
|
static void
|
||||||
layout_fix_offsets1(struct layout_cell *lc)
|
layout_fix_offsets1(struct layout_cell *lc)
|
||||||
@@ -307,7 +353,8 @@ layout_fix_panes(struct window *w, struct window_pane *skip)
|
|||||||
sx = lc->sx;
|
sx = lc->sx;
|
||||||
sy = lc->sy;
|
sy = lc->sy;
|
||||||
|
|
||||||
if (layout_add_horizontal_border(w, lc, status)) {
|
if (~wp->flags & PANE_FLOATING &&
|
||||||
|
layout_add_horizontal_border(w, lc, status)) {
|
||||||
if (status == PANE_STATUS_TOP)
|
if (status == PANE_STATUS_TOP)
|
||||||
wp->yoff++;
|
wp->yoff++;
|
||||||
sy--;
|
sy--;
|
||||||
@@ -353,6 +400,7 @@ layout_count_cells(struct layout_cell *lc)
|
|||||||
return (1);
|
return (1);
|
||||||
case LAYOUT_LEFTRIGHT:
|
case LAYOUT_LEFTRIGHT:
|
||||||
case LAYOUT_TOPBOTTOM:
|
case LAYOUT_TOPBOTTOM:
|
||||||
|
case LAYOUT_FLOATING:
|
||||||
count = 0;
|
count = 0;
|
||||||
TAILQ_FOREACH(lcchild, &lc->cells, entry)
|
TAILQ_FOREACH(lcchild, &lc->cells, entry)
|
||||||
count += layout_count_cells(lcchild);
|
count += layout_count_cells(lcchild);
|
||||||
@@ -462,7 +510,7 @@ layout_resize_adjust(struct window *w, struct layout_cell *lc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Destroy a cell and redistribute the space. */
|
/* Destroy a cell and redistribute the space in tiled cells. */
|
||||||
void
|
void
|
||||||
layout_destroy_cell(struct window *w, struct layout_cell *lc,
|
layout_destroy_cell(struct window *w, struct layout_cell *lc,
|
||||||
struct layout_cell **lcroot)
|
struct layout_cell **lcroot)
|
||||||
@@ -470,17 +518,21 @@ layout_destroy_cell(struct window *w, struct layout_cell *lc,
|
|||||||
struct layout_cell *lcother, *lcparent;
|
struct layout_cell *lcother, *lcparent;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If no parent, this is the last pane so window close is imminent and
|
* If no parent, this is either a floating pane or the last
|
||||||
* there is no need to resize anything.
|
* pane so window close is imminent and there is no need to
|
||||||
|
* resize anything.
|
||||||
*/
|
*/
|
||||||
lcparent = lc->parent;
|
lcparent = lc->parent;
|
||||||
if (lcparent == NULL) {
|
if (lcparent == NULL) {
|
||||||
layout_free_cell(lc);
|
if (lc->wp != NULL && ~lc->wp->flags & PANE_FLOATING)
|
||||||
*lcroot = NULL;
|
*lcroot = NULL;
|
||||||
|
/* xxx if (lc->type == LAYOUT_WINDOWPANE) */
|
||||||
|
layout_free_cell(lc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Merge the space into the previous or next cell. */
|
/* In tiled layouts, merge the space into the previous or next cell. */
|
||||||
|
if (lcparent->type != LAYOUT_FLOATING) {
|
||||||
if (lc == TAILQ_FIRST(&lcparent->cells))
|
if (lc == TAILQ_FIRST(&lcparent->cells))
|
||||||
lcother = TAILQ_NEXT(lc, entry);
|
lcother = TAILQ_NEXT(lc, entry);
|
||||||
else
|
else
|
||||||
@@ -489,17 +541,21 @@ layout_destroy_cell(struct window *w, struct layout_cell *lc,
|
|||||||
layout_resize_adjust(w, lcother, lcparent->type, lc->sx + 1);
|
layout_resize_adjust(w, lcother, lcparent->type, lc->sx + 1);
|
||||||
else if (lcother != NULL)
|
else if (lcother != NULL)
|
||||||
layout_resize_adjust(w, lcother, lcparent->type, lc->sy + 1);
|
layout_resize_adjust(w, lcother, lcparent->type, lc->sy + 1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Remove this from the parent's list. */
|
/* Remove this from the parent's list. */
|
||||||
TAILQ_REMOVE(&lcparent->cells, lc, entry);
|
TAILQ_REMOVE(&lcparent->cells, lc, entry);
|
||||||
layout_free_cell(lc);
|
layout_free_cell(lc);
|
||||||
|
|
||||||
|
if (lcparent->type == LAYOUT_FLOATING)
|
||||||
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the parent now has one cell, remove the parent from the tree and
|
* In tiled layouts, if the parent now has one cell, remove
|
||||||
* replace it by that cell.
|
* the parent from the tree and replace it by that cell.
|
||||||
*/
|
*/
|
||||||
lc = TAILQ_FIRST(&lcparent->cells);
|
lc = TAILQ_FIRST(&lcparent->cells);
|
||||||
if (TAILQ_NEXT(lc, entry) == NULL) {
|
if (lc != NULL && TAILQ_NEXT(lc, entry) == NULL) {
|
||||||
TAILQ_REMOVE(&lcparent->cells, lc, entry);
|
TAILQ_REMOVE(&lcparent->cells, lc, entry);
|
||||||
|
|
||||||
lc->parent = lcparent->parent;
|
lc->parent = lcparent->parent;
|
||||||
@@ -741,7 +797,7 @@ layout_resize_pane_shrink(struct window *w, struct layout_cell *lc,
|
|||||||
return (size);
|
return (size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assign window pane to newly split cell. */
|
/* Assign window pane to new cell. */
|
||||||
void
|
void
|
||||||
layout_assign_pane(struct layout_cell *lc, struct window_pane *wp,
|
layout_assign_pane(struct layout_cell *lc, struct window_pane *wp,
|
||||||
int do_not_resize)
|
int do_not_resize)
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ screen_redraw_two_panes(struct window *w, enum layout_type *type)
|
|||||||
u_int count = 0;
|
u_int count = 0;
|
||||||
|
|
||||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||||
if (wp->layout_cell == NULL)
|
if (wp->flags & PANE_FLOATING || wp->layout_cell == NULL)
|
||||||
continue;
|
continue;
|
||||||
count++;
|
count++;
|
||||||
if (count > 2 || wp->layout_cell->parent == NULL)
|
if (count > 2 || wp->layout_cell->parent == NULL)
|
||||||
@@ -146,7 +146,7 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
|
|||||||
sb_w = wp->scrollbar_style.width + wp->scrollbar_style.pad;
|
sb_w = wp->scrollbar_style.width + wp->scrollbar_style.pad;
|
||||||
|
|
||||||
/* Floating pane borders */
|
/* Floating pane borders */
|
||||||
if (wp->layout_cell == NULL) {
|
if (wp->flags & PANE_FLOATING) {
|
||||||
if ((int)px == wp->xoff - 1 &&
|
if ((int)px == wp->xoff - 1 &&
|
||||||
(int)py >= wp->yoff - 1 && (int)py <= wp->yoff + (int)wp->sy)
|
(int)py >= wp->yoff - 1 && (int)py <= wp->yoff + (int)wp->sy)
|
||||||
return (SCREEN_REDRAW_BORDER_LEFT);
|
return (SCREEN_REDRAW_BORDER_LEFT);
|
||||||
@@ -247,7 +247,7 @@ screen_redraw_cell_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
|
|||||||
u_int sy = w->sy;
|
u_int sy = w->sy;
|
||||||
int sb_w, floating = 0;
|
int sb_w, floating = 0;
|
||||||
|
|
||||||
floating = (wp->layout_cell == NULL);
|
floating = (wp->flags & PANE_FLOATING);
|
||||||
|
|
||||||
sb_w = wp->scrollbar_style.width +
|
sb_w = wp->scrollbar_style.width +
|
||||||
wp->scrollbar_style.pad;
|
wp->scrollbar_style.pad;
|
||||||
@@ -268,7 +268,7 @@ screen_redraw_cell_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
|
|||||||
/* If checking a cell from a tiled pane, ignore floating panes
|
/* If checking a cell from a tiled pane, ignore floating panes
|
||||||
* because 2 side-by-side or top-bottom panes share a border
|
* because 2 side-by-side or top-bottom panes share a border
|
||||||
* which is used to do split colouring. Essentially treat all
|
* which is used to do split colouring. Essentially treat all
|
||||||
* non-floating panes as being in a single z-index.
|
* tiled panes as being in a single z-index.
|
||||||
*
|
*
|
||||||
* If checking a cell from a floating pane, only check cells
|
* If checking a cell from a floating pane, only check cells
|
||||||
* from this floating pane, again, essentially only this z-index.
|
* from this floating pane, again, essentially only this z-index.
|
||||||
@@ -277,8 +277,7 @@ screen_redraw_cell_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
|
|||||||
/* Check all the panes. */
|
/* Check all the panes. */
|
||||||
TAILQ_FOREACH(wp2, &w->z_index, zentry) {
|
TAILQ_FOREACH(wp2, &w->z_index, zentry) {
|
||||||
if (!window_pane_visible(wp2) ||
|
if (!window_pane_visible(wp2) ||
|
||||||
(wp->flags & PANE_MINIMISED) ||
|
(!floating && (wp2->flags & PANE_FLOATING)) ||
|
||||||
(!floating && wp2->layout_cell==NULL) ||
|
|
||||||
(floating && wp2 != wp))
|
(floating && wp2 != wp))
|
||||||
continue;
|
continue;
|
||||||
if (((int)px < wp2->xoff - 1 ||
|
if (((int)px < wp2->xoff - 1 ||
|
||||||
@@ -317,7 +316,7 @@ screen_redraw_type_of_cell(struct screen_redraw_ctx *ctx,
|
|||||||
if (px > sx || py > sy)
|
if (px > sx || py > sy)
|
||||||
return (CELL_OUTSIDE);
|
return (CELL_OUTSIDE);
|
||||||
|
|
||||||
floating = (wp->layout_cell == NULL);
|
floating = (wp->flags & PANE_FLOATING);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Construct a bitmask of whether the cells to the left (bit 8), right,
|
* Construct a bitmask of whether the cells to the left (bit 8), right,
|
||||||
@@ -433,7 +432,7 @@ screen_redraw_check_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py,
|
|||||||
TAILQ_FOREACH(wp, &w->z_index, zentry) {
|
TAILQ_FOREACH(wp, &w->z_index, zentry) {
|
||||||
sb_w = wp->scrollbar_style.width +
|
sb_w = wp->scrollbar_style.width +
|
||||||
wp->scrollbar_style.pad;
|
wp->scrollbar_style.pad;
|
||||||
if (! (wp->flags & PANE_MINIMISED) &&
|
if (~wp->flags & PANE_MINIMISED &&
|
||||||
((int)px >= wp->xoff - 1 &&
|
((int)px >= wp->xoff - 1 &&
|
||||||
(int)px <= wp->xoff + (int)wp->sx + sb_w) &&
|
(int)px <= wp->xoff + (int)wp->sx + sb_w) &&
|
||||||
((int)py >= wp->yoff - 1 &&
|
((int)py >= wp->yoff - 1 &&
|
||||||
@@ -453,14 +452,13 @@ screen_redraw_check_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py,
|
|||||||
* top-bottom windows with a shared border and half the shared
|
* top-bottom windows with a shared border and half the shared
|
||||||
* border is the active border.
|
* border is the active border.
|
||||||
*/
|
*/
|
||||||
if (wp->layout_cell != NULL)
|
if (~wp->flags & PANE_FLOATING)
|
||||||
tiled_only = 1;
|
tiled_only = 1;
|
||||||
|
|
||||||
do { /* Loop until back to wp==start.*/
|
do { /* Loop until back to wp==start.*/
|
||||||
|
|
||||||
if (!window_pane_visible(wp) ||
|
if (!window_pane_visible(wp) ||
|
||||||
(wp->flags & PANE_MINIMISED) ||
|
(tiled_only && (wp->flags & PANE_FLOATING)))
|
||||||
(tiled_only && wp->layout_cell==NULL))
|
|
||||||
goto next;
|
goto next;
|
||||||
*wpp = wp;
|
*wpp = wp;
|
||||||
|
|
||||||
@@ -1067,13 +1065,13 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, u_int px,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
tb = wp->yoff-1;
|
tb = wp->yoff - 1;
|
||||||
bb = wp->yoff + wp->sy;
|
bb = wp->yoff + wp->sy + 1;
|
||||||
if (!found_self ||
|
if (!found_self ||
|
||||||
(wp->flags & PANE_MINIMISED) ||
|
!window_pane_visible(wp) ||
|
||||||
py < tb ||
|
py < tb ||
|
||||||
(wp->layout_cell == NULL && py > bb) ||
|
((wp->flags & PANE_FLOATING) && py > bb) ||
|
||||||
(wp->layout_cell != NULL && py >= bb))
|
(~(wp->flags & PANE_FLOATING) && py >= bb))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Are scrollbars enabled? */
|
/* Are scrollbars enabled? */
|
||||||
@@ -1283,6 +1281,9 @@ screen_redraw_draw_pane_scrollbar(struct screen_redraw_ctx *ctx,
|
|||||||
else
|
else
|
||||||
sb_x = xoff + wp->sx - ox;
|
sb_x = xoff + wp->sx - ox;
|
||||||
|
|
||||||
|
if (ctx->statustop)
|
||||||
|
sb_y += ctx->statuslines;
|
||||||
|
|
||||||
if (slider_h < 1)
|
if (slider_h < 1)
|
||||||
slider_h = 1;
|
slider_h = 1;
|
||||||
if (slider_y >= sb_h)
|
if (slider_y >= sb_h)
|
||||||
@@ -1312,6 +1313,9 @@ screen_redraw_draw_scrollbar(struct screen_redraw_ctx *ctx,
|
|||||||
int yoff = wp->yoff;
|
int yoff = wp->yoff;
|
||||||
struct visible_ranges *vr;
|
struct visible_ranges *vr;
|
||||||
|
|
||||||
|
if (ctx->statustop)
|
||||||
|
sy += ctx->statuslines;
|
||||||
|
|
||||||
/* Set up style for slider. */
|
/* Set up style for slider. */
|
||||||
gc = sb_style->gc;
|
gc = sb_style->gc;
|
||||||
memcpy(&slgc, &gc, sizeof slgc);
|
memcpy(&slgc, &gc, sizeof slgc);
|
||||||
|
|||||||
@@ -139,10 +139,9 @@ screen_write_set_client_cb(struct tty_ctx *ttyctx, struct client *c)
|
|||||||
|
|
||||||
if (c->session->curw->window != wp->window)
|
if (c->session->curw->window != wp->window)
|
||||||
return (0);
|
return (0);
|
||||||
/*
|
|
||||||
if (wp->layout_cell == NULL)
|
if (wp->layout_cell == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
*/
|
|
||||||
if (wp->flags & (PANE_REDRAW|PANE_DROP))
|
if (wp->flags & (PANE_REDRAW|PANE_DROP))
|
||||||
return (-1);
|
return (-1);
|
||||||
if (c->flags & CLIENT_REDRAWPANES) {
|
if (c->flags & CLIENT_REDRAWPANES) {
|
||||||
|
|||||||
@@ -643,9 +643,9 @@ server_client_check_mouse_in_pane(struct window_pane *wp, u_int px, u_int py,
|
|||||||
return (SCROLLBAR_SLIDER);
|
return (SCROLLBAR_SLIDER);
|
||||||
} else /* py > sl_bottom */
|
} else /* py > sl_bottom */
|
||||||
return (SCROLLBAR_DOWN);
|
return (SCROLLBAR_DOWN);
|
||||||
} else if (wp->layout_cell == NULL &&
|
} else if (wp->flags & PANE_FLOATING &&
|
||||||
((int)px == wp->xoff - 1 ||
|
((int)px == wp->xoff - 1 ||
|
||||||
(int)py == wp->yoff -1 ||
|
(int)py == wp->yoff - 1 ||
|
||||||
(int)py == wp->yoff + (int)wp->sy)) {
|
(int)py == wp->yoff + (int)wp->sy)) {
|
||||||
/* Floating pane left, bottom or top border. */
|
/* Floating pane left, bottom or top border. */
|
||||||
return (BORDER);
|
return (BORDER);
|
||||||
@@ -664,7 +664,7 @@ server_client_check_mouse_in_pane(struct window_pane *wp, u_int px, u_int py,
|
|||||||
if ((int)py >= fwp->yoff - 1 && py <= fwp->yoff + fwp->sy) {
|
if ((int)py >= fwp->yoff - 1 && py <= fwp->yoff + fwp->sy) {
|
||||||
if (px == bdr_right)
|
if (px == bdr_right)
|
||||||
break;
|
break;
|
||||||
if (wp->layout_cell == NULL) {
|
if (wp->flags & PANE_FLOATING) {
|
||||||
/* Floating pane, check if left border. */
|
/* Floating pane, check if left border. */
|
||||||
bdr_left = fwp->xoff - 1;
|
bdr_left = fwp->xoff - 1;
|
||||||
if (px == bdr_left)
|
if (px == bdr_left)
|
||||||
@@ -675,7 +675,7 @@ server_client_check_mouse_in_pane(struct window_pane *wp, u_int px, u_int py,
|
|||||||
bdr_bottom = fwp->yoff + fwp->sy;
|
bdr_bottom = fwp->yoff + fwp->sy;
|
||||||
if (py == bdr_bottom)
|
if (py == bdr_bottom)
|
||||||
break;
|
break;
|
||||||
if (wp->layout_cell == NULL) {
|
if (wp->flags & PANE_FLOATING) {
|
||||||
/* Floating pane, check if top border. */
|
/* Floating pane, check if top border. */
|
||||||
bdr_top = fwp->yoff - 1;
|
bdr_top = fwp->yoff - 1;
|
||||||
if (py == bdr_top)
|
if (py == bdr_top)
|
||||||
@@ -885,6 +885,11 @@ have_event:
|
|||||||
px = px + m->ox;
|
px = px + m->ox;
|
||||||
py = py + m->oy;
|
py = py + m->oy;
|
||||||
|
|
||||||
|
if (type == DRAG &&
|
||||||
|
c->tty.mouse_wp != NULL)
|
||||||
|
/* Use pane from last mouse event. */
|
||||||
|
wp = c->tty.mouse_wp;
|
||||||
|
else
|
||||||
/* Try inside the pane. */
|
/* Try inside the pane. */
|
||||||
wp = window_get_active_at(w, px, py);
|
wp = window_get_active_at(w, px, py);
|
||||||
if (wp == NULL)
|
if (wp == NULL)
|
||||||
|
|||||||
14
spawn.c
14
spawn.c
@@ -265,14 +265,7 @@ spawn_pane(struct spawn_context *sc, char **cause)
|
|||||||
new_wp->flags &= ~(PANE_STATUSREADY|PANE_STATUSDRAWN);
|
new_wp->flags &= ~(PANE_STATUSREADY|PANE_STATUSDRAWN);
|
||||||
} else if (sc->lc == NULL) {
|
} else if (sc->lc == NULL) {
|
||||||
new_wp = window_add_pane(w, NULL, hlimit, sc->flags);
|
new_wp = window_add_pane(w, NULL, hlimit, sc->flags);
|
||||||
if (sc->flags & SPAWN_FLOATING) {
|
|
||||||
new_wp->flags |= PANE_FLOATING;
|
|
||||||
window_pane_resize(new_wp, sc->sx, sc->sy);
|
|
||||||
new_wp->xoff = sc->xoff;
|
|
||||||
new_wp->yoff = sc->yoff;
|
|
||||||
} else {
|
|
||||||
layout_init(w, new_wp);
|
layout_init(w, new_wp);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
new_wp = window_add_pane(w, sc->wp0, hlimit, sc->flags);
|
new_wp = window_add_pane(w, sc->wp0, hlimit, sc->flags);
|
||||||
if (sc->flags & SPAWN_ZOOM)
|
if (sc->flags & SPAWN_ZOOM)
|
||||||
@@ -281,6 +274,13 @@ spawn_pane(struct spawn_context *sc, char **cause)
|
|||||||
layout_assign_pane(sc->lc, new_wp, 0);
|
layout_assign_pane(sc->lc, new_wp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If window currently zoomed, window_set_active_pane calls
|
||||||
|
* window_unzoom which it copies back the saved_layout_cell.
|
||||||
|
*/
|
||||||
|
if (w->flags & WINDOW_ZOOMED)
|
||||||
|
new_wp->saved_layout_cell = new_wp->layout_cell;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now we have a pane with nothing running in it ready for the new
|
* Now we have a pane with nothing running in it ready for the new
|
||||||
* process. Work out the command and arguments and store the working
|
* process. Work out the command and arguments and store the working
|
||||||
|
|||||||
9
tmux.h
9
tmux.h
@@ -1176,6 +1176,7 @@ struct window_pane {
|
|||||||
int yoff;
|
int yoff;
|
||||||
|
|
||||||
int flags;
|
int flags;
|
||||||
|
int saved_flags;
|
||||||
#define PANE_REDRAW 0x1
|
#define PANE_REDRAW 0x1
|
||||||
#define PANE_DROP 0x2
|
#define PANE_DROP 0x2
|
||||||
#define PANE_FOCUSED 0x4
|
#define PANE_FOCUSED 0x4
|
||||||
@@ -1365,6 +1366,7 @@ TAILQ_HEAD(winlink_stack, winlink);
|
|||||||
enum layout_type {
|
enum layout_type {
|
||||||
LAYOUT_LEFTRIGHT,
|
LAYOUT_LEFTRIGHT,
|
||||||
LAYOUT_TOPBOTTOM,
|
LAYOUT_TOPBOTTOM,
|
||||||
|
LAYOUT_FLOATING,
|
||||||
LAYOUT_WINDOWPANE
|
LAYOUT_WINDOWPANE
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2226,10 +2228,6 @@ struct spawn_context {
|
|||||||
|
|
||||||
struct window_pane *wp0;
|
struct window_pane *wp0;
|
||||||
struct layout_cell *lc;
|
struct layout_cell *lc;
|
||||||
u_int xoff;
|
|
||||||
u_int yoff;
|
|
||||||
u_int sx;
|
|
||||||
u_int sy;
|
|
||||||
|
|
||||||
const char *name;
|
const char *name;
|
||||||
char **argv;
|
char **argv;
|
||||||
@@ -3350,6 +3348,7 @@ void layout_set_size(struct layout_cell *, u_int, u_int, u_int,
|
|||||||
u_int);
|
u_int);
|
||||||
void layout_make_leaf(struct layout_cell *, struct window_pane *);
|
void layout_make_leaf(struct layout_cell *, struct window_pane *);
|
||||||
void layout_make_node(struct layout_cell *, enum layout_type);
|
void layout_make_node(struct layout_cell *, enum layout_type);
|
||||||
|
void layout_fix_zindexes(struct window *, struct layout_cell *);
|
||||||
void layout_fix_offsets(struct window *);
|
void layout_fix_offsets(struct window *);
|
||||||
void layout_fix_panes(struct window *, struct window_pane *);
|
void layout_fix_panes(struct window *, struct window_pane *);
|
||||||
void layout_resize_adjust(struct window *, struct layout_cell *,
|
void layout_resize_adjust(struct window *, struct layout_cell *,
|
||||||
@@ -3370,7 +3369,7 @@ int layout_spread_cell(struct window *, struct layout_cell *);
|
|||||||
void layout_spread_out(struct window_pane *);
|
void layout_spread_out(struct window_pane *);
|
||||||
|
|
||||||
/* layout-custom.c */
|
/* layout-custom.c */
|
||||||
char *layout_dump(struct layout_cell *);
|
char *layout_dump(struct window *, struct layout_cell *);
|
||||||
int layout_parse(struct window *, const char *, char **);
|
int layout_parse(struct window *, const char *, char **);
|
||||||
|
|
||||||
/* layout-set.c */
|
/* layout-set.c */
|
||||||
|
|||||||
4
tty.c
4
tty.c
@@ -1382,7 +1382,7 @@ tty_draw_pane(struct tty *tty, const struct tty_ctx *ctx, u_int py)
|
|||||||
|
|
||||||
if (!ctx->bigger) {
|
if (!ctx->bigger) {
|
||||||
if (wp) {
|
if (wp) {
|
||||||
vr = screen_redraw_get_visible_ranges(wp, 0, py, nx);
|
vr = screen_redraw_get_visible_ranges(wp, 0, ctx->yoff + py, nx);
|
||||||
for (r=0; r < vr->used; r++) {
|
for (r=0; r < vr->used; r++) {
|
||||||
if (vr->nx[r] == 0)
|
if (vr->nx[r] == 0)
|
||||||
continue;
|
continue;
|
||||||
@@ -2048,7 +2048,7 @@ tty_is_obscured(const struct tty_ctx *ctx)
|
|||||||
found_self = 1;
|
found_self = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (found_self && wp->layout_cell == NULL &&
|
if (found_self && wp->flags & PANE_FLOATING &&
|
||||||
! (wp->flags & PANE_MINIMISED) &&
|
! (wp->flags & PANE_MINIMISED) &&
|
||||||
((wp->yoff >= base_wp->yoff &&
|
((wp->yoff >= base_wp->yoff &&
|
||||||
wp->yoff <= base_wp->yoff + (int)base_wp->sy) ||
|
wp->yoff <= base_wp->yoff + (int)base_wp->sy) ||
|
||||||
|
|||||||
43
window.c
43
window.c
@@ -525,6 +525,8 @@ window_set_active_pane(struct window *w, struct window_pane *wp, int notify)
|
|||||||
|
|
||||||
if (wp == w->active)
|
if (wp == w->active)
|
||||||
return (0);
|
return (0);
|
||||||
|
if (w->flags & WINDOW_ZOOMED)
|
||||||
|
window_unzoom(w, 1);
|
||||||
lastwp = w->active;
|
lastwp = w->active;
|
||||||
|
|
||||||
window_pane_stack_remove(&w->last_panes, wp);
|
window_pane_stack_remove(&w->last_panes, wp);
|
||||||
@@ -589,9 +591,9 @@ window_redraw_active_switch(struct window *w, struct window_pane *wp)
|
|||||||
|
|
||||||
/* If you want tiled planes to be able to bury
|
/* If you want tiled planes to be able to bury
|
||||||
* floating planes then do this regardless of
|
* floating planes then do this regardless of
|
||||||
* wp->layout_cell==NULL or not. A new option?
|
* wp->flags & PANE_FLOATING or not. A new option?
|
||||||
*/
|
*/
|
||||||
if (wp->layout_cell == NULL) {
|
if (wp->flags & PANE_FLOATING) {
|
||||||
TAILQ_REMOVE(&w->z_index, wp, zentry);
|
TAILQ_REMOVE(&w->z_index, wp, zentry);
|
||||||
TAILQ_INSERT_HEAD(&w->z_index, wp, zentry);
|
TAILQ_INSERT_HEAD(&w->z_index, wp, zentry);
|
||||||
wp->flags |= PANE_REDRAW;
|
wp->flags |= PANE_REDRAW;
|
||||||
@@ -614,7 +616,7 @@ window_get_active_at(struct window *w, u_int x, u_int y)
|
|||||||
if (!window_pane_visible(wp))
|
if (!window_pane_visible(wp))
|
||||||
continue;
|
continue;
|
||||||
window_pane_full_size_offset(wp, &xoff, &yoff, &sx, &sy);
|
window_pane_full_size_offset(wp, &xoff, &yoff, &sx, &sy);
|
||||||
if (wp->layout_cell != NULL) {
|
if (~wp->flags & PANE_FLOATING) {
|
||||||
/* Tiled, select up to including bottom or
|
/* Tiled, select up to including bottom or
|
||||||
right border. */
|
right border. */
|
||||||
if ((int)x < xoff || x > xoff + sx)
|
if ((int)x < xoff || x > xoff + sx)
|
||||||
@@ -688,12 +690,24 @@ window_zoom(struct window_pane *wp)
|
|||||||
if (w->flags & WINDOW_ZOOMED)
|
if (w->flags & WINDOW_ZOOMED)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
if (window_count_panes(w) == 1)
|
|
||||||
return (-1);
|
|
||||||
|
|
||||||
if (w->active != wp)
|
if (w->active != wp)
|
||||||
window_set_active_pane(w, wp, 1);
|
window_set_active_pane(w, wp, 1);
|
||||||
|
|
||||||
|
/* Bring pane above other tiled panes and minimise floating panes. */
|
||||||
|
TAILQ_FOREACH(wp1, &w->z_index, zentry) {
|
||||||
|
if (wp1 == wp) {
|
||||||
|
wp1->saved_flags |= (wp1->flags & PANE_MINIMISED);
|
||||||
|
wp1->flags &= ~PANE_MINIMISED;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (wp1->flags & PANE_FLOATING) {
|
||||||
|
wp1->saved_flags |= (wp1->flags & PANE_MINIMISED);
|
||||||
|
wp1->flags |= PANE_MINIMISED;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
TAILQ_FOREACH(wp1, &w->panes, entry) {
|
TAILQ_FOREACH(wp1, &w->panes, entry) {
|
||||||
wp1->saved_layout_cell = wp1->layout_cell;
|
wp1->saved_layout_cell = wp1->layout_cell;
|
||||||
wp1->layout_cell = NULL;
|
wp1->layout_cell = NULL;
|
||||||
@@ -720,6 +734,14 @@ window_unzoom(struct window *w, int notify)
|
|||||||
w->layout_root = w->saved_layout_root;
|
w->layout_root = w->saved_layout_root;
|
||||||
w->saved_layout_root = NULL;
|
w->saved_layout_root = NULL;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(wp, &w->z_index, zentry) {
|
||||||
|
if (wp->flags & PANE_FLOATING) {
|
||||||
|
wp->flags &= ~PANE_MINIMISED | (wp->saved_flags & PANE_MINIMISED);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||||
wp->layout_cell = wp->saved_layout_cell;
|
wp->layout_cell = wp->saved_layout_cell;
|
||||||
wp->saved_layout_cell = NULL;
|
wp->saved_layout_cell = NULL;
|
||||||
@@ -781,9 +803,10 @@ window_add_pane(struct window *w, struct window_pane *other, u_int hlimit,
|
|||||||
TAILQ_INSERT_AFTER(&w->panes, other, wp, entry);
|
TAILQ_INSERT_AFTER(&w->panes, other, wp, entry);
|
||||||
}
|
}
|
||||||
/* Floating panes are created above tiled planes. */
|
/* Floating panes are created above tiled planes. */
|
||||||
if (flags & (SPAWN_FLOATING))
|
if (flags & SPAWN_FLOATING) {
|
||||||
|
wp->flags |= PANE_FLOATING;
|
||||||
TAILQ_INSERT_HEAD(&w->z_index, wp, zentry);
|
TAILQ_INSERT_HEAD(&w->z_index, wp, zentry);
|
||||||
else
|
} else
|
||||||
TAILQ_INSERT_TAIL(&w->z_index, wp, zentry);
|
TAILQ_INSERT_TAIL(&w->z_index, wp, zentry);
|
||||||
return (wp);
|
return (wp);
|
||||||
}
|
}
|
||||||
@@ -1311,8 +1334,10 @@ window_pane_key(struct window_pane *wp, struct client *c, struct session *s,
|
|||||||
int
|
int
|
||||||
window_pane_visible(struct window_pane *wp)
|
window_pane_visible(struct window_pane *wp)
|
||||||
{
|
{
|
||||||
if (~wp->window->flags & WINDOW_ZOOMED)
|
if (~wp->window->flags & WINDOW_ZOOMED &&
|
||||||
|
~wp->flags & PANE_MINIMISED)
|
||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
return (wp == wp->window->active);
|
return (wp == wp->window->active);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user