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 ®ion) |
1689 void QWidgetPrivate::syncBackingStore(const QRegion ®ion) |
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; |
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 /***************************************************************************** |
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 |