diff options
Diffstat (limited to 'src/gui/kernel/qwidget.cpp')
-rw-r--r-- | src/gui/kernel/qwidget.cpp | 167 |
1 files changed, 110 insertions, 57 deletions
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 63d31b5..d911b48 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) @@ -181,6 +183,7 @@ QWidgetPrivate::QWidgetPrivate(int version) : ,inDirtyList(0) ,isScrolled(0) ,isMoved(0) + ,usesDoubleBufferedGLContext(0) #ifdef Q_WS_WIN ,noPaintOnScreen(0) #endif @@ -234,28 +237,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 +310,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 +1385,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 +1400,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); } @@ -2142,6 +2133,10 @@ QWidget *QWidget::find(WId id) If a widget is non-native (alien) and winId() is invoked on it, that widget will be provided a native handle. + On Mac OS X, the type returned depends on which framework Qt was linked + against. If Qt is using Carbon, the {WId} is actually an HIViewRef. If Qt + is using Cocoa, {WId} is a pointer to an NSView. + \note We recommend that you do not store this value as it is likely to change at run-time. @@ -2244,9 +2239,10 @@ WId QWidget::effectiveWinId() const The style sheet contains a textual description of customizations to the widget's style, as described in the \l{Qt Style Sheets} document. - \note Qt style sheets are currently not supported for QMacStyle - (the default style on Mac OS X). We plan to address this in some future - release. + Since Qt 4.5, Qt style sheets fully supports Mac OS X. + + \warning Qt style sheets are currently not supported for custom QStyle + subclasses. We plan to address this in some future release. \sa setStyle(), QApplication::styleSheet, {Qt Style Sheets} */ @@ -4653,6 +4649,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 +4660,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) @@ -4715,10 +4714,13 @@ void QWidget::render(QPaintDevice *target, const QPoint &targetOffset, if (redirected) { target = redirected; offset -= redirectionOffset; - if (!inRenderWithPainter) { // Clip handled by shared painter (in qpainter.cpp). - const QRegion redirectedSystemClip = redirected->paintEngine()->systemClip(); - if (!redirectedSystemClip.isEmpty()) - paintRegion &= redirectedSystemClip.translated(-offset); + } + + if (!inRenderWithPainter) { // Clip handled by shared painter (in qpainter.cpp). + if (QPaintEngine *targetEngine = target->paintEngine()) { + const QRegion targetSystemClip = targetEngine->systemClip(); + if (!targetSystemClip.isEmpty()) + paintRegion &= targetSystemClip.translated(-offset); } } @@ -4803,7 +4805,7 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset, Q_ASSERT(engine); QPaintEnginePrivate *enginePriv = engine->d_func(); Q_ASSERT(enginePriv); - QPaintDevice *target = painter->worldMatrixEnabled() ? engine->paintDevice() : painter->device(); + QPaintDevice *target = engine->paintDevice(); Q_ASSERT(target); // Render via a pixmap when dealing with non-opaque painters or printers. @@ -4822,8 +4824,13 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset, const QRegion oldSystemClip = enginePriv->systemClip; const QRegion oldSystemViewport = enginePriv->systemViewport; - // This ensures that transformed system clips are inside the current system clip. - enginePriv->setSystemViewport(oldSystemClip); + // This ensures that all painting triggered by render() is clipped to the current engine clip. + if (painter->hasClipping()) { + const QRegion painterClip = painter->deviceTransform().map(painter->clipRegion()); + enginePriv->setSystemViewport(oldSystemClip.isEmpty() ? painterClip : oldSystemClip & painterClip); + } else { + enginePriv->setSystemViewport(oldSystemClip); + } render(target, targetOffset, toBePainted, renderFlags); @@ -5928,12 +5935,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 +8981,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 +9451,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 +9480,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 +9668,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 +9813,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 +11307,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() @@ -11393,3 +11432,17 @@ void QWidget::clearMask() setMask(QRegion()); } +/*! \fn const QX11Info &QWidget::x11Info() const + Returns information about the configuration of the X display used to display + the widget. + + \warning This function is only available on X11. +*/ + +/*! \fn Qt::HANDLE QWidget::x11PictureHandle() const + Returns the X11 Picture handle of the widget for XRender + support. Use of this function is not portable. This function will + return 0 if XRender support is not compiled into Qt, if the + XRender extension is not supported on the X11 display, or if the + handle could not be created. +*/ |