Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/kernel/qwidget_x11.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    347347}
    348348
     349static Bool checkForConfigureAndExpose(Display *, XEvent *e, XPointer)
     350{
     351    return e->type == ConfigureNotify || e->type == Expose;
     352}
    349353
    350354Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w)
     
    356360    QTime t;
    357361    t.start();
     362    static const int maximumWaitTime = 2000;
    358363    if (!w->testAttribute(Qt::WA_WState_Created))
    359364        return;
    360     while (!XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), ReparentNotify, &ev)) {
    361         if (XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), MapNotify, &ev))
    362             break;
    363         if (t.elapsed() > 500)
    364             return; // give up, no event available
     365
     366    if (!(w->windowFlags() & Qt::X11BypassWindowManagerHint)) {
     367        // if the window is not override-redirect, then the window manager
     368        // will reparent us to the frame decoration window.
     369        while (!XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), ReparentNotify, &ev)) {
     370            if (t.elapsed() > maximumWaitTime)
     371                return;
     372            qApp->syncX(); // non-busy wait
     373        }
     374    }
     375
     376    while (!XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), MapNotify, &ev)) {
     377        if (t.elapsed() > maximumWaitTime)
     378            return;
    365379        qApp->syncX(); // non-busy wait
    366380    }
     381
    367382    qApp->x11ProcessEvent(&ev);
    368     if (XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), ConfigureNotify, &ev))
    369         qApp->x11ProcessEvent(&ev);
     383
     384    // ok, seems like the window manager successfully reparented us, we'll wait
     385    // for the first paint event to arrive, while handling ConfigureNotify in
     386    // the arrival order
     387    while(1)
     388    {
     389        if (XCheckIfEvent(X11->display, &ev, checkForConfigureAndExpose, 0)) {
     390            qApp->x11ProcessEvent(&ev);
     391            if (ev.type == Expose)
     392                return;
     393        }
     394        if (t.elapsed() > maximumWaitTime)
     395            return;
     396        qApp->syncX(); // non-busy wait
     397    }
    370398}
    371399
     
    491519        initializeWindow = true;
    492520
     521    QX11Info *parentXinfo = parentWidget ? &parentWidget->d_func()->xinfo : 0;
     522
    493523    if (desktop &&
    494524        qt_x11_create_desktop_on_screen >= 0 &&
     
    497527        QX11InfoData *xd = &X11->screens[qt_x11_create_desktop_on_screen];
    498528        xinfo.setX11Data(xd);
    499     } else if (parentWidget && parentWidget->d_func()->xinfo.screen() != xinfo.screen()) {
    500         xinfo = parentWidget->d_func()->xinfo;
     529    } else if (parentXinfo && (parentXinfo->screen() != xinfo.screen()
     530                               || (parentXinfo->visual() != xinfo.visual()
     531                                   && !q->inherits("QGLWidget"))))
     532    {
     533        // QGLWidgets have to be excluded here as they have a
     534        // specially crafted QX11Info structure which can't be swapped
     535        // out with the parent widgets QX11Info. The parent visual,
     536        // for instance, might not even be GL capable.
     537        xinfo = *parentXinfo;
    501538    }
    502539
     
    513550        data.crect.setRect(0, 0, sw, sh);
    514551    } else if (topLevel && !q->testAttribute(Qt::WA_Resized)) {
     552        QDesktopWidget *desktopWidget = qApp->desktop();
     553        if (desktopWidget->isVirtualDesktop()) {
     554            QRect r = desktopWidget->screenGeometry();
     555            sw = r.width();
     556            sh = r.height();
     557        }
     558
    515559        int width = sw / 2;
    516560        int height = 4 * sh / 10;
     
    755799                      qBound(1, data.crect.height(), XCOORD_MAX));
    756800        XStoreName(dpy, id, appName.data());
    757         Atom protocols[4];
     801        Atom protocols[5];
    758802        int n = 0;
    759803        protocols[n++] = ATOM(WM_DELETE_WINDOW);        // support del window protocol
    760804        protocols[n++] = ATOM(WM_TAKE_FOCUS);                // support take focus window protocol
    761805        protocols[n++] = ATOM(_NET_WM_PING);                // support _NET_WM_PING protocol
     806#ifndef QT_NO_XSYNC
     807        protocols[n++] = ATOM(_NET_WM_SYNC_REQUEST);        // support _NET_WM_SYNC_REQUEST protocol
     808#endif // QT_NO_XSYNC
    762809        if (flags & Qt::WindowContextHelpButtonHint)
    763810            protocols[n++] = ATOM(_NET_WM_CONTEXT_HELP);
     
    883930}
    884931
     932static void qt_x11_recreateWidget(QWidget *widget)
     933{
     934    if (widget->inherits("QGLWidget")) {
     935        // We send QGLWidgets a ParentChange event which causes them to
     936        // recreate their GL context, which in turn causes them to choose
     937        // their visual again. Now that WA_TranslucentBackground is set,
     938        // QGLContext::chooseVisual will select an ARGB visual.
     939        QEvent e(QEvent::ParentChange);
     940        QApplication::sendEvent(widget, &e);
     941    } else {
     942        // For regular widgets, reparent them with their parent which
     943        // also triggers a recreation of the native window
     944        QPoint pos = widget->pos();
     945        bool visible = widget->isVisible();
     946        if (visible)
     947            widget->hide();
     948
     949        widget->setParent(widget->parentWidget(), widget->windowFlags());
     950        widget->move(pos);
     951        if (visible)
     952            widget->show();
     953    }
     954}
     955
     956static void qt_x11_recreateNativeWidgetsRecursive(QWidget *widget)
     957{
     958    if (widget->internalWinId())
     959        qt_x11_recreateWidget(widget);
     960
     961    const QObjectList &children = widget->children();
     962    for (int i = 0; i < children.size(); ++i) {
     963        QWidget *child = qobject_cast<QWidget*>(children.at(i));
     964        if (child)
     965            qt_x11_recreateNativeWidgetsRecursive(child);
     966    }
     967}
     968
    885969void QWidgetPrivate::x11UpdateIsOpaque()
    886970{
     
    893977    int screen = xinfo.screen();
    894978    if (topLevel && X11->use_xrender
    895         && X11->argbVisuals[screen] && xinfo.depth() != 32) {
    896         // recreate widget
    897         QPoint pos = q->pos();
    898         bool visible = q->isVisible();
    899         if (visible)
    900             q->hide();
    901         q->setParent(q->parentWidget(), q->windowFlags());
    902         q->move(pos);
    903         if (visible)
    904             q->show();
     979        && X11->argbVisuals[screen] && xinfo.depth() != 32)
     980    {
     981        qt_x11_recreateNativeWidgetsRecursive(q);
    905982    }
    906983#endif
     984}
     985
     986/*
     987  Returns true if the background is inherited; otherwise returns
     988  false.
     989
     990  Mainly used in the paintOnScreen case.
     991*/
     992bool QWidgetPrivate::isBackgroundInherited() const
     993{
     994    Q_Q(const QWidget);
     995
     996    // windows do not inherit their background
     997    if (q->isWindow() || q->windowType() == Qt::SubWindow)
     998        return false;
     999
     1000    if (q->testAttribute(Qt::WA_NoSystemBackground) || q->testAttribute(Qt::WA_OpaquePaintEvent))
     1001        return false;
     1002
     1003    const QPalette &pal = q->palette();
     1004    QPalette::ColorRole bg = q->backgroundRole();
     1005    QBrush brush = pal.brush(bg);
     1006
     1007    // non opaque brushes leaves us no choice, we must inherit
     1008    if (!q->autoFillBackground() || !brush.isOpaque())
     1009        return true;
     1010
     1011    if (brush.style() == Qt::SolidPattern) {
     1012        // the background is just a solid color. If there is no
     1013        // propagated contents, then we claim as performance
     1014        // optimization that it was not inheritet. This is the normal
     1015        // case in standard Windows or Motif style.
     1016        const QWidget *w = q->parentWidget();
     1017        if (!w->d_func()->isBackgroundInherited())
     1018            return false;
     1019    }
     1020
     1021    return true;
    9071022}
    9081023
     
    9111026    Q_D(QWidget);
    9121027    if (!isWindow() && parentWidget())
    913         parentWidget()->d_func()->invalidateBuffer(geometry());
     1028        parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
    9141029    d->deactivateWidgetCleanup();
    9151030    if (testAttribute(Qt::WA_WState_Created)) {
     
    9551070                qt_XDestroyWindow(this, X11->display, data->winid);
    9561071        }
    957         d->setWinId(0);
     1072        QT_TRY {
     1073            d->setWinId(0);
     1074        } QT_CATCH (const std::bad_alloc &) {
     1075            // swallow - destructors must not throw
     1076        }
    9581077
    9591078        extern void qPRCleanup(QWidget *widget); // from qapplication_x11.cpp
     
    9661085            // release previous focus information participating with
    9671086            // preedit preservation of qic
    968             QInputContext *qic = inputContext();
     1087            QInputContext *qic = QApplicationPrivate::inputContext;
    9691088            if (qic)
    9701089                qic->widgetDestroyed(this);
     
    9901109    bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
    9911110    if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
    992         q->parentWidget()->d_func()->invalidateBuffer(q->geometry());
     1111        q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
    9931112    extern void qPRCreate(const QWidget *, Window);
    9941113#ifndef QT_NO_CURSOR
     
    12161335        extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap); // qpixmap_x11.cpp
    12171336        XSetWindowBackgroundPixmap(X11->display, q->internalWinId(),
    1218                                    static_cast<QX11PixmapData*>(qt_toX11Pixmap(brush.texture()).data)->x11ConvertToDefaultDepth());
     1337                                   static_cast<QX11PixmapData*>(qt_toX11Pixmap(brush.texture()).data.data())->x11ConvertToDefaultDepth());
    12191338    } else
    12201339        XSetWindowBackground(X11->display, q->internalWinId(),
     
    13091428        return;
    13101429
    1311     XWMHints *h = 0;
    1312     if (q->internalWinId())
    1313         h = XGetWMHints(X11->display, q->internalWinId());
    1314     XWMHints wm_hints;
    1315     if (!h) {
    1316         memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
    1317         h = &wm_hints;
    1318     }
    1319 
    13201430    // preparing images to set the _NET_WM_ICON property
    13211431    QIcon icon = q->windowIcon();
     1432    QVector<long> icon_data;
     1433    Qt::HANDLE pixmap_handle = 0;
    13221434    if (!icon.isNull()) {
    13231435        QList<QSize> availableSizes = icon.availableSizes();
     
    13291441            availableSizes.push_back(QSize(128,128));
    13301442        }
    1331         QVector<long> icon_data;
    13321443        for(int i = 0; i < availableSizes.size(); ++i) {
    13331444            QSize size = availableSizes.at(i);
     
    13401451                icon_data[pos++] = image.height();
    13411452                if (sizeof(long) == sizeof(quint32)) {
    1342                     memcpy(icon_data.data() + pos, image.scanLine(0), image.numBytes());
     1453                    memcpy(icon_data.data() + pos, image.scanLine(0), image.byteCount());
    13431454                } else {
    13441455                    for (int y = 0; y < image.height(); ++y) {
     
    13511462        }
    13521463        if (!icon_data.isEmpty()) {
    1353             if (q->internalWinId()) {
    1354                 XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON), XA_CARDINAL, 32,
    1355                                 PropModeReplace, (unsigned char *) icon_data.data(),
    1356                                 icon_data.size());
    1357             }
    13581464            extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap);
    13591465            /*
     
    13691475                if (!forceReset || !topData->iconPixmap)
    13701476                    topData->iconPixmap = new QBitmap(qt_toX11Pixmap(icon.pixmap(QSize(64,64))));
    1371                 h->icon_pixmap = topData->iconPixmap->handle();
     1477                pixmap_handle = topData->iconPixmap->handle();
    13721478            } else {
    13731479                // default depth, use a normal pixmap (even though this
     
    13751481                if (!forceReset || !topData->iconPixmap)
    13761482                    topData->iconPixmap = new QPixmap(qt_toX11Pixmap(icon.pixmap(QSize(64,64))));
    1377                 h->icon_pixmap = static_cast<QX11PixmapData*>(topData->iconPixmap->data)->x11ConvertToDefaultDepth();
     1483                pixmap_handle = static_cast<QX11PixmapData*>(topData->iconPixmap->data.data())->x11ConvertToDefaultDepth();
    13781484            }
    1379             h->flags |= IconPixmapHint;
    1380         } else {
    1381             h->flags &= ~(IconPixmapHint | IconMaskHint);
    1382         }
    1383     }
    1384 
    1385     if (q->internalWinId())
    1386         XSetWMHints(X11->display, q->internalWinId(), h);
     1485        }
     1486    }
     1487
     1488    if (!q->internalWinId())
     1489        return;
     1490
     1491    if (!icon_data.isEmpty()) {
     1492        XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON), XA_CARDINAL, 32,
     1493                        PropModeReplace, (unsigned char *) icon_data.data(),
     1494                        icon_data.size());
     1495    } else {
     1496        XDeleteProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON));
     1497    }
     1498
     1499    XWMHints *h = XGetWMHints(X11->display, q->internalWinId());
     1500    XWMHints wm_hints;
     1501    if (!h) {
     1502        memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
     1503        h = &wm_hints;
     1504    }
     1505
     1506    if (pixmap_handle) {
     1507        h->icon_pixmap = pixmap_handle;
     1508        h->flags |= IconPixmapHint;
     1509    } else {
     1510        h->icon_pixmap = 0;
     1511        h->flags &= ~(IconPixmapHint | IconMaskHint);
     1512    }
     1513
     1514    XSetWMHints(X11->display, q->internalWinId(), h);
    13871515    if (h != &wm_hints)
    13881516        XFree((char *)h);
     
    15101638void QWidget::activateWindow()
    15111639{
    1512     Q_D(QWidget);
    15131640    QWidget *tlw = window();
    15141641    if (tlw->isVisible() && !tlw->d_func()->topData()->embedded && !X11->deferred_map.contains(tlw)) {
     
    17511878            }
    17521879
    1753             mwmhints.flags |= MWM_HINTS_DECORATIONS;
    17541880            if (mwmhints.decorations == MWM_DECOR_ALL) {
     1881                mwmhints.flags |= MWM_HINTS_DECORATIONS;
    17551882                mwmhints.decorations = (MWM_DECOR_BORDER
    17561883                                        | MWM_DECOR_TITLE
     
    17611888
    17621889            if (q->windowFlags() & Qt::WindowMinimizeButtonHint) {
     1890                mwmhints.flags |= MWM_HINTS_DECORATIONS;
    17631891                mwmhints.decorations |= MWM_DECOR_MINIMIZE;
    17641892                mwmhints.functions |= MWM_FUNC_MINIMIZE;
    17651893            }
    17661894            if (q->windowFlags() & Qt::WindowMaximizeButtonHint) {
     1895                mwmhints.flags |= MWM_HINTS_DECORATIONS;
    17671896                mwmhints.decorations |= MWM_DECOR_MAXIMIZE;
    17681897                mwmhints.functions |= MWM_FUNC_MAXIMIZE;
     
    18161945        if (setUserTime)
    18171946            qt_net_update_user_time(q, userTime);
     1947
     1948#ifndef QT_NO_XSYNC
     1949        if (!topData()->syncUpdateCounter) {
     1950            XSyncValue value;
     1951            XSyncIntToValue(&value, 0);
     1952            topData()->syncUpdateCounter = XSyncCreateCounter(X11->display, value);
     1953
     1954            XChangeProperty(X11->display, q->internalWinId(),
     1955                            ATOM(_NET_WM_SYNC_REQUEST_COUNTER),
     1956                            XA_CARDINAL,
     1957                            32, PropModeReplace,
     1958                            (uchar *) &topData()->syncUpdateCounter, 1);
     1959
     1960            topData()->newCounterValueHi = 0;
     1961            topData()->newCounterValueLo = 0;
     1962        }
     1963#endif
    18181964
    18191965        if (!topData()->embedded
     
    21512297  parent's coord sys
    21522298 */
    2153 void QWidgetPrivate::setWSGeometry(bool dontShow)
     2299void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &)
    21542300{
    21552301    Q_Q(QWidget);
     
    24862632    if (just_update)
    24872633        q->update();
     2634    else if (!valid_rect)
     2635        dirty.translate(dx, dy);
    24882636
    24892637    int x1, y1, x2, y2, w = sr.width(), h = sr.height();
     
    26092757void QWidgetPrivate::createSysExtra()
    26102758{
     2759    extra->compress_events = true;
    26112760    extra->xDndProxy = 0;
    2612     extra->compress_events = true;
    26132761}
    26142762
     
    26192767void QWidgetPrivate::createTLSysExtra()
    26202768{
     2769    extra->topextra->spont_unmapped = 0;
     2770    extra->topextra->dnd = 0;
    26212771    extra->topextra->validWMState = 0;
    26222772    extra->topextra->waitingForMapNotify = 0;
     2773    extra->topextra->parentWinId = 0;
    26232774    extra->topextra->userTimeWindow = 0;
     2775#ifndef QT_NO_XSYNC
     2776    extra->topextra->syncUpdateCounter = 0;
     2777    extra->topextra->syncRequestTimestamp = 0;
     2778    extra->topextra->newCounterValueHi = 0;
     2779    extra->topextra->newCounterValueLo = 0;
     2780#endif
    26242781}
    26252782
     
    27462903}
    27472904
    2748 /*!
    2749     Returns information about the configuration of the X display used to display
    2750     the widget.
    2751 
    2752     \warning This function is only available on X11.
    2753 */
    27542905const QX11Info &QWidget::x11Info() const
    27552906{
     
    27882939}
    27892940
    2790 /*!
    2791     Returns the X11 Picture handle of the widget for XRender
    2792     support. Use of this function is not portable. This function will
    2793     return 0 if XRender support is not compiled into Qt, if the
    2794     XRender extension is not supported on the X11 display, or if the
    2795     handle could not be created.
    2796 */
    27972941Qt::HANDLE QWidget::x11PictureHandle() const
    27982942{
Note: See TracChangeset for help on using the changeset viewer.