From 906cbeed61d134b846de0d4a02fad61061089004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Fri, 6 Jun 2014 07:58:20 +0200 Subject: [PATCH] boxes: Ignore struts that don't attach to the side they claim Like the _NET_WM_STRUT/_NET_WM_STRUT_PARTIAL client properties, _NET_WORKAREA is defined in terms of screen geometry rather than taking individual monitors into account. However we do want to allow system chrome to be attached to a monitor edge rather than a screen edges under some circumstances. As not all clients can be assumed to deal gracefully with the resulting workarea, use those "struts" only internally for constraining windows, but ignore them when exporting _NET_WORKAREA. https://bugzilla.gnome.org/show_bug.cgi?id=730527 --- src/core/boxes.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/core/boxes.c b/src/core/boxes.c index 3ab01ff37..2a70497ca 100644 --- a/src/core/boxes.c +++ b/src/core/boxes.c @@ -546,6 +546,26 @@ compare_rect_areas (gconstpointer a, gconstpointer b) return b_area - a_area; /* positive ret value denotes b > a, ... */ } +/* ... and another helper for get_minimal_spanning_set_for_region()... */ +static gboolean +check_strut_align (MetaStrut *strut, const MetaRectangle *rect) +{ + /* Check whether @strut actually aligns to the side of @rect it claims */ + switch (strut->side) + { + case META_SIDE_TOP: + return BOX_TOP (strut->rect) <= BOX_TOP (*rect); + case META_SIDE_BOTTOM: + return BOX_BOTTOM (strut->rect) >= BOX_BOTTOM (*rect); + case META_SIDE_LEFT: + return BOX_LEFT (strut->rect) <= BOX_LEFT (*rect); + case META_SIDE_RIGHT: + return BOX_RIGHT (strut->rect) >= BOX_RIGHT (*rect); + default: + return FALSE; + } +} + /** * meta_rectangle_get_minimal_spanning_set_for_region: * @basic_rect: Input rectangle @@ -630,7 +650,8 @@ meta_rectangle_get_minimal_spanning_set_for_region ( for (strut_iter = all_struts; strut_iter; strut_iter = strut_iter->next) { GList *rect_iter; - MetaRectangle *strut_rect = &((MetaStrut*)strut_iter->data)->rect; + MetaStrut *strut = (MetaStrut*)strut_iter->data; + MetaRectangle *strut_rect = &strut->rect; tmp_list = ret; ret = NULL; @@ -638,7 +659,9 @@ meta_rectangle_get_minimal_spanning_set_for_region ( while (rect_iter) { MetaRectangle *rect = (MetaRectangle*) rect_iter->data; - if (!meta_rectangle_overlap (rect, strut_rect)) + + if (!meta_rectangle_overlap (strut_rect, rect) || + !check_strut_align (strut, basic_rect)) ret = g_list_prepend (ret, rect); else {