]> git.lizzy.rs Git - bspwm.git/blob - restore.c
New setting: persistent_monitors
[bspwm.git] / restore.c
1 /* Copyright (c) 2012-2014, Bastien Dejean
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice, this
8  *    list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright notice,
10  *    this list of conditions and the following disclaimer in the documentation
11  *    and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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
20  * ON 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  * The views and conclusions contained in the software and documentation are those
25  * of the authors and should not be interpreted as representing official policies,
26  * either expressed or implied, of the FreeBSD Project.
27  */
28
29 #include <ctype.h>
30 #include <string.h>
31 #include "bspwm.h"
32 #include "desktop.h"
33 #include "ewmh.h"
34 #include "history.h"
35 #include "monitor.h"
36 #include "query.h"
37 #include "stack.h"
38 #include "tree.h"
39 #include "settings.h"
40 #include "restore.h"
41
42 void restore_tree(char *file_path)
43 {
44         if (file_path == NULL)
45                 return;
46
47         FILE *snapshot = fopen(file_path, "r");
48         if (snapshot == NULL) {
49                 warn("Restore tree: can't open file\n");
50                 return;
51         }
52
53         PUTS("restore tree");
54
55         char line[MAXLEN];
56         char name[MAXLEN];
57         coordinates_t loc;
58         monitor_t *m = NULL;
59         desktop_t *d = NULL;
60         node_t *n = NULL;
61         unsigned int level, last_level = 0;
62
63         while (fgets(line, sizeof(line), snapshot) != NULL) {
64                 unsigned int len = strlen(line);
65                 level = 0;
66
67                 while (level < len && isspace(line[level]))
68                         level++;
69
70                 if (level == 0) {
71                         int x, y, top, right, bottom, left;
72                         unsigned int w, h;
73                         char end = 0;
74                         name[0] = '\0';
75                         sscanf(line + level, "%s %ux%u%i%i %i,%i,%i,%i %c", name, &w, &h, &x, &y,
76                                &top, &right, &bottom, &left, &end);
77                         m = find_monitor(name);
78                         if (m == NULL)
79                                 continue;
80                         m->rectangle = (xcb_rectangle_t) {x, y, w, h};
81                         m->top_padding = top;
82                         m->right_padding = right;
83                         m->bottom_padding = bottom;
84                         m->left_padding = left;
85                         if (end != 0)
86                                 mon = m;
87                 } else if (level == 1) {
88                         if (m == NULL)
89                                 continue;
90                         int wg, top, right, bottom, left;
91                         unsigned int bw;
92                         char floating, layout = 0, end = 0;
93                         name[0] = '\0';
94                         loc.desktop = NULL;
95                         sscanf(line + level, "%s %u %i %i,%i,%i,%i %c %c %c", name,
96                                &bw, &wg, &top, &right, &bottom, &left, &layout, &floating, &end);
97                         locate_desktop(name, &loc);
98                         d = loc.desktop;
99                         if (d == NULL)
100                                 continue;
101                         d->border_width = bw;
102                         d->window_gap = wg;
103                         d->top_padding = top;
104                         d->right_padding = right;
105                         d->bottom_padding = bottom;
106                         d->left_padding = left;
107                         if (layout == 'M')
108                                 d->layout = LAYOUT_MONOCLE;
109                         else if (layout == 'T')
110                                 d->layout = LAYOUT_TILED;
111                         d->floating = (floating == '-' ? false : true);
112                         if (end != 0)
113                                 m->desk = d;
114                 } else {
115                         if (m == NULL || d == NULL)
116                                 continue;
117                         node_t *birth = make_node();
118                         if (level == 2) {
119                                 empty_desktop(d);
120                                 d->root = birth;
121                         } else if (n != NULL) {
122                                 if (level > last_level) {
123                                         n->first_child = birth;
124                                 } else {
125                                         do {
126                                                 n = n->parent;
127                                         } while (n != NULL && n->second_child != NULL);
128                                         if (n == NULL)
129                                                 continue;
130                                         n->second_child = birth;
131                                 }
132                                 birth->parent = n;
133                         }
134                         n = birth;
135                         char br;
136                         if (isupper(line[level])) {
137                                 char st;
138                                 sscanf(line + level, "%c %c %lf", &st, &br, &n->split_ratio);
139                                 if (st == 'H')
140                                         n->split_type = TYPE_HORIZONTAL;
141                                 else if (st == 'V')
142                                         n->split_type = TYPE_VERTICAL;
143                         } else {
144                                 client_t *c = make_client(XCB_NONE, d->border_width);
145                                 num_clients++;
146                                 char floating, pseudo_tiled, fullscreen, urgent, locked, sticky, private, sd, sm, end = 0;
147                                 sscanf(line + level, "%c %s %s %X %u %hux%hu%hi%hi %c %c%c%c%c%c%c%c%c %c", &br,
148                                        c->class_name, c->instance_name, &c->window, &c->border_width,
149                                        &c->floating_rectangle.width, &c->floating_rectangle.height,
150                                        &c->floating_rectangle.x, &c->floating_rectangle.y,
151                                        &sd, &floating, &pseudo_tiled, &fullscreen, &urgent,
152                                        &locked, &sticky, &private, &sm, &end);
153                                 c->floating = (floating == '-' ? false : true);
154                                 c->pseudo_tiled = (pseudo_tiled == '-' ? false : true);
155                                 c->fullscreen = (fullscreen == '-' ? false : true);
156                                 c->urgent = (urgent == '-' ? false : true);
157                                 c->locked = (locked == '-' ? false : true);
158                                 c->sticky = (sticky == '-' ? false : true);
159                                 c->private = (private == '-' ? false : true);
160                                 n->split_mode = (sm == '-' ? MODE_AUTOMATIC : MODE_MANUAL);
161                                 if (sd == 'U')
162                                         n->split_dir = DIR_UP;
163                                 else if (sd == 'R')
164                                         n->split_dir = DIR_RIGHT;
165                                 else if (sd == 'D')
166                                         n->split_dir = DIR_DOWN;
167                                 else if (sd == 'L')
168                                         n->split_dir = DIR_LEFT;
169                                 n->client = c;
170                                 if (end != 0)
171                                         d->focus = n;
172                                 if (c->sticky)
173                                         m->num_sticky++;
174                         }
175                         if (br == 'a')
176                                 n->birth_rotation = 90;
177                         else if (br == 'c')
178                                 n->birth_rotation = 270;
179                         else if (br == 'm')
180                                 n->birth_rotation = 0;
181                 }
182                 last_level = level;
183         }
184
185         fclose(snapshot);
186
187         for (monitor_t *m = mon_head; m != NULL; m = m->next)
188                 for (desktop_t *d = m->desk_head; d != NULL; d = d->next)
189                         for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) {
190                                 uint32_t values[] = {CLIENT_EVENT_MASK | (focus_follows_pointer ? XCB_EVENT_MASK_ENTER_WINDOW : 0)};
191                                 xcb_change_window_attributes(dpy, n->client->window, XCB_CW_EVENT_MASK, values);
192                                 if (n->client->floating) {
193                                         n->vacant = true;
194                                         update_vacant_state(n->parent);
195                                 }
196                                 if (n->client->private)
197                                         update_privacy_level(n, true);
198                         }
199         ewmh_update_current_desktop();
200 }
201
202 void restore_history(char *file_path)
203 {
204         if (file_path == NULL)
205                 return;
206
207         FILE *snapshot = fopen(file_path, "r");
208         if (snapshot == NULL) {
209                 warn("Restore history: can't open '%s'.\n", file_path);
210                 return;
211         }
212
213         PUTS("restore history");
214
215         char line[MAXLEN];
216         char mnm[SMALEN];
217         char dnm[SMALEN];
218         xcb_window_t win;
219
220         while (fgets(line, sizeof(line), snapshot) != NULL) {
221                 if (sscanf(line, "%s %s %X", mnm, dnm, &win) == 3) {
222                         coordinates_t loc;
223                         if (win != XCB_NONE && !locate_window(win, &loc)) {
224                                 warn("Can't locate window 0x%X.\n", win);
225                                 continue;
226                         }
227                         node_t *n = (win == XCB_NONE ? NULL : loc.node);
228                         if (!locate_desktop(dnm, &loc)) {
229                                 warn("Can't locate desktop '%s'.\n", dnm);
230                                 continue;
231                         }
232                         desktop_t *d = loc.desktop;
233                         if (!locate_monitor(mnm, &loc)) {
234                                 warn("Can't locate monitor '%s'.\n", mnm);
235                                 continue;
236                         }
237                         monitor_t *m = loc.monitor;
238                         history_add(m, d, n);
239                 } else {
240                         warn("Can't parse history entry: '%s'\n", line);
241                 }
242         }
243
244         fclose(snapshot);
245 }
246
247 void restore_stack(char *file_path)
248 {
249         if (file_path == NULL)
250                 return;
251
252         FILE *snapshot = fopen(file_path, "r");
253         if (snapshot == NULL) {
254                 warn("Restore stack: can't open '%s'.\n", file_path);
255                 return;
256         }
257
258         PUTS("restore stack");
259
260         char line[MAXLEN];
261         xcb_window_t win;
262
263         while (fgets(line, sizeof(line), snapshot) != NULL) {
264                 if (sscanf(line, "%X", &win) == 1) {
265                         coordinates_t loc;
266                         if (locate_window(win, &loc))
267                                 stack_insert_after(stack_tail, loc.node);
268                         else
269                                 warn("Can't locate window 0x%X.\n", win);
270                 } else {
271                         warn("Can't parse stack entry: '%s'\n", line);
272                 }
273         }
274
275         fclose(snapshot);
276 }