]> git.lizzy.rs Git - bspwm.git/blob - restore.c
Fix initial tagging of windows
[bspwm.git] / restore.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 <ctype.h>
26 #include <string.h>
27 #include "bspwm.h"
28 #include "desktop.h"
29 #include "ewmh.h"
30 #include "history.h"
31 #include "monitor.h"
32 #include "window.h"
33 #include "query.h"
34 #include "settings.h"
35 #include "stack.h"
36 #include "tree.h"
37 #include "restore.h"
38
39 void restore_tree(char *file_path)
40 {
41     if (file_path == NULL)
42         return;
43
44     FILE *snapshot = fopen(file_path, "r");
45     if (snapshot == NULL) {
46         warn("Restore tree: can't open file\n");
47         return;
48     }
49
50     PUTS("restore tree");
51
52     char line[MAXLEN];
53     char name[MAXLEN];
54     coordinates_t loc;
55     monitor_t *m = NULL;
56     desktop_t *d = NULL;
57     node_t *n = NULL;
58     num_clients = 0;
59     unsigned int level, last_level = 0;
60
61     while (fgets(line, sizeof(line), snapshot) != NULL) {
62         unsigned int len = strlen(line);
63         level = 0;
64
65         while (level < len && isspace(line[level]))
66             level++;
67
68         if (level == 0) {
69             int x, y, left, right, top, bottom;
70             unsigned int w, h;
71             char end = 0;
72             name[0] = '\0';
73             sscanf(line + level, "%s %ux%u%i%i %i,%i,%i,%i %c", name, &w, &h, &x, &y, &top, &right, &bottom, &left, &end);
74             m = find_monitor(name);
75             if (m == NULL)
76                 continue;
77             m->rectangle = (xcb_rectangle_t) {x, y, w, h};
78             m->top_padding = top;
79             m->right_padding = right;
80             m->bottom_padding = bottom;
81             m->left_padding = left;
82             if (end != 0)
83                 mon = m;
84         } else if (level == 2) {
85             if (m == NULL)
86                 continue;
87             int wg;
88             unsigned int tf, bw;
89             char layout = 0, end = 0;
90             name[0] = '\0';
91             loc.desktop = NULL;
92             sscanf(line + level, "%s %u %i %u %c %c", name, &bw, &wg, &tf, &layout, &end);
93             locate_desktop(name, &loc);
94             d = loc.desktop;
95             if (d == NULL)
96                 continue;
97             d->border_width = bw;
98             d->window_gap = wg;
99             d->tags_field = tf;
100             if (layout == 'M')
101                 d->layout = LAYOUT_MONOCLE;
102             else if (layout == 'T')
103                 d->layout = LAYOUT_TILED;
104             if (end != 0)
105                 m->desk = d;
106
107         } else {
108             if (m == NULL || d == NULL)
109                 continue;
110             node_t *birth = make_node();
111             if (level == 4) {
112                 empty_desktop(d);
113                 d->root = birth;
114             } else if (n != NULL) {
115                 if (level > last_level) {
116                     n->first_child = birth;
117                 } else {
118                     do {
119                         n = n->parent;
120                     } while (n != NULL && n->second_child != NULL);
121                     if (n == NULL)
122                         continue;
123                     n->second_child = birth;
124                 }
125                 birth->parent = n;
126             }
127             n = birth;
128
129             char br;
130             if (isupper(line[level])) {
131                 char st;
132                 sscanf(line + level, "%c %c %lf", &st, &br, &n->split_ratio);
133                 if (st == 'H')
134                     n->split_type = TYPE_HORIZONTAL;
135                 else if (st == 'V')
136                     n->split_type = TYPE_VERTICAL;
137             } else {
138                 client_t *c = make_client(XCB_NONE);
139                 num_clients++;
140                 char floating, transient, fullscreen, urgent, locked, sticky, frame, private, sd, sm, end = 0;
141                 sscanf(line + level, "%c %s %X %u %u %hux%hu%hi%hi %c %c%c%c%c%c%c%c%c%c %c", &br, c->class_name, &c->window, &c->tags_field, &c->border_width, &c->floating_rectangle.width, &c->floating_rectangle.height, &c->floating_rectangle.x, &c->floating_rectangle.y, &sd, &floating, &transient, &fullscreen, &urgent, &locked, &sticky, &frame, &private, &sm, &end);
142                 c->floating = (floating == '-' ? false : true);
143                 c->transient = (transient == '-' ? false : true);
144                 c->fullscreen = (fullscreen == '-' ? false : true);
145                 c->urgent = (urgent == '-' ? false : true);
146                 c->locked = (locked == '-' ? false : true);
147                 c->sticky = (sticky == '-' ? false : true);
148                 c->frame = (frame == '-' ? false : true);
149                 c->private = (private == '-' ? false : true);
150                 n->split_mode = (sm == '-' ? MODE_AUTOMATIC : MODE_MANUAL);
151                 if (sd == 'U')
152                     n->split_dir = DIR_UP;
153                 else if (sd == 'R')
154                     n->split_dir = DIR_RIGHT;
155                 else if (sd == 'D')
156                     n->split_dir = DIR_DOWN;
157                 else if (sd == 'L')
158                     n->split_dir = DIR_LEFT;
159                 n->client = c;
160                 if (end != 0)
161                     d->focus = n;
162                 if (c->sticky)
163                     m->num_sticky++;
164             }
165             if (br == 'a')
166                 n->birth_rotation = 90;
167             else if (br == 'c')
168                 n->birth_rotation = 270;
169             else if (br == 'm')
170                 n->birth_rotation = 0;
171         }
172         last_level = level;
173     }
174
175     fclose(snapshot);
176
177     for (monitor_t *m = mon_head; m != NULL; m = m->next)
178         for (desktop_t *d = m->desk_head; d != NULL; d = d->next)
179             for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) {
180                 uint32_t values[] = {get_event_mask(n->client)};
181                 xcb_change_window_attributes(dpy, n->client->window, XCB_CW_EVENT_MASK, values);
182                 if (n->client->floating || !is_visible(d, n)) {
183                     n->vacant = true;
184                     update_vacant_state(n->parent);
185                 }
186                 if (n->client->private)
187                     update_privacy_level(n, true);
188             }
189     ewmh_update_current_desktop();
190 }
191
192 void restore_history(char *file_path)
193 {
194     if (file_path == NULL)
195         return;
196
197     FILE *snapshot = fopen(file_path, "r");
198     if (snapshot == NULL) {
199         warn("Restore history: can't open '%s'.\n", file_path);
200         return;
201     }
202
203     PUTS("restore history");
204
205     char line[MAXLEN];
206     char mnm[SMALEN];
207     char dnm[SMALEN];
208     xcb_window_t win;
209
210     while (fgets(line, sizeof(line), snapshot) != NULL) {
211         if (sscanf(line, "%s %s %X", mnm, dnm, &win) == 3) {
212             coordinates_t loc;
213             if (win != XCB_NONE && !locate_window(win, &loc)) {
214                 warn("Can't locate window 0x%X.\n", win);
215                 continue;
216             }
217             node_t *n = (win == XCB_NONE ? NULL : loc.node);
218             if (!locate_desktop(dnm, &loc)) {
219                 warn("Can't locate desktop '%s'.\n", dnm);
220                 continue;
221             }
222             desktop_t *d = loc.desktop;
223             if (!locate_monitor(mnm, &loc)) {
224                 warn("Can't locate monitor '%s'.\n", mnm);
225                 continue;
226             }
227             monitor_t *m = loc.monitor;
228             history_add(m, d, n);
229         } else {
230             warn("Can't parse history entry: '%s'\n", line);
231         }
232     }
233
234     fclose(snapshot);
235 }
236
237 void restore_stack(char *file_path)
238 {
239     if (file_path == NULL)
240         return;
241
242     FILE *snapshot = fopen(file_path, "r");
243     if (snapshot == NULL) {
244         warn("Restore stack: can't open '%s'.\n", file_path);
245         return;
246     }
247
248     PUTS("restore stack");
249
250     char line[MAXLEN];
251     xcb_window_t win;
252
253     while (fgets(line, sizeof(line), snapshot) != NULL) {
254         if (sscanf(line, "%X", &win) == 1) {
255             coordinates_t loc;
256             if (locate_window(win, &loc))
257                 stack_insert_after(stack_tail, loc.node);
258             else
259                 warn("Can't locate window 0x%X.\n", win);
260         } else {
261             warn("Can't parse stack entry: '%s'\n", line);
262         }
263     }
264
265     fclose(snapshot);
266 }