[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#704071: unblock: openbox/3.5.0-7



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package openbox

The only change in 3.5.0-7 are two patches taken from the upstream
repository that fix a 100% CPU hangup when disabling a RandR output
under certain circumstances (see #697571).

The debdiff is attached.

unblock openbox/3.5.0-7
diff -Nru openbox-3.5.0/debian/changelog openbox-3.5.0/debian/changelog
--- openbox-3.5.0/debian/changelog	2012-12-01 18:39:17.000000000 +0100
+++ openbox-3.5.0/debian/changelog	2013-03-27 14:53:21.000000000 +0100
@@ -1,3 +1,11 @@
+openbox (3.5.0-7) unstable; urgency=low
+
+  * QA upload.
+  * Apply upstream fix for an infinite loop when disabling RandR outputs
+    (Closes: #697571)
+
+ -- Michael Stapelberg <stapelberg@debian.org>  Wed, 27 Mar 2013 14:16:10 +0100
+
 openbox (3.5.0-6) unstable; urgency=low
 
   * Add missing Breaks/Replaces for gnome-panel-control,
diff -Nru openbox-3.5.0/debian/control openbox-3.5.0/debian/control
--- openbox-3.5.0/debian/control	2012-12-01 18:38:36.000000000 +0100
+++ openbox-3.5.0/debian/control	2013-03-27 14:53:20.000000000 +0100
@@ -1,7 +1,7 @@
 Source: openbox
 Section: x11
 Priority: optional
-Maintainer: Nico Golde <nion@debian.org>
+Maintainer: Debian QA Group <packages@qa.debian.org>
 Build-Depends: debhelper (>= 8.1.0~), gettext, libstartup-notification0-dev, libxrender-dev, pkg-config, libglib2.0-dev, libxml2-dev (>= 2.6.0), perl, libxt-dev, libxinerama-dev, libxrandr-dev, libpango1.0-dev, libx11-dev, autoconf, automake1.9, python-xdg, libimlib2-dev, dh-autoreconf, autopoint
 Standards-Version: 3.9.3
 Homepage: http://www.openbox.org
diff -Nru openbox-3.5.0/debian/patches/clever-rectangle-picking.patch openbox-3.5.0/debian/patches/clever-rectangle-picking.patch
--- openbox-3.5.0/debian/patches/clever-rectangle-picking.patch	1970-01-01 01:00:00.000000000 +0100
+++ openbox-3.5.0/debian/patches/clever-rectangle-picking.patch	2013-03-27 14:53:20.000000000 +0100
@@ -0,0 +1,195 @@
+commit d68116c9c9b2c9a9925d872141eff8e301ef3bb3
+Author: Dana Jansens <danakj@orodu.net>
+Date:   Sat Oct 15 23:04:21 2011 -0400
+
+    Pick the monitor most relevant to a rectangle more cleverly.
+    
+    When monitors overlap (this happens with cloning), we were choosing a monitor
+    to associate with a window, for maximization for example, somewhat arbitrarily.
+    
+    Now we have a more clever algorithm that considers the configured primary
+    monitor first, and that does not prefer monitors based on their sizes, but only
+    how much of the window is in the monitor, excluding parts that were claimed
+    by another monitor already.
+
+Index: openbox-3.5.0/openbox/geom.h
+===================================================================
+--- openbox-3.5.0.orig/openbox/geom.h	2013-03-27 13:28:06.462611462 +0100
++++ openbox-3.5.0/openbox/geom.h	2013-03-27 13:29:09.872687284 +0100
+@@ -65,6 +65,8 @@
+ #define RECT_RIGHT(r) ((r).x + (r).width - 1)
+ #define RECT_BOTTOM(r) ((r).y + (r).height - 1)
+ 
++#define RECT_AREA(r) ((r).width * (r).height)
++
+ #define RECT_SET_POINT(r, nx, ny) \
+     (r).x = (nx), (r).y = (ny)
+ #define RECT_SET_SIZE(r, w, h) \
+Index: openbox-3.5.0/openbox/screen.c
+===================================================================
+--- openbox-3.5.0.orig/openbox/screen.c	2013-03-27 13:28:06.462611462 +0100
++++ openbox-3.5.0/openbox/screen.c	2013-03-27 13:29:09.874687318 +0100
+@@ -1372,6 +1372,14 @@
+         b = MAX(b, (*xin_areas)[i].y + (*xin_areas)[i].height - 1);
+     }
+     RECT_SET((*xin_areas)[*nxin], l, t, r - l + 1, b - t + 1);
++
++    for (i = 0; i < *nxin; ++i)
++        ob_debug("Monitor %d @ %d,%d %dx%d\n", i,
++                 (*xin_areas)[i].x, (*xin_areas)[i].y,
++                 (*xin_areas)[i].width, (*xin_areas)[i].height);
++    ob_debug("Full desktop @ %d,%d %dx%d\n",
++             (*xin_areas)[i].x, (*xin_areas)[i].y,
++             (*xin_areas)[i].width, (*xin_areas)[i].height);
+ }
+ 
+ void screen_update_areas(void)
+@@ -1631,27 +1639,135 @@
+     return a;
+ }
+ 
++typedef struct {
++    Rect r;
++    gboolean subtract;
++} RectArithmetic;
++
+ guint screen_find_monitor(const Rect *search)
+ {
+     guint i;
+     guint most = screen_num_monitors;
+-    guint mostv = 0;
++    guint mostpx = 0;
++    GSList *counted = NULL;
+ 
+-    for (i = 0; i < screen_num_monitors; ++i) {
+-        const Rect *area = screen_physical_area_monitor(i);
+-        if (RECT_INTERSECTS_RECT(*area, *search)) {
+-            Rect r;
+-            guint v;
+-
+-            RECT_SET_INTERSECTION(r, *area, *search);
+-            v = r.width * r.height;
+-
+-            if (v > mostv) {
+-                mostv = v;
+-                most = i;
++    /* we want to count the number of pixels search has on each monitor, but not
++       double count.  so if a pixel is counted on monitor A then we should not
++       count it again on monitor B. in the end we want to return the monitor
++       that had the most pixels counted under this scheme.
++
++       this assumes that monitors earlier in the list are more desirable to be
++       considered the search area's monitor.  we try the configured primary
++       monitor first, so it gets the highest preference.
++
++       if we have counted an area A, then we want to subtract the intersection
++       of A with the area on future monitors.
++       but now consider if we count an area B that intersects A. we want to
++       subtract the area B from that counted on future monitors, but not
++       subtract the intersection of A and B twice! so we would add the
++       intersection of A and B back, to account for it being subtracted both
++       for A and B.
++
++       this is the idea behind the algorithm.  we always subtract the full area
++       for monitor M intersected with the search area. we'll call that AREA.
++       but then we go through the list |counted| and for each rectangle in
++       the list that is being subtracted from future monitors, we insert a
++       request to add back the intersection of the subtracted rect with AREA.
++       vice versa for a rect in |counted| that is getting added back.
++    */
++
++    if (config_primary_monitor_index < screen_num_monitors) {
++        const Rect *monitor;
++        Rect on_current_monitor;
++        glong area;
++
++        monitor = screen_physical_area_monitor(config_primary_monitor_index);
++
++        if (RECT_INTERSECTS_RECT(*monitor, *search)) {
++            RECT_SET_INTERSECTION(on_current_monitor, *monitor, *search);
++            area = RECT_AREA(on_current_monitor);
++
++            if (area > mostpx) {
++                mostpx = area;
++                most = config_primary_monitor_index;
+             }
++
++            /* add the intersection rect on the current monitor to the
++               counted list. that's easy for the first one, we just mark it for
++               subtraction */
++            {
++                RectArithmetic *ra = g_slice_new(RectArithmetic);
++                ra->r = on_current_monitor;
++                ra->subtract = TRUE;
++                counted = g_slist_prepend(counted, ra);
++            }
++        }
++    }
++
++    for (i = 0; i < screen_num_monitors; ++i) {
++        const Rect *monitor;
++        Rect on_current_monitor;
++        glong area;
++        GSList *it;
++
++        monitor = screen_physical_area_monitor(i);
++
++        if (i == config_primary_monitor_index)
++            continue;  /* already did this one */
++        if (!RECT_INTERSECTS_RECT(*monitor, *search))
++            continue;  /* nothing to see here */
++
++        RECT_SET_INTERSECTION(on_current_monitor, *monitor, *search);
++        area = RECT_AREA(on_current_monitor);
++
++        /* remove pixels we already counted on any previous monitors. */
++        for (it = counted; it; it = g_slist_next(it)) {
++            RectArithmetic *ra = it->data;
++            Rect intersection;
++
++            RECT_SET_INTERSECTION(intersection, ra->r, *search);
++            if (ra->subtract) area -= RECT_AREA(intersection);
++            else area += RECT_AREA(intersection);
++        }
++
++        if (area > mostpx) {
++            mostpx = area;
++            most = i;
++        }
++
++        /* add the intersection rect on the current monitor I to the counted
++           list.
++           but now we need to compensate for every rectangle R already in the
++           counted list, and add a new rect R' that is the intersection of
++           R and I, but with the reverse subtraction/addition operation.
++        */
++        for (it = counted; it; it = g_slist_next(it)) {
++            RectArithmetic *saved = it->data;
++
++            if (!RECT_INTERSECTS_RECT(saved->r, on_current_monitor))
++                continue;
++            /* we are going to subtract our rect from future monitors, but
++               part of it may already be being subtracted/added, so compensate
++               to not double add/subtract. */
++            RectArithmetic *reverse = g_slice_new(RectArithmetic);
++            RECT_SET_INTERSECTION(reverse->r, saved->r, on_current_monitor);
++            reverse->subtract = !saved->subtract;
++            /* prepend so we can continue thru the list uninterupted */
++            counted = g_slist_prepend(counted, reverse);
++        }
++        {
++            RectArithmetic *ra = g_slice_new(RectArithmetic);
++            ra->r = on_current_monitor;
++            ra->subtract = TRUE;
++            counted = g_slist_prepend(counted, ra);
+         }
+     }
++
++    while (counted) {
++        g_slice_free(RectArithmetic, counted->data);
++        counted = g_slist_delete_link(counted, counted);
++    }
++
+     return most < screen_num_monitors ? most : screen_monitor_primary(FALSE);
+ }
+ 
diff -Nru openbox-3.5.0/debian/patches/series openbox-3.5.0/debian/patches/series
--- openbox-3.5.0/debian/patches/series	2012-06-05 07:25:05.000000000 +0200
+++ openbox-3.5.0/debian/patches/series	2013-03-27 14:53:20.000000000 +0100
@@ -7,3 +7,5 @@
 90_fix_link_obt.patch
 675991_fix_crash_from_gtk3_apps.patch
 666676_wrong_undecorated_window_placement.patch
+clever-rectangle-picking.patch
+use-nearest-monitor.patch
diff -Nru openbox-3.5.0/debian/patches/use-nearest-monitor.patch openbox-3.5.0/debian/patches/use-nearest-monitor.patch
--- openbox-3.5.0/debian/patches/use-nearest-monitor.patch	1970-01-01 01:00:00.000000000 +0100
+++ openbox-3.5.0/debian/patches/use-nearest-monitor.patch	2013-03-27 14:53:20.000000000 +0100
@@ -0,0 +1,116 @@
+commit 01f62ded2fe289fe245f4f05b5825f4bdcbe1dc3
+Author: Dana Jansens <danakj@orodu.net>
+Date:   Sun Sep 30 20:29:45 2012 -0400
+
+    Use the nearest monitor when the search query rect does not intersect any monitor (Fix bug 5500)
+    
+    Previously we would try to find the primary monitor and use that when the search
+    was outside any monitor. However, if the primary monitor is chosen by the mouse
+    position and the mouse is not inside any monitor, we enter infinite recursion
+    trying to find the primary monitor.
+    
+    The nearest monitor is a better metric anyhow, and this ensures
+    screen_find_monitor() is never recursive as it always returns a value without
+    depending on other screen.c methods.
+
+diff --git a/openbox/geom.h b/openbox/geom.h
+index 8ac0e55..8e50834 100644
+--- a/openbox/geom.h
++++ b/openbox/geom.h
+@@ -104,6 +104,25 @@ typedef struct _Rect {
+      (r).height = MIN((a).y + (a).height - 1, \
+                       (b).y + (b).height - 1) - (r).y + 1)
+ 
++/* Returns the shortest manhatten distance between two rects, or 0 if they
++   intersect. */
++static inline gint rect_manhatten_distance(Rect r, Rect o)
++{
++    if (RECT_INTERSECTS_RECT(r, o))
++        return 0;
++
++    gint min_distance = G_MAXINT;
++    if (RECT_RIGHT(o) < RECT_LEFT(r))
++        min_distance = MIN(min_distance, RECT_LEFT(r) - RECT_RIGHT(o));
++    if (RECT_LEFT(o) > RECT_RIGHT(r))
++        min_distance = MIN(min_distance, RECT_LEFT(o) - RECT_RIGHT(r));
++    if (RECT_BOTTOM(o) < RECT_TOP(r))
++        min_distance = MIN(min_distance, RECT_TOP(r) - RECT_BOTTOM(o));
++    if (RECT_TOP(o) > RECT_BOTTOM(r))
++        min_distance = MIN(min_distance, RECT_TOP(o) - RECT_BOTTOM(r));
++    return min_distance;
++}
++
+ typedef struct _Strut {
+     int left;
+     int top;
+diff --git a/openbox/screen.c b/openbox/screen.c
+index 35366be..f4031f5 100644
+--- a/openbox/screen.c
++++ b/openbox/screen.c
+@@ -1644,8 +1644,10 @@ typedef struct {
+ guint screen_find_monitor(const Rect *search)
+ {
+     guint i;
+-    guint most = screen_num_monitors;
++    guint mostpx_index = screen_num_monitors;
+     guint mostpx = 0;
++    guint closest_distance_index = screen_num_monitors;
++    guint closest_distance = G_MAXUINT;
+     GSList *counted = NULL;
+ 
+     /* we want to count the number of pixels search has on each monitor, but not
+@@ -1686,7 +1688,7 @@ guint screen_find_monitor(const Rect *search)
+ 
+             if (area > mostpx) {
+                 mostpx = area;
+-                most = config_primary_monitor_index;
++                mostpx_index = config_primary_monitor_index;
+             }
+ 
+             /* add the intersection rect on the current monitor to the
+@@ -1709,10 +1711,21 @@ guint screen_find_monitor(const Rect *search)
+ 
+         monitor = screen_physical_area_monitor(i);
+ 
++        if (!RECT_INTERSECTS_RECT(*monitor, *search)) {
++            /* If we don't intersect then find the distance between the search
++               rect and the monitor. We'll use the closest monitor from this
++               metric if none of the monitors intersect. */
++            guint distance = rect_manhatten_distance(*monitor, *search);
++
++            if (distance < closest_distance) {
++                closest_distance = distance;
++                closest_distance_index = i;
++            }
++            continue;
++        }
++
+         if (i == config_primary_monitor_index)
+             continue;  /* already did this one */
+-        if (!RECT_INTERSECTS_RECT(*monitor, *search))
+-            continue;  /* nothing to see here */
+ 
+         RECT_SET_INTERSECTION(on_current_monitor, *monitor, *search);
+         area = RECT_AREA(on_current_monitor);
+@@ -1729,7 +1742,7 @@ guint screen_find_monitor(const Rect *search)
+ 
+         if (area > mostpx) {
+             mostpx = area;
+-            most = i;
++            mostpx_index = i;
+         }
+ 
+         /* add the intersection rect on the current monitor I to the counted
+@@ -1765,7 +1778,11 @@ guint screen_find_monitor(const Rect *search)
+         counted = g_slist_delete_link(counted, counted);
+     }
+ 
+-    return most < screen_num_monitors ? most : screen_monitor_primary(FALSE);
++    if (mostpx_index < screen_num_monitors)
++        return mostpx_index;
++
++    g_assert(closest_distance_index < screen_num_monitors);
++    return closest_distance_index;
+ }
+ 
+ const Rect* screen_physical_area_all_monitors(void)

Reply to: