Rewritten dirFocus. Now works.
    Tomas Janousek <tomi@nomi.cz>

Index: src/FocusControl.cc
===================================================================
--- src/FocusControl.cc	(revision 4690)
+++ src/FocusControl.cc	(working copy)
@@ -268,15 +268,16 @@
 
     // we scan through the list looking for the window that is "closest"
     // in the given direction
+
+    bool horizontal = (dir == FOCUSLEFT || dir == FOCUSRIGHT);
+    bool positive = (dir == FOCUSRIGHT || dir == FOCUSDOWN);
     
     FluxboxWindow *foundwin = 0;
-    int weight = 999999, exposure = 0; // extreme values
-    int borderW = m_screen.winFrameTheme().border().width(),
-        top = win.y(), 
-        bottom = win.y() + win.height() + 2*borderW,
-        left = win.x(),
-        right = win.x() + win.width() + 2*borderW;
+    int distance = INT_MAX;
 
+    int x = win.x() + win.width() / 2,
+	y = win.y() + win.height() / 2;
+
     Workspace::Windows &wins = m_screen.currentWorkspace()->windowList();
     Workspace::Windows::iterator it = wins.begin();
     for (; it != wins.end(); ++it) {
@@ -285,81 +286,32 @@
             || (*it)->isFocusHidden() 
             || !(*it)->winClient().acceptsFocus()) 
             continue; // skip self
+
+	int cx = (*it)->x() + (*it)->width() / 2,
+	    cy = (*it)->y() + (*it)->height() / 2;
         
-        // we check things against an edge, and within the bounds (draw a picture)
-        int edge=0, upper=0, lower=0, oedge=0, oupper=0, olower=0;
+	/* Throw out windows on the opposite side. */
+	int limit = horizontal ? x : y,
+	    value = horizontal ? cx : cy;
+	if ((positive && value <= limit) || (!positive && value >= limit))
+	    continue;
 
-        int otop = (*it)->y(), 
-            // 2 * border = border on each side 
-            obottom = (*it)->y() + (*it)->height() + 2*borderW,
-            oleft = (*it)->x(),
-            // 2 * border = border on each side
-            oright = (*it)->x() + (*it)->width() + 2*borderW;
+	/* Calculate the distance, considering the selected direction more
+	 * important */
+	int cdistance = (horizontal ? 1 : 32) * (x - cx) * (x - cx) +
+	    (!horizontal ? 1 : 32) * (y - cy) * (y - cy);
 
-        // check if they intersect
-        switch (dir) {
-        case FOCUSUP:
-            edge = obottom;
-            oedge = bottom;
-            upper = left;
-            oupper = oleft;
-            lower = right;
-            olower = oright;
-            break;
-        case FOCUSDOWN:
-            edge = top;
-            oedge = otop;
-            upper = left;
-            oupper = oleft;
-            lower = right;
-            olower = oright;
-            break;
-        case FOCUSLEFT:
-            edge = oright;
-            oedge = right;
-            upper = top;
-            oupper = otop;
-            lower = bottom;
-            olower = obottom;
-            break;
-        case FOCUSRIGHT:
-            edge = left;
-            oedge = oleft;
-            upper = top;
-            oupper = otop;
-            lower = bottom;
-            olower = obottom;
-            break;
-        }
-
-        if (oedge < edge) 
-            continue; // not in the right direction
-
-        if (olower <= upper || oupper >= lower) {
-            // outside our horz bounds, get a heavy weight penalty
-            int myweight = 100000 + oedge - edge + abs(upper-oupper)+abs(lower-olower);
-            if (myweight < weight) {
-                foundwin = *it;
-                exposure = 0;
-                weight = myweight;
-            }
-        } else if ((oedge - edge) < weight) {
-            foundwin = *it;
-            weight = oedge - edge;
-            exposure = ((lower < olower)?lower:olower) - ((upper > oupper)?upper:oupper);
-        } else if (foundwin && oedge - edge == weight) {
-            int myexp = ((lower < olower)?lower:olower) - ((upper > oupper)?upper:oupper);
-            if (myexp > exposure) {
-                foundwin = *it;
-                // weight is same
-                exposure = myexp;
-            }
-        } // else not improvement
+	/* Is it better than our current guess? */
+	if (cdistance < distance) {
+	    distance = cdistance;
+	    foundwin = *it;
+	}
     }
 
-    if (foundwin) 
+    if (foundwin) {
+	foundwin->raise();
         foundwin->setInputFocus();
-
+    }
 }
 
 void FocusControl::removeClient(WinClient &client) {
