Package: release.debian.org Severity: normal User: [email protected] 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 <[email protected]> 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 <[email protected]> +Maintainer: Debian QA Group <[email protected]> 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 <[email protected]> +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 <[email protected]> +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)

