Changeset 775


Ignore:
Timestamp:
Aug 4, 2010, 1:28:23 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

gui: Fixed a possible crash and an endless PM event loop recursion when re-parenting widgets in DIVE mode. This could be seen when dragging a toolbar out of the dock widget, dragging it back then closing the application (crash) or attempting to drag the toolbar out again (endless recursion).

Location:
trunk/src/gui
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/src/gui/kernel/qwidget_pm.cpp

    r749 r775  
    13891389            qApp->d_func()->closePopup(this);
    13901390        if (destroyWindow && !(windowType() == Qt::Desktop) &&
    1391             internalWinId() != NULLHANDLE) {
    1392             HWND id = internalWinId();
    1393             if (isWindow() && !(windowType() == Qt::Popup)) {
    1394                 // extra data including extra->topextra has been already
    1395                 // deleted at this point by deleteExtra() and therefore
    1396                 // calling frameWinId() is useless -- it will return the
    1397                 // client window handle. Use WinQueryWindow() instead.
    1398                 id = WinQueryWindow(id, QW_PARENT);
    1399                 Q_ASSERT(id != NULLHANDLE);
    1400             }
     1391            d->frameWinId() != NULLHANDLE) {
     1392            // make sure the backing store is deleted before destroying HWND --
     1393            // QPMDiveWindowSurface depends on that
     1394            delete d->topData()->backingStore;
     1395            d->topData()->backingStore = 0;
     1396            // now destroy HWND
     1397            HWND id = d->frameWinId();
    14011398#if defined(QT_DEBUGWINCREATEDESTROY)
    14021399            qDebug() << "|Destroying window" << this
     
    14721469    }
    14731470
    1474     if ((q->windowType() == Qt::Desktop))
    1475         old_fid = NULLHANDLE;
     1471    if (old_fid != NULLHANDLE && q->windowType() != Qt::Desktop) {
     1472        // make sure the backing store is deleted before destroying HWND --
     1473        // QPMDiveWindowSurface depends on that
     1474        if (extra && extra->topextra) {
     1475            delete extra->topextra->backingStore;
     1476            extra->topextra->backingStore = 0;
     1477            // zero the to-be-destroyed frame HWND just in case
     1478            extra->topextra->fId = NULLHANDLE;
     1479        }
     1480        // now destroy HWND
     1481        qt_WinDestroyWindow(old_fid);
     1482    }
     1483
    14761484    setWinId(0);
    14771485
     
    15061514        setWindowTitle_helper(extra->topextra->caption);
    15071515    }
    1508     if (old_fid != NULLHANDLE)
    1509         qt_WinDestroyWindow(old_fid);
    15101516
    15111517    if (q->testAttribute(Qt::WA_AcceptDrops) || dropSiteWasRegistered
  • TabularUnified trunk/src/gui/painting/qwindowsurface_pm.cpp

    r758 r775  
    368368        if (widget == that->window())
    369369            return &data;
    370         if (!subWidgets || !subWidgets->contains(widget->winId()))
     370        if (!subWidgets || !subWidgets->contains(widget->internalWinId()))
    371371            return 0;
    372         return &(*subWidgets)[widget->winId()];
     372        return &(*subWidgets)[widget->internalWinId()];
    373373    }
    374374
     
    379379void QPMDiveWindowSurfacePrivate::addWidget(QWidget *widget)
    380380{
     381    Q_ASSERT(widget->internalWinId());
     382
    381383    WidgetData *wd = &data;
    382384    if (widget != that->window()) {
     
    384386        if (!subWidgets)
    385387            subWidgets = new QMap<HWND, WidgetData>();
    386         wd = &(*subWidgets)[widget->winId()];
     388        wd = &(*subWidgets)[widget->internalWinId()];
    387389    }
    388390
     
    398400        // to handle other PM messages
    399401        widget->addPmEventFilter(this);
    400         WinSetVisibleRegionNotify(widget->winId(), TRUE);
     402        WinSetVisibleRegionNotify(widget->internalWinId(), TRUE);
    401403    } else {
    402404        // receive various PM messages
    403405        widget->addPmEventFilter(this);
    404         // receive reparent/destruction messages from children
    405         // to cleanup the map
     406        // receive reparent messages from children to cleanup the map
    406407        widget->installEventFilter(this);
    407408    }
     
    411412{
    412413    if (widget == that->window()) {
    413         WinSetVisibleRegionNotify(widget->winId(), FALSE);
     414        WinSetVisibleRegionNotify(widget->internalWinId(), FALSE);
    414415        widget->removePmEventFilter(this);
    415416    } else {
    416417        widget->removeEventFilter(this);
    417418        widget->removePmEventFilter(this);
    418     }
    419 
    420     if (widget != that->window())
    421         subWidgets->remove(widget->winId());
     419        subWidgets->remove(widget->internalWinId());
     420    }
    422421}
    423422
     
    425424{
    426425    QWidget *widget = qobject_cast<QWidget *>(obj);
    427     if (event->type() == QEvent::ParentAboutToChange ||
    428         event->type() == QEvent::Destroy) {
     426    if (event->type() == QEvent::ParentAboutToChange) {
    429427        removeWidget(widget);
    430428    }
     
    482480        }
    483481        case WM_SIZE: {
    484             if (msg->hwnd != that->window()->winId()) {
     482            if (msg->hwnd != that->window()->internalWinId()) {
    485483                // sometimes PM doesn't send WM_VRNENABLED to the main widget
    486484                // when the sub-widget (its descendant) gets resized within it;
     
    611609        // produce a clip region that excludes all descending obstacles
    612610        // (like child widgets with real HWNDs which are not excluded by Qt)
    613         HWND wwnd = widget->winId();
     611        HWND wwnd = widget->internalWinId();
    614612        RECTL wrcl = { wbr.left(), wh - wbr.bottom() - 1,
    615613                       wbr.right() + 1, wh - wbr.top() };
     
    659657bool QPMDiveWindowSurface::adjustSetup(QWidget *widget)
    660658{
    661     HWND hwnd = window()->winId();
     659    HWND hwnd = window()->internalWinId();
    662660
    663661    // don't include lScreenPosX and the rest by default
     
    693691        ULONG rc = WinQueryVisibleRegion(hwnd, hrgn);
    694692        if (rc != RGN_ERROR) {
    695             HWND hwndWidget = widget->winId();
     693            HWND hwndWidget = widget->internalWinId();
    696694            POINTL ptlOffset = { 0, 0 };
    697695            if (hwnd != hwndWidget) {
Note: See TracChangeset for help on using the changeset viewer.