src/gui/kernel/qwidget_x11.cpp
changeset 30 5dc02b23752f
parent 19 fcece45ef507
child 33 3e2da88830cd
--- a/src/gui/kernel/qwidget_x11.cpp	Wed Jun 23 19:07:03 2010 +0300
+++ b/src/gui/kernel/qwidget_x11.cpp	Tue Jul 06 15:10:48 2010 +0300
@@ -49,7 +49,7 @@
 #include "qbitmap.h"
 #include "qlayout.h"
 #include "qtextcodec.h"
-#include "qdatetime.h"
+#include "qelapsedtimer.h"
 #include "qcursor.h"
 #include "qstack.h"
 #include "qcolormap.h"
@@ -352,7 +352,7 @@
         return;
     QApplication::flush();
     XEvent ev;
-    QTime t;
+    QElapsedTimer t;
     t.start();
     static const int maximumWaitTime = 2000;
     if (!w->testAttribute(Qt::WA_WState_Created))
@@ -780,7 +780,7 @@
         XWMHints wm_hints;                        // window manager hints
         memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
         wm_hints.flags = InputHint | StateHint | WindowGroupHint;
-        wm_hints.input = True;
+        wm_hints.input = q->testAttribute(Qt::WA_X11DoNotAcceptFocus) ? False : True;
         wm_hints.initial_state = NormalState;
         wm_hints.window_group = X11->wm_client_leader;
 
@@ -1166,7 +1166,7 @@
     adjustFlags(data.window_flags, q);
     // keep compatibility with previous versions, we need to preserve the created state
     // (but we recreate the winId for the widget being reparented, again for compatibility)
-    if (wasCreated || (!q->isWindow() && parent->testAttribute(Qt::WA_WState_Created)))
+    if (wasCreated)
         createWinId();
     if (q->isWindow() || (!parent || parent->isVisible()) || explicitlyHidden)
         q->setAttribute(Qt::WA_WState_Hidden);
@@ -1641,7 +1641,29 @@
         if (X11->userTime == 0)
             X11->userTime = X11->time;
         qt_net_update_user_time(tlw, X11->userTime);
-        XSetInputFocus(X11->display, tlw->internalWinId(), XRevertToParent, X11->time);
+
+        if (X11->isSupportedByWM(ATOM(_NET_ACTIVE_WINDOW))
+            && !(tlw->windowFlags() & Qt::X11BypassWindowManagerHint)) {
+            XEvent e;
+            e.xclient.type = ClientMessage;
+            e.xclient.message_type = ATOM(_NET_ACTIVE_WINDOW);
+            e.xclient.display = X11->display;
+            e.xclient.window = tlw->internalWinId();
+            e.xclient.format = 32;
+            e.xclient.data.l[0] = 1;     // 1 == application
+            e.xclient.data.l[1] = X11->userTime;
+            if (QWidget *aw = QApplication::activeWindow())
+                e.xclient.data.l[2] = aw->internalWinId();
+            else
+                e.xclient.data.l[2] = XNone;
+            e.xclient.data.l[3] = 0;
+            e.xclient.data.l[4] = 0;
+            XSendEvent(X11->display, RootWindow(X11->display, tlw->x11Info().screen()),
+                       false, SubstructureNotifyMask | SubstructureRedirectMask, &e);
+        } else {
+            if (!qt_widget_private(tlw)->topData()->waitingForMapNotify)
+                XSetInputFocus(X11->display, tlw->internalWinId(), XRevertToParent, X11->time);
+        }
     }
 }
 
@@ -2978,7 +3000,7 @@
             return X11->solid_fills[i].picture;
     }
     // none found, replace one
-    int i = rand() % 16;
+    int i = qrand() % 16;
 
     if (X11->solid_fills[i].screen != screen && X11->solid_fills[i].picture) {
         XRenderFreePicture (X11->display, X11->solid_fills[i].picture);
@@ -3030,4 +3052,24 @@
     xinfo->setX11Data(xd);
 }
 
+void QWidgetPrivate::updateX11AcceptFocus()
+{
+    Q_Q(QWidget);
+    if (!q->isWindow() || !q->internalWinId())
+        return;
+
+    XWMHints *h = XGetWMHints(X11->display, q->internalWinId());
+    XWMHints wm_hints;
+    if (!h) {
+        memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
+        h = &wm_hints;
+    }
+    h->flags |= InputHint;
+    h->input = q->testAttribute(Qt::WA_X11DoNotAcceptFocus) ? False : True;
+
+    XSetWMHints(X11->display, q->internalWinId(), h);
+    if (h != &wm_hints)
+        XFree((char *)h);
+}
+
 QT_END_NAMESPACE