diff options
Diffstat (limited to 'sway/container.c')
-rw-r--r-- | sway/container.c | 415 |
1 files changed, 266 insertions, 149 deletions
diff --git a/sway/container.c b/sway/container.c index ef0e6c55..baf84378 100644 --- a/sway/container.c +++ b/sway/container.c | |||
@@ -1,6 +1,7 @@ | |||
1 | #include <stdlib.h> | 1 | #include <stdlib.h> |
2 | #include <stdbool.h> | 2 | #include <stdbool.h> |
3 | #include <strings.h> | 3 | #include <strings.h> |
4 | #include <pcre.h> | ||
4 | #include "config.h" | 5 | #include "config.h" |
5 | #include "container.h" | 6 | #include "container.h" |
6 | #include "workspace.h" | 7 | #include "workspace.h" |
@@ -53,26 +54,30 @@ static void free_swayc(swayc_t *cont) { | |||
53 | // New containers | 54 | // New containers |
54 | 55 | ||
55 | swayc_t *new_output(wlc_handle handle) { | 56 | swayc_t *new_output(wlc_handle handle) { |
56 | const struct wlc_size *size = wlc_output_get_resolution(handle); | ||
57 | const char *name = wlc_output_get_name(handle); | 57 | const char *name = wlc_output_get_name(handle); |
58 | int i, len; | ||
59 | |||
58 | // Find current outputs to see if this already exists | 60 | // Find current outputs to see if this already exists |
59 | { | 61 | if (name) { |
60 | int i, len = root_container.children->length; | 62 | len = root_container.children->length; |
61 | for (i = 0; i < len; ++i) { | 63 | for (i = 0; i < len; ++i) { |
62 | swayc_t *op = root_container.children->items[i]; | 64 | swayc_t *op = root_container.children->items[i]; |
63 | const char *op_name = op->name; | 65 | if (strcmp(op->name, name) == 0) { |
64 | if (op_name && name && strcmp(op_name, name) == 0) { | 66 | sway_log(L_DEBUG, "restoring output %lu:%s", handle, op->name); |
65 | sway_log(L_DEBUG, "restoring output %lu:%s", handle, op_name); | ||
66 | return op; | 67 | return op; |
67 | } | 68 | } |
68 | } | 69 | } |
70 | } else { | ||
71 | sway_log(L_ERROR, "Output has no given name"); | ||
72 | return NULL; | ||
69 | } | 73 | } |
70 | 74 | ||
71 | sway_log(L_DEBUG, "Added output %lu:%s", handle, name); | 75 | sway_log(L_DEBUG, "Adding output %lu:%s", handle, name); |
72 | 76 | ||
77 | // Find output config | ||
73 | struct output_config *oc = NULL; | 78 | struct output_config *oc = NULL; |
74 | int i; | 79 | len = config->output_configs->length; |
75 | for (i = 0; i < config->output_configs->length; ++i) { | 80 | for (i = 0; i < len; ++i) { |
76 | oc = config->output_configs->items[i]; | 81 | oc = config->output_configs->items[i]; |
77 | if (strcasecmp(name, oc->name) == 0) { | 82 | if (strcasecmp(name, oc->name) == 0) { |
78 | sway_log(L_DEBUG, "Matched output config for %s", name); | 83 | sway_log(L_DEBUG, "Matched output config for %s", name); |
@@ -86,77 +91,88 @@ swayc_t *new_output(wlc_handle handle) { | |||
86 | } | 91 | } |
87 | 92 | ||
88 | swayc_t *output = new_swayc(C_OUTPUT); | 93 | swayc_t *output = new_swayc(C_OUTPUT); |
89 | if (oc && oc->width != -1 && oc->height != -1) { | ||
90 | output->width = oc->width; | ||
91 | output->height = oc->height; | ||
92 | struct wlc_size new_size = { .w = oc->width, .h = oc->height }; | ||
93 | wlc_output_set_resolution(handle, &new_size); | ||
94 | } else { | ||
95 | output->width = size->w; | ||
96 | output->height = size->h; | ||
97 | } | ||
98 | output->handle = handle; | 94 | output->handle = handle; |
99 | output->name = name ? strdup(name) : NULL; | 95 | output->name = name ? strdup(name) : NULL; |
100 | |||
101 | // Find position for it | ||
102 | if (oc && oc->x != -1 && oc->y != -1) { | ||
103 | sway_log(L_DEBUG, "Set %s position to %d, %d", name, oc->x, oc->y); | ||
104 | output->x = oc->x; | ||
105 | output->y = oc->y; | ||
106 | } else { | ||
107 | int x = 0; | ||
108 | for (i = 0; i < root_container.children->length; ++i) { | ||
109 | swayc_t *c = root_container.children->items[i]; | ||
110 | if (c->type == C_OUTPUT) { | ||
111 | if (c->width + c->x > x) { | ||
112 | x = c->width + c->x; | ||
113 | } | ||
114 | } | ||
115 | } | ||
116 | output->x = x; | ||
117 | } | ||
118 | 96 | ||
119 | add_child(&root_container, output); | 97 | if (oc) { |
120 | 98 | // Set output width/height | |
121 | // Create workspace | 99 | if (oc->width > 0 && oc->height > 0) { |
122 | char *ws_name = NULL; | 100 | output->width = oc->width; |
123 | if (name) { | 101 | output->height = oc->height; |
124 | for (i = 0; i < config->workspace_outputs->length; ++i) { | 102 | struct wlc_size geo = { .w = oc->width, .h = oc->height}; |
125 | struct workspace_output *wso = config->workspace_outputs->items[i]; | 103 | wlc_output_set_resolution(handle, &geo); |
126 | if (strcasecmp(wso->output, name) == 0) { | 104 | } else { |
127 | sway_log(L_DEBUG, "Matched workspace to output: %s for %s", wso->workspace, wso->output); | 105 | struct wlc_size geo = *wlc_output_get_resolution(handle); |
128 | // Check if any other workspaces are using this name | 106 | output->width = geo.w; |
129 | if (workspace_by_name(wso->workspace)) { | 107 | output->height = geo.h; |
130 | sway_log(L_DEBUG, "But it's already taken"); | 108 | } |
131 | break; | 109 | // find position in config or find where it should go |
110 | // TODO more intelligent method | ||
111 | if (oc->x > 0 && oc->y > 0) { | ||
112 | output->x = oc->x; | ||
113 | output->y = oc->y; | ||
114 | } else { | ||
115 | unsigned int x = 0; | ||
116 | len = root_container.children->length; | ||
117 | for (i = 0; i < len; ++i) { | ||
118 | swayc_t *c = root_container.children->items[i]; | ||
119 | if (c->type == C_OUTPUT) { | ||
120 | unsigned int cx = c->width + c->x; | ||
121 | if (cx > x) { | ||
122 | x = cx; | ||
123 | } | ||
132 | } | 124 | } |
133 | sway_log(L_DEBUG, "So we're going to use it"); | ||
134 | ws_name = strdup(wso->workspace); | ||
135 | break; | ||
136 | } | 125 | } |
126 | output->x = x; | ||
137 | } | 127 | } |
138 | } | 128 | } |
139 | if (!ws_name) { | 129 | // Add as child to root |
140 | ws_name = workspace_next_name(); | 130 | add_child(&root_container, output); |
141 | } | ||
142 | 131 | ||
143 | // create and initilize default workspace | 132 | // create and initilize default workspace |
144 | swayc_t *ws = new_workspace(output, ws_name); | 133 | swayc_t *ws = new_workspace(output, NULL); |
145 | ws->is_focused = true; | 134 | ws->is_focused = true; |
146 | 135 | ||
147 | free(ws_name); | ||
148 | |||
149 | return output; | 136 | return output; |
150 | } | 137 | } |
151 | 138 | ||
152 | swayc_t *new_workspace(swayc_t *output, const char *name) { | 139 | swayc_t *new_workspace(swayc_t *output, const char *name) { |
153 | if (!ASSERT_NONNULL(output)) { | 140 | swayc_t *ws = NULL; |
154 | return NULL; | 141 | struct workspace_output *wsop; |
142 | if (name) { | ||
143 | // Find existing workspace with same name. | ||
144 | // or workspace found by special name | ||
145 | if ((ws = workspace_by_name(name))) { | ||
146 | return ws; | ||
147 | } | ||
148 | // Find matching output from config | ||
149 | if (!output) { | ||
150 | if ((wsop = wsop_find_workspace(name))) { | ||
151 | int i, len = root_container.children->length; | ||
152 | for (i = 0; i < len; ++i) { | ||
153 | swayc_t *op = root_container.children->items[i]; | ||
154 | if (strcasecmp(op->name, wsop->output) == 0) { | ||
155 | output = op; | ||
156 | goto find_wsop_end; | ||
157 | } | ||
158 | } | ||
159 | } | ||
160 | // Set output to active_output if there is no output. | ||
161 | output = swayc_active_output(); | ||
162 | find_wsop_end:; | ||
163 | } | ||
164 | } else { | ||
165 | // No name or output, use active_output | ||
166 | if (!output) { | ||
167 | output = swayc_active_output(); | ||
168 | } | ||
169 | // search for available output name | ||
170 | if (!(name = workspace_output_open_name(output))) { | ||
171 | // otherwise just use simple next name | ||
172 | name = workspace_next_name(); | ||
173 | } | ||
155 | } | 174 | } |
156 | sway_log(L_DEBUG, "Added workspace %s for output %u", name, (unsigned int)output->handle); | ||
157 | swayc_t *workspace = new_swayc(C_WORKSPACE); | 175 | swayc_t *workspace = new_swayc(C_WORKSPACE); |
158 | |||
159 | // TODO: default_layout | ||
160 | if (config->default_layout != L_NONE) { | 176 | if (config->default_layout != L_NONE) { |
161 | workspace->layout = config->default_layout; | 177 | workspace->layout = config->default_layout; |
162 | } else if (config->default_orientation != L_NONE) { | 178 | } else if (config->default_orientation != L_NONE) { |
@@ -374,7 +390,7 @@ swayc_t *destroy_view(swayc_t *view) { | |||
374 | // Container lookup | 390 | // Container lookup |
375 | 391 | ||
376 | 392 | ||
377 | swayc_t *swayc_by_test(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data) { | 393 | swayc_t *swayc_by_test_r(swayc_t *container, swayc_test_func test, void *data) { |
378 | if (!container->children) { | 394 | if (!container->children) { |
379 | return NULL; | 395 | return NULL; |
380 | } | 396 | } |
@@ -393,7 +409,7 @@ swayc_t *swayc_by_test(swayc_t *container, bool (*test)(swayc_t *view, void *dat | |||
393 | if (test(child, data)) { | 409 | if (test(child, data)) { |
394 | return child; | 410 | return child; |
395 | } else { | 411 | } else { |
396 | swayc_t *res = swayc_by_test(child, test, data); | 412 | swayc_t *res = swayc_by_test_r(child, test, data); |
397 | if (res) { | 413 | if (res) { |
398 | return res; | 414 | return res; |
399 | } | 415 | } |
@@ -401,18 +417,193 @@ swayc_t *swayc_by_test(swayc_t *container, bool (*test)(swayc_t *view, void *dat | |||
401 | } | 417 | } |
402 | return NULL; | 418 | return NULL; |
403 | } | 419 | } |
420 | swayc_t *swayc_by_test(swayc_test_func test, void *data) { | ||
421 | return swayc_by_test_r(&root_container, test, data); | ||
422 | } | ||
423 | |||
424 | void swayc_map_r(swayc_t *container, swayc_map_func f, void *data) { | ||
425 | if (container) { | ||
426 | f(container, data); | ||
427 | int i; | ||
428 | if (container->children) { | ||
429 | for (i = 0; i < container->children->length; ++i) { | ||
430 | swayc_t *child = container->children->items[i]; | ||
431 | swayc_map_r(child, f, data); | ||
432 | } | ||
433 | } | ||
434 | if (container->floating) { | ||
435 | for (i = 0; i < container->floating->length; ++i) { | ||
436 | swayc_t *child = container->floating->items[i]; | ||
437 | swayc_map_r(child, f, data); | ||
438 | } | ||
439 | } | ||
440 | } | ||
441 | } | ||
442 | void swayc_map(swayc_map_func f, void *data) { | ||
443 | swayc_map_r(&root_container, f, data); | ||
444 | } | ||
445 | |||
446 | void swayc_map_by_test_r(swayc_t *container, | ||
447 | swayc_map_func func, swayc_test_func test, | ||
448 | void *funcdata, void *testdata) { | ||
449 | if (container) { | ||
450 | if (test(container, testdata)) { | ||
451 | func(container, funcdata); | ||
452 | } | ||
453 | int i; | ||
454 | if (container->children) { | ||
455 | for (i = 0; i < container->children->length; ++i) { | ||
456 | swayc_t *child = container->children->items[i]; | ||
457 | swayc_map_by_test_r(child, func, test, funcdata, testdata); | ||
458 | } | ||
459 | } | ||
460 | if (container->floating) { | ||
461 | for (i = 0; i < container->floating->length; ++i) { | ||
462 | swayc_t *child = container->floating->items[i]; | ||
463 | swayc_map_by_test_r(child, func, test, funcdata, testdata); | ||
464 | } | ||
465 | } | ||
466 | } | ||
467 | } | ||
468 | void swayc_map_by_test( | ||
469 | swayc_map_func func, swayc_test_func test, | ||
470 | void *funcdata, void *testdata) { | ||
471 | swayc_map_by_test_r(&root_container, func, test, funcdata, testdata); | ||
472 | } | ||
473 | |||
474 | |||
475 | |||
476 | // Map functions | ||
477 | void set_gaps(swayc_t *view, void *_data) { | ||
478 | int *data = _data; | ||
479 | if (view->type == C_WORKSPACE || view->type == C_VIEW) { | ||
480 | view->gaps = *data; | ||
481 | } | ||
482 | } | ||
404 | 483 | ||
405 | static bool test_name(swayc_t *view, void *data) { | 484 | void add_gaps(swayc_t *view, void *_data) { |
406 | if (!view && !view->name) { | 485 | int *data = _data; |
407 | return false; | 486 | if (view->type == C_WORKSPACE || view->type == C_VIEW) { |
487 | if ((view->gaps += *data) < 0) { | ||
488 | view->gaps = 0; | ||
489 | } | ||
408 | } | 490 | } |
409 | return strcmp(view->name, data) == 0; | ||
410 | } | 491 | } |
411 | 492 | ||
412 | swayc_t *swayc_by_name(const char *name) { | 493 | // Test functions |
413 | return swayc_by_test(&root_container, test_name, (void *)name); | 494 | bool test_name(swayc_t *view, void *data) { |
495 | return view->name && strcmp(view->name, data) == 0; | ||
414 | } | 496 | } |
415 | 497 | ||
498 | // test_name_regex | ||
499 | struct test_name_regex { | ||
500 | pcre *reg; | ||
501 | pcre_extra *regext; | ||
502 | }; | ||
503 | |||
504 | void *compile_regex(const char *pattern) { | ||
505 | struct test_name_regex *regex = malloc(sizeof *regex); | ||
506 | const char *error; | ||
507 | int erroffset; | ||
508 | if (!(regex->reg = pcre_compile(pattern, 0, &error, &erroffset, NULL))) { | ||
509 | sway_log(L_ERROR, "Regex compilation failed:%s:%s", pattern, error); | ||
510 | free(regex); | ||
511 | return NULL; | ||
512 | } | ||
513 | regex->regext = pcre_study(regex->reg, 0, &error); | ||
514 | if (error) { | ||
515 | sway_log(L_DEBUG, "Regex study failed:%s:%s", pattern, error); | ||
516 | } | ||
517 | return regex; | ||
518 | } | ||
519 | |||
520 | void free_regex(void *_regex) { | ||
521 | struct test_name_regex *regex = _regex; | ||
522 | pcre_free(regex->reg); | ||
523 | pcre_free_study(regex->regext); | ||
524 | free(regex); | ||
525 | } | ||
526 | |||
527 | static bool exec_regex(const char *pattern, struct test_name_regex *regex) { | ||
528 | int ovector[300]; | ||
529 | return 0 < pcre_exec(regex->reg, regex->regext, pattern, | ||
530 | strlen(pattern), 0, 0, ovector, 300); | ||
531 | } | ||
532 | |||
533 | bool test_name_regex(swayc_t *view, void *data) { | ||
534 | return view->name && exec_regex(view->name, data); | ||
535 | } | ||
536 | bool test_layout(swayc_t *view, void *data) { | ||
537 | return view->layout & *(enum swayc_layouts *)data; | ||
538 | } | ||
539 | bool test_type(swayc_t *view, void *data) { | ||
540 | return view->layout & *(enum swayc_types *)data; | ||
541 | } | ||
542 | bool test_visibility(swayc_t *view, void *data) { | ||
543 | return view->visible == *(bool *)data; | ||
544 | } | ||
545 | bool test_handle(swayc_t *view, void *data) { | ||
546 | return view->handle == *(wlc_handle *)data; | ||
547 | } | ||
548 | |||
549 | // C_VIEW tests | ||
550 | bool test_view_state(swayc_t *view, void *data) { | ||
551 | return view->type == C_VIEW | ||
552 | && wlc_view_get_state(view->handle) & *(int *)data; | ||
553 | } | ||
554 | bool test_view_type(swayc_t *view, void *data) { | ||
555 | return view->type == C_VIEW | ||
556 | && wlc_view_get_type(view->handle) & *(int *)data; | ||
557 | } | ||
558 | bool test_view_title(swayc_t *view, void *data) { | ||
559 | return view->type == C_VIEW | ||
560 | && strcmp(view->name, data) == 0; | ||
561 | } | ||
562 | bool test_view_class(swayc_t *view, void *data) { | ||
563 | return view->type == C_VIEW | ||
564 | && strcmp(wlc_view_get_class(view->handle), data) == 0; | ||
565 | } | ||
566 | bool test_view_appid(swayc_t *view, void *data) { | ||
567 | return view->type == C_VIEW | ||
568 | && strcmp(wlc_view_get_app_id(view->handle), data) == 0; | ||
569 | } | ||
570 | bool test_view_title_regex(swayc_t *view, void *data) { | ||
571 | return view->type == C_VIEW | ||
572 | && exec_regex(view->name, data); | ||
573 | } | ||
574 | bool test_view_class_regex(swayc_t *view, void *data) { | ||
575 | return view->type == C_VIEW | ||
576 | && exec_regex(wlc_view_get_class(view->handle), data); | ||
577 | } | ||
578 | bool test_view_appid_regex(swayc_t *view, void *data) { | ||
579 | return view->type == C_VIEW | ||
580 | && exec_regex(wlc_view_get_app_id(view->handle), data); | ||
581 | } | ||
582 | |||
583 | // Fancy test combiners | ||
584 | bool test_and(swayc_t *view, void *data) { | ||
585 | struct test_list *list = data; | ||
586 | while (list->test) { | ||
587 | if (!list->test(view, list->data)) { | ||
588 | return false; | ||
589 | } | ||
590 | ++list; | ||
591 | } | ||
592 | return true; | ||
593 | } | ||
594 | bool test_or(swayc_t *view, void *data) { | ||
595 | struct test_list *list = data; | ||
596 | while (list->test) { | ||
597 | if (list->test(view, list->data)) { | ||
598 | return true; | ||
599 | } | ||
600 | ++list; | ||
601 | } | ||
602 | return false; | ||
603 | } | ||
604 | |||
605 | // Focus|parent lookup | ||
606 | |||
416 | swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) { | 607 | swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) { |
417 | if (!ASSERT_NONNULL(container)) { | 608 | if (!ASSERT_NONNULL(container)) { |
418 | return NULL; | 609 | return NULL; |
@@ -465,42 +656,6 @@ swayc_t *swayc_focus_by_layout(swayc_t *container, enum swayc_layouts layout) { | |||
465 | return container; | 656 | return container; |
466 | } | 657 | } |
467 | 658 | ||
468 | |||
469 | static swayc_t *_swayc_by_handle_helper(wlc_handle handle, swayc_t *parent) { | ||
470 | if (!parent || !parent->children) { | ||
471 | return NULL; | ||
472 | } | ||
473 | int i, len; | ||
474 | swayc_t **child; | ||
475 | if (parent->type == C_WORKSPACE) { | ||
476 | len = parent->floating->length; | ||
477 | child = (swayc_t **)parent->floating->items; | ||
478 | for (i = 0; i < len; ++i, ++child) { | ||
479 | if ((*child)->handle == handle) { | ||
480 | return *child; | ||
481 | } | ||
482 | } | ||
483 | } | ||
484 | |||
485 | len = parent->children->length; | ||
486 | child = (swayc_t**)parent->children->items; | ||
487 | for (i = 0; i < len; ++i, ++child) { | ||
488 | if ((*child)->handle == handle) { | ||
489 | return *child; | ||
490 | } else { | ||
491 | swayc_t *res; | ||
492 | if ((res = _swayc_by_handle_helper(handle, *child))) { | ||
493 | return res; | ||
494 | } | ||
495 | } | ||
496 | } | ||
497 | return NULL; | ||
498 | } | ||
499 | |||
500 | swayc_t *swayc_by_handle(wlc_handle handle) { | ||
501 | return _swayc_by_handle_helper(handle, &root_container); | ||
502 | } | ||
503 | |||
504 | swayc_t *swayc_active_output(void) { | 659 | swayc_t *swayc_active_output(void) { |
505 | return root_container.focused; | 660 | return root_container.focused; |
506 | } | 661 | } |
@@ -533,11 +688,13 @@ swayc_t *swayc_active_workspace_for(swayc_t *cont) { | |||
533 | // Container information | 688 | // Container information |
534 | 689 | ||
535 | bool swayc_is_fullscreen(swayc_t *view) { | 690 | bool swayc_is_fullscreen(swayc_t *view) { |
536 | return view && view->type == C_VIEW && (wlc_view_get_state(view->handle) & WLC_BIT_FULLSCREEN); | 691 | return view && view->type == C_VIEW |
692 | && wlc_view_get_state(view->handle) & WLC_BIT_FULLSCREEN; | ||
537 | } | 693 | } |
538 | 694 | ||
539 | bool swayc_is_active(swayc_t *view) { | 695 | bool swayc_is_active(swayc_t *view) { |
540 | return view && view->type == C_VIEW && (wlc_view_get_state(view->handle) & WLC_BIT_ACTIVATED); | 696 | return view && view->type == C_VIEW |
697 | && wlc_view_get_state(view->handle) & WLC_BIT_ACTIVATED; | ||
541 | } | 698 | } |
542 | 699 | ||
543 | bool swayc_is_parent_of(swayc_t *parent, swayc_t *child) { | 700 | bool swayc_is_parent_of(swayc_t *parent, swayc_t *child) { |
@@ -566,25 +723,6 @@ int swayc_gap(swayc_t *container) { | |||
566 | 723 | ||
567 | // Mapping | 724 | // Mapping |
568 | 725 | ||
569 | void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) { | ||
570 | if (container) { | ||
571 | f(container, data); | ||
572 | int i; | ||
573 | if (container->children) { | ||
574 | for (i = 0; i < container->children->length; ++i) { | ||
575 | swayc_t *child = container->children->items[i]; | ||
576 | container_map(child, f, data); | ||
577 | } | ||
578 | } | ||
579 | if (container->floating) { | ||
580 | for (i = 0; i < container->floating->length; ++i) { | ||
581 | swayc_t *child = container->floating->items[i]; | ||
582 | container_map(child, f, data); | ||
583 | } | ||
584 | } | ||
585 | } | ||
586 | } | ||
587 | |||
588 | void update_visibility_output(swayc_t *container, wlc_handle output) { | 726 | void update_visibility_output(swayc_t *container, wlc_handle output) { |
589 | // Inherit visibility | 727 | // Inherit visibility |
590 | swayc_t *parent = container->parent; | 728 | swayc_t *parent = container->parent; |
@@ -653,24 +791,3 @@ void update_visibility(swayc_t *container) { | |||
653 | } | 791 | } |
654 | } | 792 | } |
655 | 793 | ||
656 | void set_gaps(swayc_t *view, void *_data) { | ||
657 | int *data = _data; | ||
658 | if (!ASSERT_NONNULL(view)) { | ||
659 | return; | ||
660 | } | ||
661 | if (view->type == C_WORKSPACE || view->type == C_VIEW) { | ||
662 | view->gaps = *data; | ||
663 | } | ||
664 | } | ||
665 | |||
666 | void add_gaps(swayc_t *view, void *_data) { | ||
667 | int *data = _data; | ||
668 | if (!ASSERT_NONNULL(view)) { | ||
669 | return; | ||
670 | } | ||
671 | if (view->type == C_WORKSPACE || view->type == C_VIEW) { | ||
672 | if ((view->gaps += *data) < 0) { | ||
673 | view->gaps = 0; | ||
674 | } | ||
675 | } | ||
676 | } | ||