1 /* Copyright (c) 2012, Bastien Dejean
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
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.
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.
38 void restore_tree(char *file_path)
40 if (file_path == NULL)
43 FILE *snapshot = fopen(file_path, "r");
44 if (snapshot == NULL) {
45 warn("Restore tree: can't open '%s'.\n", file_path);
55 unsigned int level, last_level = 0;
57 while (fgets(line, sizeof(line), snapshot) != NULL) {
58 unsigned int len = strlen(line);
61 while (level < len && isspace(line[level]))
65 int x, y, top, right, bottom, left;
69 sscanf(line + level, "%s %ux%u%i%i %i,%i,%i,%i %c", name, &w, &h, &x, &y,
70 &top, &right, &bottom, &left, &end);
71 m = find_monitor(name);
74 m->rectangle = (xcb_rectangle_t) {x, y, w, h};
76 m->right_padding = right;
77 m->bottom_padding = bottom;
78 m->left_padding = left;
81 } else if (level == 1) {
84 int wg, top, right, bottom, left;
86 char floating, layout = 0, end = 0;
89 sscanf(line + level, "%s %u %i %i,%i,%i,%i %c %c %c", name,
90 &bw, &wg, &top, &right, &bottom, &left, &layout, &floating, &end);
91 locate_desktop(name, &loc);
99 d->right_padding = right;
100 d->bottom_padding = bottom;
101 d->left_padding = left;
103 d->layout = LAYOUT_MONOCLE;
104 } else if (layout == 'T') {
105 d->layout = LAYOUT_TILED;
111 if (m == NULL || d == NULL)
113 node_t *birth = make_node();
117 } else if (n != NULL) {
118 if (level > last_level) {
119 n->first_child = birth;
123 } while (n != NULL && n->second_child != NULL);
126 n->second_child = birth;
132 if (isupper(line[level])) {
134 sscanf(line + level, "%c %c %lf", &split_type, &birth_rotation, &n->split_ratio);
135 if (split_type == 'H') {
136 n->split_type = TYPE_HORIZONTAL;
137 } else if (split_type == 'V') {
138 n->split_type = TYPE_VERTICAL;
141 client_t *c = make_client(XCB_NONE, d->border_width);
143 char urgent, locked, sticky, private, split_dir, split_mode, state, layer, end = 0;
144 sscanf(line + level, "%c %s %s %X %u %hux%hu%hi%hi %c%c %c%c %c%c%c%c %c", &birth_rotation,
145 c->class_name, c->instance_name, &c->window, &c->border_width,
146 &c->floating_rectangle.width, &c->floating_rectangle.height,
147 &c->floating_rectangle.x, &c->floating_rectangle.y,
148 &split_dir, &split_mode, &state, &layer,
149 &urgent, &locked, &sticky, &private, &end);
150 n->split_mode = (split_mode == '-' ? MODE_AUTOMATIC : MODE_MANUAL);
151 if (split_dir == 'U') {
152 n->split_dir = DIR_UP;
153 } else if (split_dir == 'R') {
154 n->split_dir = DIR_RIGHT;
155 } else if (split_dir == 'D') {
156 n->split_dir = DIR_DOWN;
157 } else if (split_dir == 'L') {
158 n->split_dir = DIR_LEFT;
161 c->state = STATE_FLOATING;
162 } else if (state == 'F') {
163 c->state = STATE_FULLSCREEN;
164 } else if (state == 'p') {
165 c->state = STATE_PSEUDO_TILED;
168 c->layer = LAYER_BELOW;
169 } else if (layer == 'a') {
170 c->layer = LAYER_ABOVE;
172 c->urgent = (urgent == '-' ? false : true);
173 c->locked = (locked == '-' ? false : true);
174 c->sticky = (sticky == '-' ? false : true);
175 c->private = (private == '-' ? false : true);
184 if (birth_rotation == 'a') {
185 n->birth_rotation = 90;
186 } else if (birth_rotation == 'c') {
187 n->birth_rotation = 270;
188 } else if (birth_rotation == 'm') {
189 n->birth_rotation = 0;
197 for (monitor_t *m = mon_head; m != NULL; m = m->next) {
198 for (desktop_t *d = m->desk_head; d != NULL; d = d->next) {
199 for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) {
200 uint32_t values[] = {CLIENT_EVENT_MASK | (focus_follows_pointer ? XCB_EVENT_MASK_ENTER_WINDOW : 0)};
201 xcb_change_window_attributes(dpy, n->client->window, XCB_CW_EVENT_MASK, values);
202 if (!IS_TILED(n->client)) {
204 update_vacant_state(n->parent);
206 if (n->client->private) {
207 update_privacy_level(n, true);
210 /* Has the side effect of restoring the node's rectangles and the client's tiled rectangles */
215 ewmh_update_current_desktop();
218 void restore_history(char *file_path)
220 if (file_path == NULL)
223 FILE *snapshot = fopen(file_path, "r");
224 if (snapshot == NULL) {
225 warn("Restore history: can't open '%s'.\n", file_path);
234 while (fgets(line, sizeof(line), snapshot) != NULL) {
235 if (sscanf(line, "%s %s %X", mnm, dnm, &win) == 3) {
237 if (win != XCB_NONE && !locate_window(win, &loc)) {
238 warn("Can't locate window 0x%X.\n", win);
241 node_t *n = (win == XCB_NONE ? NULL : loc.node);
242 if (!locate_desktop(dnm, &loc)) {
243 warn("Can't locate desktop '%s'.\n", dnm);
246 desktop_t *d = loc.desktop;
247 if (!locate_monitor(mnm, &loc)) {
248 warn("Can't locate monitor '%s'.\n", mnm);
251 monitor_t *m = loc.monitor;
252 history_add(m, d, n);
254 warn("Can't parse history entry: '%s'\n", line);
261 void restore_stack(char *file_path)
263 if (file_path == NULL)
266 FILE *snapshot = fopen(file_path, "r");
267 if (snapshot == NULL) {
268 warn("Restore stack: can't open '%s'.\n", file_path);
275 while (fgets(line, sizeof(line), snapshot) != NULL) {
276 if (sscanf(line, "%X", &win) == 1) {
278 if (locate_window(win, &loc))
279 stack_insert_after(stack_tail, loc.node);
281 warn("Can't locate window 0x%X.\n", win);
283 warn("Can't parse stack entry: '%s'\n", line);