Changeset 116 for trunk/src/gui/kernel
- Timestamp:
- Aug 17, 2009, 7:09:10 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gui/kernel/qapplication_pm.cpp
r114 r116 56 56 57 57 #include "private/qeventdispatcher_pm_p.h" 58 58 59 59 60 #include "qwidget_p.h" … … 105 106 106 107 extern void qt_WinQueryClipRegionOrRect(HWND hwnd, HRGN hrgn); // qwidget_pm.cpp 108 109 107 110 108 111 MRESULT EXPENTRY QtWndProc(HWND, ULONG, MPARAM, MPARAM); … … 132 135 // inline void showChildren(bool spontaneous) { d_func()->showChildren(spontaneous); } 133 136 // inline void hideChildren(bool spontaneous) { d_func()->hideChildren(spontaneous); } 134 137 inline void validateObstacles() { d_func()->validateObstacles(); } 135 138 // inline uint testWindowState(uint teststate){ return dataPtr()->window_state & teststate; } 136 139 // inline void forceUpdate() { … … 1447 1450 // qwidget_pm.cpp), we have to validate areas that intersect with our 1448 1451 // children and siblings, taking their clip regions into account. 1449 validateObstacles();1452 validateObstacles(); 1450 1453 1451 1454 Q_ASSERT(testAttribute(Qt::WA_WState_Created)); … … 1463 1466 1464 1467 // @todo not sure we need it 1465 // const QRegion dirtyInBackingStore(qt_dirtyRegion(this)); 1466 // // Make sure the invalidated region contains the region we're about to repaint. 1467 // // BeginPaint will set the clip to the invalidated region and it is impossible 1468 // // to enlarge it afterwards (only shrink it). Using GetDCEx is not suffient 1469 // // as it may return an invalid context (especially on Windows Vista). 1470 // if (!dirtyInBackingStore.isEmpty()) 1471 // InvalidateRgn(internalWinId(), dirtyInBackingStore.handle(), false); 1468 const QRegion dirtyInBackingStore(qt_dirtyRegion(this)); 1469 // Make sure the invalidated region contains the region we're about to repaint. 1470 // BeginPaint will set the clip to the invalidated region and it is impossible 1471 // to enlarge it afterwards (only shrink it). 1472 if (!dirtyInBackingStore.isEmpty()) 1473 WinInvalidateRegion(internalWinId(), dirtyInBackingStore.handle(), FALSE); 1472 1474 1473 1475 RECTL rcl; … … 1475 1477 1476 1478 #if 1 1477 qDebug("WM_PAINT: [%s] %ld,%ld:%ld,%ld",1479 qDebug("WM_PAINT: [%s] ", 1478 1480 QWidgetPrivate::name(this).constData(), 1479 rcl.xLeft, rcl.yBottom, rcl.xRight, rcl.yTop );1481 rcl.xLeft, rcl.yBottom, rcl.xRight, rcl.yTop); 1480 1482 #endif 1481 1483 … … 1489 1491 } 1490 1492 1491 if (WinQueryClipRegion( internalWinId(), 0) != QCRGN_NO_CLIP_REGION) {1492 // Correct the update region by intersecting it with the clip1493 // region (PM doesn't do that itself). It is necessary1494 // to have a correct QRegion in QPaintEvent.1495 HRGN hcrgn = GpiCreateRegion(displayPS, 0, NULL);1496 WinQueryClipRegion(internalWinId(), hcrgn);1497 GpiCombineRegion(displayPS, hrgn, hrgn, hcrgn, CRGN_AND);1498 GpiDestroyRegion(displayPS, hcrgn);1499 }1500 1501 1493 // flip y coordinate 1502 1494 rcl.yBottom = height() - (rcl.yBottom + 1); 1503 1495 rcl.yTop = height() - (rcl.yTop + 1); 1504 1496 1505 const QRect updateRect(QPoint(rcl.xLeft, rcl.yBottom), 1506 QPoint(rcl.xRight, rcl.yTop)); 1497 // note: right top point is exlusive in rcl 1498 QRect updRect(QPoint(rcl.xLeft, rcl.yTop + 1), 1499 QPoint(rcl.xRight - 1, rcl.yBottom)); 1507 1500 1508 1501 // Mapping region from system to qt (32 bit) coordinate system. 1509 // @todo use hrgn here once we implement QRegion<->HRGN relationship 1510 d_func()->syncBackingStore(updateRect.translated(data->wrect.topLeft())); 1502 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 1508 // @todo use hrgn here converted to QRegion? 1509 d_func()->syncBackingStore(updRect); 1511 1510 1512 1511 WinEndPaint(d_func()->hd); 1513 1512 d_func()->hd = NULLHANDLE; 1513 1514 1515 1516 1514 1517 1515 1518 return true; … … 1522 1525 bool QETWidget::translateConfigEvent(const QMSG &qmsg) 1523 1526 { 1524 // @todo implement 1525 return false; 1527 if (!testAttribute(Qt::WA_WState_Created)) // in QWidget::create() 1528 return true; 1529 1530 if (testAttribute(Qt::WA_WState_ConfigPending)) { 1531 // it's possible that we're trying to set the frame size smaller 1532 // than it possible for WC_FRAME in QWidget::setGeometry_sys(). 1533 // here we correct this (crect there is set before WinSetWindowPos() 1534 // that sends WM_SIZE). 1535 QSize newSize(SHORT1FROMMP(qmsg.mp2), SHORT2FROMMP(qmsg.mp2)); 1536 if (qmsg.msg == WM_SIZE && size() != newSize) 1537 data->crect.setSize(newSize); 1538 return true; 1539 } 1540 1541 if (testAttribute(Qt::WA_DontShowOnScreen)) 1542 return true; 1543 // @todo check if this is actually called for !isWindow() widget 1544 // if (!isWindow()) 1545 // return true; 1546 1547 setAttribute(Qt::WA_WState_ConfigPending); // set config flag 1548 1549 HWND fId = NULLHANDLE; 1550 ULONG fStyle = 0; 1551 if (isWindow()) { 1552 fId = d_func()->frameWinId(); 1553 fStyle = WinQueryWindowULong(fId, QWL_STYLE); 1554 } 1555 1556 QRect cr = geometry(); 1557 if (qmsg.msg == WM_SIZE) { // resize event 1558 QSize oldSize = size(); 1559 QSize newSize(SHORT1FROMMP(qmsg.mp2), SHORT2FROMMP(qmsg.mp2)); 1560 cr.setSize(newSize); 1561 data->crect = cr; 1562 if (isWindow()) { // update title/icon text 1563 d_func()->createTLExtra(); 1564 QString title; 1565 if ((fStyle & WS_MINIMIZED)) 1566 title = windowIconText(); 1567 if (title.isEmpty()) 1568 title = windowTitle(); 1569 if (!title.isEmpty()) 1570 d_func()->setWindowTitle_helper(title); 1571 } 1572 if (oldSize != newSize) { 1573 // Spontaneous (external to Qt) WM_SIZE messages should occur only 1574 // on top-level widgets. If we get them for a non top-level widget, 1575 // the result will most likely be incorrect because widget masks will 1576 // not be properly processed (i.e. in the way it is done in 1577 // QWidget::setGeometry_sys() when the geometry is changed from 1578 // within Qt). So far, I see no need to support this (who will ever 1579 // need to move a non top-level window of a foreign process?). 1580 Q_ASSERT(isWindow()); 1581 if (isVisible()) { 1582 QTLWExtra *tlwExtra = d_func()->maybeTopData(); 1583 static bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt(); 1584 const bool hasStaticContents = tlwExtra && tlwExtra->backingStore 1585 && tlwExtra->backingStore->hasStaticContents(); 1586 // If we have a backing store with static contents, we have to disable the top-level 1587 // resize optimization in order to get invalidated regions for resized widgets. 1588 // The optimization discards all invalidateBuffer() calls since we're going to 1589 // repaint everything anyways, but that's not the case with static contents. 1590 if (!slowResize && tlwExtra && !hasStaticContents) 1591 tlwExtra->inTopLevelResize = true; 1592 QResizeEvent e(newSize, oldSize); 1593 QApplication::sendSpontaneousEvent(this, &e); 1594 if (d_func()->paintOnScreen()) { 1595 QRegion updateRegion(rect()); 1596 if (testAttribute(Qt::WA_StaticContents)) 1597 updateRegion -= QRect(0, 0, oldSize.width(), oldSize.height()); 1598 // syncBackingStore() should have already flushed the widget 1599 // contents to the screen, so no need to redraw the exposed 1600 // areas in WM_PAINT once more 1601 d_func()->syncBackingStore(updateRegion); 1602 WinValidateRect(internalWinId(), 1603 updateRegion.handle(newSize.height()), FALSE); 1604 } else { 1605 d_func()->syncBackingStore(); 1606 // see above 1607 RECTL rcl = { 0, 0, newSize.width(), newSize.height() }; 1608 WinValidateRect(internalWinId(), &rcl, FALSE); 1609 } 1610 if (!slowResize && tlwExtra) 1611 tlwExtra->inTopLevelResize = false; 1612 } else { 1613 QResizeEvent *e = new QResizeEvent(newSize, oldSize); 1614 QApplication::postEvent(this, e); 1615 } 1616 } 1617 } else if (qmsg.msg == WM_MOVE) { // move event 1618 QPoint oldPos = geometry().topLeft(); 1619 SWP swp; 1620 if (isWindow()) { 1621 WinQueryWindowPos(fId, &swp); 1622 // flip y coordinate 1623 swp.y = QApplication::desktop()->height() - (swp.y + swp.cy); 1624 QTLWExtra *top = d_func()->topData(); 1625 swp.x += top->frameStrut.left(); 1626 swp.y += top->frameStrut.top(); 1627 } else { 1628 WinQueryWindowPos(internalWinId(), &swp); 1629 // flip y coordinate 1630 swp.y = parentWidget()->height() - (swp.y + swp.cy); 1631 } 1632 QPoint newCPos(swp.x, swp.y); 1633 if (newCPos != oldPos) { 1634 cr.moveTopLeft(newCPos); 1635 data->crect = cr; 1636 if (isVisible()) { 1637 QMoveEvent e(newCPos, oldPos); // cpos (client position) 1638 QApplication::sendSpontaneousEvent(this, &e); 1639 } else { 1640 QMoveEvent *e = new QMoveEvent(newCPos, oldPos); 1641 QApplication::postEvent(this, e); 1642 } 1643 } 1644 } 1645 setAttribute(Qt::WA_WState_ConfigPending, false); // clear config flag 1646 return true; 1526 1647 } 1527 1648
Note:
See TracChangeset
for help on using the changeset viewer.