mirror of
https://github.com/tmux/tmux.git
synced 2026-06-20 17:25:57 +00:00
Add functions to work out cell neighbours, and to remove a tiled cell.
From Dane Jensen.
This commit is contained in:
113
layout.c
113
layout.c
@@ -588,12 +588,57 @@ layout_resize_adjust(struct window *w, struct layout_cell *lc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find and return the nearest neighbour to a cell in a specific direction. */
|
||||||
|
static struct layout_cell *
|
||||||
|
layout_cell_get_neighbour_direction(struct layout_cell *lc, int direction)
|
||||||
|
{
|
||||||
|
struct layout_cell *lcn = lc;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (direction)
|
||||||
|
lcn = TAILQ_NEXT(lcn, entry);
|
||||||
|
else
|
||||||
|
lcn = TAILQ_PREV(lcn, layout_cells, entry);
|
||||||
|
|
||||||
|
if (lcn == NULL ||
|
||||||
|
layout_cell_is_tiled(lcn) ||
|
||||||
|
layout_cell_has_tiled_child(lcn))
|
||||||
|
return (lcn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find and return the nearest neighbour. Prefers cells "after" the specified
|
||||||
|
* cell. This behavior defines how cell dimensions are redistributed when a cell
|
||||||
|
* is hidden/shown and floated/tiled.
|
||||||
|
*/
|
||||||
|
struct layout_cell *
|
||||||
|
layout_cell_get_neighbour(struct layout_cell *lc)
|
||||||
|
{
|
||||||
|
struct layout_cell *lcother, *lcparent = lc->parent;
|
||||||
|
int direction = 1;
|
||||||
|
|
||||||
|
if (lcparent == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
if (lc == TAILQ_LAST(&lcparent->cells, layout_cells))
|
||||||
|
direction = !direction;
|
||||||
|
|
||||||
|
lcother = layout_cell_get_neighbour_direction(lc, direction);
|
||||||
|
if (lcother == NULL)
|
||||||
|
lcother = layout_cell_get_neighbour_direction(lc, !direction);
|
||||||
|
|
||||||
|
return (lcother);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Destroy a cell and redistribute the space. */
|
/* Destroy a cell and redistribute the space. */
|
||||||
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)
|
||||||
{
|
{
|
||||||
struct layout_cell *lcother = NULL, *lcparent;
|
struct layout_cell *lcother = NULL, *lcparent;
|
||||||
|
int change;
|
||||||
|
|
||||||
/* If no parent, this is the last pane in a window. */
|
/* If no parent, this is the last pane in a window. */
|
||||||
lcparent = lc->parent;
|
lcparent = lc->parent;
|
||||||
@@ -604,27 +649,27 @@ layout_destroy_cell(struct window *w, struct layout_cell *lc,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (~lc->flags & LAYOUT_CELL_FLOATING) {
|
if (!layout_cell_is_tiled(lc)) {
|
||||||
/* Merge the space into the previous or next cell. */
|
TAILQ_REMOVE(&lcparent->cells, lc, entry);
|
||||||
if (lc == TAILQ_FIRST(&lcparent->cells))
|
layout_free_cell(lc);
|
||||||
lcother = TAILQ_NEXT(lc, entry);
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
lcother = layout_cell_get_neighbour(lc);
|
||||||
|
if (lcother != NULL) {
|
||||||
|
if (lcparent->type == LAYOUT_LEFTRIGHT)
|
||||||
|
change = lc->sx + 1;
|
||||||
else
|
else
|
||||||
lcother = TAILQ_PREV(lc, layout_cells, entry);
|
change = lc->sy + 1;
|
||||||
}
|
layout_resize_adjust(w, lcother, lcparent->type, change);
|
||||||
if (lcother != NULL && (~lcother->flags & LAYOUT_CELL_FLOATING)) {
|
} else
|
||||||
if (lcparent->type == LAYOUT_LEFTRIGHT) {
|
layout_remove_tile(w, lcparent);
|
||||||
layout_resize_adjust(w, lcother, lcparent->type,
|
|
||||||
lc->sx + 1);
|
|
||||||
} else {
|
|
||||||
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);
|
||||||
|
|
||||||
|
out:
|
||||||
/*
|
/*
|
||||||
* If the parent now has one cell, remove the parent from the tree and
|
* If the parent now has one cell, remove the parent from the tree and
|
||||||
* replace it by that cell.
|
* replace it by that cell.
|
||||||
@@ -1564,3 +1609,39 @@ layout_get_floating_cell(struct cmdq_item *item, struct args *args,
|
|||||||
lcnew = layout_floating_pane(w, sx, sy, ox, oy);
|
lcnew = layout_floating_pane(w, sx, sy, ox, oy);
|
||||||
return (lcnew);
|
return (lcnew);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Removes a cell from the tiled layout by giving the cell's space to the
|
||||||
|
* nearest neighbour.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
layout_remove_tile(struct window *w, struct layout_cell *lc)
|
||||||
|
{
|
||||||
|
struct layout_cell *lcneighbour, *lcparent;
|
||||||
|
enum layout_type type;
|
||||||
|
int change;
|
||||||
|
|
||||||
|
if (lc->flags & LAYOUT_CELL_FLOATING)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
lcneighbour = layout_cell_get_neighbour(lc);
|
||||||
|
if (lcneighbour == NULL) {
|
||||||
|
if (lc->parent != NULL)
|
||||||
|
layout_remove_tile(w, lc->parent);
|
||||||
|
} else if ((lcparent = lcneighbour->parent) != NULL) {
|
||||||
|
type = lcparent->type;
|
||||||
|
/*
|
||||||
|
* Adding the size of the layout cell plus its border to the
|
||||||
|
* neighbour.
|
||||||
|
*/
|
||||||
|
if (type == LAYOUT_TOPBOTTOM)
|
||||||
|
change = lc->sy + 1;
|
||||||
|
else
|
||||||
|
change = lc->sx + 1;
|
||||||
|
layout_resize_adjust(w, lcneighbour, type, change);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zeroing out the cell geometry until the cell is retiled. */
|
||||||
|
layout_set_size(lc, 0, 0, 0, 0);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|||||||
6
tmux.h
6
tmux.h
@@ -3504,6 +3504,7 @@ 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 *,
|
||||||
enum layout_type, int);
|
enum layout_type, int);
|
||||||
|
struct layout_cell *layout_cell_get_neighbour(struct layout_cell *);
|
||||||
void layout_init(struct window *, struct window_pane *);
|
void layout_init(struct window *, struct window_pane *);
|
||||||
void layout_free(struct window *);
|
void layout_free(struct window *);
|
||||||
void layout_resize(struct window *, u_int, u_int);
|
void layout_resize(struct window *, u_int, u_int);
|
||||||
@@ -3524,10 +3525,11 @@ struct layout_cell *layout_floating_pane(struct window *, u_int, u_int, int,
|
|||||||
void layout_close_pane(struct window_pane *);
|
void layout_close_pane(struct window_pane *);
|
||||||
int layout_spread_cell(struct window *, struct layout_cell *);
|
int layout_spread_cell(struct window *, struct layout_cell *);
|
||||||
void layout_spread_out(struct window_pane *);
|
void layout_spread_out(struct window_pane *);
|
||||||
struct layout_cell *layout_get_floating_cell(struct cmdq_item *, struct args *,
|
|
||||||
struct window *, struct window_pane *, char **);
|
|
||||||
struct layout_cell *layout_get_tiled_cell(struct cmdq_item *, struct args *,
|
struct layout_cell *layout_get_tiled_cell(struct cmdq_item *, struct args *,
|
||||||
struct window *, struct window_pane *, int, char **);
|
struct window *, struct window_pane *, int, char **);
|
||||||
|
struct layout_cell *layout_get_floating_cell(struct cmdq_item *, struct args *,
|
||||||
|
struct window *, struct window_pane *, char **);
|
||||||
|
int layout_remove_tile(struct window *, struct layout_cell *);
|
||||||
|
|
||||||
/* layout-custom.c */
|
/* layout-custom.c */
|
||||||
char *layout_dump(struct window *, struct layout_cell *);
|
char *layout_dump(struct window *, struct layout_cell *);
|
||||||
|
|||||||
Reference in New Issue
Block a user