]> git.lizzy.rs Git - bspwm.git/blob - restore.c
Cosmetic improvements
[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;
116                 sscanf(line + level, "%c %s %X %u %hux%hu%hi%hi %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);
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->client = c;
123                 if (len >= 2 && line[len - 2] == '*')
124                     d->focus = n;
125             }
126             if (br == 'a')
127                 n->birth_rotation = 90;
128             else if (br == 'c')
129                 n->birth_rotation = 270;
130             else if (br == 'm')
131                 n->birth_rotation = 0;
132         }
133         last_level = level;
134     }
135
136     fclose(snapshot);
137
138     if (!aborted) {
139         for (monitor_t *m = mon_head; m != NULL; m = m->next)
140             for (desktop_t *d = m->desk_head; d != NULL; d = d->next)
141                 for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) {
142                     uint32_t values[] = {(focus_follows_pointer ? CLIENT_EVENT_MASK_FFP : CLIENT_EVENT_MASK)};
143                     xcb_change_window_attributes(dpy, n->client->window, XCB_CW_EVENT_MASK, values);
144                     if (n->client->floating) {
145                         n->vacant = true;
146                         update_vacant_state(n->parent);
147                     }
148                 }
149         ewmh_update_current_desktop();
150     }
151 }
152
153 void restore_history(char *file_path)
154 {
155     if (file_path == NULL)
156         return;
157
158     FILE *snapshot = fopen(file_path, "r");
159     if (snapshot == NULL) {
160         warn("Restore history: can't open file\n");
161         return;
162     }
163
164     PUTS("restore history");
165
166     char line[MAXLEN];
167     desktop_t *d = NULL;
168     unsigned int level;
169
170     while (fgets(line, sizeof(line), snapshot) != NULL) {
171         unsigned int i = strlen(line) - 1;
172         while (i > 0 && isspace(line[i]))
173             line[i--] = '\0';
174         level = 0;
175         while (level < strlen(line) && isspace(line[level]))
176             level++;
177         if (level == 0) {
178             coordinates_t loc;
179             if (locate_desktop(line + level, &loc))
180                 d = loc.desktop;
181         } else if (d != NULL) {
182             xcb_window_t win;
183             if (sscanf(line + level, "%X", &win) == 1) {
184                 coordinates_t loc;
185                 if (locate_window(win, &loc))
186                     history_add(d->history, loc.node);
187             }
188         }
189     }
190
191     fclose(snapshot);
192 }