Changeset 938 for trunk/src/gui/kernel/qapplication_pm.cpp
- Timestamp:
- Aug 4, 2011, 8:42:53 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gui/kernel/qapplication_pm.cpp
r936 r938 144 144 QRect frameStrut() const { return d_func()->frameStrut(); } 145 145 HWND frameWinId() const { return d_func()->frameWinId(); } 146 QETWidget* modalBlocker() const { return (QETWidget *)d_func()->modalBlocker(); } 146 147 bool pmEvent(QMSG *m, MRESULT *r) { return QWidget::pmEvent(m, r); } 147 148 // void markFrameStrutDirty() { data->fstrut_dirty = 1; } … … 1268 1269 } 1269 1270 1271 static void qt_pull_blocked_widgets(QETWidget *widget) 1272 { 1273 QWidgetList list = QApplication::topLevelWidgets(); 1274 foreach (QWidget *w, list) { 1275 QETWidget *ew = (QETWidget *)w; 1276 QETWidget *above = (QETWidget*)ew->modalBlocker(); 1277 if (above == widget) { 1278 WinSetWindowPos(ew->frameWinId(), widget->frameWinId(), 1279 0, 0, 0, 0, SWP_ZORDER); 1280 qt_pull_blocked_widgets(ew); 1281 } 1282 } 1283 } 1284 1270 1285 PFNWP QtOldFrameProc = 0; 1271 1286 1272 1287 MRESULT EXPENTRY QtFrameProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) 1273 1288 { 1289 static bool pullingBlockedWigets = false; 1290 1274 1291 do { 1275 1292 if (!qApp) // unstable app state … … 1315 1332 // If PM tries to activate a modally blocked window, pass activation 1316 1333 // over to the top modal window instead of letting it activate the 1317 // blocked one. Z-order changes are simply ignored for now. 1318 // @todo Blocked widgets should keep Z-order WRT their modal 1319 // blockers whenever they move (e.g. bringing the modal one to top 1320 // should also put the one it blocks right under it instead of 1321 // possibly leaving it somewhere behind other windows). 1334 // blocked one 1322 1335 PSWP pswp =(PSWP)qmsg.mp1; 1323 1336 if (app_do_modal && 1324 1337 ((pswp->fl & SWP_ACTIVATE) || (pswp->fl & SWP_ZORDER))) { 1325 Q Widget *top = 0;1326 if ( !QApplicationPrivate::tryModalHelper(widget, &top) && top && widget != top) {1338 QETWidget *above = (QETWidget *)widget->modalBlocker(); 1339 if (above) { 1327 1340 if (pswp->fl & SWP_ACTIVATE) { 1328 if (top->isVisible()) { 1329 top->activateWindow(); 1330 } else { 1331 // This is the case when native file dialogs are shown 1332 QWidget *p = (top->parentWidget() ? top->parentWidget()->window() : 0); 1333 if (p && p->isVisible()) { 1334 p->activateWindow(); 1335 } 1336 } 1341 // find the blocker that isn't blocked itself and 1342 // delegate activation to it (WM_WINDOWPOSCHANGED will 1343 // care about the rest) 1344 while (above->modalBlocker()) 1345 above = above->modalBlocker(); 1346 WinSetWindowPos(above->frameWinId(), HWND_TOP, 0, 0, 0, 0, 1347 SWP_ACTIVATE | SWP_ZORDER); 1337 1348 pswp->fl &= ~SWP_ACTIVATE; 1338 1349 } 1339 1350 if (pswp->fl & SWP_ZORDER) { 1340 pswp->fl &= ~SWP_ZORDER; 1351 // forbid changing the Z-order of the blocked widget 1352 // (except when it is moved right under its blocker) 1353 if (pswp->hwndInsertBehind != above->frameWinId()) 1354 pswp->fl &= ~SWP_ZORDER; 1341 1355 } 1342 1356 } 1357 } 1358 break; 1359 } 1360 1361 case WM_WINDOWPOSCHANGED: { 1362 PSWP pswp =(PSWP)qmsg.mp1; 1363 // make sure blocked widgets stay behind the blocker on Z-order change 1364 if (app_do_modal && (pswp->fl & SWP_ZORDER) && !pullingBlockedWigets) { 1365 // protect against various kinds of recursion (e.g. when the 1366 // blocked widgets are PM owners of the blocker in which case PM 1367 // manages pulling on its own and will put us in a loop) 1368 pullingBlockedWigets = true; 1369 qt_pull_blocked_widgets(widget); 1370 pullingBlockedWigets = false; 1343 1371 } 1344 1372 break; … … 1478 1506 // programmatically, e.g. from the Window List) 1479 1507 QWidgetList list = QApplication::topLevelWidgets(); 1480 foreach (QWidget *w, list) {1508 foreach (QWidget *w, list) { 1481 1509 if (w != widget && QApplicationPrivate::isBlockedByModal(w)) { 1482 WinEnableWindow(w->d_func()->frameWinId(), FALSE); 1510 if (!w->d_func()->modalBlocker()) { 1511 WinEnableWindow(w->d_func()->frameWinId(), FALSE); 1512 // also remember the blocker widget so that the blocked one can 1513 // pass activation attempts to it (note that the blocker is not 1514 // necessarily modal itself, it's just the window right above 1515 // the one being blocked, we will use this to restore z-order of 1516 // of blocked widgets in qt_pull_blocked_widgets()) 1517 QWidget *widgetAbove = 0; 1518 HWND above = w->d_func()->frameWinId(); 1519 while (!widgetAbove) { 1520 above = WinQueryWindow(above, QW_PREV); 1521 if (!above) 1522 break; 1523 widgetAbove = qt_widget_from_hwnd(above); 1524 } 1525 if (!widgetAbove) 1526 widgetAbove = widget; 1527 w->d_func()->setModalBlocker(widgetAbove); 1528 } 1483 1529 } 1484 1530 } … … 1515 1561 foreach(QWidget *w, list) { 1516 1562 if (w != widget && !QApplicationPrivate::isBlockedByModal(w)) { 1517 WinEnableWindow(w->d_func()->frameWinId(), TRUE); 1563 if (w->d_func()->modalBlocker()) { 1564 w->d_func()->setModalBlocker(0); 1565 WinEnableWindow(w->d_func()->frameWinId(), TRUE); 1566 } 1518 1567 } 1519 1568 }
Note:
See TracChangeset
for help on using the changeset viewer.