Changeset 120 for trunk/src


Ignore:
Timestamp:
Aug 18, 2009, 4:30:00 PM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

gui: QWidget::setWindowState/setGeometry_sys/setWSGeometry in progress.

Location:
trunk/src/gui
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/gui/kernel/qapplication_pm.cpp

    r117 r120  
    4444#include "qt_os2.h"
    4545
     46#include "qdebug.h"
     47
    4648#include "qapplication.h"
    4749#include "qapplication_p.h"
     
    6163#include "qkeymapper_p.h"
    6264#include "qcursor_p.h"
     65
     66#define QT_DEBUGMSGFLOW
    6367
    6468QT_BEGIN_NAMESPACE
     
    120124//  void syncBackingStore(const QRegion &rgn) { d_func()->syncBackingStore(rgn); }
    121125//  void syncBackingStore() { d_func()->syncBackingStore(); }
    122 //  QWidgetData *dataPtr() { return data; }
    123 //  QWidgetPrivate *dptr() { return d_func(); }
     126    QWidgetData *dataPtr() { return data; }
     127    QWidgetPrivate *dptr() { return d_func(); }
    124128//  QRect frameStrut() const { return d_func()->frameStrut(); }
    125129    bool        pmEvent(QMSG *m, MRESULT *r) { return QWidget::pmEvent(m, r); }
     
    494498        // flip y coordinate
    495499        qmsg.ptl.y = QApplication::desktop()->height() - (qmsg.ptl.y + 1);
     500
     501#if defined(QT_DEBUGMSGFLOW)
     502        {
     503            QString str = qStrQMSG(qmsg);
     504            if (!str.isEmpty())
     505                qDebug() << "*** [W]" << str.toUtf8().constData();
     506        }
     507#endif
    496508
    497509        // send through app filter
     
    709721#endif
    710722
     723        MRESULT rc = (MRESULT) FALSE;
     724
    711725        HWND hwndC = WinWindowFromID(hwnd, FID_CLIENT);
    712726        QETWidget *widget = (QETWidget*)QWidget::find(hwndC);
     
    714728            break;
    715729
     730        Q_ASSERT(widget->isWindow());
     731
     732#if defined(QT_DEBUGMSGFLOW)
     733        {
     734            QMSG qmsg; // create QMSG structure
     735            qmsg.hwnd = hwnd;
     736            qmsg.msg = msg;
     737            qmsg.mp1 = mp1;
     738            qmsg.mp2 = mp2;
     739            QString str = qStrQMSG(qmsg);
     740            if (!str.isEmpty())
     741                qDebug() << "*** [F]" << str.toUtf8().constData();
     742        }
     743#endif
     744
    716745        switch(msg) {
     746
     747        case WM_WINDOWPOSCHANGED: {
     748            // We detect spontaneous min/max/restore events here instead of
     749            // WM_MINMAXFRAME, because WM_MINMAXFRAME is a pre-process message
     750            // (i.e. no actual changes have been made). We need actual changes
     751            // in order to update the frame strut and send WindowStateChange.
     752            rc = QtOldFrameProc(hwnd, msg, mp1, mp2);
     753
     754            ULONG awp = LONGFROMMP(mp2);
     755
     756            bool window_state_change = false;
     757            Qt::WindowStates oldstate = Qt::WindowStates(widget->dataPtr()->window_state);
     758
     759            if (awp & AWP_MINIMIZED) {
     760                window_state_change = true;
     761                widget->dataPtr()->window_state |= Qt::WindowMinimized;
     762                if (widget->isVisible()) {
     763                    QHideEvent e;
     764                    qt_sendSpontaneousEvent(widget, &e);
     765                    widget->dptr()->hideChildren(true);
     766                    const QString title = widget->windowIconText();
     767                    if (!title.isEmpty())
     768                        widget->dptr()->setWindowTitle_helper(title);
     769                }
     770            } else {
     771                if (awp & AWP_MAXIMIZED) {
     772                    widget->topData()->normalGeometry = widget->geometry();
     773                }
     774                if (awp & AWP_RESTORED) {
     775                    window_state_change = true;
     776                    if (awp & AWP_MAXIMIZED)
     777                        widget->dataPtr()->window_state |= Qt::WindowMaximized;
     778                    else if (!widget->isMinimized())
     779                        widget->dataPtr()->window_state &= ~Qt::WindowMaximized;
     780
     781                    if (widget->isMinimized()) {
     782                        widget->dataPtr()->window_state &= ~Qt::WindowMinimized;
     783                        widget->dptr()->showChildren(true);
     784                        QShowEvent e;
     785                        qt_sendSpontaneousEvent(widget, &e);
     786                        const QString title = widget->windowTitle();
     787                        if (!title.isEmpty())
     788                            widget->dptr()->setWindowTitle_helper(title);
     789                    }
     790                }
     791            }
     792
     793            if (window_state_change) {
     794                widget->dptr()->updateFrameStrut();
     795                if (!widget->topData()->inSetWindowState) {
     796                    // send WindowStateChange event if this message is NOT
     797                    // originated from QWidget::setWindowState().
     798                    QWindowStateChangeEvent e(oldstate);
     799                    qt_sendSpontaneousEvent(widget, &e);
     800                }
     801            }
     802
     803            return rc;
     804        }
     805
    717806        default:
    718807            break;
     
    14761565    d_func()->hd = WinBeginPaint(internalWinId(), 0, &rcl);
    14771566
    1478 #if 1
    1479     qDebug("WM_PAINT: [%s] BEGIN %ld,%ld-%ld,%ld hps=%08lX",
    1480            QWidgetPrivate::name(this).constData(),
    1481            rcl.xLeft, rcl.yBottom, rcl.xRight, rcl.yTop, d_func()->hd);
     1567#if defined(QT_DEBUGMSGFLOW)
     1568    qDebug() << " PAINT BEGIN:" << rcl << "hps:" << qStrHPS(d_func()->hd);
    14821569#endif
    14831570
     
    15011588    // Mapping region from system to qt (32 bit) coordinate system.
    15021589    updRect.translate(data->wrect.topLeft());
    1503 #if 1
    1504     qDebug("WM_PAINT: [%s] update=%d,%d/%d,%d",
    1505            QWidgetPrivate::name(this).constData(),
    1506            updRect.x(), updRect.y(), updRect.width(), updRect.height());
    1507 #endif
     1590#if defined(QT_DEBUGMSGFLOW)
     1591    qDebug() << " PAINT updRect:" << updRect;
     1592#endif
     1593
    15081594    // @todo use hrgn here converted to QRegion?
    15091595    d_func()->syncBackingStore(updRect);
     
    15121598    d_func()->hd = NULLHANDLE;
    15131599
    1514 #if 1
    1515     qDebug("WM_PAINT: [%s] END", QWidgetPrivate::name(this).constData());
     1600#if defined(QT_DEBUGMSGFLOW)
     1601    qDebug() << " PAINT END";
    15161602#endif
    15171603
     
    16591745}
    16601746
     1747
     1748/*!
     1749    Returns a QWidget pointer or 0 if there is no widget corresponding to the
     1750    given HWND. As opposed to QWidget::find(), correctly handles WC_FRAME
     1751    windows created for top level widgets. Used for debugging.
     1752 */
     1753QWidget *qWidgetFromHWND(HWND hwnd)
     1754{
     1755    char buf[10];
     1756    if (WinQueryClassName(hwnd, sizeof(buf), buf)) {
     1757        if (!strcmp(buf, "#1")) // WC_FRAME
     1758            hwnd = WinWindowFromID(hwnd, FID_CLIENT);
     1759        return QWidget::find(hwnd);
     1760    }
     1761    return 0;
     1762}
     1763
     1764/*!
     1765    \internal
     1766
     1767    Returns a human readable widget name in the form "class/name". Used for
     1768    debugging.
     1769 */
     1770QDbgStr qWidgetName(QWidget *w)
     1771{
     1772    if (w)
     1773        return QString()
     1774            .sprintf("%s.%s", w->metaObject()->className(),
     1775                     w->objectName().isEmpty() ? "<noname>" :
     1776                     w->objectName().toUtf8().constData());
     1777    return QString(QLatin1String("<no-widget>"));
     1778}
     1779
     1780QDbgStr qStrHWND(HWND hwnd)
     1781{
     1782    return QString().sprintf("%08lX/", hwnd) +
     1783           qWidgetName(qWidgetFromHWND(hwnd));
     1784}
     1785
     1786QDbgStr qStrHPS(HPS hps)
     1787{
     1788    return QString().sprintf("%08lX", hps);
     1789}
     1790
     1791QDbgStr qStrHPOINTER(HPOINTER hptr)
     1792{
     1793    return QString().sprintf("%08lX", hptr);
     1794}
     1795
     1796QDbgStr qStrHRGN(HRGN hrgn)
     1797{
     1798    return QString().sprintf("%08lX", hrgn);
     1799}
     1800
     1801QDbgStr qStrQMSG(const QMSG &qmsg)
     1802{
     1803    QString str;
     1804
     1805    #define myCaseBegin(a) case a: { \
     1806        str = QString().sprintf(#a ": hwnd %08lX.", qmsg.hwnd); \
     1807        str += qWidgetName(qWidgetFromHWND(qmsg.hwnd));
     1808    #define myCaseEnd() }
     1809
     1810    switch (qmsg.msg) {
     1811
     1812    myCaseBegin(WM_PAINT)
     1813        break;
     1814    myCaseEnd()
     1815
     1816    myCaseBegin(WM_SIZE)
     1817        str += QString().
     1818            sprintf(" old (%hd,%ld) new (%hd,%hd)",
     1819                    SHORT1FROMMP(qmsg.mp1), SHORT2FROMMP(qmsg.mp1),
     1820                    SHORT1FROMMP(qmsg.mp2), SHORT2FROMMP(qmsg.mp2));
     1821        break;
     1822    myCaseEnd()
     1823
     1824    myCaseBegin(WM_MOVE)
     1825        break;
     1826    myCaseEnd()
     1827
     1828    default:
     1829        break;
     1830    }
     1831
     1832    return str;
     1833
     1834    #undef myCaseEnd
     1835    #undef myCaseBegin
     1836}
     1837
     1838QDbgStr qStrRECTL(const RECTL &rcl)
     1839{
     1840    return QString().sprintf("RECTL(%ld,%ld %ld,%ld)",
     1841                             rcl.xLeft, rcl.yBottom, rcl.xRight, rcl.yTop);
     1842}
     1843
    16611844QT_END_NAMESPACE
  • trunk/src/gui/kernel/qwidget_p.h

    r114 r120  
    157157    HWND fId;
    158158    HSWITCH swEntry;
     159    uint inSetWindowState : 1;
    159160#endif
    160161    QRect normalGeometry; // used by showMin/maximized/FullScreen
     
    636637#ifdef Q_WS_PM
    637638    void validateObstacles();
    638 
    639     static QWidget *fromHWND(HWND hwnd);
    640     static QByteArray name(QWidget *w);
    641     inline static QByteArray name(HWND hwnd) { return name(fromHWND(hwnd)); }
    642639#endif
    643640
  • trunk/src/gui/kernel/qwidget_pm.cpp

    r114 r120  
    4444#include "qt_os2.h"
    4545
     46#include "qdebug.h"
     47
    4648#include "qwidget.h"
    4749#include "qwidget_p.h"
     
    4951#include "qapplication.h"
    5052#include "qdesktopwidget.h"
     53#include "qevent.h"
    5154
    5255#include "private/qapplication_p.h"
    5356#include "private/qbackingstore_p.h"
    5457
    55 #include <qdebug.h>
    56 
    57 #define QT_DEBUGWINCREATEDESTROY
    58 #define QT_DEBUGWIDGETMASK
     58//#define QT_DEBUGWINCREATEDESTROY
     59//#define QT_DEBUGWIDGETMASK
    5960
    6061QT_BEGIN_NAMESPACE
     
    143144{
    144145#if defined(QT_DEBUGWIDGETMASK)
    145     qDebug("qt_WinInvalidateRegionEx: hwnd=%08lX [%s] "
    146            "hwndFrom=%08lX hwndTo=%08lX", hwnd,
    147            QWidgetPrivate::name(hwnd).constData(),
    148            hwndFrom, hwndTo);
     146    qDebug("qt_WinInvalidateRegionEx: hwnd=%s hwndFrom=%08lX hwndTo=%08lX",
     147           qStrHWND(hwnd).toUtf8().constData(), hwndFrom, hwndTo);
    149148#endif
    150149
     
    174173        WinQueryWindowPos(child, &swp);
    175174#if defined(QT_DEBUGWIDGETMASK)
    176         qDebug(" child=%08lX [fl=%08lX] [%s]", child, swp.fl,
    177                QWidgetPrivate::name(child).constData());
     175        qDebug(" child=%s [fl=%08lX]", qStrHWND(child).toUtf8().constData(),
     176               swp.fl);
    178177#endif
    179178        // proceed only if not hidden
     
    259258
    260259#if defined(QT_DEBUGWIDGETMASK)
    261     qDebug("qt_WinProcessWindowObstacles: hwnd=%08lX [%s], prcl=%p "
    262            "hrgn=%08lX, op=%ld flags=%08lX", hwnd,
    263            QWidgetPrivate::name(hwnd).constData(),
    264            prcl, hrgn, op, flags);
     260    qDebug("qt_WinProcessWindowObstacles: hwnd=%s, prcl=%p "
     261           "hrgn=%08lX, op=%ld flags=%08lX",
     262           qStrHWND(hwnd).toUtf8().constData(), prcl, hrgn, op, flags);
    265263#endif
    266264
     
    313311                WinQueryWindowPos(relative, &swp);
    314312#if defined(QT_DEBUGWIDGETMASK)
    315                 qDebug(" child=%08lX [fl=%08lX] [%s]", relative, swp.fl,
    316                        QWidgetPrivate::name(relative).constData());
     313                qDebug(" child=%s [fl=%08lX]",
     314                       qStrHWND(relative).toUtf8().constData(), swp.fl);
    317315#endif
    318316                // skip if hidden
     
    353351            WinQueryWindowPos(relative, &swp);
    354352#if defined(QT_DEBUGWIDGETMASK)
    355             qDebug(" sibling=%08lX [fl=%08lX] [%s]", relative, swp.fl,
    356                    QWidgetPrivate::name(relative).constData());
     353            qDebug(" sibling=%s [fl=%08lX]",
     354                   qStrHWND(relative).toUtf8().constData(), swp.fl);
    357355#endif
    358356            // skip if hidden
     
    403401            WinQueryWindowPos(parent, &swp);
    404402#if defined(QT_DEBUGWIDGETMASK)
    405             qDebug(" parent=%08lX [fl=%08lX] [%s]", parent, swp.fl,
    406                    QWidgetPrivate::name(parent).constData());
     403            qDebug(" parent=%s [fl=%08lX]",
     404                   qStrHWND(parent).toUtf8().constData(), swp.fl);
    407405#endif
    408406            delta.x += swp.x;
     
    412410                WinQueryWindowPos(relative, &swp);
    413411#if defined(QT_DEBUGWIDGETMASK)
    414                 qDebug(" ancestor=%08lX [fl=%08lX] [%s]", relative, swp.fl,
    415                        QWidgetPrivate::name(parent).constData());
     412                qDebug(" ancestor=%s [fl=%08lX]",
     413                       qStrHWND(relative).toUtf8().constData(), swp.fl);
    416414#endif
    417415                // skip if hidden
     
    452450
    453451    Partial reimplementation of the WinSetWindowPos() API that obeys window clip
    454     regions. Currently supported flags are SWP_ZORDER, SWP_SHOW, SWP_HIDE and
    455     SWP_ACTIVATE. Other flags should not be used. Note that if any other flag is
    456     specified (alone or in addition to the supported ones), or if the given
    457     window is a top-level window, this function acts exactly like the original
     452    regions. Currently supported flags are SWP_ZORDER, SWP_SHOW, SWP_HIDE,
     453    SWP_ACTIVATE, SWP_MOVE, SWP_SIZE and SWP_NOREDRAW; other flags should no be
     454    used.
     455
     456    Note that if the above restrictions are not met or if the given window is a
     457    top-level window, this function acts exactly like the original
    458458    WinSetWindowPos() function.
    459459 */
     
    463463{
    464464#if defined(QT_DEBUGWIDGETMASK)
    465     qDebug("qt_WinSetWindowPos: hwnd=%08lX [%s] fl=%08lX", hwnd,
    466            QWidgetPrivate::name(hwnd).constData(), fl);
     465    qDebug("qt_WinSetWindowPos: hwnd=%s fl=%08lX",
     466           qStrHWND(hwnd).toUtf8().constData(), fl);
    467467#endif
    468468
    469469    HWND desktop = WinQueryDesktopWindow(0, 0);
    470470
    471     Q_ASSERT(((fl & ~(SWP_ZORDER | SWP_SHOW | SWP_HIDE)) == 0) ||
     471    Q_ASSERT(((fl & ~(SWP_ZORDER | SWP_SHOW | SWP_HIDE | SWP_ACTIVATE |
     472                      SWP_MOVE | SWP_SIZE | SWP_NOREDRAW)) == 0) ||
    472473             hwnd == desktop || WinQueryWindow(hwnd, QW_PARENT) == desktop);
    473474
    474     if ((fl & ~(SWP_ZORDER | SWP_SHOW | SWP_HIDE)) != 0 ||
     475    if ((fl & ~(SWP_ZORDER | SWP_SHOW | SWP_HIDE | SWP_ACTIVATE |
     476                SWP_MOVE | SWP_SIZE | SWP_NOREDRAW)) != 0 ||
    475477         hwnd == desktop || WinQueryWindow(hwnd, QW_PARENT) == desktop) {
    476478        return WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl);
     
    490492        fl &= ~SWP_HIDE;
    491493
     494    // do the job but not invalidate or redraw
    492495    BOOL rc = WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy,
    493496                              fl | SWP_NOREDRAW);
     
    501504        fl &= ~SWP_ZORDER;
    502505
    503     if ((fl & (SWP_ZORDER | SWP_SHOW | SWP_HIDE)) == 0)
     506    if ((fl & (SWP_ZORDER | SWP_SHOW | SWP_HIDE | SWP_MOVE | SWP_SIZE)) == 0)
    504507        return rc;
    505508
     
    520523        qt_WinInvalidateRegionEx(hwndParent, hrgnSelf,
    521524                                  WinQueryWindow(hwnd, QW_NEXT), HWND_BOTTOM);
    522     } else { // fl & SWP_ZORDER
    523         // below we assume that WinSetWindowPos() returns FALSE if
    524         // an incorrect (unrelated) hwndInsertBehind is passed when SWP_ZORDER
    525         // is set
    526 
    527         // first, detect whether we are moving up or down
    528         BOOL up;
    529         HWND hwndFrom, hwndTo;
    530         if (swpOld.hwndInsertBehind == HWND_TOP) {
    531             up = FALSE;
    532             hwndFrom = WinQueryWindow(hwndParent, QW_TOP);
    533             hwndTo = swpNew.hwndInsertBehind;
    534         } else {
    535             up = TRUE;
    536             for (HWND hwndAbove = hwnd;
    537                   (hwndAbove = WinQueryWindow(hwndAbove, QW_PREV)) != 0;) {
    538                 if (hwndAbove == swpOld.hwndInsertBehind) {
    539                     up = FALSE;
    540                     break;
     525    } else {
     526        // SWP_ZORDER or SWP_MOVE or SWP_SIZE
     527
     528        if (fl & SWP_ZORDER) {
     529            // below we assume that WinSetWindowPos() returns FALSE if
     530            // an incorrect (unrelated) hwndInsertBehind is passed when SWP_ZORDER
     531            // is set
     532
     533            // first, detect whether we are moving up or down
     534            BOOL up;
     535            HWND hwndFrom, hwndTo;
     536            if (swpOld.hwndInsertBehind == HWND_TOP) {
     537                up = FALSE;
     538                hwndFrom = WinQueryWindow(hwndParent, QW_TOP);
     539                hwndTo = swpNew.hwndInsertBehind;
     540            } else {
     541                up = TRUE;
     542                for (HWND hwndAbove = hwnd;
     543                      (hwndAbove = WinQueryWindow(hwndAbove, QW_PREV)) != 0;) {
     544                    if (hwndAbove == swpOld.hwndInsertBehind) {
     545                        up = FALSE;
     546                        break;
     547                    }
    541548                }
    542             }
     549                if (up) {
     550                    hwndFrom = swpOld.hwndInsertBehind;
     551                    hwndTo = WinQueryWindow(hwnd, QW_NEXT);
     552                } else {
     553                    hwndFrom = WinQueryWindow(swpOld.hwndInsertBehind, QW_NEXT);
     554                    hwndTo = swpNew.hwndInsertBehind;
     555                }
     556            }
     557#if defined(QT_DEBUGWIDGETMASK)
     558            qDebug(" moving up? %ld", up);
     559            qDebug(" hwndFrom=%s", qStrHWND(hwndFrom).toUtf8().constData());
     560            qDebug(" hwndTo=%s", qStrHWND(hwndTo).toUtf8().constData());
     561#endif
     562
     563            SWP swp;
     564            HWND sibling = hwndFrom;
     565            HRGN hrgn = GpiCreateRegion(hps, 0, NULL);
     566            HRGN hrgnUpd = GpiCreateRegion(hps, 0, NULL);
     567
    543568            if (up) {
    544                 hwndFrom = swpOld.hwndInsertBehind;
    545                 hwndTo = WinQueryWindow(hwnd, QW_NEXT);
     569                // go upwards in z-order
     570                while (1) {
     571                    WinQueryWindowPos(sibling, &swp);
     572#if defined(QT_DEBUGWIDGETMASK)
     573                    qDebug(" sibling=%s [fl=%08lX]",
     574                           qStrHWND(sibling).toUtf8().constData(), swp.fl);
     575#endif
     576                    // proceed only if not hidden
     577                    if (swp.fl & SWP_SHOW) {
     578                        // get sibling's bounds (clip region or rect)
     579                        qt_WinQueryClipRegionOrRect(sibling, hrgn);
     580                        // translate the region to this window's coordinate system
     581                        POINTL ptl = { swp.x - swpNew.x, swp.y - swpNew.y };
     582                        GpiOffsetRegion(hps, hrgn, &ptl);
     583                        // add to the region of siblings we're moving on top of
     584                        GpiCombineRegion(hps, hrgnUpd, hrgnUpd, hrgn, CRGN_OR);
     585#if defined(QT_DEBUGWIDGETMASK)
     586                        qDebug("  processed");
     587#endif
     588                    }
     589                    // iterate to the prev window (above)
     590                    if (sibling == hwndTo)
     591                        break;
     592                    sibling = swp.hwndInsertBehind;
     593                }
     594                // intersect the resulting region with the widget region and
     595                // invalidate
     596                GpiCombineRegion(hps, hrgnUpd, hrgnSelf, hrgnUpd, CRGN_AND);
     597                WinInvalidateRegion(hwnd, hrgnUpd, TRUE);
    546598            } else {
    547                 hwndFrom = WinQueryWindow(swpOld.hwndInsertBehind, QW_NEXT);
    548                 hwndTo = swpNew.hwndInsertBehind;
    549             }
    550         }
     599                // go downwards in reverse z-order
     600                POINTL ptl = { 0, 0 };
     601                while (1) {
     602                    WinQueryWindowPos(sibling, &swp);
    551603#if defined(QT_DEBUGWIDGETMASK)
    552         qDebug(" moving up? %ld", up);
    553         qDebug(" hwndFrom=%08lX [%s]", hwndFrom,
    554                QWidgetPrivate::name(hwndFrom).constData());
    555         qDebug(" hwndTo=%08lX [%s]", hwndTo,
    556                QWidgetPrivate::name(hwndTo).constData());
    557 #endif
    558 
    559         SWP swp;
    560         HWND sibling = hwndFrom;
    561         HRGN hrgn = GpiCreateRegion(hps, 0, NULL);
    562         HRGN hrgnUpd = GpiCreateRegion(hps, 0, NULL);
    563 
    564         if (up) {
    565             // go upwards in z-order
    566             while (1) {
    567                 WinQueryWindowPos(sibling, &swp);
     604                    qDebug(" sibling=%s [fl=%08lX]",
     605                           qStrHWND(sibling).toUtf8().constData(), swp.fl);
     606#endif
     607                    // proceed only if not hidden
     608                    if (swp.fl & SWP_SHOW) {
     609                        // get sibling's bounds (clip region or rect)
     610                        qt_WinQueryClipRegionOrRect(sibling, hrgn);
     611                        // undo the previous translation and translate this window's
     612                        // region to the siblings's coordinate system
     613                        ptl.x += swpNew.x - swp.x;
     614                        ptl.y += swpNew.y - swp.y;
     615                        GpiOffsetRegion(hps, hrgnSelf, &ptl);
     616                        // intersect the sibling's region with the translated one
     617                        // and invalidate the sibling
     618                        GpiCombineRegion(hps, hrgnUpd, hrgnSelf, hrgn, CRGN_AND);
     619                        WinInvalidateRegion(sibling, hrgnUpd, TRUE);
     620                        // substract the invalidated area from the widget's region
     621                        // (no need to invalidate it any more)
     622                        GpiCombineRegion(hps, hrgnSelf, hrgnSelf, hrgnUpd, CRGN_DIFF);
     623                        // prepare the translation from the sibling's
     624                        // coordinates back to this window's coordinates
     625                        ptl.x = swp.x - swpNew.x;
     626                        ptl.y = swp.y - swpNew.y;
    568627#if defined(QT_DEBUGWIDGETMASK)
    569                 qDebug(" sibling=%08lX [fl=%08lX] [%s]", sibling, swp.fl,
    570                        QWidgetPrivate::name(sibling).constData());
    571 #endif
    572                 // proceed only if not hidden
    573                 if (swp.fl & SWP_SHOW) {
    574                     // get sibling's bounds (clip region or rect)
    575                     qt_WinQueryClipRegionOrRect(sibling, hrgn);
    576                     // translate the region to this window's coordinate system
    577                     POINTL ptl = { swp.x - swpNew.x, swp.y - swpNew.y };
    578                     GpiOffsetRegion(hps, hrgn, &ptl);
    579                     // add to the region of siblings we're moving on top of
    580                     GpiCombineRegion(hps, hrgnUpd, hrgnUpd, hrgn, CRGN_OR);
    581 #if defined(QT_DEBUGWIDGETMASK)
    582                     qDebug("  processed");
    583 #endif
     628                        qDebug("  processed");
     629#endif
     630                    }
     631                    // iterate to the next window (below)
     632                    if (sibling == hwndTo)
     633                        break;
     634                    sibling = WinQueryWindow(sibling, QW_NEXT);
    584635                }
    585                 // iterate to the prev window (above)
    586                 if (sibling == hwndTo)
    587                     break;
    588                 sibling = swp.hwndInsertBehind;
    589             }
    590             // intersect the resulting region with the widget region and
    591             // invalidate
    592             GpiCombineRegion(hps, hrgnUpd, hrgnSelf, hrgnUpd, CRGN_AND);
    593             WinInvalidateRegion(hwnd, hrgnUpd, TRUE);
    594         } else {
    595             // go downwards in reverse z-order
    596             POINTL ptl = { 0, 0 };
    597             while (1) {
    598                 WinQueryWindowPos(sibling, &swp);
    599 #if defined(QT_DEBUGWIDGETMASK)
    600                 qDebug(" sibling=%08lX [fl=%08lX] [%s]", sibling, swp.fl,
    601                        QWidgetPrivate::name(sibling).constData());
    602 #endif
    603                 // proceed only if not hidden
    604                 if (swp.fl & SWP_SHOW) {
    605                     // get sibling's bounds (clip region or rect)
    606                     qt_WinQueryClipRegionOrRect(sibling, hrgn);
    607                     // undo the previous translation and translate this window's
    608                     // region to the siblings's coordinate system
    609                     ptl.x += swpNew.x - swp.x;
    610                     ptl.y += swpNew.y - swp.y;
    611                     GpiOffsetRegion(hps, hrgnSelf, &ptl);
    612                     // intersect the sibling's region with the translated one
    613                     // and invalidate the sibling
    614                     GpiCombineRegion(hps, hrgnUpd, hrgnSelf, hrgn, CRGN_AND);
    615                     WinInvalidateRegion(sibling, hrgnUpd, TRUE);
    616                     // substract the invalidated area from the widget's region
    617                     // (no need to invalidate it any more)
    618                     GpiCombineRegion(hps, hrgnSelf, hrgnSelf, hrgnUpd, CRGN_DIFF);
    619                     // prepare the translation from the sibling's
    620                     // coordinates back to this window's coordinates
    621                     ptl.x = swp.x - swpNew.x;
    622                     ptl.y = swp.y - swpNew.y;
    623 #if defined(QT_DEBUGWIDGETMASK)
    624                     qDebug("  processed");
    625 #endif
     636            }
     637
     638            GpiDestroyRegion(hps, hrgnUpd);
     639            GpiDestroyRegion(hps, hrgn);
     640        }
     641
     642        if (fl & (SWP_MOVE | SWP_SIZE)) {
     643            // Since we don't use WS_CLIPCHILDREN and WS_CLIPSIBLINGS,
     644            // WinSetWindowPos() does not correctly update involved windows.
     645            // The fix is to do it ourselves, taking clip regions into account.
     646            // set new and old rectangles
     647            const RECTL rcls [2] = {
     648                // new (relative to parent)
     649                { swpNew.x, swpNew.y, swpNew.x + swpNew.cx, swpNew.y + swpNew.cy },
     650                // old (relative to parent)
     651                { swpOld.x, swpOld.y, swpOld.x + swpOld.cx, swpOld.y + swpOld.cy }
     652            };
     653            const RECTL &rclNew = rcls [0];
     654            const RECTL &rclOld = rcls [1];
     655            // delta to shift coordinate space from parent to this widget
     656            POINTL ptlToSelf = { -swpNew.x, -swpNew.y };
     657            // use parent PS for blitting
     658            HPS hps = WinGetPS(hwndParent);
     659            // get old and new clip regions (relative to parent)
     660            HRGN hrgnOld = GpiCreateRegion(hps, 1, &rclOld);
     661            HRGN hrgnNew = GpiCreateRegion(hps, 1, &rclNew);
     662            if (WinQueryClipRegion(hwnd, 0) != QCRGN_NO_CLIP_REGION) {
     663                HRGN hrgnTemp = GpiCreateRegion(hps, 0, NULL);
     664                // old (clipped to the old rect)
     665                WinQueryClipRegion(hwnd, hrgnTemp);
     666                GpiOffsetRegion(hps, hrgnTemp, (PPOINTL) &rclOld);
     667                GpiCombineRegion(hps, hrgnOld, hrgnTemp, hrgnOld, CRGN_AND);
     668                // new (clipped to the new rect)
     669                WinQueryClipRegion(hwnd, hrgnTemp);
     670                if (swpOld.cy != swpNew.cy) {
     671                    // keep the clip region top-left aligned by adding the
     672                    // height delta (new size - old size)
     673                    POINTL ptl = {0, swpNew.cy - swpOld.cy };
     674                    GpiOffsetRegion(hps, hrgnTemp, &ptl);
     675                    WinSetClipRegion(hwnd, hrgnTemp);
    626676                }
    627                 // iterate to the next window (below)
    628                 if (sibling == hwndTo)
    629                     break;
    630                 sibling = WinQueryWindow(sibling, QW_NEXT);
    631             }
    632         }
    633 
    634         GpiDestroyRegion(hps, hrgnUpd);
    635         GpiDestroyRegion(hps, hrgn);
     677                GpiOffsetRegion(hps, hrgnTemp, (PPOINTL) &rclNew);
     678                GpiCombineRegion(hps, hrgnNew, hrgnTemp, hrgnNew, CRGN_AND);
     679                GpiDestroyRegion(hps, hrgnTemp);
     680            }
     681            // the rest is useful only when the widget is visible
     682            if (swpNew.fl & SWP_SHOW) {
     683                // create affected region (old + new, relative to widget)
     684                HRGN hrgnAff = GpiCreateRegion(hps, 0, NULL);
     685                GpiCombineRegion(hps, hrgnAff, hrgnOld, hrgnNew, CRGN_OR);
     686                GpiOffsetRegion(hps, hrgnAff, &ptlToSelf);
     687                // get bounding rectangle of affected region
     688                RECTL rclAff;
     689                GpiQueryRegionBox(hps, hrgnAff, &rclAff);
     690                // get region of obstacles limited to affected rectangle
     691                HRGN hrgnObst = GpiCreateRegion(hps, 0, NULL);
     692                qt_WinProcessWindowObstacles(hwnd, &rclAff, hrgnObst, CRGN_OR,
     693                                             PWO_Sibings | PWO_Ancestors |
     694                                             PWO_Screen | PWO_TopLevel);
     695                // shift region of obstacles and affected region back to
     696                // parent coords
     697                GpiOffsetRegion(hps, hrgnObst, (PPOINTL) &rclNew);
     698                GpiOffsetRegion(hps, hrgnAff, (PPOINTL) &rclNew);
     699                // get parent bounds (clip region or rect)
     700                HRGN hrgnUpd = GpiCreateRegion(hps, 0, NULL);
     701                qt_WinQueryClipRegionOrRect(hwndParent, hrgnUpd);
     702                // add parts of old region beyond parent bounds to
     703                // region of obstacles
     704                GpiCombineRegion(hps, hrgnOld, hrgnOld, hrgnUpd, CRGN_DIFF);
     705                GpiCombineRegion(hps, hrgnObst, hrgnObst, hrgnOld, CRGN_OR);
     706                // substract region of obstacles from affected region
     707                GpiCombineRegion(hps, hrgnAff, hrgnAff, hrgnObst, CRGN_DIFF);
     708                // remember it as parent update region (need later)
     709                GpiCombineRegion(hps, hrgnUpd, hrgnAff, 0, CRGN_COPY);
     710                // copy region of obstacles to delta region and shift it by
     711                // delta (note: movement is considered to be top-left aligned)
     712                HRGN hrgnDelta = GpiCreateRegion(hps, 0, NULL);
     713                GpiCombineRegion(hps, hrgnDelta, hrgnObst, 0, CRGN_COPY);
     714                POINTL ptlDelta = { rclNew.xLeft - rclOld.xLeft,
     715                                    rclNew.yTop - rclOld.yTop };
     716                GpiOffsetRegion(hps, hrgnDelta, &ptlDelta);
     717                // substract region of obstacles from delta region to get
     718                // pure delta
     719                GpiCombineRegion(hps, hrgnDelta, hrgnDelta, hrgnObst, CRGN_DIFF);
     720                // calculate minimal rectangle to blit (top-left aligned)
     721                int minw = qMin(swpOld.cx, swpNew.cx);
     722                int minh = qMin(swpOld.cy, swpNew.cy);
     723                POINTL blitPtls [4] = {
     724                    // target (new)
     725                    { rclNew.xLeft, rclNew.yTop - minh },
     726                    { rclNew.xLeft + minw, rclNew.yTop },
     727                    // source (old)
     728                    { rclOld.xLeft, rclOld.yTop - minh },
     729                };
     730                // proceed with blitting only if target and source rects differ
     731                if (blitPtls[0].x !=  blitPtls[2].x ||
     732                    blitPtls[0].y !=  blitPtls[2].y)
     733                {
     734                    // Substract delta region from affected region (to minimize
     735                    // flicker)
     736                    GpiCombineRegion(hps, hrgnAff, hrgnAff, hrgnDelta, CRGN_DIFF);
     737                    // set affected region to parent PS
     738                    GpiSetClipRegion(hps, hrgnAff, NULL);
     739                    // blit minimal rectangle
     740                    GpiBitBlt(hps, hps, 3, blitPtls, ROP_SRCCOPY, BBO_IGNORE);
     741                    GpiSetClipRegion(hps, 0, NULL);
     742                }
     743                // substract new widget region from the parent update region
     744                // and invalidate it (with underlying children)
     745                GpiCombineRegion(hps, hrgnUpd, hrgnUpd, hrgnNew, CRGN_DIFF );
     746                qt_WinInvalidateRegionEx(hwndParent, hrgnUpd,
     747                                         WinQueryWindow(hwnd, QW_NEXT),
     748                                         HWND_BOTTOM);
     749                // intersect pure delta region with new region
     750                // (to detect areas clipped off to minimize flicker when blitting)
     751                GpiCombineRegion(hps, hrgnDelta, hrgnDelta, hrgnNew, CRGN_AND);
     752                // substract blitted rectangle from new region
     753                GpiSetRegion(hps, hrgnAff, 1, (PRECTL) &blitPtls);
     754                GpiCombineRegion(hps, hrgnNew, hrgnNew, hrgnAff, CRGN_DIFF);
     755                // combine the rest with intersected delta region
     756                GpiCombineRegion(hps, hrgnNew, hrgnNew, hrgnDelta, CRGN_OR);
     757                // shift the result back to widget coords and invalidate
     758                GpiOffsetRegion(hps, hrgnNew, &ptlToSelf);
     759                WinInvalidateRegion(hwnd, hrgnNew, TRUE);
     760                // free resources
     761                GpiDestroyRegion(hps, hrgnDelta);
     762                GpiDestroyRegion(hps, hrgnUpd);
     763                GpiDestroyRegion(hps, hrgnObst);
     764                GpiDestroyRegion(hps, hrgnAff);
     765            }
     766            // free resources
     767            GpiDestroyRegion(hps, hrgnOld);
     768            GpiDestroyRegion(hps, hrgnNew);
     769            WinReleasePS(hps);
     770        }
    636771    }
    637772
     
    8791014                   "|  style = %08lX\n"
    8801015                   "|  fcFlags = %08lX",
    881                    QWidgetPrivate::name(q).constData(), ownerw,
     1016                   qWidgetName(q).toUtf8().constData(), ownerw,
    8821017                   title.constData(), fStyle, fcFlags);
    8831018#endif
     
    9071042                   "|  title = '%s'\n"
    9081043                   "|  style = %08lX",
    909                    QWidgetPrivate::name(q).constData(), fId, className.constData(),
     1044                   qWidgetName(q).toUtf8().constData(), fId, className.constData(),
    9101045                   title.constData(), style);
    9111046#endif
     
    9201055                   "|  title = '%s'\n"
    9211056                   "|  style = %08lX",
    922                    QWidgetPrivate::name(q).constData(), className.constData(),
     1057                   qWidgetName(q).toUtf8().constData(), className.constData(),
    9231058                   title.constData(), style);
    9241059#endif
     
    9951130                // because we didn't know the frame dimensions yet)
    9961131                if (wasMoved) {
    997                     swp.x = data.crect.left() - fs.left();
    998                     swp.y = data.crect.top() - fs.top();
     1132                    // QWidget::move() includes frame strut so no correction is
     1133                    // necessary (crect was abused to store the frame position
     1134                    // until window creation)
     1135                    swp.x = data.crect.x();
     1136                    swp.y = data.crect.y();
    9991137                }
    10001138                if (wasResized) {
     
    10341172               "|  title = '%s'\n"
    10351173               "|  style = %08lX",
    1036                QWidgetPrivate::name(q).constData(), parentw, className.constData(),
     1174               qWidgetName(q).toUtf8().constData(), parentw, className.constData(),
    10371175               title.constData(), style);
    10381176#endif
     
    11081246#if defined(QT_DEBUGWINCREATEDESTROY)
    11091247            qDebug("|Destroying window [%s]:\n"
    1110                    "|  hwnd = %08lX", QWidgetPrivate::name(this).constData(), id);
     1248                   "|  hwnd = %08lX", qWidgetName(this).toUtf8().constData(), id);
    11111249#endif
    11121250
     
    12411379void QWidget::setWindowState(Qt::WindowStates newstate)
    12421380{
    1243     // @todo implement
     1381    Q_D(QWidget);
     1382    Qt::WindowStates oldstate = windowState();
     1383    if (oldstate == newstate)
     1384        return;
     1385
     1386    ULONG fl = (newstate & Qt::WindowActive) ? SWP_ACTIVATE : 0;
     1387
     1388    if (isWindow()) {
     1389        createWinId();
     1390        Q_ASSERT(testAttribute(Qt::WA_WState_Created));
     1391
     1392        HWND fId = d->frameWinId();
     1393        Q_ASSERT(fId != NULLHANDLE);
     1394
     1395        // set flag for the WM_WINDOWPOSCHANGED handler in QtFrameProc
     1396        d->topData()->inSetWindowState = true;
     1397
     1398        // Ensure the initial size is valid, since we store it as normalGeometry below.
     1399        if (!testAttribute(Qt::WA_Resized) && !isVisible())
     1400            adjustSize();
     1401
     1402        if ((oldstate & Qt::WindowMaximized) != (newstate & Qt::WindowMaximized)) {
     1403            if (newstate & Qt::WindowMaximized && !(oldstate & Qt::WindowFullScreen))
     1404                d->topData()->normalGeometry = geometry();
     1405            if (isVisible() && !(newstate & Qt::WindowMinimized)) {
     1406                fl |= (newstate & Qt::WindowMaximized) ? SWP_MAXIMIZE : SWP_RESTORE;
     1407                WinSetWindowPos(fId, 0, 0, 0, 0, 0, fl);
     1408                if (!(newstate & Qt::WindowFullScreen)) {
     1409                    QRect r = d->topData()->normalGeometry;
     1410                    if (!(newstate & Qt::WindowMaximized) && r.width() >= 0) {
     1411                        if (pos() != r.topLeft() || size() !=r.size()) {
     1412                            d->topData()->normalGeometry = QRect(0,0,-1,-1);
     1413                            setGeometry(r);
     1414                        }
     1415                    }
     1416                } else {
     1417                    d->updateFrameStrut();
     1418                }
     1419            }
     1420        }
     1421
     1422        if ((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen)) {
     1423            if (newstate & Qt::WindowFullScreen) {
     1424                if (d->topData()->normalGeometry.width() < 0 && !(oldstate & Qt::WindowMaximized))
     1425                    d->topData()->normalGeometry = geometry();
     1426                QRect r = QApplication::desktop()->screenGeometry(this);
     1427                QRect fs(d->frameStrut());
     1428                r.rLeft() -= fs.left();
     1429                r.rRight() += fs.right();
     1430                r.rTop() -= fs.top();
     1431                r.rBottom() += fs.bottom();
     1432                fl |= SWP_ZORDER | SWP_MOVE | SWP_SIZE;
     1433                WinSetWindowPos(fId, HWND_TOP, r.left(),
     1434                                // flip y coodrinate
     1435                                QApplication::desktop()->height() - (r.top() + r.width()),
     1436                                r.width(), r.height(), fl);
     1437            } else {
     1438                // preserve maximized state
     1439                if (isVisible()) {
     1440                    fl |= (newstate & Qt::WindowMaximized) ? SWP_MAXIMIZE : SWP_RESTORE;
     1441                    WinSetWindowPos(fId, 0, 0, 0, 0, 0, fl);
     1442                }
     1443
     1444                if (!(newstate & Qt::WindowMaximized)) {
     1445                    QRect r = d->topData()->normalGeometry;
     1446                    d->topData()->normalGeometry = QRect(0,0,-1,-1);
     1447                    if (r.isValid())
     1448                        setGeometry(r);
     1449                }
     1450            }
     1451        }
     1452
     1453        if ((oldstate & Qt::WindowMinimized) != (newstate & Qt::WindowMinimized)) {
     1454            if (isVisible()) {
     1455                fl |= (newstate & Qt::WindowMinimized) ? SWP_MINIMIZE :
     1456                      (newstate & Qt::WindowMaximized) ? SWP_MAXIMIZE : SWP_RESTORE;
     1457                WinSetWindowPos(fId, 0, 0, 0, 0, 0, fl);
     1458            }
     1459        }
     1460
     1461        // set flag for the WM_WINDOWPOSCHANGED handler in QtFrameProc
     1462        d->topData()->inSetWindowState = false;
     1463    }
     1464    data->window_state = newstate;
     1465    QWindowStateChangeEvent e(oldstate);
     1466    QApplication::sendEvent(this, &e);
    12441467}
    12451468
     
    12761499{
    12771500    Q_Q(QWidget);
    1278 #if defined(QT_NON_COMMERCIAL)
    1279     QT_NC_SHOW_WINDOW
    1280 #endif
    12811501    if (q->testAttribute(Qt::WA_OutsideWSRange))
    12821502        return;
     
    13681588}
    13691589
     1590#define XCOORD_MAX 32767
     1591#define WRECT_MAX 32767
     1592
    13701593/*
    13711594  Helper function for non-toplevel widgets. Helps to map Qt's 32bit
    1372   coordinate system to Windpws's 16bit coordinate system.
     1595  coordinate system to PM 16bit coordinate system.
    13731596
    13741597  This code is duplicated from the X11 code, so any changes there
     
    13801603void QWidgetPrivate::setWSGeometry(bool dontShow)
    13811604{
    1382     // @todo implement
    1383 }
     1605    Q_Q(QWidget);
     1606    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
     1607
     1608    /*
     1609      There are up to four different coordinate systems here:
     1610      Qt coordinate system for this widget.
     1611      X coordinate system for this widget (relative to wrect).
     1612      Qt coordinate system for parent
     1613      X coordinate system for parent (relative to parent's wrect).
     1614     */
     1615    QRect validRange(-XCOORD_MAX,-XCOORD_MAX, 2*XCOORD_MAX, 2*XCOORD_MAX);
     1616    QRect wrectRange(-WRECT_MAX,-WRECT_MAX, 2*WRECT_MAX, 2*WRECT_MAX);
     1617    QRect wrect;
     1618    //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)
     1619    QRect xrect = data.crect;
     1620
     1621    const QWidget *const parent = q->parentWidget();
     1622    QRect parentWRect = parent->data->wrect;
     1623
     1624    if (parentWRect.isValid()) {
     1625        // parent is clipped, and we have to clip to the same limit as parent
     1626        if (!parentWRect.contains(xrect)) {
     1627            xrect &= parentWRect;
     1628            wrect = xrect;
     1629            //translate from parent's to my Qt coord sys
     1630            wrect.translate(-data.crect.topLeft());
     1631        }
     1632        //translate from parent's Qt coords to parent's X coords
     1633        xrect.translate(-parentWRect.topLeft());
     1634
     1635    } else {
     1636        // parent is not clipped, we may or may not have to clip
     1637
     1638        if (data.wrect.isValid() && QRect(QPoint(),data.crect.size()).contains(data.wrect)) {
     1639            // This is where the main optimization is: we are already
     1640            // clipped, and if our clip is still valid, we can just
     1641            // move our window, and do not need to move or clip
     1642            // children
     1643
     1644            QRect vrect = xrect & parent->rect();
     1645            vrect.translate(-data.crect.topLeft()); //the part of me that's visible through parent, in my Qt coords
     1646            if (data.wrect.contains(vrect)) {
     1647                xrect = data.wrect;
     1648                xrect.translate(data.crect.topLeft());
     1649                if (q->internalWinId() != NULLHANDLE) {
     1650                    Q_ASSERT(parent->internalWinId() != NULLHANDLE);
     1651                    int h = parent->height();
     1652                    qt_WinSetWindowPos(q->internalWinId(), 0, xrect.x(),
     1653                                       // flip y coordinate
     1654                                       h - (xrect.y() + 1),
     1655                                       xrect.width(), xrect.height(),
     1656                                       SWP_MOVE | SWP_SIZE);
     1657                }
     1658                return;
     1659            }
     1660        }
     1661
     1662        if (!validRange.contains(xrect)) {
     1663            // we are too big, and must clip
     1664            xrect &=wrectRange;
     1665            wrect = xrect;
     1666            wrect.translate(-data.crect.topLeft());
     1667            //parent's X coord system is equal to parent's Qt coord
     1668            //sys, so we don't need to map xrect.
     1669        }
     1670
     1671    }
     1672
     1673
     1674    // unmap if we are outside the valid window system coord system
     1675    bool outsideRange = !xrect.isValid();
     1676    bool mapWindow = false;
     1677    if (q->testAttribute(Qt::WA_OutsideWSRange) != outsideRange) {
     1678        q->setAttribute(Qt::WA_OutsideWSRange, outsideRange);
     1679        if (outsideRange) {
     1680            if (q->internalWinId() != NULLHANDLE)
     1681                qt_WinSetWindowPos(q->internalWinId(), 0, 0, 0, 0, 0, SWP_HIDE);
     1682            q->setAttribute(Qt::WA_Mapped, false);
     1683        } else if (!q->isHidden()) {
     1684            mapWindow = true;
     1685        }
     1686    }
     1687
     1688    if (outsideRange)
     1689        return;
     1690
     1691    bool jump = (data.wrect != wrect);
     1692    data.wrect = wrect;
     1693
     1694    // and now recursively for all children...
     1695    for (int i = 0; i < children.size(); ++i) {
     1696        QObject *object = children.at(i);
     1697        if (object->isWidgetType()) {
     1698            QWidget *w = static_cast<QWidget *>(object);
     1699            if (!w->isWindow() && w->testAttribute(Qt::WA_WState_Created))
     1700                w->d_func()->setWSGeometry();
     1701        }
     1702    }
     1703
     1704    // move ourselves to the new position and map (if necessary) after
     1705    // the movement. Rationale: moving unmapped windows is much faster
     1706    // than moving mapped windows
     1707    if (q->internalWinId() != NULLHANDLE) {
     1708        int h = parent->height();
     1709        if (parent->internalWinId() == NULLHANDLE) {
     1710            xrect.translate(parent->mapTo(q->nativeParentWidget(), QPoint(0, 0)));
     1711            h = q->nativeParentWidget()->height();
     1712        }
     1713        qt_WinSetWindowPos(q->internalWinId(), 0, xrect.x(),
     1714                           // flip y coordinate
     1715                           h - (xrect.y() + 1),
     1716                           xrect.width(), xrect.height(), SWP_MOVE | SWP_SIZE);
     1717    }
     1718    if (mapWindow && !dontShow) {
     1719        q->setAttribute(Qt::WA_Mapped);
     1720        if (q->internalWinId() != NULLHANDLE)
     1721            qt_WinSetWindowPos(q->internalWinId(), 0, 0, 0, 0, 0, SWP_SHOW);
     1722    }
     1723
     1724    if (jump && q->internalWinId() != NULLHANDLE)
     1725        WinInvalidateRect(q->internalWinId(), NULL, FALSE);
     1726}
     1727
     1728//
     1729// The internal qPMRequestConfig, defined in qapplication_pm.cpp, stores move,
     1730// resize and setGeometry requests for a widget that is already
     1731// processing a config event. The purpose is to avoid recursion.
     1732//
     1733void qPMRequestConfig(WId, int, int, int, int, int);
    13841734
    13851735void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
    13861736{
    1387     // @todo implement
     1737    Q_Q(QWidget);
     1738    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
     1739    if (extra) { // any size restrictions?
     1740        w = qMin(w,extra->maxw);
     1741        h = qMin(h,extra->maxh);
     1742        w = qMax(w,extra->minw);
     1743        h = qMax(h,extra->minh);
     1744    }
     1745    if (q->isWindow())
     1746        topData()->normalGeometry = QRect(0, 0, -1, -1);
     1747
     1748    QSize  oldSize(q->size());
     1749    QPoint oldPos(q->pos());
     1750
     1751    if (!q->isWindow())
     1752        isMove = (data.crect.topLeft() != QPoint(x, y));
     1753    bool isResize = w != oldSize.width() || h != oldSize.height();
     1754
     1755    if (!isMove && !isResize)
     1756        return;
     1757
     1758    HWND fId = frameWinId();
     1759
     1760    if (isResize && !q->testAttribute(Qt::WA_StaticContents) &&
     1761        q->internalWinId() != NULLHANDLE) {
     1762        RECTL rcl = { 0, 0, data.crect.width(), data.crect.height() };
     1763        WinValidateRect(q->internalWinId(), &rcl, FALSE);
     1764    }
     1765
     1766    if (isResize)
     1767        data.window_state &= ~Qt::WindowMaximized;
     1768
     1769    if (data.window_state & Qt::WindowFullScreen) {
     1770        data.window_state &= ~Qt::WindowFullScreen;
     1771    }
     1772
     1773    QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
     1774    const bool inTopLevelResize = tlwExtra ? tlwExtra->inTopLevelResize : false;
     1775
     1776    if (q->testAttribute(Qt::WA_WState_ConfigPending)) {        // processing config event
     1777        if (q->internalWinId() != NULLHANDLE)
     1778            qPMRequestConfig(q->internalWinId(), isMove ? 2 : 1, x, y, w, h);
     1779    } else {
     1780        if (!q->testAttribute(Qt::WA_DontShowOnScreen))
     1781            q->setAttribute(Qt::WA_WState_ConfigPending);
     1782        if (q->windowType() == Qt::Desktop) {
     1783            data.crect.setRect(x, y, w, h);
     1784        } else if (q->isWindow()) {
     1785            int sh = QApplication::desktop()->height();
     1786            QRect fs(frameStrut());
     1787            if (extra) {
     1788                fs.setLeft(x - fs.left());
     1789                fs.setTop(y - fs.top());
     1790                fs.setRight((x + w - 1) + fs.right());
     1791                fs.setBottom((y + h - 1) + fs.bottom());
     1792            }
     1793            if (w == 0 || h == 0) {
     1794                q->setAttribute(Qt::WA_OutsideWSRange, true);
     1795                if (q->isVisible() && q->testAttribute(Qt::WA_Mapped))
     1796                    hide_sys();
     1797                data.crect = QRect(x, y, w, h);
     1798            } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) {
     1799                q->setAttribute(Qt::WA_OutsideWSRange, false);
     1800
     1801                // put the window in its place and show it
     1802                WinSetWindowPos(fId, 0, fs.x(),
     1803                                // flip y coordinate
     1804                                sh - (fs.y() + fs.height()),
     1805                                fs.width(), fs.height(), SWP_MOVE | SWP_SIZE);
     1806                data.crect.setRect(x, y, w, h);
     1807
     1808                show_sys();
     1809            } else if (!q->testAttribute(Qt::WA_DontShowOnScreen)) {
     1810                q->setAttribute(Qt::WA_OutsideWSRange, false);
     1811                // If the window is hidden and in maximized state or minimized, instead of moving the
     1812                // window, set the normal position of the window.
     1813                SWP swp;
     1814                WinQueryWindowPos(fId, &swp);
     1815                if (((swp.fl & SWP_MAXIMIZE) && !WinIsWindowVisible(fId)) ||
     1816                    (swp.fl & SWP_MINIMIZE)) {
     1817                    WinSetWindowUShort(fId, QWS_XRESTORE, fs.x());
     1818                    WinSetWindowUShort(fId, QWS_YRESTORE, // flip y coordinate
     1819                                       sh - (fs.y() + fs.height()));
     1820                    WinSetWindowUShort(fId, QWS_CXRESTORE, fs.width());
     1821                    WinSetWindowUShort(fId, QWS_CYRESTORE, fs.height());
     1822                } else {
     1823                    WinSetWindowPos(fId, 0, fs.x(),
     1824                                    // flip y coordinate
     1825                                    sh - (fs.y() + fs.height()),
     1826                                    fs.width(), fs.height(), SWP_MOVE | SWP_SIZE);
     1827                }
     1828                if (!q->isVisible())
     1829                    WinInvalidateRect(q->internalWinId(), NULL, FALSE);
     1830
     1831                // If the layout has heightForWidth, the WinSetWindowPos() above can
     1832                // change the size/position, so refresh them.
     1833                WinQueryWindowPos(fId, &swp);
     1834                // flip y coordinate
     1835                swp.y = sh - (swp.y + swp.cy);
     1836                QRect fs(frameStrut());
     1837                data.crect.setRect(swp.x + fs.left(),
     1838                                   swp.y + fs.top(),
     1839                                   swp.cx - fs.left() - fs.right(),
     1840                                   swp.cy - fs.top() - fs.bottom());
     1841                isResize = data.crect.size() != oldSize;
     1842            } else {
     1843                q->setAttribute(Qt::WA_OutsideWSRange, false);
     1844                data.crect.setRect(x, y, w, h);
     1845            }
     1846        } else {
     1847            QRect oldGeom(data.crect);
     1848            data.crect.setRect(x, y, w, h);
     1849            if (q->isVisible() && (!inTopLevelResize || q->internalWinId())) {
     1850                // Top-level resize optimization does not work for native child widgets;
     1851                // disable it for this particular widget.
     1852                if (inTopLevelResize)
     1853                    tlwExtra->inTopLevelResize = false;
     1854
     1855                if (!isResize)
     1856                    moveRect(QRect(oldPos, oldSize), x - oldPos.x(), y - oldPos.y());
     1857                else
     1858                    invalidateBuffer_resizeHelper(oldPos, oldSize);
     1859
     1860                if (inTopLevelResize)
     1861                    tlwExtra->inTopLevelResize = true;
     1862            }
     1863            if (q->testAttribute(Qt::WA_WState_Created))
     1864                setWSGeometry();
     1865        }
     1866        q->setAttribute(Qt::WA_WState_ConfigPending, false);
     1867    }
     1868
     1869    if (q->isWindow() && q->isVisible() && isResize && !inTopLevelResize) {
     1870        invalidateBuffer(q->rect()); //after the resize
     1871    }
     1872
     1873    // Process events immediately rather than in translateConfigEvent to
     1874    // avoid windows message process delay.
     1875    if (q->isVisible()) {
     1876        if (isMove && q->pos() != oldPos) {
     1877            // in QMoveEvent, pos() and oldPos() exclude the frame, adjust them
     1878            QRect fs(frameStrut());
     1879            QMoveEvent e(q->pos() + fs.topLeft(), oldPos + fs.topLeft());
     1880            QApplication::sendEvent(q, &e);
     1881        }
     1882        if (isResize) {
     1883            static bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt();
     1884            // If we have a backing store with static contents, we have to disable the top-level
     1885            // resize optimization in order to get invalidated regions for resized widgets.
     1886            // The optimization discards all invalidateBuffer() calls since we're going to
     1887            // repaint everything anyways, but that's not the case with static contents.
     1888            const bool setTopLevelResize = !slowResize && q->isWindow() && extra && extra->topextra
     1889                                           && !extra->topextra->inTopLevelResize
     1890                                           && (!extra->topextra->backingStore
     1891                                               || !extra->topextra->backingStore->hasStaticContents());
     1892            if (setTopLevelResize)
     1893                extra->topextra->inTopLevelResize = true;
     1894            QResizeEvent e(q->size(), oldSize);
     1895            QApplication::sendEvent(q, &e);
     1896            if (setTopLevelResize)
     1897                extra->topextra->inTopLevelResize = false;
     1898        }
     1899    } else {
     1900        if (isMove && q->pos() != oldPos)
     1901            q->setAttribute(Qt::WA_PendingMoveEvent, true);
     1902        if (isResize)
     1903            q->setAttribute(Qt::WA_PendingResizeEvent, true);
     1904    }
    13881905}
    13891906
     
    14231940    extra->topextra->fId = NULLHANDLE;
    14241941    extra->topextra->swEntry = NULLHANDLE;
     1942    extra->topextra->inSetWindowState = false;
    14251943}
    14261944
     
    15402058}
    15412059
    1542 /*!
    1543     Returns a QWidget pointer or 0 if there is no widget corresponding to the
    1544     given HWND. As opposed to QWidget::find(), correctly handles WC_FRAME
    1545     windows created for top level widgets. Used for debugging.
    1546  */
    1547 // static
    1548 QWidget *QWidgetPrivate::fromHWND(HWND hwnd)
    1549 {
    1550     char buf[10];
    1551     if (WinQueryClassName(hwnd, sizeof(buf), buf)) {
    1552         if (!strcmp(buf, "#1")) // WC_FRAME
    1553             hwnd = WinWindowFromID(hwnd, FID_CLIENT);
    1554         return QWidget::find(hwnd);
    1555     }
    1556     return 0;
    1557 }
    1558 
    1559 /*!
    1560     \internal
    1561 
    1562     Returns a human readable widget name in the form "class/name". Used for
    1563     debugging.
    1564  */
    1565 // static
    1566 QByteArray QWidgetPrivate::name(QWidget *w)
    1567 {
    1568     if (w)
    1569         return QString()
    1570             .sprintf("%s/%s", w->metaObject()->className(),
    1571                      w->objectName().toLocal8Bit().constData()).toLocal8Bit();
    1572     return QByteArray("<no-widget>");
    1573 }
    1574 
    1575 
    15762060QT_END_NAMESPACE
  • trunk/src/gui/kernel/qwindowdefs_pm.h

    r113 r120  
    6868#define NULLHANDLE ((LHANDLE)0)
    6969
    70 Q_GUI_EXPORT HPS qt_display_ps();
    71 
    7270// constants to address extra window data
    7371#define QWL_QTCLIPRGN       (QWL_USER)
     
    7775QT_BEGIN_NAMESPACE
    7876
     77class QWidget;
     78
     79Q_GUI_EXPORT HPS qt_display_ps();
     80
     81Q_GUI_EXPORT QWidget *qWidgetFromHWND(HWND hwnd);
     82
     83// For printing non-quoted QString's with QDebug
     84struct Q_CORE_EXPORT QDbgStr: public QString
     85{
     86    inline QDbgStr(const QString &str) : QString(str) {}
     87};
     88
     89Q_GUI_EXPORT QDbgStr qWidgetName(QWidget *w);
     90inline QDbgStr qWidgetName(HWND hwnd)
     91{ return qWidgetName(qWidgetFromHWND(hwnd)); }
     92
     93Q_CORE_EXPORT QDbgStr qStrHWND(HWND hwnd);
     94Q_CORE_EXPORT QDbgStr qStrHPS(HPS hps);
     95Q_CORE_EXPORT QDbgStr qStrHPOINTER(HPOINTER hptr);
     96Q_CORE_EXPORT QDbgStr qStrHRGN(HRGN hrgn);
     97
     98Q_CORE_EXPORT QDbgStr qStrQMSG(const QMSG &qmsg);
     99
     100// the following declarations require OS/2 types not defined here,
     101// we don't drag them in but require qt_os2.h to be included before
     102#if defined(QT_OS2_H)
     103
     104Q_CORE_EXPORT QDbgStr qStrRECTL(const RECTL &rcl);
     105
     106#endif // defined(QT_OS2_H)
     107
     108// don't drag qdebug.h as well but require it to be included before
     109#if defined(QDEBUG_H) && !defined(QT_NO_DEBUG_STREAM)
     110
     111// Prints a non-quoted QString
     112inline QDebug operator<<(QDebug dbg, const QDbgStr &str)
     113{ dbg << str.utf8().constData(); return dbg; }
     114
     115inline QDebug operator<<(QDebug dbg, const RECTL &rcl)
     116{ dbg << qStrRECTL(rcl); return dbg; }
     117
     118#endif // defined(QDEBUG_H) && !defined(QT_NO_DEBUG_STREAM)
     119
    79120QT_END_NAMESPACE
    80121
  • trunk/src/gui/painting/qwindowsurface_raster.cpp

    r115 r120  
    205205#if 1
    206206    qDebug("QRasterWindowSurface::flush: [%s] br=%d,%d/%d,%d",
    207            QWidgetPrivate::name(widget).constData(),
     207           qWidgetName(widget).toUtf8().constData(),
    208208           br.x(), br.y(), br.width(), br.height());
    209209#endif
Note: See TracChangeset for help on using the changeset viewer.