]> Dogcows Code - chaz/openbox/blobdiff - openbox/screen.c
check for damage and render extensions if going to use composite. require them for...
[chaz/openbox] / openbox / screen.c
index a562566ebe1bb1f2f3bb3db3bf91daf01e3a8a56..1ef080752dbfdb50a885b10e27f83d7b3a39a23a 100644 (file)
@@ -66,12 +66,12 @@ Window   screen_support_win;
 Time     screen_desktop_user_time = CurrentTime;
 
 /*! An array of desktops, holding array of areas per monitor */
-static Rect  *monitor_area;
+static Rect  *monitor_area = NULL;
 /*! An array of desktops, holding an array of struts */
-static GSList **struts_top;
-static GSList **struts_left;
-static GSList **struts_right;
-static GSList **struts_bottom;
+static GSList *struts_top = NULL;
+static GSList *struts_left = NULL;
+static GSList *struts_right = NULL;
+static GSList *struts_bottom = NULL;
 
 static ObPagerPopup *desktop_cycle_popup;
 
@@ -364,6 +364,15 @@ void screen_startup(gboolean reconfig)
         return;
     }
 
+#ifdef USE_XCOMPOSITE
+    if (extensions_comp) {
+        /* Redirect window contents to offscreen pixmaps */
+        XCompositeRedirectSubwindows(ob_display,
+                                     RootWindow(ob_display, ob_screen),
+                                     CompositeRedirectAutomatic);
+    }
+#endif
+
     /* get the initial size */
     screen_resize();
 
