src/gui/kernel/qwidget.cpp
branchRCL_3
changeset 7 3f74d0d4af4c
parent 5 d3bac044e0f0
child 13 c0432d11811c
equal deleted inserted replaced
6:dee5afe5301f 7:3f74d0d4af4c
   116 #include "private/qevent_p.h"
   116 #include "private/qevent_p.h"
   117 
   117 
   118 #include "private/qgraphicssystem_p.h"
   118 #include "private/qgraphicssystem_p.h"
   119 #include "private/qgesturemanager_p.h"
   119 #include "private/qgesturemanager_p.h"
   120 
   120 
       
   121 #ifdef QT_KEYPAD_NAVIGATION
       
   122 #include "qtabwidget.h" // Needed in inTabWidget()
       
   123 #endif // QT_KEYPAD_NAVIGATION
       
   124 
   121 // widget/widget data creation count
   125 // widget/widget data creation count
   122 //#define QWIDGET_EXTRA_DEBUG
   126 //#define QWIDGET_EXTRA_DEBUG
   123 //#define ALIEN_DEBUG
   127 //#define ALIEN_DEBUG
   124 
   128 
   125 QT_BEGIN_NAMESPACE
   129 QT_BEGIN_NAMESPACE
   190       , dirtyOpaqueChildren(1)
   194       , dirtyOpaqueChildren(1)
   191       , isOpaque(0)
   195       , isOpaque(0)
   192       , inDirtyList(0)
   196       , inDirtyList(0)
   193       , isScrolled(0)
   197       , isScrolled(0)
   194       , isMoved(0)
   198       , isMoved(0)
       
   199       , isGLWidget(0)
   195       , usesDoubleBufferedGLContext(0)
   200       , usesDoubleBufferedGLContext(0)
   196 #if defined(Q_WS_X11)
   201 #if defined(Q_WS_X11)
   197       , picture(0)
   202       , picture(0)
   198 #elif defined(Q_WS_WIN)
   203 #elif defined(Q_WS_WIN)
   199       , noPaintOnScreen(0)
   204       , noPaintOnScreen(0)
   200       , nativeGesturePanEnabled(0)
   205       , nativeGesturePanEnabled(0)
   201 #elif defined(Q_WS_MAC)
   206 #elif defined(Q_WS_MAC)
   202       , needWindowChange(0)
   207       , needWindowChange(0)
   203       , isGLWidget(0)
       
   204       , window_event(0)
   208       , window_event(0)
   205       , qd_hd(0)
   209       , qd_hd(0)
   206 #endif
   210 #endif
   207 {
   211 {
   208     if (!qApp) {
   212     if (!qApp) {
  1437         qApp->d_func()->sendSyntheticEnterLeave(this);
  1441         qApp->d_func()->sendSyntheticEnterLeave(this);
  1438 #endif
  1442 #endif
  1439     }
  1443     }
  1440 #endif
  1444 #endif
  1441 
  1445 
       
  1446 #ifdef Q_OS_SYMBIAN
       
  1447     if (d->extra && d->extra->topextra && d->extra->topextra->backingStore) {
       
  1448         // Okay, we are about to destroy the top-level window that owns
       
  1449         // the backing store. Make sure we delete the backing store right away
       
  1450         // before the window handle is invalid. This is important because
       
  1451         // the backing store will delete its window surface, which may or may
       
  1452         // not have a reference to this widget that will be used later to
       
  1453         // notify the window it no longer has a surface.
       
  1454         delete d->extra->topextra->backingStore;
       
  1455         d->extra->topextra->backingStore = 0;
       
  1456     }
       
  1457 #endif
  1442     if (QWidgetBackingStore *bs = d->maybeBackingStore()) {
  1458     if (QWidgetBackingStore *bs = d->maybeBackingStore()) {
  1443         bs->removeDirtyWidget(this);
  1459         bs->removeDirtyWidget(this);
  1444         if (testAttribute(Qt::WA_StaticContents))
  1460         if (testAttribute(Qt::WA_StaticContents))
  1445             bs->removeStaticWidget(this);
  1461             bs->removeStaticWidget(this);
  1446     }
  1462     }
  1658 {
  1674 {
  1659     if (paintOnScreen()) {
  1675     if (paintOnScreen()) {
  1660         repaint_sys(dirty);
  1676         repaint_sys(dirty);
  1661         dirty = QRegion();
  1677         dirty = QRegion();
  1662     } else if (QWidgetBackingStore *bs = maybeBackingStore()) {
  1678     } else if (QWidgetBackingStore *bs = maybeBackingStore()) {
       
  1679 #ifdef QT_MAC_USE_COCOA
       
  1680         Q_UNUSED(bs);
       
  1681         void qt_mac_set_needs_display(QWidget *, QRegion);
       
  1682         qt_mac_set_needs_display(q_func(), QRegion());
       
  1683 #else
  1663         bs->sync();
  1684         bs->sync();
       
  1685 #endif
  1664     }
  1686     }
  1665 }
  1687 }
  1666 
  1688 
  1667 void QWidgetPrivate::syncBackingStore(const QRegion &region)
  1689 void QWidgetPrivate::syncBackingStore(const QRegion &region)
  1668 {
  1690 {
  1669     if (paintOnScreen())
  1691     if (paintOnScreen())
  1670         repaint_sys(region);
  1692         repaint_sys(region);
  1671     else if (QWidgetBackingStore *bs = maybeBackingStore())
  1693     else if (QWidgetBackingStore *bs = maybeBackingStore()) {
       
  1694 #ifdef QT_MAC_USE_COCOA
       
  1695         Q_UNUSED(bs);
       
  1696         void qt_mac_set_needs_display(QWidget *, QRegion);
       
  1697         qt_mac_set_needs_display(q_func(), region);
       
  1698 #else
  1672         bs->sync(q_func(), region);
  1699         bs->sync(q_func(), region);
       
  1700 #endif
       
  1701     }
  1673 }
  1702 }
  1674 
  1703 
  1675 void QWidgetPrivate::setUpdatesEnabled_helper(bool enable)
  1704 void QWidgetPrivate::setUpdatesEnabled_helper(bool enable)
  1676 {
  1705 {
  1677     Q_Q(QWidget);
  1706     Q_Q(QWidget);
  6092     if (QWExtra *topData = window()->d_func()->extra) {
  6121     if (QWExtra *topData = window()->d_func()->extra) {
  6093         if (topData->proxyWidget && topData->proxyWidget->hasFocus()) {
  6122         if (topData->proxyWidget && topData->proxyWidget->hasFocus()) {
  6094             previousProxyFocus = topData->proxyWidget->widget()->focusWidget();
  6123             previousProxyFocus = topData->proxyWidget->widget()->focusWidget();
  6095             if (previousProxyFocus && previousProxyFocus->focusProxy())
  6124             if (previousProxyFocus && previousProxyFocus->focusProxy())
  6096                 previousProxyFocus = previousProxyFocus->focusProxy();
  6125                 previousProxyFocus = previousProxyFocus->focusProxy();
       
  6126             if (previousProxyFocus == this && !topData->proxyWidget->d_func()->proxyIsGivingFocus)
       
  6127                 return;
  6097         }
  6128         }
  6098     }
  6129     }
  6099 #endif
  6130 #endif
  6100 
  6131 
  6101     QWidget *w = f;
  6132     QWidget *w = f;
  6412             }
  6443             }
  6413         }
  6444         }
  6414         first = fp;
  6445         first = fp;
  6415     }
  6446     }
  6416 
  6447 
       
  6448     if (fp == second)
       
  6449         return;
  6417 
  6450 
  6418     if (QWidget *sp = second->focusProxy())
  6451     if (QWidget *sp = second->focusProxy())
  6419         second = sp;
  6452         second = sp;
  6420 
  6453 
  6421 //    QWidget *fp = first->d_func()->focus_prev;
  6454 //    QWidget *fp = first->d_func()->focus_prev;
  7502     QList<QObject*> childList = children;
  7535     QList<QObject*> childList = children;
  7503     for (int i = 0; i < childList.size(); ++i) {
  7536     for (int i = 0; i < childList.size(); ++i) {
  7504         QWidget *widget = qobject_cast<QWidget*>(childList.at(i));
  7537         QWidget *widget = qobject_cast<QWidget*>(childList.at(i));
  7505         if (!widget || widget->isWindow() || widget->testAttribute(Qt::WA_WState_Hidden))
  7538         if (!widget || widget->isWindow() || widget->testAttribute(Qt::WA_WState_Hidden))
  7506             continue;
  7539             continue;
       
  7540 #ifdef QT_MAC_USE_COCOA
       
  7541         // Before doing anything we need to make sure that we don't leave anything in a non-consistent state.
       
  7542         // When hiding a widget we need to make sure that no mouse_down events are active, because
       
  7543         // the mouse_up event will never be received by a hidden widget or one of its descendants.
       
  7544         // The solution is simple, before going through with this we check if there are any mouse_down events in
       
  7545         // progress, if so we check if it is related to this widget or not. If so, we just reset the mouse_down and
       
  7546         // then we continue.
       
  7547         // In X11 and Windows we send a mouse_release event, however we don't do that here because we were already
       
  7548         // ignoring that from before. I.e. Carbon did not send the mouse release event, so we will not send the
       
  7549         // mouse release event. There are two ways to interpret this:
       
  7550         // 1. If we don't send the mouse release event, the widget might get into an inconsistent state, i.e. it
       
  7551         // might be waiting for a release event that will never arrive.
       
  7552         // 2. If we send the mouse release event, then the widget might decide to trigger an action that is not
       
  7553         // supposed to trigger because it is not visible.
       
  7554         if(widget == qt_button_down)
       
  7555             qt_button_down = 0;
       
  7556 #endif // QT_MAC_USE_COCOA
  7507         if (spontaneous)
  7557         if (spontaneous)
  7508             widget->setAttribute(Qt::WA_Mapped, false);
  7558             widget->setAttribute(Qt::WA_Mapped, false);
  7509         else
  7559         else
  7510             widget->setAttribute(Qt::WA_WState_Visible, false);
  7560             widget->setAttribute(Qt::WA_WState_Visible, false);
  7511         widget->d_func()->hideChildren(spontaneous);
  7561         widget->d_func()->hideChildren(spontaneous);
  7896 inline void setDisabledStyle(QWidget *w, bool setStyle)
  7946 inline void setDisabledStyle(QWidget *w, bool setStyle)
  7897 {
  7947 {
  7898     // set/reset WS_DISABLED style.
  7948     // set/reset WS_DISABLED style.
  7899     if(w && w->isWindow() && w->isVisible() && w->isEnabled()) {
  7949     if(w && w->isWindow() && w->isVisible() && w->isEnabled()) {
  7900         LONG dwStyle = GetWindowLong(w->winId(), GWL_STYLE);
  7950         LONG dwStyle = GetWindowLong(w->winId(), GWL_STYLE);
       
  7951         LONG newStyle = dwStyle;
  7901         if (setStyle)
  7952         if (setStyle)
  7902             dwStyle |= WS_DISABLED;
  7953             newStyle |= WS_DISABLED;
  7903         else
  7954         else
  7904             dwStyle &= ~WS_DISABLED;
  7955             newStyle &= ~WS_DISABLED;
  7905         SetWindowLong(w->winId(), GWL_STYLE, dwStyle);
  7956         if (newStyle != dwStyle) {
  7906         // we might need to repaint in some situations (eg. menu)
  7957             SetWindowLong(w->winId(), GWL_STYLE, newStyle);
  7907         w->repaint();
  7958             // we might need to repaint in some situations (eg. menu)
       
  7959             w->repaint();
       
  7960         }
  7908     }
  7961     }
  7909 }
  7962 }
  7910 #endif
  7963 #endif
  7911 
  7964 
  7912 /*****************************************************************************
  7965 /*****************************************************************************
  8242             if (w && w->isVisible() && !w->isWindow())
  8295             if (w && w->isVisible() && !w->isWindow())
  8243                 QApplication::sendEvent(w, event);
  8296                 QApplication::sendEvent(w, event);
  8244         }
  8297         }
  8245 
  8298 
  8246 #ifdef QT_SOFTKEYS_ENABLED
  8299 #ifdef QT_SOFTKEYS_ENABLED
  8247         if (isWindow() && isActiveWindow())
  8300         if (isWindow())
  8248             QSoftKeyManager::updateSoftKeys();
  8301             QSoftKeyManager::updateSoftKeys();
  8249 #endif
  8302 #endif
  8250 
  8303 
  8251         break; }
  8304         break; }
  8252 
  8305 
 11597             }
 11650             }
 11598         }
 11651         }
 11599     }
 11652     }
 11600     return targetWidget;
 11653     return targetWidget;
 11601 }
 11654 }
       
 11655 
       
 11656 /*!
       
 11657     \internal
       
 11658 
       
 11659     Tells us if it there is currently a reachable widget by keypad navigation in
       
 11660     a certain \a orientation.
       
 11661     If no navigation is possible, occuring key events in that \a orientation may
       
 11662     be used to interact with the value in the focussed widget, even though it
       
 11663     currently has not the editFocus.
       
 11664 
       
 11665     \sa QWidgetPrivate::widgetInNavigationDirection(), QWidget::hasEditFocus()
       
 11666 */
       
 11667 bool QWidgetPrivate::canKeypadNavigate(Qt::Orientation orientation)
       
 11668 {
       
 11669     return orientation == Qt::Horizontal?
       
 11670             (QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionEast)
       
 11671                     || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionWest))
       
 11672             :(QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionNorth)
       
 11673                     || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionSouth));
       
 11674 }
       
 11675 /*!
       
 11676     \internal
       
 11677 
       
 11678     Checks, if the \a widget is inside a QTabWidget. If is is inside
       
 11679     one, left/right key events will be used to switch between tabs in keypad
       
 11680     navigation. If there is no QTabWidget, the horizontal key events can be used
       
 11681 to
       
 11682     interact with the value in the focussed widget, even though it currently has
       
 11683     not the editFocus.
       
 11684 
       
 11685     \sa QWidget::hasEditFocus()
       
 11686 */
       
 11687 bool QWidgetPrivate::inTabWidget(QWidget *widget)
       
 11688 {
       
 11689     for (QWidget *tabWidget = widget; tabWidget; tabWidget = tabWidget->parentWidget())
       
 11690         if (qobject_cast<const QTabWidget*>(tabWidget))
       
 11691             return true;
       
 11692     return false;
       
 11693 }
 11602 #endif
 11694 #endif
 11603 
 11695 
 11604 /*!
 11696 /*!
 11605     \preliminary
 11697     \preliminary
 11606     \since 4.2
 11698     \since 4.2