-
Notifications
You must be signed in to change notification settings - Fork 2
/
inplacerotate.c
125 lines (112 loc) · 3.03 KB
/
inplacerotate.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
int
isdualstacklayout(Monitor *m)
{
if (m->lt[m->sellt]->arrange != &flextile)
return 0;
int layout = m->ltaxis[LAYOUT];
if (layout < 0)
layout *= -1;
return (
layout == SPLIT_HORIZONTAL_DUAL_STACK ||
layout == SPLIT_HORIZONTAL_DUAL_STACK_FIXED ||
layout == SPLIT_VERTICAL_DUAL_STACK ||
layout == SPLIT_VERTICAL_DUAL_STACK_FIXED
);
}
int
iscenteredlayout(Monitor *m, int n)
{
if (m->lt[m->sellt]->arrange != &flextile)
return 0;
int layout = m->ltaxis[LAYOUT];
if (layout < 0)
layout *= -1;
return (
(layout == SPLIT_CENTERED_VERTICAL && (n - m->nmaster > 1)) ||
layout == SPLIT_CENTERED_VERTICAL_FIXED ||
(layout == SPLIT_CENTERED_HORIZONTAL && (n - m->nmaster > 1)) ||
layout == SPLIT_CENTERED_HORIZONTAL_FIXED ||
layout == FLOATING_MASTER
);
}
void
insertclient(Client *item, Client *insertItem, int after)
{
Client *c;
if (item == NULL || insertItem == NULL || item == insertItem)
return;
detach(insertItem);
if (!after && selmon->clients == item) {
attach(insertItem);
return;
}
if (after) {
c = item;
} else {
for (c = selmon->clients; c; c = c->next) {
if (c->next == item)
break;
}
}
insertItem->next = c->next;
c->next = insertItem;
}
void
inplacerotate(const Arg *arg)
{
Monitor *m = selmon;
if (!m->sel || (m->sel->isfloating && !arg->f))
return;
unsigned int n, selidx = 0, i = 0, tidx, center, dualstack;
Client *c = NULL,
*shead = NULL, *stail = NULL,
*thead = NULL, *ttail = NULL,
*mhead = NULL, *mtail = NULL;
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), ++n);
tidx = m->nmaster + (m->nstack > 0 ? m->nstack : (n - m->nmaster) / 2 + ((n - m->nmaster) % 2 > 0 ? 1 : 0));
// Shift client
for (c = m->clients; c; c = c->next) {
if (ISVISIBLE(c) && !(c->isfloating) && !HIDDEN(c)) {
if (m->sel == c)
selidx = i;
if (i == m->nmaster - 1)
mtail = c;
if (i == m->nmaster)
shead = c;
if (i == tidx - 1)
stail = c;
if (i == tidx)
thead = c;
if (mhead == NULL)
mhead = c;
ttail = c;
i++;
}
}
center = iscenteredlayout(m, n);
dualstack = isdualstacklayout(m);
if ((!center && !dualstack) || (center && n <= m->nmaster + (m->nstack ? m->nstack : 1))) {
if (arg->i < 0 && selidx >= selmon->nmaster) insertclient(ttail, shead, 1);
if (arg->i > 0 && selidx >= selmon->nmaster) insertclient(shead, ttail, 0);
} else {
if (arg->i < 0 && selidx >= selmon->nmaster && selidx < tidx) insertclient(stail, shead, 1);
if (arg->i > 0 && selidx >= selmon->nmaster && selidx < tidx) insertclient(shead, stail, 0);
if (arg->i < 0 && selidx >= tidx) insertclient(ttail, thead, 1);
if (arg->i > 0 && selidx >= tidx) insertclient(thead, ttail, 0);
}
if (arg->i < 0 && selidx < selmon->nmaster) insertclient(mtail, mhead, 1);
if (arg->i > 0 && selidx < selmon->nmaster) insertclient(mhead, mtail, 0);
// Restore focus position
i = 0;
for (c = selmon->clients; c; c = c->next) {
if (!ISVISIBLE(c) || (c->isfloating))
continue;
if (i == selidx) {
focus(c);
break;
}
i++;
}
arrangemon(selmon);
focus(c);
}