]> git.lizzy.rs Git - bspwm.git/blobdiff - src/window.c
Resolve the rule consequences passed to the erc
[bspwm.git] / src / window.c
index 7cfcd6ef807d1d74f5e322ef76de5fbb4109c4ea..a22b5e78a042d8b6323f07b319708bf0910ef3cc 100644 (file)
 #include <stdlib.h>
 #include <stdbool.h>
 #include <string.h>
+#include <xcb/shape.h>
 #include "bspwm.h"
 #include "ewmh.h"
 #include "monitor.h"
+#include "desktop.h"
 #include "query.h"
 #include "rule.h"
 #include "settings.h"
@@ -61,7 +63,7 @@ void schedule_window(xcb_window_t win)
                }
        }
 
-       rule_consequence_t *csq = make_rule_conquence();
+       rule_consequence_t *csq = make_rule_consequence();
        apply_rules(win, csq);
        if (!schedule_rules(win, csq)) {
                manage_window(win, csq, -1);
@@ -69,7 +71,7 @@ void schedule_window(xcb_window_t win)
        }
 }
 
-void manage_window(xcb_window_t win, rule_consequence_t *csq, int fd)
+bool manage_window(xcb_window_t win, rule_consequence_t *csq, int fd)
 {
        monitor_t *m = mon;
        desktop_t *d = mon->desk;
@@ -77,7 +79,7 @@ void manage_window(xcb_window_t win, rule_consequence_t *csq, int fd)
 
        parse_rule_consequence(fd, csq);
 
-       if (ewmh_handle_struts(win)) {
+       if (!ignore_ewmh_struts && ewmh_handle_struts(win)) {
                for (monitor_t *m = mon_head; m != NULL; m = m->next) {
                        arrange(m, m->desk);
                }
@@ -87,7 +89,7 @@ void manage_window(xcb_window_t win, rule_consequence_t *csq, int fd)
                free(csq->layer);
                free(csq->state);
                window_show(win);
-               return;
+               return false;
        }
 
        if (csq->node_desc[0] != '\0') {
@@ -122,11 +124,8 @@ void manage_window(xcb_window_t win, rule_consequence_t *csq, int fd)
                f = mon->desk->focus;
        }
 
-       if (csq->split_dir[0] != '\0' && f != NULL) {
-               direction_t dir;
-               if (parse_direction(csq->split_dir, &dir)) {
-                       presel_dir(m, d, f, dir);
-               }
+       if (csq->split_dir != NULL && f != NULL) {
+               presel_dir(m, d, f, *csq->split_dir);
        }
 
        if (csq->split_ratio != 0 && f != NULL) {
@@ -158,8 +157,17 @@ void manage_window(xcb_window_t win, rule_consequence_t *csq, int fd)
        snprintf(c->class_name, sizeof(c->class_name), "%s", csq->class_name);
        snprintf(c->instance_name, sizeof(c->instance_name), "%s", csq->instance_name);
 
+       if ((csq->state != NULL && (*(csq->state) == STATE_FLOATING || *(csq->state) == STATE_FULLSCREEN)) || csq->hidden) {
+               n->vacant = true;
+       }
+
        f = insert_node(m, d, n, f);
        clients_count++;
+       if (single_monocle && d->layout == LAYOUT_MONOCLE && tiled_count(d->root, true) > 1) {
+               set_layout(m, d, d->user_layout, false);
+       }
+
+       n->vacant = false;
 
        put_status(SBSC_MASK_NODE_ADD, "node_add 0x%08X 0x%08X 0x%08X 0x%08X\n", m->id, d->id, f!=NULL?f->id:0, win);
 
@@ -194,6 +202,9 @@ void manage_window(xcb_window_t win, rule_consequence_t *csq, int fd)
                hide_node(d, n);
        }
 
+       ewmh_update_client_list(false);
+       ewmh_set_wm_desktop(n, d);
+
        if (!csq->hidden && csq->focus) {
                if (d == mon->desk || csq->follow) {
                        focus_node(m, d, n);
@@ -205,10 +216,10 @@ void manage_window(xcb_window_t win, rule_consequence_t *csq, int fd)
                draw_border(n, false, (m == mon));
        }
 
-       ewmh_set_wm_desktop(n, d);
-       ewmh_update_client_list(false);
        free(csq->layer);
        free(csq->state);
+
+       return true;
 }
 
 void set_window_state(xcb_window_t win, xcb_icccm_wm_state_t state)
@@ -254,13 +265,14 @@ void initialize_presel_feedback(node_t *n)
        }
 
        xcb_window_t win = xcb_generate_id(dpy);
-       uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK;
-       uint32_t values[] = {get_color_pixel(presel_feedback_color), 1, focus_follows_pointer ? XCB_EVENT_MASK_ENTER_WINDOW : 0};
+       uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_SAVE_UNDER;
+       uint32_t values[] = {get_color_pixel(presel_feedback_color), 1};
        xcb_create_window(dpy, XCB_COPY_FROM_PARENT, win, root, 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
                                  XCB_COPY_FROM_PARENT, mask, values);
 
        xcb_icccm_set_wm_class(dpy, win, sizeof(PRESEL_FEEDBACK_IC), PRESEL_FEEDBACK_IC);
-       window_grab_buttons(win);
+       /* Make presel window's input shape NULL to pass any input to window below */
+       xcb_shape_rectangles(dpy, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, win, 0, 0, 0, NULL);
        stacking_list_t *s = stack_tail;
        while (s != NULL && !IS_TILED(s->node->client)) {
                s = s->prev;
@@ -273,7 +285,7 @@ void initialize_presel_feedback(node_t *n)
 
 void draw_presel_feedback(monitor_t *m, desktop_t *d, node_t *n)
 {
-       if (n == NULL || n->presel == NULL || d->layout == LAYOUT_MONOCLE) {
+       if (n == NULL || n->presel == NULL || d->user_layout == LAYOUT_MONOCLE || !presel_feedback) {
                return;
        }
 
@@ -282,7 +294,7 @@ void draw_presel_feedback(monitor_t *m, desktop_t *d, node_t *n)
                initialize_presel_feedback(n);
        }
 
-       int gap = gapless_monocle && IS_MONOCLE(d) ? 0 : d->window_gap;
+       int gap = gapless_monocle && d->layout == LAYOUT_MONOCLE ? 0 : d->window_gap;
        presel_t *p = n->presel;
        xcb_rectangle_t rect = n->rectangle;
        rect.x = rect.y = 0;
@@ -396,7 +408,7 @@ void draw_border(node_t *n, bool focused_node, bool focused_monitor)
 
        uint32_t border_color_pxl = get_border_color(focused_node, focused_monitor);
        for (node_t *f = first_extrema(n); f != NULL; f = next_leaf(f, n)) {
-               if (f->client != NULL && f->client->border_width > 0) {
+               if (f->client != NULL) {
                        window_draw_border(f->id, border_color_pxl);
                }
        }
@@ -572,6 +584,8 @@ bool resize_client(coordinates_t *loc, resize_handle_t rh, int dx, int dy, bool
                        sr = MIN(1, sr);
                        horizontal_fence->split_ratio = sr;
                }
+               node_t *target_fence = horizontal_fence != NULL ? horizontal_fence : vertical_fence;
+               adjust_ratios(target_fence, target_fence->rectangle);
                arrange(loc->monitor, loc->desktop);
        } else {
                int w = width, h = height;
@@ -716,18 +730,32 @@ void query_pointer(xcb_window_t *win, xcb_point_t *pt)
 
        if (qpr != NULL) {
                if (win != NULL) {
-                       *win = qpr->child;
-                       xcb_point_t pt = {qpr->root_x, qpr->root_y};
-                       for (stacking_list_t *s = stack_tail; s != NULL; s = s->prev) {
-                               if (!s->node->client->shown || s->node->hidden) {
-                                       continue;
+                       if (qpr->child == XCB_NONE) {
+                               xcb_point_t mpt = (xcb_point_t) {qpr->root_x, qpr->root_y};
+                               monitor_t *m = monitor_from_point(mpt);
+                               if (m != NULL) {
+                                       desktop_t *d = m->desk;
+                                       for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) {
+                                               if (n->client == NULL && is_inside(mpt, get_rectangle(m, d, n))) {
+                                                       *win = n->id;
+                                                       break;
+                                               }
+                                       }
                                }
-                               xcb_rectangle_t rect = get_rectangle(NULL, NULL, s->node);
-                               if (is_inside(pt, rect)) {
-                                       if (s->node->id == qpr->child || is_presel_window(qpr->child)) {
-                                               *win = s->node->id;
+                       } else {
+                               *win = qpr->child;
+                               xcb_point_t pt = {qpr->root_x, qpr->root_y};
+                               for (stacking_list_t *s = stack_tail; s != NULL; s = s->prev) {
+                                       if (!s->node->client->shown || s->node->hidden) {
+                                               continue;
+                                       }
+                                       xcb_rectangle_t rect = get_rectangle(NULL, NULL, s->node);
+                                       if (is_inside(pt, rect)) {
+                                               if (s->node->id == qpr->child || is_presel_window(qpr->child)) {
+                                                       *win = s->node->id;
+                                               }
+                                               break;
                                        }
-                                       break;
                                }
                        }
                }