diff options
21 files changed, 531 insertions, 78 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index c54ddd0..1998ccf 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -154,7 +154,6 @@ void QDeclarativeFlickablePrivate::init() */ qreal QDeclarativeFlickablePrivate::overShootDistance(qreal velocity, qreal size) { - Q_Q(QDeclarativeFlickable); if (maxVelocity <= 0) return 0.0; diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp index cd72ef9..693fd20 100644 --- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp @@ -1268,7 +1268,6 @@ void QDeclarativeVisualDataModel::_q_dataChanged(const QModelIndex &begin, const void QDeclarativeVisualDataModel::_q_modelReset() { - Q_D(QDeclarativeVisualDataModel); emit modelReset(); } diff --git a/src/declarative/qml/qdeclarativelist.h b/src/declarative/qml/qdeclarativelist.h index 8d59384..eac4967 100644 --- a/src/declarative/qml/qdeclarativelist.h +++ b/src/declarative/qml/qdeclarativelist.h @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) class QObject; -class QMetaObject; +struct QMetaObject; template<typename T> struct QDeclarativeListProperty { typedef void (*AppendFunction)(QDeclarativeListProperty<T> *, T*); diff --git a/src/declarative/util/qdeclarativetimeline_p_p.h b/src/declarative/util/qdeclarativetimeline_p_p.h index c08c07c..598c897 100644 --- a/src/declarative/util/qdeclarativetimeline_p_p.h +++ b/src/declarative/util/qdeclarativetimeline_p_p.h @@ -160,7 +160,7 @@ public: QDeclarativeTimeLineObject *callbackObject() const; private: - friend class QDeclarativeTimeLinePrivate; + friend struct QDeclarativeTimeLinePrivate; Callback d0; void *d1; QDeclarativeTimeLineObject *d2; diff --git a/src/declarative/util/qdeclarativeview.h b/src/declarative/util/qdeclarativeview.h index 03d8db3..107f3f9 100644 --- a/src/declarative/util/qdeclarativeview.h +++ b/src/declarative/util/qdeclarativeview.h @@ -43,6 +43,7 @@ #define QDECLARATIVEVIEW_H #include <QtCore/qdatetime.h> +#include <QtCore/qurl.h> #include <QtGui/qgraphicssceneevent.h> #include <QtGui/qgraphicsview.h> #include <QtGui/qwidget.h> @@ -64,7 +65,8 @@ class Q_DECLARATIVE_EXPORT QDeclarativeView : public QGraphicsView Q_OBJECT Q_PROPERTY(ResizeMode resizeMode READ resizeMode WRITE setResizeMode) Q_PROPERTY(Status status READ status NOTIFY statusChanged) - + Q_PROPERTY(QUrl source READ source WRITE setSource DESIGNABLE true) + Q_ENUMS(ResizeMode Status) public: explicit QDeclarativeView(QWidget *parent = 0); QDeclarativeView(const QUrl &source, QWidget *parent = 0); diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 365afdd..6bc02cc 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -5972,12 +5972,12 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) QList<QGesture *> allGestures = event->gestures(); DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" - << "Delivering gestures:" << allGestures; + << "Gestures:" << allGestures; QSet<QGesture *> startedGestures; - QPoint delta = graphicsView->mapFromGlobal(QPoint()); - QTransform toScene = QTransform::fromTranslate(delta.x(), delta.y()) - * graphicsView->viewportTransform().inverted(); + QPoint delta = viewport->mapFromGlobal(QPoint()); + QTransform toScene = QTransform::fromTranslate(delta.x(), delta.y()) + * graphicsView->viewportTransform().inverted(); foreach (QGesture *gesture, allGestures) { // cache scene coordinates of the hot spot if (gesture->hasHotSpot()) { @@ -6003,7 +6003,8 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) cachedTargetItems = cachedItemGestures.keys(); qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst); DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" - << "Conflicting gestures:" << conflictedGestures; + << "Normal gestures:" << normalGestures + << "Conflicting gestures:" << conflictedGestures; // deliver conflicted gestures as override events AND remember // initial gesture targets @@ -6080,6 +6081,10 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) const Qt::GestureFlags flags = d->gestureContext.value(gesture->gestureType()); if (flags & Qt::IgnoredGesturesPropagateToParent) parentPropagatedGestures.insert(gesture); + } else { + DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" + << "no target for" << gesture << "at" + << gesture->hotSpot() << gesture->d_func()->sceneHotSpot; } } qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst); diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 4ec2ae2..203f637 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -498,9 +498,7 @@ inline bool QApplicationPrivate::isAlien(QWidget *widget) { if (!widget) return false; -#if defined(Q_WS_MAC) // Fake alien behavior on the Mac :) - return !widget->isWindow() && widget->window()->testAttribute(Qt::WA_DontShowOnScreen); -#elif defined(Q_WS_QWS) +#if defined(Q_WS_QWS) return !widget->isWindow() # ifdef Q_BACKINGSTORE_SUBSURFACES && !(widget->d_func()->maybeTopData() && widget->d_func()->maybeTopData()->windowSurface) @@ -3013,7 +3011,7 @@ bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event, return result; } -#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_MAC) /* This function should only be called when the widget changes visibility, i.e. when the \a widget is shown, hidden or deleted. This function does nothing @@ -3073,7 +3071,7 @@ void QApplicationPrivate::sendSyntheticEnterLeave(QWidget *widget) sendMouseEvent(widgetUnderCursor, &e, widgetUnderCursor, tlw, &qt_button_down, qt_last_mouse_receiver); #endif // QT_NO_CURSOR } -#endif // Q_WS_WIN || Q_WS_X11 +#endif // Q_WS_WIN || Q_WS_X11 || Q_WS_MAC /*! Returns the desktop widget (also called the root window). diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index babfc72..c7d0e48 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -184,7 +184,8 @@ bool qt_mac_app_fullscreen = false; bool qt_scrollbar_jump_to_pos = false; static bool qt_mac_collapse_on_dblclick = true; extern int qt_antialiasing_threshold; // from qapplication.cpp -QPointer<QWidget> qt_button_down; // widget got last button-down +QWidget * qt_button_down; // widget got last button-down +QPointer<QWidget> qt_last_mouse_receiver; #ifndef QT_MAC_USE_COCOA static bool qt_button_down_in_content; // whether the button_down was in the content area. static bool qt_mac_previous_press_in_popup_mode = false; diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index e0a6103..8653dec 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -514,7 +514,7 @@ public: int symbianResourceChange(const QSymbianEvent *symbianEvent); #endif -#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) void sendSyntheticEnterLeave(QWidget *widget); #endif diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 6a16403..a1dcc2a 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -185,6 +185,9 @@ extern "C" { extern NSString *NSTextInputReplacementRangeAttributeName; } +#ifdef ALIEN_DEBUG +static int qCocoaViewCount = 0; +#endif @implementation QT_MANGLE_NAMESPACE(QCocoaView) @@ -195,6 +198,12 @@ extern "C" { [self finishInitWithQWidget:widget widgetPrivate:widgetprivate]; } composingText = new QString(); + +#ifdef ALIEN_DEBUG + ++qCocoaViewCount; + qDebug() << "init: qCocoaViewCount is" << qCocoaViewCount; +#endif + composing = false; sendKeyEvents = true; [self setHidden:YES]; @@ -414,6 +423,12 @@ extern "C" { { delete composingText; [[NSNotificationCenter defaultCenter] removeObserver:self]; + +#ifdef ALIEN_DEBUG + --qCocoaViewCount; + qDebug() << "qCocoaViewCount is" << qCocoaViewCount; +#endif + [super dealloc]; } @@ -523,6 +538,10 @@ extern "C" { CGContextClearRect(cg, NSRectToCGRect(aRect)); } + // Check for alien widgets, use qwidgetPrivate->drawWidget() to draw the widget if this + // is the case. This makes sure child widgets are drawn as well, Cocoa does not know about + // those and wont send them drawRect calls. + if (qwidget->testAttribute(Qt::WA_NativeWindow) && qt_widget_private(qwidget)->hasAlienChildren == false) { if (engine && !qwidget->testAttribute(Qt::WA_NoSystemBackground) && (qwidget->isWindow() || qwidget->autoFillBackground()) || qwidget->testAttribute(Qt::WA_TintedBackground) @@ -542,6 +561,12 @@ extern "C" { e.setErased(true); #endif qt_sendSpontaneousEvent(qwidget, &e); + } else { + qwidget->setAttribute(Qt::WA_WState_InPaintEvent, false); // QWidgetPrivate::drawWidget sets this + QWidgetPrivate *qwidgetPrivate = qt_widget_private(qwidget); + qwidgetPrivate->drawWidget(qwidget, qrgn, QPoint(), QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawPaintOnScreen | QWidgetPrivate::DrawRecursive, 0); + } + if (!redirectionOffset.isNull()) QPainter::restoreRedirected(qwidget); if (engine) diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index 9560952..19bae5a 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -139,7 +139,7 @@ void QMacWindowFader::performFade() extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); // qapplication.cpp; extern QWidget * mac_mouse_grabber; -extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp +extern QWidget *qt_button_down; //qapplication_mac.cpp void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds) { @@ -686,6 +686,12 @@ bool qt_dispatchKeyEvent(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEve if ([event type] == NSKeyDown) { qt_keymapper_private()->updateKeyMap(0, key_event, 0); } + + // Redirect keys to alien widgets. + if (widgetToGetEvent->testAttribute(Qt::WA_NativeWindow) == false) { + widgetToGetEvent = qApp->focusWidget(); + } + if (widgetToGetEvent == 0) return false; @@ -940,7 +946,7 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev [static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(tmpView) qt_qwidget]; } } else { - extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp + extern QWidget * qt_button_down; //qapplication_mac.cpp QPoint pos; widgetToGetMouse = QApplicationPrivate::pickMouseReceiver(qwidget, qglobalPoint, pos, eventType, @@ -952,7 +958,20 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev return false; NSPoint localPoint = [tmpView convertPoint:windowPoint fromView:nil]; - QPoint qlocalPoint(localPoint.x, localPoint.y); + QPoint qlocalPoint = QPoint(localPoint.x, localPoint.y); + + // Search for alien child widgets (either on this qwidget or on the popup) + if (widgetToGetMouse->testAttribute(Qt::WA_NativeWindow) == false || qt_widget_private(widgetToGetMouse)->hasAlienChildren) { + QPoint qScreenPoint = flipPoint(globalPoint).toPoint(); +#ifdef ALIEN_DEBUG + qDebug() << "alien mouse event" << qScreenPoint << possibleAlien; +#endif + QWidget *possibleAlien = widgetToGetMouse->childAt(qlocalPoint); + if (possibleAlien) { + qlocalPoint = possibleAlien->mapFromGlobal(widgetToGetMouse->mapToGlobal(qlocalPoint)); + widgetToGetMouse = possibleAlien; + } + } EventRef carbonEvent = static_cast<EventRef>(const_cast<void *>([theEvent eventRef])); if (qt_mac_sendMacEventToWidget(widgetToGetMouse, carbonEvent)) @@ -997,7 +1016,19 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev } [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->localPoint = localPoint; QMouseEvent qme(eventType, qlocalPoint, qglobalPoint, button, buttons, keyMods); - qt_sendSpontaneousEvent(widgetToGetMouse, &qme); + +#ifdef ALIEN_DEBUG + qDebug() << "sending mouse event to" << widgetToGetMouse; +#endif + extern QWidget *qt_button_down; + extern QPointer<QWidget> qt_last_mouse_receiver; + + if (qwidget->testAttribute(Qt::WA_NativeWindow) && qt_widget_private(qwidget)->hasAlienChildren == false) + qt_sendSpontaneousEvent(widgetToGetMouse, &qme); + else + QApplicationPrivate::sendMouseEvent(widgetToGetMouse, &qme, widgetToGetMouse, qwidget, &qt_button_down, + qt_last_mouse_receiver); + if (eventType == QEvent::MouseButtonPress && button == Qt::RightButton) { QContextMenuEvent qcme(QContextMenuEvent::Mouse, qlocalPoint, qglobalPoint, keyMods); qt_sendSpontaneousEvent(widgetToGetMouse, &qcme); diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 2f6ec6b..b19d541 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -205,6 +205,7 @@ QWidgetPrivate::QWidgetPrivate(int version) , nativeGesturePanEnabled(0) #elif defined(Q_WS_MAC) , needWindowChange(0) + , hasAlienChildren(0) , window_event(0) , qd_hd(0) #endif @@ -1168,6 +1169,10 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f) if (f & Qt::MSWindowsOwnDC) q->setAttribute(Qt::WA_NativeWindow); +#ifdef Q_WS_MAC + q->setAttribute(Qt::WA_NativeWindow); +#endif + q->setAttribute(Qt::WA_QuitOnClose); // might be cleared in adjustQuitOnCloseAttribute() adjustQuitOnCloseAttribute(); @@ -1263,6 +1268,10 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow) } if (QWidget *parent = parentWidget()) { +#ifdef Q_WS_MAC + if (testAttribute(Qt::WA_NativeWindow) == false) + parent->d_func()->hasAlienChildren = true; +#endif if (type & Qt::Window) { if (!parent->testAttribute(Qt::WA_WState_Created)) parent->createWinId(); @@ -1433,7 +1442,7 @@ QWidget::~QWidget() } } -#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) else if (!internalWinId() && isVisible()) { qApp->d_func()->sendSyntheticEnterLeave(this); #ifdef Q_WS_QWS @@ -2306,6 +2315,9 @@ QWidget *QWidget::find(WId id) WId QWidget::winId() const { if (!testAttribute(Qt::WA_WState_Created) || !internalWinId()) { +#ifdef ALIEN_DEBUG + qDebug() << "QWidget::winId: creating native window for" << this; +#endif QWidget *that = const_cast<QWidget*>(this); that->setAttribute(Qt::WA_NativeWindow); that->d_func()->createWinId(); @@ -2318,6 +2330,10 @@ WId QWidget::winId() const void QWidgetPrivate::createWinId(WId winid) { Q_Q(QWidget); + +#ifdef ALIEN_DEBUG + qDebug() << "QWidgetPrivate::createWinId for" << q << winid; +#endif const bool forceNativeWindow = q->testAttribute(Qt::WA_NativeWindow); if (!q->testAttribute(Qt::WA_WState_Created) || (forceNativeWindow && !q->internalWinId())) { if (!q->isWindow()) { @@ -2360,6 +2376,9 @@ Ensures that the widget has a window system identifier, i.e. that it is known to void QWidget::createWinId() { Q_D(QWidget); +#ifdef ALIEN_DEBUG + qDebug() << "QWidget::createWinId" << this; +#endif // qWarning("QWidget::createWinId is obsolete, please fix your code."); d->createWinId(); } @@ -5249,7 +5268,15 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP QPaintEngine *paintEngine = pdev->paintEngine(); if (paintEngine) { setRedirected(pdev, -offset); +#ifdef Q_WS_MAC + // (Alien support) Special case for Mac when redirecting: If the paint device + // is of the Widget type we need to set WA_WState_InPaintEvent since painting + // outside the paint event is not supported on QWidgets. The attributeis + // restored further down. + if (pdev->devType() == QInternal::Widget) + static_cast<QWidget *>(pdev)->setAttribute(Qt::WA_WState_InPaintEvent); +#endif if (sharedPainter) paintEngine->d_func()->systemClip = toBePainted; else @@ -5290,6 +5317,10 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP //restore if (paintEngine) { +#ifdef Q_WS_MAC + if (pdev->devType() == QInternal::Widget) + static_cast<QWidget *>(pdev)->setAttribute(Qt::WA_WState_InPaintEvent, false); +#endif restoreRedirected(); if (!sharedPainter) paintEngine->d_func()->systemRect = QRect(); @@ -7322,7 +7353,7 @@ void QWidgetPrivate::hide_helper() // next bit tries to move the focus if the focus widget is now // hidden. if (wasVisible) { -#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) qApp->d_func()->sendSyntheticEnterLeave(q); #endif @@ -7454,7 +7485,7 @@ void QWidget::setVisible(bool visible) d->show_helper(); -#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) qApp->d_func()->sendSyntheticEnterLeave(this); #endif } @@ -7569,7 +7600,7 @@ void QWidgetPrivate::hideChildren(bool spontaneous) widget->d_func()->hide_sys(); } } -#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) qApp->d_func()->sendSyntheticEnterLeave(widget); #endif #ifndef QT_NO_ACCESSIBILITY @@ -9787,7 +9818,7 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f) desktopWidget = parent; bool newParent = (parent != parentWidget()) || !wasCreated || desktopWidget; -#if defined(Q_WS_X11) || defined(Q_WS_WIN) +#if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_MAC) if (newParent && parent && !desktopWidget) { if (testAttribute(Qt::WA_NativeWindow) && !qApp->testAttribute(Qt::AA_DontCreateNativeWidgetSiblings)) parent->d_func()->enforceNativeChildren(); @@ -10433,7 +10464,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) } case Qt::WA_PaintOnScreen: d->updateIsOpaque(); -#if defined(Q_WS_WIN) || defined(Q_WS_X11) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_MAC) // Recreate the widget if it's already created as an alien widget and // WA_PaintOnScreen is enabled. Paint on screen widgets must have win id. // So must their children. diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index dcb87fc..6d8c97b 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -459,7 +459,13 @@ static bool qt_isGenuineQWidget(OSViewRef ref) bool qt_isGenuineQWidget(const QWidget *window) { - return window && qt_isGenuineQWidget(OSViewRef(window->winId())); + if (!window) + return false; + + if (!window->internalWinId()) + return true; //alien + + return qt_isGenuineQWidget(OSViewRef(window->internalWinId())); } Q_GUI_EXPORT OSWindowRef qt_mac_window_for(const QWidget *w) @@ -2608,7 +2614,16 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO } } else { data.fstrut_dirty = false; // non-toplevel widgets don't have a frame, so no need to update the strut - if(OSViewRef osview = qt_mac_create_widget(q, this, qt_mac_nativeview_for(parentWidget))) { + +#ifdef QT_MAC_USE_COCOA + if (q->testAttribute(Qt::WA_NativeWindow) == false || + q->internalWinId() != 0) { +#ifdef ALIEN_DEBUG + qDebug() << "Skipping native widget creation for" << this; +#endif + } else +#endif + if (OSViewRef osview = qt_mac_create_widget(q, this, qt_mac_nativeview_for(parentWidget))) { #ifndef QT_MAC_USE_COCOA HIRect bounds = CGRectMake(data.crect.x(), data.crect.y(), data.crect.width(), data.crect.height()); HIViewSetFrame(osview, &bounds); @@ -2869,9 +2884,12 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f) q->setAttribute(Qt::WA_WState_Visible, false); q->setAttribute(Qt::WA_WState_Hidden, false); adjustFlags(data.window_flags, q); - // keep compatibility with previous versions, we need to preserve the created state - // (but we recreate the winId for the widget being reparented, again for compatibility) - if (wasCreated || (!q->isWindow() && parent->testAttribute(Qt::WA_WState_Created))) { + // keep compatibility with previous versions, we need to preserve the created state. + // (but we recreate the winId for the widget being reparented, again for compatibility, + // unless this is an alien widget. ) + const bool nonWindowWithCreatedParent = !q->isWindow() && parent->testAttribute(Qt::WA_WState_Created); + const bool nativeWidget = q->internalWinId() != 0; + if (wasCreated || nativeWidget && nonWindowWithCreatedParent) { createWinId(); if (q->isWindow()) { #ifndef QT_MAC_USE_COCOA @@ -2955,7 +2973,7 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f) QPoint QWidget::mapToGlobal(const QPoint &pos) const { Q_D(const QWidget); - if (!testAttribute(Qt::WA_WState_Created)) { + if (!testAttribute(Qt::WA_WState_Created) || !internalWinId()) { QPoint p = pos + data->crect.topLeft(); return isWindow() ? p : parentWidget()->mapToGlobal(p); } @@ -2982,7 +3000,7 @@ QPoint QWidget::mapToGlobal(const QPoint &pos) const QPoint QWidget::mapFromGlobal(const QPoint &pos) const { Q_D(const QWidget); - if (!testAttribute(Qt::WA_WState_Created)) { + if (!testAttribute(Qt::WA_WState_Created) || !internalWinId()) { QPoint p = isWindow() ? pos : parentWidget()->mapFromGlobal(pos); return p - data->crect.topLeft(); } @@ -3320,10 +3338,20 @@ void QWidgetPrivate::update_sys(const QRegion &rgn) } #else // Cocoa doesn't do regions, it seems more efficient to just update the bounding rect instead of a potential number of message passes for each rect. - const QRect &boundingRect = rgn.boundingRect(); - [qt_mac_nativeview_for(q) setNeedsDisplayInRect:NSMakeRect(boundingRect.x(), - boundingRect.y(), boundingRect.width(), - boundingRect.height())]; + const QRect & boundingRect = rgn.boundingRect(); + + // Alien support: get the first native ancestor widget (will be q itself in the non-alien case), + // map the coordinates from q space to NSView space and invalidate the rect. + QWidget *nativeParent = q->internalWinId() ? q : q->nativeParentWidget(); + if (nativeParent == 0) + return; + const QRect nativeBoundingRect = QRect( + QPoint(q->mapTo(nativeParent, boundingRect.topLeft())), + QSize(boundingRect.size())); + + [qt_mac_nativeview_for(nativeParent) setNeedsDisplayInRect:NSMakeRect(nativeBoundingRect.x(), + nativeBoundingRect.y(), nativeBoundingRect.width(), + nativeBoundingRect.height())]; #endif } diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index efd9a0a..2cb8586 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -720,6 +720,7 @@ public: #elif defined(Q_WS_MAC) // <--------------------------------------------------------- MAC // This is new stuff uint needWindowChange : 1; + uint hasAlienChildren : 1; // Each wiget keeps a list of all its child and grandchild OpenGL widgets. // This list is used to update the gl context whenever a parent and a granparent diff --git a/src/gui/text/qsyntaxhighlighter.cpp b/src/gui/text/qsyntaxhighlighter.cpp index 6750c09..28af5bb 100644 --- a/src/gui/text/qsyntaxhighlighter.cpp +++ b/src/gui/text/qsyntaxhighlighter.cpp @@ -59,23 +59,24 @@ class QSyntaxHighlighterPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QSyntaxHighlighter) public: - inline QSyntaxHighlighterPrivate() : rehighlightPending(false) {} + inline QSyntaxHighlighterPrivate() + : rehighlightPending(false), inReformatBlocks(false) + {} QPointer<QTextDocument> doc; void _q_reformatBlocks(int from, int charsRemoved, int charsAdded); - void reformatBlock(QTextBlock block); - + void reformatBlocks(int from, int charsRemoved, int charsAdded); + void reformatBlock(const QTextBlock &block); + inline void rehighlight(QTextCursor &cursor, QTextCursor::MoveOperation operation) { - QObject::disconnect(doc, SIGNAL(contentsChange(int,int,int)), - q_func(), SLOT(_q_reformatBlocks(int,int,int))); + inReformatBlocks = true; cursor.beginEditBlock(); int from = cursor.position(); cursor.movePosition(operation); - _q_reformatBlocks(from, 0, cursor.position() - from); + reformatBlocks(from, 0, cursor.position() - from); cursor.endEditBlock(); - QObject::connect(doc, SIGNAL(contentsChange(int,int,int)), - q_func(), SLOT(_q_reformatBlocks(int,int,int))); + inReformatBlocks = false; } inline void _q_delayedRehighlight() { @@ -83,17 +84,19 @@ public: return; rehighlightPending = false; q_func()->rehighlight(); - return; } void applyFormatChanges(); QVector<QTextCharFormat> formatChanges; QTextBlock currentBlock; bool rehighlightPending; + bool inReformatBlocks; }; void QSyntaxHighlighterPrivate::applyFormatChanges() { + bool formatsChanged = false; + QTextLayout *layout = currentBlock.layout(); QList<QTextLayout::FormatRange> ranges = layout->additionalFormats(); @@ -101,19 +104,23 @@ void QSyntaxHighlighterPrivate::applyFormatChanges() const int preeditAreaStart = layout->preeditAreaPosition(); const int preeditAreaLength = layout->preeditAreaText().length(); - QList<QTextLayout::FormatRange>::Iterator it = ranges.begin(); - while (it != ranges.end()) { - if (it->start >= preeditAreaStart - && it->start + it->length <= preeditAreaStart + preeditAreaLength) - ++it; - else - it = ranges.erase(it); + if (preeditAreaLength != 0) { + QList<QTextLayout::FormatRange>::Iterator it = ranges.begin(); + while (it != ranges.end()) { + if (it->start >= preeditAreaStart + && it->start + it->length <= preeditAreaStart + preeditAreaLength) { + ++it; + } else { + it = ranges.erase(it); + formatsChanged = true; + } + } } QTextCharFormat emptyFormat; QTextLayout::FormatRange r; - r.start = r.length = -1; + r.start = -1; int i = 0; while (i < formatChanges.count()) { @@ -135,34 +142,46 @@ void QSyntaxHighlighterPrivate::applyFormatChanges() r.length = i - r.start; - if (r.start >= preeditAreaStart) { - r.start += preeditAreaLength; - } else if (r.start + r.length >= preeditAreaStart) { - r.length += preeditAreaLength; + if (preeditAreaLength != 0) { + if (r.start >= preeditAreaStart) + r.start += preeditAreaLength; + else if (r.start + r.length >= preeditAreaStart) + r.length += preeditAreaLength; } ranges << r; - r.start = r.length = -1; + formatsChanged = true; + r.start = -1; } if (r.start != -1) { r.length = formatChanges.count() - r.start; - if (r.start >= preeditAreaStart) { - r.start += preeditAreaLength; - } else if (r.start + r.length >= preeditAreaStart) { - r.length += preeditAreaLength; + if (preeditAreaLength != 0) { + if (r.start >= preeditAreaStart) + r.start += preeditAreaLength; + else if (r.start + r.length >= preeditAreaStart) + r.length += preeditAreaLength; } ranges << r; + formatsChanged = true; } - layout->setAdditionalFormats(ranges); + if (formatsChanged) { + layout->setAdditionalFormats(ranges); + doc->markContentsDirty(currentBlock.position(), currentBlock.length()); + } } void QSyntaxHighlighterPrivate::_q_reformatBlocks(int from, int charsRemoved, int charsAdded) { - Q_UNUSED(charsRemoved); + if (!inReformatBlocks) + reformatBlocks(from, charsRemoved, charsAdded); +} + +void QSyntaxHighlighterPrivate::reformatBlocks(int from, int charsRemoved, int charsAdded) +{ rehighlightPending = false; QTextBlock block = doc->findBlock(from); @@ -191,21 +210,18 @@ void QSyntaxHighlighterPrivate::_q_reformatBlocks(int from, int charsRemoved, in formatChanges.clear(); } -void QSyntaxHighlighterPrivate::reformatBlock(QTextBlock block) +void QSyntaxHighlighterPrivate::reformatBlock(const QTextBlock &block) { Q_Q(QSyntaxHighlighter); Q_ASSERT_X(!currentBlock.isValid(), "QSyntaxHighlighter::reformatBlock()", "reFormatBlock() called recursively"); currentBlock = block; - QTextBlock previous = block.previous(); formatChanges.fill(QTextCharFormat(), block.length() - 1); q->highlightBlock(block.text()); applyFormatChanges(); - doc->markContentsDirty(block.position(), block.length()); - currentBlock = QTextBlock(); } @@ -349,8 +365,8 @@ void QSyntaxHighlighter::setDocument(QTextDocument *doc) if (d->doc) { connect(d->doc, SIGNAL(contentsChange(int,int,int)), this, SLOT(_q_reformatBlocks(int,int,int))); - QTimer::singleShot(0, this, SLOT(_q_delayedRehighlight())); d->rehighlightPending = true; + QTimer::singleShot(0, this, SLOT(_q_delayedRehighlight())); } } @@ -391,11 +407,16 @@ void QSyntaxHighlighter::rehighlight() void QSyntaxHighlighter::rehighlightBlock(const QTextBlock &block) { Q_D(QSyntaxHighlighter); - if (!d->doc) + if (!d->doc || !block.isValid() || block.document() != d->doc) return; + const bool rehighlightPending = d->rehighlightPending; + QTextCursor cursor(block); d->rehighlight(cursor, QTextCursor::EndOfBlock); + + if (rehighlightPending) + d->rehighlightPending = rehighlightPending; } /*! @@ -460,7 +481,6 @@ void QSyntaxHighlighter::rehighlightBlock(const QTextBlock &block) void QSyntaxHighlighter::setFormat(int start, int count, const QTextCharFormat &format) { Q_D(QSyntaxHighlighter); - if (start < 0 || start >= d->formatChanges.count()) return; @@ -628,7 +648,7 @@ QTextBlockUserData *QSyntaxHighlighter::currentBlockUserData() const \since 4.4 Returns the current text block. - */ +*/ QTextBlock QSyntaxHighlighter::currentBlock() const { Q_D(const QSyntaxHighlighter); diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp index 4620597..bdab6fb 100644 --- a/src/gui/widgets/qmainwindow.cpp +++ b/src/gui/widgets/qmainwindow.cpp @@ -1478,7 +1478,8 @@ void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool set) return; // ### Disable the unified toolbar when using anything but the native graphics system. - if (windowSurface()) + // ### Disable when using alien widgets as well + if (windowSurface() || testAttribute(Qt::WA_NativeWindow) == false) return; d->useHIToolBar = set; diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp index a2058cd..f8ecca3 100644 --- a/tests/auto/gestures/tst_gestures.cpp +++ b/tests/auto/gestures/tst_gestures.cpp @@ -58,7 +58,7 @@ static QPointF mapToGlobal(const QPointF &pt, QGraphicsItem *item, QGraphicsView *view) { - return view->mapToGlobal(view->mapFromScene(item->mapToScene(pt))); + return view->viewport()->mapToGlobal(view->mapFromScene(item->mapToScene(pt))); } class CustomGesture : public QGesture @@ -353,6 +353,8 @@ private slots: void deleteGestureTargetWidget(); void deleteGestureTargetItem_data(); void deleteGestureTargetItem(); + void viewportCoordinates(); + void partialGesturePropagation(); }; tst_Gestures::tst_Gestures() @@ -742,7 +744,6 @@ public: ignoredFinishedGestures.clear(); } -protected: QRectF boundingRect() const { return size; @@ -1771,7 +1772,6 @@ void tst_Gestures::panelStacksBehindParent() void tst_Gestures::deleteGestureTargetWidget() { - } void tst_Gestures::deleteGestureTargetItem_data() @@ -1857,5 +1857,97 @@ void tst_Gestures::deleteGestureTargetItem() sendCustomGesture(&event, item1, &scene); } +class GraphicsView : public QGraphicsView +{ +public: + GraphicsView(QGraphicsScene *scene, QWidget *parent = 0) + : QGraphicsView(scene, parent) + { + } + + using QGraphicsView::setViewportMargins; +}; + +// just making sure that even if the graphicsview has margins hotspot still +// works properly. It should use viewport for converting global coordinates to +// scene coordinates. +void tst_Gestures::viewportCoordinates() +{ + QGraphicsScene scene; + GraphicsView view(&scene); + view.setViewportMargins(10,20,15,25); + view.setWindowFlags(Qt::X11BypassWindowManagerHint); + + GestureItem *item1 = new GestureItem("item1"); + item1->grabGesture(CustomGesture::GestureType); + item1->size = QRectF(0, 0, 3, 3); + item1->setZValue(2); + scene.addItem(item1); + + view.show(); + QTest::qWaitForWindowShown(&view); + view.ensureVisible(scene.sceneRect()); + + view.viewport()->grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren); + + CustomEvent event; + event.hotSpot = mapToGlobal(item1->boundingRect().center(), item1, &view); + event.hasHotSpot = true; + sendCustomGesture(&event, item1, &scene); + QVERIFY(item1->gestureEventsReceived != 0); +} + +void tst_Gestures::partialGesturePropagation() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + view.setWindowFlags(Qt::X11BypassWindowManagerHint); + + GestureItem *item1 = new GestureItem("item1"); + item1->grabGesture(CustomGesture::GestureType); + item1->setZValue(8); + scene.addItem(item1); + + GestureItem *item2 = new GestureItem("item2[partial]"); + item2->grabGesture(CustomGesture::GestureType, Qt::ReceivePartialGestures); + item2->setZValue(6); + scene.addItem(item2); + + GestureItem *item3 = new GestureItem("item3"); + item3->grabGesture(CustomGesture::GestureType); + item3->setZValue(4); + scene.addItem(item3); + + GestureItem *item4 = new GestureItem("item4[partial]"); + item4->grabGesture(CustomGesture::GestureType, Qt::ReceivePartialGestures); + item4->setZValue(2); + scene.addItem(item4); + + view.show(); + QTest::qWaitForWindowShown(&view); + view.ensureVisible(scene.sceneRect()); + + view.viewport()->grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren); + + item1->ignoredUpdatedGestures << CustomGesture::GestureType; + + CustomEvent event; + event.hotSpot = mapToGlobal(QPointF(5, 5), item1, &view); + event.hasHotSpot = true; + sendCustomGesture(&event, item1, &scene); + + static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1; + + QCOMPARE(item1->gestureOverrideEventsReceived, 1); + QCOMPARE(item2->gestureOverrideEventsReceived, 1); + QCOMPARE(item3->gestureOverrideEventsReceived, 1); + QCOMPARE(item4->gestureOverrideEventsReceived, 1); + + QCOMPARE(item1->gestureEventsReceived, TotalGestureEventsCount); + QCOMPARE(item2->gestureEventsReceived, TotalGestureEventsCount-2); // except for started and finished + QCOMPARE(item3->gestureEventsReceived, 0); + QCOMPARE(item4->gestureEventsReceived, 0); +} + QTEST_MAIN(tst_Gestures) #include "tst_gestures.moc" diff --git a/tools/designer/src/plugins/plugins.pro b/tools/designer/src/plugins/plugins.pro index baf5261..cf4fa8a 100644 --- a/tools/designer/src/plugins/plugins.pro +++ b/tools/designer/src/plugins/plugins.pro @@ -7,3 +7,4 @@ win32:!contains(QT_EDITION, OpenSource):SUBDIRS += activeqt # contains(QT_CONFIG, opengl): SUBDIRS += tools/view3d contains(QT_CONFIG, webkit): SUBDIRS += qwebview contains(QT_CONFIG, phonon): SUBDIRS += phononwidgets +contains(QT_CONFIG, declarative): SUBDIRS += qdeclarativeview diff --git a/tools/designer/src/plugins/qdeclarativeview/qdeclarativeview.pro b/tools/designer/src/plugins/qdeclarativeview/qdeclarativeview.pro new file mode 100644 index 0000000..b8abe87 --- /dev/null +++ b/tools/designer/src/plugins/qdeclarativeview/qdeclarativeview.pro @@ -0,0 +1,13 @@ +TEMPLATE = lib +TARGET = qdeclarativeview +CONFIG += qt warn_on plugin designer +QT += declarative + +include(../plugins.pri) +build_all:!build_pass { + CONFIG -= build_all + CONFIG += release +} + +SOURCES += qdeclarativeview_plugin.cpp +HEADERS += qdeclarativeview_plugin.h diff --git a/tools/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.cpp b/tools/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.cpp new file mode 100644 index 0000000..b352a9b --- /dev/null +++ b/tools/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.cpp @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Designer of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdeclarativeview_plugin.h" + +#include <QtDesigner/QExtensionFactory> +#include <QtDesigner/QExtensionManager> + +#include <QtCore/qplugin.h> +#include <QtDeclarative/QDeclarativeView> + +static const char toolTipC[] = "QtDeclarative view widget"; + +QT_BEGIN_NAMESPACE + +QDeclarativeViewPlugin::QDeclarativeViewPlugin(QObject *parent) : + QObject(parent), + m_initialized(false) +{ +} + +QString QDeclarativeViewPlugin::name() const +{ + return QLatin1String("QDeclarativeView"); +} + +QString QDeclarativeViewPlugin::group() const +{ + return QLatin1String("Display Widgets"); +} + +QString QDeclarativeViewPlugin::toolTip() const +{ + return QString(QLatin1String(toolTipC)); +} + +QString QDeclarativeViewPlugin::whatsThis() const +{ + return QString(QLatin1String(toolTipC)); +} + +QString QDeclarativeViewPlugin::includeFile() const +{ + return QLatin1String("QtDeclarative/QDeclarativeView"); +} + +QIcon QDeclarativeViewPlugin::icon() const +{ + return QIcon(); +} + +bool QDeclarativeViewPlugin::isContainer() const +{ + return false; +} + +QWidget *QDeclarativeViewPlugin::createWidget(QWidget *parent) +{ + return new QDeclarativeView(parent); +} + +bool QDeclarativeViewPlugin::isInitialized() const +{ + return m_initialized; +} + +void QDeclarativeViewPlugin::initialize(QDesignerFormEditorInterface * /*core*/) +{ + if (m_initialized) + return; + + m_initialized = true; +} + +QString QDeclarativeViewPlugin::domXml() const +{ + return QLatin1String("\ + <ui language=\"c++\">\ + <widget class=\"QDeclarativeView\" name=\"declarativeView\">\ + <property name=\"geometry\">\ + <rect>\ + <x>0</x>\ + <y>0</y>\ + <width>300</width>\ + <height>200</height>\ + </rect>\ + </property>\ + </widget>\ + </ui>"); +} + +Q_EXPORT_PLUGIN2(customwidgetplugin, QDeclarativeViewPlugin) + +QT_END_NAMESPACE diff --git a/tools/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.h b/tools/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.h new file mode 100644 index 0000000..2f13f16 --- /dev/null +++ b/tools/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Designer of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDECLARATIVEVIEW_PLUGIN_H +#define QDECLARATIVEVIEW_PLUGIN_H + +#include <QtDesigner/QDesignerCustomWidgetInterface> + +QT_BEGIN_NAMESPACE + +class QDeclarativeViewPlugin: public QObject, public QDesignerCustomWidgetInterface +{ + Q_OBJECT + Q_INTERFACES(QDesignerCustomWidgetInterface) +public: + QDeclarativeViewPlugin(QObject *parent = 0); + + virtual QString name() const; + virtual QString group() const; + virtual QString toolTip() const; + virtual QString whatsThis() const; + virtual QString includeFile() const; + virtual QIcon icon() const; + virtual bool isContainer() const; + virtual QWidget *createWidget(QWidget *parent); + virtual bool isInitialized() const; + virtual void initialize(QDesignerFormEditorInterface *core); + virtual QString domXml() const; + +private: + bool m_initialized; +}; + +QT_END_NAMESPACE + +#endif // QDECLARATIVEVIEW_PLUGIN_H |