From e6ca7ca06f585fa22662443275d44a407f366c9d Mon Sep 17 00:00:00 2001 From: Albert Safin Date: Wed, 19 Feb 2020 00:48:31 +0000 Subject: [PATCH 1/2] Sanitize con and window rect dimensions Make sure they're neither zero (prohibited by X11) nor overflown during subtraction. --- include/util.h | 1 + src/render.c | 4 ++++ src/util.c | 6 ++++++ 3 files changed, 11 insertions(+) diff --git a/include/util.h b/include/util.h index 68b3c68f..8459db10 100644 --- a/include/util.h +++ b/include/util.h @@ -65,6 +65,7 @@ bool rect_contains(Rect rect, uint32_t x, uint32_t y); Rect rect_add(Rect a, Rect b); Rect rect_sub(Rect a, Rect b); bool rect_equals(Rect a, Rect b); +Rect rect_sanitize_dimensions(Rect rect); /** * Returns true if the name consists of only digits. diff --git a/src/render.c b/src/render.c index 112268cc..40704f52 100644 --- a/src/render.c +++ b/src/render.c @@ -64,6 +64,8 @@ void render_con(Con *con) { inset->width -= (2 * con->border_width); inset->height -= (2 * con->border_width); + *inset = rect_sanitize_dimensions(*inset); + /* NB: We used to respect resize increment size hints for tiling * windows up until commit 0db93d9 here. However, since all terminal * emulators cope with ignoring the size hints in a better way than we @@ -121,6 +123,8 @@ void render_con(Con *con) { render_con_dockarea(con, child, ¶ms); } + child->rect = rect_sanitize_dimensions(child->rect); + DLOG("child at (%d, %d) with (%d x %d)\n", child->rect.x, child->rect.y, child->rect.width, child->rect.height); x_raise_con(child); diff --git a/src/util.c b/src/util.c index e9df9575..969dc2a2 100644 --- a/src/util.c +++ b/src/util.c @@ -53,6 +53,12 @@ Rect rect_sub(Rect a, Rect b) { a.height - b.height}; } +Rect rect_sanitize_dimensions(Rect rect) { + rect.width = (int32_t)rect.width <= 0 ? 1 : rect.width; + rect.height = (int32_t)rect.height <= 0 ? 1 : rect.height; + return rect; +} + bool rect_equals(Rect a, Rect b) { return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height; } From 670c23600f30a5f0e417c0d3d256356c73e149b4 Mon Sep 17 00:00:00 2001 From: Albert Safin Date: Wed, 19 Feb 2020 01:07:05 +0000 Subject: [PATCH 2/2] Decoration click/mouse move: iterate children in reverse order In the case of decoration overlap, we should handle the one that is drawn on top, i.e., the last one. --- src/click.c | 2 +- src/handlers.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/click.c b/src/click.c index e5dcfa92..19076252 100644 --- a/src/click.c +++ b/src/click.c @@ -361,7 +361,7 @@ int handle_button_press(xcb_button_press_event_t *event) { /* Check if the click was on the decoration of a child */ Con *child; - TAILQ_FOREACH (child, &(con->nodes_head), nodes) { + TAILQ_FOREACH_REVERSE (child, &(con->nodes_head), nodes_head, nodes) { if (!rect_contains(child->deco_rect, event->event_x, event->event_y)) continue; diff --git a/src/handlers.c b/src/handlers.c index 79e5329b..7926fec5 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -160,7 +160,7 @@ static void handle_enter_notify(xcb_enter_notify_event_t *event) { layout_t layout = (enter_child ? con->parent->layout : con->layout); if (layout == L_DEFAULT) { Con *child; - TAILQ_FOREACH (child, &(con->nodes_head), nodes) { + TAILQ_FOREACH_REVERSE (child, &(con->nodes_head), nodes_head, nodes) { if (rect_contains(child->deco_rect, event->event_x, event->event_y)) { LOG("using child %p / %s instead!\n", child, child->name); con = child; @@ -217,7 +217,7 @@ static void handle_motion_notify(xcb_motion_notify_event_t *event) { /* see over which rect the user is */ Con *current; - TAILQ_FOREACH (current, &(con->nodes_head), nodes) { + TAILQ_FOREACH_REVERSE (current, &(con->nodes_head), nodes_head, nodes) { if (!rect_contains(current->deco_rect, event->event_x, event->event_y)) continue;