]> git.lizzy.rs Git - bspwm.git/blob - restore.c
Keep the real wm name on the supporting window
[bspwm.git] / restore.c
1 #include <ctype.h>
2 #include <string.h>
3 #include "types.h"
4 #include "tree.h"
5 #include "settings.h"
6 #include "ewmh.h"
7 #include "bspwm.h"
8 #include "query.h"
9 #include "restore.h"
10
11 void restore_tree(char *file_path)
12 {
13     if (file_path == NULL)
14         return;
15
16     FILE *snapshot = fopen(file_path, "r");
17     if (snapshot == NULL) {
18         warn("Restore: can't open file\n");
19         return;
20     }
21
22     PUTS("restore tree");
23
24     char line[MAXLEN];
25     monitor_t *m = NULL;
26     desktop_t *d = NULL;
27     node_t *n = NULL;
28     num_clients = 0;
29     unsigned int level, last_level = 0;
30     bool aborted = false;
31
32     while (fgets(line, sizeof(line), snapshot) != NULL) {
33         unsigned int len = strlen(line);
34         level = 0;
35         while (level < strlen(line) && isspace(line[level]))
36             level++;
37         if (level == 0) {
38             if (m == NULL)
39                 m = mon_head;
40             else
41                 m = m->next;
42             if (m == NULL) {
43                 aborted = true;
44                 break;
45             }
46             d = NULL;
47             if (len >= 2)
48                 switch (line[len - 2]) {
49                     case '#':
50                         mon = m;
51                         break;
52                     case '~':
53                         last_mon = m;
54                         break;
55                 }
56         } else if (level == 2) {
57             if (d == NULL)
58                 d = m->desk_head;
59             else
60                 d = d->next;
61             if (d == NULL) {
62                 aborted = true;
63                 break;
64             }
65             int i = len - 1;
66             while (i > 0 && !isupper(line[i]))
67                 i--;
68             if (line[i] == 'M')
69                 d->layout = LAYOUT_MONOCLE;
70             else if (line[i] == 'T')
71                 d->layout = LAYOUT_TILED;
72             if (len >= 2)
73                 switch (line[len - 2]) {
74                     case '@':
75                         m->desk = d;
76                         break;
77                     case '~':
78                         m->last_desk = d;
79                         break;
80                 }
81         } else {
82             node_t *birth = make_node();
83             if (level == 4) {
84                 empty_desktop(d);
85                 d->root = birth;
86             } else if (n != NULL) {
87                 if (level > last_level) {
88                     n->first_child = birth;
89                 } else {
90                     do {
91                         n = n->parent;
92                     } while (n != NULL && n->second_child != NULL);
93                     if (n == NULL) {
94                         warn("Restore: malformed file\n");
95                         aborted = true;
96                         break;
97                     }
98                     n->second_child = birth;
99                 }
100                 birth->parent = n;
101             }
102             n = birth;
103
104             char br;
105             if (isupper(line[level])) {
106                 char st;
107                 sscanf(line + level, "%c %c %lf", &st, &br, &n->split_ratio);
108                 if (st == 'H')
109                     n->split_type = TYPE_HORIZONTAL;
110                 else if (st == 'V')
111                     n->split_type = TYPE_VERTICAL;
112             } else {
113                 client_t *c = make_client(XCB_NONE);
114                 num_clients++;
115                 char floating, transient, fullscreen, urgent, locked, split_mode;
116                 sscanf(line + level, "%c %s %X %u %hux%hu%hi%hi %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, &floating, &transient, &fullscreen, &urgent, &locked, &split_mode);
117                 c->floating = (floating == '-' ? false : true);
118                 c->transient = (transient == '-' ? false : true);
119                 c->fullscreen = (fullscreen == '-' ? false : true);
120                 c->urgent = (urgent == '-' ? false : true);
121                 c->locked = (locked == '-' ? false : true);
122                 n->split_mode = (split_mode == '-' ? false : true);
123                 n->client = c;
124                 if (len >= 2 && line[len - 2] == '*')
125                     d->focus = n;
126             }
127             if (br == 'a')
128                 n->birth_rotation = 90;
129             else if (br == 'c')
130                 n->birth_rotation = 270;
131             else if (br == 'm')
132                 n->birth_rotation = 0;
133         }
134         last_level = level;
135     }
136
137     fclose(snapshot);
138
139     if (!aborted) {
140         for (monitor_t *m = mon_head; m != NULL; m = m->next)
141             for (desktop_t *d = m->desk_head; d != NULL; d = d->next)
142                 for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) {
143                     uint32_t values[] = {(focus_follows_pointer ? CLIENT_EVENT_MASK_FFP : CLIENT_EVENT_MASK)};
144                     xcb_change_window_attributes(dpy, n->client->window, XCB_CW_EVENT_MASK, values);
145                     if (n->client->floating) {
146                         n->vacant = true;
147                         update_vacant_state(n->parent);
148                     }
149                 }
150         ewmh_update_current_desktop();
151     }
152 }
153
154 void restore_history(char *file_path)
155 {
156     if (file_path == NULL)
157         return;
158
159     FILE *snapshot = fopen(file_path, "r");
160     if (snapshot == NULL) {
161         warn("Restore history: can't open file\n");
162         return;
163     }
164
165     PUTS("restore history");
166
167     char line[MAXLEN];
168     desktop_t *d = NULL;
169     unsigned int level;
170
171     while (fgets(line, sizeof(line), snapshot) != NULL) {
172         unsigned int i = strlen(line) - 1;
173         while (i > 0 && isspace(line[i]))
174             line[i--] = '\0';
175         level = 0;
176         while (level < strlen(line) && isspace(line[level]))
177             level++;
178         if (level == 0) {
179             coordinates_t loc;
180             if (locate_desktop(line + level, &loc))
181                 d = loc.desktop;
182         } else if (d != NULL) {
183             xcb_window_t win;
184             if (sscanf(line + level, "%X", &win) == 1) {
185                 coordinates_t loc;
186                 if (locate_window(win, &loc))
187                     history_add(d->history, loc.node);
188             }
189         }
190     }
191
192     fclose(snapshot);
193 }