Changeset 561 for trunk/src/gui/kernel/qwidget_x11.cpp
- Timestamp:
- Feb 11, 2010, 11:19:06 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
Property svn:mergeinfo
set to (toggle deleted branches)
/branches/vendor/nokia/qt/4.6.1 merged eligible /branches/vendor/nokia/qt/current merged eligible /branches/vendor/trolltech/qt/current 3-149
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/gui/kernel/qwidget_x11.cpp
r2 r561 2 2 ** 3 3 ** 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) 5 6 ** 6 7 ** This file is part of the QtGui module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 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. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** 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. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 347 347 } 348 348 349 static Bool checkForConfigureAndExpose(Display *, XEvent *e, XPointer) 350 { 351 return e->type == ConfigureNotify || e->type == Expose; 352 } 349 353 350 354 Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w) … … 356 360 QTime t; 357 361 t.start(); 362 static const int maximumWaitTime = 2000; 358 363 if (!w->testAttribute(Qt::WA_WState_Created)) 359 364 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; 365 379 qApp->syncX(); // non-busy wait 366 380 } 381 367 382 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 } 370 398 } 371 399 … … 491 519 initializeWindow = true; 492 520 521 QX11Info *parentXinfo = parentWidget ? &parentWidget->d_func()->xinfo : 0; 522 493 523 if (desktop && 494 524 qt_x11_create_desktop_on_screen >= 0 && … … 497 527 QX11InfoData *xd = &X11->screens[qt_x11_create_desktop_on_screen]; 498 528 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; 501 538 } 502 539 … … 513 550 data.crect.setRect(0, 0, sw, sh); 514 551 } 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 515 559 int width = sw / 2; 516 560 int height = 4 * sh / 10; … … 755 799 qBound(1, data.crect.height(), XCOORD_MAX)); 756 800 XStoreName(dpy, id, appName.data()); 757 Atom protocols[ 4];801 Atom protocols[5]; 758 802 int n = 0; 759 803 protocols[n++] = ATOM(WM_DELETE_WINDOW); // support del window protocol 760 804 protocols[n++] = ATOM(WM_TAKE_FOCUS); // support take focus window protocol 761 805 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 762 809 if (flags & Qt::WindowContextHelpButtonHint) 763 810 protocols[n++] = ATOM(_NET_WM_CONTEXT_HELP); … … 883 930 } 884 931 932 static 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 956 static 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 885 969 void QWidgetPrivate::x11UpdateIsOpaque() 886 970 { … … 893 977 int screen = xinfo.screen(); 894 978 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); 905 982 } 906 983 #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 */ 992 bool 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; 907 1022 } 908 1023 … … 911 1026 Q_D(QWidget); 912 1027 if (!isWindow() && parentWidget()) 913 parentWidget()->d_func()->invalidateBuffer( geometry());1028 parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry())); 914 1029 d->deactivateWidgetCleanup(); 915 1030 if (testAttribute(Qt::WA_WState_Created)) { … … 955 1070 qt_XDestroyWindow(this, X11->display, data->winid); 956 1071 } 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 } 958 1077 959 1078 extern void qPRCleanup(QWidget *widget); // from qapplication_x11.cpp … … 966 1085 // release previous focus information participating with 967 1086 // preedit preservation of qic 968 QInputContext *qic = inputContext();1087 QInputContext *qic = QApplicationPrivate::inputContext; 969 1088 if (qic) 970 1089 qic->widgetDestroyed(this); … … 990 1109 bool wasCreated = q->testAttribute(Qt::WA_WState_Created); 991 1110 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())); 993 1112 extern void qPRCreate(const QWidget *, Window); 994 1113 #ifndef QT_NO_CURSOR … … 1216 1335 extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap); // qpixmap_x11.cpp 1217 1336 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()); 1219 1338 } else 1220 1339 XSetWindowBackground(X11->display, q->internalWinId(), … … 1309 1428 return; 1310 1429 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 happy1317 h = &wm_hints;1318 }1319 1320 1430 // preparing images to set the _NET_WM_ICON property 1321 1431 QIcon icon = q->windowIcon(); 1432 QVector<long> icon_data; 1433 Qt::HANDLE pixmap_handle = 0; 1322 1434 if (!icon.isNull()) { 1323 1435 QList<QSize> availableSizes = icon.availableSizes(); … … 1329 1441 availableSizes.push_back(QSize(128,128)); 1330 1442 } 1331 QVector<long> icon_data;1332 1443 for(int i = 0; i < availableSizes.size(); ++i) { 1333 1444 QSize size = availableSizes.at(i); … … 1340 1451 icon_data[pos++] = image.height(); 1341 1452 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()); 1343 1454 } else { 1344 1455 for (int y = 0; y < image.height(); ++y) { … … 1351 1462 } 1352 1463 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 }1358 1464 extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap); 1359 1465 /* … … 1369 1475 if (!forceReset || !topData->iconPixmap) 1370 1476 topData->iconPixmap = new QBitmap(qt_toX11Pixmap(icon.pixmap(QSize(64,64)))); 1371 h->icon_pixmap= topData->iconPixmap->handle();1477 pixmap_handle = topData->iconPixmap->handle(); 1372 1478 } else { 1373 1479 // default depth, use a normal pixmap (even though this … … 1375 1481 if (!forceReset || !topData->iconPixmap) 1376 1482 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(); 1378 1484 } 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); 1387 1515 if (h != &wm_hints) 1388 1516 XFree((char *)h); … … 1510 1638 void QWidget::activateWindow() 1511 1639 { 1512 Q_D(QWidget);1513 1640 QWidget *tlw = window(); 1514 1641 if (tlw->isVisible() && !tlw->d_func()->topData()->embedded && !X11->deferred_map.contains(tlw)) { … … 1751 1878 } 1752 1879 1753 mwmhints.flags |= MWM_HINTS_DECORATIONS;1754 1880 if (mwmhints.decorations == MWM_DECOR_ALL) { 1881 mwmhints.flags |= MWM_HINTS_DECORATIONS; 1755 1882 mwmhints.decorations = (MWM_DECOR_BORDER 1756 1883 | MWM_DECOR_TITLE … … 1761 1888 1762 1889 if (q->windowFlags() & Qt::WindowMinimizeButtonHint) { 1890 mwmhints.flags |= MWM_HINTS_DECORATIONS; 1763 1891 mwmhints.decorations |= MWM_DECOR_MINIMIZE; 1764 1892 mwmhints.functions |= MWM_FUNC_MINIMIZE; 1765 1893 } 1766 1894 if (q->windowFlags() & Qt::WindowMaximizeButtonHint) { 1895 mwmhints.flags |= MWM_HINTS_DECORATIONS; 1767 1896 mwmhints.decorations |= MWM_DECOR_MAXIMIZE; 1768 1897 mwmhints.functions |= MWM_FUNC_MAXIMIZE; … … 1816 1945 if (setUserTime) 1817 1946 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 1818 1964 1819 1965 if (!topData()->embedded … … 2151 2297 parent's coord sys 2152 2298 */ 2153 void QWidgetPrivate::setWSGeometry(bool dontShow )2299 void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &) 2154 2300 { 2155 2301 Q_Q(QWidget); … … 2486 2632 if (just_update) 2487 2633 q->update(); 2634 else if (!valid_rect) 2635 dirty.translate(dx, dy); 2488 2636 2489 2637 int x1, y1, x2, y2, w = sr.width(), h = sr.height(); … … 2609 2757 void QWidgetPrivate::createSysExtra() 2610 2758 { 2759 extra->compress_events = true; 2611 2760 extra->xDndProxy = 0; 2612 extra->compress_events = true;2613 2761 } 2614 2762 … … 2619 2767 void QWidgetPrivate::createTLSysExtra() 2620 2768 { 2769 extra->topextra->spont_unmapped = 0; 2770 extra->topextra->dnd = 0; 2621 2771 extra->topextra->validWMState = 0; 2622 2772 extra->topextra->waitingForMapNotify = 0; 2773 extra->topextra->parentWinId = 0; 2623 2774 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 2624 2781 } 2625 2782 … … 2746 2903 } 2747 2904 2748 /*!2749 Returns information about the configuration of the X display used to display2750 the widget.2751 2752 \warning This function is only available on X11.2753 */2754 2905 const QX11Info &QWidget::x11Info() const 2755 2906 { … … 2788 2939 } 2789 2940 2790 /*!2791 Returns the X11 Picture handle of the widget for XRender2792 support. Use of this function is not portable. This function will2793 return 0 if XRender support is not compiled into Qt, if the2794 XRender extension is not supported on the X11 display, or if the2795 handle could not be created.2796 */2797 2941 Qt::HANDLE QWidget::x11PictureHandle() const 2798 2942 {
Note:
See TracChangeset
for help on using the changeset viewer.