src/gui/kernel/qwidget_x11.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gui/kernel/qwidget_x11.cpp	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,3029 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qevent.h"
+#include "qwidget.h"
+#include "qdesktopwidget.h"
+#include "qapplication.h"
+#include "qapplication_p.h"
+#include "qnamespace.h"
+#include "qpainter.h"
+#include "qbitmap.h"
+#include "qlayout.h"
+#include "qtextcodec.h"
+#include "qdatetime.h"
+#include "qcursor.h"
+#include "qstack.h"
+#include "qcolormap.h"
+#include "qdebug.h"
+#include "qmenu.h"
+#include "private/qmenu_p.h"
+#include "private/qbackingstore_p.h"
+#include "private/qwindowsurface_x11_p.h"
+
+//extern bool qt_sendSpontaneousEvent(QObject *, QEvent *); //qapplication_x11.cpp
+
+#include <private/qpixmap_x11_p.h>
+#include <private/qpaintengine_x11_p.h>
+#include "qt_x11_p.h"
+#include "qx11info_x11.h"
+
+#include <stdlib.h>
+
+//#define ALIEN_DEBUG
+
+// defined in qapplication_x11.cpp
+//bool qt_wstate_iconified(WId);
+//void qt_updated_rootinfo();
+
+
+#if !defined(QT_NO_IM)
+#include "qinputcontext.h"
+#include "qinputcontextfactory.h"
+#endif
+
+#include "qwidget_p.h"
+
+#define XCOORD_MAX 16383
+#define WRECT_MAX 8191
+
+QT_BEGIN_NAMESPACE
+
+extern bool qt_nograb();
+
+QWidget *QWidgetPrivate::mouseGrabber = 0;
+QWidget *QWidgetPrivate::keyboardGrabber = 0;
+
+void qt_net_remove_user_time(QWidget *tlw);
+void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp);
+
+int qt_x11_create_desktop_on_screen = -1;
+
+extern void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp);
+
+// MWM support
+struct QtMWMHints {
+    ulong flags, functions, decorations;
+    long input_mode;
+    ulong status;
+};
+
+enum {
+    MWM_HINTS_FUNCTIONS   = (1L << 0),
+
+    MWM_FUNC_ALL      = (1L << 0),
+    MWM_FUNC_RESIZE   = (1L << 1),
+    MWM_FUNC_MOVE     = (1L << 2),
+    MWM_FUNC_MINIMIZE = (1L << 3),
+    MWM_FUNC_MAXIMIZE = (1L << 4),
+    MWM_FUNC_CLOSE    = (1L << 5),
+
+    MWM_HINTS_DECORATIONS = (1L << 1),
+
+    MWM_DECOR_ALL      = (1L << 0),
+    MWM_DECOR_BORDER   = (1L << 1),
+    MWM_DECOR_RESIZEH  = (1L << 2),
+    MWM_DECOR_TITLE    = (1L << 3),
+    MWM_DECOR_MENU     = (1L << 4),
+    MWM_DECOR_MINIMIZE = (1L << 5),
+    MWM_DECOR_MAXIMIZE = (1L << 6),
+
+    MWM_HINTS_INPUT_MODE = (1L << 2),
+
+    MWM_INPUT_MODELESS                  = 0L,
+    MWM_INPUT_PRIMARY_APPLICATION_MODAL = 1L,
+    MWM_INPUT_FULL_APPLICATION_MODAL    = 3L
+};
+
+
+static QtMWMHints GetMWMHints(Display *display, Window window)
+{
+    QtMWMHints mwmhints;
+
+    Atom type;
+    int format;
+    ulong nitems, bytesLeft;
+    uchar *data = 0;
+    if ((XGetWindowProperty(display, window, ATOM(_MOTIF_WM_HINTS), 0, 5, false,
+                            ATOM(_MOTIF_WM_HINTS), &type, &format, &nitems, &bytesLeft,
+                            &data) == Success)
+        && (type == ATOM(_MOTIF_WM_HINTS)
+            && format == 32
+            && nitems >= 5)) {
+        mwmhints = *(reinterpret_cast<QtMWMHints *>(data));
+    } else {
+        mwmhints.flags = 0L;
+        mwmhints.functions = MWM_FUNC_ALL;
+        mwmhints.decorations = MWM_DECOR_ALL;
+        mwmhints.input_mode = 0L;
+        mwmhints.status = 0L;
+    }
+
+    if (data)
+        XFree(data);
+
+    return mwmhints;
+}
+
+static void SetMWMHints(Display *display, Window window, const QtMWMHints &mwmhints)
+{
+    if (mwmhints.flags != 0l) {
+        XChangeProperty(display, window, ATOM(_MOTIF_WM_HINTS), ATOM(_MOTIF_WM_HINTS), 32,
+                        PropModeReplace, (unsigned char *) &mwmhints, 5);
+    } else {
+        XDeleteProperty(display, window, ATOM(_MOTIF_WM_HINTS));
+    }
+}
+
+// Returns true if we should set WM_TRANSIENT_FOR on \a w
+static inline bool isTransient(const QWidget *w)
+{
+    return ((w->windowType() == Qt::Dialog
+             || w->windowType() == Qt::Sheet
+             || w->windowType() == Qt::Tool
+             || w->windowType() == Qt::SplashScreen
+             || w->windowType() == Qt::ToolTip
+             || w->windowType() == Qt::Drawer
+             || w->windowType() == Qt::Popup)
+            && !w->testAttribute(Qt::WA_X11BypassTransientForHint));
+}
+
+static void do_size_hints(QWidget* widget, QWExtra *x);
+
+/*****************************************************************************
+  QWidget member functions
+ *****************************************************************************/
+
+const uint stdWidgetEventMask =                        // X event mask
+        (uint)(
+            KeyPressMask | KeyReleaseMask |
+            ButtonPressMask | ButtonReleaseMask |
+            KeymapStateMask |
+            ButtonMotionMask | PointerMotionMask |
+            EnterWindowMask | LeaveWindowMask |
+            FocusChangeMask |
+            ExposureMask |
+            PropertyChangeMask |
+            StructureNotifyMask
+       );
+
+const uint stdDesktopEventMask =                        // X event mask
+       (uint)(
+           KeymapStateMask |
+           EnterWindowMask | LeaveWindowMask |
+           PropertyChangeMask
+      );
+
+
+/*
+  The qt_ functions below are implemented in qwidgetcreate_x11.cpp.
+*/
+
+Window qt_XCreateWindow(const QWidget *creator,
+                         Display *display, Window parent,
+                         int x, int y, uint w, uint h,
+                         int borderwidth, int depth,
+                         uint windowclass, Visual *visual,
+                         ulong valuemask, XSetWindowAttributes *attributes);
+Window qt_XCreateSimpleWindow(const QWidget *creator,
+                               Display *display, Window parent,
+                               int x, int y, uint w, uint h, int borderwidth,
+                               ulong border, ulong background);
+void qt_XDestroyWindow(const QWidget *destroyer,
+                        Display *display, Window window);
+
+
+static void qt_insert_sip(QWidget* scrolled_widget, int dx, int dy)
+{
+    if (!scrolled_widget->isWindow() && !scrolled_widget->internalWinId())
+        return;
+    QX11Data::ScrollInProgress sip = { X11->sip_serial++, scrolled_widget, dx, dy };
+    X11->sip_list.append(sip);
+
+    XClientMessageEvent client_message;
+    client_message.type = ClientMessage;
+    client_message.window = scrolled_widget->internalWinId();
+    client_message.format = 32;
+    client_message.message_type = ATOM(_QT_SCROLL_DONE);
+    client_message.data.l[0] = sip.id;
+
+    XSendEvent(X11->display, scrolled_widget->internalWinId(), False, NoEventMask,
+        (XEvent*)&client_message);
+}
+
+static int qt_sip_count(QWidget* scrolled_widget)
+{
+    int sips=0;
+
+    for (int i = 0; i < X11->sip_list.size(); ++i) {
+        const QX11Data::ScrollInProgress &sip = X11->sip_list.at(i);
+        if (sip.scrolled_widget == scrolled_widget)
+            sips++;
+    }
+
+    return sips;
+}
+
+static void create_wm_client_leader()
+{
+    if (X11->wm_client_leader) return;
+
+    X11->wm_client_leader =
+        XCreateSimpleWindow(X11->display,
+                             QX11Info::appRootWindow(),
+                             0, 0, 1, 1, 0, 0, 0);
+
+    // set client leader property to itself
+    XChangeProperty(X11->display,
+                     X11->wm_client_leader, ATOM(WM_CLIENT_LEADER),
+                     XA_WINDOW, 32, PropModeReplace,
+                     (unsigned char *)&X11->wm_client_leader, 1);
+
+#ifndef QT_NO_SESSIONMANAGER
+    // If we are session managed, inform the window manager about it
+    QByteArray session = qApp->sessionId().toLatin1();
+    if (!session.isEmpty()) {
+        XChangeProperty(X11->display,
+                         X11->wm_client_leader, ATOM(SM_CLIENT_ID),
+                         XA_STRING, 8, PropModeReplace,
+                         (unsigned char *)session.data(), session.size());
+    }
+#endif
+}
+
+/*!
+   \internal
+   Update the X11 cursor of the widget w.
+   \a force is true if this function is called from dispatchEnterLeave, it means that the
+   mouse is actually directly under this widget.
+ */
+void qt_x11_enforce_cursor(QWidget * w, bool force)
+{
+    if (!w->testAttribute(Qt::WA_WState_Created))
+        return;
+
+    static QPointer<QWidget> lastUnderMouse = 0;
+    if (force) {
+        lastUnderMouse = w;
+    } else if (lastUnderMouse && lastUnderMouse->effectiveWinId() == w->effectiveWinId()) {
+        w = lastUnderMouse;
+    } else if (!w->internalWinId()) {
+        return; //the mouse is not under this widget, and it's not native, so don't change it
+    }
+
+    while (!w->internalWinId() && w->parentWidget() && !w->isWindow() && !w->testAttribute(Qt::WA_SetCursor))
+        w = w->parentWidget();
+
+    QWidget *nativeParent = w;
+    if (!w->internalWinId())
+        nativeParent = w->nativeParentWidget();
+    // This does the same as effectiveWinId(), but since it is possible
+    // to not have a native parent widget due to a special hack in
+    // qwidget for reparenting widgets to a different X11 screen,
+    // added additional check to make sure native parent widget exists.
+    if (!nativeParent || !nativeParent->internalWinId())
+        return;
+    WId winid = nativeParent->internalWinId();
+
+    if (w->isWindow() || w->testAttribute(Qt::WA_SetCursor)) {
+#ifndef QT_NO_CURSOR
+        QCursor *oc = QApplication::overrideCursor();
+        if (oc) {
+            XDefineCursor(X11->display, winid, oc->handle());
+        } else if (w->isEnabled()) {
+            XDefineCursor(X11->display, winid, w->cursor().handle());
+        } else {
+            // enforce the windows behavior of clearing the cursor on
+            // disabled widgets
+            XDefineCursor(X11->display, winid, XNone);
+        }
+#endif
+    } else {
+        XDefineCursor(X11->display, winid, XNone);
+    }
+}
+
+Q_GUI_EXPORT void qt_x11_enforce_cursor(QWidget * w)
+{
+    qt_x11_enforce_cursor(w, false);
+}
+
+static Bool checkForConfigureAndExpose(Display *, XEvent *e, XPointer)
+{
+    return e->type == ConfigureNotify || e->type == Expose;
+}
+
+Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w)
+{
+    if (!w || (!w->isWindow() && !w->internalWinId()))
+        return;
+    QApplication::flush();
+    XEvent ev;
+    QTime t;
+    t.start();
+    static const int maximumWaitTime = 2000;
+    if (!w->testAttribute(Qt::WA_WState_Created))
+        return;
+
+    if (!(w->windowFlags() & Qt::X11BypassWindowManagerHint)) {
+        // if the window is not override-redirect, then the window manager
+        // will reparent us to the frame decoration window.
+        while (!XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), ReparentNotify, &ev)) {
+            if (t.elapsed() > maximumWaitTime)
+                return;
+            qApp->syncX(); // non-busy wait
+        }
+    }
+
+    while (!XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), MapNotify, &ev)) {
+        if (t.elapsed() > maximumWaitTime)
+            return;
+        qApp->syncX(); // non-busy wait
+    }
+
+    qApp->x11ProcessEvent(&ev);
+
+    // ok, seems like the window manager successfully reparented us, we'll wait
+    // for the first paint event to arrive, while handling ConfigureNotify in
+    // the arrival order
+    while(1)
+    {
+        if (XCheckIfEvent(X11->display, &ev, checkForConfigureAndExpose, 0)) {
+            qApp->x11ProcessEvent(&ev);
+            if (ev.type == Expose)
+                return;
+        }
+        if (t.elapsed() > maximumWaitTime)
+            return;
+        qApp->syncX(); // non-busy wait
+    }
+}
+
+void qt_change_net_wm_state(const QWidget* w, bool set, Atom one, Atom two = 0)
+{
+    if (!w->isVisible()) // not managed by the window manager
+        return;
+
+    XEvent e;
+    e.xclient.type = ClientMessage;
+    e.xclient.message_type = ATOM(_NET_WM_STATE);
+    e.xclient.display = X11->display;
+    e.xclient.window = w->internalWinId();
+    e.xclient.format = 32;
+    e.xclient.data.l[0] = set ? 1 : 0;
+    e.xclient.data.l[1] = one;
+    e.xclient.data.l[2] = two;
+    e.xclient.data.l[3] = 0;
+    e.xclient.data.l[4] = 0;
+    XSendEvent(X11->display, RootWindow(X11->display, w->x11Info().screen()),
+               false, (SubstructureNotifyMask | SubstructureRedirectMask), &e);
+}
+
+struct QX11WindowAttributes {
+    const XWindowAttributes *att;
+};
+
+void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const XWindowAttributes &a)
+{
+    QX11WindowAttributes att;
+    att.att = &a;
+    qt_x11_getX11InfoForWindow(xinfo,att);
+}
+
+
+static QVector<Atom> getNetWmState(QWidget *w)
+{
+    QVector<Atom> returnValue;
+
+    // Don't read anything, just get the size of the property data
+    Atom actualType;
+    int actualFormat;
+    ulong propertyLength;
+    ulong bytesLeft;
+    uchar *propertyData = 0;
+    if (XGetWindowProperty(X11->display, w->internalWinId(), ATOM(_NET_WM_STATE), 0, 0,
+                           False, XA_ATOM, &actualType, &actualFormat,
+                           &propertyLength, &bytesLeft, &propertyData) == Success
+        && actualType == XA_ATOM && actualFormat == 32) {
+        returnValue.resize(bytesLeft / 4);
+        XFree((char*) propertyData);
+
+        // fetch all data
+        if (XGetWindowProperty(X11->display, w->internalWinId(), ATOM(_NET_WM_STATE), 0,
+                               returnValue.size(), False, XA_ATOM, &actualType, &actualFormat,
+                               &propertyLength, &bytesLeft, &propertyData) != Success) {
+            returnValue.clear();
+        } else if (propertyLength != (ulong)returnValue.size()) {
+            returnValue.resize(propertyLength);
+        }
+
+        // put it into netWmState
+        if (!returnValue.isEmpty()) {
+            memcpy(returnValue.data(), propertyData, returnValue.size() * sizeof(Atom));
+        }
+        XFree((char*) propertyData);
+    }
+
+    return returnValue;
+}
+
+void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
+{
+    Q_Q(QWidget);
+    Qt::WindowType type = q->windowType();
+    Qt::WindowFlags &flags = data.window_flags;
+    QWidget *parentWidget = q->parentWidget();
+
+    if (type == Qt::ToolTip)
+        flags |= Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint;
+    if (type == Qt::Popup)
+        flags |= Qt::X11BypassWindowManagerHint;
+
+    bool topLevel = (flags & Qt::Window);
+    bool popup = (type == Qt::Popup);
+    bool dialog = (type == Qt::Dialog
+                   || type == Qt::Sheet);
+    bool desktop = (type == Qt::Desktop);
+    bool tool = (type == Qt::Tool || type == Qt::SplashScreen
+                 || type == Qt::ToolTip || type == Qt::Drawer);
+
+#ifdef ALIEN_DEBUG
+    qDebug() << "QWidgetPrivate::create_sys START:" << q << "topLevel?" << topLevel << "WId:"
+             << window << "initializeWindow:" << initializeWindow << "destroyOldWindow" << destroyOldWindow;
+#endif
+    if (topLevel) {
+        if (parentWidget) { // if our parent stays on top, so must we
+            QWidget *ptl = parentWidget->window();
+            if(ptl && (ptl->windowFlags() & Qt::WindowStaysOnTopHint))
+                flags |= Qt::WindowStaysOnTopHint;
+        }
+
+        if (type == Qt::SplashScreen) {
+            if (X11->isSupportedByWM(ATOM(_NET_WM_WINDOW_TYPE_SPLASH))) {
+                flags &= ~Qt::X11BypassWindowManagerHint;
+            } else {
+                flags |= Qt::X11BypassWindowManagerHint | Qt::FramelessWindowHint;
+            }
+        }
+        // All these buttons depend on the system menu, so we enable it
+        if (flags & (Qt::WindowMinimizeButtonHint
+                     | Qt::WindowMaximizeButtonHint
+                     | Qt::WindowContextHelpButtonHint))
+            flags |= Qt::WindowSystemMenuHint;
+    }
+
+
+    Window parentw, destroyw = 0;
+    WId id = 0;
+
+    // always initialize
+    if (!window)
+        initializeWindow = true;
+
+    QX11Info *parentXinfo = parentWidget ? &parentWidget->d_func()->xinfo : 0;
+
+    if (desktop &&
+        qt_x11_create_desktop_on_screen >= 0 &&
+        qt_x11_create_desktop_on_screen != xinfo.screen()) {
+        // desktop on a certain screen other than the default requested
+        QX11InfoData *xd = &X11->screens[qt_x11_create_desktop_on_screen];
+        xinfo.setX11Data(xd);
+    } else if (parentXinfo && (parentXinfo->screen() != xinfo.screen()
+                               || parentXinfo->visual() != xinfo.visual()))
+    {
+        xinfo = *parentXinfo;
+    }
+
+    //get display, screen number, root window and desktop geometry for
+    //the current screen
+    Display *dpy = X11->display;
+    int scr = xinfo.screen();
+    Window root_win = RootWindow(dpy, scr);
+    int sw = DisplayWidth(dpy,scr);
+    int sh = DisplayHeight(dpy,scr);
+
+    if (desktop) {                                // desktop widget
+        dialog = popup = false;                        // force these flags off
+        data.crect.setRect(0, 0, sw, sh);
+    } else if (topLevel && !q->testAttribute(Qt::WA_Resized)) {
+        QDesktopWidget *desktopWidget = qApp->desktop();
+        if (desktopWidget->isVirtualDesktop()) {
+            QRect r = desktopWidget->screenGeometry();
+            sw = r.width();
+            sh = r.height();
+        }
+
+        int width = sw / 2;
+        int height = 4 * sh / 10;
+        if (extra) {
+            width = qMax(qMin(width, extra->maxw), extra->minw);
+            height = qMax(qMin(height, extra->maxh), extra->minh);
+        }
+        data.crect.setSize(QSize(width, height));
+    }
+
+    parentw = topLevel ? root_win : parentWidget->effectiveWinId();
+
+    XSetWindowAttributes wsa;
+
+    if (window) {                                // override the old window
+        if (destroyOldWindow) {
+            if (topLevel)
+                X11->dndEnable(q, false);
+            destroyw = data.winid;
+        }
+        id = window;
+        setWinId(window);
+        XWindowAttributes a;
+        XGetWindowAttributes(dpy, window, &a);
+        data.crect.setRect(a.x, a.y, a.width, a.height);
+
+        if (a.map_state == IsUnmapped)
+            q->setAttribute(Qt::WA_WState_Visible, false);
+        else
+            q->setAttribute(Qt::WA_WState_Visible);
+
+        qt_x11_getX11InfoForWindow(&xinfo,a);
+
+    } else if (desktop) {                        // desktop widget
+#ifdef QWIDGET_EXTRA_DEBUG
+        qDebug() << "create desktop";
+#endif
+        id = (WId)parentw;                        // id = root window
+//         QWidget *otherDesktop = find(id);        // is there another desktop?
+//         if (otherDesktop && otherDesktop->testWFlags(Qt::WPaintDesktop)) {
+//             otherDesktop->d->setWinId(0);        // remove id from widget mapper
+//             d->setWinId(id);                     // make sure otherDesktop is
+//             otherDesktop->d->setWinId(id);       // found first
+//         } else {
+        setWinId(id);
+//         }
+    } else if (topLevel || q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) {
+#ifdef QWIDGET_EXTRA_DEBUG
+        static int topLevels = 0;
+        static int children = 0;
+        if (parentw == root_win)
+            qDebug() << "create toplevel" << ++topLevels;
+        else
+            qDebug() << "create child" << ++children;
+#endif
+        QRect safeRect = data.crect; //##### must handle huge sizes as well.... i.e. wrect
+        if (safeRect.width() < 1|| safeRect.height() < 1) {
+            if (topLevel) {
+                // top-levels must be at least 1x1
+                safeRect.setSize(safeRect.size().expandedTo(QSize(1, 1)));
+            } else {
+                // create it way off screen, and rely on
+                // setWSGeometry() to do the right thing with it later
+                safeRect = QRect(-1000,-1000,1,1);
+            }
+        }
+#ifndef QT_NO_XRENDER
+        int screen = xinfo.screen();
+        if (topLevel && X11->use_xrender
+            && xinfo.depth() != 32 && X11->argbVisuals[screen]
+            && q->testAttribute(Qt::WA_TranslucentBackground))
+        {
+            QX11InfoData *xd = xinfo.getX11Data(true);
+
+            xd->screen = screen;
+            xd->visual = X11->argbVisuals[screen];
+            xd->colormap = X11->argbColormaps[screen];
+            xd->depth = 32;
+            xd->defaultVisual = false;
+            xd->defaultColormap = false;
+            xd->cells = xd->visual->map_entries;
+            xinfo.setX11Data(xd);
+        }
+#endif
+        if (xinfo.defaultVisual() && xinfo.defaultColormap()) {
+            id = (WId)qt_XCreateSimpleWindow(q, dpy, parentw,
+                                             safeRect.left(), safeRect.top(),
+                                             safeRect.width(), safeRect.height(),
+                                             0,
+                                             BlackPixel(dpy, xinfo.screen()),
+                                             WhitePixel(dpy, xinfo.screen()));
+        } else {
+            wsa.background_pixel = WhitePixel(dpy, xinfo.screen());
+            wsa.border_pixel = BlackPixel(dpy, xinfo.screen());
+            wsa.colormap = xinfo.colormap();
+            id = (WId)qt_XCreateWindow(q, dpy, parentw,
+                                       safeRect.left(), safeRect.top(),
+                                       safeRect.width(), safeRect.height(),
+                                       0, xinfo.depth(), InputOutput,
+                                       (Visual *) xinfo.visual(),
+                                       CWBackPixel|CWBorderPixel|CWColormap,
+                                       &wsa);
+        }
+
+        setWinId(id);                                // set widget id/handle + hd
+    }
+
+#ifndef QT_NO_XRENDER
+    if (picture) {
+        XRenderFreePicture(X11->display, picture);
+        picture = 0;
+    }
+
+    if (X11->use_xrender && !desktop && q->internalWinId()) {
+        XRenderPictFormat *format = XRenderFindVisualFormat(dpy, (Visual *) xinfo.visual());
+        if (format)
+            picture = XRenderCreatePicture(dpy, id, format, 0, 0);
+    }
+#endif // QT_NO_XRENDER
+
+    QtMWMHints mwmhints;
+    mwmhints.flags = 0L;
+    mwmhints.functions = 0L;
+    mwmhints.decorations = 0;
+    mwmhints.input_mode = 0L;
+    mwmhints.status = 0L;
+
+    if (topLevel) {
+        ulong wsa_mask = 0;
+        if (type != Qt::SplashScreen) { // && customize) {
+            mwmhints.flags |= MWM_HINTS_DECORATIONS;
+
+            bool customize = flags & Qt::CustomizeWindowHint;
+            if (!(flags & Qt::FramelessWindowHint) && !(customize && !(flags & Qt::WindowTitleHint))) {
+                mwmhints.decorations |= MWM_DECOR_BORDER;
+                mwmhints.decorations |= MWM_DECOR_RESIZEH;
+
+                if (flags & Qt::WindowTitleHint)
+                    mwmhints.decorations |= MWM_DECOR_TITLE;
+
+                if (flags & Qt::WindowSystemMenuHint)
+                    mwmhints.decorations |= MWM_DECOR_MENU;
+
+                if (flags & Qt::WindowMinimizeButtonHint) {
+                    mwmhints.decorations |= MWM_DECOR_MINIMIZE;
+                    mwmhints.functions |= MWM_FUNC_MINIMIZE;
+                }
+
+                if (flags & Qt::WindowMaximizeButtonHint) {
+                    mwmhints.decorations |= MWM_DECOR_MAXIMIZE;
+                    mwmhints.functions |= MWM_FUNC_MAXIMIZE;
+                }
+
+                if (flags & Qt::WindowCloseButtonHint)
+                     mwmhints.functions |= MWM_FUNC_CLOSE;
+            }
+        } else {
+            // if type == Qt::SplashScreen
+            mwmhints.decorations = MWM_DECOR_ALL;
+        }
+
+        if (tool) {
+            wsa.save_under = True;
+            wsa_mask |= CWSaveUnder;
+        }
+
+        if (flags & Qt::X11BypassWindowManagerHint) {
+            wsa.override_redirect = True;
+            wsa_mask |= CWOverrideRedirect;
+        }
+
+        if (wsa_mask && initializeWindow) {
+            Q_ASSERT(id);
+            XChangeWindowAttributes(dpy, id, wsa_mask, &wsa);
+        }
+
+        if (mwmhints.functions != 0) {
+            mwmhints.flags |= MWM_HINTS_FUNCTIONS;
+            mwmhints.functions |= MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
+        } else {
+            mwmhints.functions = MWM_FUNC_ALL;
+        }
+
+        if (!(flags & Qt::FramelessWindowHint)
+            && flags & Qt::CustomizeWindowHint
+            && flags & Qt::WindowTitleHint
+            && !(flags &
+                 (Qt::WindowMinimizeButtonHint
+                  | Qt::WindowMaximizeButtonHint
+                  | Qt::WindowCloseButtonHint))) {
+            // a special case - only the titlebar without any button
+            mwmhints.flags = MWM_HINTS_FUNCTIONS;
+            mwmhints.functions = MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
+            mwmhints.decorations = 0;
+        }
+    }
+
+    if (!initializeWindow) {
+        // do no initialization
+    } else if (popup) {                        // popup widget
+        // set EWMH window types
+        setNetWmWindowTypes();
+
+        wsa.override_redirect = True;
+        wsa.save_under = True;
+        Q_ASSERT(id);
+        XChangeWindowAttributes(dpy, id, CWOverrideRedirect | CWSaveUnder,
+                                &wsa);
+    } else if (topLevel && !desktop) {        // top-level widget
+        if (!X11->wm_client_leader)
+            create_wm_client_leader();
+
+        // note: WM_TRANSIENT_FOR is set in QWidgetPrivate::show_sys()
+
+        XSizeHints size_hints;
+        size_hints.flags = USSize | PSize | PWinGravity;
+        size_hints.x = data.crect.left();
+        size_hints.y = data.crect.top();
+        size_hints.width = data.crect.width();
+        size_hints.height = data.crect.height();
+        size_hints.win_gravity =
+            QApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity;
+
+        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.initial_state = NormalState;
+        wm_hints.window_group = X11->wm_client_leader;
+
+        XClassHint class_hint;
+        QByteArray appName = qAppName().toLatin1();
+        class_hint.res_name = appName.data(); // application name
+        class_hint.res_class = const_cast<char *>(QX11Info::appClass());   // application class
+
+        XSetWMProperties(dpy, id, 0, 0,
+                         qApp->d_func()->argv, qApp->d_func()->argc,
+                         &size_hints, &wm_hints, &class_hint);
+
+        XResizeWindow(dpy, id,
+                      qBound(1, data.crect.width(), XCOORD_MAX),
+                      qBound(1, data.crect.height(), XCOORD_MAX));
+        XStoreName(dpy, id, appName.data());
+        Atom protocols[5];
+        int n = 0;
+        protocols[n++] = ATOM(WM_DELETE_WINDOW);        // support del window protocol
+        protocols[n++] = ATOM(WM_TAKE_FOCUS);                // support take focus window protocol
+        protocols[n++] = ATOM(_NET_WM_PING);                // support _NET_WM_PING protocol
+#ifndef QT_NO_XSYNC
+        protocols[n++] = ATOM(_NET_WM_SYNC_REQUEST);        // support _NET_WM_SYNC_REQUEST protocol
+#endif // QT_NO_XSYNC
+        if (flags & Qt::WindowContextHelpButtonHint)
+            protocols[n++] = ATOM(_NET_WM_CONTEXT_HELP);
+        XSetWMProtocols(dpy, id, protocols, n);
+
+        // set mwm hints
+        SetMWMHints(dpy, id, mwmhints);
+
+        // set EWMH window types
+        setNetWmWindowTypes();
+
+        // set _NET_WM_PID
+        long curr_pid = getpid();
+        XChangeProperty(dpy, id, ATOM(_NET_WM_PID), XA_CARDINAL, 32, PropModeReplace,
+                        (unsigned char *) &curr_pid, 1);
+
+        // when we create a toplevel widget, the frame strut should be dirty
+        data.fstrut_dirty = 1;
+
+        // declare the widget's window role
+        if (QTLWExtra *topData = maybeTopData()) {
+            if (!topData->role.isEmpty()) {
+                QByteArray windowRole = topData->role.toUtf8();
+                XChangeProperty(dpy, id,
+                                ATOM(WM_WINDOW_ROLE), XA_STRING, 8, PropModeReplace,
+                                (unsigned char *)windowRole.constData(), windowRole.length());
+            }
+        }
+
+        // set client leader property
+        XChangeProperty(dpy, id, ATOM(WM_CLIENT_LEADER),
+                        XA_WINDOW, 32, PropModeReplace,
+                        (unsigned char *)&X11->wm_client_leader, 1);
+    } else {
+        // non-toplevel widgets don't have a frame, so no need to
+        // update the strut
+        data.fstrut_dirty = 0;
+    }
+
+    if (initializeWindow && q->internalWinId()) {
+        // don't erase when resizing
+        wsa.bit_gravity = QApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity;
+        Q_ASSERT(id);
+        XChangeWindowAttributes(dpy, id, CWBitGravity, &wsa);
+    }
+
+    // set X11 event mask
+    if (desktop) {
+//         QWidget* main_desktop = find(id);
+//         if (main_desktop->testWFlags(Qt::WPaintDesktop))
+//             XSelectInput(dpy, id, stdDesktopEventMask | ExposureMask);
+//         else
+        XSelectInput(dpy, id, stdDesktopEventMask);
+    } else if (q->internalWinId()) {
+        XSelectInput(dpy, id, stdWidgetEventMask);
+#if !defined (QT_NO_TABLET)
+        QTabletDeviceDataList *tablet_list = qt_tablet_devices();
+        if (X11->ptrXSelectExtensionEvent) {
+            for (int i = 0; i < tablet_list->size(); ++i) {
+                QTabletDeviceData tablet = tablet_list->at(i);
+                X11->ptrXSelectExtensionEvent(dpy, id, reinterpret_cast<XEventClass*>(tablet.eventList),
+                                              tablet.eventCount);
+            }
+        }
+#endif
+    }
+
+    if (desktop) {
+        q->setAttribute(Qt::WA_WState_Visible);
+    } else if (topLevel) {                        // set X cursor
+        if (initializeWindow) {
+            qt_x11_enforce_cursor(q);
+
+            if (QTLWExtra *topData = maybeTopData())
+                if (!topData->caption.isEmpty())
+                    setWindowTitle_helper(topData->caption);
+
+            //always enable dnd: it's not worth the effort to maintain the state
+            // NOTE: this always creates topData()
+            X11->dndEnable(q, true);
+
+            if (maybeTopData() && maybeTopData()->opacity != 255)
+                q->setWindowOpacity(maybeTopData()->opacity/255.);
+
+        }
+    } else if (q->testAttribute(Qt::WA_SetCursor) && q->internalWinId()) {
+        qt_x11_enforce_cursor(q);
+    }
+
+    if (extra && !extra->mask.isEmpty() && q->internalWinId())
+        XShapeCombineRegion(X11->display, q->internalWinId(), ShapeBounding, 0, 0,
+                            extra->mask.handle(), ShapeSet);
+
+    if (q->hasFocus() && q->testAttribute(Qt::WA_InputMethodEnabled)) {
+        QInputContext *inputContext = q->inputContext();
+        if (inputContext)
+            inputContext->setFocusWidget(q);
+    }
+
+    if (destroyw)
+        qt_XDestroyWindow(q, dpy, destroyw);
+
+    // newly created windows are positioned at the window system's
+    // (0,0) position. If the parent uses wrect mapping to expand the
+    // coordinate system, we must also adjust this widget's window
+    // system position
+    if (!topLevel && !parentWidget->data->wrect.topLeft().isNull())
+        setWSGeometry();
+    else if (topLevel && (data.crect.width() == 0 || data.crect.height() == 0))
+        q->setAttribute(Qt::WA_OutsideWSRange, true);
+
+    if (!topLevel && q->testAttribute(Qt::WA_NativeWindow) && q->testAttribute(Qt::WA_Mapped)) {
+        Q_ASSERT(q->internalWinId());
+        XMapWindow(X11->display, q->internalWinId());
+        // Ensure that mapped alien widgets are flushed immediately when re-created as native widgets.
+        if (QWindowSurface *surface = q->windowSurface())
+            surface->flush(q, q->rect(), q->mapTo(surface->window(), QPoint()));
+    }
+
+#ifdef ALIEN_DEBUG
+    qDebug() << "QWidgetPrivate::create_sys END:" << q;
+#endif
+}
+
+static void qt_x11_recreateWidget(QWidget *widget)
+{
+    if (widget->inherits("QGLWidget")) {
+        // We send QGLWidgets a ParentChange event which causes them to
+        // recreate their GL context, which in turn causes them to choose
+        // their visual again. Now that WA_TranslucentBackground is set,
+        // QGLContext::chooseVisual will select an ARGB visual.
+        QEvent e(QEvent::ParentChange);
+        QApplication::sendEvent(widget, &e);
+    } else {
+        // For regular widgets, reparent them with their parent which
+        // also triggers a recreation of the native window
+        QPoint pos = widget->pos();
+        bool visible = widget->isVisible();
+        if (visible)
+            widget->hide();
+
+        widget->setParent(widget->parentWidget(), widget->windowFlags());
+        widget->move(pos);
+        if (visible)
+            widget->show();
+    }
+}
+
+static void qt_x11_recreateNativeWidgetsRecursive(QWidget *widget)
+{
+    if (widget->internalWinId())
+        qt_x11_recreateWidget(widget);
+
+    const QObjectList &children = widget->children();
+    for (int i = 0; i < children.size(); ++i) {
+        QWidget *child = qobject_cast<QWidget*>(children.at(i));
+        if (child)
+            qt_x11_recreateNativeWidgetsRecursive(child);
+    }
+}
+
+void QWidgetPrivate::x11UpdateIsOpaque()
+{
+#ifndef QT_NO_XRENDER
+    Q_Q(QWidget);
+    if (!q->testAttribute(Qt::WA_WState_Created) || !q->testAttribute(Qt::WA_TranslucentBackground))
+        return;
+
+    bool topLevel = (data.window_flags & Qt::Window);
+    int screen = xinfo.screen();
+    if (topLevel && X11->use_xrender
+        && X11->argbVisuals[screen] && xinfo.depth() != 32)
+    {
+        qt_x11_recreateNativeWidgetsRecursive(q);
+    }
+#endif
+}
+
+/*
+  Returns true if the background is inherited; otherwise returns
+  false.
+
+  Mainly used in the paintOnScreen case.
+*/
+bool QWidgetPrivate::isBackgroundInherited() const
+{
+    Q_Q(const QWidget);
+
+    // windows do not inherit their background
+    if (q->isWindow() || q->windowType() == Qt::SubWindow)
+        return false;
+
+    if (q->testAttribute(Qt::WA_NoSystemBackground) || q->testAttribute(Qt::WA_OpaquePaintEvent))
+        return false;
+
+    const QPalette &pal = q->palette();
+    QPalette::ColorRole bg = q->backgroundRole();
+    QBrush brush = pal.brush(bg);
+
+    // non opaque brushes leaves us no choice, we must inherit
+    if (!q->autoFillBackground() || !brush.isOpaque())
+        return true;
+
+    if (brush.style() == Qt::SolidPattern) {
+        // the background is just a solid color. If there is no
+        // propagated contents, then we claim as performance
+        // optimization that it was not inheritet. This is the normal
+        // case in standard Windows or Motif style.
+        const QWidget *w = q->parentWidget();
+        if (!w->d_func()->isBackgroundInherited())
+            return false;
+    }
+
+    return true;
+}
+
+void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
+{
+    Q_D(QWidget);
+    if (!isWindow() && parentWidget())
+        parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
+    d->deactivateWidgetCleanup();
+    if (testAttribute(Qt::WA_WState_Created)) {
+        setAttribute(Qt::WA_WState_Created, false);
+        QObjectList childList = children();
+        for (int i = 0; i < childList.size(); ++i) { // destroy all widget children
+            register QObject *obj = childList.at(i);
+            if (obj->isWidgetType())
+                static_cast<QWidget*>(obj)->destroy(destroySubWindows,
+                                                    destroySubWindows);
+        }
+        if (QWidgetPrivate::mouseGrabber == this)
+            releaseMouse();
+        if (QWidgetPrivate::keyboardGrabber == this)
+            releaseKeyboard();
+        if (isWindow())
+            X11->deferred_map.removeAll(this);
+        if (isModal()) {
+            // just be sure we leave modal
+            QApplicationPrivate::leaveModal(this);
+        }
+        else if ((windowType() == Qt::Popup))
+            qApp->d_func()->closePopup(this);
+
+#ifndef QT_NO_XRENDER
+        if (d->picture) {
+            if (destroyWindow)
+                XRenderFreePicture(X11->display, d->picture);
+            d->picture = 0;
+        }
+#endif // QT_NO_XRENDER
+
+        // delete the _NET_WM_USER_TIME_WINDOW
+        qt_net_remove_user_time(this);
+
+        if ((windowType() == Qt::Desktop)) {
+            if (acceptDrops())
+                X11->dndEnable(this, false);
+        } else {
+            if (isWindow())
+                X11->dndEnable(this, false);
+            if (destroyWindow)
+                qt_XDestroyWindow(this, X11->display, data->winid);
+        }
+        QT_TRY {
+            d->setWinId(0);
+        } QT_CATCH (const std::bad_alloc &) {
+            // swallow - destructors must not throw
+        }
+
+        extern void qPRCleanup(QWidget *widget); // from qapplication_x11.cpp
+        if (testAttribute(Qt::WA_WState_Reparented))
+            qPRCleanup(this);
+
+        if(d->ic) {
+            delete d->ic;
+        } else {
+            // release previous focus information participating with
+            // preedit preservation of qic
+            QInputContext *qic = inputContext();
+            if (qic)
+                qic->widgetDestroyed(this);
+        }
+    }
+}
+
+void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
+{
+    Q_Q(QWidget);
+#ifdef ALIEN_DEBUG
+    qDebug() << "QWidgetPrivate::setParent_sys START" << q << "parent:" << parent;
+#endif
+    QX11Info old_xinfo = xinfo;
+    if (parent && parent->windowType() == Qt::Desktop) {
+        // make sure the widget is created on the same screen as the
+        // programmer specified desktop widget
+        xinfo = parent->d_func()->xinfo;
+        parent = 0;
+    }
+
+    QTLWExtra *topData = maybeTopData();
+    bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
+    if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
+        q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
+    extern void qPRCreate(const QWidget *, Window);
+#ifndef QT_NO_CURSOR
+    QCursor oldcurs;
+#endif
+
+    // dnd unregister (we will register again below)
+    if (q->testAttribute(Qt::WA_DropSiteRegistered))
+        q->setAttribute(Qt::WA_DropSiteRegistered, false);
+
+    // if we are a top then remove our dnd prop for now
+    // it will get rest later
+    if (q->isWindow() && wasCreated)
+        X11->dndEnable(q, false);
+
+    if (topData)
+        qt_net_remove_user_time(q);
+
+//     QWidget *oldparent = q->parentWidget();
+    WId old_winid = wasCreated ? data.winid : 0;
+    if ((q->windowType() == Qt::Desktop))
+        old_winid = 0;
+    setWinId(0);
+
+#ifndef QT_NO_XRENDER
+    if (picture) {
+        XRenderFreePicture(X11->display, picture);
+        picture = 0;
+    }
+#endif
+
+    // hide and reparent our own window away. Otherwise we might get
+    // destroyed when emitting the child remove event below. See QWorkspace.
+    if (wasCreated && old_winid) {
+        XUnmapWindow(X11->display, old_winid);
+        if (!old_xinfo.screen() != xinfo.screen())
+            XReparentWindow(X11->display, old_winid, RootWindow(X11->display, xinfo.screen()), 0, 0);
+    }
+    if (topData) {
+        topData->parentWinId = 0;
+        // zero the frame strut and mark it dirty
+        topData->frameStrut.setCoords(0, 0, 0, 0);
+
+        // reparenting from top-level, make sure show() works again
+        topData->waitingForMapNotify = 0;
+        topData->validWMState = 0;
+    }
+    data.fstrut_dirty = (!parent || (f & Qt::Window)); // toplevels get a dirty framestrut
+
+    QObjectPrivate::setParent_helper(parent);
+    bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
+
+    data.window_flags = f;
+    q->setAttribute(Qt::WA_WState_Created, false);
+    q->setAttribute(Qt::WA_WState_Visible, false);
+    q->setAttribute(Qt::WA_WState_Hidden, false);
+    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)))
+        createWinId();
+    if (q->isWindow() || (!parent || parent->isVisible()) || explicitlyHidden)
+        q->setAttribute(Qt::WA_WState_Hidden);
+    q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
+
+    if (wasCreated) {
+        QObjectList chlist = q->children();
+        for (int i = 0; i < chlist.size(); ++i) { // reparent children
+            QObject *obj = chlist.at(i);
+            if (obj->isWidgetType()) {
+                QWidget *w = (QWidget *)obj;
+                if (!w->testAttribute(Qt::WA_WState_Created))
+                    continue;
+                if (xinfo.screen() != w->d_func()->xinfo.screen()) {
+                    // ### force setParent() to not shortcut out (because
+                    // ### we're setting the parent to the current parent)
+                    // ### setParent will add child back to the list
+                    // ### of children so we need to make sure the
+                    // ### widget won't be added twice.
+                    w->d_func()->parent = 0;
+                    this->children.removeOne(w);
+                    w->setParent(q);
+                } else if (!w->isWindow()) {
+                    w->d_func()->invalidateBuffer(w->rect());
+                    if (w->internalWinId()) {
+                        if (w->testAttribute(Qt::WA_NativeWindow)) {
+                            QWidget *nativeParentWidget = w->nativeParentWidget();
+                            // Qt::WA_NativeWindow ensures that we always have a nativeParentWidget
+                            Q_ASSERT(nativeParentWidget != 0);
+                            QPoint p = w->mapTo(nativeParentWidget, QPoint());
+                            XReparentWindow(X11->display,
+                                            w->internalWinId(),
+                                            nativeParentWidget->internalWinId(),
+                                            p.x(), p.y());
+                        } else {
+                            w->d_func()->setParent_sys(q, w->data->window_flags);
+                        }
+                    }
+                } else if (isTransient(w)) {
+                    /*
+                      when reparenting toplevel windows with toplevel-transient children,
+                      we need to make sure that the window manager gets the updated
+                      WM_TRANSIENT_FOR information... unfortunately, some window managers
+                      don't handle changing WM_TRANSIENT_FOR before the toplevel window is
+                      visible, so we unmap and remap all toplevel-transient children *after*
+                      the toplevel parent has been mapped.  thankfully, this is easy in Qt :)
+
+                      note that the WM_TRANSIENT_FOR hint is actually updated in
+                      QWidgetPrivate::show_sys()
+                    */
+                    if (w->internalWinId())
+                        XUnmapWindow(X11->display, w->internalWinId());
+                    QApplication::postEvent(w, new QEvent(QEvent::ShowWindowRequest));
+                }
+            }
+        }
+        qPRCreate(q, old_winid);
+        updateSystemBackground();
+
+        if (old_winid) {
+            Window *cmwret;
+            int count;
+            if (XGetWMColormapWindows(X11->display, old_winid, &cmwret, &count)) {
+                Window *cmw;
+                int cmw_size = sizeof(Window)*count;
+                cmw = new Window[count];
+                memcpy((char *)cmw, (char *)cmwret, cmw_size);
+                XFree((char *)cmwret);
+                int i;
+                for (i=0; i<count; i++) {
+                    if (cmw[i] == old_winid) {
+                        cmw[i] = q->internalWinId();
+                        break;
+                    }
+                }
+                int top_count;
+                if (XGetWMColormapWindows(X11->display, q->window()->internalWinId(),
+                                          &cmwret, &top_count))
+                {
+                    Window *merged_cmw = new Window[count + top_count];
+                    memcpy((char *)merged_cmw, (char *)cmw, cmw_size);
+                    memcpy((char *)merged_cmw + cmw_size, (char *)cmwret, sizeof(Window)*top_count);
+                    delete [] cmw;
+                    XFree((char *)cmwret);
+                    cmw = merged_cmw;
+                    count += top_count;
+                }
+
+                XSetWMColormapWindows(X11->display, q->window()->internalWinId(), cmw, count);
+                delete [] cmw;
+            }
+
+            qt_XDestroyWindow(q, X11->display, old_winid);
+        }
+    }
+
+    // check if we need to register our dropsite
+    if (q->testAttribute(Qt::WA_AcceptDrops)
+        || (!q->isWindow() && q->parentWidget() && q->parentWidget()->testAttribute(Qt::WA_DropSiteRegistered))) {
+        q->setAttribute(Qt::WA_DropSiteRegistered, true);
+    }
+#if !defined(QT_NO_IM)
+    ic = 0;
+#endif
+    invalidateBuffer(q->rect());
+#ifdef ALIEN_DEBUG
+    qDebug() << "QWidgetPrivate::setParent_sys END" << q;
+#endif
+}
+
+
+QPoint QWidget::mapToGlobal(const QPoint &pos) const
+{
+    Q_D(const QWidget);
+    if (!testAttribute(Qt::WA_WState_Created) || !internalWinId()) {
+        QPoint p = pos + data->crect.topLeft();
+        //cannot trust that !isWindow() implies parentWidget() before create
+        return (isWindow() || !parentWidget()) ?  p : parentWidget()->mapToGlobal(p);
+    }
+    int           x, y;
+    Window child;
+    QPoint p = d->mapToWS(pos);
+    XTranslateCoordinates(X11->display, internalWinId(),
+                          QApplication::desktop()->screen(d->xinfo.screen())->internalWinId(),
+                          p.x(), p.y(), &x, &y, &child);
+    return QPoint(x, y);
+}
+
+
+QPoint QWidget::mapFromGlobal(const QPoint &pos) const
+{
+    Q_D(const QWidget);
+    if (!testAttribute(Qt::WA_WState_Created) || !internalWinId()) {
+        //cannot trust that !isWindow() implies parentWidget() before create
+        QPoint p = (isWindow() || !parentWidget()) ?  pos : parentWidget()->mapFromGlobal(pos);
+        return p - data->crect.topLeft();
+    }
+    int           x, y;
+    Window child;
+    XTranslateCoordinates(X11->display,
+                          QApplication::desktop()->screen(d->xinfo.screen())->internalWinId(),
+                          internalWinId(), pos.x(), pos.y(), &x, &y, &child);
+    return d->mapFromWS(QPoint(x, y));
+}
+
+void QWidgetPrivate::updateSystemBackground()
+{
+    Q_Q(QWidget);
+    if (!q->testAttribute(Qt::WA_WState_Created) || !q->internalWinId())
+        return;
+    QBrush brush = q->palette().brush(QPalette::Active, q->backgroundRole());
+    Qt::WindowType type = q->windowType();
+    if (brush.style() == Qt::NoBrush
+        || q->testAttribute(Qt::WA_NoSystemBackground)
+        || q->testAttribute(Qt::WA_UpdatesDisabled)
+        || type == Qt::Popup || type == Qt::ToolTip
+        )
+        XSetWindowBackgroundPixmap(X11->display, q->internalWinId(), XNone);
+    else if (brush.style() == Qt::SolidPattern && brush.isOpaque())
+        XSetWindowBackground(X11->display, q->internalWinId(),
+                             QColormap::instance(xinfo.screen()).pixel(brush.color()));
+    else if (isBackgroundInherited())
+        XSetWindowBackgroundPixmap(X11->display, q->internalWinId(), ParentRelative);
+    else if (brush.style() == Qt::TexturePattern) {
+        extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap); // qpixmap_x11.cpp
+        XSetWindowBackgroundPixmap(X11->display, q->internalWinId(),
+                                   static_cast<QX11PixmapData*>(qt_toX11Pixmap(brush.texture()).data.data())->x11ConvertToDefaultDepth());
+    } else
+        XSetWindowBackground(X11->display, q->internalWinId(),
+                             QColormap::instance(xinfo.screen()).pixel(brush.color()));
+}
+
+#ifndef QT_NO_CURSOR
+void QWidgetPrivate::setCursor_sys(const QCursor &)
+{
+    Q_Q(QWidget);
+    qt_x11_enforce_cursor(q);
+    XFlush(X11->display);
+}
+
+void QWidgetPrivate::unsetCursor_sys()
+{
+    Q_Q(QWidget);
+    qt_x11_enforce_cursor(q);
+    XFlush(X11->display);
+}
+#endif
+
+static XTextProperty*
+qstring_to_xtp(const QString& s)
+{
+    static XTextProperty tp = { 0, 0, 0, 0 };
+    static bool free_prop = true; // we can't free tp.value in case it references
+    // the data of the static QCString below.
+    if (tp.value) {
+        if (free_prop)
+            XFree(tp.value);
+        tp.value = 0;
+        free_prop = true;
+    }
+
+    static const QTextCodec* mapper = QTextCodec::codecForLocale();
+    int errCode = 0;
+    if (mapper) {
+        QByteArray mapped = mapper->fromUnicode(s);
+        char* tl[2];
+        tl[0] = mapped.data();
+        tl[1] = 0;
+        errCode = XmbTextListToTextProperty(X11->display, tl, 1, XStdICCTextStyle, &tp);
+#if defined(QT_DEBUG)
+        if (errCode < 0)
+            qDebug("qstring_to_xtp result code %d", errCode);
+#endif
+    }
+    if (!mapper || errCode < 0) {
+        static QByteArray qcs;
+        qcs = s.toAscii();
+        tp.value = (uchar*)qcs.data();
+        tp.encoding = XA_STRING;
+        tp.format = 8;
+        tp.nitems = qcs.length();
+        free_prop = false;
+    }
+
+    // ### If we knew WM could understand unicode, we could use
+    // ### a much simpler, cheaper encoding...
+    /*
+        tp.value = (XChar2b*)s.unicode();
+        tp.encoding = XA_UNICODE; // wish
+        tp.format = 16;
+        tp.nitems = s.length();
+    */
+
+    return &tp;
+}
+
+void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
+{
+    Q_Q(QWidget);
+    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+    if (!q->internalWinId())
+        return;
+    XSetWMName(X11->display, q->internalWinId(), qstring_to_xtp(caption));
+
+    QByteArray net_wm_name = caption.toUtf8();
+    XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_NAME), ATOM(UTF8_STRING), 8,
+                    PropModeReplace, (unsigned char *)net_wm_name.data(), net_wm_name.size());
+}
+
+void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
+{
+    Q_Q(QWidget);
+    if (!q->testAttribute(Qt::WA_WState_Created))
+        return;
+    QTLWExtra *topData = this->topData();
+    if (topData->iconPixmap && !forceReset)
+        // already been set
+        return;
+
+    // preparing images to set the _NET_WM_ICON property
+    QIcon icon = q->windowIcon();
+    QVector<long> icon_data;
+    Qt::HANDLE pixmap_handle = 0;
+    if (!icon.isNull()) {
+        QList<QSize> availableSizes = icon.availableSizes();
+        if(availableSizes.isEmpty()) {
+            // try to use default sizes since the icon can be a scalable image like svg.
+            availableSizes.push_back(QSize(16,16));
+            availableSizes.push_back(QSize(32,32));
+            availableSizes.push_back(QSize(64,64));
+            availableSizes.push_back(QSize(128,128));
+        }
+        for(int i = 0; i < availableSizes.size(); ++i) {
+            QSize size = availableSizes.at(i);
+            QPixmap pixmap = icon.pixmap(size);
+            if (!pixmap.isNull()) {
+                QImage image = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+                int pos = icon_data.size();
+                icon_data.resize(pos + 2 + image.width()*image.height());
+                icon_data[pos++] = image.width();
+                icon_data[pos++] = image.height();
+                if (sizeof(long) == sizeof(quint32)) {
+                    memcpy(icon_data.data() + pos, image.scanLine(0), image.numBytes());
+                } else {
+                    for (int y = 0; y < image.height(); ++y) {
+                        uint *scanLine = reinterpret_cast<uint *>(image.scanLine(y));
+                        for (int x = 0; x < image.width(); ++x)
+                            icon_data[pos + y*image.width() + x] = scanLine[x];
+                    }
+                }
+            }
+        }
+        if (!icon_data.isEmpty()) {
+            extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap);
+            /*
+              if the app is running on an unknown desktop, or it is not
+              using the default visual, convert the icon to 1bpp as stated
+              in the ICCCM section 4.1.2.4; otherwise, create the icon pixmap
+              in the default depth (even though this violates the ICCCM)
+            */
+            if (X11->desktopEnvironment == DE_UNKNOWN
+                || !QX11Info::appDefaultVisual(xinfo.screen())
+                || !QX11Info::appDefaultColormap(xinfo.screen())) {
+                // unknown DE or non-default visual/colormap, use 1bpp bitmap
+                if (!forceReset || !topData->iconPixmap)
+                    topData->iconPixmap = new QBitmap(qt_toX11Pixmap(icon.pixmap(QSize(64,64))));
+                pixmap_handle = topData->iconPixmap->handle();
+            } else {
+                // default depth, use a normal pixmap (even though this
+                // violates the ICCCM), since this works on all DEs known to Qt
+                if (!forceReset || !topData->iconPixmap)
+                    topData->iconPixmap = new QPixmap(qt_toX11Pixmap(icon.pixmap(QSize(64,64))));
+                pixmap_handle = static_cast<QX11PixmapData*>(topData->iconPixmap->data.data())->x11ConvertToDefaultDepth();
+            }
+        }
+    }
+
+    if (!q->internalWinId())
+        return;
+
+    if (!icon_data.isEmpty()) {
+        XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON), XA_CARDINAL, 32,
+                        PropModeReplace, (unsigned char *) icon_data.data(),
+                        icon_data.size());
+    } else {
+        XDeleteProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON));
+    }
+
+    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;
+    }
+
+    if (pixmap_handle) {
+        h->icon_pixmap = pixmap_handle;
+        h->flags |= IconPixmapHint;
+    } else {
+        h->icon_pixmap = 0;
+        h->flags &= ~(IconPixmapHint | IconMaskHint);
+    }
+
+    XSetWMHints(X11->display, q->internalWinId(), h);
+    if (h != &wm_hints)
+        XFree((char *)h);
+}
+
+void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
+{
+    Q_Q(QWidget);
+    if (!q->internalWinId())
+        return;
+    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+    XSetWMIconName(X11->display, q->internalWinId(), qstring_to_xtp(iconText));
+
+    QByteArray icon_name = iconText.toUtf8();
+    XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON_NAME), ATOM(UTF8_STRING), 8,
+                    PropModeReplace, (unsigned char *) icon_name.constData(), icon_name.size());
+}
+
+
+void QWidget::grabMouse()
+{
+    if (isVisible() && !qt_nograb()) {
+        if (QWidgetPrivate::mouseGrabber && QWidgetPrivate::mouseGrabber != this)
+            QWidgetPrivate::mouseGrabber->releaseMouse();
+        Q_ASSERT(testAttribute(Qt::WA_WState_Created));
+#ifndef QT_NO_DEBUG
+        int status =
+#endif
+            XGrabPointer(X11->display, effectiveWinId(), False,
+                          (uint)(ButtonPressMask | ButtonReleaseMask |
+                                  PointerMotionMask | EnterWindowMask |
+                                  LeaveWindowMask),
+                          GrabModeAsync, GrabModeAsync,
+                          XNone, XNone, X11->time);
+#ifndef QT_NO_DEBUG
+        if (status) {
+            const char *s =
+                status == GrabNotViewable ? "\"GrabNotViewable\"" :
+                status == AlreadyGrabbed  ? "\"AlreadyGrabbed\"" :
+                status == GrabFrozen      ? "\"GrabFrozen\"" :
+                status == GrabInvalidTime ? "\"GrabInvalidTime\"" :
+                "<?>";
+            qWarning("QWidget::grabMouse: Failed with %s", s);
+        }
+#endif
+        QWidgetPrivate::mouseGrabber = this;
+    }
+}
+
+
+#ifndef QT_NO_CURSOR
+void QWidget::grabMouse(const QCursor &cursor)
+{
+    if (!qt_nograb()) {
+        if (QWidgetPrivate::mouseGrabber && QWidgetPrivate::mouseGrabber != this)
+            QWidgetPrivate::mouseGrabber->releaseMouse();
+        Q_ASSERT(testAttribute(Qt::WA_WState_Created));
+#ifndef QT_NO_DEBUG
+        int status =
+#endif
+        XGrabPointer(X11->display, effectiveWinId(), False,
+                      (uint)(ButtonPressMask | ButtonReleaseMask |
+                             PointerMotionMask | EnterWindowMask | LeaveWindowMask),
+                      GrabModeAsync, GrabModeAsync,
+                      XNone, cursor.handle(), X11->time);
+#ifndef QT_NO_DEBUG
+        if (status) {
+            const char *s =
+                status == GrabNotViewable ? "\"GrabNotViewable\"" :
+                status == AlreadyGrabbed  ? "\"AlreadyGrabbed\"" :
+                status == GrabFrozen      ? "\"GrabFrozen\"" :
+                status == GrabInvalidTime ? "\"GrabInvalidTime\"" :
+                                            "<?>";
+            qWarning("QWidget::grabMouse: Failed with %s", s);
+        }
+#endif
+        QWidgetPrivate::mouseGrabber = this;
+    }
+}
+#endif
+
+
+void QWidget::releaseMouse()
+{
+    if (!qt_nograb() && QWidgetPrivate::mouseGrabber == this) {
+        XUngrabPointer(X11->display, X11->time);
+        XFlush(X11->display);
+        QWidgetPrivate::mouseGrabber = 0;
+    }
+}
+
+
+void QWidget::grabKeyboard()
+{
+    if (!qt_nograb()) {
+        if (QWidgetPrivate::keyboardGrabber && QWidgetPrivate::keyboardGrabber != this)
+            QWidgetPrivate::keyboardGrabber->releaseKeyboard();
+        XGrabKeyboard(X11->display, effectiveWinId(), False, GrabModeAsync, GrabModeAsync,
+                      X11->time);
+        QWidgetPrivate::keyboardGrabber = this;
+    }
+}
+
+
+void QWidget::releaseKeyboard()
+{
+    if (!qt_nograb() && QWidgetPrivate::keyboardGrabber == this) {
+        XUngrabKeyboard(X11->display, X11->time);
+        QWidgetPrivate::keyboardGrabber = 0;
+    }
+}
+
+
+QWidget *QWidget::mouseGrabber()
+{
+    return QWidgetPrivate::mouseGrabber;
+}
+
+
+QWidget *QWidget::keyboardGrabber()
+{
+    return QWidgetPrivate::keyboardGrabber;
+}
+
+void QWidget::activateWindow()
+{
+    QWidget *tlw = window();
+    if (tlw->isVisible() && !tlw->d_func()->topData()->embedded && !X11->deferred_map.contains(tlw)) {
+        if (X11->userTime == 0)
+            X11->userTime = X11->time;
+        qt_net_update_user_time(tlw, X11->userTime);
+        XSetInputFocus(X11->display, tlw->internalWinId(), XRevertToParent, X11->time);
+    }
+}
+
+void QWidget::setWindowState(Qt::WindowStates newstate)
+{
+    Q_D(QWidget);
+    bool needShow = false;
+    Qt::WindowStates oldstate = windowState();
+    if (oldstate == newstate)
+        return;
+    if (isWindow()) {
+        // Ensure the initial size is valid, since we store it as normalGeometry below.
+        if (!testAttribute(Qt::WA_Resized) && !isVisible())
+            adjustSize();
+
+        QTLWExtra *top = d->topData();
+
+        if ((oldstate & Qt::WindowMaximized) != (newstate & Qt::WindowMaximized)) {
+            if (X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))
+                && X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))) {
+                if ((newstate & Qt::WindowMaximized) && !(oldstate & Qt::WindowFullScreen))
+                    top->normalGeometry = geometry();
+                qt_change_net_wm_state(this, (newstate & Qt::WindowMaximized),
+                                       ATOM(_NET_WM_STATE_MAXIMIZED_HORZ),
+                                       ATOM(_NET_WM_STATE_MAXIMIZED_VERT));
+            } else if (! (newstate & Qt::WindowFullScreen)) {
+                if (newstate & Qt::WindowMaximized) {
+                    // save original geometry
+                    const QRect normalGeometry = geometry();
+
+                    if (isVisible()) {
+                        data->fstrut_dirty = true;
+                        const QRect maxRect = QApplication::desktop()->availableGeometry(this);
+                        const QRect r = top->normalGeometry;
+                        const QRect fs = d->frameStrut();
+                        setGeometry(maxRect.x() + fs.left(),
+                                    maxRect.y() + fs.top(),
+                                    maxRect.width() - fs.left() - fs.right(),
+                                    maxRect.height() - fs.top() - fs.bottom());
+                        top->normalGeometry = r;
+                    }
+
+                    if (top->normalGeometry.width() < 0)
+                        top->normalGeometry = normalGeometry;
+                } else {
+                    // restore original geometry
+                    setGeometry(top->normalGeometry);
+                }
+            }
+        }
+
+        if ((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen)) {
+            if (X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN))) {
+                if (newstate & Qt::WindowFullScreen) {
+                    top->normalGeometry = geometry();
+                    top->fullScreenOffset = d->frameStrut().topLeft();
+                }
+                qt_change_net_wm_state(this, (newstate & Qt::WindowFullScreen),
+                                       ATOM(_NET_WM_STATE_FULLSCREEN));
+            } else {
+                needShow = isVisible();
+
+                if (newstate & Qt::WindowFullScreen) {
+                    data->fstrut_dirty = true;
+                    const QRect normalGeometry = geometry();
+                    const QPoint fullScreenOffset = d->frameStrut().topLeft();
+
+                    top->savedFlags = windowFlags();
+                    setParent(0, Qt::Window | Qt::FramelessWindowHint);
+                    const QRect r = top->normalGeometry;
+                    setGeometry(qApp->desktop()->screenGeometry(this));
+                    top->normalGeometry = r;
+
+                    if (top->normalGeometry.width() < 0) {
+                        top->normalGeometry = normalGeometry;
+                        top->fullScreenOffset = fullScreenOffset;
+                    }
+                } else {
+                    setParent(0, top->savedFlags);
+
+                    if (newstate & Qt::WindowMaximized) {
+                        // from fullscreen to maximized
+                        data->fstrut_dirty = true;
+                        const QRect maxRect = QApplication::desktop()->availableGeometry(this);
+                        const QRect r = top->normalGeometry;
+                        const QRect fs = d->frameStrut();
+                        setGeometry(maxRect.x() + fs.left(),
+                                    maxRect.y() + fs.top(),
+                                    maxRect.width() - fs.left() - fs.right(),
+                                    maxRect.height() - fs.top() - fs.bottom());
+                        top->normalGeometry = r;
+                    } else {
+                        // restore original geometry
+                        setGeometry(top->normalGeometry.adjusted(-top->fullScreenOffset.x(),
+                                                                 -top->fullScreenOffset.y(),
+                                                                 -top->fullScreenOffset.x(),
+                                                                 -top->fullScreenOffset.y()));
+                    }
+                }
+            }
+        }
+
+        createWinId();
+        Q_ASSERT(testAttribute(Qt::WA_WState_Created));
+        if ((oldstate & Qt::WindowMinimized) != (newstate & Qt::WindowMinimized)) {
+            if (isVisible()) {
+                if (newstate & Qt::WindowMinimized) {
+                    XEvent e;
+                    e.xclient.type = ClientMessage;
+                    e.xclient.message_type = ATOM(WM_CHANGE_STATE);
+                    e.xclient.display = X11->display;
+                    e.xclient.window = data->winid;
+                    e.xclient.format = 32;
+                    e.xclient.data.l[0] = IconicState;
+                    e.xclient.data.l[1] = 0;
+                    e.xclient.data.l[2] = 0;
+                    e.xclient.data.l[3] = 0;
+                    e.xclient.data.l[4] = 0;
+                    XSendEvent(X11->display,
+                               RootWindow(X11->display,d->xinfo.screen()),
+                               False, (SubstructureNotifyMask|SubstructureRedirectMask), &e);
+                } else {
+                    setAttribute(Qt::WA_Mapped);
+                    XMapWindow(X11->display, effectiveWinId());
+                }
+            }
+
+            needShow = false;
+        }
+    }
+
+    data->window_state = newstate;
+
+    if (needShow)
+        show();
+
+    if (newstate & Qt::WindowActive)
+        activateWindow();
+
+    QWindowStateChangeEvent e(oldstate);
+    QApplication::sendEvent(this, &e);
+}
+
+/*!
+  \internal
+  Platform-specific part of QWidget::show().
+*/
+
+void QWidgetPrivate::show_sys()
+{
+    Q_Q(QWidget);
+    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+
+    if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
+        invalidateBuffer(q->rect());
+        q->setAttribute(Qt::WA_Mapped);
+        if (QTLWExtra *tlwExtra = maybeTopData())
+            tlwExtra->waitingForMapNotify = 0;
+        return;
+    }
+
+    if (q->isWindow()) {
+        XWMHints *h = XGetWMHints(X11->display, q->internalWinId());
+        XWMHints  wm_hints;
+        bool got_hints = h != 0;
+        if (!got_hints) {
+            memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
+            h = &wm_hints;
+        }
+        h->initial_state = q->isMinimized() ? IconicState : NormalState;
+        h->flags |= StateHint;
+        XSetWMHints(X11->display, q->internalWinId(), h);
+        if (got_hints)
+            XFree((char *)h);
+
+        // update WM_NORMAL_HINTS
+        do_size_hints(q, extra);
+
+        // udpate WM_TRANSIENT_FOR
+        if (isTransient(q)) {
+            QWidget *p = q->parentWidget();
+
+#ifndef QT_NO_MENU
+            // hackish ... try to find the main window related to this QMenu
+            if (qobject_cast<QMenu *>(q)) {
+                p = static_cast<QMenuPrivate*>(this)->causedPopup.widget;
+                if (!p)
+                    p = q->parentWidget();
+                if (!p)
+                    p = QApplication::widgetAt(q->pos());
+                if (!p)
+                    p = qApp->activeWindow();
+            }
+#endif
+            if (p)
+                p = p->window();
+            if (p) {
+                // transient for window
+                XSetTransientForHint(X11->display, q->internalWinId(), p->internalWinId());
+            } else {
+                // transient for group
+                XSetTransientForHint(X11->display, q->internalWinId(), X11->wm_client_leader);
+            }
+        }
+
+        // update _MOTIF_WM_HINTS
+        QtMWMHints mwmhints = GetMWMHints(X11->display, q->internalWinId());
+
+        if (data.window_modality != Qt::NonModal) {
+            switch (data.window_modality) {
+            case Qt::WindowModal:
+                mwmhints.input_mode = MWM_INPUT_PRIMARY_APPLICATION_MODAL;
+                break;
+            case Qt::ApplicationModal:
+            default:
+                mwmhints.input_mode = MWM_INPUT_FULL_APPLICATION_MODAL;
+                break;
+            }
+            mwmhints.flags |= MWM_HINTS_INPUT_MODE;
+        } else {
+            mwmhints.input_mode = MWM_INPUT_MODELESS;
+            mwmhints.flags &= ~MWM_HINTS_INPUT_MODE;
+        }
+
+        if (q->minimumSize() == q->maximumSize()) {
+            // fixed size, remove the resize handle (since mwm/dtwm
+            // isn't smart enough to do it itself)
+            mwmhints.flags |= MWM_HINTS_FUNCTIONS;
+            if (mwmhints.functions == MWM_FUNC_ALL) {
+                mwmhints.functions = MWM_FUNC_MOVE;
+            } else {
+                mwmhints.functions &= ~MWM_FUNC_RESIZE;
+            }
+
+            if (mwmhints.decorations == MWM_DECOR_ALL) {
+                mwmhints.flags |= MWM_HINTS_DECORATIONS;
+                mwmhints.decorations = (MWM_DECOR_BORDER
+                                        | MWM_DECOR_TITLE
+                                        | MWM_DECOR_MENU);
+            } else {
+                mwmhints.decorations &= ~MWM_DECOR_RESIZEH;
+            }
+
+            if (q->windowFlags() & Qt::WindowMinimizeButtonHint) {
+                mwmhints.flags |= MWM_HINTS_DECORATIONS;
+                mwmhints.decorations |= MWM_DECOR_MINIMIZE;
+                mwmhints.functions |= MWM_FUNC_MINIMIZE;
+            }
+            if (q->windowFlags() & Qt::WindowMaximizeButtonHint) {
+                mwmhints.flags |= MWM_HINTS_DECORATIONS;
+                mwmhints.decorations |= MWM_DECOR_MAXIMIZE;
+                mwmhints.functions |= MWM_FUNC_MAXIMIZE;
+            }
+            if (q->windowFlags() & Qt::WindowCloseButtonHint)
+                mwmhints.functions |= MWM_FUNC_CLOSE;
+        }
+
+        SetMWMHints(X11->display, q->internalWinId(), mwmhints);
+
+        // update _NET_WM_STATE
+        QVector<Atom> netWmState = getNetWmState(q);
+
+        Qt::WindowFlags flags = q->windowFlags();
+        if (flags & Qt::WindowStaysOnTopHint) {
+            if (flags & Qt::WindowStaysOnBottomHint)
+                qWarning() << "QWidget: Incompatible window flags: the window can't be on top and on bottom at the same time";
+            netWmState.append(ATOM(_NET_WM_STATE_ABOVE));
+            netWmState.append(ATOM(_NET_WM_STATE_STAYS_ON_TOP));
+        } else if (flags & Qt::WindowStaysOnBottomHint) {
+            netWmState.append(ATOM(_NET_WM_STATE_BELOW));
+        }
+        if (q->isFullScreen()) {
+            netWmState.append(ATOM(_NET_WM_STATE_FULLSCREEN));
+        }
+        if (q->isMaximized()) {
+            netWmState.append(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ));
+            netWmState.append(ATOM(_NET_WM_STATE_MAXIMIZED_VERT));
+        }
+        if (data.window_modality != Qt::NonModal) {
+            netWmState.append(ATOM(_NET_WM_STATE_MODAL));
+        }
+
+        if (!netWmState.isEmpty()) {
+            XChangeProperty(X11->display, q->internalWinId(),
+                            ATOM(_NET_WM_STATE), XA_ATOM, 32, PropModeReplace,
+                            (unsigned char *) netWmState.data(), netWmState.size());
+        } else {
+            XDeleteProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_STATE));
+        }
+
+        // set _NET_WM_USER_TIME
+        Time userTime = X11->userTime;
+        bool setUserTime = false;
+        if (q->testAttribute(Qt::WA_ShowWithoutActivating)) {
+            userTime = 0;
+            setUserTime = true;
+        } else if (userTime != CurrentTime) {
+            setUserTime = true;
+        }
+        if (setUserTime)
+            qt_net_update_user_time(q, userTime);
+
+#ifndef QT_NO_XSYNC
+        if (!topData()->syncUpdateCounter) {
+            XSyncValue value;
+            XSyncIntToValue(&value, 0);
+            topData()->syncUpdateCounter = XSyncCreateCounter(X11->display, value);
+
+            XChangeProperty(X11->display, q->internalWinId(),
+                            ATOM(_NET_WM_SYNC_REQUEST_COUNTER),
+                            XA_CARDINAL,
+                            32, PropModeReplace,
+                            (uchar *) &topData()->syncUpdateCounter, 1);
+
+            topData()->newCounterValueHi = 0;
+            topData()->newCounterValueLo = 0;
+        }
+#endif
+
+        if (!topData()->embedded
+            && (topData()->validWMState || topData()->waitingForMapNotify)
+            && !q->isMinimized()) {
+            X11->deferred_map.append(q);
+            return;
+        }
+
+        if (q->isMaximized() && !q->isFullScreen()
+            && !(X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))
+                 && X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT)))) {
+            XMapWindow(X11->display, q->internalWinId());
+            data.fstrut_dirty = true;
+            qt_x11_wait_for_window_manager(q);
+
+            // if the wm was not smart enough to adjust our size, do that manually
+            QRect maxRect = QApplication::desktop()->availableGeometry(q);
+
+            QTLWExtra *top = topData();
+            QRect normalRect = top->normalGeometry;
+            const QRect fs = frameStrut();
+
+            q->setGeometry(maxRect.x() + fs.left(),
+                           maxRect.y() + fs.top(),
+                           maxRect.width() - fs.left() - fs.right(),
+                           maxRect.height() - fs.top() - fs.bottom());
+
+            // restore the original normalGeometry
+            top->normalGeometry = normalRect;
+            // internalSetGeometry() clears the maximized flag... make sure we set it back
+            data.window_state = data.window_state | Qt::WindowMaximized;
+            q->setAttribute(Qt::WA_Mapped);
+            return;
+        }
+
+        if (q->isFullScreen() && !X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN))) {
+            XMapWindow(X11->display, q->internalWinId());
+            qt_x11_wait_for_window_manager(q);
+            q->setAttribute(Qt::WA_Mapped);
+            return;
+        }
+    }
+
+    invalidateBuffer(q->rect());
+
+    if (q->testAttribute(Qt::WA_OutsideWSRange))
+        return;
+    q->setAttribute(Qt::WA_Mapped);
+    if (q->isWindow())
+        topData()->waitingForMapNotify = 1;
+
+    if (!q->isWindow()
+        && (!q->autoFillBackground()
+            || q->palette().brush(q->backgroundRole()).style() == Qt::LinearGradientPattern)) {
+        if (q->internalWinId()) {
+            XSetWindowBackgroundPixmap(X11->display, q->internalWinId(), XNone);
+            XMapWindow(X11->display, q->internalWinId());
+            updateSystemBackground();
+        }
+        return;
+    }
+
+    if (q->internalWinId())
+        XMapWindow(X11->display, q->internalWinId());
+
+    // Freedesktop.org Startup Notification
+    if (X11->startupId && q->isWindow()) {
+        QByteArray message("remove: ID=");
+        message.append(X11->startupId);
+        sendStartupMessage(message.constData());
+        X11->startupId = 0;
+    }
+}
+
+/*!
+  \internal
+  Platform-specific part of QWidget::show().
+*/
+
+void QWidgetPrivate::sendStartupMessage(const char *message) const
+{
+    Q_Q(const QWidget);
+
+    if (!message)
+        return;
+
+    XEvent xevent;
+    xevent.xclient.type = ClientMessage;
+    xevent.xclient.message_type = ATOM(_NET_STARTUP_INFO_BEGIN);
+    xevent.xclient.display = X11->display;
+    xevent.xclient.window = q->internalWinId();
+    xevent.xclient.format = 8;
+
+    Window rootWindow = RootWindow(X11->display, DefaultScreen(X11->display));
+    uint sent = 0;
+    uint length = strlen(message) + 1;
+    do {
+        if (sent == 20)
+            xevent.xclient.message_type = ATOM(_NET_STARTUP_INFO);
+
+        for (uint i = 0; i < 20 && i + sent <= length; i++)
+            xevent.xclient.data.b[i] = message[i + sent++];
+
+        XSendEvent(X11->display, rootWindow, false, PropertyChangeMask, &xevent);
+    } while (sent <= length);
+}
+
+void QWidgetPrivate::setNetWmWindowTypes()
+{
+    Q_Q(QWidget);
+    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+
+    if (!q->isWindow()) {
+        if (q->internalWinId())
+            XDeleteProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_WINDOW_TYPE));
+        return;
+    }
+
+    QVector<long> windowTypes;
+
+    // manual selection 1 (these are never set by Qt and take precedence)
+    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDesktop))
+        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DESKTOP));
+    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDock))
+        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DOCK));
+    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeNotification))
+        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_NOTIFICATION));
+
+    // manual selection 2 (Qt uses these during auto selection);
+    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeUtility))
+        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_UTILITY));
+    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeSplash))
+        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_SPLASH));
+    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDialog))
+        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DIALOG));
+    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeToolTip))
+        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_TOOLTIP));
+
+    // manual selection 3 (these can be set by Qt, but don't have a
+    // corresponding Qt::WindowType). note that order of the *MENU
+    // atoms is important
+    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeMenu))
+        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_MENU));
+    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu))
+        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU));
+    if (q->testAttribute(Qt::WA_X11NetWmWindowTypePopupMenu))
+        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_POPUP_MENU));
+    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeToolBar))
+        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_TOOLBAR));
+    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeCombo))
+        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_COMBO));
+    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDND))
+        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DND));
+
+    // automatic selection
+    switch (q->windowType()) {
+    case Qt::Dialog:
+    case Qt::Sheet:
+        // dialog netwm type
+        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DIALOG));
+        break;
+
+    case Qt::Tool:
+    case Qt::Drawer:
+        // utility netwm type
+        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_UTILITY));
+        break;
+
+    case Qt::ToolTip:
+        // tooltip netwm type
+        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_TOOLTIP));
+        break;
+
+    case Qt::SplashScreen:
+        // splash netwm type
+        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_SPLASH));
+        break;
+
+    default:
+        break;
+    }
+
+    if (q->windowFlags() & Qt::FramelessWindowHint) {
+        // override netwm type - quick and easy for KDE noborder
+        windowTypes.append(ATOM(_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));
+    }
+
+    // normal netwm type - default
+    windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_NORMAL));
+
+    if (!windowTypes.isEmpty()) {
+        XChangeProperty(X11->display, q->winId(), ATOM(_NET_WM_WINDOW_TYPE), XA_ATOM, 32,
+                        PropModeReplace, (unsigned char *) windowTypes.constData(),
+                        windowTypes.count());
+    } else {
+        XDeleteProperty(X11->display, q->winId(), ATOM(_NET_WM_WINDOW_TYPE));
+    }
+}
+
+/*!
+  \internal
+  Platform-specific part of QWidget::hide().
+*/
+
+void QWidgetPrivate::hide_sys()
+{
+    Q_Q(QWidget);
+    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+    deactivateWidgetCleanup();
+    if (q->isWindow()) {
+        X11->deferred_map.removeAll(q);
+        if (q->internalWinId()) // in nsplugin, may be 0
+            XWithdrawWindow(X11->display, q->internalWinId(), xinfo.screen());
+        XFlush(X11->display);
+    } else {
+        invalidateBuffer(q->rect());
+        if (q->internalWinId()) // in nsplugin, may be 0
+            XUnmapWindow(X11->display, q->internalWinId());
+    }
+    q->setAttribute(Qt::WA_Mapped, false);
+}
+
+void QWidgetPrivate::setFocus_sys()
+{
+
+}
+
+
+void QWidgetPrivate::raise_sys()
+{
+    Q_Q(QWidget);
+    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+    if (q->internalWinId())
+        XRaiseWindow(X11->display, q->internalWinId());
+}
+
+void QWidgetPrivate::lower_sys()
+{
+    Q_Q(QWidget);
+    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+    if (q->internalWinId())
+        XLowerWindow(X11->display, q->internalWinId());
+    if(!q->isWindow())
+        invalidateBuffer(q->rect());
+}
+
+void QWidgetPrivate::stackUnder_sys(QWidget* w)
+{
+    Q_Q(QWidget);
+    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+    if (q->internalWinId() && w->internalWinId()) {
+        Window stack[2];
+        stack[0] = w->internalWinId();;
+        stack[1] = q->internalWinId();
+        XRestackWindows(X11->display, stack, 2);
+    }
+    if(!q->isWindow() || !w->internalWinId())
+        invalidateBuffer(q->rect());
+}
+
+
+static void do_size_hints(QWidget* widget, QWExtra *x)
+{
+    Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
+    XSizeHints s;
+    s.flags = 0;
+    if (x) {
+        QRect g = widget->geometry();
+        s.x = g.x();
+        s.y = g.y();
+        s.width = g.width();
+        s.height = g.height();
+        if (x->minw > 0 || x->minh > 0) {
+            // add minimum size hints
+            s.flags |= PMinSize;
+            s.min_width  = qMin(XCOORD_MAX, x->minw);
+            s.min_height = qMin(XCOORD_MAX, x->minh);
+        }
+        if (x->maxw < QWIDGETSIZE_MAX || x->maxh < QWIDGETSIZE_MAX) {
+            // add maximum size hints
+            s.flags |= PMaxSize;
+            s.max_width  = qMin(XCOORD_MAX, x->maxw);
+            s.max_height = qMin(XCOORD_MAX, x->maxh);
+        }
+        if (x->topextra &&
+            (x->topextra->incw > 0 || x->topextra->inch > 0)) {
+            // add resize increment hints
+            s.flags |= PResizeInc | PBaseSize;
+            s.width_inc = x->topextra->incw;
+            s.height_inc = x->topextra->inch;
+            s.base_width = x->topextra->basew;
+            s.base_height = x->topextra->baseh;
+        }
+    }
+    if (widget->testAttribute(Qt::WA_Moved)) {
+        // user (i.e. command-line) specified position
+        s.flags |= USPosition;
+        s.flags |= PPosition;
+    }
+    if (widget->testAttribute(Qt::WA_Resized)) {
+        // user (i.e. command-line) specified size
+        s.flags |= USSize;
+        s.flags |= PSize;
+    }
+    s.flags |= PWinGravity;
+    if (widget->testAttribute(Qt::WA_Moved) && x && x->topextra && !x->topextra->posFromMove) {
+        // position came from setGeometry(), tell the WM that we don't
+        // want our window gravity-shifted
+        s.win_gravity = StaticGravity;
+    } else {
+        // position came from move()
+        s.x = widget->x();
+        s.y = widget->y();
+        s.win_gravity = QApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity;
+    }
+    if (widget->internalWinId())
+        XSetWMNormalHints(X11->display, widget->internalWinId(), &s);
+}
+
+
+/*
+  Helper function for non-toplevel widgets. Helps to map Qt's 32bit
+  coordinate system to X11's 16bit coordinate system.
+
+  Sets the geometry of the widget to data.crect, but clipped to sizes
+  that X can handle. Unmaps widgets that are completely outside the
+  valid range.
+
+  Maintains data.wrect, which is the geometry of the X widget,
+  measured in this widget's coordinate system.
+
+  if the parent is not clipped, parentWRect is empty, otherwise
+  parentWRect is the geometry of the parent's X rect, measured in
+  parent's coord sys
+ */
+void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &)
+{
+    Q_Q(QWidget);
+    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+
+    /*
+      There are up to four different coordinate systems here:
+      Qt coordinate system for this widget.
+      X coordinate system for this widget (relative to wrect).
+      Qt coordinate system for parent
+      X coordinate system for parent (relative to parent's wrect).
+     */
+    Display *dpy = xinfo.display();
+    QRect validRange(-XCOORD_MAX,-XCOORD_MAX, 2*XCOORD_MAX, 2*XCOORD_MAX);
+    QRect wrectRange(-WRECT_MAX,-WRECT_MAX, 2*WRECT_MAX, 2*WRECT_MAX);
+    QRect wrect;
+    //xrect is the X geometry of my X widget. (starts out in  parent's Qt coord sys, and ends up in parent's X coord sys)
+    QRect xrect = data.crect;
+
+    const QWidget *const parent = q->parentWidget();
+    QRect parentWRect = parent->data->wrect;
+
+    if (parentWRect.isValid()) {
+        // parent is clipped, and we have to clip to the same limit as parent
+        if (!parentWRect.contains(xrect)) {
+            xrect &= parentWRect;
+            wrect = xrect;
+            //translate from parent's to my Qt coord sys
+            wrect.translate(-data.crect.topLeft());
+        }
+        //translate from parent's Qt coords to parent's X coords
+        xrect.translate(-parentWRect.topLeft());
+
+    } else {
+        // parent is not clipped, we may or may not have to clip
+
+        if (data.wrect.isValid() && QRect(QPoint(),data.crect.size()).contains(data.wrect)) {
+            // This is where the main optimization is: we are already
+            // clipped, and if our clip is still valid, we can just
+            // move our window, and do not need to move or clip
+            // children
+
+            QRect vrect = xrect & parent->rect();
+            vrect.translate(-data.crect.topLeft()); //the part of me that's visible through parent, in my Qt coords
+            if (data.wrect.contains(vrect)) {
+                xrect = data.wrect;
+                xrect.translate(data.crect.topLeft());
+                if (data.winid)
+                    XMoveWindow(dpy, data.winid, xrect.x(), xrect.y());
+                return;
+            }
+        }
+
+        if (!validRange.contains(xrect)) {
+            // we are too big, and must clip
+            xrect &=wrectRange;
+            wrect = xrect;
+            wrect.translate(-data.crect.topLeft());
+            //parent's X coord system is equal to parent's Qt coord
+            //sys, so we don't need to map xrect.
+        }
+
+    }
+
+    // unmap if we are outside the valid window system coord system
+    bool outsideRange = !xrect.isValid();
+    bool mapWindow = false;
+    if (q->testAttribute(Qt::WA_OutsideWSRange) != outsideRange) {
+        q->setAttribute(Qt::WA_OutsideWSRange, outsideRange);
+        if (outsideRange) {
+            if (data.winid)
+                XUnmapWindow(dpy, data.winid);
+            q->setAttribute(Qt::WA_Mapped, false);
+        } else if (!q->isHidden()) {
+            mapWindow = true;
+        }
+    }
+
+    if (outsideRange)
+        return;
+
+    bool jump = (data.wrect != wrect);
+    data.wrect = wrect;
+
+
+    // and now recursively for all children...
+    // ### can be optimized
+    for (int i = 0; i < children.size(); ++i) {
+        QObject *object = children.at(i);
+        if (object->isWidgetType()) {
+            QWidget *w = static_cast<QWidget *>(object);
+            if (!w->isWindow() && w->testAttribute(Qt::WA_WState_Created))
+                w->d_func()->setWSGeometry(jump);
+        }
+    }
+
+    if (data.winid) {
+        // move ourselves to the new position and map (if necessary) after
+        // the movement. Rationale: moving unmapped windows is much faster
+        // than moving mapped windows
+        if (jump) //avoid flicker when jumping
+            XSetWindowBackgroundPixmap(dpy, data.winid, XNone);
+        if (!parent->internalWinId())
+            xrect.translate(parent->mapTo(q->nativeParentWidget(), QPoint(0, 0)));
+        XMoveResizeWindow(dpy, data.winid, xrect.x(), xrect.y(), xrect.width(), xrect.height());
+    }
+
+    //to avoid flicker, we have to show children after the helper widget has moved
+    if (jump) {
+        for (int i = 0; i < children.size(); ++i) {
+            QObject *object = children.at(i);
+            if (object->isWidgetType()) {
+                QWidget *w = static_cast<QWidget *>(object);
+                if (!w->testAttribute(Qt::WA_OutsideWSRange) && !w->testAttribute(Qt::WA_Mapped) && !w->isHidden()) {
+                    w->setAttribute(Qt::WA_Mapped);
+                    if (w->internalWinId())
+                        XMapWindow(dpy, w->data->winid);
+                }
+            }
+        }
+    }
+
+
+    if  (jump && data.winid)
+        XClearArea(dpy, data.winid, 0, 0, wrect.width(), wrect.height(), True);
+
+    if (mapWindow && !dontShow) {
+        q->setAttribute(Qt::WA_Mapped);
+        if (data.winid)
+            XMapWindow(dpy, data.winid);
+    }
+}
+
+void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
+{
+    Q_Q(QWidget);
+    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+    Display *dpy = X11->display;
+
+    if ((q->windowType() == Qt::Desktop))
+        return;
+    if (q->isWindow()) {
+        if (!X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))
+            && !X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ)))
+            data.window_state &= ~Qt::WindowMaximized;
+        if (!X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN)))
+            data.window_state &= ~Qt::WindowFullScreen;
+        if (QTLWExtra *topData = maybeTopData())
+            topData->normalGeometry = QRect(0,0,-1,-1);
+    } else {
+        uint s = data.window_state;
+        s &= ~(Qt::WindowMaximized | Qt::WindowFullScreen);
+        data.window_state = s;
+    }
+    if (extra) {                                // any size restrictions?
+        w = qMin(w,extra->maxw);
+        h = qMin(h,extra->maxh);
+        w = qMax(w,extra->minw);
+        h = qMax(h,extra->minh);
+    }
+    QPoint oldPos(q->pos());
+    QSize oldSize(q->size());
+    QRect oldGeom(data.crect);
+    QRect  r(x, y, w, h);
+
+    // We only care about stuff that changes the geometry, or may
+    // cause the window manager to change its state
+    if (!q->isWindow() && oldGeom == r)
+        return;
+
+    data.crect = r;
+    bool isResize = q->size() != oldSize;
+
+    if (q->isWindow()) {
+        if (w == 0 || h == 0) {
+            q->setAttribute(Qt::WA_OutsideWSRange, true);
+            if (q->isVisible() && q->testAttribute(Qt::WA_Mapped))
+                hide_sys();
+        } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) {
+            q->setAttribute(Qt::WA_OutsideWSRange, false);
+
+            // put the window in its place and show it
+            if (data.winid)
+                XMoveResizeWindow(dpy, data.winid, x, y, w, h);
+            topData()->posFromMove = false; // force StaticGravity
+            do_size_hints(q, extra);
+            show_sys();
+        } else {
+            q->setAttribute(Qt::WA_OutsideWSRange, false);
+            if (!q->isVisible())
+                do_size_hints(q, extra);
+            if (isMove) {
+                if ((data.window_flags & Qt::X11BypassWindowManagerHint) == Qt::X11BypassWindowManagerHint
+                    // work around 4Dwm's incompliance with ICCCM 4.1.5
+                    || X11->desktopEnvironment == DE_4DWM) {
+                    if (data.winid)
+                        XMoveResizeWindow(dpy, data.winid, x, y, w, h);
+                } else if (q->isVisible()
+                           && topData()->validWMState
+                           && X11->isSupportedByWM(ATOM(_NET_MOVERESIZE_WINDOW))) {
+                    XEvent e;
+                    e.xclient.type = ClientMessage;
+                    e.xclient.message_type = ATOM(_NET_MOVERESIZE_WINDOW);
+                    e.xclient.display = X11->display;
+                    e.xclient.window = q->internalWinId();
+                    e.xclient.format = 32;
+                    e.xclient.data.l[0] = StaticGravity | 1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12;
+                    e.xclient.data.l[1] = x;
+                    e.xclient.data.l[2] = y;
+                    e.xclient.data.l[3] = w;
+                    e.xclient.data.l[4] = h;
+                    XSendEvent(X11->display, RootWindow(X11->display, q->x11Info().screen()),
+                               false, (SubstructureNotifyMask | SubstructureRedirectMask), &e);
+                } else if (data.winid) {
+                    // pos() is right according to ICCCM 4.1.5
+                    XMoveResizeWindow(dpy, data.winid, q->pos().x(), q->pos().y(), w, h);
+                }
+            } else if (isResize && data.winid) {
+                if (!q->isVisible()
+                    && topData()->validWMState
+                    && !q->testAttribute(Qt::WA_PendingMoveEvent)) {
+                    /*
+                       even though we've not visible, we could be in a
+                       race w/ the window manager, and it may ignore
+                       our ConfigureRequest. setting posFromMove to
+                       false makes sure that doDeferredMap() in
+                       qapplication_x11.cpp keeps the window in the
+                       right place
+                    */
+                    topData()->posFromMove = false;
+                }
+                XResizeWindow(dpy, data.winid, w, h);
+            }
+        }
+        if (isResize && !q->testAttribute(Qt::WA_DontShowOnScreen)) // set config pending only on resize, see qapplication_x11.cpp, translateConfigEvent()
+            q->setAttribute(Qt::WA_WState_ConfigPending);
+
+    } else {
+        QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
+        const bool inTopLevelResize = tlwExtra ? tlwExtra->inTopLevelResize : false;
+        const bool disableInTopLevelResize = inTopLevelResize && q->internalWinId();
+        if (disableInTopLevelResize) {
+            // Top-level resize optimization does not work for native child widgets;
+            // disable it for this particular widget.
+            tlwExtra->inTopLevelResize = false;
+        }
+
+        if (!isResize && (!inTopLevelResize || disableInTopLevelResize) && q->isVisible()) {
+            moveRect(QRect(oldPos, oldSize), x - oldPos.x(), y - oldPos.y());
+        }
+        if (q->testAttribute(Qt::WA_WState_Created))
+            setWSGeometry();
+
+        if (isResize && (!inTopLevelResize || disableInTopLevelResize) && q->isVisible())
+            invalidateBuffer_resizeHelper(oldPos, oldSize);
+
+        if (disableInTopLevelResize)
+            tlwExtra->inTopLevelResize = true;
+    }
+
+    if (q->isVisible()) {
+        if (isMove && q->pos() != oldPos) {
+            if (X11->desktopEnvironment != DE_4DWM) {
+                // pos() is right according to ICCCM 4.1.5
+                QMoveEvent e(q->pos(), oldPos);
+                QApplication::sendEvent(q, &e);
+            } else {
+                // work around 4Dwm's incompliance with ICCCM 4.1.5
+                QMoveEvent e(data.crect.topLeft(), oldGeom.topLeft());
+                QApplication::sendEvent(q, &e);
+            }
+        }
+        if (isResize) {
+            static bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt();
+            // If we have a backing store with static contents, we have to disable the top-level
+            // resize optimization in order to get invalidated regions for resized widgets.
+            // The optimization discards all invalidateBuffer() calls since we're going to
+            // repaint everything anyways, but that's not the case with static contents.
+            const bool setTopLevelResize = !slowResize && q->isWindow() && extra && extra->topextra
+                                           && !extra->topextra->inTopLevelResize
+                                           && (!extra->topextra->backingStore
+                                               || !extra->topextra->backingStore->hasStaticContents());
+            if (setTopLevelResize)
+                extra->topextra->inTopLevelResize = true;
+            QResizeEvent e(q->size(), oldSize);
+            QApplication::sendEvent(q, &e);
+            if (setTopLevelResize)
+                extra->topextra->inTopLevelResize = false;
+        }
+    } else {
+        if (isMove && q->pos() != oldPos)
+            q->setAttribute(Qt::WA_PendingMoveEvent, true);
+        if (isResize)
+            q->setAttribute(Qt::WA_PendingResizeEvent, true);
+    }
+}
+
+void QWidgetPrivate::setConstraints_sys()
+{
+    Q_Q(QWidget);
+#ifdef ALIEN_DEBUG
+    qDebug() << "QWidgetPrivate::setConstraints_sys START" << q;
+#endif
+    if (q->testAttribute(Qt::WA_WState_Created))
+        do_size_hints(q, extra);
+#ifdef ALIEN_DEBUG
+    qDebug() << "QWidgetPrivate::setConstraints_sys END" << q;
+#endif
+}
+
+void QWidgetPrivate::scroll_sys(int dx, int dy)
+{
+    Q_Q(QWidget);
+
+    scrollChildren(dx, dy);
+    if (!paintOnScreen()) {
+        scrollRect(q->rect(), dx, dy);
+    } else {
+        scroll_sys(dx, dy, QRect());
+    }
+}
+
+void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
+{
+    Q_Q(QWidget);
+
+    if (!paintOnScreen()) {
+        scrollRect(r, dx, dy);
+        return;
+    }
+    bool valid_rect = r.isValid();
+    bool just_update = qAbs(dx) > q->width() || qAbs(dy) > q->height();
+    QRect sr = valid_rect ? r : clipRect();
+    if (just_update)
+        q->update();
+    else if (!valid_rect)
+        dirty.translate(dx, dy);
+
+    int x1, y1, x2, y2, w = sr.width(), h = sr.height();
+    if (dx > 0) {
+        x1 = sr.x();
+        x2 = x1+dx;
+        w -= dx;
+    } else {
+        x2 = sr.x();
+        x1 = x2-dx;
+        w += dx;
+    }
+    if (dy > 0) {
+        y1 = sr.y();
+        y2 = y1+dy;
+        h -= dy;
+    } else {
+        y2 = sr.y();
+        y1 = y2-dy;
+        h += dy;
+    }
+
+    if (dx == 0 && dy == 0)
+        return;
+
+    Display *dpy = X11->display;
+    // Want expose events
+    if (w > 0 && h > 0 && !just_update && q->internalWinId()) {
+        GC gc = XCreateGC(dpy, q->internalWinId(), 0, 0);
+        XSetGraphicsExposures(dpy, gc, True);
+        XCopyArea(dpy, q->internalWinId(), q->internalWinId(), gc, x1, y1, w, h, x2, y2);
+        XFreeGC(dpy, gc);
+    }
+
+    if (!valid_rect && !children.isEmpty()) {        // scroll children
+        QPoint pd(dx, dy);
+        for (int i = 0; i < children.size(); ++i) { // move all children
+            register QObject *object = children.at(i);
+            if (object->isWidgetType()) {
+                QWidget *w = static_cast<QWidget *>(object);
+                if (!w->isWindow())
+                    w->move(w->pos() + pd);
+            }
+        }
+    }
+
+    if (just_update)
+        return;
+
+    // Don't let the server be bogged-down with repaint events
+    bool repaint_immediately = (qt_sip_count(q) < 3 && !q->testAttribute(Qt::WA_WState_InPaintEvent));
+
+    if (dx) {
+        int x = x2 == sr.x() ? sr.x()+w : sr.x();
+        if (repaint_immediately)
+            q->repaint(x, sr.y(), qAbs(dx), sr.height());
+        else if (q->internalWinId())
+            XClearArea(dpy, data.winid, x, sr.y(), qAbs(dx), sr.height(), True);
+    }
+    if (dy) {
+        int y = y2 == sr.y() ? sr.y()+h : sr.y();
+        if (repaint_immediately)
+            q->repaint(sr.x(), y, sr.width(), qAbs(dy));
+        else if (q->internalWinId())
+            XClearArea(dpy, data.winid, sr.x(), y, sr.width(), qAbs(dy), True);
+    }
+
+    qt_insert_sip(q, dx, dy); // #### ignores r
+}
+
+int QWidget::metric(PaintDeviceMetric m) const
+{
+    Q_D(const QWidget);
+    int val;
+    if (m == PdmWidth) {
+        val = data->crect.width();
+    } else if (m == PdmHeight) {
+        val = data->crect.height();
+    } else {
+        Display *dpy = X11->display;
+        int scr = d->xinfo.screen();
+        switch (m) {
+            case PdmDpiX:
+            case PdmPhysicalDpiX:
+                if (d->extra && d->extra->customDpiX)
+                    val = d->extra->customDpiX;
+                else if (d->parent)
+                    val = static_cast<QWidget *>(d->parent)->metric(m);
+                else
+                    val = QX11Info::appDpiX(scr);
+                break;
+            case PdmDpiY:
+            case PdmPhysicalDpiY:
+                if (d->extra && d->extra->customDpiY)
+                    val = d->extra->customDpiY;
+                else if (d->parent)
+                    val = static_cast<QWidget *>(d->parent)->metric(m);
+                else
+                    val = QX11Info::appDpiY(scr);
+                break;
+            case PdmWidthMM:
+                val = (DisplayWidthMM(dpy,scr)*data->crect.width())/
+                      DisplayWidth(dpy,scr);
+                break;
+            case PdmHeightMM:
+                val = (DisplayHeightMM(dpy,scr)*data->crect.height())/
+                      DisplayHeight(dpy,scr);
+                break;
+            case PdmNumColors:
+                val = d->xinfo.cells();
+                break;
+            case PdmDepth:
+                val = d->xinfo.depth();
+                break;
+            default:
+                val = 0;
+                qWarning("QWidget::metric: Invalid metric command");
+        }
+    }
+    return val;
+}
+
+void QWidgetPrivate::createSysExtra()
+{
+    extra->compress_events = true;
+    extra->xDndProxy = 0;
+}
+
+void QWidgetPrivate::deleteSysExtra()
+{
+}
+
+void QWidgetPrivate::createTLSysExtra()
+{
+    extra->topextra->spont_unmapped = 0;
+    extra->topextra->dnd = 0;
+    extra->topextra->validWMState = 0;
+    extra->topextra->waitingForMapNotify = 0;
+    extra->topextra->parentWinId = 0;
+    extra->topextra->userTimeWindow = 0;
+#ifndef QT_NO_XSYNC
+    extra->topextra->syncUpdateCounter = 0;
+    extra->topextra->syncRequestTimestamp = 0;
+    extra->topextra->newCounterValueHi = 0;
+    extra->topextra->newCounterValueLo = 0;
+#endif
+}
+
+void QWidgetPrivate::deleteTLSysExtra()
+{
+    // don't destroy input context here. it will be destroyed in
+    // QWidget::destroy() destroyInputContext();
+}
+
+void QWidgetPrivate::registerDropSite(bool on)
+{
+    Q_UNUSED(on);
+}
+
+void QWidgetPrivate::setMask_sys(const QRegion &region)
+{
+    Q_Q(QWidget);
+    if (!q->internalWinId())
+        return;
+
+    if (region.isEmpty()) {
+        XShapeCombineMask(X11->display, q->internalWinId(), ShapeBounding, 0, 0,
+                          XNone, ShapeSet);
+    } else {
+        XShapeCombineRegion(X11->display, q->internalWinId(), ShapeBounding, 0, 0,
+                            region.handle(), ShapeSet);
+    }
+}
+
+/*!
+  \internal
+
+  Computes the frame rectangle when needed.  This is an internal function, you
+  should never call this.
+*/
+
+void QWidgetPrivate::updateFrameStrut()
+{
+    Q_Q(QWidget);
+
+    QTLWExtra *top = topData();
+    if (!top->validWMState) {
+        return;
+    }
+    if (!q->isWindow() && !q->internalWinId()) {
+        data.fstrut_dirty = false;
+        return;
+    }
+
+    Atom type_ret;
+    Window l = q->effectiveWinId(), w = l, p, r; // target window, its parent, root
+    Window *c;
+    int i_unused;
+    unsigned int nc;
+    unsigned char *data_ret;
+    unsigned long l_unused;
+
+    while (XQueryTree(X11->display, w, &r, &p, &c, &nc)) {
+        if (c && nc > 0)
+            XFree(c);
+
+        if (! p) {
+            qWarning("QWidget::updateFrameStrut: No parent");
+            return;
+        }
+
+        // if the parent window is the root window, an Enlightenment virtual root or
+        // a NET WM virtual root window, stop here
+        data_ret = 0;
+        if (p == r ||
+            (XGetWindowProperty(X11->display, p,
+                                ATOM(ENLIGHTENMENT_DESKTOP), 0, 1, False, XA_CARDINAL,
+                                &type_ret, &i_unused, &l_unused, &l_unused,
+                                &data_ret) == Success &&
+             type_ret == XA_CARDINAL)) {
+            if (data_ret)
+                XFree(data_ret);
+
+            break;
+        } else if (X11->isSupportedByWM(ATOM(_NET_VIRTUAL_ROOTS)) && X11->net_virtual_root_list) {
+            int i = 0;
+            while (X11->net_virtual_root_list[i] != 0) {
+                if (X11->net_virtual_root_list[i++] == p)
+                    break;
+            }
+        }
+
+        l = w;
+        w = p;
+    }
+
+    // we have our window
+    int transx, transy;
+    XWindowAttributes wattr;
+    if (XTranslateCoordinates(X11->display, l, w,
+                              0, 0, &transx, &transy, &p) &&
+        XGetWindowAttributes(X11->display, w, &wattr)) {
+        top->frameStrut.setCoords(transx,
+                                  transy,
+                                  wattr.width - data.crect.width() - transx,
+                                  wattr.height - data.crect.height() - transy);
+
+        // add the border_width for the window managers frame... some window managers
+        // do not use a border_width of zero for their frames, and if we the left and
+        // top strut, we ensure that pos() is absolutely correct.  frameGeometry()
+        // will still be incorrect though... perhaps i should have foffset as well, to
+        // indicate the frame offset (equal to the border_width on X).
+        // - Brad
+        top->frameStrut.adjust(wattr.border_width,
+                               wattr.border_width,
+                               wattr.border_width,
+                               wattr.border_width);
+    }
+
+   data.fstrut_dirty = false;
+}
+
+void QWidgetPrivate::setWindowOpacity_sys(qreal opacity)
+{
+    Q_Q(QWidget);
+    ulong value = ulong(opacity * 0xffffffff);
+    XChangeProperty(QX11Info::display(), q->internalWinId(), ATOM(_NET_WM_WINDOW_OPACITY), XA_CARDINAL,
+                    32, PropModeReplace, (uchar*)&value, 1);
+}
+
+const QX11Info &QWidget::x11Info() const
+{
+    Q_D(const QWidget);
+    return d->xinfo;
+}
+
+void QWidgetPrivate::setWindowRole()
+{
+    Q_Q(QWidget);
+    if (!q->internalWinId())
+        return;
+    QByteArray windowRole = topData()->role.toUtf8();
+    XChangeProperty(X11->display, q->internalWinId(),
+                    ATOM(WM_WINDOW_ROLE), XA_STRING, 8, PropModeReplace,
+                    (unsigned char *)windowRole.constData(), windowRole.length());
+}
+
+Q_GLOBAL_STATIC(QX11PaintEngine, qt_widget_paintengine)
+QPaintEngine *QWidget::paintEngine() const
+{
+    Q_D(const QWidget);
+    if (qt_widget_paintengine()->isActive()) {
+        if (d->extraPaintEngine)
+            return d->extraPaintEngine;
+        QWidget *self = const_cast<QWidget *>(this);
+        self->d_func()->extraPaintEngine = new QX11PaintEngine();
+        return d->extraPaintEngine;
+    }
+    return qt_widget_paintengine();
+}
+
+QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys()
+{
+    return new QX11WindowSurface(q_func());
+}
+
+Qt::HANDLE QWidget::x11PictureHandle() const
+{
+#ifndef QT_NO_XRENDER
+    Q_D(const QWidget);
+    if (!internalWinId() && testAttribute(Qt::WA_WState_Created))
+        (void)winId(); // enforce native window
+    return d->picture;
+#else
+    return 0;
+#endif // QT_NO_XRENDER
+}
+
+#ifndef QT_NO_XRENDER
+XRenderColor QX11Data::preMultiply(const QColor &c)
+{
+    XRenderColor color;
+    const uint A = c.alpha(),
+               R = c.red(),
+               G = c.green(),
+               B = c.blue();
+    color.alpha = (A | A << 8);
+    color.red   = (R | R << 8) * color.alpha / 0x10000;
+    color.green = (G | G << 8) * color.alpha / 0x10000;
+    color.blue  = (B | B << 8) * color.alpha / 0x10000;
+    return color;
+}
+Picture QX11Data::getSolidFill(int screen, const QColor &c)
+{
+    if (!X11->use_xrender)
+        return XNone;
+
+    XRenderColor color = preMultiply(c);
+    for (int i = 0; i < X11->solid_fill_count; ++i) {
+        if (X11->solid_fills[i].screen == screen
+            && X11->solid_fills[i].color.alpha == color.alpha
+            && X11->solid_fills[i].color.red == color.red
+            && X11->solid_fills[i].color.green == color.green
+            && X11->solid_fills[i].color.blue == color.blue)
+            return X11->solid_fills[i].picture;
+    }
+    // none found, replace one
+    int i = rand() % 16;
+
+    if (X11->solid_fills[i].screen != screen && X11->solid_fills[i].picture) {
+        XRenderFreePicture (X11->display, X11->solid_fills[i].picture);
+        X11->solid_fills[i].picture = 0;
+    }
+
+    if (!X11->solid_fills[i].picture) {
+        Pixmap pixmap = XCreatePixmap (X11->display, RootWindow (X11->display, screen), 1, 1, 32);
+        XRenderPictureAttributes attrs;
+        attrs.repeat = True;
+        X11->solid_fills[i].picture = XRenderCreatePicture (X11->display, pixmap,
+                                                            XRenderFindStandardFormat(X11->display, PictStandardARGB32),
+                                                            CPRepeat, &attrs);
+        XFreePixmap (X11->display, pixmap);
+    }
+
+    X11->solid_fills[i].color = color;
+    X11->solid_fills[i].screen = screen;
+    XRenderFillRectangle (X11->display, PictOpSrc, X11->solid_fills[i].picture, &color, 0, 0, 1, 1);
+    return X11->solid_fills[i].picture;
+}
+#endif
+
+void QWidgetPrivate::setModal_sys()
+{
+}
+
+void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const QX11WindowAttributes &att)
+{
+    QX11InfoData* xd = xinfo->getX11Data(true);
+    const XWindowAttributes &a = *(att.att);
+    // find which screen the window is on...
+    xd->screen = QX11Info::appScreen(); // by default, use the default :)
+    int i;
+    for (i = 0; i < ScreenCount(X11->display); i++) {
+        if (RootWindow(X11->display, i) == a.root) {
+            xd->screen = i;
+            break;
+        }
+    }
+
+    xd->depth = a.depth;
+    xd->cells = DisplayCells(X11->display, xd->screen);
+    xd->visual = a.visual;
+    xd->defaultVisual = (XVisualIDFromVisual((Visual *) a.visual) ==
+                         XVisualIDFromVisual((Visual *) QX11Info::appVisual(xinfo->screen())));
+    xd->colormap = a.colormap;
+    xd->defaultColormap = (a.colormap == QX11Info::appColormap(xinfo->screen()));
+    xinfo->setX11Data(xd);
+}
+
+QT_END_NAMESPACE