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