@@ -496,7 +505,7 @@ void screen_set_num_desktops(guint num)
 {
     guint old;
     gulong *viewport;
-    GList *it;
+    GList *it, *stacking_copy;
 
     g_assert(num > 0);
 
@@ -516,11 +525,21 @@ void screen_set_num_desktops(guint num)
     /* the number of rows/columns will differ */
     screen_update_layout();
 
-    /* move windows on desktops that will no longer exist! */
-    for (it = client_list; it; it = g_list_next(it)) {
-        ObClient *c = it->data;
-        if (c->desktop >= num && c->desktop != DESKTOP_ALL)
-            client_set_desktop(c, num - 1, FALSE);
+    /* move windows on desktops that will no longer exist!
+       make a copy of the list cuz we're changing it */
+    stacking_copy = g_list_copy(stacking_list);
+    for (it = g_list_last(stacking_copy); it; it = g_list_previous(it)) {
+        if (WINDOW_IS_CLIENT(it->data)) {
+            ObClient *c = it->data;
+            if (c->desktop != DESKTOP_ALL && c->desktop >= num)
+                client_set_desktop(c, num - 1, FALSE, TRUE);
+            /* raise all the windows that are on the current desktop which
+               is being merged */
+            else if (screen_desktop == num - 1 &&
+                     (c->desktop == DESKTOP_ALL ||
+                      c->desktop == screen_desktop))
+                stacking_raise(WINDOW_AS_CLIENT(c));
+        }
     }
  
     /* change our struts/area to match (after moving windows) */
@@ -561,7 +580,7 @@ void screen_set_desktop(guint num, gboolean dofocus)
     ignore_start = event_start_ignore_all_enters();
 
     if (moveresize_client)
-        client_set_desktop(moveresize_client, num, TRUE);
+        client_set_desktop(moveresize_client, num, TRUE, FALSE);
 
     /* show windows before hiding the rest to lessen the enter/leave events */
 
@@ -579,6 +598,11 @@ void screen_set_desktop(guint num, gboolean dofocus)
     allow_omni = focus_client && (client_normal(focus_client) &&
                                   focus_client->desktop == DESKTOP_ALL);
 
+    /* the client moved there already so don't move focus. prevent flicker
+       on sendtodesktop + follow */
+    if (focus_client && focus_client->desktop == screen_desktop)
+        dofocus = FALSE;
+
     /* have to try focus here because when you leave an empty desktop
        there is no focus out to watch for. also, we have different rules
        here. we always allow it to look under the mouse pointer if
@@ -1097,15 +1121,21 @@ void screen_install_colormap(ObClient *client, gboolean install)
     (RANGES_INTERSECT(s->bottom_start, s->bottom_end - s->bottom_start + 1, \
                       monitor_area[i].x, monitor_area[i].width))
 
+typedef struct {
+    guint desktop;
+    StrutPartial *strut;
+} ObScreenStrut;
+
 #define RESET_STRUT_LIST(sl) \
-    {if (sl) for (i = 0; sl[i]; ++i) g_slist_free(sl[i]); \
-     sl = g_renew(GSList*, sl, screen_num_desktops + 1); \
-     memset(sl, sizeof(GSList*) * screen_num_desktops, NULL);}
+    (g_slist_free(sl), sl = NULL)
 
 #define ADD_STRUT_TO_LIST(sl, d, s) \
-    {for (i = 0; i < screen_num_desktops; ++i) \
-         if (i == d || d == DESKTOP_ALL) \
-             sl[i] = g_slist_prepend(sl[i], s);}
+{ \
+    ObScreenStrut *ss = g_new(ObScreenStrut, 1); \
+    ss->desktop = d; \
+    ss->strut = s;  \
+    sl = g_slist_prepend(sl, ss); \
+}
 
 void screen_update_areas()
 {
@@ -1163,25 +1193,29 @@ void screen_update_areas()
 
             /* only add the strut to the area if it touches the monitor */
 
-            for (sit = struts_left[j]; sit; sit = g_slist_next(sit)) {
-                StrutPartial *s = sit->data;
-                if (STRUT_LEFT_ON_MONITOR(s, i))
-                    l = MAX(l, s->left);
+            for (sit = struts_left; sit; sit = g_slist_next(sit)) {
+                ObScreenStrut *s = sit->data;
+                if ((s->desktop == j || s->desktop == DESKTOP_ALL) &&
+                    STRUT_LEFT_ON_MONITOR(s->strut, i))
+                    l = MAX(l, s->strut->left);
             }
-            for (sit = struts_top[j]; sit; sit = g_slist_next(sit)) {
-                StrutPartial *s = sit->data;
-                if (STRUT_TOP_ON_MONITOR(s, i))
-                    t = MAX(t, s->top);
+            for (sit = struts_top; sit; sit = g_slist_next(sit)) {
+                ObScreenStrut *s = sit->data;
+                if ((s->desktop == j || s->desktop == DESKTOP_ALL) &&
+                    STRUT_TOP_ON_MONITOR(s->strut, i))
+                    t = MAX(t, s->strut->top);
             }
-            for (sit = struts_right[j]; sit; sit = g_slist_next(sit)) {
-                StrutPartial *s = sit->data;
-                if (STRUT_RIGHT_ON_MONITOR(s, i))
-                    r = MAX(r, s->right);
+            for (sit = struts_right; sit; sit = g_slist_next(sit)) {
+                ObScreenStrut *s = sit->data;
+                if ((s->desktop == j || s->desktop == DESKTOP_ALL) &&
+                    STRUT_RIGHT_ON_MONITOR(s->strut, i))
+                    r = MAX(r, s->strut->right);
             }
-            for (sit = struts_bottom[j]; sit; sit = g_slist_next(sit)) {
-                StrutPartial *s = sit->data;
-                if (STRUT_BOTTOM_ON_MONITOR(s, i))
-                    b = MAX(b, s->bottom);
+            for (sit = struts_bottom; sit; sit = g_slist_next(sit)) {
+                ObScreenStrut *s = sit->data;
+                if ((s->desktop == j || s->desktop == DESKTOP_ALL) &&
+                    STRUT_BOTTOM_ON_MONITOR(s->strut, i))
+                    b = MAX(b, s->strut->bottom);
             }
 
             /* based on these margins, set the work area for the
@@ -1196,20 +1230,8 @@ void screen_update_areas()
                 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);
-        }
-    }
+    for (it = client_list; it; it = g_list_next(it))
+        client_reconfigure(it->data, FALSE);
 
     g_free(dims);
 }
@@ -1255,16 +1277,16 @@ Rect* screen_area_all_monitors(guint desktop)
                       s->bottom_start, s->bottom_end - s->bottom_start + 1))
 
 #define STRUT_LEFT_IGNORE(s, us, search) \
-    (head != SCREEN_AREA_ALL_MONITORS || !us || \
+    (head == SCREEN_AREA_ALL_MONITORS && us && \
      RECT_LEFT(monitor_area[i]) + s->left > RECT_LEFT(*search))
 #define STRUT_RIGHT_IGNORE(s, us, search) \
-    (head != SCREEN_AREA_ALL_MONITORS || !us || \
+    (head == SCREEN_AREA_ALL_MONITORS && us && \
      RECT_RIGHT(monitor_area[i]) - s->right < RECT_RIGHT(*search))
 #define STRUT_TOP_IGNORE(s, us, search) \
-    (head != SCREEN_AREA_ALL_MONITORS || !us || \
+    (head == SCREEN_AREA_ALL_MONITORS && us && \
      RECT_TOP(monitor_area[i]) + s->top > RECT_TOP(*search))
 #define STRUT_BOTTOM_IGNORE(s, us, search) \
-    (head != SCREEN_AREA_ALL_MONITORS || !us || \
+    (head == SCREEN_AREA_ALL_MONITORS && us && \
      RECT_BOTTOM(monitor_area[i]) - s->bottom < RECT_BOTTOM(*search))
 
 Rect* screen_area(guint desktop, guint head, Rect *search)
@@ -1302,16 +1324,18 @@ Rect* screen_area(guint desktop, guint head, Rect *search)
         ar = r = RECT_LEFT(monitor_area[screen_num_monitors]);
         ab = b = RECT_TOP(monitor_area[screen_num_monitors]);
         for (i = 0; i < screen_num_monitors; ++i) {
+            /* add the monitor if applicable */
             if (RANGES_INTERSECT(search->x, search->width,
-                                 monitor_area[i].x, monitor_area[i].width) ||
-                RANGES_INTERSECT(search->y, search->height,
+                                 monitor_area[i].x, monitor_area[i].width))
+            {
+                at = t = MIN(t, RECT_TOP(monitor_area[i]));
+                ab = b = MAX(b, RECT_BOTTOM(monitor_area[i]));
+            }
+            if (RANGES_INTERSECT(search->y, search->height,
                                  monitor_area[i].y, monitor_area[i].height))
             {
-                /* add the monitor */
                 al = l = MIN(l, RECT_LEFT(monitor_area[i]));
-                at = t = MIN(t, RECT_TOP(monitor_area[i]));
                 ar = r = MAX(r, RECT_RIGHT(monitor_area[i]));
-                ab = b = MAX(b, RECT_BOTTOM(monitor_area[i]));
             }
         }
     } else {
@@ -1327,29 +1351,33 @@ Rect* screen_area(guint desktop, guint head, Rect *search)
         for (i = 0; i < screen_num_monitors; ++i) {
             if (head != SCREEN_AREA_ALL_MONITORS && head != i) continue;
 
-            for (it = struts_left[d]; it; it = g_slist_next(it)) {
-                StrutPartial *s = it->data;
-                if (STRUT_LEFT_IN_SEARCH(s, search) &&
-                    !STRUT_LEFT_IGNORE(s, us, search))
-                    l = MAX(l, al + s->left);
+            for (it = struts_left; it; it = g_slist_next(it)) {
+                ObScreenStrut *s = it->data;
+                if ((s->desktop == d || s->desktop == DESKTOP_ALL) &&
+                    STRUT_LEFT_IN_SEARCH(s->strut, search) &&
+                    !STRUT_LEFT_IGNORE(s->strut, us, search))
+                    l = MAX(l, al + s->strut->left);
             }
-            for (it = struts_top[d]; it; it = g_slist_next(it)) {
-                StrutPartial *s = it->data;
-                if (STRUT_TOP_IN_SEARCH(s, search) &&
-                    !STRUT_TOP_IGNORE(s, us, search))
-                    t = MAX(t, al + s->top);
+            for (it = struts_top; it; it = g_slist_next(it)) {
+                ObScreenStrut *s = it->data;
+                if ((s->desktop == d || s->desktop == DESKTOP_ALL) &&
+                    STRUT_TOP_IN_SEARCH(s->strut, search) &&
+                    !STRUT_TOP_IGNORE(s->strut, us, search))
+                    t = MAX(t, at + s->strut->top);
             }
-            for (it = struts_right[d]; it; it = g_slist_next(it)) {
-                StrutPartial *s = it->data;
-                if (STRUT_RIGHT_IN_SEARCH(s, search) &&
-                    !STRUT_RIGHT_IGNORE(s, us, search))
-                    r = MIN(r, ar - s->right);
+            for (it = struts_right; it; it = g_slist_next(it)) {
+                ObScreenStrut *s = it->data;
+                if ((s->desktop == d || s->desktop == DESKTOP_ALL) &&
+                    STRUT_RIGHT_IN_SEARCH(s->strut, search) &&
+                    !STRUT_RIGHT_IGNORE(s->strut, us, search))
+                    r = MIN(r, ar - s->strut->right);
             }
-            for (it = struts_bottom[d]; it; it = g_slist_next(it)) {
-                StrutPartial *s = it->data;
-                if (STRUT_BOTTOM_IN_SEARCH(s, search) &&
-                    !STRUT_BOTTOM_IGNORE(s, us, search))
-                    r = MIN(r, ar - s->bottom);
+            for (it = struts_bottom; it; it = g_slist_next(it)) {
+                ObScreenStrut *s = it->data;
+                if ((s->desktop == d || s->desktop == DESKTOP_ALL) &&
+                    STRUT_BOTTOM_IN_SEARCH(s->strut, search) &&
+                    !STRUT_BOTTOM_IGNORE(s->strut, us, search))
+                    b = MIN(b, ab - s->strut->bottom);
             }
 
             /* limit to this monitor */
This page took 0.029009 seconds and 4 git commands to generate.