monitor.c
// find the dimensions, EXCLUDING STRUTS, of the monitor displaying point x,y
find the dimensions, EXCLUDING STRUTS, of the monitor displaying point x,y
find the dimensions EXCLUDING STRUTS of the monitor displaying point x y
void monitor_dimensions_struts(int x, int y, workarea *mon)
{
	int i;
	for (i = 0; i < sizeof(cache_monitor)/sizeof(workarea); i++)
	{
		workarea *cm = &cache_monitor[i]; if (!cm->w) continue;
		if (INTERSECT(x, y, 1, 1, cm->x-cm->l, cm->y-cm->t, cm->w+cm->l+cm->r, cm->h+cm->t+cm->b))
		{
			memmove(mon, cm, sizeof(workarea));
			return;
		}
	}
	monitor_dimensions(x, y, mon);
	XWindowAttributes *rattr = window_get_attributes(root);
	int left = 0, right = 0, top = 0, bottom = 0;
	Window win;
	winlist_ascend(windows_in_play(), i, win)
	{
		XWindowAttributes *attr = window_get_attributes(win);
		if (attr && !attr->override_redirect
			&& INTERSECT(attr->x, attr->y, attr->width, attr->height, mon->x, mon->y, mon->w, mon->h))
		{
			unsigned long strut[12]; memset(strut, 0, sizeof(strut));
			if (window_get_cardinal_prop(win, netatoms[_NET_WM_STRUT_PARTIAL], strut, 12)
				|| window_get_cardinal_prop(win, netatoms[_NET_WM_STRUT], strut, 4))
			{
				left = MAX(left, strut[0]); right  = MAX(right,  strut[1]);
				top  = MAX(top,  strut[2]); bottom = MAX(bottom, strut[3]);
			}
		}
	}
	mon->l = MIN(mon->w/3, MAX(0, left-mon->x));
	mon->r = MIN(mon->w/3, MAX(0, (mon->x+mon->w)-(rattr->width-right)));
	mon->t = MIN(mon->h/3, MAX(0, top-mon->y));
	mon->b = MIN(mon->h/3, MAX(0, (mon->y+mon->h)-(rattr->height-bottom)));
	mon->x += mon->l; mon->y += mon->t;
	mon->w -= (mon->l+mon->r);
	mon->h -= (mon->t+mon->b);
	for (i = 0; i < sizeof(cache_monitor)/sizeof(workarea); i++)
	{
		workarea *cm = &cache_monitor[i];
		if (!cm->w)
		{
			memmove(cm, mon, sizeof(workarea));
			break;
		}
	}
}
void monitor_dimensions_struts ( int x , int y , workarea * mon ) { int i ; for ( i = 0 ; i < sizeof ( cache_monitor ) / sizeof ( workarea ) ; i ++ ) { workarea * cm = & cache_monitor [ i ] ; if ( ! cm -> w ) continue ; if ( INTERSECT ( x , y , 1 , 1 , cm -> x - cm -> l , cm -> y - cm -> t , cm -> w + cm -> l + cm -> r , cm -> h + cm -> t + cm -> b ) ) { memmove ( mon , cm , sizeof ( workarea ) ) ; return ; } } monitor_dimensions ( x , y , mon ) ; XWindowAttributes * rattr = window_get_attributes ( root ) ; int left = 0 , right = 0 , top = 0 , bottom = 0 ; Window win ; winlist_ascend ( windows_in_play ( ) , i , win ) { XWindowAttributes * attr = window_get_attributes ( win ) ; if ( attr && ! attr -> override_redirect && INTERSECT ( attr -> x , attr -> y , attr -> width , attr -> height , mon -> x , mon -> y , mon -> w , mon -> h ) ) { unsigned long strut [ 12 ] ; memset ( strut , 0 , sizeof ( strut ) ) ; if ( window_get_cardinal_prop ( win , netatoms [ _NET_WM_STRUT_PARTIAL ] , strut , 12 ) || window_get_cardinal_prop ( win , netatoms [ _NET_WM_STRUT ] , strut , 4 ) ) { left = MAX ( left , strut [ 0 ] ) ; right = MAX ( right , strut [ 1 ] ) ; top = MAX ( top , strut [ 2 ] ) ; bottom = MAX ( bottom , strut [ 3 ] ) ; } } } mon -> l = MIN ( mon -> w / 3 , MAX ( 0 , left - mon -> x ) ) ; mon -> r = MIN ( mon -> w / 3 , MAX ( 0 , ( mon -> x + mon -> w ) - ( rattr -> width - right ) ) ) ; mon -> t = MIN ( mon -> h / 3 , MAX ( 0 , top - mon -> y ) ) ; mon -> b = MIN ( mon -> h / 3 , MAX ( 0 , ( mon -> y + mon -> h ) - ( rattr -> height - bottom ) ) ) ; mon -> x += mon -> l ; mon -> y += mon -> t ; mon -> w -= ( mon -> l + mon -> r ) ; mon -> h -= ( mon -> t + mon -> b ) ; for ( i = 0 ; i < sizeof ( cache_monitor ) / sizeof ( workarea ) ; i ++ ) { workarea * cm = & cache_monitor [ i ] ; if ( ! cm -> w ) { memmove ( cm , mon , sizeof ( workarea ) ) ; break ; } } }
find the dimensions, EXCLUDING STRUTS, of the monitor displaying point x,y
find the dimensions EXCLUDING STRUTS of the monitor displaying point x y
// check cache. we may be able to avoid walking all windows // strut cardinals are relative to the root window size, which is not necessarily the monitor size // walk the open apps and check for struts // this is fairly lightweight thanks to some caches // we only pay attention to the first four params // this is no more complex that _NET_WM_STRUT, but newer stuff uses _PARTIAL // limit struts on any side to 1/3 monitor size // update cache. strust change rarely, so this is long-lived. // see handle_propertynotify() also