+ GSList *sit;
+
+ ob_debug("updating screen areas\n");
+
+ g_free(monitor_area);
+ extensions_xinerama_screens(&monitor_area, &screen_num_monitors);
+
+ dims = g_new(gulong, 4 * screen_num_desktops * screen_num_monitors);
+
+ g_slist_free(struts_left); struts_left = NULL;
+ g_slist_free(struts_top); struts_top = NULL;
+ g_slist_free(struts_right); struts_right = NULL;
+ g_slist_free(struts_bottom); struts_bottom = NULL;
+
+ /* collect the struts */
+ for (it = client_list; it; it = g_list_next(it)) {
+ ObClient *c = it->data;
+ if (c->strut.left)
+ struts_left = g_slist_prepend(struts_left, &c->strut);
+ if (c->strut.top)
+ struts_top = g_slist_prepend(struts_top, &c->strut);
+ if (c->strut.right)
+ struts_right = g_slist_prepend(struts_right, &c->strut);
+ if (c->strut.bottom)
+ struts_bottom = g_slist_prepend(struts_bottom, &c->strut);
+ }
+ if (dock_strut.left)
+ struts_left = g_slist_prepend(struts_left, &dock_strut);
+ if (dock_strut.top)
+ struts_top = g_slist_prepend(struts_top, &dock_strut);
+ if (dock_strut.right)
+ struts_right = g_slist_prepend(struts_right, &dock_strut);
+ if (dock_strut.bottom)
+ struts_bottom = g_slist_prepend(struts_bottom, &dock_strut);
+
+ /* set up the work areas to be full screen */
+ for (i = 0; i < screen_num_monitors; ++i)
+ for (j = 0; j < screen_num_desktops; ++j) {
+ dims[i * j + 0] = monitor_area[i].x;
+ dims[i * j + 1] = monitor_area[i].y;
+ dims[i * j + 2] = monitor_area[i].width;
+ dims[i * j + 3] = monitor_area[i].height;
+ }
+
+ /* calculate the work areas from the struts */
+ for (i = 0; i < screen_num_monitors; ++i)
+ for (j = 0; j < screen_num_desktops; ++j) {
+ gint l = 0, r = 0, t = 0, b = 0;
+
+ /* only add the strut to the area if it touches the monitor */
+
+ for (sit = struts_left; sit; sit = g_slist_next(sit)) {
+ StrutPartial *s = sit->data;
+ if (RANGE_INTERSECT
+ (s->left_start, s->left_end - s->left_start + 1,
+ monitor_area[i].y, monitor_area[i].height))
+ l = MAX(l, s->left);
+ }
+ for (sit = struts_top; sit; sit = g_slist_next(sit)) {
+ StrutPartial *s = sit->data;
+ if (RANGE_INTERSECT
+ (s->top_start, s->top_end - s->top_start + 1,
+ monitor_area[i].x, monitor_area[i].width))
+ t = MAX(t, s->top);
+ }
+ for (sit = struts_right; sit; sit = g_slist_next(sit)) {
+ StrutPartial *s = sit->data;
+ if (RANGE_INTERSECT
+ (s->right_start, s->right_end - s->right_start + 1,
+ monitor_area[i].y, monitor_area[i].height))
+ r = MAX(r, s->right);
+ }
+ for (sit = struts_bottom; sit; sit = g_slist_next(sit)) {
+ StrutPartial *s = sit->data;
+ if (RANGE_INTERSECT
+ (s->bottom_start, s->bottom_end - s->bottom_start + 1,
+ monitor_area[i].x, monitor_area[i].width))
+ b = MAX(b, s->bottom);
+ }
+
+ /* based on these margins, set the work area for the
+ monitor/desktop */
+ dims[i * j + 0] += l;
+ dims[i * j + 1] += t;
+ dims[i * j + 2] -= l + r;
+ dims[i * j + 3] -= t + b;
+ }
+
+ PROP_SETA32(RootWindow(ob_display, ob_screen), net_workarea, cardinal,
+ dims, 4 * screen_num_desktops * screen_num_monitors);
+
+ /* the area has changed, adjust all the windows if they need it */
+ for (it = client_list; it; it = g_list_next(it)) {
+ gint x, y, w, h, lw, lh;
+ ObClient *client = it->data;
+
+ RECT_TO_DIMS(client->area, x, y, w, h);
+ client_try_configure(client, &x, &y, &w, &h, &lw, &lh, FALSE);
+ if (!RECT_EQUAL_DIMS(client->area, x, y, w, h)) {
+ gulong ignore_start;
+
+ ignore_start = event_start_ignore_all_enters();
+ client_configure(client, x, y, w, h, FALSE, TRUE);
+ event_end_ignore_all_enters(ignore_start);
+ }
+ }
+
+ g_free(dims);
+}
+
+Rect* screen_area(guint desktop, Rect *search)
+{