diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 5705214..b150ba0 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -6710,54 +6710,86 @@ void QWidget::setTabOrder(QWidget* first, QWidget *second)
         return;
     }
 
-    QWidget *fp = first->focusProxy();
-    if (fp) {
+    QWidget *fpx = first->focusProxy();
+    QWidget *f_last_focus_child = 0;
+    if (fpx) {
         // If first is redirected, set first to the last child of first
         // that can take keyboard focus so that second is inserted after
         // that last child, and the focus order within first is (more
         // likely to be) preserved.
         QList<QWidget *> l = first->findChildren<QWidget *>();
-        for (int i = l.size()-1; i >= 0; --i) {
-            QWidget * next = l.at(i);
-            if (next->window() == fp->window()) {
-                fp = next;
-                if (fp->focusPolicy() != Qt::NoFocus)
-                    break;
-            }
+        QWidget * next = fpx; //NOTE: we start from "first->focusProxy()"
+        while (next->window() == fpx->window() && l.contains(next)) {
+            if (next->focusPolicy() != Qt::NoFocus)
+                f_last_focus_child = next;
+            next = next->d_func()->focus_next; // i.e. next->nextInFocusChain();
         }
-        first = fp;
+        if (f_last_focus_child == 0)
+            f_last_focus_child = fpx;
+    }
+    else {
+        f_last_focus_child = first;
     }
 
-    if (fp == second)
+    if (f_last_focus_child == second)
         return;
 
-    if (QWidget *sp = second->focusProxy())
-        second = sp;
+    QWidget *spx = second->focusProxy();
+    QWidget * s_last_focus_child = 0;
+    if (spx) {
+        QList<QWidget *> l = qFindChildren<QWidget *>(second);
+        QWidget * next = second; //NOTE: we start from "second"
+        while (next->window() == spx->window() && l.contains(next)) {
+            if (next->focusPolicy() != Qt::NoFocus)
+                s_last_focus_child = next;
+            next = next->d_func()->focus_next; // i.e. next->nextInFocusChain();
+        }
+        if (s_last_focus_child == 0)
+            s_last_focus_child = spx;
+    }
+    else {
+        s_last_focus_child = second;
+    }
 
-//    QWidget *fp = first->d_func()->focus_prev;
-    QWidget *fn = first->d_func()->focus_next;
+    QWidget *fn = f_last_focus_child->d_func()->focus_next;
 
-    if (fn == second || first == second)
+    if (fn == s_last_focus_child || f_last_focus_child == second)
         return;
 
+    // we "cut out" part from "second" to "s_last_focus_child"; keep track here of left-over 
+    // "loose ends" which should get tied up:
     QWidget *sp = second->d_func()->focus_prev;
-    QWidget *sn = second->d_func()->focus_next;
+    QWidget *sn = s_last_focus_child->d_func()->focus_next;
 
-    fn->d_func()->focus_prev = second;
-    first->d_func()->focus_next = second;
+    // place "second" after "first.lastFocusChild"
+    second->d_func()->focus_prev = f_last_focus_child;
+    f_last_focus_child->d_func()->focus_next = second;
 
-    second->d_func()->focus_next = fn;
-    second->d_func()->focus_prev = first;
+    // place "second.lastFocusChild" before first.lastFocusChild->nextInFocusChain().
+    fn->d_func()->focus_prev = s_last_focus_child;
+    s_last_focus_child->d_func()->focus_next = fn;
 
     sp->d_func()->focus_next = sn;
     sn->d_func()->focus_prev = sp;
 
 
-    Q_ASSERT(first->d_func()->focus_next->d_func()->focus_prev == first);
-    Q_ASSERT(first->d_func()->focus_prev->d_func()->focus_next == first);
-
     Q_ASSERT(second->d_func()->focus_next->d_func()->focus_prev == second);
     Q_ASSERT(second->d_func()->focus_prev->d_func()->focus_next == second);
+
+    Q_ASSERT(f_last_focus_child->d_func()->focus_prev->d_func()->focus_next == f_last_focus_child);
+    Q_ASSERT(f_last_focus_child->d_func()->focus_next->d_func()->focus_prev == f_last_focus_child);
+
+    Q_ASSERT(fn->d_func()->focus_next->d_func()->focus_prev == fn);
+    Q_ASSERT(fn->d_func()->focus_prev->d_func()->focus_next == fn);
+
+    Q_ASSERT(s_last_focus_child->d_func()->focus_prev->d_func()->focus_next == s_last_focus_child);
+    Q_ASSERT(s_last_focus_child->d_func()->focus_next->d_func()->focus_prev == s_last_focus_child);
+
+    Q_ASSERT(sp->d_func()->focus_next->d_func()->focus_prev == sp);
+    Q_ASSERT(sp->d_func()->focus_prev->d_func()->focus_next == sp);
+
+    Q_ASSERT(sn->d_func()->focus_prev->d_func()->focus_next == sn);
+    Q_ASSERT(sn->d_func()->focus_next->d_func()->focus_prev == sn);
 }
 
 /*!\internal
