-
Notifications
You must be signed in to change notification settings - Fork 1
/
manage.c
127 lines (104 loc) · 2.72 KB
/
manage.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "extern.h"
/*
* Manage pane (p) in a column (c) after pane (a).
*/
void
manage_pane(struct pane *p, struct column *c, struct pane *a)
{
assert(c != NULL);
assert(p != NULL);
assert(p->next == NULL);
assert(p->prev == NULL);
assert(p->column == NULL);
TRACE("manage_pane: adding %s after %s in column x=%d",
PANE_STR(p), PANE_STR(a), c->x);
resize_add(c, p);
p->column = c;
if (a == NULL) { /* Add to top */
p->next = c->first;
if (c->first)
c->first->prev = p;
p->prev = NULL;
} else { /* Add after 'after' */
assert(a != c->last || a->next == NULL);
p->next = a->next;
p->prev = a;
if (a->next)
a->next->prev = p;
a->next = p;
}
if (p->next == NULL)
c->last = p;
if (p->prev == NULL)
c->first = p;
p->column = c;
c->n++;
assert(c->last != NULL);
assert(c->first != NULL);
assert(p->column == c);
assert(c->n > 0);
assert(p != c->last || p->next == NULL);
assert(p != c->first || p->prev == NULL);
resize_relayout(c);
TRACE_END("add to column done for pane %ld (after %ld)",
PANE_NUMBER(p), PANE_NUMBER(a));
dump_column(c);
}
/*
* Removes a pane (p) from its column.
* Practically the pane will be orphan and not referenced until re-added.
* If focus is not changed, focus stays the same (focus is
* column-agnostic).
*/
void
remove_pane(struct pane *p, int want_resize)
{
struct column *c;
assert(p != NULL);
assert(p->column != NULL);
TRACE_BEGIN("remove_pane: from column begin for pane %ld",
PANE_NUMBER(p));
if (p->column->first == p) {
p->column->first = p->next;
if (p->column->first != NULL)
p->column->first->prev = NULL;
} else {
assert(p->prev != NULL);
p->prev->next = p->next;
}
if (p->column->last == p) {
p->column->last = p->prev;
if (p->column->last != NULL)
p->column->last->next = NULL;
} else {
assert(p->next != NULL);
p->next->prev = p->prev;
}
p->column->n--;
p->next = p->prev = NULL;
assert(p->column->n == 0 || p->column->first != NULL);
assert(p->column->n == 0 || p->column->last != NULL);
assert(p->column->n != 0 || p->column->first == NULL);
assert(p->column->n != 0 || p->column->last == NULL);
assert(p->column->first != p);
assert(p->column->last != p);
assert(p->next == NULL);
assert(p->prev == NULL);
TRACE_END("remove from column done for pane %ld",
PANE_NUMBER(p));
dump_column(p->column);
c = p->column;
p->column = NULL;
/*
* We need to call resize from outside of this function,
* because we might be in middle destroying windows,
* which might no longer have a workable Window pointer.
*/
resize_remove(c, p);
if (want_resize == 1) {
TRACE("remove_pane: want_resize");
resize_relayout(c);
} else {
TRACE("remove_pane: did not want resize");
}
}