diff --git a/src/wmspec.c b/src/wmspec.c index 57a72d16..645cd6c5 100644 --- a/src/wmspec.c +++ b/src/wmspec.c @@ -845,10 +845,43 @@ Bool wNETWMGetUsableArea(WScreen *scr, int head, WArea *area) rect = wGetRectForHead(scr, head); - area->x1 = rect.pos.x + area->x1; - area->x2 = rect.pos.x + rect.size.width - area->x2; - area->y1 = rect.pos.y + area->y1; - area->y2 = rect.pos.y + rect.size.height - area->y2; + /* NOTE(gryf): calculation for the reserved area should be preformed for + * current head, but area, which comes form _NET_WM_STRUT, has to be + * calculated relative to entire screen size, i.e. suppose we have three + * heads arranged like this: + * + * ╔════════════════════════╗ + * ║ 0 ║ + * ║ ╠═══════════╗ + * ║ ║ 2 ║ + * ║ ║ ║ + * ╟────────────────────────╫───────────╢ + * ╠════════════════════════╬═══════════╝ + * ║ 1 ║ + * ║ ║ + * ║ ║ + * ║ ║ + * ║ ║ + * ╟────────────────────────╢ + * ╚════════════════════════╝ + * + * where head 0 have resolution 1920x1080, head 1: 1920x1200 and head 2 + * 800x600, so the screen size in this arrangement will be 2720x2280 (1920 + * + 800) x (1080 + 1200). + * + * Bottom line represents some 3rd party panel, which sets properties in + * _NET_WM_STRUT_PARTIAL and optionally _NET_WM_STRUT. + * + * By coincidence, coordinates x1 and y1 from left and top are the same as + * the original data which came from _NET_WM_STRUT, since they meaning + * distance from the edge. + */ + + /* optional reserved space from right */ + area->x2 = scr->scr_width - area->x2; + + /* optional reserved space from bottom */ + area->y2 = scr->scr_height - area->y2; return True; }