summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qwidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel/qwidget.cpp')
-rw-r--r--src/gui/kernel/qwidget.cpp119
1 files changed, 72 insertions, 47 deletions
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 63d31b5..31fed5e 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -66,6 +66,7 @@
#ifdef Q_WS_MAC
# include "qt_mac_p.h"
# include "qt_cocoa_helpers_mac_p.h"
+# include "qmainwindow.h"
#endif
#if defined(Q_WS_QWS)
# include "qwsdisplay_qws.h"
@@ -164,6 +165,7 @@ static inline bool bypassGraphicsProxyWidget(QWidget *p)
#endif
extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp
+extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp
QWidgetPrivate::QWidgetPrivate(int version) :
QObjectPrivate(version), extra(0), focus_child(0)
@@ -234,28 +236,6 @@ QWindowSurface *QWidgetPrivate::createDefaultWindowSurface()
/*!
\internal
- This is an internal function, you should never call this.
-
- This function is called to focus associated input context. The
- code intends to eliminate duplicate focus for the context even if
- the context is shared between widgets
-
- \sa QInputContext::setFocus()
- */
-void QWidgetPrivate::focusInputContext()
-{
-#ifndef QT_NO_IM
- Q_Q(QWidget);
- QInputContext *qic = q->inputContext();
- if (qic) {
- if(qic->focusWidget() != q)
- qic->setFocusWidget(q);
- }
-#endif // QT_NO_IM
-}
-
-/*!
- \internal
*/
void QWidgetPrivate::scrollChildren(int dx, int dy)
{
@@ -329,20 +309,24 @@ void QWidget::setInputContext(QInputContext *context)
/*!
+ \obsolete
+
This function can be called on the widget that currently has focus
to reset the input method operating on it.
- \sa QInputContext, QInputContext::reset()
+ This function is providing for convenience, instead you should use
+ \l{QInputContext::}{reset()} on the input context that was
+ returned by inputContext().
+
+ \sa QInputContext, inputContext(), QInputContext::reset()
*/
void QWidget::resetInputContext()
{
if (!hasFocus())
return;
#ifndef QT_NO_IM
- if (!d_func()->ic)
- return;
QInputContext *qic = this->inputContext();
- if( qic )
+ if(qic)
qic->reset();
#endif // QT_NO_IM
}
@@ -1400,7 +1384,13 @@ int QWidgetPrivate::maxInstances = 0; // Maximum number of widget instances
void QWidgetPrivate::setWinId(WId id) // set widget identifier
{
Q_Q(QWidget);
- if (mapper && data.winid) {
+ // the user might create a widget with Qt::Desktop window
+ // attribute (or create another QDesktopWidget instance), which
+ // will have the same windowid (the root window id) as the
+ // qt_desktopWidget. We should not add the second desktop widget
+ // to the mapper.
+ bool userDesktopWidget = qt_desktopWidget != 0 && qt_desktopWidget != q && q->windowType() == Qt::Desktop;
+ if (mapper && data.winid && !userDesktopWidget) {
mapper->remove(data.winid);
uncreatedWidgets->insert(q);
}
@@ -1409,7 +1399,7 @@ void QWidgetPrivate::setWinId(WId id) // set widget identifier
#if defined(Q_WS_X11)
hd = id; // X11: hd == ident
#endif
- if (mapper && id) {
+ if (mapper && id && !userDesktopWidget) {
mapper->insert(data.winid, q);
uncreatedWidgets->remove(q);
}
@@ -4653,6 +4643,8 @@ void QWidget::unsetCursor()
*/
/*!
+ \since 4.3
+
Renders the \a sourceRegion of this widget into the \a target
using \a renderFlags to determine how to render. Rendering
starts at \a targetOffset in the \a target. For example:
@@ -4662,12 +4654,13 @@ void QWidget::unsetCursor()
If \a sourceRegion is a null region, this function will use QWidget::rect() as
the region, i.e. the entire widget.
- \bold{Note:} Make sure to call QPainter::end() for the given \a target's
+ Ensure that you call QPainter::end() for the \a target device's
active painter (if any) before rendering. For example:
\snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 8
- \since 4.3
+ \note To obtain the contents of an OpenGL widget, use QGLWidget::grabFrameBuffer()
+ or QGLWidget::renderPixmap() instead.
*/
void QWidget::render(QPaintDevice *target, const QPoint &targetOffset,
const QRegion &sourceRegion, RenderFlags renderFlags)
@@ -5928,12 +5921,12 @@ bool QWidget::isActiveWindow() const
return true;
#endif
if(style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, this)) {
- if(((tlw->windowType() == Qt::Dialog) || (tlw->windowType() == Qt::Tool)) &&
+ if(tlw->windowType() == Qt::Tool &&
!tlw->isModal() &&
(!tlw->parentWidget() || tlw->parentWidget()->isActiveWindow()))
return true;
QWidget *w = qApp->activeWindow();
- while(w && ((tlw->windowType() == Qt::Dialog) || (tlw->windowType() == Qt::Tool)) &&
+ while(w && tlw->windowType() == Qt::Tool &&
!w->isModal() && w->parentWidget()) {
w = w->parentWidget()->window();
if(w == tlw)
@@ -8974,17 +8967,36 @@ QWidget *QWidget::childAt(const QPoint &p) const
QWidget *QWidgetPrivate::childAt_helper(const QPoint &p, bool ignoreChildrenInDestructor) const
{
Q_Q(const QWidget);
- if (!q->rect().contains(p))
+#ifdef Q_WS_MAC
+ bool includeFrame = q->isWindow() && qobject_cast<const QMainWindow *>(q)
+ && static_cast<const QMainWindow *>(q)->unifiedTitleAndToolBarOnMac();
+#endif
+
+ if (
+#ifdef Q_WS_MAC
+ !includeFrame &&
+#endif
+ !q->rect().contains(p))
return 0;
+
for (int i = children.size(); i > 0 ;) {
--i;
QWidget *w = qobject_cast<QWidget *>(children.at(i));
- if (w && !w->isWindow() && !w->isHidden() && w->geometry().contains(p)) {
+ if (w && !w->isWindow() && !w->isHidden()
+ && (w->geometry().contains(p)
+#ifdef Q_WS_MAC
+ || (includeFrame && w->geometry().contains(qt_mac_nativeMapFromParent(w, p)))
+#endif
+ )) {
if (ignoreChildrenInDestructor && w->data->in_destructor)
continue;
if (w->testAttribute(Qt::WA_TransparentForMouseEvents))
continue;
QPoint childPoint = w->mapFromParent(p);
+#ifdef Q_WS_MAC
+ if (includeFrame && !w->geometry().contains(p))
+ childPoint = qt_mac_nativeMapFromParent(w, p);
+#endif
if (QWidget *t = w->d_func()->childAt_helper(childPoint, ignoreChildrenInDestructor))
return t;
// if WMouseNoMask is set the widget mask is ignored, if
@@ -9425,11 +9437,13 @@ void QWidget::repaint(const QRect &rect)
if (!isVisible() || !updatesEnabled() || rect.isEmpty())
return;
- QTLWExtra *tlwExtra = !d->paintOnScreen() ? window()->d_func()->maybeTopData() : 0;
- if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) {
- tlwExtra->inRepaint = true;
- tlwExtra->backingStore->markDirty(rect, this, true);
- tlwExtra->inRepaint = false;
+ if (hasBackingStoreSupport()) {
+ QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
+ if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) {
+ tlwExtra->inRepaint = true;
+ tlwExtra->backingStore->markDirty(rect, this, true);
+ tlwExtra->inRepaint = false;
+ }
} else {
d->repaint_sys(rect);
}
@@ -9452,11 +9466,13 @@ void QWidget::repaint(const QRegion &rgn)
if (!isVisible() || !updatesEnabled() || rgn.isEmpty())
return;
- QTLWExtra *tlwExtra = !d->paintOnScreen() ? window()->d_func()->maybeTopData() : 0;
- if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) {
- tlwExtra->inRepaint = true;
- tlwExtra->backingStore->markDirty(rgn, this, true);
- tlwExtra->inRepaint = false;
+ if (hasBackingStoreSupport()) {
+ QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
+ if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) {
+ tlwExtra->inRepaint = true;
+ tlwExtra->backingStore->markDirty(rgn, this, true);
+ tlwExtra->inRepaint = false;
+ }
} else {
d->repaint_sys(rgn);
}
@@ -9638,7 +9654,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
"QWidgetPrivate::high_attributes[] too small to contain all attributes in WidgetAttribute");
#ifdef Q_WS_WIN
- if (attribute == Qt::WA_PaintOnScreen) {
+ if (attribute == Qt::WA_PaintOnScreen && on) {
// see qwidget_win.cpp, ::paintEngine for details
paintEngine();
if (d->noPaintOnScreen)
@@ -9783,12 +9799,21 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
}
break;
#endif
- case Qt::WA_NativeWindow:
+ case Qt::WA_NativeWindow: {
+ QInputContext *ic = 0;
+ if (on && !internalWinId() && testAttribute(Qt::WA_InputMethodEnabled) && hasFocus()) {
+ ic = d->inputContext();
+ ic->reset();
+ ic->setFocusWidget(0);
+ }
if (!qApp->testAttribute(Qt::AA_DontCreateNativeWidgetSiblings) && parentWidget())
parentWidget()->d_func()->enforceNativeChildren();
if (on && !internalWinId() && testAttribute(Qt::WA_WState_Created))
d->createWinId();
+ if (ic)
+ ic->setFocusWidget(this);
break;
+ }
case Qt::WA_PaintOnScreen:
d->updateIsOpaque();
#if defined(Q_WS_WIN) || defined(Q_WS_X11)
@@ -11268,7 +11293,7 @@ QT_END_NAMESPACE
currently the active one then it will not make it the active
window. It will change the color of the taskbar entry to indicate
that the window has changed in some way. This is because Microsoft
- do not allow an application to interrupt what the user is currently
+ does not allow an application to interrupt what the user is currently
doing in another application.
\sa isActiveWindow(), window(), show()