summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/gui.pro7
-rw-r--r--src/gui/image/qnativeimage.cpp8
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm74
-rw-r--r--src/gui/painting/qwindowsurface_raster.cpp29
-rw-r--r--src/gui/painting/qwindowsurface_raster_p.h3
5 files changed, 74 insertions, 47 deletions
diff --git a/src/gui/gui.pro b/src/gui/gui.pro
index fe1a595..076fe0a 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -65,15 +65,14 @@ symbian {
neon:*-g++* {
DEFINES += QT_HAVE_NEON
HEADERS += $$NEON_HEADERS
- SOURCES += $$NEON_SOURCES
DRAWHELPER_NEON_ASM_FILES = $$NEON_ASM
- neon_compiler.commands = $$QMAKE_CXX -c -mfpu=neon
- neon_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
+ neon_compiler.commands = $$QMAKE_CXX -c
+ neon_compiler.commands += $(CXXFLAGS) -mfpu=neon $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
neon_compiler.dependency_type = TYPE_C
neon_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
- neon_compiler.input = DRAWHELPER_NEON_ASM_FILES
+ neon_compiler.input = DRAWHELPER_NEON_ASM_FILES NEON_SOURCES
neon_compiler.variable_out = OBJECTS
neon_compiler.name = compiling[neon] ${QMAKE_FILE_IN}
silent:neon_compiler.commands = @echo compiling[neon] ${QMAKE_FILE_IN} && $$neon_compiler.commands
diff --git a/src/gui/image/qnativeimage.cpp b/src/gui/image/qnativeimage.cpp
index 01baa36..8face87 100644
--- a/src/gui/image/qnativeimage.cpp
+++ b/src/gui/image/qnativeimage.cpp
@@ -181,15 +181,17 @@ QNativeImage::QNativeImage(int width, int height, QImage::Format format,bool /*
if (ok) {
xshmimg->data = (char*)shmat(xshminfo.shmid, 0, 0);
xshminfo.shmaddr = xshmimg->data;
- if (shmctl(xshminfo.shmid, IPC_RMID, 0) == -1)
- qWarning() << "Error while marking the shared memory segment to be destroyed";
ok = (xshminfo.shmaddr != (char*)-1);
if (ok)
image = QImage((uchar *)xshmimg->data, width, height, format);
}
xshminfo.readOnly = false;
- if (ok)
+ if (ok) {
ok = XShmAttach(X11->display, &xshminfo);
+ XSync(X11->display, False);
+ if (shmctl(xshminfo.shmid, IPC_RMID, 0) == -1)
+ qWarning() << "Error while marking the shared memory segment to be destroyed";
+ }
if (!ok) {
qWarning() << "QNativeImage: Unable to attach to shared memory segment.";
if (xshmimg->data) {
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index ddbf53f..e50bdd3 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -1060,30 +1060,26 @@ QWidget *qt_mac_getTargetForMouseEvent(
returnGlobalPoint = flipPoint([NSEvent mouseLocation]).toPoint();
QWidget *mouseGrabber = QWidget::mouseGrabber();
bool buttonDownNotBlockedByModal = qt_button_down && !QApplicationPrivate::isBlockedByModal(qt_button_down);
+ QWidget *popup = QApplication::activePopupWidget();
// Resolve the widget under the mouse:
QWidget *widgetUnderMouse = 0;
- if (nativeWidget) {
+ if (popup || qt_button_down || !nativeWidget) {
+ // Using QApplication::widgetAt for finding the widget under the mouse
+ // is most safe, since it ignores cocoas own mouse down redirections (which
+ // we need to be prepared for when using nativeWidget as starting point).
+ // (the only exception is for QMacNativeWidget, where QApplication::widgetAt fails).
+ // But it is also slower (I guess), so we try to avoid it and use nativeWidget if we can:
+ widgetUnderMouse = QApplication::widgetAt(returnGlobalPoint);
+ }
+
+ if (!widgetUnderMouse && nativeWidget) {
+ // Entering here should be the common case. We
+ // also handle the QMacNativeWidget fallback case.
QPoint p = nativeWidget->mapFromGlobal(returnGlobalPoint);
widgetUnderMouse = nativeWidget->childAt(p);
- if (!widgetUnderMouse){
- // Cocoa will redirct mouse event to the current
- // mouse down widget, which is not what we want for our
- // widgetUnderMouse assignment. So we need to check
- // if we are actually inside nativeView:
- if (nativeWidget->rect().contains(p)) {
- widgetUnderMouse = nativeWidget;
- } else {
- // Ok, fallback to find the widget under mouse ourselves.
- widgetUnderMouse = QApplication::widgetAt(returnGlobalPoint);
- }
- }
- } else {
- // Calling QApplication::widgetAt is potentially slow, hence the
- // reason we avoid it if we can. So supplying a nativeWidget to
- // this function is mostly an optimization. But at the same time,
- // calling QApplication::widgetAt fails for QMacNativeWidget...
- widgetUnderMouse = QApplication::widgetAt(returnGlobalPoint);
+ if (!widgetUnderMouse && nativeWidget->rect().contains(p))
+ widgetUnderMouse = nativeWidget;
}
if (widgetUnderMouse) {
@@ -1107,23 +1103,27 @@ QWidget *qt_mac_getTargetForMouseEvent(
if (returnWidgetUnderMouse)
*returnWidgetUnderMouse = widgetUnderMouse;
- // Resolve the target for the mouse event. Default will be widgetUnderMouse, except
- // if there is a popup-"grab", mousegrab, or button-down-"grab":
- QWidget *popup = QApplication::activePopupWidget();
+ // Resolve the target for the mouse event. Default will be
+ // widgetUnderMouse, except if there is a grab (popup/mouse/button-down):
if (popup && !mouseGrabber) {
- if (!popup->isAncestorOf(widgetUnderMouse)) {
- // The popup will always grab the mouse unless the
- // mouse is over a child, or the user scrolls:
+ // We special case handling of popups, since they have an implicitt mouse grab.
+ QWidget *candidate = buttonDownNotBlockedByModal ? qt_button_down : widgetUnderMouse;
+ if (!popup->isAncestorOf(candidate)) {
+ // INVARIANT: we have a popup, but the candidate is not
+ // in it. But the popup will grab the mouse anyway,
+ // except if the user scrolls:
if (eventType == QEvent::Wheel)
return 0;
returnLocalPoint = popup->mapFromGlobal(returnGlobalPoint);
return popup;
- } else if (popup == widgetUnderMouse) {
+ } else if (popup == candidate) {
+ // INVARIANT: The candidate is the popup itself, and not a child:
returnLocalPoint = popup->mapFromGlobal(returnGlobalPoint);
return popup;
} else {
- returnLocalPoint = widgetUnderMouse->mapFromGlobal(returnGlobalPoint);
- return widgetUnderMouse;
+ // INVARIANT: The candidate is a child inside the popup:
+ returnLocalPoint = candidate->mapFromGlobal(returnGlobalPoint);
+ return candidate;
}
}
@@ -1192,16 +1192,14 @@ bool qt_mac_handleMouseEvent(NSEvent *event, QEvent::Type eventType, Qt::MouseBu
if (!widgetToGetMouse)
return false;
- if (!nativeWidget) {
- // Path typically taken for mouse moves (send
- // directly from [QCocoaWindow sendEvent]
- if (!widgetUnderMouse)
- return false;
- nativeWidget = widgetUnderMouse->internalWinId() ?
- widgetUnderMouse : widgetUnderMouse->nativeParentWidget();
- if (!nativeWidget)
- return false;
- }
+ // From here on, we let nativeWidget actually be the native widget under widgetUnderMouse. The reason
+ // for this, is that qt_mac_getTargetForMouseEvent will set cocoa's mouse event redirection aside when
+ // determining which widget is under the mouse (in other words, it will usually ignore nativeWidget).
+ // nativeWidget will be used in QApplicationPrivate::sendMouseEvent to correctly dispatch enter/leave events.
+ if (widgetUnderMouse)
+ nativeWidget = widgetUnderMouse->internalWinId() ? widgetUnderMouse : widgetUnderMouse->nativeParentWidget();
+ if (!nativeWidget)
+ return false;
NSView *view = qt_mac_effectiveview_for(nativeWidget);
// Handle tablet events (if any) first.
diff --git a/src/gui/painting/qwindowsurface_raster.cpp b/src/gui/painting/qwindowsurface_raster.cpp
index 843c9ff..419518ac 100644
--- a/src/gui/painting/qwindowsurface_raster.cpp
+++ b/src/gui/painting/qwindowsurface_raster.cpp
@@ -78,6 +78,9 @@ public:
#ifdef Q_WS_X11
GC gc;
+#ifndef QT_NO_MITSHM
+ uint needsSync : 1;
+#endif
#ifndef QT_NO_XRENDER
uint translucentBackground : 1;
#endif
@@ -94,6 +97,9 @@ QRasterWindowSurface::QRasterWindowSurface(QWidget *window, bool setDefaultSurfa
d_ptr->translucentBackground = X11->use_xrender
&& window->x11Info().depth() == 32;
#endif
+#ifndef QT_NO_MITHSM
+ d_ptr->needsSync = false;
+#endif
#endif
d_ptr->image = 0;
d_ptr->inSetGeometry = false;
@@ -116,8 +122,23 @@ QPaintDevice *QRasterWindowSurface::paintDevice()
return &d_ptr->image->image;
}
+#if defined(Q_WS_X11) && !defined(QT_NO_MITSHM)
+void QRasterWindowSurface::syncX()
+{
+ // delay writing to the backbuffer until we know for sure X is done reading from it
+ if (d_ptr->needsSync) {
+ XSync(X11->display, false);
+ d_ptr->needsSync = false;
+ }
+}
+#endif
+
void QRasterWindowSurface::beginPaint(const QRegion &rgn)
{
+#if defined(Q_WS_X11) && !defined(QT_NO_MITSHM)
+ syncX();
+#endif
+
#if (defined(Q_WS_X11) && !defined(QT_NO_XRENDER)) || (defined(Q_WS_WIN) && !defined(Q_WS_WINCE))
if (!qt_widget_private(window())->isOpaque && window()->testAttribute(Qt::WA_TranslucentBackground)) {
#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE)
@@ -217,13 +238,13 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi
if (d_ptr->image->xshmpm) {
XCopyArea(X11->display, d_ptr->image->xshmpm, widget->handle(), d_ptr->gc,
br.x(), br.y(), br.width(), br.height(), wbr.x(), wbr.y());
- XSync(X11->display, False);
+ d_ptr->needsSync = true;
} else if (d_ptr->image->xshmimg) {
const QImage &src = d->image->image;
br = br.intersected(src.rect());
XShmPutImage(X11->display, widget->handle(), d_ptr->gc, d_ptr->image->xshmimg,
br.x(), br.y(), wbr.x(), wbr.y(), br.width(), br.height(), False);
- XSync(X11->display, False);
+ d_ptr->needsSync = true;
} else
#endif
{
@@ -392,6 +413,10 @@ bool QRasterWindowSurface::scroll(const QRegion &area, int dx, int dy)
if (!d->image || d->image->image.isNull())
return false;
+#if defined(Q_WS_X11) && !defined(QT_NO_MITSHM)
+ syncX();
+#endif
+
const QVector<QRect> rects = area.rects();
for (int i = 0; i < rects.size(); ++i)
qt_scrollRectInImage(d->image->image, rects.at(i), QPoint(dx, dy));
diff --git a/src/gui/painting/qwindowsurface_raster_p.h b/src/gui/painting/qwindowsurface_raster_p.h
index b6e61e1..903810b 100644
--- a/src/gui/painting/qwindowsurface_raster_p.h
+++ b/src/gui/painting/qwindowsurface_raster_p.h
@@ -107,6 +107,9 @@ public:
bool scroll(const QRegion &area, int dx, int dy);
private:
+#if defined(Q_WS_X11) && !defined(QT_NO_MITSHM)
+ void syncX();
+#endif
void prepareBuffer(QImage::Format format, QWidget *widget);
Q_DECLARE_PRIVATE(QRasterWindowSurface)
QScopedPointer<QRasterWindowSurfacePrivate> d_ptr;