]> git.lizzy.rs Git - bspwm.git/blob - stack.c
Set proper socket option to allow fast restart
[bspwm.git] / stack.c
1 /* * Copyright (c) 2012-2013 Bastien Dejean
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification,
5  * are permitted provided that the following conditions are met:
6  *
7  *  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *  * Redistributions in binary form must reproduce the above copyright notice,
10  * this list of conditions and the following disclaimer in the documentation and/or
11  * other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
17  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include <stdlib.h>
26 #include "bspwm.h"
27 #include "window.h"
28 #include "stack.h"
29
30 stacking_list_t *make_stack(node_t *n)
31 {
32     stacking_list_t *s = malloc(sizeof(stacking_list_t));
33     s->node = n;
34     s->prev = s->next = NULL;
35     return s;
36 }
37
38 void stack_insert_after(stacking_list_t *a, node_t *n)
39 {
40     stacking_list_t *s = make_stack(n);
41     if (a == NULL) {
42         stack_head = stack_tail = s;
43     } else {
44         remove_stack_node(n);
45         stacking_list_t *b = a->next;
46         if (b != NULL)
47             b->prev = s;
48         s->next = b;
49         s->prev = a;
50         a->next = s;
51         if (stack_tail == a)
52             stack_tail = s;
53     }
54 }
55
56 void stack_insert_before(stacking_list_t *a, node_t *n)
57 {
58     stacking_list_t *s = make_stack(n);
59     if (a == NULL) {
60         stack_head = stack_tail = s;
61     } else {
62         remove_stack_node(n);
63         stacking_list_t *b = a->prev;
64         if (b != NULL)
65             b->next = s;
66         s->prev = b;
67         s->next = a;
68         a->prev = s;
69         if (stack_head == a)
70             stack_head = s;
71     }
72 }
73
74 void remove_stack(stacking_list_t *s)
75 {
76     if (s == NULL)
77         return;
78     stacking_list_t *a = s->prev;
79     stacking_list_t *b = s->next;
80     if (a != NULL)
81         a->next = b;
82     if (b != NULL)
83         b->prev = a;
84     if (s == stack_head)
85         stack_head = b;
86     if (s == stack_tail)
87         stack_tail = a;
88     free(s);
89 }
90
91 void remove_stack_node(node_t *n)
92 {
93     for (stacking_list_t *s = stack_head; s != NULL; s = s->next)
94         if (s->node == n) {
95             remove_stack(s);
96             return;
97         }
98 }
99
100 void stack(node_t *n, stack_flavor_t f)
101 {
102     PRINTF("stack %X\n", n->client->window);
103
104     if (stack_head == NULL) {
105         stack_insert_after(NULL, n);
106     } else if (n->client->fullscreen) {
107         if (f == STACK_ABOVE) {
108             stack_insert_after(stack_tail, n);
109             window_raise(n->client->window);
110         }
111     } else {
112         if (f == STACK_ABOVE && n->client->floating && !auto_raise)
113             return;
114         stacking_list_t *latest_tiled = NULL;
115         stacking_list_t *oldest_floating = NULL;
116         for (stacking_list_t *s = (f == STACK_ABOVE ? stack_tail : stack_head); s != NULL; s = (f == STACK_ABOVE ? s->prev : s->next)) {
117             if (s->node != n) {
118                 if (s->node->client->floating == n->client->floating) {
119                     if (f == STACK_ABOVE) {
120                         stack_insert_after(s, n);
121                         window_above(n->client->window, s->node->client->window);
122                     } else {
123                         stack_insert_before(s, n);
124                         window_below(n->client->window, s->node->client->window);
125                     }
126                     return;
127                 } else if ((f != STACK_ABOVE || latest_tiled == NULL) && !s->node->client->floating) {
128                     latest_tiled = s;
129                 } else if ((f == STACK_ABOVE || oldest_floating == NULL) && s->node->client->floating) {
130                     oldest_floating = s;
131                 }
132             }
133         }
134         if (latest_tiled == NULL && oldest_floating == NULL)
135             return;
136         if (n->client->floating) {
137             if (latest_tiled == NULL)
138                 return;
139             window_above(n->client->window, latest_tiled->node->client->window);
140             stack_insert_after(latest_tiled, n);
141         } else {
142             if (oldest_floating == NULL)
143                 return;
144             window_below(n->client->window, oldest_floating->node->client->window);
145             stack_insert_before(oldest_floating, n);
146         }
147     }
148 }